@pinecall/dot 0.11.23 → 0.11.25

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 (124) hide show
  1. package/README.md +145 -63
  2. package/dist/agent/index.d.ts +3 -2
  3. package/dist/agent/index.d.ts.map +1 -1
  4. package/dist/agent/index.js +2 -1
  5. package/dist/agent/index.js.map +1 -1
  6. package/dist/agent/tutor.d.ts +12 -10
  7. package/dist/agent/tutor.d.ts.map +1 -1
  8. package/dist/agent/tutor.js +81 -68
  9. package/dist/agent/tutor.js.map +1 -1
  10. package/dist/agent/walks.d.ts +19 -0
  11. package/dist/agent/walks.d.ts.map +1 -0
  12. package/dist/agent/walks.js +89 -0
  13. package/dist/agent/walks.js.map +1 -0
  14. package/dist/page/page.d.ts +2 -2
  15. package/dist/page/page.d.ts.map +1 -1
  16. package/dist/page/page.js +5 -5
  17. package/dist/page/page.js.map +1 -1
  18. package/dist/page/roles.d.ts +2 -0
  19. package/dist/page/roles.d.ts.map +1 -1
  20. package/dist/page/roles.js +21 -2
  21. package/dist/page/roles.js.map +1 -1
  22. package/dist/pointer/asking.d.ts +25 -0
  23. package/dist/pointer/asking.d.ts.map +1 -0
  24. package/dist/pointer/asking.js +82 -0
  25. package/dist/pointer/asking.js.map +1 -0
  26. package/dist/pointer/flight.d.ts +40 -4
  27. package/dist/pointer/flight.d.ts.map +1 -1
  28. package/dist/pointer/flight.js +139 -17
  29. package/dist/pointer/flight.js.map +1 -1
  30. package/dist/pointer/frames.d.ts +28 -0
  31. package/dist/pointer/frames.d.ts.map +1 -0
  32. package/dist/pointer/frames.js +66 -0
  33. package/dist/pointer/frames.js.map +1 -0
  34. package/dist/pointer/icons.d.ts +8 -0
  35. package/dist/pointer/icons.d.ts.map +1 -0
  36. package/dist/pointer/icons.js +15 -0
  37. package/dist/pointer/icons.js.map +1 -0
  38. package/dist/pointer/menu.d.ts +5 -4
  39. package/dist/pointer/menu.d.ts.map +1 -1
  40. package/dist/pointer/menu.js +56 -47
  41. package/dist/pointer/menu.js.map +1 -1
  42. package/dist/pointer/person.d.ts +13 -2
  43. package/dist/pointer/person.d.ts.map +1 -1
  44. package/dist/pointer/person.js +47 -41
  45. package/dist/pointer/person.js.map +1 -1
  46. package/dist/pointer/pressing.d.ts +6 -0
  47. package/dist/pointer/pressing.d.ts.map +1 -0
  48. package/dist/pointer/pressing.js +32 -0
  49. package/dist/pointer/pressing.js.map +1 -0
  50. package/dist/pointer/sections.d.ts +4 -7
  51. package/dist/pointer/sections.d.ts.map +1 -1
  52. package/dist/pointer/sections.js +11 -17
  53. package/dist/pointer/sections.js.map +1 -1
  54. package/dist/pointer/typing.d.ts +5 -3
  55. package/dist/pointer/typing.d.ts.map +1 -1
  56. package/dist/pointer/typing.js +46 -15
  57. package/dist/pointer/typing.js.map +1 -1
  58. package/dist/server/index.d.ts +34 -0
  59. package/dist/server/index.d.ts.map +1 -0
  60. package/dist/server/index.js +108 -0
  61. package/dist/server/index.js.map +1 -0
  62. package/dist/server/questions.d.ts +30 -0
  63. package/dist/server/questions.d.ts.map +1 -0
  64. package/dist/server/questions.js +136 -0
  65. package/dist/server/questions.js.map +1 -0
  66. package/dist/server/saying.d.ts +31 -0
  67. package/dist/server/saying.d.ts.map +1 -0
  68. package/dist/server/saying.js +124 -0
  69. package/dist/server/saying.js.map +1 -0
  70. package/dist/tutor/acting.d.ts +42 -0
  71. package/dist/tutor/acting.d.ts.map +1 -0
  72. package/dist/tutor/acting.js +180 -0
  73. package/dist/tutor/acting.js.map +1 -0
  74. package/dist/tutor/aloud.d.ts +50 -0
  75. package/dist/tutor/aloud.d.ts.map +1 -0
  76. package/dist/tutor/aloud.js +288 -0
  77. package/dist/tutor/aloud.js.map +1 -0
  78. package/dist/tutor/ask.d.ts +49 -0
  79. package/dist/tutor/ask.d.ts.map +1 -0
  80. package/dist/tutor/ask.js +47 -0
  81. package/dist/tutor/ask.js.map +1 -0
  82. package/dist/tutor/listening.d.ts +17 -0
  83. package/dist/tutor/listening.d.ts.map +1 -0
  84. package/dist/tutor/listening.js +66 -0
  85. package/dist/tutor/listening.js.map +1 -0
  86. package/dist/tutor/options.d.ts +37 -1
  87. package/dist/tutor/options.d.ts.map +1 -1
  88. package/dist/tutor/options.js +1 -1
  89. package/dist/tutor/options.js.map +1 -1
  90. package/dist/tutor/reading.d.ts +58 -0
  91. package/dist/tutor/reading.d.ts.map +1 -0
  92. package/dist/tutor/reading.js +193 -0
  93. package/dist/tutor/reading.js.map +1 -0
  94. package/dist/tutor/text.d.ts +16 -0
  95. package/dist/tutor/text.d.ts.map +1 -0
  96. package/dist/tutor/text.js +119 -0
  97. package/dist/tutor/text.js.map +1 -0
  98. package/dist/tutor/tutor.d.ts +2 -9
  99. package/dist/tutor/tutor.d.ts.map +1 -1
  100. package/dist/tutor/tutor.js +110 -87
  101. package/dist/tutor/tutor.js.map +1 -1
  102. package/dist/tutor/walking.d.ts +26 -8
  103. package/dist/tutor/walking.d.ts.map +1 -1
  104. package/dist/tutor/walking.js +145 -30
  105. package/dist/tutor/walking.js.map +1 -1
  106. package/dist/tutor/walks.d.ts +33 -0
  107. package/dist/tutor/walks.d.ts.map +1 -1
  108. package/dist/tutor/walks.js +121 -13
  109. package/dist/tutor/walks.js.map +1 -1
  110. package/dist/wire/acts.d.ts +60 -0
  111. package/dist/wire/acts.d.ts.map +1 -0
  112. package/dist/wire/acts.js +120 -0
  113. package/dist/wire/acts.js.map +1 -0
  114. package/dist/wire/ask.d.ts +132 -0
  115. package/dist/wire/ask.d.ts.map +1 -0
  116. package/dist/wire/ask.js +102 -0
  117. package/dist/wire/ask.js.map +1 -0
  118. package/dist/wire/index.d.ts +38 -8
  119. package/dist/wire/index.d.ts.map +1 -1
  120. package/dist/wire/index.js +86 -12
  121. package/dist/wire/index.js.map +1 -1
  122. package/docs/macros.md +216 -0
  123. package/docs/write-a-tutor.md +247 -0
  124. package/package.json +11 -6
