@erdemtuna/doc-review 0.8.0 → 0.9.0

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/src/chrome.css CHANGED
@@ -10,7 +10,7 @@
10
10
  --strong-border: #d9d5c9;
11
11
  --txt: #26241e;
12
12
  --strong-txt: #1b1a16;
13
- --mute: #8b877d;
13
+ --mute: #736e63;
14
14
  --mute-2: #6b6862;
15
15
  --faint: #b6b2a8;
16
16
  --faint-2: #a8a49a;
@@ -29,6 +29,18 @@
29
29
  --narrow: 720px;
30
30
  --overlay: 60;
31
31
  --focus-ring: 0 0 0 3px rgba(90, 99, 216, .28);
32
+ --diff-paper: #fffefa;
33
+ --diff-ink: #302f29;
34
+ --diff-muted: #696459;
35
+ --diff-line: #dedad0;
36
+ --diff-removed: #fff2ee;
37
+ --diff-added: #eff7ec;
38
+ --diff-delete: #f6d3c9;
39
+ --diff-insert: #cee8c8;
40
+ --diff-delete-ink: #833f31;
41
+ --diff-insert-ink: #386132;
42
+ --diff-gap: #f7f5ef;
43
+ --diff-accent: #426581;
32
44
  }
33
45
 
34
46
  :root[data-theme="dark"] {
@@ -56,6 +68,18 @@
56
68
  --green: #8ea37f;
57
69
  --btn-bg: #f0ede6;
58
70
  --btn-fg: #1b1a16;
71
+ --diff-paper: #24231f;
72
+ --diff-ink: #eae7df;
73
+ --diff-muted: #b8b1a5;
74
+ --diff-line: #464239;
75
+ --diff-removed: #372723;
76
+ --diff-added: #263426;
77
+ --diff-delete: #61382e;
78
+ --diff-insert: #355735;
79
+ --diff-delete-ink: #ffb6a5;
80
+ --diff-insert-ink: #b1d9a7;
81
+ --diff-gap: #2a2823;
82
+ --diff-accent: #9bbad2;
59
83
  }
60
84
 
61
85
  * { box-sizing: border-box; }
@@ -69,7 +93,7 @@ body {
69
93
  }
70
94
  button, textarea { font: inherit; color: inherit; }
71
95
  button:focus-visible, textarea:focus-visible, [tabindex]:focus-visible { outline: none; box-shadow: var(--focus-ring); }
72
- .app { display: grid; grid-template-rows: var(--toolbar-h) minmax(0, 1fr); height: 100dvh; }
96
+ .app { display: grid; grid-template-rows: auto minmax(0, 1fr); height: 100dvh; }
73
97
  .icon { display: block; flex: none; }
