@seliseblocks/mailcraft 0.2.16 → 0.2.19

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 (78) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/DOCS.md +70 -67
  3. package/README.md +8 -8
  4. package/README.md.txt +8 -8
  5. package/dist/mailcraft-editor.bundle.js +89 -76
  6. package/dist/mailcraft-editor.bundle.js.map +3 -3
  7. package/examples/templates/activate-your-account.html +1 -1
  8. package/examples/templates/back-in-stock.html +4 -4
  9. package/examples/templates/cart-left-behind.html +3 -3
  10. package/examples/templates/community-giveaway.html +3 -3
  11. package/examples/templates/frontend-futures-invite.html +3 -3
  12. package/examples/templates/give-25-get-25.html +2 -2
  13. package/examples/templates/invoice-paid.html +3 -3
  14. package/examples/templates/meet-nova-launch.html +7 -7
  15. package/examples/templates/mega-weekend-sale.html +1 -1
  16. package/examples/templates/order-confirmed.html +6 -6
  17. package/examples/templates/rate-your-headphones.html +3 -3
  18. package/examples/templates/reset-your-password.html +1 -1
  19. package/examples/templates/thankyou-promo-code.html +3 -3
  20. package/examples/templates/the-sunday-brief.html +4 -4
  21. package/examples/templates/welcome-to-your-workspace.html +4 -4
  22. package/examples/templates/your-order-shipped.html +2 -2
  23. package/examples/templates/your-password-was-changed.html +2 -2
  24. package/examples/templates/your-signin-code.html +1 -1
  25. package/examples/vanilla.html +66 -66
  26. package/package.json +1 -1
  27. package/src/core/binder.js +10 -0
  28. package/src/core/blocks.js +3 -3
  29. package/src/core/editor-core.js +195 -6
  30. package/src/core/export.js +311 -22
  31. package/src/core/i18n/ar.js +2 -0
  32. package/src/core/i18n/bg.js +2 -0
  33. package/src/core/i18n/bn.js +2 -0
  34. package/src/core/i18n/ca.js +2 -0
  35. package/src/core/i18n/cs.js +2 -0
  36. package/src/core/i18n/da.js +2 -0
  37. package/src/core/i18n/de-CH.js +2 -0
  38. package/src/core/i18n/de.js +2 -0
  39. package/src/core/i18n/dz.js +2 -0
  40. package/src/core/i18n/el.js +2 -0
  41. package/src/core/i18n/en.js +2 -0
  42. package/src/core/i18n/es.js +2 -0
  43. package/src/core/i18n/et.js +2 -0
  44. package/src/core/i18n/fi.js +2 -0
  45. package/src/core/i18n/fr.js +2 -0
  46. package/src/core/i18n/hr.js +2 -0
  47. package/src/core/i18n/hu.js +2 -0
  48. package/src/core/i18n/index.js +83 -83
  49. package/src/core/i18n/it.js +2 -0
  50. package/src/core/i18n/lt.js +2 -0
  51. package/src/core/i18n/lv.js +2 -0
  52. package/src/core/i18n/nb.js +2 -0
  53. package/src/core/i18n/nl.js +2 -0
  54. package/src/core/i18n/pl.js +2 -0
  55. package/src/core/i18n/pt.js +2 -0
  56. package/src/core/i18n/ro.js +2 -0
  57. package/src/core/i18n/ru.js +2 -0
  58. package/src/core/i18n/sk.js +2 -0
  59. package/src/core/i18n/sl.js +2 -0
  60. package/src/core/i18n/sv.js +2 -0
  61. package/src/core/i18n/tr.js +2 -0
  62. package/src/core/i18n/uk.js +2 -0
  63. package/src/core/icons.js +17 -43
  64. package/src/core/ids.js +1 -1
  65. package/src/core/import-html.js +390 -20
  66. package/src/core/layout-style.js +25 -0
  67. package/src/core/parse.js +10 -10
  68. package/src/core/placeholder.js +15 -15
  69. package/src/core/sanitize.js +4 -1
  70. package/src/core/theme.js +22 -1
  71. package/src/core/variables.js +11 -11
  72. package/src/mailcraft-editor.js +11 -1
  73. package/src/render/block-body.js +129 -17
  74. package/src/render/canvas.js +35 -6
  75. package/src/render/fields.js +19 -0
  76. package/src/render/focus-preserve.js +158 -158
  77. package/src/render/screenshot.js +26 -3
  78. package/src/render/style.js +6 -1