@@ -0,0 +1,15 @@
1
+ /** The person's drawings: its pointer (arrow, hand, I-beam) and the icons of the corner's buttons. */
2
+ // Captions: lines of words in a frame, struck through while off. Pause: two bars, a triangle while held. Stop: a square.
3
+ export const CAPTIONS = (size) => `<svg viewBox="0 0 24 24" width="${size}" height="${size}" aria-hidden="true"><rect x="3" y="5.5" width="18" height="13" rx="3"/><path d="M7 10.5h4M13.5 10.5h3.5M7 14h6.5M16 14h1"/><path class="pc-off" d="M4 4l16 16"/></svg>`;
4
+ export const PAUSE = `<svg viewBox="0 0 24 24" width="12" height="12" aria-hidden="true"><path class="pc-hold" d="M8.5 6v12M15.5 6v12" stroke-width="3"/><path class="pc-go" d="M8 5.5v13l10-6.5Z"/></svg>`;
5
+ export const STOP = `<svg viewBox="0 0 24 24" width="10" height="10" aria-hidden="true"><rect x="5" y="5" width="14" height="14" rx="2.5"/></svg>`;
6
+ // The arrow is the screen recorder's (~/ss/screen-demo/build.mjs), in the face's colour; the hand and the I-beam are drawn to match.
7
+ export const ARROW = `<svg class="pc-arrow" viewBox="0 0 26 26" data-kind="arrow" aria-hidden="true">
8
+ <path class="pc-kind-arrow" d="M3 2 L3 21 L8 16.5 L11.4 24 L14.6 22.6 L11.3 15.3 L18 15.3 Z" fill="var(--pc-face, #1f6b55)" stroke="#fff" stroke-width="1.6" stroke-linejoin="round"/>
9
+ <path class="pc-kind-hand" d="M8 3.5c0-1.1 1.8-1.1 1.8 0V11h.6V9.2c0-1.1 1.8-1.1 1.8 0V11h.6V9.8c0-1.1 1.8-1.1 1.8 0V11.4h.6v-.8c0-1.1 1.8-1.1 1.8 0V16c0 3.6-2.2 6.5-5.6 6.5-2.5 0-3.8-1.2-5-3.2l-2.6-4.4c-.6-1 .7-2 1.6-1.2L8 15.4Z" fill="var(--pc-face, #1f6b55)" stroke="#fff" stroke-width="1.4" stroke-linejoin="round"/>
10
+ <path class="pc-kind-ibeam" d="M9 3h5M9 23h5M11.5 3v20" fill="none" stroke="var(--pc-face, #1f6b55)" stroke-width="2.4" stroke-linecap="round"/>
11
+ </svg>`;
12
+ // Back and next: a bar and a triangle toward it, a sentence before or after.
13
+ export const BACK = `<svg viewBox="0 0 24 24" width="11" height="11" aria-hidden="true"><path d="M6.5 6v12" stroke-width="2.6"/><path d="M18 6.5v11L9 12Z" fill="currentColor" stroke="none"/></svg>`;
14
+ export const NEXT = `<svg viewBox="0 0 24 24" width="11" height="11" aria-hidden="true"><path d="M17.5 6v12" stroke-width="2.6"/><path d="M6 6.5v11l9-5.5Z" fill="currentColor" stroke="none"/></svg>`;
15
+ //# sourceMappingURL=icons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icons.js","sourceRoot":"","sources":["../../src/pointer/icons.ts"],"names":[],"mappings":"AAAA,sGAAsG;AAEtG,yHAAyH;AACzH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAU,EAAE,CAC/C,mCAAmC,IAAI,aAAa,IAAI,yKAAyK,CAAC;AACpO,MAAM,CAAC,MAAM,KAAK,GAAG,sLAAsL,CAAC;AAC5M,MAAM,CAAC,MAAM,IAAI,GAAG,8HAA8H,CAAC;AAEnJ,qIAAqI;AACrI,MAAM,CAAC,MAAM,KAAK,GAAG;;;;OAId,CAAC;AAER,6EAA6E;AAC7E,MAAM,CAAC,MAAM,IAAI,GAAG,iLAAiL,CAAC;AACtM,MAAM,CAAC,MAAM,IAAI,GAAG,kLAAkL,CAAC"}
@@ -1,4 +1,5 @@
1
1
  /** The walks a visitor may play with no call: a small button beside the resting face, its pills fanned in an arc round it. */
2
+ import type { Asking } from "./asking.js";
2
3
  import type { Point } from "./flight.js";
3
4
  /** One walk as its pill shows it. */
