@morgan-and-morgan/intake-agent 1.0.0-alpha.17 → 1.0.0-alpha.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -55,7 +55,8 @@ check sees the intended setting.
55
55
  ## Consultation prompt design
56
56
 
57
57
  The responsive prompt follows the [desktop and mobile Figma layouts](https://www.figma.com/design/0SxWl42gdhx08KFe2ldpd8/MM-Design-System-v4.0?node-id=21250-169311).
58
- Portrait, avatar, status dots, and icons are exported from those layers.
58
+ The portrait and avatar use cropped, optimized original photos; CSS applies the Figma framing.
59
+ Status dots and icons are exported from their layers.
59
60
  The fonts are the existing website's [Kuunari Bold Compressed](https://www.forthepeople.com/themes/custom/morgan/fonts/Kuunari/kuunari-bold-compressed.woff2)
60
61
  and [Nunito Sans](https://www.forthepeople.com/themes/custom/morgan/fonts/NunitoSans/NunitoSans.woff2).
61
62
  On forthepeople.com, the prompt loads these fonts from the host site to respect
@@ -63,5 +64,6 @@ its font security policy. Other hosts use the bundled copies.
63
64
  Keep prompt assets in `public/` and `apps/expo/public/intake-widget/` identical;
64
65
  the asset tests check both the CDN and portal copies.
65
66
 
66
- Retain `consultation-prompt.webp` at both asset origins for older deployed widget
67
- versions. The redesigned prompt does not request it.
67
+ Retain `consultation-prompt.webp`, `consultation-team.png`, and
68
+ `consultation-john-morgan.png` at both asset origins for older deployed widget
69
+ versions. The current prompt requests the separate WebP photos instead.
Binary file
@@ -311,12 +311,16 @@
311
311
  return dispose;
312
312
  };
313
313
  const PROMPT_STYLES = [
314
+ // Initial dialog focus announces the popup without drawing a ring around its backdrop.
315
+ ".mm-prompt-backdrop:focus{outline:none}",
314
316
  `.mm-prompt-backdrop{--mm-prompt-blue:${designSystemColors["primary-800"]};--mm-prompt-dark:${designSystemColors["primary-900"]};--mm-prompt-yellow:${designSystemColors["secondary-500"]};--mm-prompt-yellow-end:${designSystemColors["secondary-700"]};--mm-prompt-text:${designSystemColors["primary-100"]};position:fixed;inset:0;z-index:2147483002;display:flex;flex-direction:column;align-items:center;padding:12px;overflow-y:auto;overscroll-behavior:contain;touch-action:pan-y pinch-zoom;background:rgba(0,0,0,.5);animation:mm-prompt-backdrop-in .25s cubic-bezier(.23,1,.32,1) both;font-family:"MMIntakeNunitoSans",var(--mm-font);font-variation-settings:"YTLC" 500,"wdth" 100;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}`,
315
317
  // Auto margins center the card when it fits and keep its top reachable when it overflows.
316
318
  ".mm-prompt-card{position:relative;isolation:isolate;display:flex;flex:none;flex-direction:column;margin-block:auto;width:600px;max-width:100%;padding:16px 16px 32px;border-radius:16px;background:var(--mm-prompt-blue);color:var(--mm-white);box-shadow:0 4px 5px rgba(0,0,0,.1),0 7px 10px rgba(0,0,0,.07),0 2px 16px rgba(0,0,0,.08);animation:mm-prompt-card-in .25s cubic-bezier(.23,1,.32,1) both}",
317
319
  ".mm-prompt-status{position:relative;z-index:1;display:flex;align-items:center;gap:13px;align-self:flex-start;max-width:calc(100% - 52px);padding:8px 40px 8px 8px;border-radius:999px;background:var(--mm-prompt-dark);color:var(--mm-prompt-text)}",
318
320
  ".mm-prompt-avatar{position:relative;flex:none;width:56px;height:56px}",
319
- ".mm-prompt-team{display:block;width:100%;height:100%;border-radius:50%}",
321
+ // Crop the original at (310, 234, 454, 454), then preserve Figma's avatar framing in CSS.
322
+ ".mm-prompt-team-crop{position:absolute;inset:0;overflow:hidden;border-radius:50%;transform:scaleX(-1)}",
323
+ ".mm-prompt-team{position:absolute;display:block;left:-3.26787%;top:-0.29881%;width:103.65294%;height:103.65298%;max-width:none;transform:rotate(-1.62035deg);transform-origin:0 0}",
320
324
  // The exported indicator bounds include Figma's 2px outside stroke.
321
325
  ".mm-prompt-online{position:absolute;right:-2px;top:40.17px;display:block;line-height:0}",
322
326
  ".mm-prompt-online img{display:block}",
@@ -326,8 +330,9 @@
326
330
  '.mm-prompt-title{position:relative;z-index:1;flex:1;min-width:0;height:232px;display:flex;flex-direction:column;justify-content:flex-end;margin:0;font-family:"MMIntakeKuunari",Impact,sans-serif;font-size:72px;font-weight:700;line-height:64px;letter-spacing:-2px;text-transform:uppercase}',
327
331
  ".mm-prompt-title-line{display:block;white-space:nowrap}",
328
332
  ".mm-prompt-mobile-break{display:none}",
329
- ".mm-prompt-portrait{position:relative;flex:none;width:270px;height:304px}",
330
- ".mm-prompt-image{display:block;width:100%;height:100%;pointer-events:none}",
333
+ // Figma node 21250:169707 crops the transparent source without baking in the card background.
334
+ ".mm-prompt-portrait{position:relative;flex:none;width:270px;height:304px;overflow:hidden}",
335
+ ".mm-prompt-image{position:absolute;display:block;left:-40.22%;top:-3.95%;width:181.72%;height:107.91%;max-width:none;pointer-events:none}",
331
336
  `.mm-prompt-cta{position:relative;display:flex;align-items:center;justify-content:center;gap:16px;height:56px;margin:0 16px;border-radius:8px;background:linear-gradient(to bottom,var(--mm-prompt-yellow) 41.827%,var(--mm-prompt-yellow-end));box-shadow:0 2px 4px rgba(0,0,0,.05),0 4px 3px rgba(0,0,0,.04),0 1px 2px rgba(0,0,0,.03);color:${designSystemColors["base-black"]};font-size:20px;font-weight:700;line-height:24px}`,
332
337
  ".mm-prompt-cta-label{min-width:90px}",
333
338
  // Preserve the Figma text frames in the SVG exports so centering retains their alignment.
@@ -347,11 +352,11 @@
347
352
  const promptMarkup = (assetUrl) => [
348
353
  '<div class="mm-prompt-card">',
349
354
  '<div class="mm-prompt-status"><span class="mm-prompt-avatar" aria-hidden="true">',
350
- `<img loading="lazy" class="mm-prompt-team" src="${assetUrl("consultation-team.png")}" alt="" width="56" height="56" decoding="async" />`,
355
+ `<span class="mm-prompt-team-crop"><img loading="lazy" class="mm-prompt-team" src="${assetUrl("consultation-team.webp")}" alt="" width="360" height="360" decoding="async" /></span>`,
351
356
  `<picture class="mm-prompt-online"><source media="(max-width:623px)" srcset="${assetUrl("consultation-online-mobile.svg")}" /><img loading="lazy" src="${assetUrl("consultation-online-desktop.svg")}" alt="" /></picture>`,
352
357
  '</span><p class="mm-prompt-status-text">Our team is <br class="mm-prompt-mobile-break" />available 24/7</p></div>',
353
358
  '<div class="mm-prompt-hero"><h2 class="mm-prompt-title"><span class="mm-prompt-title-line">Click <br class="mm-prompt-mobile-break" />to start</span><span class="mm-prompt-title-line">your free</span><span class="mm-prompt-title-line">consultation</span></h2>',
354
- `<div class="mm-prompt-portrait" aria-hidden="true"><img loading="lazy" class="mm-prompt-image" src="${assetUrl("consultation-john-morgan.png")}" alt="" width="270" height="304" decoding="async" /></div></div>`,
359
+ `<div class="mm-prompt-portrait" aria-hidden="true"><img loading="lazy" class="mm-prompt-image" src="${assetUrl("consultation-john-morgan.webp")}" alt="" width="1500" height="1000" decoding="async" /></div></div>`,
355
360
  `<span class="mm-prompt-cta" aria-hidden="true"><img loading="lazy" class="mm-prompt-chat-icon" src="${assetUrl("consultation-chat.svg")}" alt="" width="24" height="29" /><span class="mm-prompt-cta-label">Chat now</span></span>`,
356
361
  '<button class="mm-prompt-open" type="button" aria-label="Chat now about a free consultation"></button>',
357
362
  `<button class="mm-prompt-close" type="button" aria-label="Dismiss consultation prompt"><img class="mm-prompt-close-icon" src="${assetUrl("consultation-close.svg")}" alt="" width="18" height="29" /><span class="mm-prompt-close-contrast" aria-hidden="true">×</span></button>`,
@@ -425,7 +430,7 @@
425
430
  '<section class="mm-chat" role="dialog" aria-label="Morgan and Morgan intake chat" inert hidden>',
426
431
  '<div class="mm-frame-wrap"><div class="mm-loading" role="status" aria-label="Loading secure chat"><span class="mm-dot"></span><span class="mm-dot"></span><span class="mm-dot"></span></div><iframe class="mm-frame mm-chat-frame" title="Morgan and Morgan intake chat" referrerpolicy="strict-origin-when-cross-origin"></iframe></div>',
427
432
  "</section>",
428
- '<section class="mm-prompt-backdrop" role="dialog" aria-modal="true" aria-label="Start your free consultation" inert hidden>',
433
+ '<section class="mm-prompt-backdrop" role="dialog" aria-modal="true" aria-label="Start your free consultation" tabindex="-1" inert hidden>',
429
434
  promptMarkup(assetUrl),
430
435
  "</section>"
431
436
  ].join("");
@@ -599,7 +604,7 @@
599
604
  promptReturnFocus = document.activeElement instanceof HTMLElement && document.activeElement !== mount ? document.activeElement : null;
600
605
  elements.promptBackdrop.hidden = false;
601
606
  elements.promptBackdrop.removeAttribute("inert");
602
- elements.promptClose.focus();
607
+ elements.promptBackdrop.focus({ preventScroll: true });
603
608
  };
604
609
  const syncViewport = () => {
605
610
  const viewport = globalThis.visualViewport;
@@ -804,14 +809,9 @@
804
809
  };
805
810
  const handleKeydown = (event) => {
806
811
  if (event.key === "Tab" && elements.promptBackdrop.hidden === false) {
807
- const { activeElement } = shadow;
808
- if (!event.shiftKey && activeElement === elements.promptClose) {
809
- event.preventDefault();
810
- elements.promptOpen.focus();
811
- } else if (event.shiftKey && activeElement === elements.promptOpen) {
812
- event.preventDefault();
813
- elements.promptClose.focus();
814
- }
812
+ event.preventDefault();
813
+ const next = shadow.activeElement === elements.promptClose ? elements.promptOpen : elements.promptClose;
814
+ next.focus();
815
815
  return;
816
816
  }
817
817
  if (event.key !== "Escape") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@morgan-and-morgan/intake-agent",
3
- "version": "1.0.0-alpha.17",
3
+ "version": "1.0.0-alpha.18",
4
4
  "description": "Embeddable chat widget loader.",
5
5
  "license": "UNLICENSED",
6
6
  "files": [
@@ -34,6 +34,6 @@
34
34
  "@typescript/native-preview": "catalog:",
35
35
  "lucide-react-native": "^0.562.0",
36
36
  "typescript": "~5.9.3",
37
- "vite": "^7.3.6"
37
+ "vite": "^7.3.7"
38
38
  }
39
39
  }