@@ -1,83 +1,83 @@
1
- import { EN as ENBase } from './en.js';
2
-
3
- /**
4
- * Builds a translator. `overrides` is whatever a host passes as `.messages`
5
- * on the element -- a host's own table, an imported locale, or both merged
6
- * via `defineMessages` below.
7
- *
8
- * Three deliberate properties:
9
- * 1. English always resolves. A locale is an overlay, never a replacement,
10
- * so a partial or missing translation shows English rather than a gap.
11
- * 2. Params interpolate `{name}`.
12
- * 3. A truly missing key (not in `overrides`, not in `EN`) renders as the
13
- * key itself, not an empty string -- a visible `toast.deleted` in the UI
14
- * is obviously wrong and names the exact key to add, where blank text
15
- * just looks like a broken build.
16
- */
17
- export function createTranslator(overrides) {
18
- const table = overrides || {};
19
- return function t(key, params) {
20
- const template = table[key] ?? ENBase[key] ?? key;
21
- if (!params) return template;
22
- return template.replace(/\{(\w+)\}/g, (whole, name) => (name in params ? String(params[name]) : whole));
23
- };
24
- }
25
-
26
- /** Merges a locale over a base, for a host assembling its own table -- the documented way to combine a shipped locale with a few product-specific overrides. */
27
- export function defineMessages(base, overrides) {
28
- return Object.assign({}, base, overrides);
29
- }
30
-
31
- /** Keys in `base` that `locale` does not translate. What a translator has left to do. */
32
- export function missingKeys(locale, base) {
33
- const source = base || ENBase;
34
- return Object.keys(source).filter((key) => locale[key] === undefined).sort();
35
- }
36
-
37
- /**
38
- * Every locale that ships, for a host building a language switcher.
39
- * Metadata only -- no message tables -- so listing the locales never pulls
40
- * every translation file into a consumer's bundle; a host deep-imports the
41
- * one it wants, e.g. `mailcraft-editor/src/core/i18n/bn.js`.
42
- */
43
- export const LOCALES = [
44
- { tag: 'en', name: 'English' },
45
- { tag: 'ar', name: 'Arabic', rtl: true },
46
- { tag: 'bn', name: 'Bangla' },
47
- { tag: 'dz', name: 'Dzongkha' },
48
- { tag: 'bg', name: 'Bulgarian' },
49
- { tag: 'ca', name: 'Catalan' },
50
- { tag: 'cs', name: 'Czech' },
51
- { tag: 'da', name: 'Danish' },
52
- { tag: 'de', name: 'German' },
53
- { tag: 'de-CH', name: 'Swiss German' },
54
- { tag: 'el', name: 'Greek' },
55
- { tag: 'es', name: 'Spanish' },
56
- { tag: 'et', name: 'Estonian' },
57
- { tag: 'fi', name: 'Finnish' },
58
- { tag: 'fr', name: 'French' },
59
- { tag: 'hr', name: 'Croatian' },
60
- { tag: 'hu', name: 'Hungarian' },
61
- { tag: 'it', name: 'Italian' },
62
- { tag: 'lt', name: 'Lithuanian' },
63
- { tag: 'lv', name: 'Latvian' },
64
- { tag: 'nb', name: 'Norwegian Bokmål' },
65
- { tag: 'nl', name: 'Dutch' },
66
- { tag: 'pl', name: 'Polish' },
67
- { tag: 'pt', name: 'Portuguese' },
68
- { tag: 'ro', name: 'Romanian' },
69
- { tag: 'ru', name: 'Russian' },
70
- { tag: 'sk', name: 'Slovak' },
71
- { tag: 'sl', name: 'Slovenian' },
72
- { tag: 'sv', name: 'Swedish' },
73
- { tag: 'tr', name: 'Turkish' },
74
- { tag: 'uk', name: 'Ukrainian' },
75
- ];
76
-
77
- /** `true` when the tag is written right to left. Metadata only -- `dir` is still what actually flips the layout. */
78
- export function isRtl(tag) {
79
- const entry = LOCALES.find((l) => l.tag === tag);
80
- return entry ? entry.rtl === true : false;
81
- }
82
-
83
- export { EN, MESSAGE_KEYS } from './en.js';
1
+ import { EN as ENBase } from './en.js';
2
+
3
+ /**
4
+ * Builds a translator. `overrides` is whatever a host passes as `.messages`
5
+ * on the element -- a host's own table, an imported locale, or both merged
6
+ * via `defineMessages` below.
7
+ *
8
+ * Three deliberate properties:
9
+ * 1. English always resolves. A locale is an overlay, never a replacement,
10
+ * so a partial or missing translation shows English rather than a gap.
11
+ * 2. Params interpolate `{name}`.
12
+ * 3. A truly missing key (not in `overrides`, not in `EN`) renders as the
13
+ * key itself, not an empty string -- a visible `toast.deleted` in the UI
14
+ * is obviously wrong and names the exact key to add, where blank text
15
+ * just looks like a broken build.
16
+ */
17
+ export function createTranslator(overrides) {
18
+ const table = overrides || {};
19
+ return function t(key, params) {
20
+ const template = table[key] ?? ENBase[key] ?? key;
21
+ if (!params) return template;
22
+ return template.replace(/\{(\w+)\}/g, (whole, name) => (name in params ? String(params[name]) : whole));
23
+ };
24
+ }
25
+
26
+ /** Merges a locale over a base, for a host assembling its own table -- the documented way to combine a shipped locale with a few product-specific overrides. */
27
+ export function defineMessages(base, overrides) {
28
+ return Object.assign({}, base, overrides);
29
+ }
30
+
31
+ /** Keys in `base` that `locale` does not translate. What a translator has left to do. */
32
+ export function missingKeys(locale, base) {
33
+ const source = base || ENBase;
34
+ return Object.keys(source).filter((key) => locale[key] === undefined).sort();
35
+ }
36
+
37
+ /**
38
+ * Every locale that ships, for a host building a language switcher.
39
+ * Metadata only -- no message tables -- so listing the locales never pulls
40
+ * every translation file into a consumer's bundle; a host deep-imports the
41
+ * one it wants, e.g. `mailcraft-editor/src/core/i18n/bn.js`.
42
+ */
43
+ export const LOCALES = [
44
+ { tag: 'en', name: 'English' },
45
+ { tag: 'ar', name: 'Arabic', rtl: true },
46
+ { tag: 'bn', name: 'Bangla' },
47
+ { tag: 'dz', name: 'Dzongkha' },
48
+ { tag: 'bg', name: 'Bulgarian' },
49
+ { tag: 'ca', name: 'Catalan' },
50
+ { tag: 'cs', name: 'Czech' },
51
+ { tag: 'da', name: 'Danish' },
52
+ { tag: 'de', name: 'German' },
53
+ { tag: 'de-CH', name: 'Swiss German' },
54
+ { tag: 'el', name: 'Greek' },
55
+ { tag: 'es', name: 'Spanish' },
56
+ { tag: 'et', name: 'Estonian' },
57
+ { tag: 'fi', name: 'Finnish' },
58
+ { tag: 'fr', name: 'French' },
59
+ { tag: 'hr', name: 'Croatian' },
60
+ { tag: 'hu', name: 'Hungarian' },
61
+ { tag: 'it', name: 'Italian' },
62
+ { tag: 'lt', name: 'Lithuanian' },
63
+ { tag: 'lv', name: 'Latvian' },
64
+ { tag: 'nb', name: 'Norwegian Bokmål' },
65
+ { tag: 'nl', name: 'Dutch' },
66
+ { tag: 'pl', name: 'Polish' },
67
+ { tag: 'pt', name: 'Portuguese' },
68
+ { tag: 'ro', name: 'Romanian' },
69
+ { tag: 'ru', name: 'Russian' },
70
+ { tag: 'sk', name: 'Slovak' },
71
+ { tag: 'sl', name: 'Slovenian' },
72
+ { tag: 'sv', name: 'Swedish' },
73
+ { tag: 'tr', name: 'Turkish' },
74
+ { tag: 'uk', name: 'Ukrainian' },
75
+ ];
76
+
77
+ /** `true` when the tag is written right to left. Metadata only -- `dir` is still what actually flips the layout. */
78
+ export function isRtl(tag) {
79
+ const entry = LOCALES.find((l) => l.tag === tag);
80
+ return entry ? entry.rtl === true : false;
81
+ }
82
+
83
+ export { EN, MESSAGE_KEYS } from './en.js';
@@ -170,6 +170,8 @@ export const IT = {
170
170
  'toast.imageReplaced': 'Immagine sostituita',
171
171
  'toast.imageAdded': 'Immagine aggiunta al canvas',
172
172
  'toast.htmlCopied': 'HTML copiato negli appunti',
173
+ 'toast.exportImageOne': '1 immagine non verrà visualizzata all’invio — origine segnaposto o data:/cid:',
174
+ 'toast.exportImageMany': '{count} immagini non verranno visualizzate all’invio — origini segnaposto o data:/cid:',
173
175
  'toast.templateLoaded': '{name} caricato',
174
176
  'toast.snippetDefaultLabel': 'Snippet',
175
177
  'toast.snippetInserted': '{name} inserito',
@@ -170,6 +170,8 @@ export const LT = {
170
170
  'toast.imageReplaced': 'Vaizdas pakeistas',
171
171
  'toast.imageAdded': 'Vaizdas pridėtas į drobę',
172
172
  'toast.htmlCopied': 'HTML nukopijuotas į iškarpinę',
173
+ 'toast.exportImageOne': '1 paveikslėlis nebus rodomas išsiuntus — vietos rezervavimo arba data:/cid: šaltinis',
174
+ 'toast.exportImageMany': '{count} paveikslėliai nebus rodomi išsiuntus — vietos rezervavimo arba data:/cid: šaltiniai',
173
175
  'toast.templateLoaded': '{name} įkeltas',
174
176
  'toast.snippetDefaultLabel': 'Iškarpa',
175
177
  'toast.snippetInserted': '{name} įterptas',
@@ -170,6 +170,8 @@ export const LV = {
170
170
  'toast.imageReplaced': 'Attēls aizstāts',
171
171
  'toast.imageAdded': 'Attēls pievienots audeklam',
172
172
  'toast.htmlCopied': 'HTML nokopēts starpliktuvē',
173
+ 'toast.exportImageOne': '1 attēls netiks rādīts pēc nosūtīšanas — vietturis vai data:/cid: avots',
174
+ 'toast.exportImageMany': '{count} attēli netiks rādīti pēc nosūtīšanas — vietturi vai data:/cid: avoti',
173
175
  'toast.templateLoaded': '{name} ielādēts',
174
176
  'toast.snippetDefaultLabel': 'Fragments',
175
177
  'toast.snippetInserted': '{name} ievietots',
@@ -170,6 +170,8 @@ export const NB = {
170
170
  'toast.imageReplaced': 'Bilde erstattet',
171
171
  'toast.imageAdded': 'Bilde lagt til på lerretet',
172
172
  'toast.htmlCopied': 'HTML kopiert til utklippstavlen',
173
+ 'toast.exportImageOne': '1 bilde vises ikke når e-posten sendes — plassholder eller data:/cid:-kilde',
174
+ 'toast.exportImageMany': '{count} bilder vises ikke når e-posten sendes — plassholder- eller data:/cid:-kilder',
173
175
  'toast.templateLoaded': '{name} lastet inn',
174
176
  'toast.snippetDefaultLabel': 'Utdrag',
175
177
  'toast.snippetInserted': '{name} satt inn',
@@ -170,6 +170,8 @@ export const NL = {
170
170
  'toast.imageReplaced': 'Afbeelding vervangen',
171
171
  'toast.imageAdded': 'Afbeelding toegevoegd aan canvas',
172
172
  'toast.htmlCopied': 'HTML gekopieerd naar klembord',
173
+ 'toast.exportImageOne': '1 afbeelding wordt bij verzending niet weergegeven — tijdelijke aanduiding of data:/cid:-bron',
174
+ 'toast.exportImageMany': '{count} afbeeldingen worden bij verzending niet weergegeven — tijdelijke aanduidingen of data:/cid:-bronnen',
173
175
  'toast.templateLoaded': '{name} geladen',
174
176
  'toast.snippetDefaultLabel': 'Fragment',
175
177
  'toast.snippetInserted': '{name} ingevoegd',
@@ -170,6 +170,8 @@ export const PL = {
170
170
  'toast.imageReplaced': 'Zastąpiono obraz',
171
171
  'toast.imageAdded': 'Dodano obraz do płótna',
172
172
  'toast.htmlCopied': 'Skopiowano HTML do schowka',
173
+ 'toast.exportImageOne': '1 obraz nie wyświetli się po wysłaniu — źródło zastępcze lub data:/cid:',
174
+ 'toast.exportImageMany': '{count} obrazów nie wyświetli się po wysłaniu — źródła zastępcze lub data:/cid:',
173
175
  'toast.templateLoaded': 'Wczytano {name}',
174
176
  'toast.snippetDefaultLabel': 'Fragment',
175
177
  'toast.snippetInserted': 'Wstawiono {name}',
@@ -170,6 +170,8 @@ export const PT = {
170
170
  'toast.imageReplaced': 'Imagem substituída',
171
171
  'toast.imageAdded': 'Imagem adicionada à tela',
172
172
  'toast.htmlCopied': 'HTML copiado para a área de transferência',
173
+ 'toast.exportImageOne': '1 imagem não será exibida ao enviar — origem de marcador de posição ou data:/cid:',
174
+ 'toast.exportImageMany': '{count} imagens não serão exibidas ao enviar — origens de marcador de posição ou data:/cid:',
173
175
  'toast.templateLoaded': '{name} carregado',
174
176
  'toast.snippetDefaultLabel': 'Trecho',
175
177
  'toast.snippetInserted': '{name} inserido',
@@ -170,6 +170,8 @@ export const RO = {
170
170
  'toast.imageReplaced': 'Imagine înlocuită',
171
171
  'toast.imageAdded': 'Imagine adăugată pe canvas',
172
172
  'toast.htmlCopied': 'HTML copiat în clipboard',
173
+ 'toast.exportImageOne': '1 imagine nu va fi afișată la trimitere — sursă substituent sau data:/cid:',
174
+ 'toast.exportImageMany': '{count} imagini nu vor fi afișate la trimitere — surse substituent sau data:/cid:',
173
175
  'toast.templateLoaded': '{name} încărcat',
174
176
  'toast.snippetDefaultLabel': 'Fragment',
175
177
  'toast.snippetInserted': '{name} inserat',
@@ -170,6 +170,8 @@ export const RU = {
170
170
  'toast.imageReplaced': 'Изображение заменено',
171
171
  'toast.imageAdded': 'Изображение добавлено на холст',
172
172
  'toast.htmlCopied': 'HTML скопирован в буфер обмена',
173
+ 'toast.exportImageOne': '1 изображение не отобразится при отправке — заполнитель или источник data:/cid:',
174
+ 'toast.exportImageMany': '{count} изображений не отобразятся при отправке — заполнители или источники data:/cid:',
173
175
  'toast.templateLoaded': '{name} загружен',
174
176
  'toast.snippetDefaultLabel': 'Фрагмент',
175
177
  'toast.snippetInserted': '{name} вставлен',
@@ -170,6 +170,8 @@ export const SK = {
170
170
  'toast.imageReplaced': 'Obrázok nahradený',
171
171
  'toast.imageAdded': 'Obrázok pridaný na plátno',
172
172
  'toast.htmlCopied': 'HTML skopírované do schránky',
173
+ 'toast.exportImageOne': '1 obrázok sa po odoslaní nezobrazí — zástupný alebo data:/cid: zdroj',
174
+ 'toast.exportImageMany': '{count} obrázkov sa po odoslaní nezobrazí — zástupné alebo data:/cid: zdroje',
173
175
  'toast.templateLoaded': '{name} načítané',
174
176
  'toast.snippetDefaultLabel': 'Úryvok',
175
177
  'toast.snippetInserted': '{name} vložené',
@@ -170,6 +170,8 @@ export const SL = {
170
170
  'toast.imageReplaced': 'Slika zamenjana',
171
171
  'toast.imageAdded': 'Slika dodana na platno',
172
172
  'toast.htmlCopied': 'HTML kopiran v odložišče',
173
+ 'toast.exportImageOne': '1 slika ob pošiljanju ne bo prikazana — ograda ali vir data:/cid:',
174
+ 'toast.exportImageMany': '{count} slik ob pošiljanju ne bo prikazanih — ograde ali viri data:/cid:',
173
175
  'toast.templateLoaded': '{name} naloženo',
174
176
  'toast.snippetDefaultLabel': 'Odlomek',
175
177
  'toast.snippetInserted': '{name} vstavljeno',
@@ -170,6 +170,8 @@ export const SV = {
170
170
  'toast.imageReplaced': 'Bild ersatt',
171
171
  'toast.imageAdded': 'Bild tillagd på canvasen',
172
172
  'toast.htmlCopied': 'HTML kopierad till urklipp',
173
+ 'toast.exportImageOne': '1 bild visas inte när mejlet skickas — platshållare eller data:/cid:-källa',
174
+ 'toast.exportImageMany': '{count} bilder visas inte när mejlet skickas — platshållar- eller data:/cid:-källor',
173
175
  'toast.templateLoaded': '{name} inläst',
174
176
  'toast.snippetDefaultLabel': 'Snutt',
175
177
  'toast.snippetInserted': '{name} infogad',
@@ -170,6 +170,8 @@ export const TR = {
170
170
  'toast.imageReplaced': 'Görsel değiştirildi',
171
171
  'toast.imageAdded': 'Görsel tuvale eklendi',
172
172
  'toast.htmlCopied': 'HTML panoya kopyalandı',
173
+ 'toast.exportImageOne': '1 görsel gönderildiğinde görüntülenmeyecek — yer tutucu veya data:/cid: kaynağı',
174
+ 'toast.exportImageMany': '{count} görsel gönderildiğinde görüntülenmeyecek — yer tutucu veya data:/cid: kaynakları',
173
175
  'toast.templateLoaded': '{name} yüklendi',
174
176
  'toast.snippetDefaultLabel': 'Snippet',
175
177
  'toast.snippetInserted': '{name} eklendi',
@@ -170,6 +170,8 @@ export const UK = {
170
170
  'toast.imageReplaced': 'Зображення замінено',
171
171
  'toast.imageAdded': 'Зображення додано на полотно',
172
172
  'toast.htmlCopied': 'HTML скопійовано в буфер обміну',
173
+ 'toast.exportImageOne': '1 зображення не відображатиметься після надсилання — заповнювач або джерело data:/cid:',
174
+ 'toast.exportImageMany': '{count} зображень не відображатимуться після надсилання — заповнювачі або джерела data:/cid:',
173
175
  'toast.templateLoaded': '{name} завантажено',
174
176
  'toast.snippetDefaultLabel': 'Фрагмент',
175
177
  'toast.snippetInserted': '{name} вставлено',
package/src/core/icons.js CHANGED
@@ -1,4 +1,10 @@
1
- /** Thin-stroke icon set (Lucide grammar, stroke 1.5), ported path-for-path from the original prototype. */
1
+ /**
2
+ * Thin-stroke icon set, stroke 1.5 on a 24 grid. The shapes are this
3
+ * project's own, carried over path-for-path from its earlier prototype;
4
+ * the thin-stroke grammar follows the convention Lucide popularised, but
5
+ * no path data is taken from Lucide or any other set. Keep it that way --
6
+ * new glyphs get drawn here, not pasted in.
7
+ */
2
8
  const ICONS = {
3
9
  text: ['M4 6h16', 'M4 12h12', 'M4 18h9'],
4
10
  image: [['rect', 3, 4, 18, 16], ['circle', 8.5, 9.5, 1.5], 'M3 17l5-5 4 4 3-3 6 6'],
@@ -53,6 +59,7 @@ const ICONS = {
53
59
  formatClear: ['M5 18 11 5h2l4 9', 'M7.5 13h7', 'M16 17l5 5', 'M21 17l-5 5'],
54
60
  chevronDown: ['M7 9l5 5 5-5'],
55
61
  x: ['M4 4l16 16', 'M20 4L4 20'],
62
+ xSocial: [['rect', 3, 3, 18, 18], 'M8.5 8.5l7 7', 'M15.5 8.5l-7 7'],
56
63
  instagram: [['rect', 3, 3, 18, 18], ['circle', 12, 12, 4], ['circle', 17, 7, 0.9]],
57
64
  linkedin: [['rect', 3, 3, 18, 18], 'M8 10v7', ['circle', 8, 7.2, 0.9], 'M12 17v-4a2.5 2.5 0 0 1 5 0v4'],
58
65
  facebook: [['rect', 3, 3, 18, 18], 'M15 8h-1.5A2.5 2.5 0 0 0 11 10.5V21', 'M8.5 13h5'],
@@ -103,31 +110,6 @@ const ICONS = {
103
110
  dribbble: [['circle', 12, 12, 9], 'M4 10c4 1.2 12 1.2 16.5 0', 'M8.5 4.5c2.5 3 5 8.5 5 14.5', 'M9 20c2-4 7-6 11.5-5'],
104
111
  };
105
112
 
106
- /**
107
- * Official brand glyphs (Simple Icons, CC0), rendered as filled paths --
108
- * the hand-drawn stroke approximations they replace read as amateur at
109
- * social-strip sizes. Kept separate from ICONS because these render
110
- * fill-based (icon() is a stroke builder) and because the key 'x' must not
111
- * shadow the ✕ close icon; resolve through brandIcon(), never icon().
112
- */
113
- const BRAND_GLYPHS = {
114
- behance: 'M16.969 16.927a2.561 2.561 0 0 0 1.901.677 2.501 2.501 0 0 0 1.531-.475c.362-.235.636-.584.779-.99h2.585a5.091 5.091 0 0 1-1.9 2.896 5.292 5.292 0 0 1-3.091.88 5.839 5.839 0 0 1-2.284-.433 4.871 4.871 0 0 1-1.723-1.211 5.657 5.657 0 0 1-1.08-1.874 7.057 7.057 0 0 1-.383-2.393c-.005-.8.129-1.595.396-2.349a5.313 5.313 0 0 1 5.088-3.604 4.87 4.87 0 0 1 2.376.563c.661.362 1.231.87 1.668 1.485a6.2 6.2 0 0 1 .943 2.133c.194.821.263 1.666.205 2.508h-7.699c-.063.79.184 1.574.688 2.187ZM6.947 4.084a8.065 8.065 0 0 1 1.928.198 4.29 4.29 0 0 1 1.49.638c.418.303.748.711.958 1.182.241.579.357 1.203.341 1.83a3.506 3.506 0 0 1-.506 1.961 3.726 3.726 0 0 1-1.503 1.287 3.588 3.588 0 0 1 2.027 1.437c.464.747.697 1.615.67 2.494a4.593 4.593 0 0 1-.423 2.032 3.945 3.945 0 0 1-1.163 1.413 5.114 5.114 0 0 1-1.683.807 7.135 7.135 0 0 1-1.928.259H0V4.084h6.947Zm-.235 12.9c.308.004.616-.029.916-.099a2.18 2.18 0 0 0 .766-.332c.228-.158.411-.371.534-.619.142-.317.208-.663.191-1.009a2.08 2.08 0 0 0-.642-1.715 2.618 2.618 0 0 0-1.696-.505h-3.54v4.279h3.471Zm13.635-5.967a2.13 2.13 0 0 0-1.654-.619 2.336 2.336 0 0 0-1.163.259 2.474 2.474 0 0 0-.738.62 2.359 2.359 0 0 0-.396.792c-.074.239-.12.485-.137.734h4.769a3.239 3.239 0 0 0-.679-1.785l-.002-.001Zm-13.813-.648a2.254 2.254 0 0 0 1.423-.433c.399-.355.607-.88.56-1.413a1.916 1.916 0 0 0-.178-.891 1.298 1.298 0 0 0-.495-.533 1.851 1.851 0 0 0-.711-.274 3.966 3.966 0 0 0-.835-.073H3.241v3.631h3.293v-.014ZM21.62 5.122h-5.976v1.527h5.976V5.122Z',
115
- discord: 'M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z',
116
- dribbble: 'M12 24C5.385 24 0 18.615 0 12S5.385 0 12 0s12 5.385 12 12-5.385 12-12 12zm10.12-10.358c-.35-.11-3.17-.953-6.384-.438 1.34 3.684 1.887 6.684 1.992 7.308 2.3-1.555 3.936-4.02 4.395-6.87zm-6.115 7.808c-.153-.9-.75-4.032-2.19-7.77l-.066.02c-5.79 2.015-7.86 6.025-8.04 6.4 1.73 1.358 3.92 2.166 6.29 2.166 1.42 0 2.77-.29 4-.814zm-11.62-2.58c.232-.4 3.045-5.055 8.332-6.765.135-.045.27-.084.405-.12-.26-.585-.54-1.167-.832-1.74C7.17 11.775 2.206 11.71 1.756 11.7l-.004.312c0 2.633.998 5.037 2.634 6.855zm-2.42-8.955c.46.008 4.683.026 9.477-1.248-1.698-3.018-3.53-5.558-3.8-5.928-2.868 1.35-5.01 3.99-5.676 7.17zM9.6 2.052c.282.38 2.145 2.914 3.822 6 3.645-1.365 5.19-3.44 5.373-3.702-1.81-1.61-4.19-2.586-6.795-2.586-.825 0-1.63.1-2.4.285zm10.335 3.483c-.218.29-1.935 2.493-5.724 4.04.24.49.47.985.68 1.486.08.18.15.36.22.53 3.41-.43 6.8.26 7.14.33-.02-2.42-.88-4.64-2.31-6.38z',
117
- facebook: 'M9.101 23.691v-7.98H6.627v-3.667h2.474v-1.58c0-4.085 1.848-5.978 5.858-5.978.401 0 .955.042 1.468.103a8.68 8.68 0 0 1 1.141.195v3.325a8.623 8.623 0 0 0-.653-.036 26.805 26.805 0 0 0-.733-.009c-.707 0-1.259.096-1.675.309a1.686 1.686 0 0 0-.679.622c-.258.42-.374.995-.374 1.752v1.297h3.919l-.386 2.103-.287 1.564h-3.246v8.245C19.396 23.238 24 18.179 24 12.044c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.628 3.874 10.35 9.101 11.647Z',
118
- instagram: 'M7.0301.084c-1.2768.0602-2.1487.264-2.911.5634-.7888.3075-1.4575.72-2.1228 1.3877-.6652.6677-1.075 1.3368-1.3802 2.127-.2954.7638-.4956 1.6365-.552 2.914-.0564 1.2775-.0689 1.6882-.0626 4.947.0062 3.2586.0206 3.6671.0825 4.9473.061 1.2765.264 2.1482.5635 2.9107.308.7889.72 1.4573 1.388 2.1228.6679.6655 1.3365 1.0743 2.1285 1.38.7632.295 1.6361.4961 2.9134.552 1.2773.056 1.6884.069 4.9462.0627 3.2578-.0062 3.668-.0207 4.9478-.0814 1.28-.0607 2.147-.2652 2.9098-.5633.7889-.3086 1.4578-.72 2.1228-1.3881.665-.6682 1.0745-1.3378 1.3795-2.1284.2957-.7632.4966-1.636.552-2.9124.056-1.2809.0692-1.6898.063-4.948-.0063-3.2583-.021-3.6668-.0817-4.9465-.0607-1.2797-.264-2.1487-.5633-2.9117-.3084-.7889-.72-1.4568-1.3876-2.1228C21.2982 1.33 20.628.9208 19.8378.6165 19.074.321 18.2017.1197 16.9244.0645 15.6471.0093 15.236-.005 11.977.0014 8.718.0076 8.31.0215 7.0301.0839m.1402 21.6932c-1.17-.0509-1.8053-.2453-2.2287-.408-.5606-.216-.96-.4771-1.3819-.895-.422-.4178-.6811-.8186-.9-1.378-.1644-.4234-.3624-1.058-.4171-2.228-.0595-1.2645-.072-1.6442-.079-4.848-.007-3.2037.0053-3.583.0607-4.848.05-1.169.2456-1.805.408-2.2282.216-.5613.4762-.96.895-1.3816.4188-.4217.8184-.6814 1.3783-.9003.423-.1651 1.0575-.3614 2.227-.4171 1.2655-.06 1.6447-.072 4.848-.079 3.2033-.007 3.5835.005 4.8495.0608 1.169.0508 1.8053.2445 2.228.408.5608.216.96.4754 1.3816.895.4217.4194.6816.8176.9005 1.3787.1653.4217.3617 1.056.4169 2.2263.0602 1.2655.0739 1.645.0796 4.848.0058 3.203-.0055 3.5834-.061 4.848-.051 1.17-.245 1.8055-.408 2.2294-.216.5604-.4763.96-.8954 1.3814-.419.4215-.8181.6811-1.3783.9-.4224.1649-1.0577.3617-2.2262.4174-1.2656.0595-1.6448.072-4.8493.079-3.2045.007-3.5825-.006-4.848-.0608M16.953 5.5864A1.44 1.44 0 1 0 18.39 4.144a1.44 1.44 0 0 0-1.437 1.4424M5.8385 12.012c.0067 3.4032 2.7706 6.1557 6.173 6.1493 3.4026-.0065 6.157-2.7701 6.1506-6.1733-.0065-3.4032-2.771-6.1565-6.174-6.1498-3.403.0067-6.156 2.771-6.1496 6.1738M8 12.0077a4 4 0 1 1 4.008 3.9921A3.9996 3.9996 0 0 1 8 12.0077',
119
- linkedin: 'M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z',
120
- pinterest: 'M12.017 0C5.396 0 .029 5.367.029 11.987c0 5.079 3.158 9.417 7.618 11.162-.105-.949-.199-2.403.041-3.439.219-.937 1.406-5.957 1.406-5.957s-.359-.72-.359-1.781c0-1.663.967-2.911 2.168-2.911 1.024 0 1.518.769 1.518 1.688 0 1.029-.653 2.567-.992 3.992-.285 1.193.6 2.165 1.775 2.165 2.128 0 3.768-2.245 3.768-5.487 0-2.861-2.063-4.869-5.008-4.869-3.41 0-5.409 2.562-5.409 5.199 0 1.033.394 2.143.889 2.741.099.12.112.225.085.345-.09.375-.293 1.199-.334 1.363-.053.225-.172.271-.401.165-1.495-.69-2.433-2.878-2.433-4.646 0-3.776 2.748-7.252 7.92-7.252 4.158 0 7.392 2.967 7.392 6.923 0 4.135-2.607 7.462-6.233 7.462-1.214 0-2.354-.629-2.758-1.379l-.749 2.848c-.269 1.045-1.004 2.352-1.498 3.146 1.123.345 2.306.535 3.55.535 6.607 0 11.985-5.365 11.985-11.987C23.97 5.39 18.592.026 11.985.026L12.017 0z',
121
- reddit: 'M12 0C5.373 0 0 5.373 0 12c0 3.314 1.343 6.314 3.515 8.485l-2.286 2.286C.775 23.225 1.097 24 1.738 24H12c6.627 0 12-5.373 12-12S18.627 0 12 0Zm4.388 3.199c1.104 0 1.999.895 1.999 1.999 0 1.105-.895 2-1.999 2-.946 0-1.739-.657-1.947-1.539v.002c-1.147.162-2.032 1.15-2.032 2.341v.007c1.776.067 3.4.567 4.686 1.363.473-.363 1.064-.58 1.707-.58 1.547 0 2.802 1.254 2.802 2.802 0 1.117-.655 2.081-1.601 2.531-.088 3.256-3.637 5.876-7.997 5.876-4.361 0-7.905-2.617-7.998-5.87-.954-.447-1.614-1.415-1.614-2.538 0-1.548 1.255-2.802 2.803-2.802.645 0 1.239.218 1.712.585 1.275-.79 2.881-1.291 4.64-1.365v-.01c0-1.663 1.263-3.034 2.88-3.207.188-.911.993-1.595 1.959-1.595Zm-8.085 8.376c-.784 0-1.459.78-1.506 1.797-.047 1.016.64 1.429 1.426 1.429.786 0 1.371-.369 1.418-1.385.047-1.017-.553-1.841-1.338-1.841Zm7.406 0c-.786 0-1.385.824-1.338 1.841.047 1.017.634 1.385 1.418 1.385.785 0 1.473-.413 1.426-1.429-.046-1.017-.721-1.797-1.506-1.797Zm-3.703 4.013c-.974 0-1.907.048-2.77.135-.147.015-.241.168-.183.305.483 1.154 1.622 1.964 2.953 1.964 1.33 0 2.47-.81 2.953-1.964.057-.137-.037-.29-.184-.305-.863-.087-1.795-.135-2.769-.135Z',
122
- snapchat: 'M12.206.793c.99 0 4.347.276 5.93 3.821.529 1.193.403 3.219.299 4.847l-.003.06c-.012.18-.022.345-.03.51.075.045.203.09.401.09.3-.016.659-.12 1.033-.301.165-.088.344-.104.464-.104.182 0 .359.029.509.09.45.149.734.479.734.838.015.449-.39.839-1.213 1.168-.089.029-.209.075-.344.119-.45.135-1.139.36-1.333.81-.09.224-.061.524.12.868l.015.015c.06.136 1.526 3.475 4.791 4.014.255.044.435.27.42.509 0 .075-.015.149-.045.225-.24.569-1.273.988-3.146 1.271-.059.091-.12.375-.164.57-.029.179-.074.36-.134.553-.076.271-.27.405-.555.405h-.03c-.135 0-.313-.031-.538-.074-.36-.075-.765-.135-1.273-.135-.3 0-.599.015-.913.074-.6.104-1.123.464-1.723.884-.853.599-1.826 1.288-3.294 1.288-.06 0-.119-.015-.18-.015h-.149c-1.468 0-2.427-.675-3.279-1.288-.599-.42-1.107-.779-1.707-.884-.314-.045-.629-.074-.928-.074-.54 0-.958.089-1.272.149-.211.043-.391.074-.54.074-.374 0-.523-.224-.583-.42-.061-.192-.09-.389-.135-.567-.046-.181-.105-.494-.166-.57-1.918-.222-2.95-.642-3.189-1.226-.031-.063-.052-.15-.055-.225-.015-.243.165-.465.42-.509 3.264-.54 4.73-3.879 4.791-4.02l.016-.029c.18-.345.224-.645.119-.869-.195-.434-.884-.658-1.332-.809-.121-.029-.24-.074-.346-.119-1.107-.435-1.257-.93-1.197-1.273.09-.479.674-.793 1.168-.793.146 0 .27.029.383.074.42.194.789.3 1.104.3.234 0 .384-.06.465-.105l-.046-.569c-.098-1.626-.225-3.651.307-4.837C7.392 1.077 10.739.807 11.727.807l.419-.015h.06z',
123
- spotify: 'M12 0C5.4 0 0 5.4 0 12s5.4 12 12 12 12-5.4 12-12S18.66 0 12 0zm5.521 17.34c-.24.359-.66.48-1.021.24-2.82-1.74-6.36-2.101-10.561-1.141-.418.122-.779-.179-.899-.539-.12-.421.18-.78.54-.9 4.56-1.021 8.52-.6 11.64 1.32.42.18.479.659.301 1.02zm1.44-3.3c-.301.42-.841.6-1.262.3-3.239-1.98-8.159-2.58-11.939-1.38-.479.12-1.02-.12-1.14-.6-.12-.48.12-1.021.6-1.141C9.6 9.9 15 10.561 18.72 12.84c.361.181.54.78.241 1.2zm.12-3.36C15.24 8.4 8.82 8.16 5.16 9.301c-.6.179-1.2-.181-1.38-.721-.18-.601.18-1.2.72-1.381 4.26-1.26 11.28-1.02 15.721 1.621.539.3.719 1.02.419 1.56-.299.421-1.02.599-1.559.3z',
124
- telegram: 'M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z',
125
- threads: 'M12.186 24h-.007c-3.581-.024-6.334-1.205-8.184-3.509C2.35 18.44 1.5 15.586 1.472 12.01v-.017c.03-3.579.879-6.43 2.525-8.482C5.845 1.205 8.6.024 12.18 0h.014c2.746.02 5.043.725 6.826 2.098 1.677 1.29 2.858 3.13 3.509 5.467l-2.04.569c-1.104-3.96-3.898-5.984-8.304-6.015-2.91.022-5.11.936-6.54 2.717C4.307 6.504 3.616 8.914 3.589 12c.027 3.086.718 5.496 2.057 7.164 1.43 1.783 3.631 2.698 6.54 2.717 2.623-.02 4.358-.631 5.8-2.045 1.647-1.613 1.618-3.593 1.09-4.798-.31-.71-.873-1.3-1.634-1.75-.192 1.352-.622 2.446-1.284 3.272-.886 1.102-2.14 1.704-3.73 1.79-1.202.065-2.361-.218-3.259-.801-1.063-.689-1.685-1.74-1.752-2.964-.065-1.19.408-2.285 1.33-3.082.88-.76 2.119-1.207 3.583-1.291a13.853 13.853 0 0 1 3.02.142c-.126-.742-.375-1.332-.75-1.757-.513-.586-1.308-.883-2.359-.89h-.029c-.844 0-1.992.232-2.721 1.32L7.734 7.847c.98-1.454 2.568-2.256 4.478-2.256h.044c3.194.02 5.097 1.975 5.287 5.388.108.046.216.094.321.142 1.49.7 2.58 1.761 3.154 3.07.797 1.82.871 4.79-1.548 7.158-1.85 1.81-4.094 2.628-7.277 2.65Zm1.003-11.69c-.242 0-.487.007-.739.021-1.836.103-2.98.946-2.916 2.143.067 1.256 1.452 1.839 2.784 1.767 1.224-.065 2.818-.543 3.086-3.71a10.5 10.5 0 0 0-2.215-.221z',
126
- tiktok: 'M12.525.02c1.31-.02 2.61-.01 3.91-.02.08 1.53.63 3.09 1.75 4.17 1.12 1.11 2.7 1.62 4.24 1.79v4.03c-1.44-.05-2.89-.35-4.2-.97-.57-.26-1.1-.59-1.62-.93-.01 2.92.01 5.84-.02 8.75-.08 1.4-.54 2.79-1.35 3.94-1.31 1.92-3.58 3.17-5.91 3.21-1.43.08-2.86-.31-4.08-1.03-2.02-1.19-3.44-3.37-3.65-5.71-.02-.5-.03-1-.01-1.49.18-1.9 1.12-3.72 2.58-4.96 1.66-1.44 3.98-2.13 6.15-1.72.02 1.48-.04 2.96-.04 4.44-.99-.32-2.15-.23-3.02.37-.63.41-1.11 1.04-1.36 1.75-.21.51-.15 1.07-.14 1.61.24 1.64 1.82 3.02 3.5 2.87 1.12-.01 2.19-.66 2.77-1.61.19-.33.4-.67.41-1.06.1-1.79.06-3.57.07-5.36.01-4.03-.01-8.05.02-12.07z',
127
- whatsapp: 'M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413Z',
128
- x: 'M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z',
129
- youtube: 'M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z',
130
- };
131
113
 
132
114
  /** One representative brand hex per platform, for the social block's "Brand" palette mode. Flat approximations, not exact brand-guideline swatches. */
133
115
  export const SOCIAL_BRAND = {
@@ -169,26 +151,18 @@ export function icon(name, size) {
169
151
  return svg;
170
152
  }
171
153
 
154
+ /** Social keys whose glyph differs from the same-named UI icon. */
155
+ const SOCIAL_ALIAS = { x: 'xSocial' };
156
+
172
157
  /**
173
- * Social-platform icon: the official filled brand glyph when we have one,
174
- * falling back to the stroke set (mail, globe, link, unknown labels).
175
- * Fill inherits currentColor exactly like the stroke icons, so the social
176
- * block's palette/contrast logic and the export round-trip are unchanged.
158
+ * Social-platform icon. Every glyph resolves into the same in-house stroke
159
+ * set as the rest of the chrome -- geometric marks that identify where a
160
+ * link goes without reproducing anyone's registered logo artwork. Kept as
161
+ * its own entry point because the social key 'x' must not resolve to the
162
+ * UI's close glyph; resolve through brandIcon(), never icon().
177
163
  */
178
164
  export function brandIcon(name, size) {
179
- const d = BRAND_GLYPHS[name];
180
- if (!d) return icon(name, size);
181
- const svg = document.createElementNS(SVG_NS, 'svg');
182
- svg.setAttribute('width', String(size || 18));
183
- svg.setAttribute('height', String(size || 18));
184
- svg.setAttribute('viewBox', '0 0 24 24');
185
- svg.setAttribute('fill', 'currentColor');
186
- svg.style.display = 'block';
187
- svg.style.flex = 'none';
188
- const p = document.createElementNS(SVG_NS, 'path');
189
- p.setAttribute('d', d);
190
- svg.appendChild(p);
191
- return svg;
165
+ return icon(SOCIAL_ALIAS[name] || name, size);
192
166
  }
193
167
 
194
168
  function shapeNode(shape) {
package/src/core/ids.js CHANGED
@@ -1 +1 @@
1
- export const uid = () => Math.random().toString(36).slice(2, 9);
1
+ export const uid = () => Math.random().toString(36).slice(2, 9);