4
5
  export interface MenuItem {
@@ -16,11 +17,13 @@ export interface MenuOptions {
16
17
  };
17
18
  /** A walk picked, by its place in the list. */
18
19
  onPick: (index: number) => void;
20
+ /** The place in the list of the walk of the section the visitor is on, or -1 when none is. */
21
+ current: () => number;
19
22
  /** What the button that shows the next pills is called for a screen reader: "More walks". */
20
23
  more: string;
24
+ /** The field for what the visitor wants shown, above the pills while the menu is open; the menu then opens with no walks too. */
25
+ ask?: Asking | undefined;
21
26
  }
22
- /** How long a walk offered alone stays beside the face, in ms. */
23
- export declare const OFFERED_MS = 5000;
24
27
  /** How many pills show at once; the rest come a page at a time, from a small button under them. */
25
28
  export declare const PAGE = 4;
26
29
  /** How far apart two pills stand, in px: a pill's height and a gap of 6, so no two ever overlap. */
@@ -38,8 +41,6 @@ export declare class Menu {
38
41
  offer(items: MenuItem[]): void;
39
42
  /** Whether the button may show now: not during a call, nor while a walk plays. */
40
43
  available(on: boolean): void;
41
- /** Offer one walk alone, beside the face, for `ms`, while the button shows and the pills are folded. */
42
- suggest(index: number, ms?: number): void;
43
44
  /** Fan the pills out, or fold them back. */
44
45
  toggle(open: boolean): void;
45
46
  get open(): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../src/pointer/menu.ts"],"names":[],"mappings":"AAAA,8HAA8H;AAS9H,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AA6BzC,qCAAqC;AACrC,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,IAAI,EAAE,MAAM;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,+CAA+C;IAC/C,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,6FAA6F;IAC7F,IAAI,EAAE,MAAM,CAAC;CACd;AAED,kEAAkE;AAClE,eAAO,MAAM,UAAU,OAAO,CAAC;AAE/B,mGAAmG;AACnG,eAAO,MAAM,IAAI,IAAI,CAAC;AAEtB,oGAAoG;AACpG,eAAO,MAAM,IAAI,QAAW,CAAC;AAM7B;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,EAAE,CAOhG;AAED,qBAAa,IAAI;;IAwBf,YAAY,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,EAAE,OAAO,EAAE,WAAW,EAiCrF;IAED,iDAAiD;IACjD,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,CAsB7B;IAED,kFAAkF;IAClF,SAAS,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAI3B;IAED,wGAAwG;IACxG,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,SAAa,GAAG,IAAI,CAQ5C;IAED,4CAA4C;IAC5C,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAO1B;IAwBD,IAAI,IAAI,IAAI,OAAO,CAElB;IA8CD,KAAK,IAAI,IAAI,CASZ;CACF"}
1
+ {"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../src/pointer/menu.ts"],"names":[],"mappings":"AAAA,8HAA8H;AAS9H,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAgCzC,qCAAqC;AACrC,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,IAAI,EAAE,MAAM;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,+CAA+C;IAC/C,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,8FAA8F;IAC9F,OAAO,EAAE,MAAM,MAAM,CAAC;IACtB,6FAA6F;IAC7F,IAAI,EAAE,MAAM,CAAC;IACb,iIAAiI;IACjI,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B;AAED,mGAAmG;AACnG,eAAO,MAAM,IAAI,IAAI,CAAC;AAEtB,oGAAoG;AACpG,eAAO,MAAM,IAAI,QAAW,CAAC;AAM7B;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,EAAE,CAOhG;AAED,qBAAa,IAAI;;IAmCf,YAAY,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,EAAE,OAAO,EAAE,WAAW,EAsCrF;IAED,iDAAiD;IACjD,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,CAsB7B;IAED,kFAAkF;IAClF,SAAS,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAI3B;IAED,4CAA4C;IAC5C,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAW1B;IA8BD,IAAI,IAAI,IAAI,OAAO,CAElB;IAoCD,KAAK,IAAI,IAAI,CASZ;CACF"}
@@ -3,8 +3,8 @@
3
3
  // The button sits on the face's shoulder, toward the page, in front of the face: behind it, a click
4
4
  // meant for it reached the face and began a call. A click fans the walks out beside the
5
5
  // face, each a pill with its title and length, read from the top: the first walk is the highest. Escape, a click elsewhere or
6
- // a pick closes them. One walk can also be offered alone, beside the face, for a few seconds: the one
7
- // of the section scrolled to. Every colour is the person's: --pc-face, --pc-bubble, --pc-bubble-ink.
6
+ // a pick closes them. The walk of the section the visitor is on is marked, and the page it stands on is the
7
+ // one that opens. Every colour is the person's: --pc-face, --pc-bubble, --pc-bubble-ink.
8
8
  import { clock } from "../wire/index.js";
9
9
  /** A pill's height, in px. */
10
10
  const PILL = 24;
