@beyondwork/docx-react-component 1.0.52 → 1.0.54

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 (103) hide show
  1. package/package.json +31 -40
  2. package/src/api/public-types.ts +67 -7
  3. package/src/io/chart-preview-resolver.ts +41 -0
  4. package/src/io/docx-session.ts +217 -23
  5. package/src/runtime/collab/checkpoint-store.ts +1 -1
  6. package/src/runtime/collab/event-types.ts +4 -0
  7. package/src/runtime/collab/runtime-collab-sync.ts +88 -8
  8. package/src/runtime/document-runtime.ts +182 -9
  9. package/src/runtime/layout/inert-layout-facet.ts +1 -0
  10. package/src/runtime/layout/layout-engine-version.ts +97 -2
  11. package/src/runtime/layout/layout-invalidation.ts +150 -30
  12. package/src/runtime/layout/page-graph.ts +19 -0
  13. package/src/runtime/layout/paginated-layout-engine.ts +128 -19
  14. package/src/runtime/layout/project-block-fragments.ts +27 -0
  15. package/src/runtime/layout/public-facet.ts +70 -1
  16. package/src/runtime/prerender/cache-envelope.ts +30 -0
  17. package/src/runtime/prerender/customxml-cache.ts +17 -3
  18. package/src/runtime/prerender/prerender-document.ts +17 -1
  19. package/src/runtime/render/render-frame-diff.ts +38 -2
  20. package/src/runtime/render/render-kernel.ts +67 -19
  21. package/src/runtime/surface-projection.ts +28 -0
  22. package/src/runtime/table-schema.ts +27 -0
  23. package/src/runtime/table-style-resolver.ts +51 -0
  24. package/src/ui/WordReviewEditor.tsx +6 -3
  25. package/src/ui/editor-runtime-boundary.ts +39 -2
  26. package/src/ui/headless/comment-decoration-model.ts +60 -5
  27. package/src/ui/headless/revision-decoration-model.ts +94 -6
  28. package/src/ui/shared/revision-filters.ts +16 -6
  29. package/src/ui-tailwind/chart/ChartSurface.tsx +236 -0
  30. package/src/ui-tailwind/chart/layout/axis-layout.ts +17 -9
  31. package/src/ui-tailwind/chart/layout/legend-layout.ts +231 -0
  32. package/src/ui-tailwind/chart/layout/plot-area.ts +152 -59
  33. package/src/ui-tailwind/chart/layout/title-layout.ts +184 -0
  34. package/src/ui-tailwind/chart/render/area.tsx +277 -0
  35. package/src/ui-tailwind/chart/render/bar-column.tsx +356 -0
  36. package/src/ui-tailwind/chart/render/bubble.tsx +134 -0
  37. package/src/ui-tailwind/chart/render/combo.tsx +85 -0
  38. package/src/ui-tailwind/chart/render/data-labels.tsx +513 -0
  39. package/src/ui-tailwind/chart/render/font-metrics.ts +298 -0
  40. package/src/ui-tailwind/chart/render/gridlines.ts +228 -0
  41. package/src/ui-tailwind/chart/render/line.tsx +363 -0
  42. package/src/ui-tailwind/chart/render/number-format.ts +120 -16
  43. package/src/ui-tailwind/chart/render/pie.tsx +275 -0
  44. package/src/ui-tailwind/chart/render/progressive-render.ts +103 -0
  45. package/src/ui-tailwind/chart/render/scatter.tsx +228 -0
  46. package/src/ui-tailwind/chart/render/smooth-curve.ts +101 -0
  47. package/src/ui-tailwind/chart/render/svg-primitives.ts +378 -0
  48. package/src/ui-tailwind/chart/render/unsupported.tsx +126 -0
  49. package/src/ui-tailwind/chrome/collab-audience-chip.tsx +11 -0
  50. package/src/ui-tailwind/chrome/collab-negotiation-action-bar.tsx +44 -18
  51. package/src/ui-tailwind/chrome/collab-presence-strip.tsx +68 -7
  52. package/src/ui-tailwind/chrome/collab-role-chip.tsx +21 -2
  53. package/src/ui-tailwind/chrome/collab-tamper-banner.tsx +20 -3
  54. package/src/ui-tailwind/chrome/tw-alert-banner.tsx +102 -37
  55. package/src/ui-tailwind/chrome/tw-command-palette.tsx +358 -0
  56. package/src/ui-tailwind/chrome/tw-comment-preview.tsx +108 -0
  57. package/src/ui-tailwind/chrome/tw-context-menu.tsx +227 -0
  58. package/src/ui-tailwind/chrome/tw-display-mode-selector.tsx +136 -0
  59. package/src/ui-tailwind/chrome/tw-empty-state.tsx +76 -0
  60. package/src/ui-tailwind/chrome/tw-image-context-toolbar.tsx +30 -16
  61. package/src/ui-tailwind/chrome/tw-object-context-toolbar.tsx +23 -4
  62. package/src/ui-tailwind/chrome/tw-paste-drop-toast.tsx +113 -0
  63. package/src/ui-tailwind/chrome/tw-revision-hover-preview.tsx +150 -0
  64. package/src/ui-tailwind/chrome/tw-selection-tool-formatting.tsx +2 -0
  65. package/src/ui-tailwind/chrome/tw-selection-tool-host.tsx +38 -2
  66. package/src/ui-tailwind/chrome/tw-selection-tool-placement.ts +15 -3
  67. package/src/ui-tailwind/chrome/tw-selection-toolbar.tsx +32 -20
  68. package/src/ui-tailwind/chrome/tw-shortcut-hint.tsx +68 -0
  69. package/src/ui-tailwind/chrome/tw-suggestion-card.tsx +10 -10
  70. package/src/ui-tailwind/chrome/tw-table-context-toolbar.tsx +26 -5
  71. package/src/ui-tailwind/chrome/tw-table-grip-layer.tsx +29 -22
  72. package/src/ui-tailwind/chrome/tw-unsaved-modal.tsx +72 -10
  73. package/src/ui-tailwind/chrome-overlay/tw-scope-card.tsx +33 -18
  74. package/src/ui-tailwind/chrome-overlay/tw-table-continuation-header.tsx +94 -0
  75. package/src/ui-tailwind/editor-surface/perf-probe.ts +1 -0
  76. package/src/ui-tailwind/editor-surface/pm-page-break-decorations.ts +20 -7
  77. package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +54 -0
  78. package/src/ui-tailwind/editor-surface/scroll-anchor.ts +93 -0
  79. package/src/ui-tailwind/editor-surface/tw-table-node-view.tsx +107 -3
  80. package/src/ui-tailwind/index.ts +11 -0
  81. package/src/ui-tailwind/page-stack/tw-footnote-area.tsx +2 -2
  82. package/src/ui-tailwind/page-stack/tw-page-chrome-entry.tsx +274 -0
  83. package/src/ui-tailwind/page-stack/tw-page-footer-band.tsx +15 -2
  84. package/src/ui-tailwind/page-stack/tw-page-header-band.tsx +15 -2
  85. package/src/ui-tailwind/page-stack/tw-page-stack-chrome-layer.tsx +19 -147
  86. package/src/ui-tailwind/review/tw-comment-sidebar.tsx +83 -32
  87. package/src/ui-tailwind/review/tw-health-panel.tsx +174 -109
  88. package/src/ui-tailwind/review/tw-rail-card.tsx +9 -1
  89. package/src/ui-tailwind/review/tw-review-rail.tsx +36 -42
  90. package/src/ui-tailwind/review/tw-revision-sidebar.tsx +189 -101
  91. package/src/ui-tailwind/review/tw-workflow-tab.tsx +11 -1
  92. package/src/ui-tailwind/status/tw-status-bar.tsx +114 -46
  93. package/src/ui-tailwind/theme/chart-palette-adapter.ts +57 -0
  94. package/src/ui-tailwind/theme/editor-theme.css +275 -46
  95. package/src/ui-tailwind/theme/tokens.css +345 -0
  96. package/src/ui-tailwind/theme/tokens.ts +313 -0
  97. package/src/ui-tailwind/theme/use-density.ts +60 -0
  98. package/src/ui-tailwind/toolbar/tw-role-action-region.tsx +14 -1
  99. package/src/ui-tailwind/toolbar/tw-shell-header.tsx +73 -32
  100. package/src/ui-tailwind/toolbar/tw-toolbar-icon-button.tsx +49 -9
  101. package/src/ui-tailwind/toolbar/tw-toolbar.tsx +178 -14
  102. package/src/ui-tailwind/tw-review-workspace.tsx +39 -6
  103. package/src/ui-tailwind/chrome/review-queue-bar.tsx +0 -85
