From ca8d1833ffaf8f73ef9d9f661d80ec7e39b298b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Hermes?= Date: Fri, 23 Oct 2026 08:14:29 +0200 Subject: [PATCH 1/5] Start page first screen, a visible list toggle, and a blue current change - Start page: on screens from 768px wide and 640px high, the hero sits centred in the first screen with "How it works" at its bottom edge and an arrow on to the rest (tighter spacing on laptop heights). Phones keep the plain flow. - Desktop: the "List 20" button in the top bar shows and hides the docked list of changes, and the list header has a collapse button. Before, the list could only be hidden from the View menu. - The current change is marked in the selection blue (edge and a light tint) instead of grey, which read as "disabled"; the same in the list and the overview bar. Co-Authored-By: Claude Opus 5.5 --- DocDiff.html | 122 +++++++++++++++++++++++++++++++++++++++--- site/en/index.html | 122 +++++++++++++++++++++++++++++++++++++++--- site/index.html | 122 +++++++++++++++++++++++++++++++++++++++--- src/js/01-i18n.js | 4 ++ src/js/06-compare.js | 14 +++++ src/js/10-controls.js | 11 +++- src/styles.css | 85 +++++++++++++++++++++++++++-- src/template.html | 8 ++- 8 files changed, 460 insertions(+), 28 deletions(-) diff --git a/DocDiff.html b/DocDiff.html index efea311..d90e1d6 100644 --- a/DocDiff.html +++ b/DocDiff.html @@ -273,8 +273,8 @@ --changed: 34 90% 46%; /* amber edge of a changed paragraph */ --changed-ink: 28 90% 25%; - --current: 215 25% 13%; /* edge of the current change */ - --current-tint: 215 30% 50% / 0.07; /* background of the current change */ + --current: 212.8 100% 42%; /* edge of the current change: the selection blue */ + --current-tint: 212.8 100% 50% / 0.07; /* background of the current change */ --hover-tint: 215 20% 50% / 0.05; --warning-ton-2: 45 100% 88%; @@ -325,8 +325,8 @@ --changed: 38 70% 48%; --changed-ink: 40 95% 72%; - --current: 0 0% 93%; - --current-tint: 0 0% 100% / 0.06; + --current: 210 100% 66%; + --current-tint: 210 100% 66% / 0.1; --hover-tint: 0 0% 100% / 0.04; --warning-ton-2: 42 70% 24%; @@ -1016,6 +1016,72 @@ margin: 0 auto; padding: 44px 0 40px; } +/* The first screen: the hero centred in the space above "How it works", which sits at the + bottom edge, with a quiet way on to the rest. */ +.landing-more { + display: none; +} +@media (min-width: 768px) and (min-height: 640px) { + .landing-inner { + padding-top: 0; + } + .landing-first { + min-height: calc(100dvh - var(--topbar-h)); + display: flex; + flex-direction: column; + } + .landing-first > .landing-hero { + flex: 1 0 auto; + display: flex; + flex-direction: column; + justify-content: center; + padding: 40px 0; + } + .landing-first > .landing-section { + margin-top: 0; + } + .landing-more { + display: inline-flex; + align-items: center; + justify-content: center; + align-self: center; + width: 44px; + height: 44px; + margin: 12px 0 8px; + border: 0; + border-radius: 999px; + background: transparent; + color: hsl(var(--muted-foreground)); + cursor: pointer; + } + .landing-more:hover { + color: hsl(var(--foreground)); + background: hsl(var(--ton-2)); + } + .landing-more .icon { + width: 22px; + height: 22px; + stroke-width: 2; + } +} +/* Laptop screens (768–860px high): a tighter first screen so the arrow stays visible */ +@media (min-width: 768px) and (min-height: 640px) and (max-height: 860px) { + .landing-first > .landing-hero { + padding: 20px 0; + } + .landing-first > .landing-section { + padding-top: 20px; + } + .landing-first .how-steps { + margin-top: 12px; + } + .landing-first .landing-trust { + margin-top: 18px; + } + .landing-more { + margin: 4px 0; + } +} .landing-title { max-width: 30ch; @@ -2192,6 +2258,17 @@ justify-content: space-between; gap: var(--sp-2); } +/* Collapses the docked list (desktop); the list button in the top bar brings it back */ +.rail-close { + margin-right: -8px; + color: hsl(var(--muted-foreground)); +} +body:not(.tier-desktop) .rail-close { + display: none; +} +#btn-list[aria-expanded="true"] { + background: hsl(var(--ton-2)); +} .list-title { font-size: var(--text-title); font-weight: 600; @@ -3679,7 +3756,7 @@

Dokumente

- + -
+

Was es kann – und was nicht

@@ -3899,6 +3979,7 @@

Häufige Fragen

0 Änderungen

+
@@ -4149,6 +4230,7 @@

hfFilterBtn: 'Kopf-/Fußzeilen ausblenden', hfHiddenCount: '{n} ausgeblendet', sidebarToggle: 'Änderungsliste', + listHide: 'Liste ausblenden', themeLabel: 'Farbschema', themeLight: 'Hell', themeDark: 'Dunkel', @@ -4456,6 +4538,7 @@

Ihre Daten

slotClearLeft: 'Alte Fassung entfernen', slotClearRight: 'Neue Fassung entfernen', howTitle: 'So funktioniert’s', + landingMore: 'Mehr erfahren', how1Title: 'Zwei Fassungen wählen', how1Text: 'Als PDF, Word-Datei oder eingefügten Text. Die Dateien werden nur in diesem Browser-Tab gelesen.', how2Title: 'Änderungen durchgehen', @@ -4546,6 +4629,7 @@

Ihre Daten

hfFilterBtn: 'Hide headers & footers', hfHiddenCount: '{n} hidden', sidebarToggle: 'List of changes', + listHide: 'Hide list', themeLabel: 'Colour scheme', themeLight: 'Light', themeDark: 'Dark', @@ -4853,6 +4937,7 @@

Your data

slotClearLeft: 'Remove old version', slotClearRight: 'Remove new version', howTitle: 'How it works', + landingMore: 'Learn more', how1Title: 'Choose two versions', how1Text: 'As PDF, Word file or pasted text. The files are only read inside this browser tab.', how2Title: 'Go through the changes', @@ -7756,6 +7841,20 @@

Your data

document.querySelectorAll('.btn-load-sample').forEach(btn => { btn.addEventListener('click', loadSampleComparison); }); + + // Start page: from the first screen on to what Doc Diff can and cannot do. + const more = document.getElementById('landing-more'); + if (more) { + more.addEventListener('click', () => { + const next = document.getElementById('landing-scope'); + const pad = document.getElementById('empty-launchpad'); + const heading = next.querySelector('h2'); + heading.setAttribute('tabindex', '-1'); + heading.focus({ preventScroll: true }); + const top = next.getBoundingClientRect().top - pad.getBoundingClientRect().top + pad.scrollTop - 16; + pad.scrollTo({ top, behavior: prefersReducedMotion() ? 'auto' : 'smooth' }); + }); + } } // Moved blocks keep type 'deleted' (old position) / 'inserted' (new position); this note @@ -13991,6 +14090,9 @@

${escapeHtml(t('exportRedlineHeading'))}

const docked = currentTier === 'desktop'; document.body.classList.toggle('sidebar-collapsed', docked && !state.sidebarOpen); setMenuChecked('btn-toggle-sidebar', state.sidebarOpen); + // On the desktop the list button in the top bar shows and hides the docked list. + if (docked) document.getElementById('btn-list').setAttribute('aria-expanded', String(state.sidebarOpen)); + else if (!document.body.classList.contains('list-open')) document.getElementById('btn-list').setAttribute('aria-expanded', 'false'); scheduleRulerDraw(); } @@ -14036,7 +14138,8 @@