74
98
  .sr-only {
75
99
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
@@ -81,16 +105,104 @@ button:focus-visible, textarea:focus-visible, [tabindex]:focus-visible { outline
81
105
  z-index: 20;
82
106
  display: grid;
83
107
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
108
+ grid-template-areas: "versions controls actions";
109
+ grid-template-rows: auto;
84
110
  align-items: center;
85
- gap: 12px;
86
- padding: 6px 10px;
111
+ gap: 2px 12px;
112
+ padding: 8px 16px;
87
113
  border-bottom: 1px solid var(--hair);
88
114
  background: var(--panel);
89
115
  }
90
- .toolbar-product { min-width: 0; }
91
- .toolbar-actions { display: flex; align-items: center; justify-content: flex-end; gap: 6px; }
116
+ .toolbar-product { grid-area: versions; min-width: 0; }
117
+ .toolbar-actions { grid-area: actions; display: flex; align-items: center; justify-content: flex-end; gap: 6px; }
118
+ .review-details { position: relative; }
119
+ .review-details summary {
120
+ display: flex; align-items: center; justify-content: center; gap: 8px;
121
+ min-height: 44px; min-width: 44px; padding: 8px 12px;
122
+ color: var(--mute-2); border-radius: 8px; cursor: pointer; list-style: none;
123
+ }
124
+ .review-details summary::-webkit-details-marker { display: none; }
125
+ .review-details summary:hover, .review-details[open] summary { background: var(--soft); color: var(--strong-txt); }
126
+ .review-details summary:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }
127
+ .review-details-menu {
128
+ position: absolute; top: calc(100% + 8px); right: 0; z-index: 80;
129
+ width: min(280px, calc(100vw - 24px)); padding: 8px;
130
+ border: 1px solid var(--strong-border); border-radius: 10px; background: var(--panel);
131
+ box-shadow: 0 12px 32px #0002;
132
+ }
133
+ .review-details-menu > p { margin: 8px; font-size: 12px; }
134
+ .review-details-menu > button {
135
+ display: block; width: 100%; min-height: 44px; padding: 10px 12px; border: 0;
136
+ border-radius: 6px; background: transparent; text-align: left; cursor: pointer;
137
+ }
138
+ .review-details-menu > button:hover { background: var(--soft); }
139
+ .execution-notice {
140
+ position: absolute; top: 12px; left: 12px; right: 12px; z-index: 94; margin: 0;
141
+ padding: 12px 16px; border: 1px solid var(--strong-border); border-radius: 8px;
142
+ background: var(--panel); box-shadow: 0 4px 16px #0001; overflow-wrap: anywhere;
143
+ }
144
+ #documentTrustControls { display: none !important; }
145
+ .page-controls {
146
+ grid-area: controls;
147
+ justify-self: center;
148
+ display: flex;
149
+ align-items: center;
150
+ max-width: 100%;
151
+ min-width: 0;
152
+ }
153
+ .page-controls .mode-control { flex: none; }
154
+ .document-trust { grid-area: scripts; flex: none; display: flex; align-items: center; gap: 2px; }
155
+ .script-switch {
156
+ display: flex; align-items: center; gap: 8px;
157
+ height: 44px; padding: 5px 8px;
158
+ border: 1px solid transparent; border-radius: 8px; background: transparent;
159
+ font-weight: 550; cursor: pointer;
160
+ }
161
+ .script-switch:hover:not([aria-disabled="true"]) { background: var(--soft); border-color: var(--hair); }
162
+ .script-switch:focus-visible, .script-retry:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
163
+ .script-switch[aria-disabled="true"] { cursor: wait; }
164
+ .script-switch-value { width: 20px; flex: none; text-align: center; color: var(--mute-2); font-size: 11px; font-weight: 400; }
165
+ .script-switch-label { white-space: nowrap; }
166
+ .script-switch-short-label { display: none; }
167
+ .script-switch-track {
168
+ position: relative; flex: none; width: 30px; height: 18px;
169
+ border: 1px solid var(--mute-2); border-radius: 20px; background: var(--soft);
170
+ }
171
+ .script-switch-track::after {
172
+ content: ""; position: absolute; top: 3px; left: 3px;
173
+ width: 10px; height: 10px; border-radius: 50%; background: var(--mute-2);
174
+ transition: transform 120ms ease;
175
+ }
176
+ .script-switch[aria-checked="true"] .script-switch-track { background: var(--btn-bg); border-color: var(--btn-bg); }
177
+ .script-switch[aria-checked="true"] .script-switch-track::after { background: var(--btn-fg); transform: translateX(12px); }
178
+ .script-help, .script-status, .script-error {
179
+ margin: 0; padding: 0; color: var(--mute-2); overflow-wrap: anywhere;
180
+ }
181
+ .script-status { color: var(--txt); }
182
+ .script-error { color: var(--danger); }
183
+ .script-retry { flex: none; height: 24px; padding: 0; border: 0; background: transparent; text-decoration: underline; cursor: pointer; font-size: 11px; }
184
+ .script-details { flex: none; }
185
+ .script-details summary {
186
+ display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%;
187
+ cursor: pointer; color: var(--mute-2); font-size: 12px; list-style: none;
188
+ }
189
+ .script-details summary::-webkit-details-marker { display: none; }
190
+ .script-details summary:hover { background: var(--soft); }
191
+ .script-details summary:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }
192
+ .script-details-body {
193
+ position: absolute; right: 8px; top: calc(100% + 4px); width: min(380px, calc(100vw - 16px));
194
+ max-height: min(300px, 50vh); overflow: auto; padding: 12px 16px;
195
+ border: 1px solid var(--strong-border); border-radius: 8px; background: var(--panel);
196
+ box-shadow: 0 8px 24px #0002; color: var(--txt); font-size: 12px; line-height: 1.5;
197
+ }
198
+ .script-details-body p { margin: 0 0 8px; overflow-wrap: anywhere; }
199
+ .script-details-body p:last-child { margin-bottom: 0; }
200
+ @media (prefers-reduced-motion: reduce) {
201
+ .script-switch-track::after { transition: none; }
202
+ }
92
203
  .toolbar-btn {
93
- min-height: 34px;
204
+ min-height: 44px;
205
+ min-width: 44px;
94
206
  display: inline-flex;
95
207
  align-items: center;
96
208
  justify-content: center;
@@ -105,6 +217,7 @@ button:focus-visible, textarea:focus-visible, [tabindex]:focus-visible { outline
105
217
  }
106
218
  .toolbar-btn:hover, .toolbar-btn[aria-expanded="true"] { border-color: var(--hair); background: var(--soft); color: var(--strong-txt); }
107
219
  .toolbar-btn:disabled { opacity: .55; cursor: wait; }
220
+ #modeButton:disabled { opacity: 1; }
108
221
  .count-badge {
109
222
  min-width: 19px; height: 19px; display: inline-flex; align-items: center; justify-content: center;
110
223
  padding: 0 5px; border-radius: 999px; background: var(--chip); color: var(--mute-2); font-size: 11px;
@@ -141,7 +254,138 @@ button:focus-visible, textarea:focus-visible, [tabindex]:focus-visible { outline
141
254
  .mode-menu small { color: var(--mute); font-size: 11px; font-weight: 400; }
142
255
 
143
256
  .stage { min-width: 0; min-height: 0; background: var(--canvas); }
257
+ .stage { position: relative; }
258
+ .history-toggle { display: flex; width: fit-content; gap: 2px; padding: 3px; border: 1px solid var(--hair); border-radius: 11px; background: var(--soft); }
259
+ .history-toggle .toolbar-btn { padding-inline: 14px; white-space: nowrap; }
260
+ .history-toggle [aria-pressed="true"] { background: var(--card); border-color: var(--strong-border); color: var(--strong-txt); box-shadow: 0 1px 3px #0001; }
261
+ .history-panel { position: absolute; inset: 0; z-index: 1; height: 100%; overflow: auto; padding: 18px clamp(12px, 2vw, 28px) 28px; background: var(--panel); scrollbar-gutter: stable; }
262
+ .history-head, .history-controls, .history-navigation { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px; }
263
+ .history-head h1 { margin: 0; font-size: 20px; letter-spacing: -.5px; }
264
+ .history-head h1 .section { margin-left: 10px; vertical-align: middle; letter-spacing: .04em; }
265
+ .history-summary { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 4px 16px; margin: 8px 0 14px; color: var(--mute-2); font-size: 12px; }
266
+ .history-summary > p { margin: 0; overflow-wrap: anywhere; }
267
+ .history-summary > :empty { display: none; }
268
+ .history-panel label { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; min-width: 0; }
269
+ .history-panel select { max-width: 100%; min-width: 0; min-height: 44px; padding: 8px 10px; border: 1px solid var(--strong-border); border-radius: 7px; background: var(--card); color: var(--txt); font: inherit; text-overflow: ellipsis; }
270
+ .history-panel select:focus-visible { outline: 2px solid var(--focus); }
271
+ .history-controls { justify-content: flex-start; margin: 0; gap: 8px 16px; }
272
+ .history-controls > label { flex-wrap: nowrap; color: var(--mute-2); font-size: 12px; }
273
+ .history-round-label select { max-width: min(280px, 65vw); }
274
+ #historyTargetLabel { flex: 1 1 200px; }
275
+ #historyTarget { width: 100%; }
276
+ #comparisonModes { display: flex; flex-wrap: wrap; gap: 2px; padding: 3px; border: 1px solid var(--hair); border-radius: 9px; }
277
+ #comparisonModes:empty { display: none; }
278
+ .history-controls button { min-height: 44px; min-width: 44px; }
279
+ .history-controls [aria-pressed="true"] { background: var(--soft); color: var(--strong-txt); }
280
+ .history-controls button:disabled { opacity: .55; cursor: default; }
281
+ .history-counts { display: flex; flex-wrap: wrap; gap: 16px; margin: 0; color: var(--mute-2); }
282
+ .history-timing { display: flex; flex-wrap: wrap; gap: 12px 24px; margin: 14px 0; }
283
+ .history-timing > div { min-width: 0; }
284
+ .history-timing dt { font-size: 11px; text-transform: uppercase; color: var(--mute-2); letter-spacing: .04em; }
285
+ .history-timing dd { margin: 2px 0 0; font-weight: 550; overflow-wrap: anywhere; }
286
+ .history-context { color: var(--mute-2); overflow-wrap: anywhere; }
287
+ .history-context p { margin: 6px 0; }
288
+ .history-diagnostics { font-size: 12px; color: var(--mute-2); margin: 12px 0 0; }
289
+ .history-diagnostics summary { cursor: pointer; min-height: 44px; padding-block: 12px; width: fit-content; }
290
+ .history-diagnostics > p { max-width: 90ch; }
291
+ .history-diagnostics > button { min-height: 44px; }
292
+ .change-detail { border: 1px solid var(--diff-line); border-radius: 0 0 8px 8px; background: var(--card); overflow-wrap: anywhere; }
293
+ .change-detail:empty { display: none; }
294
+ .comparison-header { position: sticky; top: 0; z-index: 4; background: var(--panel); }
295
+ .history-navigation { background: var(--panel); justify-content: flex-start; margin: 0; padding: 0 0 8px; gap: 8px; font-size: 12px; }
296
+ .history-navigation button { min-height: 44px; min-width: 44px; }
297
+ .history-navigation .change-jump-label { flex: 1; justify-content: flex-end; }
298
+ .change-jump-label select { max-width: min(420px, 100%); }
299
+ .comparison-headings, .comparison-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
300
+ .comparison-headings { background: var(--soft); border: 1px solid var(--diff-line); border-radius: 8px 8px 0 0; color: var(--diff-muted); font-size: 12px; font-weight: 600; }
301
+ .comparison-headings > div { padding: 12px 18px; }
302
+ .comparison-headings > div + div, .comparison-after { border-left: 1px solid var(--diff-line); }
303
+ .comparison-row + .comparison-row { border-top: 1px solid var(--hair-2); }
304
+ .comparison-cell { display: flex; min-width: 0; padding: 16px 20px 16px 0; }
305
+ .comparison-cell-body { flex: 1; min-width: 0; }
306
+ .comparison-gutter { flex: 0 0 32px; padding-top: 2px; text-align: center; font: 12px/1.6 ui-monospace, monospace; color: var(--diff-muted); user-select: none; }
307
+ .comparison-block { min-width: 0; font: 15px/1.7 system-ui, sans-serif; color: var(--diff-ink); }
308
+ .comparison-block :is(p, h1, h2, h3, h4, h5, h6, pre, ul, ol, figure, blockquote) { margin: 0; }
309
+ .comparison-block h1 { font-size: 25px; line-height: 1.3; letter-spacing: -.5px; }
310
+ .comparison-block h2 { font-size: 21px; line-height: 1.4; letter-spacing: -.3px; }
311
+ .comparison-block h3 { font-size: 18px; line-height: 1.4; }
312
+ .comparison-block :is(h4, h5, h6) { font-size: 16px; line-height: 1.5; }
313
+ .comparison-block pre { white-space: pre-wrap; overflow-wrap: anywhere; font: 12px/1.7 ui-monospace, monospace; tab-size: 4; }
314
+ .comparison-block blockquote { padding-left: 12px; border-left: 3px solid var(--strong-border); color: var(--diff-muted); }
315
+ .comparison-block :is(code, kbd, samp) { font-family: ui-monospace, monospace; font-size: .9em; background: var(--soft); border-radius: 3px; padding: 1px 3px; }
316
+ .comparison-removed { background: var(--diff-removed); }
317
+ .comparison-added { background: var(--diff-added); }
318
+ .comparison-gap { background: repeating-linear-gradient(135deg, var(--diff-paper) 0, var(--diff-paper) 5px, var(--diff-gap) 5px, var(--diff-gap) 7px); }
319
+ .comparison-surface { background: var(--diff-paper); color: var(--diff-ink); }
320
+ .comparison-surface del { background: var(--diff-delete); text-decoration: line-through; text-decoration-color: var(--diff-delete-ink); border-radius: 2px; }
321
+ .comparison-surface ins { background: var(--diff-insert); text-decoration: underline; text-decoration-thickness: 2px; text-decoration-color: var(--diff-insert-ink); text-underline-offset: 3px; border-radius: 2px; }
322
+ .comparison-current > .comparison-before { box-shadow: inset 3px 0 var(--diff-accent); }
323
+ .comparison-mobile-label { display: none; }
324
+ .comparison-change-label { display: block; color: var(--diff-muted); font-size: 11px; margin-bottom: 6px; }
325
+ .comparison-expand { display: block; width: 100%; min-height: 44px; padding: 10px 16px; border: 0; border-block: 1px solid var(--diff-line); background: var(--soft); color: var(--diff-muted); cursor: pointer; text-align: center; font: 12px/1.5 system-ui, sans-serif; }
326
+ .comparison-expand:hover { background: var(--chip); color: var(--strong-txt); }
327
+ .comparison-surface :focus-visible, .history-panel summary:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }
328
+ .comparison-notice, .comparison-budget { padding: 14px 18px; margin: 0; font-size: 12px; color: var(--diff-muted); }
329
+ .comparison-budget { color: var(--danger); }
330
+ .comparison-block .metadata-note, .comparison-block .structure-note, .comparison-block .newline-note { display: block; margin-top: 5px; font: 12px/1.5 system-ui, sans-serif; color: var(--diff-muted); overflow-wrap: anywhere; }
331
+ .saved-link { color: var(--diff-accent); text-decoration: underline; text-decoration-style: dotted; }
332
+ .saved-image { padding: 12px; border: 1px dashed var(--diff-muted); border-radius: 5px; background: var(--diff-gap); }
333
+ .saved-image small { display: block; color: var(--diff-muted); font-size: 12px; }
334
+ .saved-list { padding-inline-start: 22px; }
335
+ .saved-table { width: 100%; border-collapse: collapse; table-layout: fixed; }
336
+ .saved-table :is(th, td) { padding: 7px 10px; border: 1px solid var(--diff-line); text-align: left; vertical-align: top; }
337
+ .saved-table th { background: var(--soft); }
338
+ .saved-table .comparison-block { font-size: 13px; }
339
+ .comparison-source .comparison-cell { padding-block: 0; padding-right: 8px; }
340
+ .comparison-source .comparison-change-label { display: none; }
341
+ .comparison-source .comparison-gutter { flex-basis: 60px; text-align: right; padding: 0 12px 0 4px; white-space: pre; }
342
+ .comparison-source .comparison-block pre { line-height: 22px; min-height: 22px; }
343
+ .comparison-source .comparison-block .newline-note { margin: 0; padding: 3px 0; }
344
+ .capture-warning, .reload-notice { padding: 12px; border: 1px solid var(--strong-border); border-radius: 8px; background: var(--panel); overflow-wrap: anywhere; }
345
+ .capture-warning p, .reload-notice p { margin: 0 0 8px; }
346
+ .reload-notice { position: absolute; top: 8px; left: 8px; right: 8px; z-index: 95; box-shadow: 0 6px 24px #0002; }
347
+ body.comparing :is(#compose, #alignedCard, .page-controls, #commentsButton, #reviewDetails, #executionStatus, #reloadNotice) { display: none !important; }
348
+ body.comparing #frame { pointer-events: none; }
349
+ @media (max-width: 600px) {
350
+ .toolbar {
351
+ grid-template-columns: minmax(0, 1fr) auto;
352
+ grid-template-areas: "versions versions" "controls actions";
353
+ grid-template-rows: auto auto; gap: 4px 6px; padding: 8px 10px;
354
+ }
355
+ .page-controls { justify-self: start; }
356
+ .mode-menu { left: 0; transform: none; width: min(250px, calc(100vw - 24px)); }
357
+ body.comparing .toolbar { grid-template-areas: "versions versions"; grid-template-rows: auto; }
358
+ }
359
+ @media (max-width: 540px) {
360
+ .history-panel { padding: 12px 8px; }
361
+ .history-head { align-items: flex-start; }
362
+ }
363
+ @media (max-width: 700px) {
364
+ .comparison-headings { display: none; }
365
+ .change-detail { border-radius: 8px; }
366
+ .comparison-row { grid-template-columns: minmax(0, 1fr); border-bottom: 1px solid var(--diff-line); }
367
+ .comparison-after { border-left: 0; border-top: 1px solid var(--diff-line); }
368
+ .comparison-gap { display: none; }
369
+ .comparison-unchanged > .comparison-after { display: none; }
370
+ .comparison-cell { padding-right: 10px; }
371
+ .comparison-mobile-label { display: block; color: var(--diff-muted); font: 600 12px/1.6 system-ui, sans-serif; margin-bottom: 8px; }
372
+ .comparison-change-label { display: none; }
373
+ .comparison-current > .comparison-after { box-shadow: inset 3px 0 var(--diff-accent); }
374
+ .comparison-block { font-size: 14px; }
375
+ .comparison-source .comparison-gutter { flex-basis: 48px; }
376
+ .history-navigation { flex-wrap: nowrap; }
377
+ .history-navigation .change-jump-label { flex: 1; }
378
+ .change-jump-label > span { display: none; }
379
+ .change-jump-label select { max-width: 100%; width: 100%; }
380
+ .history-navigation button { font-size: 0; width: 44px; flex: 0 0 44px; padding: 4px; }
381
+ .history-navigation button::before { font-size: 18px; }
382
+ #previousChange::before { content: "←"; }
383
+ #nextChange::before { content: "→"; }
384
+ #changePosition { white-space: nowrap; }
385
+ }
144
386
  #frame { width: 100%; height: 100%; border: 0; display: block; background: #fff; }
387
+ #frame[data-replacing] { opacity: 0; pointer-events: none; }
388
+ #previousFrame { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; border: 0; display: block; pointer-events: none; }
145
389
 
146
390
  .icon-btn {
147
391
  width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center;
@@ -392,8 +636,9 @@ button:focus-visible, textarea:focus-visible, [tabindex]:focus-visible { outline
392
636
  @keyframes rise { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
393
637
 
394
638
  @media (max-width: 720px) {
395
- .toolbar { grid-template-columns: minmax(36px, 1fr) auto minmax(36px, 1fr); padding-inline: 7px; }
639
+ .toolbar { padding-inline: 7px; }
396
640
  .toolbar-btn { width: 36px; padding: 6px; position: relative; }
641
+ .history-toggle .toolbar-btn { width: auto; padding-inline: 7px; }
397
642
  #modeButton { width: auto; padding-inline: 9px; }
398
643
  .toolbar-label { display: none; }
399
644
  .count-badge { position: absolute; top: -3px; right: -3px; min-width: 17px; height: 17px; padding: 0 4px; font-size: 10px; border: 2px solid var(--panel); }
package/src/chrome.html CHANGED
@@ -9,31 +9,91 @@
9
9
  <body data-session="__SESSION_ID__" data-token="__TOKEN__">
10
10
  <div class="app">
11
11
  <header class="toolbar" aria-label="Review controls">
12
- <div class="toolbar-product" aria-hidden="true"></div>
13
- <div class="mode-control">
14
- <button type="button" id="modeButton" class="toolbar-btn" aria-haspopup="menu" aria-expanded="false">
15
- <span id="modeIcon"></span><span id="modeLabel">View</span><span id="modeChevron"></span>
16
- </button>
17
- <div id="modeMenu" class="mode-menu" role="menu" hidden>
18
- <button type="button" role="menuitemradio" aria-checked="true" data-mode="view">
19
- <span data-icon="eye"></span><span><strong>View</strong><small>Editing off, comments enabled</small></span><span class="menu-check"></span>
20
- </button>
21
- <button type="button" role="menuitemradio" aria-checked="false" data-mode="edit">
22
- <span data-icon="pencil"></span><span><strong>Edit</strong><small>Direct editing on</small></span><span class="menu-check"></span>
12
+ <div class="toolbar-product history-toggle" role="group" aria-label="Review destination">
13
+ <button type="button" id="latestVersion" class="toolbar-btn" aria-pressed="true" aria-controls="frame">Review</button>
14
+ <button type="button" id="seeChanges" class="toolbar-btn" aria-pressed="false" aria-controls="historyPanel">Changes</button>
15
+ </div>
16
+ <div class="page-controls" role="group" aria-label="Page controls">
17
+ <div class="mode-control">
18
+ <button type="button" id="modeButton" class="toolbar-btn" aria-haspopup="menu" aria-expanded="false">
19
+ <span id="modeIcon"></span><span id="modeLabel">View</span><span id="modeChevron"></span>
23
20
  </button>
21
+ <div id="modeMenu" class="mode-menu" role="menu" hidden>
22
+ <button type="button" role="menuitemradio" aria-checked="true" data-mode="view">
23
+ <span data-icon="eye"></span><span><strong>View</strong><small>Editing off, comments enabled</small></span><span class="menu-check"></span>
24
+ </button>
25
+ <button type="button" role="menuitemradio" aria-checked="false" data-mode="edit">
26
+ <span data-icon="pencil"></span><span><strong>Edit</strong><small>Direct editing on</small></span><span class="menu-check"></span>
27
+ </button>
28
+ </div>
24
29
  </div>
25
30
  </div>
26
31
  <div class="toolbar-actions">
32
+ <div id="documentTrustControls" hidden></div>
27
33
  <button type="button" id="commentsButton" class="toolbar-btn" aria-controls="drawer" aria-label="Comments" aria-expanded="false">
28
34
  <span data-icon="messages"></span><span class="toolbar-label">Comments</span><span id="toolbarCount" class="count-badge">0</span>
29
35
  </button>
36
+ <details id="reviewDetails" class="review-details">
37
+ <summary>More <span aria-hidden="true">⌄</span></summary>
38
+ <div class="review-details-menu">
39
+ <p class="section">Page recovery</p>
40
+ <button type="button" id="executionStatic">Reload without scripts</button>
41
+ <button type="button" id="executionAuto" hidden>Use page interactions</button>
42
+ <p id="executionDetails" class="history-context" hidden></p>
43
+ </div>
44
+ </details>
30
45
  </div>
31
46
  </header>
32
47
  <main class="stage">
48
+ <p id="executionStatus" class="execution-notice" role="status" hidden></p>
49
+ <section id="reloadNotice" class="reload-notice" aria-label="Source update" hidden>
50
+ <p id="reloadMessage"></p>
51
+ <button type="button" id="safeReload" class="btn-primary">Reload latest; keep comment drafts</button>
52
+ <button type="button" id="keepCurrent" class="btn-ghost">Keep this page</button>
53
+ </section>
33
54
  <iframe
34
55
  id="frame"
35
56
  title="Artifact under review"
36
57
  sandbox="allow-scripts allow-forms allow-modals"></iframe>
58
+ <section id="historyPanel" class="history-panel" aria-labelledby="historyTitle" hidden>
59
+ <h1 id="historyTitle" class="sr-only">Changes</h1>
60
+ <div class="history-controls">
61
+ <label class="history-round-label">Round <select id="roundPicker" aria-label="Review round"></select></label>
62
+ <label id="historyTargetLabel" hidden>Page <select id="historyTarget" aria-label="Comparison page"></select></label>
63
+ <div id="comparisonModes" role="group" aria-label="Comparison format"></div>
64
+ <button type="button" id="captureResult" class="btn-primary" hidden>Capture result</button>
65
+ </div>
66
+ <div class="history-summary">
67
+ <p id="historyStatus" role="status">No review rounds yet. Send feedback to start a comparison.</p>
68
+ <div id="historyCounts" class="history-counts"></div>
69
+ </div>
70
+ <p id="historyError" class="compose-error" role="alert" hidden></p>
71
+ <div class="comparison-header">
72
+ <nav id="changeNavigation" class="history-navigation" aria-label="Change navigation" hidden>
73
+ <button type="button" id="previousChange" class="btn-ghost" aria-label="Previous change">Previous</button>
74
+ <span id="changePosition"></span>
75
+ <label class="change-jump-label"><span>Jump to</span> <select id="changeJump" aria-label="Jump to change"></select></label>
76
+ <button type="button" id="nextChange" class="btn-ghost" aria-label="Next change">Next</button>
77
+ </nav>
78
+ <div class="comparison-heading-slot"></div>
79
+ </div>
80
+ <article id="changeDetail" class="change-detail" aria-label="Continuous before and after comparison"></article>
81
+ <details id="historyDiagnostics" class="history-diagnostics">
82
+ <summary>Comparison details</summary>
83
+ <p id="historyCurrentStatus" class="history-context" hidden></p>
84
+ <p id="historyViewCoverage" class="history-context" hidden></p>
85
+ <div id="historyUnavailable" class="history-context" hidden></div>
86
+ <p>Content is a readable reconstruction of saved blocks, not the original page layout. Historical scripts, authored styles and image URLs are never replayed. Table rows use saved cell selectors; complex spanning structure is shown in row order. Source shows saved file text.</p>
87
+ <dl id="historyTiming" class="history-timing" hidden></dl>
88
+ <p id="historyCaptureDelay" class="history-context" hidden></p>
89
+ <details id="historyLimitations" hidden>
90
+ <summary>Comparison coverage and limits</summary>
91
+ <ul id="historyLimitationsList"></ul>
92
+ </details>
93
+ <button type="button" id="finishCapture" class="btn-ghost" hidden>Finish with available snapshots</button>
94
+ <p id="finishCaptureHelp" class="history-context" hidden>Finishing marks missing Content as unavailable; it does not invent a result. Existing Source comparisons remain available, and this target will no longer retry capture.</p>
95
+ </details>
96
+ </section>
37
97
  </main>
38
98
 
39
99
  <section id="compose" class="contextual-compose" role="dialog" aria-modal="false" aria-labelledby="composeTitle" hidden>
@@ -107,6 +167,13 @@
107
167
  </div>
108
168
  <textarea id="note" rows="2" placeholder="Overall note…"></textarea>
109
169
  <button type="button" id="send" class="send" disabled>Nothing to send yet</button>
170
+ <p id="draftWarning" class="dim" hidden></p>
171
+ <div id="captureWarning" class="capture-warning" role="alert" hidden>
172
+ <p id="captureWarningText"></p>
173
+ <div id="captureTargets"></div>
174
+ <button type="button" id="recaptureBaseline" class="btn-primary">Recapture and send</button>
175
+ <button type="button" id="sendWithoutComparison" class="btn-ghost">Send without comparison</button>
176
+ </div>
110
177
  <div class="agent-line" id="agentLine" hidden><span class="dot amber"></span><span id="agentText"></span></div>
111
178
  </div>
112
179
  <div class="send-secondary">