@@ -14,6 +14,7 @@
14
14
  */
15
15
 
16
16
  @import "tailwindcss";
17
+ @import "./tokens.css";
17
18
 
18
19
  @theme {
19
20
  /* Backgrounds */
@@ -32,9 +33,8 @@
32
33
  --color-secondary: #6b6b6b;
33
34
  --color-tertiary: #616161;
34
35
 
35
- /* Accent */
36
- --color-accent: #18b394;
37
- --color-accent-soft: rgba(24, 179, 148, 0.1);
36
+ /* Accent — 6a.S1 forest-green flip. Values resolve through tokens.css. */
37
+ --color-accent: var(--color-accent-primary);
38
38
  --color-workflow: #7557d8;
39
39
  --color-workflow-soft: rgba(117, 87, 216, 0.12);
40
40
 
@@ -123,8 +123,7 @@
123
123
  * the .dark block below so the transform lives in one place.
124
124
  */
125
125
  --shadow-hairline: 0 0 0 1px var(--color-border);
126
- --shadow-soft: 0 4px 14px -10px rgba(16, 24, 40, 0.14);
127
- --shadow-float: 0 12px 28px -20px rgba(16, 24, 40, 0.18);
126
+ /* --shadow-soft / --shadow-float / --shadow-focus owned by tokens.css (§3.3/§3.4). */
128
127
 
129
128
  /*
130
129
  * Tailwind shadow-sm / shadow-md / shadow-lg / shadow-xl follow the runtime
@@ -170,26 +169,10 @@
170
169
  --color-secondary: #A5B7AC;
171
170
  --color-tertiary: #7F9187;
172
171
 
173
- --color-accent: #53B487;
174
- --color-accent-soft: rgba(83, 180, 135, 0.16);
172
+ /* Accent / semantic / change / comment dark values owned by tokens.css. */
175
173
  --color-workflow: #c7b6ff;
176
174
  --color-workflow-soft: rgba(199, 182, 255, 0.16);
177
175
 
178
- --color-comment: #c7b6ff;
179
- --color-comment-soft: rgba(199, 182, 255, 0.18);
180
- --color-comment-strong: rgba(199, 182, 255, 0.24);
181
- --color-insert: #8fd2a9;
182
- --color-insert-soft: rgba(143, 210, 169, 0.18);
183
- --color-delete: #d78d84;
184
- --color-delete-soft: rgba(215, 141, 132, 0.14);
185
-
186
- --color-warning: #c7b6ff;
187
- --color-warning-soft: rgba(199, 182, 255, 0.16);
188
- --color-danger: #d78d84;
189
- --color-danger-soft: rgba(215, 141, 132, 0.16);
190
- --color-success: #8fd2a9;
191
- --color-success-soft: rgba(143, 210, 169, 0.18);
192
-
193
176
  --color-border: rgba(255, 255, 255, 0.09);
194
177
  --color-border-strong: rgba(255, 255, 255, 0.16);
195
178
 
@@ -202,8 +185,7 @@
202
185
  --color-page-ruler: color-mix(in srgb, var(--color-border) 70%, transparent);
203
186
  --color-workspace-canvas: #111827;
204
187
 
205
- --shadow-soft: 0 6px 18px -10px rgba(0, 0, 0, 0.55);
206
- --shadow-float: 0 18px 40px -22px rgba(0, 0, 0, 0.7);
188
+ /* --shadow-soft / --shadow-float / --shadow-focus owned by tokens.css. */
207
189
  }
