@inkandswitch/patchwork-pkg-base 0.0.102 → 0.0.104

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.
@@ -109,14 +109,27 @@
109
109
  --account-picker-hover: var(--studio-fill-offset-10, #e5e5e5);
110
110
  --account-picker-tooltip-bg: var(--studio-line, black);
111
111
  --account-picker-tooltip-fg: var(--studio-fill, white);
112
+ --account-picker-quick: max(1ms, calc(120ms * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)));
113
+ --account-picker-ease-out: cubic-bezier(0.23, 1, 0.32, 1);
112
114
  }
113
115
  }
114
116
  .account-picker {
115
117
  width: 100%;
116
118
  height: 100%;
117
119
  overflow: auto;
118
- padding: 1.5rem 2rem;
120
+ padding: 1.5rem clamp(1rem, 6%, 2rem);
119
121
  color: var(--account-picker-fg);
122
+ &,
123
+ & *,
124
+ & *::before,
125
+ & *::after {
126
+ box-sizing: border-box;
127
+ }
128
+ & .auth {
129
+ width: 100%;
130
+ max-width: 22rem;
131
+ margin-inline: auto;
132
+ }
120
133
  & .profile-header {
121
134
  position: relative;
122
135
  display: flex;
@@ -213,6 +226,13 @@
213
226
  & .input-row {
214
227
  display: flex;
215
228
  gap: 0.25rem;
229
+ & .input {
230
+ flex: 1;
231
+ min-width: 0;
232
+ }
233
+ & .btn {
234
+ flex-shrink: 0;
235
+ }
216
236
  }
217
237
  & .tabs-list {
218
238
  display: grid;
@@ -236,7 +256,12 @@
236
256
  border: none;
237
257
  background: transparent;
238
258
  color: inherit;
239
- transition: all max(1ms, calc(100ms * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)));
259
+ transition-property:
260
+ background-color,
261
+ color,
262
+ box-shadow;
263
+ transition-duration: var(--account-picker-quick);
264
+ transition-timing-function: ease;
240
265
  &[data-selected] {
241
266
  background: var(--account-picker-bg);
242
267
  color: var(--account-picker-fg);
@@ -255,9 +280,17 @@
255
280
  font-weight: 500;
256
281
  border: none;
257
282
  height: 2rem;
283
+ justify-content: center;
258
284
  padding: 0 0.75rem;
259
- transition: all max(1ms, calc(100ms * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)));
285
+ transition:
286
+ background-color var(--account-picker-quick) ease,
287
+ box-shadow var(--account-picker-quick) ease,
288
+ opacity var(--account-picker-quick) ease,
289
+ transform var(--account-picker-quick) var(--account-picker-ease-out);
260
290
  color: var(--account-picker-fg);
291
+ &:active {
292
+ transform: scale(0.97);
293
+ }
261
294
  &:disabled {
262
295
  pointer-events: none;
263
296
  opacity: 0.3;
@@ -449,14 +482,17 @@
449
482
  border: 0;
450
483
  }
451
484
  & .hint {
485
+ margin: 0;
452
486
  font-size: 0.75rem;
453
487
  color: var(--account-picker-muted);
454
488
  line-height: 1.4;
489
+ text-wrap: pretty;
455
490
  }
456
491
  & .error-text {
457
492
  font-size: 0.75rem;
458
- color: hsl(0 70% 50%);
493
+ color: var(--studio-danger-text, var(--studio-danger, hsl(0 70% 50%)));
459
494
  min-height: 1rem;
495
+ overflow-wrap: anywhere;
460
496
  }
461
497
  & .loading-text {
462
498
  color: var(--account-picker-muted);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/contact/styles.css", "../src/picker/styles.css"],
4
- "sourcesContent": ["@layer package {\n:root,\n:host,\n[theme] {\n --contact-fg: var(--editor-line, black);\n --contact-muted-fg: var(--editor-line-offset-50, #999);\n --contact-border: var(--editor-fill-offset-10, #e5e5e5);\n --contact-fallback-bg: var(--editor-fill-offset-20, #ccc);\n --contact-fallback-fg: var(--editor-line-offset-30, #4d4d4d);\n --contact-family: var(--editor-family-sans, system-ui, sans-serif);\n}\n}\n\n/* Avatar */\n\n.contact-avatar {\n position: relative;\n display: inline-flex;\n flex-shrink: 0;\n overflow: hidden;\n border-radius: 9999px;\n border: var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--contact-border);\n min-width: 2rem;\n min-height: 2rem;\n max-width: 2rem;\n max-height: 2rem;\n height: 100%;\n width: 100%;\n}\n\n.contact-avatar--sm {\n min-width: initial;\n min-height: initial;\n max-width: initial;\n max-height: initial;\n width: 1.5rem;\n height: 1.5rem;\n}\n\n.contact-avatar--lg {\n min-width: initial;\n min-height: initial;\n max-width: initial;\n max-height: initial;\n width: 64px;\n height: 64px;\n}\n\n.contact-avatar--present {\n box-shadow: 0 0 0 2px var(--contact-presence-color, #888);\n}\n\n.contact-avatar-image {\n position: absolute;\n inset: 0;\n z-index: 1;\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.contact-avatar-fallback {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 9999px;\n background: var(--contact-fallback-bg);\n color: var(--contact-fallback-fg);\n}\n\n/* Contact Viewer */\n\n.contact-viewer {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.5rem;\n color: var(--contact-fg);\n}\n\n.contact-viewer-name {\n margin: 0;\n font-size: 1.25rem;\n font-weight: 600;\n}\n\n.contact-viewer-label {\n margin: 0;\n font-size: 0.875rem;\n color: var(--contact-muted-fg);\n}\n\n/* Cursor token (tool id \"contact-cursor\") \u2014 the contact's name on a pill in\n their presence color. Hosts overlay it next to their own cursor primitive,\n so it must not intercept pointer events. The pill background is the user's\n presence color (not a theme surface), so the label uses white ink, which is\n legible across the whole USER_COLOR_PALETTE. */\n\n.contact-cursor-token {\n display: inline-block;\n max-width: 160px;\n padding: 2px 6px;\n border-radius: 4px;\n background: var(--contact-cursor-color, #888);\n color: white;\n font-family: var(--contact-family, system-ui, sans-serif);\n font-size: 11px;\n font-weight: 500;\n line-height: 1.3;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n user-select: none;\n pointer-events: none;\n}\n", "@layer package {\n:root,\n:host,\n[theme] {\n --account-picker-fg: var(--studio-line, black);\n --account-picker-muted: var(--studio-line-offset-50, #999);\n --account-picker-bg: var(--studio-fill, white);\n --account-picker-border: var(--studio-fill-offset-10, #e5e5e5);\n --account-picker-hover: var(--studio-fill-offset-10, #e5e5e5);\n --account-picker-tooltip-bg: var(--studio-line, black);\n --account-picker-tooltip-fg: var(--studio-fill, white);\n}\n}\n\n.account-picker {\n width: 100%;\n height: 100%;\n overflow: auto;\n padding: 1.5rem 2rem;\n color: var(--account-picker-fg);\n\n & .profile-header {\n position: relative;\n display: flex;\n align-items: flex-start;\n gap: 0.75rem;\n margin-bottom: 1.5rem;\n }\n\n & .identity {\n position: relative;\n flex-shrink: 0;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 0.125rem;\n }\n\n & .presence-slot {\n width: 0;\n overflow: visible;\n }\n\n\n & .avatar-button {\n position: relative;\n background: none;\n border: none;\n padding: 0;\n margin-inline-start: 5px;\n border-radius: 50%;\n flex-shrink: 0;\n overflow: hidden;\n width: 56px;\n height: 56px;\n display: block;\n cursor: var(--studio-cursor-pointer, pointer);\n\n &::after {\n content: \"\";\n position: absolute;\n inset: 0;\n border-radius: 50%;\n background: rgb(0 0 0 / 30%);\n opacity: 0;\n transition: opacity max(1ms, calc(100ms * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)));\n }\n\n &:hover::after,\n &:focus-visible::after {\n opacity: 1;\n }\n\n & patchwork-view {\n display: block;\n width: 56px;\n height: 56px;\n overflow: hidden;\n }\n\n & img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n border: none;\n outline: none;\n }\n }\n\n & .input.profile-name-input {\n margin-top: 12px;\n font-size: 1.125rem;\n font-weight: 600;\n border: var(--studio-border-width, 1px) var(--studio-border-style, solid) transparent;\n background: transparent;\n padding: 0.25rem 0.375rem;\n border-radius: 4px;\n height: auto;\n\n &:focus-visible {\n outline: var(--studio-focus-ring, 2px solid var(--account-picker-fg));\n outline-offset: var(--studio-focus-ring-offset, 1px);\n }\n }\n\n & .actions {\n display: flex;\n flex-wrap: wrap;\n gap: 0.375rem;\n margin-bottom: 1rem;\n }\n\n & .section {\n margin-bottom: 0.25rem;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 0.25rem;\n }\n\n & .field-group {\n display: grid;\n width: 100%;\n gap: 0.5rem;\n padding-block: 0.5rem;\n }\n\n & .input-row {\n display: flex;\n gap: 0.25rem;\n }\n\n & .tabs-list {\n display: grid;\n grid-template-columns: 1fr 1fr;\n height: 2rem;\n align-items: center;\n border-radius: 6px;\n background: var(--account-picker-border);\n padding: 2px;\n color: var(--account-picker-muted);\n }\n\n & .tabs-trigger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n padding: 0.25rem 0.5rem;\n font-size: 0.8125rem;\n font-weight: 500;\n cursor: var(--studio-cursor-pointer, pointer);\n border: none;\n background: transparent;\n color: inherit;\n transition: all max(1ms, calc(100ms * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)));\n\n &[data-selected] {\n background: var(--account-picker-bg);\n color: var(--account-picker-fg);\n box-shadow: 0 1px 2px rgb(0 0 0 / 6%);\n }\n }\n\n & .tabs-content {\n margin-top: 0.5rem;\n }\n\n & .btn {\n cursor: var(--studio-cursor-pointer, pointer);\n display: inline-flex;\n align-items: center;\n border-radius: 4px;\n font-size: 0.8125rem;\n font-weight: 500;\n border: none;\n height: 2rem;\n padding: 0 0.75rem;\n transition: all max(1ms, calc(100ms * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)));\n color: var(--account-picker-fg);\n\n &:disabled {\n pointer-events: none;\n opacity: 0.3;\n }\n\n &.default {\n background: var(--account-picker-fg);\n color: var(--account-picker-bg);\n\n &:hover {\n opacity: 0.85;\n }\n }\n\n &.outline,\n &.secondary,\n &.ghost {\n background: var(--account-picker-bg);\n border: var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--account-picker-border);\n box-shadow: 0 1px 2px rgb(0 0 0 / 5%);\n\n &:hover {\n background: var(--studio-chrome-hover-fill, var(--account-picker-hover));\n box-shadow: none;\n }\n }\n }\n\n & .input {\n display: flex;\n height: 2rem;\n width: 100%;\n border-radius: 4px;\n border: var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--account-picker-border);\n background: var(--account-picker-bg);\n padding: 0.375rem 0.5rem;\n font-size: 0.8125rem;\n color: var(--account-picker-fg);\n\n &::placeholder {\n color: var(--account-picker-muted);\n }\n\n &:focus-visible {\n outline: var(--studio-focus-ring, 2px solid var(--account-picker-fg));\n outline-offset: var(--studio-focus-ring-offset, 1px);\n }\n\n &:disabled {\n opacity: var(--studio-disabled-opacity, 0.5);\n }\n\n &.valid {\n border-color: hsl(140 40% 60%);\n }\n }\n\n & .label {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--account-picker-muted);\n }\n\n & .tooltip-trigger {\n cursor: var(--studio-cursor-pointer, pointer);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n height: 2rem;\n width: 2rem;\n border: none;\n background: transparent;\n color: inherit;\n\n &:hover {\n background: var(--studio-chrome-hover-fill, var(--account-picker-hover));\n }\n }\n\n & .tooltip-content {\n z-index: var(--studio-layer-tooltip, 50);\n border-radius: 4px;\n background: var(--account-picker-tooltip-bg);\n padding: 0.25rem 0.5rem;\n font-size: 0.75rem;\n color: var(--account-picker-tooltip-fg);\n }\n\n /* ---- Color picker ---- */\n\n & .presence-cursor {\n display: inline-flex;\n align-items: flex-start;\n background: none;\n border: none;\n padding: 0;\n cursor: var(--studio-cursor-pointer, pointer);\n\n &:hover .presence-nametag {\n opacity: 0.85;\n }\n }\n\n & .presence-cursor-arrow {\n width: 16px;\n height: 24px;\n flex-shrink: 0;\n filter: drop-shadow(0 1px 1px rgb(0 0 0 / 25%));\n }\n\n & .presence-nametag {\n margin-top: 12px;\n margin-inline-start: -3px;\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 0.75rem;\n font-weight: 500;\n line-height: 1.3;\n color: white;\n max-width: 12rem;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n & .color-popup {\n position: absolute;\n top: calc(100% + 6px);\n left: 0;\n padding: 6px;\n background: var(--account-picker-bg);\n border: var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--account-picker-border);\n border-radius: 8px;\n box-shadow: 0 4px 16px rgb(0 0 0 / 12%);\n z-index: var(--studio-layer-dropdown, 30);\n }\n\n & .color-grid {\n display: grid;\n grid-template-columns: repeat(7, 24px);\n gap: 2px;\n }\n\n & .color-swatch {\n width: 24px;\n height: 24px;\n cursor: var(--studio-cursor-pointer, pointer);\n padding: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n border-radius: 3px;\n\n &:hover {\n opacity: 0.75;\n }\n\n &.selected {\n box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.5);\n }\n }\n\n & .color-swatch-custom {\n position: relative;\n overflow: hidden;\n cursor: var(--studio-cursor-pointer, pointer);\n background: conic-gradient(\n hsl(0 70% 55%),\n hsl(60 70% 55%),\n hsl(120 70% 55%),\n hsl(180 70% 55%),\n hsl(240 70% 55%),\n hsl(300 70% 55%),\n hsl(360 70% 55%)\n );\n\n & input {\n position: absolute;\n inset: 0;\n opacity: 0;\n cursor: var(--studio-cursor-pointer, pointer);\n width: 100%;\n height: 100%;\n border: none;\n padding: 0;\n }\n }\n\n & .icon {\n width: 14px;\n height: 14px;\n }\n\n & .icon-inline {\n width: 14px;\n height: 14px;\n margin-inline-end: 0.25rem;\n }\n\n & .icon-check {\n width: 14px;\n height: 14px;\n margin: auto;\n color: white;\n filter: drop-shadow(0 0.5px 1px rgb(0 0 0 / 25%));\n }\n\n & .sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n\n & .hint {\n font-size: 0.75rem;\n color: var(--account-picker-muted);\n line-height: 1.4;\n }\n\n & .error-text {\n font-size: 0.75rem;\n color: hsl(0 70% 50%);\n min-height: 1rem;\n }\n\n & .loading-text {\n color: var(--account-picker-muted);\n }\n\n & .btn.sign-out {\n color: var(--account-picker-muted);\n\n &:hover {\n color: white;\n background: hsl(0 65% 52%);\n }\n }\n\n & .btn.sign-out-confirm {\n background: hsl(0 65% 52%);\n color: white;\n\n &:hover {\n opacity: 0.9;\n }\n }\n\n & .modal-backdrop {\n position: fixed;\n inset: 0;\n background: var(--studio-backdrop, rgb(0 0 0 / 20%));\n backdrop-filter: var(--studio-backdrop-blur, blur(2px));\n z-index: var(--studio-layer-overlay, 100);\n }\n\n & .modal {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n z-index: var(--studio-layer-modal, 101);\n background: var(--account-picker-bg);\n border: var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--account-picker-border);\n border-radius: 8px;\n padding: 1.25rem;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n width: 20rem;\n max-width: 90vw;\n box-shadow: 0 8px 30px rgb(0 0 0 / 10%);\n }\n\n & .cropper-modal {\n width: auto;\n align-items: center;\n }\n\n & .cropper-viewport {\n position: relative;\n width: 260px;\n height: 260px;\n overflow: hidden;\n border-radius: 6px;\n background: var(--account-picker-border);\n cursor: var(--studio-cursor-grab, grab);\n touch-action: none;\n\n &:active {\n cursor: var(--studio-cursor-grabbing, grabbing);\n }\n }\n\n & .cropper-image {\n position: absolute;\n top: 0;\n left: 0;\n transform-origin: 0 0;\n max-width: none;\n user-select: none;\n -webkit-user-drag: none;\n }\n\n & .cropper-mask {\n position: absolute;\n inset: 0;\n border-radius: 50%;\n box-shadow: 0 0 0 9999px rgb(0 0 0 / 45%);\n pointer-events: none;\n }\n\n & .cropper-zoom {\n width: 260px;\n accent-color: var(--account-picker-fg);\n }\n\n & .modal-title {\n font-size: 0.875rem;\n font-weight: 600;\n margin: 0;\n }\n\n & .modal-actions {\n display: flex;\n gap: 0.375rem;\n justify-content: flex-end;\n margin-top: 0.25rem;\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["@layer package {\n:root,\n:host,\n[theme] {\n --contact-fg: var(--editor-line, black);\n --contact-muted-fg: var(--editor-line-offset-50, #999);\n --contact-border: var(--editor-fill-offset-10, #e5e5e5);\n --contact-fallback-bg: var(--editor-fill-offset-20, #ccc);\n --contact-fallback-fg: var(--editor-line-offset-30, #4d4d4d);\n --contact-family: var(--editor-family-sans, system-ui, sans-serif);\n}\n}\n\n/* Avatar */\n\n.contact-avatar {\n position: relative;\n display: inline-flex;\n flex-shrink: 0;\n overflow: hidden;\n border-radius: 9999px;\n border: var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--contact-border);\n min-width: 2rem;\n min-height: 2rem;\n max-width: 2rem;\n max-height: 2rem;\n height: 100%;\n width: 100%;\n}\n\n.contact-avatar--sm {\n min-width: initial;\n min-height: initial;\n max-width: initial;\n max-height: initial;\n width: 1.5rem;\n height: 1.5rem;\n}\n\n.contact-avatar--lg {\n min-width: initial;\n min-height: initial;\n max-width: initial;\n max-height: initial;\n width: 64px;\n height: 64px;\n}\n\n.contact-avatar--present {\n box-shadow: 0 0 0 2px var(--contact-presence-color, #888);\n}\n\n.contact-avatar-image {\n position: absolute;\n inset: 0;\n z-index: 1;\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.contact-avatar-fallback {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 9999px;\n background: var(--contact-fallback-bg);\n color: var(--contact-fallback-fg);\n}\n\n/* Contact Viewer */\n\n.contact-viewer {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.5rem;\n color: var(--contact-fg);\n}\n\n.contact-viewer-name {\n margin: 0;\n font-size: 1.25rem;\n font-weight: 600;\n}\n\n.contact-viewer-label {\n margin: 0;\n font-size: 0.875rem;\n color: var(--contact-muted-fg);\n}\n\n/* Cursor token (tool id \"contact-cursor\") \u2014 the contact's name on a pill in\n their presence color. Hosts overlay it next to their own cursor primitive,\n so it must not intercept pointer events. The pill background is the user's\n presence color (not a theme surface), so the label uses white ink, which is\n legible across the whole USER_COLOR_PALETTE. */\n\n.contact-cursor-token {\n display: inline-block;\n max-width: 160px;\n padding: 2px 6px;\n border-radius: 4px;\n background: var(--contact-cursor-color, #888);\n color: white;\n font-family: var(--contact-family, system-ui, sans-serif);\n font-size: 11px;\n font-weight: 500;\n line-height: 1.3;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n user-select: none;\n pointer-events: none;\n}\n", "@layer package {\n:root,\n:host,\n[theme] {\n --account-picker-fg: var(--studio-line, black);\n --account-picker-muted: var(--studio-line-offset-50, #999);\n --account-picker-bg: var(--studio-fill, white);\n --account-picker-border: var(--studio-fill-offset-10, #e5e5e5);\n --account-picker-hover: var(--studio-fill-offset-10, #e5e5e5);\n --account-picker-tooltip-bg: var(--studio-line, black);\n --account-picker-tooltip-fg: var(--studio-fill, white);\n --account-picker-quick: max(1ms, calc(120ms * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)));\n --account-picker-ease-out: cubic-bezier(0.23, 1, 0.32, 1);\n}\n}\n\n.account-picker {\n width: 100%;\n height: 100%;\n overflow: auto;\n /* narrow containers get a narrower gutter */\n padding: 1.5rem clamp(1rem, 6%, 2rem);\n color: var(--account-picker-fg);\n\n /* width: 100% plus padding must stay inside the container */\n &,\n & *,\n & *::before,\n & *::after {\n box-sizing: border-box;\n }\n\n /* sign up / log in: one readable column, centred when there's room */\n & .auth {\n width: 100%;\n max-width: 22rem;\n margin-inline: auto;\n }\n\n & .profile-header {\n position: relative;\n display: flex;\n align-items: flex-start;\n gap: 0.75rem;\n margin-bottom: 1.5rem;\n }\n\n & .identity {\n position: relative;\n flex-shrink: 0;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 0.125rem;\n }\n\n & .presence-slot {\n width: 0;\n overflow: visible;\n }\n\n\n & .avatar-button {\n position: relative;\n background: none;\n border: none;\n padding: 0;\n margin-inline-start: 5px;\n border-radius: 50%;\n flex-shrink: 0;\n overflow: hidden;\n width: 56px;\n height: 56px;\n display: block;\n cursor: var(--studio-cursor-pointer, pointer);\n\n &::after {\n content: \"\";\n position: absolute;\n inset: 0;\n border-radius: 50%;\n background: rgb(0 0 0 / 30%);\n opacity: 0;\n transition: opacity max(1ms, calc(100ms * var(--studio-motion-scale, 1) * var(--studio-motion-preference, 1)));\n }\n\n &:hover::after,\n &:focus-visible::after {\n opacity: 1;\n }\n\n & patchwork-view {\n display: block;\n width: 56px;\n height: 56px;\n overflow: hidden;\n }\n\n & img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n border: none;\n outline: none;\n }\n }\n\n & .input.profile-name-input {\n margin-top: 12px;\n font-size: 1.125rem;\n font-weight: 600;\n border: var(--studio-border-width, 1px) var(--studio-border-style, solid) transparent;\n background: transparent;\n padding: 0.25rem 0.375rem;\n border-radius: 4px;\n height: auto;\n\n &:focus-visible {\n outline: var(--studio-focus-ring, 2px solid var(--account-picker-fg));\n outline-offset: var(--studio-focus-ring-offset, 1px);\n }\n }\n\n & .actions {\n display: flex;\n flex-wrap: wrap;\n gap: 0.375rem;\n margin-bottom: 1rem;\n }\n\n & .section {\n margin-bottom: 0.25rem;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 0.25rem;\n }\n\n & .field-group {\n display: grid;\n width: 100%;\n gap: 0.5rem;\n padding-block: 0.5rem;\n }\n\n & .input-row {\n display: flex;\n gap: 0.25rem;\n\n /* inputs have an intrinsic width; let them shrink beside the eye button */\n & .input {\n flex: 1;\n min-width: 0;\n }\n\n & .btn {\n flex-shrink: 0;\n }\n }\n\n & .tabs-list {\n display: grid;\n grid-template-columns: 1fr 1fr;\n height: 2rem;\n align-items: center;\n border-radius: 6px;\n background: var(--account-picker-border);\n padding: 2px;\n color: var(--account-picker-muted);\n }\n\n & .tabs-trigger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n padding: 0.25rem 0.5rem;\n font-size: 0.8125rem;\n font-weight: 500;\n cursor: var(--studio-cursor-pointer, pointer);\n border: none;\n background: transparent;\n color: inherit;\n transition-property: background-color, color, box-shadow;\n transition-duration: var(--account-picker-quick);\n transition-timing-function: ease;\n\n &[data-selected] {\n background: var(--account-picker-bg);\n color: var(--account-picker-fg);\n box-shadow: 0 1px 2px rgb(0 0 0 / 6%);\n }\n }\n\n & .tabs-content {\n margin-top: 0.5rem;\n }\n\n & .btn {\n cursor: var(--studio-cursor-pointer, pointer);\n display: inline-flex;\n align-items: center;\n border-radius: 4px;\n font-size: 0.8125rem;\n font-weight: 500;\n border: none;\n height: 2rem;\n justify-content: center;\n padding: 0 0.75rem;\n transition:\n background-color var(--account-picker-quick) ease,\n box-shadow var(--account-picker-quick) ease,\n opacity var(--account-picker-quick) ease,\n transform var(--account-picker-quick) var(--account-picker-ease-out);\n color: var(--account-picker-fg);\n\n /* a small press, so the button feels heard */\n &:active {\n transform: scale(0.97);\n }\n\n &:disabled {\n pointer-events: none;\n opacity: 0.3;\n }\n\n &.default {\n background: var(--account-picker-fg);\n color: var(--account-picker-bg);\n\n &:hover {\n opacity: 0.85;\n }\n }\n\n &.outline,\n &.secondary,\n &.ghost {\n background: var(--account-picker-bg);\n border: var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--account-picker-border);\n box-shadow: 0 1px 2px rgb(0 0 0 / 5%);\n\n &:hover {\n background: var(--studio-chrome-hover-fill, var(--account-picker-hover));\n box-shadow: none;\n }\n }\n }\n\n & .input {\n display: flex;\n height: 2rem;\n width: 100%;\n border-radius: 4px;\n border: var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--account-picker-border);\n background: var(--account-picker-bg);\n padding: 0.375rem 0.5rem;\n font-size: 0.8125rem;\n color: var(--account-picker-fg);\n\n &::placeholder {\n color: var(--account-picker-muted);\n }\n\n &:focus-visible {\n outline: var(--studio-focus-ring, 2px solid var(--account-picker-fg));\n outline-offset: var(--studio-focus-ring-offset, 1px);\n }\n\n &:disabled {\n opacity: var(--studio-disabled-opacity, 0.5);\n }\n\n &.valid {\n border-color: hsl(140 40% 60%);\n }\n }\n\n & .label {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--account-picker-muted);\n }\n\n & .tooltip-trigger {\n cursor: var(--studio-cursor-pointer, pointer);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n height: 2rem;\n width: 2rem;\n border: none;\n background: transparent;\n color: inherit;\n\n &:hover {\n background: var(--studio-chrome-hover-fill, var(--account-picker-hover));\n }\n }\n\n & .tooltip-content {\n z-index: var(--studio-layer-tooltip, 50);\n border-radius: 4px;\n background: var(--account-picker-tooltip-bg);\n padding: 0.25rem 0.5rem;\n font-size: 0.75rem;\n color: var(--account-picker-tooltip-fg);\n }\n\n /* ---- Color picker ---- */\n\n & .presence-cursor {\n display: inline-flex;\n align-items: flex-start;\n background: none;\n border: none;\n padding: 0;\n cursor: var(--studio-cursor-pointer, pointer);\n\n &:hover .presence-nametag {\n opacity: 0.85;\n }\n }\n\n & .presence-cursor-arrow {\n width: 16px;\n height: 24px;\n flex-shrink: 0;\n filter: drop-shadow(0 1px 1px rgb(0 0 0 / 25%));\n }\n\n & .presence-nametag {\n margin-top: 12px;\n margin-inline-start: -3px;\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 0.75rem;\n font-weight: 500;\n line-height: 1.3;\n color: white;\n max-width: 12rem;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n & .color-popup {\n position: absolute;\n top: calc(100% + 6px);\n left: 0;\n padding: 6px;\n background: var(--account-picker-bg);\n border: var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--account-picker-border);\n border-radius: 8px;\n box-shadow: 0 4px 16px rgb(0 0 0 / 12%);\n z-index: var(--studio-layer-dropdown, 30);\n }\n\n & .color-grid {\n display: grid;\n grid-template-columns: repeat(7, 24px);\n gap: 2px;\n }\n\n & .color-swatch {\n width: 24px;\n height: 24px;\n cursor: var(--studio-cursor-pointer, pointer);\n padding: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n border-radius: 3px;\n\n &:hover {\n opacity: 0.75;\n }\n\n &.selected {\n box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.5);\n }\n }\n\n & .color-swatch-custom {\n position: relative;\n overflow: hidden;\n cursor: var(--studio-cursor-pointer, pointer);\n background: conic-gradient(\n hsl(0 70% 55%),\n hsl(60 70% 55%),\n hsl(120 70% 55%),\n hsl(180 70% 55%),\n hsl(240 70% 55%),\n hsl(300 70% 55%),\n hsl(360 70% 55%)\n );\n\n & input {\n position: absolute;\n inset: 0;\n opacity: 0;\n cursor: var(--studio-cursor-pointer, pointer);\n width: 100%;\n height: 100%;\n border: none;\n padding: 0;\n }\n }\n\n & .icon {\n width: 14px;\n height: 14px;\n }\n\n & .icon-inline {\n width: 14px;\n height: 14px;\n margin-inline-end: 0.25rem;\n }\n\n & .icon-check {\n width: 14px;\n height: 14px;\n margin: auto;\n color: white;\n filter: drop-shadow(0 0.5px 1px rgb(0 0 0 / 25%));\n }\n\n & .sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n\n & .hint {\n margin: 0;\n font-size: 0.75rem;\n color: var(--account-picker-muted);\n line-height: 1.4;\n text-wrap: pretty;\n }\n\n & .error-text {\n font-size: 0.75rem;\n color: var(--studio-danger-text, var(--studio-danger, hsl(0 70% 50%)));\n min-height: 1rem;\n overflow-wrap: anywhere;\n }\n\n & .loading-text {\n color: var(--account-picker-muted);\n }\n\n & .btn.sign-out {\n color: var(--account-picker-muted);\n\n &:hover {\n color: white;\n background: hsl(0 65% 52%);\n }\n }\n\n & .btn.sign-out-confirm {\n background: hsl(0 65% 52%);\n color: white;\n\n &:hover {\n opacity: 0.9;\n }\n }\n\n & .modal-backdrop {\n position: fixed;\n inset: 0;\n background: var(--studio-backdrop, rgb(0 0 0 / 20%));\n backdrop-filter: var(--studio-backdrop-blur, blur(2px));\n z-index: var(--studio-layer-overlay, 100);\n }\n\n & .modal {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n z-index: var(--studio-layer-modal, 101);\n background: var(--account-picker-bg);\n border: var(--studio-border-width, 1px) var(--studio-border-style, solid) var(--account-picker-border);\n border-radius: 8px;\n padding: 1.25rem;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n width: 20rem;\n max-width: 90vw;\n box-shadow: 0 8px 30px rgb(0 0 0 / 10%);\n }\n\n & .cropper-modal {\n width: auto;\n align-items: center;\n }\n\n & .cropper-viewport {\n position: relative;\n width: 260px;\n height: 260px;\n overflow: hidden;\n border-radius: 6px;\n background: var(--account-picker-border);\n cursor: var(--studio-cursor-grab, grab);\n touch-action: none;\n\n &:active {\n cursor: var(--studio-cursor-grabbing, grabbing);\n }\n }\n\n & .cropper-image {\n position: absolute;\n top: 0;\n left: 0;\n transform-origin: 0 0;\n max-width: none;\n user-select: none;\n -webkit-user-drag: none;\n }\n\n & .cropper-mask {\n position: absolute;\n inset: 0;\n border-radius: 50%;\n box-shadow: 0 0 0 9999px rgb(0 0 0 / 45%);\n pointer-events: none;\n }\n\n & .cropper-zoom {\n width: 260px;\n accent-color: var(--account-picker-fg);\n }\n\n & .modal-title {\n font-size: 0.875rem;\n font-weight: 600;\n margin: 0;\n }\n\n & .modal-actions {\n display: flex;\n gap: 0.375rem;\n justify-content: flex-end;\n margin-top: 0.25rem;\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -63,7 +63,7 @@ var plugins = [
63
63
  name: "Account Picker",
64
64
  supportedDatatypes: ["account"],
65
65
  async load() {
66
- const { AccountPickerTool } = await import("./AccountPicker-A2PAS5CG.js");
66
+ const { AccountPickerTool } = await import("./AccountPicker-DCX77HQI.js");
67
67
  const { styled } = await import("./styles-KCFZAQMN.js");
68
68
  return styled(AccountPickerTool);
69
69
  }
@@ -41,6 +41,7 @@ const STYLES = `
41
41
  box-sizing: border-box;
42
42
  overflow: hidden;
43
43
  user-select: none;
44
+ outline: none;
44
45
  }
45
46
  .patternwitch * { box-sizing: border-box; }
46
47
 
@@ -319,6 +320,8 @@ const TOOL_CURSORS = Object.fromEntries(
319
320
  export default function PatternWitchTool(handle, element) {
320
321
  const root = document.createElement("div");
321
322
  root.className = "patternwitch";
323
+ // Focusable, so keyboard shortcuts only fire while you're in this tool.
324
+ root.tabIndex = -1;
322
325
  const style = document.createElement("style");
323
326
  style.textContent = STYLES;
324
327
  element.append(style, root);
@@ -327,52 +330,108 @@ export default function PatternWitchTool(handle, element) {
327
330
  let activeColor = 0;
328
331
  let activeTool = "draw"; // "draw" | "fill"
329
332
  let showSettings = false;
330
- const history = []; // stack of pixel snapshots for undo (local)
331
- const HISTORY_MAX = 40;
333
+ const HISTORY_MAX = 200;
332
334
 
333
335
  // ---- helpers ----
334
336
  const getDoc = () => handle.doc();
335
337
  const clamp = (n, lo, hi) => Math.max(lo, Math.min(hi, n));
336
338
  const snapshot = () => getDoc().pixels.map((row) => row.slice());
337
339
 
338
- function pushHistory(pixels = snapshot()) {
339
- history.push(pixels);
340
+ // ============================================================
341
+ // Undo: commands, not snapshots
342
+ // ============================================================
343
+ // An op makes a change to the doc and returns the op that reverses it (or
344
+ // null if it changed nothing). Undoing an op returns the op that redoes it,
345
+ // so the same shape runs both ways.
346
+ //
347
+ // Inverses only touch what this user did, and they check before they write:
348
+ // a cell a peer has painted since is left alone. So undo stays local while
349
+ // someone else is drawing on the same canvas.
350
+ const history = []; // inverse ops, for undo (local)
351
+ const future = []; // inverse-of-inverse ops, for redo (local)
352
+
353
+ function run(op) {
354
+ const inverse = op();
355
+ if (!inverse) return;
356
+ history.push(inverse);
340
357
  if (history.length > HISTORY_MAX) history.shift();
358
+ future.length = 0; // a new edit forks history; the old future is gone
359
+ }
360
+
361
+ function undo() {
362
+ const op = history.pop();
363
+ if (!op) return;
364
+ const redoOp = op();
365
+ if (redoOp) future.push(redoOp);
341
366
  }
342
367
 
343
- // Write a whole grid cell by cell, so concurrent edits from peers merge
344
- // instead of fighting over replaced rows.
345
- function writePixels(next) {
368
+ function redo() {
369
+ const op = future.pop();
370
+ if (!op) return;
371
+ const undoOp = op();
372
+ if (undoOp) history.push(undoOp);
373
+ }
374
+
375
+ // Run several ops as one; the inverse runs their inverses backwards.
376
+ const sequence = (ops) => () => {
377
+ const inverses = ops.map((op) => op()).filter(Boolean).reverse();
378
+ return inverses.length ? sequence(inverses) : null;
379
+ };
380
+
381
+ // Set cells, each [x, y, to, expected?]. With `expected`, a cell is only
382
+ // written if it still holds that value, which is how inverses avoid
383
+ // clobbering peers. Cell by cell, never whole rows: replacing rows makes
384
+ // concurrent edits merge as list insertions, shifting pixels sideways.
385
+ function paintOp(cells) {
386
+ const done = [];
346
387
  handle.change((d) => {
347
- if (d.height !== next.length || d.width !== next[0].length) {
348
- d.height = next.length;
349
- d.width = next[0].length;
350
- d.pixels = next;
351
- return;
388
+ for (const [x, y, to, expected] of cells) {
389
+ if (y >= d.height || x >= d.width) continue;
390
+ const current = d.pixels[y][x];
391
+ if (expected !== undefined && current !== expected) continue;
392
+ if (current === to) continue;
393
+ d.pixels[y][x] = to;
394
+ done.push([x, y, current, to]);
352
395
  }
353
- for (let y = 0; y < d.height; y++)
354
- for (let x = 0; x < d.width; x++)
355
- if (d.pixels[y][x] !== next[y][x]) d.pixels[y][x] = next[y][x];
356
396
  });
397
+ return done.length ? () => paintOp(done) : null;
357
398
  }
358
399
 
359
- // Resize the grid, preserving overlapping pixels.
360
- function resize(newW, newH, record = true) {
400
+ // Every cell where `next` differs from the doc, as paintOp cells.
401
+ function diffCells(next) {
402
+ const { pixels } = getDoc();
403
+ const cells = [];
404
+ for (let y = 0; y < next.length; y++)
405
+ for (let x = 0; x < next[y].length; x++)
406
+ if (pixels[y][x] !== next[y][x]) cells.push([x, y, next[y][x]]);
407
+ return cells;
408
+ }
409
+
410
+ // Resize in place (trim / extend rows and columns) so cells inside both
411
+ // sizes are never rewritten and peers' paint there survives. The inverse
412
+ // resizes back and restores the cropped cells, unless something has since
413
+ // been painted over the blank space they come back into.
414
+ function resizeOp(newW, newH) {
361
415
  newW = clamp(Math.round(newW), MIN_SIZE, MAX_SIZE);
362
416
  newH = clamp(Math.round(newH), MIN_SIZE, MAX_SIZE);
363
- const doc = getDoc();
364
- if (newW === doc.width && newH === doc.height) return;
365
- if (record) pushHistory();
366
- const old = doc.pixels;
367
- const next = makePixels(newW, newH, 0);
368
- for (let y = 0; y < Math.min(newH, doc.height); y++)
369
- for (let x = 0; x < Math.min(newW, doc.width); x++)
370
- next[y][x] = old[y][x];
417
+ const { width: oldW, height: oldH } = getDoc();
418
+ if (newW === oldW && newH === oldH) return null;
419
+ const cropped = [];
371
420
  handle.change((d) => {
421
+ for (let y = 0; y < oldH; y++)
422
+ for (let x = y < newH ? newW : 0; x < oldW; x++)
423
+ if (d.pixels[y][x] !== 0) cropped.push([x, y, d.pixels[y][x], 0]);
424
+ if (oldH > newH) d.pixels.splice(newH, oldH - newH);
425
+ for (let y = 0; y < Math.min(oldH, newH); y++) {
426
+ const row = d.pixels[y];
427
+ if (oldW > newW) row.splice(newW, oldW - newW);
428
+ else if (newW > oldW) row.push(...new Array(newW - oldW).fill(0));
429
+ }
430
+ for (let y = oldH; y < newH; y++) d.pixels.push(new Array(newW).fill(0));
372
431
  d.width = newW;
373
432
  d.height = newH;
374
- d.pixels = next;
375
433
  });
434
+ return sequence([() => resizeOp(oldW, oldH), () => paintOp(cropped)]);
376
435
  }
377
436
 
378
437
  function floodFill(sx, sy, target) {
@@ -380,7 +439,6 @@ export default function PatternWitchTool(handle, element) {
380
439
  const { width, height } = doc;
381
440
  const from = doc.pixels[sy][sx];
382
441
  if (from === target) return;
383
- const before = snapshot();
384
442
  const grid = snapshot();
385
443
  const stack = [[sx, sy]];
386
444
  while (stack.length) {
@@ -390,19 +448,14 @@ export default function PatternWitchTool(handle, element) {
390
448
  grid[y][x] = target;
391
449
  stack.push([x + 1, y], [x - 1, y], [x, y + 1], [x, y - 1]);
392
450
  }
393
- pushHistory(before);
394
- writePixels(grid);
395
- }
396
-
397
- function undo() {
398
- if (!history.length) return;
399
- writePixels(history.pop());
451
+ const cells = diffCells(grid);
452
+ run(() => paintOp(cells));
400
453
  }
401
454
 
402
455
  function clearAll() {
403
- const doc = getDoc();
404
- pushHistory();
405
- writePixels(makePixels(doc.width, doc.height, activeColor));
456
+ const { width, height } = getDoc();
457
+ const cells = diffCells(makePixels(width, height, activeColor));
458
+ run(() => paintOp(cells));
406
459
  }
407
460
 
408
461
  // ============================================================
@@ -411,11 +464,11 @@ export default function PatternWitchTool(handle, element) {
411
464
  root.innerHTML = `
412
465
  <div class="toolbar">
413
466
  <div class="tool-group">
414
- <button class="btn" data-tool="draw" title="Draw">${icon("pencil")}</button>
415
- <button class="btn" data-tool="fill" title="Fill">${icon("fill")}</button>
467
+ <button class="btn" data-tool="draw" title="Brush (B)">${icon("pencil")}</button>
468
+ <button class="btn" data-tool="fill" title="Fill (F)">${icon("fill")}</button>
416
469
  </div>
417
470
  <div class="tool-group">
418
- <button class="btn" data-act="undo" title="Undo">${icon("undo")}</button>
471
+ <button class="btn" data-act="undo" title="Undo (⌘Z)">${icon("undo")}</button>
419
472
  <button class="btn" data-act="clear" data-danger title="Clear all">${icon("trash")}</button>
420
473
  </div>
421
474
  <div class="spacer"></div>
@@ -532,7 +585,6 @@ export default function PatternWitchTool(handle, element) {
532
585
  let painting = false;
533
586
  let strokeCells = null; // Map<"x,y", colour> of pending changes
534
587
  let lastCell = null; // last painted cell in the current stroke
535
- let strokeBefore = null; // pixels as they were when the stroke started
536
588
 
537
589
  function paintCell(x, y) {
538
590
  const k = `${x},${y}`;
@@ -566,21 +618,15 @@ export default function PatternWitchTool(handle, element) {
566
618
  }
567
619
  }
568
620
 
569
- // Commit cell by cell: replacing whole rows makes concurrent edits merge as
570
- // list insertions, which shifts pixels sideways and duplicates them.
571
621
  function commitStroke() {
572
- const cells = strokeCells;
573
- const before = strokeBefore;
622
+ const pending = strokeCells;
574
623
  strokeCells = null;
575
- strokeBefore = null;
576
- if (!cells || cells.size === 0) return;
577
- pushHistory(before);
578
- handle.change((d) => {
579
- for (const [k, color] of cells) {
580
- const [x, y] = k.split(",").map(Number);
581
- if (y < d.height && x < d.width) d.pixels[y][x] = color;
582
- }
624
+ if (!pending || pending.size === 0) return;
625
+ const cells = [...pending].map(([k, color]) => {
626
+ const [x, y] = k.split(",").map(Number);
627
+ return [x, y, color];
583
628
  });
629
+ run(() => paintOp(cells));
584
630
  }
585
631
 
586
632
  canvas.addEventListener("pointerdown", (e) => {
@@ -593,7 +639,6 @@ export default function PatternWitchTool(handle, element) {
593
639
  }
594
640
  painting = true;
595
641
  strokeCells = new Map();
596
- strokeBefore = snapshot();
597
642
  canvas.setPointerCapture(e.pointerId);
598
643
  paintCell(c.x, c.y);
599
644
  lastCell = c;
@@ -622,11 +667,48 @@ export default function PatternWitchTool(handle, element) {
622
667
  // Toolbar / actions
623
668
  // ============================================================
624
669
  root.querySelectorAll("[data-tool]").forEach((el) => {
625
- el.addEventListener("click", () => {
626
- activeTool = el.dataset.tool;
627
- renderToolbar();
628
- });
670
+ el.addEventListener("click", () => setTool(el.dataset.tool));
671
+ });
672
+ function setTool(tool) {
673
+ activeTool = tool;
674
+ renderToolbar();
675
+ }
676
+
677
+ // Shortcuts, scoped to this tool: the listener is on our root, which only
678
+ // sees keys while focus is inside it. Text-ish inputs in the settings modal
679
+ // keep their own keys.
680
+ root.addEventListener("keydown", (e) => {
681
+ if (e.target.closest("input, textarea, select, [contenteditable]")) return;
682
+ const key = e.key.toLowerCase();
683
+ const mod = e.metaKey || e.ctrlKey;
684
+ if (mod && !e.altKey && key === "z") {
685
+ e.preventDefault();
686
+ e.stopPropagation();
687
+ if (e.shiftKey) redo();
688
+ else undo();
689
+ return;
690
+ }
691
+ if (mod || e.altKey || e.shiftKey) return;
692
+ if (key === "b") setTool("draw");
693
+ else if (key === "f") setTool("fill");
694
+ else if (/^[0-9]$/.test(key)) {
695
+ // 1–9 then 0, like the number row: 1 is the first colour, 0 the tenth.
696
+ const i = key === "0" ? 9 : Number(key) - 1;
697
+ if (i >= getDoc().palette.length) return;
698
+ activeColor = i;
699
+ renderPalette();
700
+ } else return;
701
+ e.preventDefault();
702
+ e.stopPropagation();
703
+ });
704
+
705
+ // Clicking anywhere in the tool (including the canvas) takes focus, so the
706
+ // shortcuts work straight after painting.
707
+ root.addEventListener("pointerdown", (e) => {
708
+ if (e.target.closest("input")) return;
709
+ root.focus({ preventScroll: true });
629
710
  });
711
+
630
712
  root.querySelector('[data-act="undo"]').addEventListener("click", undo);
631
713
  root.querySelector('[data-act="clear"]').addEventListener("click", clearAll);
632
714
  root.querySelector('[data-act="settings"]').addEventListener("click", () => {
@@ -647,17 +729,19 @@ export default function PatternWitchTool(handle, element) {
647
729
  const rect = canvas.getBoundingClientRect();
648
730
  const step = Math.max(4, rect.width / doc.width); // px per cell
649
731
  grip.setPointerCapture(e.pointerId);
650
- pushHistory(); // one undo entry for the whole drag
732
+ const steps = []; // each step's inverse; one undo entry for the whole drag
651
733
 
652
734
  const onMove = (ev) => {
653
735
  const dW = Math.round((ev.clientX - startX) / step);
654
736
  const dH = Math.round((ev.clientY - startY) / step);
655
- resize(startW + dW, startH + dH, false);
737
+ const inverse = resizeOp(startW + dW, startH + dH);
738
+ if (inverse) steps.push(inverse);
656
739
  };
657
740
  const onUp = (ev) => {
658
741
  grip.releasePointerCapture(ev.pointerId);
659
742
  grip.removeEventListener("pointermove", onMove);
660
743
  grip.removeEventListener("pointerup", onUp);
744
+ if (steps.length) run(() => sequence(steps.reverse()));
661
745
  };
662
746
  grip.addEventListener("pointermove", onMove);
663
747
  grip.addEventListener("pointerup", onUp);
@@ -744,10 +828,9 @@ export default function PatternWitchTool(handle, element) {
744
828
  });
745
829
 
746
830
  modal.querySelector("[data-apply-size]").addEventListener("click", () => {
747
- resize(
748
- Number(modal.querySelector('[data-dim="w"]').value),
749
- Number(modal.querySelector('[data-dim="h"]').value),
750
- );
831
+ const w = Number(modal.querySelector('[data-dim="w"]').value);
832
+ const h = Number(modal.querySelector('[data-dim="h"]').value);
833
+ run(() => resizeOp(w, h));
751
834
  });
752
835
 
753
836
  modal.querySelector("[data-close]").addEventListener("click", () => {
@@ -759,21 +842,49 @@ export default function PatternWitchTool(handle, element) {
759
842
  modalMount.append(backdrop);
760
843
  }
761
844
 
762
- // Remove a palette colour and remap pixels that referenced it.
763
845
  function removeColor(index) {
764
- pushHistory();
846
+ run(() => removeColorOp(index));
847
+ }
848
+
849
+ // Remove a palette colour and remap pixels that referenced it: its own
850
+ // pixels become colour 0, and higher indices shift down by one.
851
+ function removeColorOp(index) {
852
+ const hex = getDoc().palette[index];
853
+ const orphans = new Set(); // "x,y" of pixels that were this colour
765
854
  handle.change((d) => {
766
855
  d.palette.splice(index, 1);
767
856
  const max = d.palette.length - 1;
768
857
  for (let y = 0; y < d.height; y++)
769
858
  for (let x = 0; x < d.width; x++) {
770
859
  let v = d.pixels[y][x];
771
- if (v === index) v = 0;
772
- else if (v > index) v = v - 1;
860
+ if (v === index) {
861
+ orphans.add(`${x},${y}`);
862
+ v = 0;
863
+ } else if (v > index) v = v - 1;
773
864
  v = clamp(v, 0, max);
774
865
  if (d.pixels[y][x] !== v) d.pixels[y][x] = v;
775
866
  }
776
867
  });
868
+ return () => insertColorOp(index, hex, orphans);
869
+ }
870
+
871
+ // Inverse of removeColorOp. Every index at or above `index` shifts back up,
872
+ // including pixels peers painted in the meantime, since those were painted
873
+ // against the shorter palette. Orphans get their colour back if they're
874
+ // still colour 0; one a peer has repainted keeps the peer's colour.
875
+ function insertColorOp(index, hex, orphans) {
876
+ handle.change((d) => {
877
+ d.palette.splice(index, 0, hex);
878
+ for (let y = 0; y < d.height; y++)
879
+ for (let x = 0; x < d.width; x++) {
880
+ const v = d.pixels[y][x];
881
+ let next = v;
882
+ if (v === 0 && orphans.has(`${x},${y}`)) next = index;
883
+ else if (v >= index) next = v + 1;
884
+ if (next !== v) d.pixels[y][x] = next;
885
+ }
886
+ });
887
+ return () => removeColorOp(index);
777
888
  }
778
889
 
779
890
  // ============================================================
@@ -0,0 +1,2 @@
1
+ import{r as a,s as b}from"./chunk-LVZ6VVQF.js";import"./chunk-FW4363Y4.js";export{a as IsolatedDocumentArea,b as mountIsolationRoot};
2
+ //# sourceMappingURL=IsolatedDocumentArea-LKOLK7UD.js.map