@@ -20,6 +20,9 @@ const STYLE = `
20
20
  font: 500 12px/${PILL}px system-ui, -apple-system, "Segoe UI", sans-serif; white-space: nowrap; box-shadow: 0 4px 14px rgb(0 0 0 / .16);
21
21
  opacity: 0; transform: scale(.85); transition: opacity .18s, transform .18s; }
22
22
  .pc-pill.pc-shown { opacity: 1; transform: none; }
23
+ .pc-pill.pc-here { background: var(--pc-face, #1f6b55); color: #fff; box-shadow: 0 0 0 3px color-mix(in srgb, var(--pc-face, #1f6b55) 30%, transparent), 0 4px 14px rgb(0 0 0 / .2); }
24
+ .pc-pill.pc-here .pc-tri { border-left-color: #fff; }
25
+ .pc-pill.pc-here .pc-long { opacity: .8; }
23
26
  .pc-pill .pc-tri { width: 0; height: 0; border-style: solid; border-width: 4px 0 4px 6px; border-color: transparent transparent transparent var(--pc-face, #1f6b55); }
24
27
  .pc-pill .pc-long { opacity: .55; font-variant-numeric: tabular-nums; }
25
28
  .pc-more { position: fixed; z-index: 3; display: grid; place-items: center; width: ${PILL}px; height: ${PILL}px; padding: 0; border: 0;
@@ -31,8 +34,6 @@ const STYLE = `
31
34
  .pc-more:focus-visible { outline: 2px solid var(--pc-face-ring, #44a785); outline-offset: 2px; }
32
35
  @media (prefers-reduced-motion: reduce) { .pc-pill, .pc-walks, .pc-more svg { transition: none; } }
33
36
  `;
34
- /** How long a walk offered alone stays beside the face, in ms. */
35
- export const OFFERED_MS = 5000;
36
37
  /** How many pills show at once; the rest come a page at a time, from a small button under them. */
37
38
  export const PAGE = 4;
38
39
  /** How far apart two pills stand, in px: a pill's height and a gap of 6, so no two ever overlap. */
@@ -64,11 +65,10 @@ export class Menu {
64
65
  #open = false;
65
66
  /** Which page of pills shows, from 0. */
66
67
  #page = 0;
67
- /** The walk offered alone, by its place in the list, and when it goes. */
68
- #alone = null;
69
68
  #outside = (event) => {
70
69
  const target = event.target instanceof Node ? event.target : null;
71
- if (target !== null && [this.#button, this.#more, ...this.#pills].some((part) => part.contains(target)))
70
+ const parts = [this.#button, this.#more, ...this.#pills, ...(this.#options.ask ? [this.#options.ask.element] : [])];
71
+ if (target !== null && parts.some((part) => part.contains(target)))
72
72
  return;
73
73
  this.toggle(false);
74
74
  };
@@ -78,6 +78,21 @@ export class Menu {
78
78
  };
79
79
  // The face rests in a corner of the window, so a resize moves it, and the button and pills with it.
80
80
  #resized = () => this.#place();
81
+ /** The walk marked now, by its place in the list; -1 for none. */
82
+ #here = -1;
83
+ // While the menu is open the mark follows the page: when the visitor scrolls into another section its walk is
84
+ // marked, and its page shown; a visitor paging within one section is left where they are.
85
+ #scrolled = () => {
86
+ if (!this.#open)
87
+ return;
88
+ const here = this.#options.current();
89
+ if (here === this.#here)
90
+ return;
91
+ this.#mark(here);
92
+ if (here >= 0)
93
+ this.#page = Math.floor(here / PAGE);
94
+ this.#show();
95
+ };
81
96
  constructor(document, host, options) {
82
97
  this.#document = document;
83
98
  this.#options = options;
@@ -92,7 +107,13 @@ export class Menu {
92
107
  this.#button.setAttribute("aria-label", options.label);
93
108
  this.#button.setAttribute("aria-expanded", "false");
94
109
  this.#button.title = options.label;
95
- this.#button.addEventListener("click", () => this.toggle(!this.#open));
110
+ // A single walk and nothing to type: the button plays it, with no menu to open first.
111
+ this.#button.addEventListener("click", () => {
112
+ if (this.#pills.length === 1 && this.#options.ask === undefined)
113
+ this.#options.onPick(0);
114
+ else
115
+ this.toggle(!this.#open);
116
+ });
96
117
  host(this.#button);
97
118
  this.#more = document.createElement("button");
98
119
  this.#more.type = "button";
@@ -111,10 +132,10 @@ export class Menu {
111
132
  document.addEventListener("pointerdown", this.#outside, true);
112
133
  document.addEventListener("keydown", this.#escape);
113
134
  document.defaultView?.addEventListener("resize", this.#resized);
135
+ document.defaultView?.addEventListener("scroll", this.#scrolled, { passive: true });
114
136
  }
115
137
  /** The walks to offer; none hides the button. */
116
138
  offer(items) {
117
- this.#unsuggest();
118
139
  for (const pill of this.#pills)
119
140
  pill.remove();
120
141
  this.#pills = items.map((item, index) => {
@@ -126,7 +147,8 @@ export class Menu {
126
147
  tri.className = "pc-tri";
127
148
  const long = this.#document.createElement("span");
128
149
  long.className = "pc-long";
129
- long.textContent = clock(item.ms);
150
+ // A walk whose length is not known before it plays (a page read aloud) shows none.
151
+ long.textContent = item.ms > 0 ? clock(item.ms) : "";
130
152
  pill.append(tri, this.#document.createTextNode(item.title), long);
131
153
  pill.addEventListener("click", () => {
132
154
  this.toggle(false);
@@ -135,37 +157,36 @@ export class Menu {
135
157
  this.#host(pill);
136
158
  return pill;
137
159
  });
138
- this.#button.hidden = items.length === 0;
160
+ this.#button.hidden = items.length === 0 && this.#options.ask === undefined;
139
161
  }
140
162
  /** Whether the button may show now: not during a call, nor while a walk plays. */
141
163
  available(on) {
142
- this.#button.hidden = !on || this.#pills.length === 0;
164
+ this.#button.hidden = !on || (this.#pills.length === 0 && this.#options.ask === undefined);
143
165
  if (!on)
144
166
  this.toggle(false);
145
167
  if (on)
146
168
  this.#place();
147
169
  }
148
- /** Offer one walk alone, beside the face, for `ms`, while the button shows and the pills are folded. */
149
- suggest(index, ms = OFFERED_MS) {
150
- const pill = this.#pills[index];
151
- if (pill === undefined || this.#open || this.#button.hidden)
152
- return;
153
- this.#unsuggest();
154
- this.#alone = { index, timer: setTimeout(() => this.#unsuggest(), ms) };
155
- this.#place();
156
- pill.hidden = false;
157
- setTimeout(() => pill.classList.add("pc-shown"), 30);
158
- }
159
170
  /** Fan the pills out, or fold them back. */
160
171
  toggle(open) {
161
- this.#unsuggest();
162
172
  this.#open = open && !this.#button.hidden;
163
- this.#page = 0;
173
+ // It opens on the page of the walk of the section the visitor is on, and marks it.
174
+ const here = this.#open ? this.#options.current() : -1;
175
+ this.#page = here < 0 ? 0 : Math.floor(here / PAGE);
176
+ this.#mark(here);
164
177
  this.#button.setAttribute("aria-expanded", String(this.#open));
165
178
  this.#show();
166
- if (this.#open)
179
+ if (!this.#open)
180
+ return;
181
+ if (this.#options.ask)
182
+ this.#options.ask.focus();
183
+ else
167
184
  this.#shown()[0]?.focus();
168
185
  }
186
+ #mark(here) {
187
+ this.#here = here;
188
+ this.#pills.forEach((pill, index) => pill.classList.toggle("pc-here", index === here));
189
+ }
169
190
  /** The pills of the page showing, while the pills are fanned out. */
170
191
  #shown() {
171
192
  return this.#open ? this.#pills.slice(this.#page * PAGE, (this.#page + 1) * PAGE) : [];
@@ -185,6 +206,7 @@ export class Menu {
185
206
  setTimeout(() => pill.classList.add("pc-shown"), 30 * index);
186
207
  });
187
208
  this.#more.hidden = !this.#open || this.#pills.length <= PAGE;
209
+ this.#options.ask?.show(this.#open);
188
210
  this.#more.classList.toggle("pc-last", (this.#page + 1) * PAGE >= this.#pills.length);
189
211
  }
190
212
  get open() {
@@ -212,36 +234,23 @@ export class Menu {
212
234
  const paged = this.#pills.length > PAGE;
213
235
  const slots = fanned(shown.length + (paged ? 1 : 0), at, radius, this.#options.dock);
214
236
  shown.forEach((pill, index) => stand(pill, slots[slots.length - 1 - index] ?? at));
237
+ // The field stands above the highest pill, or beside the face when there is none.
238
+ const [beside] = fanned(1, at, radius, this.#options.dock);
239
+ const highest = slots[slots.length - 1] ?? beside;
240
+ if (this.#options.ask && highest !== undefined) {
241
+ const bottom = (view?.innerHeight ?? 0) - highest.y + (slots.length > 0 ? PILL / 2 + 8 : -PILL / 2);
242
+ this.#options.ask.place(bottom, right ? (view?.innerWidth ?? 0) - highest.x : highest.x, right);
243
+ }
215
244
  const [under] = slots;
216
245
  if (paged && under !== undefined) {
217
246
  Object.assign(this.#more.style, { left: `${right ? under.x - PILL : under.x}px`, top: `${under.y - PILL / 2}px` });
218
247
  }
219
- // A walk offered alone stands where the lowest pill would, beside the face.
220
- const [beside] = fanned(1, at, radius, this.#options.dock);
221
- if (this.#alone !== null && beside !== undefined)
222
- stand(this.#pills[this.#alone.index], beside);
223
- }
224
- #unsuggest() {
225
- if (this.#alone === null)
226
- return;
227
- clearTimeout(this.#alone.timer);
228
- const { index } = this.#alone;
229
- const pill = this.#pills[index];
230
- this.#alone = null;
231
- if (pill === undefined || this.#open)
232
- return;
233
- pill.classList.remove("pc-shown");
234
- // Hidden once it has faded, unless it was offered again or the pills fanned out meanwhile.
235
- setTimeout(() => {
236
- if (!this.#open && this.#alone?.index !== index)
237
- pill.hidden = true;
238
- }, 200);
239
248
  }
240
249
  close() {
241
- this.#unsuggest();
242
250
  this.#document.removeEventListener("pointerdown", this.#outside, true);
243
251
  this.#document.removeEventListener("keydown", this.#escape);
244
252
  this.#document.defaultView?.removeEventListener("resize", this.#resized);
253
+ this.#document.defaultView?.removeEventListener("scroll", this.#scrolled);
245
254
  this.#button.remove();
246
255
  this.#more.remove();
247
256
  for (const pill of this.#pills)
@@ -1 +1 @@
1
- {"version":3,"file":"menu.js","sourceRoot":"","sources":["../../src/pointer/menu.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"menu.js","sourceRoot":"","sources":["../../src/pointer/menu.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,8 @@ export interface Side {
6
6
  west: boolean;
7
7
  up: boolean;
8
8
  }
9
+ /** Whether the face and its words on `side` of the tip stay on a screen `width` by `height`. */
10
+ export declare function fitsOn(tip: Point, side: Side, width: number, height: number): boolean;
9
11
  /** The first side whose reach fits the screen and covers nothing of `avoid`; else the first that fits; else below and right. */
10
12
  export declare function sideOf(tip: Point, avoid: DOMRect | null, width: number, height: number): Side;
11
13
  export interface PersonOptions {
@@ -32,6 +34,15 @@ export interface PersonOptions {
32
34
  label: string;
33
35
  onClick: () => void;
34
36
  };
37
+ /** The buttons that take a walk a sentence back, and on to the next. */
38
+ back: {
39
+ label: string;
40
+ onClick: () => void;
41
+ };
42
+ next: {
43
+ label: string;
44
+ onClick: () => void;
45
+ };
35
46
  /** The captions button, when the site lets the visitor choose: its name, and its click. */
36
47
  captions: {
37
48
  label: string;
@@ -66,8 +77,8 @@ export declare class Person {
66
77
  /** What the visitor is saying, in the corner; null hides it. */
67
78
  heard(text: string | null): void;
68
79
  /**
69
- * The corner's buttons: captions and hang-up while a call is on, captions, pause and stop while a
70
- * walk plays; captions pressed while they show, pause while the walk is held. Called every frame, so
80
+ * The corner's buttons: captions and hang-up while a call is on, back, pause, next, stop and captions
81
+ * while a walk plays; captions pressed while they show, pause while the walk is held. Called every frame, so
71
82
  * it writes only what changed.
72
83
  */
73
84
  buttons(call: boolean, walk: boolean, captioned: boolean, paused?: boolean): void;
@@ -1 +1 @@
1
- {"version":3,"file":"person.d.ts","sourceRoot":"","sources":["../../src/pointer/person.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"person.d.ts","sourceRoot":"","sources":["../../src/pointer/person.ts"],"names":[],"mappings":"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"}
@@ -5,9 +5,10 @@
5
5
  // the way a multiplayer cursor carries a name tag. The spotlight and the "here" ring live there too,
6
6
  // and, in the corner it rests in, what the visitor is saying and the buttons: captions, with hang-up
7
7
  // in a call and stop in a walk. They stand beside the resting face, and slide into its corner while
8
- // it tours, back aside as it comes home. Every colour is a custom property: --pc-face
9
- // (the dot and the arrow), --pc-face-ring, --pc-bubble, --pc-bubble-ink, --pc-heard, --pc-heard-ink,
10
- // --pc-hang.
8
+ // it tours, back aside as it comes home. Every colour is a custom property: --pc-face (the dot and
9
+ // the arrow), --pc-face-ring, --pc-bubble, --pc-bubble-ink, --pc-heard, --pc-heard-ink, --pc-hang.
10
+ import { ARROW, BACK, CAPTIONS, NEXT, PAUSE, STOP } from "./icons.js";
11
+ import { boxOf } from "./frames.js";
11
12
  /** The resting face's size, in px, and how far its edge stands from the corner of the window. */
12
13
  const SIZE = 58;
13
14
  const EDGE = 14;
@@ -36,6 +37,7 @@ const STYLE = `
36
37
  .pc-bubble .pc-coming { opacity: .38; }
37
38
  .pc-person.pc-touring .pc-bubble { right: auto; bottom: auto; left: 62px; top: 14px; border-radius: 4px 16px 16px 16px; transform-origin: top left; }
38
39
  .pc-person.pc-touring.pc-west .pc-face { left: -54px; }
40
+ .pc-person.pc-touring.pc-west .pc-arrow { left: -23px; transform: scaleX(-1); }
39
41
  .pc-person.pc-touring.pc-west .pc-progress { left: -60px; }
40
42
  .pc-person.pc-touring.pc-west .pc-bubble { left: auto; right: 62px; border-radius: 16px 4px 16px 16px; transform-origin: top right; }
41
43
  .pc-person.pc-touring.pc-up .pc-face { top: -56px; }
@@ -47,13 +49,15 @@ const STYLE = `
47
49
  background: var(--pc-heard, #e7f3ee); color: var(--pc-heard-ink, #17201c); border-radius: 16px 16px 4px 16px;
48
50
  font: 14px/1.45 system-ui, -apple-system, "Segoe UI", sans-serif; box-shadow: 0 10px 28px rgb(0 0 0 / .12); transition: opacity .2s; }
49
51
  .pc-heard[hidden] { display: block !important; opacity: 0; }
50
- .pc-calling { position: fixed; right: calc(${EDGE}px + var(--pc-dot-size, ${SIZE}px) + 8px); bottom: calc(${EDGE}px + var(--pc-dot-size, ${SIZE}px) / 2 - 17px); display: flex; gap: 8px; pointer-events: auto; transition: right .35s cubic-bezier(.2,.8,.2,1), left .35s cubic-bezier(.2,.8,.2,1); }
52
+ .pc-calling { position: fixed; right: calc(${EDGE}px + var(--pc-dot-size, ${SIZE}px) + 8px); bottom: calc(${EDGE}px + var(--pc-dot-size, ${SIZE}px) / 2 - 16px); display: flex; gap: 2px; padding: 3px;
53
+ border-radius: 999px; background: var(--pc-bubble, #fff); box-shadow: 0 4px 14px rgb(0 0 0 / .18); pointer-events: auto; transition: right .35s cubic-bezier(.2,.8,.2,1), left .35s cubic-bezier(.2,.8,.2,1); }
51
54
  .pc-layer.pc-away .pc-calling { right: ${EDGE}px; }
52
55
  .pc-calling[hidden] { display: none; }
53
- .pc-calling button { all: unset; box-sizing: border-box; height: 34px; min-width: 34px; padding: 0 10px; border-radius: 999px; cursor: pointer;
54
- font: 600 12px/34px system-ui, -apple-system, "Segoe UI", sans-serif; text-align: center; box-shadow: 0 4px 12px rgb(0 0 0 / .18); }
56
+ .pc-calling button { all: unset; box-sizing: border-box; height: 26px; min-width: 26px; padding: 0 8px; border-radius: 999px; cursor: pointer;
57
+ font: 600 11px/26px system-ui, -apple-system, "Segoe UI", sans-serif; text-align: center; color: var(--pc-bubble-ink, #17201c); }
58
+ .pc-calling button:hover { background: color-mix(in srgb, var(--pc-bubble-ink, #17201c) 9%, transparent); }
55
59
  .pc-calling button:focus-visible { outline: 2px solid var(--pc-face-ring, #44a785); outline-offset: 2px; }
56
- .pc-calling .pc-cc, .pc-calling .pc-pause, .pc-calling .pc-stop { display: grid; place-items: center; padding: 0; background: var(--pc-bubble, #fff); color: var(--pc-bubble-ink, #17201c); }
60
+ .pc-calling .pc-cc, .pc-calling .pc-pause, .pc-calling .pc-stop, .pc-calling .pc-back, .pc-calling .pc-next { display: grid; place-items: center; padding: 0; }
57
61
  .pc-calling svg { display: block; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
58
62
  .pc-calling .pc-stop svg { fill: currentColor; stroke: none; }
59
63
  .pc-pause .pc-go { display: none; fill: currentColor; stroke: none; }
@@ -63,7 +67,7 @@ const STYLE = `
63
67
  .pc-cc[aria-pressed="false"] { opacity: .6; }
64
68
  .pc-cc[aria-pressed="false"] .pc-off { display: inline; }
65
69
  .pc-calling button[hidden] { display: none; }
66
- .pc-calling .pc-hang { background: var(--pc-hang, #d6453d); color: #fff; font-size: 16px; }
70
+ .pc-calling .pc-hang, .pc-calling .pc-hang:hover { background: var(--pc-hang, #d6453d); color: #fff; font-size: 13px; }
67
71
  .pc-play { position: fixed; width: 26px; height: 26px; border-radius: 50%; pointer-events: auto; cursor: pointer; border: 0; padding: 0;
68
72
  background: var(--pc-face, #1f6b55); color: #fff; font: 11px/26px system-ui, sans-serif; text-align: center; box-shadow: 0 3px 10px rgb(0 0 0 / .25); }
69
73
  .pc-play[hidden] { display: none; }
@@ -74,20 +78,10 @@ const STYLE = `
74
78
  .pc-spot { position: fixed; border-radius: 16px; box-shadow: 0 0 0 9999px rgb(10 18 16 / .34), 0 0 0 3px var(--pc-face-ring, #44a785); opacity: 0; transition: opacity .3s; }
75
79
  .pc-spot.pc-on { opacity: 1; }
76
80
  .pc-ring { position: fixed; width: 18px; height: 18px; margin: -9px 0 0 -9px; border-radius: 50%; border: 2px solid var(--pc-face-ring, #44a785); opacity: 0; }
77
- .pc-ring.pc-go { animation: pc-ring 1.1s ease-out 2; }
81
+ .pc-ring.pc-go { animation: pc-ring 1.1s ease-out 1; }
78
82
  @keyframes pc-ring { 0% { transform: scale(.6); opacity: .9; } 100% { transform: scale(3.2); opacity: 0; } }
79
83
  @media (prefers-reduced-motion: reduce) { .pc-face, .pc-bubble, .pc-heard, .pc-spot { transition: none; } .pc-ring.pc-go { animation: none; opacity: .9; } }
80
84
  `;
81
- // Captions: lines of words in a frame, struck through while off. Pause: two bars, a triangle while held. Stop: a square.
82
- const CAPTIONS = (size) => `<svg viewBox="0 0 24 24" width="${size}" height="${size}" aria-hidden="true"><rect x="3" y="5.5" width="18" height="13" rx="3"/><path d="M7 10.5h4M13.5 10.5h3.5M7 14h6.5M16 14h1"/><path class="pc-off" d="M4 4l16 16"/></svg>`;
83
- const PAUSE = `<svg viewBox="0 0 24 24" width="12" height="12" aria-hidden="true"><path class="pc-hold" d="M8.5 6v12M15.5 6v12" stroke-width="3"/><path class="pc-go" d="M8 5.5v13l10-6.5Z"/></svg>`;
84
- const STOP = `<svg viewBox="0 0 24 24" width="10" height="10" aria-hidden="true"><rect x="5" y="5" width="14" height="14" rx="2.5"/></svg>`;
85
- // The arrow is the screen recorder's (~/ss/screen-demo/build.mjs), in the face's colour; the hand and the I-beam are drawn to match.
86
- const ARROW = `<svg class="pc-arrow" viewBox="0 0 26 26" data-kind="arrow" aria-hidden="true">
87
- <path class="pc-kind-arrow" d="M3 2 L3 21 L8 16.5 L11.4 24 L14.6 22.6 L11.3 15.3 L18 15.3 Z" fill="var(--pc-face, #1f6b55)" stroke="#fff" stroke-width="1.6" stroke-linejoin="round"/>
88
- <path class="pc-kind-hand" d="M8 3.5c0-1.1 1.8-1.1 1.8 0V11h.6V9.2c0-1.1 1.8-1.1 1.8 0V11h.6V9.8c0-1.1 1.8-1.1 1.8 0V11.4h.6v-.8c0-1.1 1.8-1.1 1.8 0V16c0 3.6-2.2 6.5-5.6 6.5-2.5 0-3.8-1.2-5-3.2l-2.6-4.4c-.6-1 .7-2 1.6-1.2L8 15.4Z" fill="var(--pc-face, #1f6b55)" stroke="#fff" stroke-width="1.4" stroke-linejoin="round"/>
89
- <path class="pc-kind-ibeam" d="M9 3h5M9 23h5M11.5 3v20" fill="none" stroke="var(--pc-face, #1f6b55)" stroke-width="2.4" stroke-linecap="round"/>
90
- </svg>`;
91
85
  /** How far the face and its words reach from the tip, across and down, in px; above, they end this far over it. */
92
86
  const REACH = { across: 340, down: 96, over: 14 };
93
87
  /** How much of the box being explained the face may touch: the tip stands in its first line. */
@@ -98,18 +92,24 @@ const SIDES = [
98
92
  { west: false, up: true },
99
93
  { west: true, up: true },
100
94
  ];
101
- /** The first side whose reach fits the screen and covers nothing of `avoid`; else the first that fits; else below and right. */
102
- export function sideOf(tip, avoid, width, height) {
103
- const reach = (side) => ({
95
+ /** The box the face and its words take on `side` of the tip. */
96
+ function reachOf(tip, side) {
97
+ return {
104
98
  left: side.west ? tip.x - REACH.across : tip.x + 8,
105
99
  right: side.west ? tip.x - 8 : tip.x + REACH.across,
106
100
  top: side.up ? tip.y - REACH.down : tip.y + 8,
107
101
  bottom: side.up ? tip.y - REACH.over : tip.y + REACH.down,
108
- });
109
- const fits = (side) => {
110
- const box = reach(side);
111
- return box.left >= 0 && box.right <= width && box.top >= 0 && box.bottom <= height;
112
102
  };
103
+ }
104
+ /** Whether the face and its words on `side` of the tip stay on a screen `width` by `height`. */
105
+ export function fitsOn(tip, side, width, height) {
106
+ const box = reachOf(tip, side);
107
+ return box.left >= 0 && box.right <= width && box.top >= 0 && box.bottom <= height;
108
+ }
109
+ /** The first side whose reach fits the screen and covers nothing of `avoid`; else the first that fits; else below and right. */
110
+ export function sideOf(tip, avoid, width, height) {
111
+ const reach = (side) => reachOf(tip, side);
112
+ const fits = (side) => fitsOn(tip, side, width, height);
113
113
  const clear = (side) => {
114
114
  const box = reach(side);
115
115
  if (avoid === null)
@@ -132,6 +132,8 @@ export class Person {
132
132
  #cc;
133
133
  #stop;
134
134
  #pause;
135
+ #back;
136
+ #next;
135
137
  #hang;
136
138
  #play;
137
139
  #offered = null;
@@ -151,7 +153,7 @@ export class Person {
151
153
  this.#layer.dataset["pinecallSkip"] = "";
152
154
  if (options.color !== undefined)
153
155
  this.#layer.style.setProperty("--pc-face", options.color);
154
- this.#layer.innerHTML = `<div class="pc-spot"></div><div class="pc-ring"></div><div class="pc-person">${ARROW}<svg class="pc-progress" viewBox="0 0 100 100" hidden aria-hidden="true"><circle cx="50" cy="50" r="47" pathLength="100" stroke-dasharray="0 100"></circle></svg><div class="pc-face" role="button" tabindex="0"></div><div class="pc-bubble" role="status" hidden></div></div><div class="pc-heard" role="status" hidden></div><div class="pc-calling" hidden><button type="button" class="pc-cc" aria-pressed="true">${CAPTIONS(17)}</button><button type="button" class="pc-pause" aria-pressed="false" hidden>${PAUSE}</button><button type="button" class="pc-stop" hidden>${STOP}</button><button type="button" class="pc-hang">✕</button></div><button type="button" class="pc-play" hidden>▶</button>`;
156
+ this.#layer.innerHTML = `<div class="pc-spot"></div><div class="pc-ring"></div><div class="pc-person">${ARROW}<svg class="pc-progress" viewBox="0 0 100 100" hidden aria-hidden="true"><circle cx="50" cy="50" r="47" pathLength="100" stroke-dasharray="0 100"></circle></svg><div class="pc-face" role="button" tabindex="0"></div><div class="pc-bubble" role="status" hidden></div></div><div class="pc-heard" role="status" hidden></div><div class="pc-calling" hidden><button type="button" class="pc-back" hidden>${BACK}</button><button type="button" class="pc-pause" aria-pressed="false" hidden>${PAUSE}</button><button type="button" class="pc-next" hidden>${NEXT}</button><button type="button" class="pc-stop" hidden>${STOP}</button><button type="button" class="pc-cc" aria-pressed="true">${CAPTIONS(15)}</button><button type="button" class="pc-hang">✕</button></div><button type="button" class="pc-play" hidden>▶</button>`;
155
157
  this.#spot = this.#part(".pc-spot");
156
158
  this.#ring = this.#part(".pc-ring");
157
159
  this.#person = this.#part(".pc-person");
@@ -161,14 +163,10 @@ export class Person {
161
163
  this.#heard = this.#part(".pc-heard");
162
164
  this.#calling = this.#part(".pc-calling");
163
165
  this.#cc = this.#part(".pc-cc");
164
- this.#stop = this.#part(".pc-stop");
165
- this.#stop.setAttribute("aria-label", options.stop.label);
166
- this.#stop.title = options.stop.label;
167
- this.#stop.addEventListener("click", options.stop.onClick);
168
- this.#pause = this.#part(".pc-pause");
169
- this.#pause.setAttribute("aria-label", options.pause.label);
170
- this.#pause.title = options.pause.label;
171
- this.#pause.addEventListener("click", options.pause.onClick);
166
+ this.#stop = this.#button(".pc-stop", options.stop);
167
+ this.#pause = this.#button(".pc-pause", options.pause);
168
+ this.#back = this.#button(".pc-back", options.back);
169
+ this.#next = this.#button(".pc-next", options.next);
172
170
  this.#play = this.#part(".pc-play");
173
171
  this.#play.setAttribute("aria-label", options.explain.label);
174
172
  this.#play.title = options.explain.label;
@@ -261,8 +259,8 @@ export class Person {
261
259
  this.#heard.textContent = text;
262
260
  }
263
261
  /**
264
- * The corner's buttons: captions and hang-up while a call is on, captions, pause and stop while a
265
- * walk plays; captions pressed while they show, pause while the walk is held. Called every frame, so
262
+ * The corner's buttons: captions and hang-up while a call is on, back, pause, next, stop and captions
263
+ * while a walk plays; captions pressed while they show, pause while the walk is held. Called every frame, so
266
264
  * it writes only what changed.
267
265
  */
268
266
  buttons(call, walk, captioned, paused = false) {
@@ -272,8 +270,8 @@ export class Person {
272
270
  };
273
271
  show(this.#calling, call || walk);
274
272
  show(this.#hang, call);
275
- show(this.#stop, walk && !call);
276
- show(this.#pause, walk && !call);
273
+ for (const one of [this.#back, this.#pause, this.#next, this.#stop])
274
+ show(one, walk && !call);
277
275
  const press = (element, on) => {
278
276
  if (element.getAttribute("aria-pressed") !== String(on))
279
277
  element.setAttribute("aria-pressed", String(on));
@@ -287,7 +285,7 @@ export class Person {
287
285
  this.#play.hidden = element === null;
288
286
  if (element === null)
289
287
  return;
290
- const box = element.getBoundingClientRect();
288
+ const box = boxOf(element);
291
289
  const width = this.#document.defaultView?.innerWidth ?? 0;
292
290
  this.#play.style.left = `${Math.min(box.right - 34, width - 40).toFixed(0)}px`;
293
291
  this.#play.style.top = `${Math.max(box.top + 8, 8).toFixed(0)}px`;
@@ -297,7 +295,7 @@ export class Person {
297
295
  this.#spot.classList.toggle("pc-on", element !== null);
298
296
  if (element === null)
299
297
  return;
300
- const box = element.getBoundingClientRect();
298
+ const box = boxOf(element);
301
299
  const pad = 8;
302
300
  const radius = Number.parseFloat(this.#document.defaultView?.getComputedStyle(element).borderRadius ?? "") || 10;
303
301
  Object.assign(this.#spot.style, {
@@ -339,6 +337,14 @@ export class Person {
339
337
  this.#layer.remove();
340
338
  this.#style.remove();
341
339
  }
340
+ /** A button of the corner, named and wired. */
341
+ #button(selector, action) {
342
+ const button = this.#part(selector);
343
+ button.setAttribute("aria-label", action.label);
344
+ button.title = action.label;
345
+ button.addEventListener("click", action.onClick);
346
+ return button;
347
+ }
342
348
  #part(selector) {
343
349
  const found = this.#layer.querySelector(selector);
344
350
  if (found === null)