208
190
 
209
191
  /*
@@ -509,6 +491,26 @@
509
491
  background: color-mix(in srgb, var(--color-danger) 14%, transparent);
510
492
  }
511
493
 
494
+ /* §3.7 canonical scope families */
495
+ .wre-scope-rail-tint-blocked {
496
+ background: var(--color-scope-tint-blocked);
497
+ }
498
+ .wre-scope-rail-tint-in-scope {
499
+ background: var(--color-scope-tint-in-scope);
500
+ }
501
+ .wre-scope-rail-tint-suggest {
502
+ background: var(--color-scope-tint-suggest);
503
+ }
504
+ .wre-scope-rail-tint-comment {
505
+ background: var(--color-scope-tint-comment);
506
+ }
507
+ .wre-scope-rail-tint-scheduled {
508
+ background: var(--color-scope-tint-scheduled);
509
+ }
510
+ .wre-scope-rail-tint-proposed {
511
+ background: var(--color-scope-tint-proposed);
512
+ }
513
+
512
514
  .wre-scope-rail-tint-active {
513
515
  outline: 1px solid color-mix(in srgb, var(--color-accent) 40%, transparent);
514
516
  outline-offset: -1px;
@@ -585,6 +587,14 @@
585
587
  .wre-scope-rail-stripe.wre-scope-rail-label-secondary { color: var(--color-secondary); }
586
588
  .wre-scope-rail-stripe.wre-scope-rail-label-danger { color: var(--color-danger); }
587
589
 
590
+ /* §3.7 canonical scope families — stripe color */
591
+ .wre-scope-rail-stripe.wre-scope-rail-tint-blocked { background: var(--color-scope-tint-blocked); }
592
+ .wre-scope-rail-stripe.wre-scope-rail-tint-in-scope { background: var(--color-scope-tint-in-scope); }
593
+ .wre-scope-rail-stripe.wre-scope-rail-tint-suggest { background: var(--color-scope-tint-suggest); }
594
+ .wre-scope-rail-stripe.wre-scope-rail-tint-comment { background: var(--color-scope-tint-comment); }
595
+ .wre-scope-rail-stripe.wre-scope-rail-tint-scheduled { background: var(--color-scope-tint-scheduled); }
596
+ .wre-scope-rail-stripe.wre-scope-rail-tint-proposed { background: var(--color-scope-tint-proposed); }
597
+
588
598
  /*
589
599
  * ─── Scope rail label pill ───
590
600
  *
@@ -650,6 +660,38 @@
650
660
  background: color-mix(in srgb, var(--color-danger) 8%, var(--color-canvas, #fff));
651
661
  }
652
662
 
663
+ /* §3.7 canonical scope families — label pill */
664
+ .wre-scope-rail-label-blocked {
665
+ color: var(--color-semantic-error);
666
+ border-color: color-mix(in srgb, var(--color-semantic-error) 40%, transparent);
667
+ background: color-mix(in srgb, var(--color-semantic-error) 8%, var(--color-canvas, #fff));
668
+ }
669
+ .wre-scope-rail-label-suggest {
670
+ color: var(--color-semantic-warning);
671
+ border-color: color-mix(in srgb, var(--color-semantic-warning) 42%, transparent);
672
+ background: color-mix(in srgb, var(--color-semantic-warning) 8%, var(--color-canvas, #fff));
673
+ }
674
+ .wre-scope-rail-label-scheduled {
675
+ color: var(--color-semantic-info);
676
+ border-color: color-mix(in srgb, var(--color-semantic-info) 40%, transparent);
677
+ background: color-mix(in srgb, var(--color-semantic-info) 8%, var(--color-canvas, #fff));
678
+ }
679
+ .wre-scope-rail-label-comment {
680
+ color: var(--color-accent-primary);
681
+ border-color: color-mix(in srgb, var(--color-accent-primary) 40%, transparent);
682
+ background: color-mix(in srgb, var(--color-accent-primary) 8%, var(--color-canvas, #fff));
683
+ }
684
+ .wre-scope-rail-label-in-scope {
685
+ color: var(--color-accent-primary);
686
+ border-color: color-mix(in srgb, var(--color-accent-primary) 40%, transparent);
687
+ background: color-mix(in srgb, var(--color-accent-primary) 8%, var(--color-canvas, #fff));
688
+ }
689
+ .wre-scope-rail-label-proposed {
690
+ color: var(--color-accent-primary);
691
+ border-color: color-mix(in srgb, var(--color-accent-primary) 40%, transparent);
692
+ background: color-mix(in srgb, var(--color-accent-primary) 8%, var(--color-canvas, #fff));
693
+ }
694
+
653
695
  .wre-scope-rail-label-active {
654
696
  box-shadow: 0 0 0 1px color-mix(in srgb, currentColor 30%, transparent);
655
697
  }
@@ -782,10 +824,14 @@
782
824
  * — consumers pick whichever matches their payload shape.
783
825
  */
784
826
  .wre-rail-card {
827
+ --wre-rail-card-edge: var(--color-border-default);
828
+ --wre-rail-card-eyebrow: var(--color-text-tertiary);
785
829
  position: relative;
786
- border-radius: var(--radius-card);
787
- background: var(--color-surface);
788
- border: 1px solid color-mix(in srgb, var(--color-border) 80%, transparent);
830
+ border-radius: var(--radius-lg);
831
+ background: var(--color-bg-elevated);
832
+ border: 1px solid var(--color-border-subtle);
833
+ border-left: 3px solid var(--wre-rail-card-edge);
834
+ box-shadow: var(--shadow-soft);
789
835
  padding: 14px 16px 16px;
790
836
  overflow: hidden;
791
837
  transition: background-color var(--motion-fast) ease-out,
@@ -810,34 +856,23 @@
810
856
  }
811
857
 
812
858
  .wre-rail-card[data-tone="inReview"] {
813
- --wre-rail-card-edge: var(--color-accent);
814
- --wre-rail-card-eyebrow: var(--color-accent);
815
- --wre-rail-card-progress-fill: var(--color-accent);
859
+ --wre-rail-card-edge: var(--color-semantic-warning);
860
+ --wre-rail-card-eyebrow: var(--color-semantic-warning);
816
861
  }
817
862
 
818
863
  .wre-rail-card[data-tone="blocked"] {
819
- --wre-rail-card-edge: var(--color-danger);
820
- --wre-rail-card-eyebrow: var(--color-danger);
821
- --wre-rail-card-progress-fill: var(--color-danger);
822
- background: color-mix(in srgb, var(--color-danger-soft) 75%, var(--color-surface));
864
+ --wre-rail-card-edge: var(--color-semantic-error);
865
+ --wre-rail-card-eyebrow: var(--color-semantic-error);
823
866
  }
824
867
 
825
868
  .wre-rail-card[data-tone="scheduled"] {
826
- --wre-rail-card-edge: var(--color-tertiary);
827
- --wre-rail-card-eyebrow: var(--color-tertiary);
828
- --wre-rail-card-progress-fill: var(--color-tertiary);
869
+ --wre-rail-card-edge: var(--color-semantic-info);
870
+ --wre-rail-card-eyebrow: var(--color-semantic-info);
829
871
  }
830
872
 
831
873
  .wre-rail-card[data-tone="resolved"] {
832
- --wre-rail-card-edge: var(--color-success);
833
- --wre-rail-card-eyebrow: var(--color-success);
834
- --wre-rail-card-progress-fill: var(--color-success);
835
- }
836
-
837
- .wre-rail-card[data-tone="neutral"] {
838
- --wre-rail-card-edge: var(--color-border-strong);
839
- --wre-rail-card-eyebrow: var(--color-tertiary);
840
- --wre-rail-card-progress-fill: var(--color-secondary);
874
+ --wre-rail-card-edge: var(--color-semantic-success);
875
+ --wre-rail-card-eyebrow: var(--color-semantic-success);
841
876
  }
842
877
 
843
878
  .wre-rail-card__eyebrow {
@@ -1007,3 +1042,197 @@
1007
1042
  color: var(--color-primary);
1008
1043
  background: color-mix(in srgb, var(--color-accent-soft) 80%, var(--color-subtle));
1009
1044
  }
1045
+
1046
+ /*
1047
+ * Lane 6d — Slice U1 (L8 Phase E): active H/F band chrome.
1048
+ *
1049
+ * Idle bands sit at 0.6 opacity so the header/footer content is
1050
+ * visible but doesn't compete with the body; hover bumps to 0.85; the
1051
+ * active band goes to full opacity and gains a 3 px accent ribbon
1052
+ * across its top edge plus a floating "Header — Section N" label in
1053
+ * the top-left corner so reviewers always know which band they are
1054
+ * editing when a section break changes the chrome.
1055
+ *
1056
+ * When any H/F story is active the chrome layer's root carries
1057
+ * `data-story-active="header|footer"` and the body PM surface dims to
1058
+ * 0.65 so the active band reads as the focal surface.
1059
+ */
1060
+ .wre-page-band {
1061
+ opacity: 0.6;
1062
+ transition: opacity var(--motion-fast, 120ms) ease-out;
1063
+ pointer-events: auto;
1064
+ }
1065
+
1066
+ .wre-page-band:hover {
1067
+ opacity: 0.85;
1068
+ }
1069
+
1070
+ .wre-page-band[data-active="true"] {
1071
+ opacity: 1;
1072
+ }
1073
+
1074
+ .wre-page-band[data-active="true"]::before {
1075
+ content: "";
1076
+ position: absolute;
1077
+ top: 0;
1078
+ left: 0;
1079
+ right: 0;
1080
+ height: 3px;
1081
+ background: var(--color-accent);
1082
+ border-radius: 0 0 var(--radius-pill) var(--radius-pill);
1083
+ pointer-events: none;
1084
+ }
1085
+
1086
+ .wre-page-band__label {
1087
+ position: absolute;
1088
+ top: 6px;
1089
+ left: 10px;
1090
+ font-size: 10px;
1091
+ letter-spacing: 0.08em;
1092
+ text-transform: uppercase;
1093
+ color: var(--color-accent);
1094
+ background: var(--color-surface);
1095
+ padding: 2px 8px;
1096
+ border-radius: var(--radius-pill);
1097
+ box-shadow: var(--shadow-soft);
1098
+ pointer-events: none;
1099
+ z-index: 1;
1100
+ }
1101
+
1102
+ [data-page-stack-chrome-layer][data-story-active="header"]
1103
+ ~ [data-pm-body-slot],
1104
+ [data-page-stack-chrome-layer][data-story-active="footer"]
1105
+ ~ [data-pm-body-slot] {
1106
+ opacity: 0.65;
1107
+ transition: opacity var(--motion-fast, 120ms) ease-out;
1108
+ }
1109
+
1110
+ /*
1111
+ * Lane 6d — Slice S2: print variant.
1112
+ *
1113
+ * At print time, collapse all editor chrome (toolbar, rails, overlays,
1114
+ * page-break spacers, dock chrome) and let the browser paginate the
1115
+ * paper cards one per physical sheet. Intentionally no `@page` rule —
1116
+ * the browser's print dialog owns paper size / margins so the host
1117
+ * application doesn't need to fight it.
1118
+ */
1119
+ @media print {
1120
+ .wre-toolbar,
1121
+ .wre-status-bar,
1122
+ .wre-review-rail,
1123
+ .wre-scope-rail-layer,
1124
+ .wre-page-chrome-widget,
1125
+ .wre-workspace-dock,
1126
+ .wre-mode-dock,
1127
+ [data-chrome-overlay],
1128
+ [data-pin-surface] {
1129
+ display: none !important;
1130
+ }
1131
+
1132
+ [data-paper-frame] {
1133
+ box-shadow: none !important;
1134
+ border: none !important;
1135
+ border-radius: 0 !important;
1136
+ margin: 0 !important;
1137
+ zoom: 1 !important;
1138
+ page-break-after: always;
1139
+ }
1140
+
1141
+ [data-paper-frame]:last-child {
1142
+ page-break-after: auto;
1143
+ }
1144
+
1145
+ .wre-page-surface {
1146
+ color: #000;
1147
+ background: #fff;
1148
+ }
1149
+ }
1150
+
1151
+ /*
1152
+ * §6.23 — Scrollbar grammar (Lane 6c.S10)
1153
+ * Thin track, thumb low-contrast until hover. Consistent across
1154
+ * rail, long popovers, and the health panel.
1155
+ * Scoped to the editor root class to avoid leaking into host chrome.
1156
+ */
1157
+ .wre-editor ::-webkit-scrollbar,
1158
+ .wre-editor *::-webkit-scrollbar {
1159
+ width: 6px;
1160
+ height: 6px;
1161
+ }
1162
+ .wre-editor ::-webkit-scrollbar-track,
1163
+ .wre-editor *::-webkit-scrollbar-track {
1164
+ background: transparent;
1165
+ }
1166
+ .wre-editor ::-webkit-scrollbar-thumb,
1167
+ .wre-editor *::-webkit-scrollbar-thumb {
1168
+ background: var(--color-border-default);
1169
+ border-radius: 9999px;
1170
+ }
1171
+ .wre-editor ::-webkit-scrollbar-thumb:hover,
1172
+ .wre-editor *::-webkit-scrollbar-thumb:hover {
1173
+ background: var(--color-border-strong);
1174
+ }
1175
+ .wre-editor,
1176
+ .wre-editor * {
1177
+ scrollbar-width: thin;
1178
+ scrollbar-color: var(--color-border-default) transparent;
1179
+ }
1180
+
1181
+ /*
1182
+ * §6.9 — Table grip hit area + affordance (Lane 6c.U8 / Commit C18)
1183
+ *
1184
+ * Visual stripe is 2 px; hit area is extended to 8 px via ::before pseudo-
1185
+ * element (3 px pad each side). On coarse-pointer devices the ::before extends
1186
+ * to 44 px total for WCAG 2.5.5 touch-target compliance.
1187
+ *
1188
+ * State cascade:
1189
+ * default → transparent background (invisible, pointer affordance only)
1190
+ * hover → --color-border-default (subtle stripe appears)
1191
+ * active → --color-accent-primary (vivid stripe during drag)
1192
+ */
1193
+ .wre-table-grip-col {
1194
+ position: absolute;
1195
+ width: 2px;
1196
+ background: transparent;
1197
+ cursor: col-resize;
1198
+ transition: background 75ms ease;
1199
+ }
1200
+ .wre-table-grip-col::before {
1201
+ content: "";
1202
+ position: absolute;
1203
+ inset: 0 -3px;
1204
+ }
1205
+ .wre-table-grip-col:hover {
1206
+ background: var(--color-border-default);
1207
+ }
1208
+ .wre-table-grip-col[data-active="true"] {
1209
+ background: var(--color-accent-primary);
1210
+ }
1211
+
1212
+ .wre-table-grip-row {
1213
+ position: absolute;
1214
+ height: 2px;
1215
+ background: transparent;
1216
+ cursor: row-resize;
1217
+ transition: background 75ms ease;
1218
+ }
1219
+ .wre-table-grip-row::before {
1220
+ content: "";
1221
+ position: absolute;
1222
+ inset: -3px 0;
1223
+ }
1224
+ .wre-table-grip-row:hover {
1225
+ background: var(--color-border-default);
1226
+ }
1227
+ .wre-table-grip-row[data-active="true"] {
1228
+ background: var(--color-accent-primary);
1229
+ }
1230
+
1231
+ @media (pointer: coarse) {
1232
+ .wre-table-grip-col::before {
1233
+ inset: 0 -21px; /* 44 px total touch hit area */
1234
+ }
1235
+ .wre-table-grip-row::before {
1236
+ inset: -21px 0; /* 44 px total touch hit area */
1237
+ }
1238
+ }