diff --git a/pontoon/administration/static/css/admin_project.css b/pontoon/administration/static/css/admin_project.css index ad3ba79a78..0c9cb910cb 100644 --- a/pontoon/administration/static/css/admin_project.css +++ b/pontoon/administration/static/css/admin_project.css @@ -161,7 +161,7 @@ form .controls .button.manage-resources[disabled]:hover { form a:link, form a:visited { - color: var(--status-translated-alt); + color: var(--status-translated); float: right; text-transform: uppercase; } diff --git a/pontoon/base/static/css/dark-theme.css b/pontoon/base/static/css/dark-theme.css index 8da513de1b..2136101073 100644 --- a/pontoon/base/static/css/dark-theme.css +++ b/pontoon/base/static/css/dark-theme.css @@ -2,6 +2,7 @@ .dark-theme { /* Main */ --main-border-1: #4d5967; + --control-border: #4d5967; --moz-logo: url(../img/moz-logo-light.svg); /* User banner and details */ @@ -36,6 +37,9 @@ --tooltip-color: #ffffff; --tooltip-color-2: #aaaaaa; --tooltip-border: #4d5967; + --tooltip-surface-background: #000000dd; + --tooltip-surface-color: #ffffff; + --tooltip-surface-color-2: #888888; /* Homepage */ --homepage-background-image: url(../img/background.svg); @@ -44,13 +48,10 @@ /* Translation status */ --status-translated: #7bc876; - --status-translated-alt: #7bc876; --status-pretranslated: #c0ff00; - --status-pretranslated-alt: #c0ff00; --status-warning: #ffa10f; --status-error: #ff3366; --status-missing: #5f7285; - --status-missing-alt: #5f7285; --status-unreviewed: #4fc4f6; --status-fuzzy: #fed271; @@ -108,6 +109,10 @@ --lilac: #c6c1f0; --grey-5: #385465; + /* Insights & profile charts: neutral "new items" series + muted labels */ + --chart-neutral: #272a2f; + --chart-label-muted: #4d5967; + /* Contribution graph (empty โ†’ most active) */ --contribution-graph-0: #333941; --contribution-graph-1: #41554c; diff --git a/pontoon/base/static/css/light-theme.css b/pontoon/base/static/css/light-theme.css index a4ecbc85c8..7f175c25a4 100644 --- a/pontoon/base/static/css/light-theme.css +++ b/pontoon/base/static/css/light-theme.css @@ -1,7 +1,10 @@ /* Light Theme Variables */ .light-theme { /* Main */ - --main-border-1: #d8d8d8; + --main-border-1: #c4c4c4; + /* Form-control border & keyboard focus ring (a11y: >=3:1) */ + --control-border: #8c8c8c; + --focus-ring: #1f86b8; --moz-logo: url(../img/moz-logo.svg); /* User banner and details */ @@ -19,8 +22,8 @@ --input-background-1: #ffffff; --input-color-1: #2a2a2a; --input-color-2: #000000; - --toggle-color-1: #999999; - --toggle-color-2: #d0d0d0; + --toggle-color-1: #757575; + --toggle-color-2: #bcbcbc; --icon-background-1: #d0d0d0; --icon-border-1: #bbbbbb; @@ -35,31 +38,34 @@ --tooltip-background: #000000dd; --tooltip-color: #ffffff; --tooltip-color-2: #aaaaaa; - --tooltip-border: #4d5967; + --tooltip-surface-background: #d8dbdf; + --tooltip-surface-color: #2b2b2b; + --tooltip-surface-color-2: #565656; + --tooltip-border: #bbc1c8; /* Homepage */ --homepage-background-image: url(../img/background-light.svg); --homepage-tour-button-background: #ffffff; --homepage-tour-button-color: #000000; - /* Translation status */ - --status-translated: #7bc876; - --status-translated-alt: #49a643; - --status-pretranslated: #c0ff00; - --status-pretranslated-alt: #80a900; - --status-warning: #ffa10f; - --status-error: #ff3366; - --status-missing: #bec7d1; - --status-missing-alt: #5f7285; - --status-unreviewed: #4fc4f6; - --status-fuzzy: #fed271; + /* Translation status. Darkened for the light theme so the same color works + for both fills (progress bars/buttons/charts) and text/icons (a11y: >=3:1). */ + --status-translated: #2f7a3b; + --status-pretranslated: #6f9400; + --status-warning: #b3700a; + --status-error: #d8143a; + --status-missing: #5f7285; + --status-unreviewed: #2487b3; + --status-fuzzy: #9c7a1f; /* Translation workspace */ --translation-background: #f6f6f6; --translation-border: #bbbbbb; --translation-color: #2a2a2a; --translation-secondary-color: #707070; - --translation-main-button-color: #2a2a2a; + /* Light text: the main action buttons (save/suggest/approve, AI) sit on the + darkened status-color backgrounds, so they need a light label. */ + --translation-main-button-color: #ffffff; --translation-subtitle-color: #555555; --editor-background: #ffffff; --editor-color: #2a2a2a; @@ -108,6 +114,10 @@ --lilac: #c6c1f0; --grey-5: #385465; + /* Insights & profile charts: neutral "new items" series + muted labels */ + --chart-neutral: #5f6772; + --chart-label-muted: #767676; + /* Contribution graph (empty โ†’ most active) */ --contribution-graph-0: #ebedf0; --contribution-graph-1: #aadfa3; @@ -137,3 +147,21 @@ --dark-grey-1: #ffffff; --black-3: #f6f6f6; } + +/* Light theme uses a light-gray tooltip, so add separation from the page */ +.light-theme .table .latest-activity .tooltip { + border: 1px solid var(--tooltip-border); + box-shadow: 0 4px 12px -4px #00000040; +} + +/* Light theme: visible keyboard-focus ring on interactive controls + (WCAG 2.4.7 focus visible, 1.4.11 >=3:1). Only on :focus-visible, so it + appears for keyboard navigation and not on mouse clicks. */ +.light-theme :is(a, button, input, textarea, select, [tabindex]):focus-visible { + outline: 2px solid var(--focus-ring); + outline-offset: 1px; +} + +.light-theme .failed-checks .warning:before { + color: var(--status-warning); +} diff --git a/pontoon/base/static/css/multiple_item_selector.css b/pontoon/base/static/css/multiple_item_selector.css index 8518a439f5..2d1782b1ef 100644 --- a/pontoon/base/static/css/multiple_item_selector.css +++ b/pontoon/base/static/css/multiple_item_selector.css @@ -41,7 +41,7 @@ margin-bottom: 0; li span.code { - color: var(--status-translated-alt); + color: var(--status-translated); float: right; text-align: left; width: auto; @@ -66,7 +66,7 @@ a:link, a:visited { - color: var(--status-translated-alt); + color: var(--status-translated); float: right; text-transform: uppercase; } diff --git a/pontoon/base/static/css/style.css b/pontoon/base/static/css/style.css index e92162e422..e6f94d9e4a 100755 --- a/pontoon/base/static/css/style.css +++ b/pontoon/base/static/css/style.css @@ -143,7 +143,7 @@ input[type='email'], input[type='date'], textarea { background: var(--input-background-1); - border: 1px solid var(--main-border-1); + border: 1px solid var(--control-border); border-radius: 3px; color: var(--input-color-1); padding: 4px 3px 3px; @@ -523,7 +523,7 @@ time { } .locale .code { - color: var(--status-translated-alt); + color: var(--status-translated); text-align: left; } @@ -998,7 +998,7 @@ header .right .select .menu { } #profile .menu li.appearance button:last-child { - border-left: 1px solid var(--main-border-1); + border-left: 1px solid var(--control-border); } #profile .menu li.appearance button .icon { @@ -1302,7 +1302,7 @@ body > form, .controls > .search-wrapper input { background: var(--dark-grey-1); - border: 1px solid var(--main-border-1); + border: 1px solid var(--control-border); color: var(--input-color-2); font-size: 13px; height: 28px; @@ -1338,7 +1338,7 @@ body > form, } .container .info a { - color: var(--status-translated-alt); + color: var(--status-translated); } .toggle-button { @@ -1347,7 +1347,7 @@ body > form, .toggle-button button { background: transparent; - border: 1px solid var(--main-border-1); + border: 1px solid var(--control-border); border-radius: 3px; box-sizing: border-box; color: var(--toggle-color-1); @@ -1375,7 +1375,7 @@ body > form, .toggle-button button.active { background: var(--button-background-1); - border-color: var(--main-border-1); + border-color: var(--control-border); color: var(--light-grey-7); font-weight: 400; } diff --git a/pontoon/base/static/css/table.css b/pontoon/base/static/css/table.css index d0b6b16fe6..bad80bdfa4 100644 --- a/pontoon/base/static/css/table.css +++ b/pontoon/base/static/css/table.css @@ -149,7 +149,7 @@ table.table.project-list.hidden { } .table td.code a { - color: var(--status-translated-alt); + color: var(--status-translated); line-height: 47px; padding: 15px 5px 14px; } @@ -182,10 +182,10 @@ table.table.project-list.hidden { .table .latest-activity .tooltip { display: block; - background: var(--tooltip-background); + background: var(--tooltip-surface-background); border-radius: 10px; bottom: 30px; - color: var(--tooltip-color); + color: var(--tooltip-surface-color); left: -100px; padding: 10px; position: absolute; @@ -198,7 +198,8 @@ table.table.project-list.hidden { content: ''; position: absolute; border: 10px solid; - border-color: var(--tooltip-background) transparent transparent transparent; + border-color: var(--tooltip-surface-background) transparent transparent + transparent; bottom: -20px; left: 160px; /* Must be (tooltip width + tooltip padding + bottom) / 2 */ clip: rect(0 20px 10px 0); @@ -218,7 +219,7 @@ table.table.project-list.hidden { } .table .latest-activity .tooltip footer { - color: var(--tooltip-color-2); + color: var(--tooltip-surface-color-2); font-style: italic; height: 48px; margin-top: 10px; @@ -365,7 +366,7 @@ table.table.project-list.hidden { } .table .progress .legend li.pretranslated .title { - color: var(--status-pretranslated-alt); + color: var(--status-pretranslated); } .table .progress .legend li.warnings .title { @@ -377,7 +378,7 @@ table.table.project-list.hidden { } .table .progress .legend li.missing .title { - color: var(--status-missing-alt); + color: var(--status-missing); } .table .progress .legend li.unreviewed .title { diff --git a/pontoon/base/static/css/terms.css b/pontoon/base/static/css/terms.css index 2a1e77b0e7..ea74693341 100644 --- a/pontoon/base/static/css/terms.css +++ b/pontoon/base/static/css/terms.css @@ -6,7 +6,7 @@ #main a:link, #main a:visited { - color: var(--status-translated-alt); + color: var(--status-translated); } #main p, diff --git a/pontoon/contributors/static/css/contributors.css b/pontoon/contributors/static/css/contributors.css index 860c60ecb4..3a5bd075ad 100644 --- a/pontoon/contributors/static/css/contributors.css +++ b/pontoon/contributors/static/css/contributors.css @@ -1,5 +1,5 @@ #heading .banner .title { - color: var(--status-translated-alt); + color: var(--status-translated); } #heading .legend { @@ -98,7 +98,7 @@ th:last-child sup { } .stats .details div.approved { - color: var(--status-translated-alt); + color: var(--status-translated); } .stats .details div.unreviewed { diff --git a/pontoon/contributors/static/css/profile.css b/pontoon/contributors/static/css/profile.css index 4fe330cab2..32da5f96ed 100644 --- a/pontoon/contributors/static/css/profile.css +++ b/pontoon/contributors/static/css/profile.css @@ -63,7 +63,7 @@ h2 { } .username { - color: var(--status-translated-alt); + color: var(--status-translated); line-height: 1.4em; font-size: 20px; font-weight: 300; @@ -106,7 +106,7 @@ h2 { } .item-with-icon .stress { - color: var(--status-translated-alt); + color: var(--status-translated); } .account-status-heading { @@ -212,7 +212,7 @@ h4.superuser { } #insights .chart-group-navigation ul li .icon { - background-color: var(--black-3); + background-color: var(--chart-neutral); border-radius: 50%; display: inline-block; margin-right: 8px; @@ -221,7 +221,7 @@ h4.superuser { } #insights .chart-group-navigation ul li .label { - color: var(--grey-3); + color: var(--chart-label-muted); cursor: pointer; font-weight: bold; vertical-align: text-top; @@ -271,7 +271,7 @@ h4.superuser { } #stats > div.translated span { - color: var(--status-translated-alt); + color: var(--status-translated); } #stats > div.unreviewed span { @@ -537,7 +537,7 @@ svg.js-calendar-graph-svg { } #timeline .localizations li a .stress { - color: var(--status-translated-alt); + color: var(--status-translated); } #timeline .localizations li a .contribution-count { diff --git a/pontoon/contributors/static/css/settings.css b/pontoon/contributors/static/css/settings.css index 5deda98ffd..a23de47876 100644 --- a/pontoon/contributors/static/css/settings.css +++ b/pontoon/contributors/static/css/settings.css @@ -8,7 +8,7 @@ form.user-locales-settings div { form a:link, form a:visited { - color: var(--status-translated-alt); + color: var(--status-translated); float: right; text-transform: uppercase; } diff --git a/pontoon/insights/static/css/insights_charts.css b/pontoon/insights/static/css/insights_charts.css index e2708157d0..4f41f2e79a 100644 --- a/pontoon/insights/static/css/insights_charts.css +++ b/pontoon/insights/static/css/insights_charts.css @@ -97,7 +97,7 @@ } #insights .legend li.disabled .label { - color: var(--grey-3); + color: var(--chart-label-muted); } #insights .legend li.disabled .label:hover { diff --git a/pontoon/insights/static/css/insights_tab.css b/pontoon/insights/static/css/insights_tab.css index 941a28352c..db680157c7 100644 --- a/pontoon/insights/static/css/insights_tab.css +++ b/pontoon/insights/static/css/insights_tab.css @@ -122,7 +122,7 @@ } #insights h3 .tooltip li.new-source-strings::marker { - color: var(--black-3); + color: var(--chart-neutral); } #insights h3 .tooltip li.completion::marker { @@ -144,7 +144,7 @@ } #insights h3 .tooltip li.new-suggestions::marker { - color: var(--black-3); + color: var(--chart-neutral); } #insights h3 .tooltip li.unreviewed::marker { @@ -170,5 +170,5 @@ } #insights .pretranslation-quality h3 .tooltip li.new-pretranslations::marker { - color: var(--black-3); + color: var(--chart-neutral); } diff --git a/pontoon/insights/static/js/insights_tab.js b/pontoon/insights/static/js/insights_tab.js index 1df745f6e6..9f5efb5baf 100644 --- a/pontoon/insights/static/js/insights_tab.js +++ b/pontoon/insights/static/js/insights_tab.js @@ -455,8 +455,8 @@ var Pontoon = (function (my) { label: 'New source strings', data: newSourcesData, yAxisID: 'strings-y-axis', - backgroundColor: style.getPropertyValue('--black-3'), - hoverBackgroundColor: style.getPropertyValue('--black-3'), + backgroundColor: style.getPropertyValue('--chart-neutral'), + hoverBackgroundColor: style.getPropertyValue('--chart-neutral'), stack: 'source-strings', order: 3, hidden: true, @@ -669,8 +669,8 @@ var Pontoon = (function (my) { label: 'New suggestions', data: chart.data('new-suggestions'), yAxisID: 'strings-y-axis', - backgroundColor: style.getPropertyValue('--black-3'), - hoverBackgroundColor: style.getPropertyValue('--black-3'), + backgroundColor: style.getPropertyValue('--chart-neutral'), + hoverBackgroundColor: style.getPropertyValue('--chart-neutral'), stack: 'new-suggestions', order: 4, hidden: true, @@ -881,8 +881,8 @@ var Pontoon = (function (my) { label: 'New pretranslations', data: newData, yAxisID: 'strings-y-axis', - backgroundColor: style.getPropertyValue('--black-3'), - hoverBackgroundColor: style.getPropertyValue('--black-3'), + backgroundColor: style.getPropertyValue('--chart-neutral'), + hoverBackgroundColor: style.getPropertyValue('--chart-neutral'), stack: 'new-pretranslations', order: 3, hidden: true, diff --git a/pontoon/messaging/static/css/messaging.css b/pontoon/messaging/static/css/messaging.css index befcbb179e..49e0934714 100644 --- a/pontoon/messaging/static/css/messaging.css +++ b/pontoon/messaging/static/css/messaging.css @@ -335,7 +335,7 @@ font-size: 14px; .sender { - color: var(--status-translated-alt); + color: var(--status-translated); width: 50%; } diff --git a/pontoon/search/static/css/search.css b/pontoon/search/static/css/search.css index 679b6d497c..825858ee78 100644 --- a/pontoon/search/static/css/search.css +++ b/pontoon/search/static/css/search.css @@ -276,7 +276,7 @@ .translation-locale-code { font-style: italic; - color: var(--status-translated-alt); + color: var(--status-translated); vertical-align: sub; } } diff --git a/pontoon/teams/static/css/info.css b/pontoon/teams/static/css/info.css index 1887d12b3b..6a54543802 100644 --- a/pontoon/teams/static/css/info.css +++ b/pontoon/teams/static/css/info.css @@ -28,7 +28,7 @@ #info-wrapper .controls .cancel { display: none; - color: var(--status-translated-alt); + color: var(--status-translated); margin: 9px; text-transform: uppercase; } diff --git a/tmp-shots/homepage.png b/tmp-shots/homepage.png new file mode 100644 index 0000000000..5379bb637c Binary files /dev/null and b/tmp-shots/homepage.png differ diff --git a/tmp-shots/localization-dashboard.png b/tmp-shots/localization-dashboard.png new file mode 100644 index 0000000000..c3de2b95e1 Binary files /dev/null and b/tmp-shots/localization-dashboard.png differ diff --git a/tmp-shots/profile.png b/tmp-shots/profile.png new file mode 100644 index 0000000000..2d778d923e Binary files /dev/null and b/tmp-shots/profile.png differ diff --git a/tmp-shots/project-dashboard.png b/tmp-shots/project-dashboard.png new file mode 100644 index 0000000000..0ec4f34fc6 Binary files /dev/null and b/tmp-shots/project-dashboard.png differ diff --git a/tmp-shots/project-insights.png b/tmp-shots/project-insights.png new file mode 100644 index 0000000000..324d57acba Binary files /dev/null and b/tmp-shots/project-insights.png differ diff --git a/tmp-shots/team-dashboard.png b/tmp-shots/team-dashboard.png new file mode 100644 index 0000000000..5379bb637c Binary files /dev/null and b/tmp-shots/team-dashboard.png differ diff --git a/tmp-shots/team-insights.png b/tmp-shots/team-insights.png new file mode 100644 index 0000000000..2458545440 Binary files /dev/null and b/tmp-shots/team-insights.png differ diff --git a/tmp-shots/tr-editor.png b/tmp-shots/tr-editor.png new file mode 100644 index 0000000000..9715e4424f Binary files /dev/null and b/tmp-shots/tr-editor.png differ diff --git a/tmp-shots/tr-filters.png b/tmp-shots/tr-filters.png new file mode 100644 index 0000000000..ee16ff5ebd Binary files /dev/null and b/tmp-shots/tr-filters.png differ diff --git a/translate/src/App.css b/translate/src/App.css index 0079dc4c40..5c6fed3e0e 100644 --- a/translate/src/App.css +++ b/translate/src/App.css @@ -202,7 +202,7 @@ #app > .main-content .third-column .react-tabs span.count:has(.preferred), #app > .main-content .third-column .react-tabs span.count:has(.pinned) { - background: var(--status-translated-alt); - color: var(--status-translated-alt); /* used as box-shadow color */ + background: var(--status-translated); + color: var(--status-translated); /* used as box-shadow color */ } } diff --git a/translate/src/hooks/useTheme.ts b/translate/src/hooks/useTheme.ts index a4464c7934..f8a6ec9aa7 100644 --- a/translate/src/hooks/useTheme.ts +++ b/translate/src/hooks/useTheme.ts @@ -28,5 +28,11 @@ export function useTheme() { } document.body.classList.remove('dark-theme', 'light-theme', 'system-theme'); document.body.classList.add(`${newTheme}-theme`); + + // Notify theme-dependent UI (e.g. the time-range chart, which embeds CSS + // variables into a canvas) to re-read colors without a page reload. + document.dispatchEvent( + new CustomEvent('themechange', { detail: { theme: newTheme } }), + ); }; } diff --git a/translate/src/modules/batchactions/components/BatchActions.css b/translate/src/modules/batchactions/components/BatchActions.css index 76712ede60..980a5501b2 100644 --- a/translate/src/modules/batchactions/components/BatchActions.css +++ b/translate/src/modules/batchactions/components/BatchActions.css @@ -36,7 +36,7 @@ } .batch-actions .topbar button.selected-count .stress { - color: var(--status-translated-alt); + color: var(--status-translated); } .batch-actions .topbar button .fas { diff --git a/translate/src/modules/entitydetails/components/Helpers.css b/translate/src/modules/entitydetails/components/Helpers.css index f484cf6f58..5e95dfcb4e 100644 --- a/translate/src/modules/entitydetails/components/Helpers.css +++ b/translate/src/modules/entitydetails/components/Helpers.css @@ -75,5 +75,5 @@ .react-tabs span.count .preferred, .react-tabs span.count .pinned { - color: var(--status-translated-alt); + color: var(--status-translated); } diff --git a/translate/src/modules/history/components/HistoryTranslation.css b/translate/src/modules/history/components/HistoryTranslation.css index 06a3ff8b0c..b51c543133 100644 --- a/translate/src/modules/history/components/HistoryTranslation.css +++ b/translate/src/modules/history/components/HistoryTranslation.css @@ -53,7 +53,7 @@ } .history .translation .content > header .info a { - color: var(--status-translated-alt); + color: var(--status-translated); } .history .translation .content > header .toggle { @@ -80,7 +80,7 @@ } .history .translation .content > header .toggle.active .stress { - color: var(--status-translated-alt); + color: var(--status-translated); } .history .translation .content > header button { diff --git a/translate/src/modules/machinery/components/MachineryTranslation.css b/translate/src/modules/machinery/components/MachineryTranslation.css index b1c1aba54d..d6e6ecc0fd 100644 --- a/translate/src/modules/machinery/components/MachineryTranslation.css +++ b/translate/src/modules/machinery/components/MachineryTranslation.css @@ -123,7 +123,7 @@ .machinery .translation > header .quality, .machinery .translation > header sup { - color: var(--status-translated-alt); + color: var(--status-translated); } .machinery .translation > header .projects { diff --git a/translate/src/modules/navbar/components/Navigation.css b/translate/src/modules/navbar/components/Navigation.css index a78e03c261..08718a1b22 100644 --- a/translate/src/modules/navbar/components/Navigation.css +++ b/translate/src/modules/navbar/components/Navigation.css @@ -32,6 +32,6 @@ } .navigation .locale-code { - color: var(--status-translated-alt); + color: var(--status-translated); padding-left: 7px; } diff --git a/translate/src/modules/otherlocales/components/OtherLocaleTranslation.css b/translate/src/modules/otherlocales/components/OtherLocaleTranslation.css index 4dc01f7a9b..db158f778a 100644 --- a/translate/src/modules/otherlocales/components/OtherLocaleTranslation.css +++ b/translate/src/modules/otherlocales/components/OtherLocaleTranslation.css @@ -28,7 +28,7 @@ } .other-locales .translation > header span { - color: var(--status-translated-alt); + color: var(--status-translated); padding-left: 3px; } diff --git a/translate/src/modules/project/components/ProjectItem.css b/translate/src/modules/project/components/ProjectItem.css index d86ec78a11..9ca03643a6 100644 --- a/translate/src/modules/project/components/ProjectItem.css +++ b/translate/src/modules/project/components/ProjectItem.css @@ -18,6 +18,6 @@ } .project-menu .menu .percent { - color: var(--status-translate-alt); + color: var(--status-translate); float: right; } diff --git a/translate/src/modules/resource/components/ResourceMenu.css b/translate/src/modules/resource/components/ResourceMenu.css index 5a447708ca..383dd0c906 100644 --- a/translate/src/modules/resource/components/ResourceMenu.css +++ b/translate/src/modules/resource/components/ResourceMenu.css @@ -99,7 +99,7 @@ } .resource-menu .menu .current a { - color: var(--status-translated-alt); + color: var(--status-translated); } .resource-menu .menu .header { diff --git a/translate/src/modules/resource/components/ResourcePercent.css b/translate/src/modules/resource/components/ResourcePercent.css index 8040550c69..8de6332cc7 100644 --- a/translate/src/modules/resource/components/ResourcePercent.css +++ b/translate/src/modules/resource/components/ResourcePercent.css @@ -1,4 +1,4 @@ .resource-menu .menu .percent { - color: var(--status-translated-alt); + color: var(--status-translated); float: right; } diff --git a/translate/src/modules/search/components/FiltersPanel.css b/translate/src/modules/search/components/FiltersPanel.css index b0f2073482..d4e26f2b9d 100644 --- a/translate/src/modules/search/components/FiltersPanel.css +++ b/translate/src/modules/search/components/FiltersPanel.css @@ -101,7 +101,7 @@ .filters-panel .menu li.horizontal-separator { background: transparent; border-top: none; - color: var(--status-translated-alt); + color: var(--status-translated); cursor: default; font-size: 13px; height: auto; @@ -237,7 +237,7 @@ .filters-panel .toolbar { position: sticky; bottom: 0; - background: var(--tooltip-background); + background: var(--tooltip-surface-background); border-top: 1px solid var(--light-grey-1); box-sizing: border-box; line-height: 23px; @@ -248,7 +248,7 @@ .filters-panel .toolbar button { background: none; border: none; - color: var(--tooltip-color-2); + color: var(--tooltip-surface-color-2); font-weight: 300; } diff --git a/translate/src/modules/search/components/SearchPanel.css b/translate/src/modules/search/components/SearchPanel.css index feaf0ef460..68fcb88577 100644 --- a/translate/src/modules/search/components/SearchPanel.css +++ b/translate/src/modules/search/components/SearchPanel.css @@ -43,7 +43,7 @@ } & .title { - color: var(--status-translated-alt); + color: var(--status-translated); cursor: default; font-size: 13px; font-weight: 300; diff --git a/translate/src/modules/search/components/TimeRangeFilter.css b/translate/src/modules/search/components/TimeRangeFilter.css index 77ca827900..e6c3ba44a4 100644 --- a/translate/src/modules/search/components/TimeRangeFilter.css +++ b/translate/src/modules/search/components/TimeRangeFilter.css @@ -9,7 +9,7 @@ } .filters-panel .menu .for-time-range button.save-range { - color: var(--status-translated-alt); + color: var(--status-translated); } .filters-panel .menu li.for-time-range button:hover { diff --git a/translate/src/modules/search/components/TimeRangeFilter.tsx b/translate/src/modules/search/components/TimeRangeFilter.tsx index 0b8d0b77d1..543e297cd7 100644 --- a/translate/src/modules/search/components/TimeRangeFilter.tsx +++ b/translate/src/modules/search/components/TimeRangeFilter.tsx @@ -8,7 +8,7 @@ import highchartsStock from 'highcharts/modules/stock'; import HighchartsReact from 'highcharts-react-official'; import type { TimeRangeType } from '..'; -import { CHART_OPTIONS } from './chart-options'; +import { getChartOptions } from './chart-options'; import './TimeRangeFilter.css'; import classNames from 'classnames'; @@ -59,7 +59,7 @@ export function TimeRangeFilter({ setExtremes: ((arg0: { min: number; max: number }) => void) | null; }; }[]; - }>(CHART_OPTIONS); + }>(getChartOptions); const [inputFrom, setInputFrom] = useState(''); const [inputTo, setInputTo] = useState(''); const [visible, setVisible] = useState(false); @@ -84,6 +84,23 @@ export function TimeRangeFilter({ }; }, []); + useEffect(() => { + // The chart embeds theme CSS variables into its canvas, so rebuild the + // options (re-reading the current theme's colors) whenever the theme + // changes, preserving the loaded data and the setExtremes handler. + function updateChartTheme() { + setChartOptions((prev) => { + const next = getChartOptions(); + next.series[0].data = prev.series[0]?.data ?? []; + next.xAxis[0].events.setExtremes = prev.xAxis[0].events.setExtremes; + return next; + }); + } + + document.addEventListener('themechange', updateChartTheme); + return () => document.removeEventListener('themechange', updateChartTheme); + }, []); + useEffect(() => { // In case of no translations if (timeRangeData.length === 0) { diff --git a/translate/src/modules/search/components/chart-options.ts b/translate/src/modules/search/components/chart-options.ts index 7f7a7d2d08..b38149b101 100644 --- a/translate/src/modules/search/components/chart-options.ts +++ b/translate/src/modules/search/components/chart-options.ts @@ -1,147 +1,153 @@ -// Default Time Range chart configuration -const style = getComputedStyle(document.body); +// Default Time Range chart configuration. Built on demand (rather than once at +// module load) so the chart reads the current theme's CSS variables โ€” this lets +// its colors update when the user switches theme without reloading the page. +export function getChartOptions() { + const style = getComputedStyle(document.body); -export const CHART_OPTIONS = { - credits: { - enabled: false, - }, - title: { - enabled: false, - }, - scrollbar: { - enabled: false, - }, - time: { - useUTC: false, - }, - tooltip: { - enabled: false, - }, - chart: { - animation: false, - backgroundColor: 'transparent', - marginLeft: 5, - marginRight: 4, - spacingBottom: 30, - spacingTop: 0, - style: { - fontFamily: 'inherit', + return { + credits: { + enabled: false, }, - }, - xAxis: [ - { - lineWidth: 0, - tickLength: 0, - labels: { - enabled: false, - }, - events: { - setExtremes: null, - }, + title: { + enabled: false, }, - ], - yAxis: [ - { - type: 'logarithmic', - minorTickInterval: 0, - gridLineWidth: 0, - labels: { - enabled: false, - }, + scrollbar: { + enabled: false, }, - ], - rangeSelector: { - selected: 0, - buttons: [ - { - type: 'all', - text: 'All', - }, - { - type: 'day', - count: 30, - text: '30 days', - }, - { - type: 'day', - count: 7, - text: '7 days', + time: { + useUTC: false, + }, + tooltip: { + enabled: false, + }, + chart: { + animation: false, + backgroundColor: 'transparent', + marginLeft: 5, + marginRight: 4, + spacingBottom: 30, + spacingTop: 0, + style: { + fontFamily: 'inherit', }, + }, + xAxis: [ { - type: 'day', - count: 1, - text: '24 h', + lineWidth: 0, + tickLength: 0, + labels: { + enabled: false, + }, + events: { + setExtremes: null as + | null + | ((arg0: { min: number; max: number }) => void), + }, }, + ], + yAxis: [ { - type: 'minute', - count: 60, - text: '60 min', + type: 'logarithmic', + minorTickInterval: 0, + gridLineWidth: 0, + labels: { + enabled: false, + }, }, ], - buttonPosition: { - x: -4, - y: 95, - }, - buttonSpacing: 20, - buttonTheme: { - fill: 'none', - stroke: 'none', - width: null, - style: { - color: style.getPropertyValue('--translation-color'), - fontWeight: 300, - textTransform: 'uppercase', + rangeSelector: { + selected: 0, + buttons: [ + { + type: 'all', + text: 'All', + }, + { + type: 'day', + count: 30, + text: '30 days', + }, + { + type: 'day', + count: 7, + text: '7 days', + }, + { + type: 'day', + count: 1, + text: '24 h', + }, + { + type: 'minute', + count: 60, + text: '60 min', + }, + ], + buttonPosition: { + x: -4, + y: 95, }, - states: { - hover: { - fill: 'none', - style: { - color: style.getPropertyValue('--status-translated'), - }, + buttonSpacing: 20, + buttonTheme: { + fill: 'none', + stroke: 'none', + width: null, + style: { + color: style.getPropertyValue('--translation-color'), + fontWeight: 300, + textTransform: 'uppercase', }, - select: { - fill: 'none', - style: { - color: style.getPropertyValue('--status-translated-alt'), - fontWeight: 300, + states: { + hover: { + fill: 'none', + style: { + color: style.getPropertyValue('--status-translated'), + }, }, - }, - disabled: { - style: { - color: style.getPropertyValue('--translation-secondary-color'), - cursor: 'default', + select: { + fill: 'none', + style: { + color: style.getPropertyValue('--status-translated'), + fontWeight: 300, + }, + }, + disabled: { + style: { + color: style.getPropertyValue('--translation-secondary-color'), + cursor: 'default', + }, }, }, }, + inputEnabled: false, }, - inputEnabled: false, - }, - navigator: { - height: 80, - maskFill: 'rgba(77, 89, 103, 0.2)', - outlineColor: style.getPropertyValue('--icon-border-1'), - handles: { - backgroundColor: style.getPropertyValue('--icon-border-1'), - borderColor: style.getPropertyValue('--time-range-handles'), - }, - series: { - type: 'column', - color: style.getPropertyValue('--status-translated'), - }, - xAxis: { - lineWidth: 1, - lineColor: style.getPropertyValue('--icon-border-1'), - gridLineWidth: 0, - labels: { - enabled: false, + navigator: { + height: 80, + maskFill: 'rgba(77, 89, 103, 0.2)', + outlineColor: style.getPropertyValue('--icon-border-1'), + handles: { + backgroundColor: style.getPropertyValue('--icon-border-1'), + borderColor: style.getPropertyValue('--time-range-handles'), + }, + series: { + type: 'column', + color: style.getPropertyValue('--status-translated'), + }, + xAxis: { + lineWidth: 1, + lineColor: style.getPropertyValue('--icon-border-1'), + gridLineWidth: 0, + labels: { + enabled: false, + }, }, }, - }, - series: [ - { - animation: false, - data: [] as Array, - type: 'column', - }, - ], -}; + series: [ + { + animation: false, + data: [] as Array, + type: 'column', + }, + ], + }; +} diff --git a/translate/src/modules/terms/components/Term.css b/translate/src/modules/terms/components/Term.css index fdcd1c4844..7230242052 100644 --- a/translate/src/modules/terms/components/Term.css +++ b/translate/src/modules/terms/components/Term.css @@ -31,7 +31,7 @@ } .terms-list .term .translate { - color: var(--status-translated-alt); + color: var(--status-translated); float: right; font-size: 11px; font-weight: 300; @@ -50,7 +50,7 @@ } .terms-list .term .usage .title { - color: var(--status-translated-alt); + color: var(--status-translated); font-size: 11px; margin-right: 3px; } diff --git a/translate/src/modules/translationform/components/TranslationForm.css b/translate/src/modules/translationform/components/TranslationForm.css index 8a3d834280..b0d71cc2e8 100644 --- a/translate/src/modules/translationform/components/TranslationForm.css +++ b/translate/src/modules/translationform/components/TranslationForm.css @@ -29,12 +29,12 @@ .translationform label > :not(:last-child)::after { content: 'ยท'; - color: var(--status-translated-alt); + color: var(--status-translated); padding: 0 3px; } .translationform label .stress { - color: var(--status-translated-alt); + color: var(--status-translated); } .translationform .accesskey-input {