${escapeHtml(t('exportRedlineHeading'))}

} document.getElementById('btn-list').addEventListener('click', e => { e.stopPropagation(); - if (document.body.classList.contains('list-open')) closeListSheet(); + if (currentTier === 'desktop') toggleSidebar(); + else if (document.body.classList.contains('list-open')) closeListSheet(); else openListSheet(); }); document.getElementById('mob-step').addEventListener('click', e => { @@ -14044,6 +14147,11 @@

${escapeHtml(t('exportRedlineHeading'))}

openListSheet(); }); document.getElementById('btn-close-sidebar-sheet').addEventListener('click', () => closeListSheet()); +document.getElementById('btn-close-rail').addEventListener('click', () => { + if (currentTier !== 'desktop' || !state.sidebarOpen) return; + toggleSidebar(); + document.getElementById('btn-list').focus({ preventScroll: true }); +}); document.getElementById('mobile-sheet-backdrop').addEventListener('click', () => { if (openMenuState) closeMenu(openMenuState.id, true); else closeListSheet(); diff --git a/site/en/index.html b/site/en/index.html index b198db7..dfa3ed4 100644 --- a/site/en/index.html +++ b/site/en/index.html @@ -276,8 +276,8 @@ --changed: 34 90% 46%; /* amber edge of a changed paragraph */ --changed-ink: 28 90% 25%; - --current: 215 25% 13%; /* edge of the current change */ - --current-tint: 215 30% 50% / 0.07; /* background of the current change */ + --current: 212.8 100% 42%; /* edge of the current change: the selection blue */ + --current-tint: 212.8 100% 50% / 0.07; /* background of the current change */ --hover-tint: 215 20% 50% / 0.05; --warning-ton-2: 45 100% 88%; @@ -328,8 +328,8 @@ --changed: 38 70% 48%; --changed-ink: 40 95% 72%; - --current: 0 0% 93%; - --current-tint: 0 0% 100% / 0.06; + --current: 210 100% 66%; + --current-tint: 210 100% 66% / 0.1; --hover-tint: 0 0% 100% / 0.04; --warning-ton-2: 42 70% 24%; @@ -1019,6 +1019,72 @@ margin: 0 auto; padding: 44px 0 40px; } +/* The first screen: the hero centred in the space above "How it works", which sits at the + bottom edge, with a quiet way on to the rest. */ +.landing-more { + display: none; +} +@media (min-width: 768px) and (min-height: 640px) { + .landing-inner { + padding-top: 0; + } + .landing-first { + min-height: calc(100dvh - var(--topbar-h)); + display: flex; + flex-direction: column; + } + .landing-first > .landing-hero { + flex: 1 0 auto; + display: flex; + flex-direction: column; + justify-content: center; + padding: 40px 0; + } + .landing-first > .landing-section { + margin-top: 0; + } + .landing-more { + display: inline-flex; + align-items: center; + justify-content: center; + align-self: center; + width: 44px; + height: 44px; + margin: 12px 0 8px; + border: 0; + border-radius: 999px; + background: transparent; + color: hsl(var(--muted-foreground)); + cursor: pointer; + } + .landing-more:hover { + color: hsl(var(--foreground)); + background: hsl(var(--ton-2)); + } + .landing-more .icon { + width: 22px; + height: 22px; + stroke-width: 2; + } +} +/* Laptop screens (768–860px high): a tighter first screen so the arrow stays visible */ +@media (min-width: 768px) and (min-height: 640px) and (max-height: 860px) { + .landing-first > .landing-hero { + padding: 20px 0; + } + .landing-first > .landing-section { + padding-top: 20px; + } + .landing-first .how-steps { + margin-top: 12px; + } + .landing-first .landing-trust { + margin-top: 18px; + } + .landing-more { + margin: 4px 0; + } +} .landing-title { max-width: 30ch; @@ -2195,6 +2261,17 @@ justify-content: space-between; gap: var(--sp-2); } +/* Collapses the docked list (desktop); the list button in the top bar brings it back */ +.rail-close { + margin-right: -8px; + color: hsl(var(--muted-foreground)); +} +body:not(.tier-desktop) .rail-close { + display: none; +} +#btn-list[aria-expanded="true"] { + background: hsl(var(--ton-2)); +} .list-title { font-size: var(--text-title); font-weight: 600; @@ -3682,7 +3759,7 @@

Documents

- +
-
+

What it can do – and what it can’t

@@ -3902,6 +3982,7 @@

Frequently asked questions

0 Änderungen

+
@@ -4152,6 +4233,7 @@

hfFilterBtn: 'Kopf-/Fußzeilen ausblenden', hfHiddenCount: '{n} ausgeblendet', sidebarToggle: 'Änderungsliste', + listHide: 'Liste ausblenden', themeLabel: 'Farbschema', themeLight: 'Hell', themeDark: 'Dunkel', @@ -4459,6 +4541,7 @@

Ihre Daten

slotClearLeft: 'Alte Fassung entfernen', slotClearRight: 'Neue Fassung entfernen', howTitle: 'So funktioniert’s', + landingMore: 'Mehr erfahren', how1Title: 'Zwei Fassungen wählen', how1Text: 'Als PDF, Word-Datei oder eingefügten Text. Die Dateien werden nur in diesem Browser-Tab gelesen.', how2Title: 'Änderungen durchgehen', @@ -4549,6 +4632,7 @@

Ihre Daten

hfFilterBtn: 'Hide headers & footers', hfHiddenCount: '{n} hidden', sidebarToggle: 'List of changes', + listHide: 'Hide list', themeLabel: 'Colour scheme', themeLight: 'Light', themeDark: 'Dark', @@ -4856,6 +4940,7 @@

Your data

slotClearLeft: 'Remove old version', slotClearRight: 'Remove new version', howTitle: 'How it works', + landingMore: 'Learn more', how1Title: 'Choose two versions', how1Text: 'As PDF, Word file or pasted text. The files are only read inside this browser tab.', how2Title: 'Go through the changes', @@ -7759,6 +7844,20 @@

Your data

document.querySelectorAll('.btn-load-sample').forEach(btn => { btn.addEventListener('click', loadSampleComparison); }); + + // Start page: from the first screen on to what Doc Diff can and cannot do. + const more = document.getElementById('landing-more'); + if (more) { + more.addEventListener('click', () => { + const next = document.getElementById('landing-scope'); + const pad = document.getElementById('empty-launchpad'); + const heading = next.querySelector('h2'); + heading.setAttribute('tabindex', '-1'); + heading.focus({ preventScroll: true }); + const top = next.getBoundingClientRect().top - pad.getBoundingClientRect().top + pad.scrollTop - 16; + pad.scrollTo({ top, behavior: prefersReducedMotion() ? 'auto' : 'smooth' }); + }); + } } // Moved blocks keep type 'deleted' (old position) / 'inserted' (new position); this note @@ -13994,6 +14093,9 @@

${escapeHtml(t('exportRedlineHeading'))}

const docked = currentTier === 'desktop'; document.body.classList.toggle('sidebar-collapsed', docked && !state.sidebarOpen); setMenuChecked('btn-toggle-sidebar', state.sidebarOpen); + // On the desktop the list button in the top bar shows and hides the docked list. + if (docked) document.getElementById('btn-list').setAttribute('aria-expanded', String(state.sidebarOpen)); + else if (!document.body.classList.contains('list-open')) document.getElementById('btn-list').setAttribute('aria-expanded', 'false'); scheduleRulerDraw(); } @@ -14039,7 +14141,8 @@

${escapeHtml(t('exportRedlineHeading'))}

} document.getElementById('btn-list').addEventListener('click', e => { e.stopPropagation(); - if (document.body.classList.contains('list-open')) closeListSheet(); + if (currentTier === 'desktop') toggleSidebar(); + else if (document.body.classList.contains('list-open')) closeListSheet(); else openListSheet(); }); document.getElementById('mob-step').addEventListener('click', e => { @@ -14047,6 +14150,11 @@

${escapeHtml(t('exportRedlineHeading'))}

openListSheet(); }); document.getElementById('btn-close-sidebar-sheet').addEventListener('click', () => closeListSheet()); +document.getElementById('btn-close-rail').addEventListener('click', () => { + if (currentTier !== 'desktop' || !state.sidebarOpen) return; + toggleSidebar(); + document.getElementById('btn-list').focus({ preventScroll: true }); +}); document.getElementById('mobile-sheet-backdrop').addEventListener('click', () => { if (openMenuState) closeMenu(openMenuState.id, true); else closeListSheet(); diff --git a/site/index.html b/site/index.html index c1a09c3..18ac7f0 100644 --- a/site/index.html +++ b/site/index.html @@ -276,8 +276,8 @@ --changed: 34 90% 46%; /* amber edge of a changed paragraph */ --changed-ink: 28 90% 25%; - --current: 215 25% 13%; /* edge of the current change */ - --current-tint: 215 30% 50% / 0.07; /* background of the current change */ + --current: 212.8 100% 42%; /* edge of the current change: the selection blue */ + --current-tint: 212.8 100% 50% / 0.07; /* background of the current change */ --hover-tint: 215 20% 50% / 0.05; --warning-ton-2: 45 100% 88%; @@ -328,8 +328,8 @@ --changed: 38 70% 48%; --changed-ink: 40 95% 72%; - --current: 0 0% 93%; - --current-tint: 0 0% 100% / 0.06; + --current: 210 100% 66%; + --current-tint: 210 100% 66% / 0.1; --hover-tint: 0 0% 100% / 0.04; --warning-ton-2: 42 70% 24%; @@ -1019,6 +1019,72 @@ margin: 0 auto; padding: 44px 0 40px; } +/* The first screen: the hero centred in the space above "How it works", which sits at the + bottom edge, with a quiet way on to the rest. */ +.landing-more { + display: none; +} +@media (min-width: 768px) and (min-height: 640px) { + .landing-inner { + padding-top: 0; + } + .landing-first { + min-height: calc(100dvh - var(--topbar-h)); + display: flex; + flex-direction: column; + } + .landing-first > .landing-hero { + flex: 1 0 auto; + display: flex; + flex-direction: column; + justify-content: center; + padding: 40px 0; + } + .landing-first > .landing-section { + margin-top: 0; + } + .landing-more { + display: inline-flex; + align-items: center; + justify-content: center; + align-self: center; + width: 44px; + height: 44px; + margin: 12px 0 8px; + border: 0; + border-radius: 999px; + background: transparent; + color: hsl(var(--muted-foreground)); + cursor: pointer; + } + .landing-more:hover { + color: hsl(var(--foreground)); + background: hsl(var(--ton-2)); + } + .landing-more .icon { + width: 22px; + height: 22px; + stroke-width: 2; + } +} +/* Laptop screens (768–860px high): a tighter first screen so the arrow stays visible */ +@media (min-width: 768px) and (min-height: 640px) and (max-height: 860px) { + .landing-first > .landing-hero { + padding: 20px 0; + } + .landing-first > .landing-section { + padding-top: 20px; + } + .landing-first .how-steps { + margin-top: 12px; + } + .landing-first .landing-trust { + margin-top: 18px; + } + .landing-more { + margin: 4px 0; + } +} .landing-title { max-width: 30ch; @@ -2195,6 +2261,17 @@ justify-content: space-between; gap: var(--sp-2); } +/* Collapses the docked list (desktop); the list button in the top bar brings it back */ +.rail-close { + margin-right: -8px; + color: hsl(var(--muted-foreground)); +} +body:not(.tier-desktop) .rail-close { + display: none; +} +#btn-list[aria-expanded="true"] { + background: hsl(var(--ton-2)); +} .list-title { font-size: var(--text-title); font-weight: 600; @@ -3682,7 +3759,7 @@

Dokumente

- +
-
+

Was es kann – und was nicht

@@ -3902,6 +3982,7 @@

Häufige Fragen

0 Änderungen

+
@@ -4152,6 +4233,7 @@

hfFilterBtn: 'Kopf-/Fußzeilen ausblenden', hfHiddenCount: '{n} ausgeblendet', sidebarToggle: 'Änderungsliste', + listHide: 'Liste ausblenden', themeLabel: 'Farbschema', themeLight: 'Hell', themeDark: 'Dunkel', @@ -4459,6 +4541,7 @@

Ihre Daten

slotClearLeft: 'Alte Fassung entfernen', slotClearRight: 'Neue Fassung entfernen', howTitle: 'So funktioniert’s', + landingMore: 'Mehr erfahren', how1Title: 'Zwei Fassungen wählen', how1Text: 'Als PDF, Word-Datei oder eingefügten Text. Die Dateien werden nur in diesem Browser-Tab gelesen.', how2Title: 'Änderungen durchgehen', @@ -4549,6 +4632,7 @@

Ihre Daten

hfFilterBtn: 'Hide headers & footers', hfHiddenCount: '{n} hidden', sidebarToggle: 'List of changes', + listHide: 'Hide list', themeLabel: 'Colour scheme', themeLight: 'Light', themeDark: 'Dark', @@ -4856,6 +4940,7 @@

Your data

slotClearLeft: 'Remove old version', slotClearRight: 'Remove new version', howTitle: 'How it works', + landingMore: 'Learn more', how1Title: 'Choose two versions', how1Text: 'As PDF, Word file or pasted text. The files are only read inside this browser tab.', how2Title: 'Go through the changes', @@ -7759,6 +7844,20 @@

Your data

document.querySelectorAll('.btn-load-sample').forEach(btn => { btn.addEventListener('click', loadSampleComparison); }); + + // Start page: from the first screen on to what Doc Diff can and cannot do. + const more = document.getElementById('landing-more'); + if (more) { + more.addEventListener('click', () => { + const next = document.getElementById('landing-scope'); + const pad = document.getElementById('empty-launchpad'); + const heading = next.querySelector('h2'); + heading.setAttribute('tabindex', '-1'); + heading.focus({ preventScroll: true }); + const top = next.getBoundingClientRect().top - pad.getBoundingClientRect().top + pad.scrollTop - 16; + pad.scrollTo({ top, behavior: prefersReducedMotion() ? 'auto' : 'smooth' }); + }); + } } // Moved blocks keep type 'deleted' (old position) / 'inserted' (new position); this note @@ -13994,6 +14093,9 @@

${escapeHtml(t('exportRedlineHeading'))}

const docked = currentTier === 'desktop'; document.body.classList.toggle('sidebar-collapsed', docked && !state.sidebarOpen); setMenuChecked('btn-toggle-sidebar', state.sidebarOpen); + // On the desktop the list button in the top bar shows and hides the docked list. + if (docked) document.getElementById('btn-list').setAttribute('aria-expanded', String(state.sidebarOpen)); + else if (!document.body.classList.contains('list-open')) document.getElementById('btn-list').setAttribute('aria-expanded', 'false'); scheduleRulerDraw(); } @@ -14039,7 +14141,8 @@

${escapeHtml(t('exportRedlineHeading'))}

} document.getElementById('btn-list').addEventListener('click', e => { e.stopPropagation(); - if (document.body.classList.contains('list-open')) closeListSheet(); + if (currentTier === 'desktop') toggleSidebar(); + else if (document.body.classList.contains('list-open')) closeListSheet(); else openListSheet(); }); document.getElementById('mob-step').addEventListener('click', e => { @@ -14047,6 +14150,11 @@

${escapeHtml(t('exportRedlineHeading'))}

openListSheet(); }); document.getElementById('btn-close-sidebar-sheet').addEventListener('click', () => closeListSheet()); +document.getElementById('btn-close-rail').addEventListener('click', () => { + if (currentTier !== 'desktop' || !state.sidebarOpen) return; + toggleSidebar(); + document.getElementById('btn-list').focus({ preventScroll: true }); +}); document.getElementById('mobile-sheet-backdrop').addEventListener('click', () => { if (openMenuState) closeMenu(openMenuState.id, true); else closeListSheet(); diff --git a/src/js/01-i18n.js b/src/js/01-i18n.js index 9e92e5a..c0fb175 100644 --- a/src/js/01-i18n.js +++ b/src/js/01-i18n.js @@ -45,6 +45,7 @@ const I18N = { hfFilterBtn: 'Kopf-/Fußzeilen ausblenden', hfHiddenCount: '{n} ausgeblendet', sidebarToggle: 'Änderungsliste', + listHide: 'Liste ausblenden', themeLabel: 'Farbschema', themeLight: 'Hell', themeDark: 'Dunkel', @@ -352,6 +353,7 @@ const I18N = { slotClearLeft: 'Alte Fassung entfernen', slotClearRight: 'Neue Fassung entfernen', howTitle: 'So funktioniert’s', + landingMore: 'Mehr erfahren', how1Title: 'Zwei Fassungen wählen', how1Text: 'Als PDF, Word-Datei oder eingefügten Text. Die Dateien werden nur in diesem Browser-Tab gelesen.', how2Title: 'Änderungen durchgehen', @@ -442,6 +444,7 @@ const I18N = { hfFilterBtn: 'Hide headers & footers', hfHiddenCount: '{n} hidden', sidebarToggle: 'List of changes', + listHide: 'Hide list', themeLabel: 'Colour scheme', themeLight: 'Light', themeDark: 'Dark', @@ -749,6 +752,7 @@ const I18N = { slotClearLeft: 'Remove old version', slotClearRight: 'Remove new version', howTitle: 'How it works', + landingMore: 'Learn more', how1Title: 'Choose two versions', how1Text: 'As PDF, Word file or pasted text. The files are only read inside this browser tab.', how2Title: 'Go through the changes', diff --git a/src/js/06-compare.js b/src/js/06-compare.js index ea0dcb2..b51042e 100644 --- a/src/js/06-compare.js +++ b/src/js/06-compare.js @@ -267,6 +267,20 @@ function bindEmptyStateButtons() { document.querySelectorAll('.btn-load-sample').forEach(btn => { btn.addEventListener('click', loadSampleComparison); }); + + // Start page: from the first screen on to what Doc Diff can and cannot do. + const more = document.getElementById('landing-more'); + if (more) { + more.addEventListener('click', () => { + const next = document.getElementById('landing-scope'); + const pad = document.getElementById('empty-launchpad'); + const heading = next.querySelector('h2'); + heading.setAttribute('tabindex', '-1'); + heading.focus({ preventScroll: true }); + const top = next.getBoundingClientRect().top - pad.getBoundingClientRect().top + pad.scrollTop - 16; + pad.scrollTo({ top, behavior: prefersReducedMotion() ? 'auto' : 'smooth' }); + }); + } } // Moved blocks keep type 'deleted' (old position) / 'inserted' (new position); this note diff --git a/src/js/10-controls.js b/src/js/10-controls.js index 8057df0..62e9e95 100644 --- a/src/js/10-controls.js +++ b/src/js/10-controls.js @@ -375,6 +375,9 @@ function applySidebarState() { const docked = currentTier === 'desktop'; document.body.classList.toggle('sidebar-collapsed', docked && !state.sidebarOpen); setMenuChecked('btn-toggle-sidebar', state.sidebarOpen); + // On the desktop the list button in the top bar shows and hides the docked list. + if (docked) document.getElementById('btn-list').setAttribute('aria-expanded', String(state.sidebarOpen)); + else if (!document.body.classList.contains('list-open')) document.getElementById('btn-list').setAttribute('aria-expanded', 'false'); scheduleRulerDraw(); } @@ -420,7 +423,8 @@ function closeListSheet(returnFocus = true) { } document.getElementById('btn-list').addEventListener('click', e => { e.stopPropagation(); - if (document.body.classList.contains('list-open')) closeListSheet(); + if (currentTier === 'desktop') toggleSidebar(); + else if (document.body.classList.contains('list-open')) closeListSheet(); else openListSheet(); }); document.getElementById('mob-step').addEventListener('click', e => { @@ -428,6 +432,11 @@ document.getElementById('mob-step').addEventListener('click', e => { openListSheet(); }); document.getElementById('btn-close-sidebar-sheet').addEventListener('click', () => closeListSheet()); +document.getElementById('btn-close-rail').addEventListener('click', () => { + if (currentTier !== 'desktop' || !state.sidebarOpen) return; + toggleSidebar(); + document.getElementById('btn-list').focus({ preventScroll: true }); +}); document.getElementById('mobile-sheet-backdrop').addEventListener('click', () => { if (openMenuState) closeMenu(openMenuState.id, true); else closeListSheet(); diff --git a/src/styles.css b/src/styles.css index 4e74049..28b70f8 100644 --- a/src/styles.css +++ b/src/styles.css @@ -98,8 +98,8 @@ --changed: 34 90% 46%; /* amber edge of a changed paragraph */ --changed-ink: 28 90% 25%; - --current: 215 25% 13%; /* edge of the current change */ - --current-tint: 215 30% 50% / 0.07; /* background of the current change */ + --current: 212.8 100% 42%; /* edge of the current change: the selection blue */ + --current-tint: 212.8 100% 50% / 0.07; /* background of the current change */ --hover-tint: 215 20% 50% / 0.05; --warning-ton-2: 45 100% 88%; @@ -150,8 +150,8 @@ --changed: 38 70% 48%; --changed-ink: 40 95% 72%; - --current: 0 0% 93%; - --current-tint: 0 0% 100% / 0.06; + --current: 210 100% 66%; + --current-tint: 210 100% 66% / 0.1; --hover-tint: 0 0% 100% / 0.04; --warning-ton-2: 42 70% 24%; @@ -841,6 +841,72 @@ body.is-comparing .empty-launchpad { margin: 0 auto; padding: 44px 0 40px; } +/* The first screen: the hero centred in the space above "How it works", which sits at the + bottom edge, with a quiet way on to the rest. */ +.landing-more { + display: none; +} +@media (min-width: 768px) and (min-height: 640px) { + .landing-inner { + padding-top: 0; + } + .landing-first { + min-height: calc(100dvh - var(--topbar-h)); + display: flex; + flex-direction: column; + } + .landing-first > .landing-hero { + flex: 1 0 auto; + display: flex; + flex-direction: column; + justify-content: center; + padding: 40px 0; + } + .landing-first > .landing-section { + margin-top: 0; + } + .landing-more { + display: inline-flex; + align-items: center; + justify-content: center; + align-self: center; + width: 44px; + height: 44px; + margin: 12px 0 8px; + border: 0; + border-radius: 999px; + background: transparent; + color: hsl(var(--muted-foreground)); + cursor: pointer; + } + .landing-more:hover { + color: hsl(var(--foreground)); + background: hsl(var(--ton-2)); + } + .landing-more .icon { + width: 22px; + height: 22px; + stroke-width: 2; + } +} +/* Laptop screens (768–860px high): a tighter first screen so the arrow stays visible */ +@media (min-width: 768px) and (min-height: 640px) and (max-height: 860px) { + .landing-first > .landing-hero { + padding: 20px 0; + } + .landing-first > .landing-section { + padding-top: 20px; + } + .landing-first .how-steps { + margin-top: 12px; + } + .landing-first .landing-trust { + margin-top: 18px; + } + .landing-more { + margin: 4px 0; + } +} .landing-title { max-width: 30ch; @@ -2017,6 +2083,17 @@ body.tier-phone .bottom-bar .review-bar { justify-content: space-between; gap: var(--sp-2); } +/* Collapses the docked list (desktop); the list button in the top bar brings it back */ +.rail-close { + margin-right: -8px; + color: hsl(var(--muted-foreground)); +} +body:not(.tier-desktop) .rail-close { + display: none; +} +#btn-list[aria-expanded="true"] { + background: hsl(var(--ton-2)); +} .list-title { font-size: var(--text-title); font-weight: 600; diff --git a/src/template.html b/src/template.html index 205289d..bf6fb89 100644 --- a/src/template.html +++ b/src/template.html @@ -231,7 +231,7 @@

Dokumente

- +
-
+

Was es kann – und was nicht

@@ -447,6 +450,7 @@

Häufige Fragen

0 Änderungen

+
From a4427f1b2af2f2f10f42b35dba2f4e4a03771f00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Hermes?= Date: Fri, 23 Oct 2026 08:16:31 +0200 Subject: [PATCH 2/5] Reviewed changes look done, and a plain sidebar icon toggles the list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Accepted: the new wording reads as plain text with a green edge (the removed words stay quietly struck through on the old side); before, it turned grey and looked disabled. Rejected: a solid neutral edge instead of a dotted one, and the ✗ in the text colour. Only colours change. - Desktop: a sidebar icon at the right end of the top bar shows and hides the list of changes, instead of the "List 20" button and a second button in the list header. Tablets keep the "List" button for the sheet. Co-Authored-By: Claude Opus 5.5 --- DocDiff.html | 56 +++++++++++++++++++------------------------ site/en/index.html | 56 +++++++++++++++++++------------------------ site/index.html | 56 +++++++++++++++++++------------------------ src/js/01-i18n.js | 2 -- src/js/10-controls.js | 14 ++++------- src/styles.css | 36 +++++++++++++++------------- src/template.html | 4 ++-- 7 files changed, 100 insertions(+), 124 deletions(-) diff --git a/DocDiff.html b/DocDiff.html index d90e1d6..72484f0 100644 --- a/DocDiff.html +++ b/DocDiff.html @@ -1869,13 +1869,19 @@ text-decoration-style: dotted; } -/* Reviewed: accepted changes are muted; the mark sits in the margin of the new version */ +/* Reviewed: a decided change reads as finished text. Accepted: the new wording is plain text + with a green edge; the removed words stay quietly struck through, so the change is still + visible. Only colours change, so reviewing never moves any text. */ .clause.is-accepted { - border-left-color: hsl(var(--muted-foreground) / 0.3); + border-left-color: hsl(var(--success)); background: transparent; } -.clause.is-accepted del.tok-del, .clause.is-accepted ins.tok-ins { + background: transparent; + color: inherit; + text-decoration-color: transparent; +} +.clause.is-accepted del.tok-del { background: transparent; color: hsl(var(--muted-foreground)); } @@ -1888,8 +1894,9 @@ font-weight: 600; color: hsl(var(--muted-foreground)); } +/* Rejected: the old wording is back as plain text, with a solid neutral edge */ .diff-row-anchor.has-ghost .clause { - border-left: 2px dotted hsl(var(--muted-foreground) / 0.6); + border-left: 2px solid hsl(var(--muted-foreground) / 0.7); } .diff-row-anchor.has-ghost .clause.is-active { border-left-style: solid; @@ -2061,7 +2068,7 @@ stroke-width: 2.2; } .review-status.is-accepted .rs-mark { color: hsl(var(--success-ink)); } -.review-status.is-rejected .rs-mark { color: hsl(var(--muted-foreground)); } +.review-status.is-rejected .rs-mark { color: hsl(var(--foreground)); } .ra-undo { display: inline-flex; align-items: center; @@ -2258,17 +2265,10 @@ justify-content: space-between; gap: var(--sp-2); } -/* Collapses the docked list (desktop); the list button in the top bar brings it back */ -.rail-close { - margin-right: -8px; - color: hsl(var(--muted-foreground)); -} -body:not(.tier-desktop) .rail-close { +/* Shows and hides the docked list of changes (desktop only; tablets and phones use a sheet) */ +body:not(.tier-desktop) #btn-rail { display: none; } -#btn-list[aria-expanded="true"] { - background: hsl(var(--ton-2)); -} .list-title { font-size: var(--text-title); font-weight: 600; @@ -2353,9 +2353,11 @@ .nav-item.ins { border-left-color: hsl(var(--success)); } .nav-item.del { border-left-color: hsl(var(--destructive)); } .nav-item.moved { border-left-style: dashed; border-left-color: hsl(var(--muted-foreground) / 0.6); } -.nav-item.is-accepted, +.nav-item.is-accepted { + border-left-color: hsl(var(--success)); +} .nav-item.is-rejected { - border-left-color: hsl(var(--muted-foreground) / 0.35); + border-left-color: hsl(var(--muted-foreground) / 0.7); } .nav-item.is-active { background: hsl(var(--current-tint)); @@ -2421,7 +2423,7 @@ stroke-width: 2.4; } .nav-status.is-accepted { color: hsl(var(--success-ink)); } -.nav-status.is-rejected { color: hsl(var(--muted-foreground)); } +.nav-status.is-rejected { color: hsl(var(--foreground)); } .nav-item.is-accepted .nav-item-ref, .nav-item.is-rejected .nav-item-ref, .nav-item.is-accepted .nav-item-snippet, @@ -3756,7 +3758,7 @@

Dokumente

-
+ @@ -3979,7 +3982,6 @@

Häufige Fragen

0 Änderungen

-
@@ -4230,7 +4232,6 @@

hfFilterBtn: 'Kopf-/Fußzeilen ausblenden', hfHiddenCount: '{n} ausgeblendet', sidebarToggle: 'Änderungsliste', - listHide: 'Liste ausblenden', themeLabel: 'Farbschema', themeLight: 'Hell', themeDark: 'Dunkel', @@ -4629,7 +4630,6 @@

Ihre Daten

hfFilterBtn: 'Hide headers & footers', hfHiddenCount: '{n} hidden', sidebarToggle: 'List of changes', - listHide: 'Hide list', themeLabel: 'Colour scheme', themeLight: 'Light', themeDark: 'Dark', @@ -14090,9 +14090,8 @@

${escapeHtml(t('exportRedlineHeading'))}

const docked = currentTier === 'desktop'; document.body.classList.toggle('sidebar-collapsed', docked && !state.sidebarOpen); setMenuChecked('btn-toggle-sidebar', state.sidebarOpen); - // On the desktop the list button in the top bar shows and hides the docked list. - if (docked) document.getElementById('btn-list').setAttribute('aria-expanded', String(state.sidebarOpen)); - else if (!document.body.classList.contains('list-open')) document.getElementById('btn-list').setAttribute('aria-expanded', 'false'); + // On the desktop the sidebar button at the right end of the top bar shows and hides the list. + document.getElementById('btn-rail').setAttribute('aria-expanded', String(docked && state.sidebarOpen)); scheduleRulerDraw(); } @@ -14138,8 +14137,7 @@

${escapeHtml(t('exportRedlineHeading'))}

} document.getElementById('btn-list').addEventListener('click', e => { e.stopPropagation(); - if (currentTier === 'desktop') toggleSidebar(); - else if (document.body.classList.contains('list-open')) closeListSheet(); + if (document.body.classList.contains('list-open')) closeListSheet(); else openListSheet(); }); document.getElementById('mob-step').addEventListener('click', e => { @@ -14147,11 +14145,7 @@

${escapeHtml(t('exportRedlineHeading'))}

openListSheet(); }); document.getElementById('btn-close-sidebar-sheet').addEventListener('click', () => closeListSheet()); -document.getElementById('btn-close-rail').addEventListener('click', () => { - if (currentTier !== 'desktop' || !state.sidebarOpen) return; - toggleSidebar(); - document.getElementById('btn-list').focus({ preventScroll: true }); -}); +document.getElementById('btn-rail').addEventListener('click', () => toggleSidebar()); document.getElementById('mobile-sheet-backdrop').addEventListener('click', () => { if (openMenuState) closeMenu(openMenuState.id, true); else closeListSheet(); diff --git a/site/en/index.html b/site/en/index.html index dfa3ed4..5165bbe 100644 --- a/site/en/index.html +++ b/site/en/index.html @@ -1872,13 +1872,19 @@ text-decoration-style: dotted; } -/* Reviewed: accepted changes are muted; the mark sits in the margin of the new version */ +/* Reviewed: a decided change reads as finished text. Accepted: the new wording is plain text + with a green edge; the removed words stay quietly struck through, so the change is still + visible. Only colours change, so reviewing never moves any text. */ .clause.is-accepted { - border-left-color: hsl(var(--muted-foreground) / 0.3); + border-left-color: hsl(var(--success)); background: transparent; } -.clause.is-accepted del.tok-del, .clause.is-accepted ins.tok-ins { + background: transparent; + color: inherit; + text-decoration-color: transparent; +} +.clause.is-accepted del.tok-del { background: transparent; color: hsl(var(--muted-foreground)); } @@ -1891,8 +1897,9 @@ font-weight: 600; color: hsl(var(--muted-foreground)); } +/* Rejected: the old wording is back as plain text, with a solid neutral edge */ .diff-row-anchor.has-ghost .clause { - border-left: 2px dotted hsl(var(--muted-foreground) / 0.6); + border-left: 2px solid hsl(var(--muted-foreground) / 0.7); } .diff-row-anchor.has-ghost .clause.is-active { border-left-style: solid; @@ -2064,7 +2071,7 @@ stroke-width: 2.2; } .review-status.is-accepted .rs-mark { color: hsl(var(--success-ink)); } -.review-status.is-rejected .rs-mark { color: hsl(var(--muted-foreground)); } +.review-status.is-rejected .rs-mark { color: hsl(var(--foreground)); } .ra-undo { display: inline-flex; align-items: center; @@ -2261,17 +2268,10 @@ justify-content: space-between; gap: var(--sp-2); } -/* Collapses the docked list (desktop); the list button in the top bar brings it back */ -.rail-close { - margin-right: -8px; - color: hsl(var(--muted-foreground)); -} -body:not(.tier-desktop) .rail-close { +/* Shows and hides the docked list of changes (desktop only; tablets and phones use a sheet) */ +body:not(.tier-desktop) #btn-rail { display: none; } -#btn-list[aria-expanded="true"] { - background: hsl(var(--ton-2)); -} .list-title { font-size: var(--text-title); font-weight: 600; @@ -2356,9 +2356,11 @@ .nav-item.ins { border-left-color: hsl(var(--success)); } .nav-item.del { border-left-color: hsl(var(--destructive)); } .nav-item.moved { border-left-style: dashed; border-left-color: hsl(var(--muted-foreground) / 0.6); } -.nav-item.is-accepted, +.nav-item.is-accepted { + border-left-color: hsl(var(--success)); +} .nav-item.is-rejected { - border-left-color: hsl(var(--muted-foreground) / 0.35); + border-left-color: hsl(var(--muted-foreground) / 0.7); } .nav-item.is-active { background: hsl(var(--current-tint)); @@ -2424,7 +2426,7 @@ stroke-width: 2.4; } .nav-status.is-accepted { color: hsl(var(--success-ink)); } -.nav-status.is-rejected { color: hsl(var(--muted-foreground)); } +.nav-status.is-rejected { color: hsl(var(--foreground)); } .nav-item.is-accepted .nav-item-ref, .nav-item.is-rejected .nav-item-ref, .nav-item.is-accepted .nav-item-snippet, @@ -3759,7 +3761,7 @@

Documents

- @@ -3982,7 +3985,6 @@

Frequently asked questions

0 Änderungen

-
@@ -4233,7 +4235,6 @@

hfFilterBtn: 'Kopf-/Fußzeilen ausblenden', hfHiddenCount: '{n} ausgeblendet', sidebarToggle: 'Änderungsliste', - listHide: 'Liste ausblenden', themeLabel: 'Farbschema', themeLight: 'Hell', themeDark: 'Dunkel', @@ -4632,7 +4633,6 @@

Ihre Daten

hfFilterBtn: 'Hide headers & footers', hfHiddenCount: '{n} hidden', sidebarToggle: 'List of changes', - listHide: 'Hide list', themeLabel: 'Colour scheme', themeLight: 'Light', themeDark: 'Dark', @@ -14093,9 +14093,8 @@

${escapeHtml(t('exportRedlineHeading'))}

const docked = currentTier === 'desktop'; document.body.classList.toggle('sidebar-collapsed', docked && !state.sidebarOpen); setMenuChecked('btn-toggle-sidebar', state.sidebarOpen); - // On the desktop the list button in the top bar shows and hides the docked list. - if (docked) document.getElementById('btn-list').setAttribute('aria-expanded', String(state.sidebarOpen)); - else if (!document.body.classList.contains('list-open')) document.getElementById('btn-list').setAttribute('aria-expanded', 'false'); + // On the desktop the sidebar button at the right end of the top bar shows and hides the list. + document.getElementById('btn-rail').setAttribute('aria-expanded', String(docked && state.sidebarOpen)); scheduleRulerDraw(); } @@ -14141,8 +14140,7 @@

${escapeHtml(t('exportRedlineHeading'))}

} document.getElementById('btn-list').addEventListener('click', e => { e.stopPropagation(); - if (currentTier === 'desktop') toggleSidebar(); - else if (document.body.classList.contains('list-open')) closeListSheet(); + if (document.body.classList.contains('list-open')) closeListSheet(); else openListSheet(); }); document.getElementById('mob-step').addEventListener('click', e => { @@ -14150,11 +14148,7 @@

${escapeHtml(t('exportRedlineHeading'))}

openListSheet(); }); document.getElementById('btn-close-sidebar-sheet').addEventListener('click', () => closeListSheet()); -document.getElementById('btn-close-rail').addEventListener('click', () => { - if (currentTier !== 'desktop' || !state.sidebarOpen) return; - toggleSidebar(); - document.getElementById('btn-list').focus({ preventScroll: true }); -}); +document.getElementById('btn-rail').addEventListener('click', () => toggleSidebar()); document.getElementById('mobile-sheet-backdrop').addEventListener('click', () => { if (openMenuState) closeMenu(openMenuState.id, true); else closeListSheet(); diff --git a/site/index.html b/site/index.html index 18ac7f0..a016b6d 100644 --- a/site/index.html +++ b/site/index.html @@ -1872,13 +1872,19 @@ text-decoration-style: dotted; } -/* Reviewed: accepted changes are muted; the mark sits in the margin of the new version */ +/* Reviewed: a decided change reads as finished text. Accepted: the new wording is plain text + with a green edge; the removed words stay quietly struck through, so the change is still + visible. Only colours change, so reviewing never moves any text. */ .clause.is-accepted { - border-left-color: hsl(var(--muted-foreground) / 0.3); + border-left-color: hsl(var(--success)); background: transparent; } -.clause.is-accepted del.tok-del, .clause.is-accepted ins.tok-ins { + background: transparent; + color: inherit; + text-decoration-color: transparent; +} +.clause.is-accepted del.tok-del { background: transparent; color: hsl(var(--muted-foreground)); } @@ -1891,8 +1897,9 @@ font-weight: 600; color: hsl(var(--muted-foreground)); } +/* Rejected: the old wording is back as plain text, with a solid neutral edge */ .diff-row-anchor.has-ghost .clause { - border-left: 2px dotted hsl(var(--muted-foreground) / 0.6); + border-left: 2px solid hsl(var(--muted-foreground) / 0.7); } .diff-row-anchor.has-ghost .clause.is-active { border-left-style: solid; @@ -2064,7 +2071,7 @@ stroke-width: 2.2; } .review-status.is-accepted .rs-mark { color: hsl(var(--success-ink)); } -.review-status.is-rejected .rs-mark { color: hsl(var(--muted-foreground)); } +.review-status.is-rejected .rs-mark { color: hsl(var(--foreground)); } .ra-undo { display: inline-flex; align-items: center; @@ -2261,17 +2268,10 @@ justify-content: space-between; gap: var(--sp-2); } -/* Collapses the docked list (desktop); the list button in the top bar brings it back */ -.rail-close { - margin-right: -8px; - color: hsl(var(--muted-foreground)); -} -body:not(.tier-desktop) .rail-close { +/* Shows and hides the docked list of changes (desktop only; tablets and phones use a sheet) */ +body:not(.tier-desktop) #btn-rail { display: none; } -#btn-list[aria-expanded="true"] { - background: hsl(var(--ton-2)); -} .list-title { font-size: var(--text-title); font-weight: 600; @@ -2356,9 +2356,11 @@ .nav-item.ins { border-left-color: hsl(var(--success)); } .nav-item.del { border-left-color: hsl(var(--destructive)); } .nav-item.moved { border-left-style: dashed; border-left-color: hsl(var(--muted-foreground) / 0.6); } -.nav-item.is-accepted, +.nav-item.is-accepted { + border-left-color: hsl(var(--success)); +} .nav-item.is-rejected { - border-left-color: hsl(var(--muted-foreground) / 0.35); + border-left-color: hsl(var(--muted-foreground) / 0.7); } .nav-item.is-active { background: hsl(var(--current-tint)); @@ -2424,7 +2426,7 @@ stroke-width: 2.4; } .nav-status.is-accepted { color: hsl(var(--success-ink)); } -.nav-status.is-rejected { color: hsl(var(--muted-foreground)); } +.nav-status.is-rejected { color: hsl(var(--foreground)); } .nav-item.is-accepted .nav-item-ref, .nav-item.is-rejected .nav-item-ref, .nav-item.is-accepted .nav-item-snippet, @@ -3759,7 +3761,7 @@

Dokumente

- @@ -3982,7 +3985,6 @@

Häufige Fragen

0 Änderungen

-
@@ -4233,7 +4235,6 @@

hfFilterBtn: 'Kopf-/Fußzeilen ausblenden', hfHiddenCount: '{n} ausgeblendet', sidebarToggle: 'Änderungsliste', - listHide: 'Liste ausblenden', themeLabel: 'Farbschema', themeLight: 'Hell', themeDark: 'Dunkel', @@ -4632,7 +4633,6 @@

Ihre Daten

hfFilterBtn: 'Hide headers & footers', hfHiddenCount: '{n} hidden', sidebarToggle: 'List of changes', - listHide: 'Hide list', themeLabel: 'Colour scheme', themeLight: 'Light', themeDark: 'Dark', @@ -14093,9 +14093,8 @@

${escapeHtml(t('exportRedlineHeading'))}

const docked = currentTier === 'desktop'; document.body.classList.toggle('sidebar-collapsed', docked && !state.sidebarOpen); setMenuChecked('btn-toggle-sidebar', state.sidebarOpen); - // On the desktop the list button in the top bar shows and hides the docked list. - if (docked) document.getElementById('btn-list').setAttribute('aria-expanded', String(state.sidebarOpen)); - else if (!document.body.classList.contains('list-open')) document.getElementById('btn-list').setAttribute('aria-expanded', 'false'); + // On the desktop the sidebar button at the right end of the top bar shows and hides the list. + document.getElementById('btn-rail').setAttribute('aria-expanded', String(docked && state.sidebarOpen)); scheduleRulerDraw(); } @@ -14141,8 +14140,7 @@

${escapeHtml(t('exportRedlineHeading'))}

} document.getElementById('btn-list').addEventListener('click', e => { e.stopPropagation(); - if (currentTier === 'desktop') toggleSidebar(); - else if (document.body.classList.contains('list-open')) closeListSheet(); + if (document.body.classList.contains('list-open')) closeListSheet(); else openListSheet(); }); document.getElementById('mob-step').addEventListener('click', e => { @@ -14150,11 +14148,7 @@

${escapeHtml(t('exportRedlineHeading'))}

openListSheet(); }); document.getElementById('btn-close-sidebar-sheet').addEventListener('click', () => closeListSheet()); -document.getElementById('btn-close-rail').addEventListener('click', () => { - if (currentTier !== 'desktop' || !state.sidebarOpen) return; - toggleSidebar(); - document.getElementById('btn-list').focus({ preventScroll: true }); -}); +document.getElementById('btn-rail').addEventListener('click', () => toggleSidebar()); document.getElementById('mobile-sheet-backdrop').addEventListener('click', () => { if (openMenuState) closeMenu(openMenuState.id, true); else closeListSheet(); diff --git a/src/js/01-i18n.js b/src/js/01-i18n.js index c0fb175..4e53795 100644 --- a/src/js/01-i18n.js +++ b/src/js/01-i18n.js @@ -45,7 +45,6 @@ const I18N = { hfFilterBtn: 'Kopf-/Fußzeilen ausblenden', hfHiddenCount: '{n} ausgeblendet', sidebarToggle: 'Änderungsliste', - listHide: 'Liste ausblenden', themeLabel: 'Farbschema', themeLight: 'Hell', themeDark: 'Dunkel', @@ -444,7 +443,6 @@ const I18N = { hfFilterBtn: 'Hide headers & footers', hfHiddenCount: '{n} hidden', sidebarToggle: 'List of changes', - listHide: 'Hide list', themeLabel: 'Colour scheme', themeLight: 'Light', themeDark: 'Dark', diff --git a/src/js/10-controls.js b/src/js/10-controls.js index 62e9e95..f796073 100644 --- a/src/js/10-controls.js +++ b/src/js/10-controls.js @@ -375,9 +375,8 @@ function applySidebarState() { const docked = currentTier === 'desktop'; document.body.classList.toggle('sidebar-collapsed', docked && !state.sidebarOpen); setMenuChecked('btn-toggle-sidebar', state.sidebarOpen); - // On the desktop the list button in the top bar shows and hides the docked list. - if (docked) document.getElementById('btn-list').setAttribute('aria-expanded', String(state.sidebarOpen)); - else if (!document.body.classList.contains('list-open')) document.getElementById('btn-list').setAttribute('aria-expanded', 'false'); + // On the desktop the sidebar button at the right end of the top bar shows and hides the list. + document.getElementById('btn-rail').setAttribute('aria-expanded', String(docked && state.sidebarOpen)); scheduleRulerDraw(); } @@ -423,8 +422,7 @@ function closeListSheet(returnFocus = true) { } document.getElementById('btn-list').addEventListener('click', e => { e.stopPropagation(); - if (currentTier === 'desktop') toggleSidebar(); - else if (document.body.classList.contains('list-open')) closeListSheet(); + if (document.body.classList.contains('list-open')) closeListSheet(); else openListSheet(); }); document.getElementById('mob-step').addEventListener('click', e => { @@ -432,11 +430,7 @@ document.getElementById('mob-step').addEventListener('click', e => { openListSheet(); }); document.getElementById('btn-close-sidebar-sheet').addEventListener('click', () => closeListSheet()); -document.getElementById('btn-close-rail').addEventListener('click', () => { - if (currentTier !== 'desktop' || !state.sidebarOpen) return; - toggleSidebar(); - document.getElementById('btn-list').focus({ preventScroll: true }); -}); +document.getElementById('btn-rail').addEventListener('click', () => toggleSidebar()); document.getElementById('mobile-sheet-backdrop').addEventListener('click', () => { if (openMenuState) closeMenu(openMenuState.id, true); else closeListSheet(); diff --git a/src/styles.css b/src/styles.css index 28b70f8..a5be560 100644 --- a/src/styles.css +++ b/src/styles.css @@ -1694,13 +1694,19 @@ ins.tok-ins.tok-marker { text-decoration-style: dotted; } -/* Reviewed: accepted changes are muted; the mark sits in the margin of the new version */ +/* Reviewed: a decided change reads as finished text. Accepted: the new wording is plain text + with a green edge; the removed words stay quietly struck through, so the change is still + visible. Only colours change, so reviewing never moves any text. */ .clause.is-accepted { - border-left-color: hsl(var(--muted-foreground) / 0.3); + border-left-color: hsl(var(--success)); background: transparent; } -.clause.is-accepted del.tok-del, .clause.is-accepted ins.tok-ins { + background: transparent; + color: inherit; + text-decoration-color: transparent; +} +.clause.is-accepted del.tok-del { background: transparent; color: hsl(var(--muted-foreground)); } @@ -1713,8 +1719,9 @@ ins.tok-ins.tok-marker { font-weight: 600; color: hsl(var(--muted-foreground)); } +/* Rejected: the old wording is back as plain text, with a solid neutral edge */ .diff-row-anchor.has-ghost .clause { - border-left: 2px dotted hsl(var(--muted-foreground) / 0.6); + border-left: 2px solid hsl(var(--muted-foreground) / 0.7); } .diff-row-anchor.has-ghost .clause.is-active { border-left-style: solid; @@ -1886,7 +1893,7 @@ ins.tok-ins.tok-marker { stroke-width: 2.2; } .review-status.is-accepted .rs-mark { color: hsl(var(--success-ink)); } -.review-status.is-rejected .rs-mark { color: hsl(var(--muted-foreground)); } +.review-status.is-rejected .rs-mark { color: hsl(var(--foreground)); } .ra-undo { display: inline-flex; align-items: center; @@ -2083,17 +2090,10 @@ body.tier-phone .bottom-bar .review-bar { justify-content: space-between; gap: var(--sp-2); } -/* Collapses the docked list (desktop); the list button in the top bar brings it back */ -.rail-close { - margin-right: -8px; - color: hsl(var(--muted-foreground)); -} -body:not(.tier-desktop) .rail-close { +/* Shows and hides the docked list of changes (desktop only; tablets and phones use a sheet) */ +body:not(.tier-desktop) #btn-rail { display: none; } -#btn-list[aria-expanded="true"] { - background: hsl(var(--ton-2)); -} .list-title { font-size: var(--text-title); font-weight: 600; @@ -2178,9 +2178,11 @@ body:not(.tier-desktop) .rail-close { .nav-item.ins { border-left-color: hsl(var(--success)); } .nav-item.del { border-left-color: hsl(var(--destructive)); } .nav-item.moved { border-left-style: dashed; border-left-color: hsl(var(--muted-foreground) / 0.6); } -.nav-item.is-accepted, +.nav-item.is-accepted { + border-left-color: hsl(var(--success)); +} .nav-item.is-rejected { - border-left-color: hsl(var(--muted-foreground) / 0.35); + border-left-color: hsl(var(--muted-foreground) / 0.7); } .nav-item.is-active { background: hsl(var(--current-tint)); @@ -2246,7 +2248,7 @@ body:not(.tier-desktop) .rail-close { stroke-width: 2.4; } .nav-status.is-accepted { color: hsl(var(--success-ink)); } -.nav-status.is-rejected { color: hsl(var(--muted-foreground)); } +.nav-status.is-rejected { color: hsl(var(--foreground)); } .nav-item.is-accepted .nav-item-ref, .nav-item.is-rejected .nav-item-ref, .nav-item.is-accepted .nav-item-snippet, diff --git a/src/template.html b/src/template.html index bf6fb89..1422c4c 100644 --- a/src/template.html +++ b/src/template.html @@ -231,7 +231,7 @@

Dokumente

- @@ -450,7 +451,6 @@

Häufige Fragen

0 Änderungen

-
From 0072da78b7ee4230fbe75354a06247d07f96dc17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Hermes?= Date: Fri, 23 Oct 2026 08:19:13 +0200 Subject: [PATCH 3/5] Start PDF.js and Mammoth only when a PDF or Word file is first read Both readers (about 1 MB of JavaScript) were compiled and run on every page load, before the start page could paint, although only PDF and Word imports need them. They are now embedded as non-executed text, like the PDF.js worker, and started on first use. The page stays one self-contained file and still works offline. Starting them takes about 70 ms on a fast laptop (several times that on a phone); that time is now off the page load. Co-Authored-By: Claude Opus 5.5 --- DocDiff.html | 30 +++++++++++++++++++++++++----- scripts/check.mjs | 4 ++++ site/en/index.html | 30 +++++++++++++++++++++++++----- site/index.html | 30 +++++++++++++++++++++++++----- src/js/06a-compare-async.js | 19 ++++++++++++++++++- src/js/09-import.js | 3 ++- src/template.html | 8 +++++--- 7 files changed, 104 insertions(+), 20 deletions(-) diff --git a/DocDiff.html b/DocDiff.html index 72484f0..575caca 100644 --- a/DocDiff.html +++ b/DocDiff.html @@ -4107,8 +4107,10 @@

- - - - -