refactor: migrate CC dark theme feature to the new architecture
Bug: twpowertools:176
Change-Id: Iaea1015a788038a8a31acbdd33b267b551e0b6a1
diff --git a/src/features/ccDarkTheme/ccDarkTheme.feature.ts b/src/features/ccDarkTheme/ccDarkTheme.feature.ts
new file mode 100644
index 0000000..74efbf2
--- /dev/null
+++ b/src/features/ccDarkTheme/ccDarkTheme.feature.ts
@@ -0,0 +1,21 @@
+import Feature from '../../common/architecture/features/Feature';
+import { ConcreteScript } from '../../common/architecture/scripts/Script';
+import { OptionCodename } from '../../common/options/optionsPrototype';
+import InjectAutoDarkTheme from './scripts/injectAutoDarkTheme.script';
+import InjectForcedDarkTheme from './scripts/injectForcedDarkTheme.script';
+import CCDarkThemeNodeWatcherScript from './scripts/nodeWatcher.script';
+
+export default class CCDarkThemeFeature extends Feature {
+ public readonly scripts: ConcreteScript[] = [
+ InjectAutoDarkTheme,
+ InjectForcedDarkTheme,
+ CCDarkThemeNodeWatcherScript,
+ ];
+
+ readonly codename = 'darkTheme';
+ readonly relatedOptions: OptionCodename[] = [
+ 'ccdarktheme',
+ 'ccdarktheme_mode',
+ 'ccdarktheme_switch_status',
+ ];
+}
diff --git a/src/features/ccDarkTheme/core/logic/darkTheme.js b/src/features/ccDarkTheme/core/logic/darkTheme.js
new file mode 100644
index 0000000..d3d7e5e
--- /dev/null
+++ b/src/features/ccDarkTheme/core/logic/darkTheme.js
@@ -0,0 +1,84 @@
+import { MDCTooltip } from '@material/tooltip';
+
+import { createPlainTooltip } from '../../../../common/tooltip.js';
+import { createExtBadge } from '../../../../contentScripts/communityConsole/utils/common.js';
+
+export const kColorThemeMode = Object.freeze({
+ Auto: Symbol('auto'),
+ Light: Symbol('light'),
+ Dark: Symbol('dark'),
+});
+
+export function injectDarkThemeButton(rightControl) {
+ var darkThemeSwitch = document.createElement('material-button');
+ darkThemeSwitch.classList.add('TWPT-dark-theme', 'TWPT-btn--with-badge');
+ darkThemeSwitch.setAttribute('button', '');
+
+ darkThemeSwitch.addEventListener('click', () => {
+ chrome.storage.sync.get(null, (currentOptions) => {
+ currentOptions.ccdarktheme_switch_status =
+ !currentOptions.ccdarktheme_switch_status;
+ chrome.storage.sync.set(currentOptions);
+ });
+ });
+
+ var switchContent = document.createElement('div');
+ switchContent.classList.add('content');
+
+ var icon = document.createElement('material-icon');
+
+ var i = document.createElement('i');
+ i.classList.add('material-icon-i', 'material-icons-extended');
+ i.textContent = 'brightness_4';
+
+ icon.appendChild(i);
+ switchContent.appendChild(icon);
+ darkThemeSwitch.appendChild(switchContent);
+
+ let badgeContent, badgeTooltip;
+ [badgeContent, badgeTooltip] = createExtBadge();
+
+ darkThemeSwitch.appendChild(badgeContent);
+
+ rightControl.style.width =
+ parseInt(window.getComputedStyle(rightControl).width) + 58 + 'px';
+ rightControl.insertAdjacentElement('afterbegin', darkThemeSwitch);
+
+ createPlainTooltip(
+ switchContent,
+ chrome.i18n.getMessage('inject_ccdarktheme_helper'),
+ );
+ new MDCTooltip(badgeTooltip);
+}
+
+export function getCurrentColorTheme(options) {
+ if (!options.ccdarktheme) {
+ return kColorThemeMode.Light;
+ } else {
+ if (options.ccdarktheme_mode == 'switch') {
+ return options.ccdarktheme_switch_status
+ ? kColorThemeMode.Dark
+ : kColorThemeMode.Light;
+ } else {
+ return kColorThemeMode.Auto;
+ }
+ }
+}
+
+export function isDarkThemeOn(options) {
+ const activeColorTheme = getCurrentColorTheme(options);
+
+ switch (activeColorTheme) {
+ case kColorThemeMode.Auto:
+ return (
+ window.matchMedia &&
+ window.matchMedia('(prefers-color-scheme: dark)').matches
+ );
+
+ case kColorThemeMode.Light:
+ return false;
+
+ case kColorThemeMode.Dark:
+ return true;
+ }
+}
diff --git a/src/features/ccDarkTheme/core/logic/reportDialog.js b/src/features/ccDarkTheme/core/logic/reportDialog.js
new file mode 100644
index 0000000..4e79f4a
--- /dev/null
+++ b/src/features/ccDarkTheme/core/logic/reportDialog.js
@@ -0,0 +1,30 @@
+import {getCurrentColorTheme, kColorThemeMode} from './darkTheme';
+
+const kReportingWidgetThemes = {
+ [kColorThemeMode.Auto]: '0',
+ [kColorThemeMode.Light]: '1',
+ [kColorThemeMode.Dark]: '2',
+};
+
+export default class ReportDialogColorThemeFix {
+ constructor() {}
+
+ async fixThemeIfReportDialogIframeAndApplicable(iframe, optionsProvider) {
+ if (!this.isReportDialogIframe(iframe)) return;
+
+ const options = await optionsProvider.getOptionsValues();
+ const currentColorTheme = getCurrentColorTheme(options);
+
+ // By default the report dialog is added with the light theme
+ if (currentColorTheme === kColorThemeMode.Light) return;
+
+ console.debug('[reportDialogColorThemeFix] Fixing report dialog iframe');
+ let url = new URL(iframe.src);
+ url.searchParams.set('theme', kReportingWidgetThemes[currentColorTheme]);
+ iframe.src = url.href;
+ }
+
+ isReportDialogIframe(iframe) {
+ return iframe.src?.includes?.('reportingwidget') ?? false;
+ }
+}
diff --git a/src/features/ccDarkTheme/core/logic/unifiedProfiles.js b/src/features/ccDarkTheme/core/logic/unifiedProfiles.js
new file mode 100644
index 0000000..a26c45b
--- /dev/null
+++ b/src/features/ccDarkTheme/core/logic/unifiedProfiles.js
@@ -0,0 +1,12 @@
+export var unifiedProfilesFix = {
+ checkIframe(iframe) {
+ var srcRegex = /support.*\.google\.com\/profile\//;
+ return srcRegex.test(iframe.src ?? '');
+ },
+ fixIframe(iframe) {
+ console.debug('[unifiedProfilesFix] Fixing unified profiles iframe');
+ var url = new URL(iframe.src);
+ url.searchParams.set('dark', 1);
+ iframe.src = url.href;
+ },
+};
diff --git a/src/features/ccDarkTheme/core/styles/abstracts/_variables.scss b/src/features/ccDarkTheme/core/styles/abstracts/_variables.scss
new file mode 100644
index 0000000..bcb922d
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/abstracts/_variables.scss
@@ -0,0 +1,48 @@
+@use '../../../../../md3/theme' as md3-theme;
+
+:root {
+ --TWPT-primary-text: #e8eaed;
+ --TWPT-primary-text-alt: var(--TWPT-primary-text);
+ --TWPT-secondary-text: #bfbfbf;
+ --TWPT-primary-background: #202124;
+ --TWPT-secondary-background: #28292c;
+ --TWPT-active-background: #3c4043;
+ --TWPT-card-border: #5f6368;
+ --TWPT-subtle-border: #383735;
+ --TWPT-link: #8ab4f8;
+ --TWPT-icon-color: rgba(255, 255, 255, .87);
+ --TWPT-highlighted-item-background: rgba(255, 255, 255, .08);
+ --TWPT-thread-read-background: var(--TWPT-highlighted-item-background);
+ --TWPT-drawer-background: #2d2e30;
+ --TWPT-drawer-text: #d2cecb;
+ --TWPT-button-background: #3c3e42;
+ --TWPT-subtle-button-background: rgba(255, 255, 255, .54);
+ --TWPT-input-underline: rgba(255, 255, 255, .28);
+ --TWPT-starred: #fbbc04;
+ --TWPT-blue-100: #BBDEFB;
+ --TWPT-blue-A100: #82B1FF;
+ --TWPT-bad-text: #f6aea9;
+ --TWPT-bad-text-lightbg: #ffc4c0;
+ --TWPT-good-text: #34a853;
+ --TWPT-good-text-lightbg: #3cc160;
+ --TWPT-interop-primary-text: var(--TWPT-primary-text);
+ --TWPT-interop-secondary-text: #c4c7c5;
+ --TWPT-interop-subtle-border: #474747;
+ --TWPT-interop-success: #37be5f;
+ --TWPT-interop-blue: #7cacf8;
+
+ @include md3-theme.dark-theme('TWPT-');
+
+ /* Overrides for variables used by the Community Console styles */
+ --gm-outlinedtextfield-outline-color: var(--TWPT-card-border);
+ --gm-outlinedtextfield-label-color: var(--TWPT-subtle-button-background);
+ --gm-outlinedtextfield-caret-color: var(--TWPT-blue-A100);
+ --gm-outlinedtextfield-outline-color--stateful: var(--TWPT-blue-A100);
+ --gm-outlinedtextfield-label-color--stateful: var(--TWPT-blue-A100);
+ --gm-outlinedtextfield-outline-color--error: var(--TWPT-bad-text);
+ --gm-outlinedtextfield-label-color--error: var(--TWPT-bad-text);
+ --gm-outlinedtextfield-helper-text-color--error: var(--TWPT-bad-text);
+
+ /* TWPT features variables */
+ --TWPT-dark-flatten-replies-more-bg: rgba(89, 89, 89, 0.9);
+}
diff --git a/src/features/ccDarkTheme/core/styles/base/_base.scss b/src/features/ccDarkTheme/core/styles/base/_base.scss
new file mode 100644
index 0000000..c50c151
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/base/_base.scss
@@ -0,0 +1,16 @@
+:root {
+ color-scheme: dark;
+}
+
+body {
+ color: var(--TWPT-primary-text);
+ background-color: var(--TWPT-primary-background)!important;
+}
+
+p {
+ color: var(--TWPT-primary-text);
+}
+
+body.ec a {
+ color: var(--TWPT-link);
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/_action-bar.scss b/src/features/ccDarkTheme/core/styles/components/_action-bar.scss
new file mode 100644
index 0000000..9bf28fa
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/_action-bar.scss
@@ -0,0 +1,15 @@
+.material-content .action-bar material-button,
+ ec-bulk-actions material-button,
+ ec-back-button material-button,
+ .sort-options material-button {
+ color: var(--TWPT-subtle-button-background)!important;
+}
+
+.material-content .action-bar .review-button.reviewing {
+ color: #1a73e8!important;
+ background: #dae7ff!important;
+}
+
+.material-content .action-bar material-button.starred {
+ color: var(--TWPT-starred)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/_activity-panel.scss b/src/features/ccDarkTheme/core/styles/components/_activity-panel.scss
new file mode 100644
index 0000000..e097612
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/_activity-panel.scss
@@ -0,0 +1,24 @@
+ec-activity-panel .title-bar h3 {
+ color: #e8eaf2!important;
+}
+
+ec-activity-panel .title-bar material-button {
+ color: var(--TWPT-subtle-button-background)!important;
+}
+
+ec-activity-panel ec-activity {
+ color: var(--TWPT-secondary-text)!important;
+ border-color: var(--TWPT-card-border)!important;
+}
+
+ec-activity-panel ec-activity .message {
+ color: var(--TWPT-primary-text-alt)!important;
+}
+
+ec-activity-panel ec-activity .thread-title {
+ color: #c3bfbc!important;
+}
+
+ec-activity-panel ec-activity .thread-body {
+ color: var(--TWPT-secondary-text)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/_canned-responses.scss b/src/features/ccDarkTheme/core/styles/components/_canned-responses.scss
new file mode 100644
index 0000000..2d07bb8
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/_canned-responses.scss
@@ -0,0 +1,39 @@
+ec-canned-responses {
+ .filter-label,
+ ec-canned-response-row .name {
+ color: var(--TWPT-primary-text)!important;
+ }
+
+ .label-row,
+ ec-canned-response-row .snippet,
+ ec-canned-response-row .tag .content,
+ ec-canned-response-row .TWPT-tag .TWPT-content {
+ color: var(--TWPT-secondary-text)!important;
+ }
+
+ material-expansionpanel:not(.expanded) .main-header:focus-within {
+ background-color: var(--TWPT-active-background)!important;
+ }
+
+ ec-canned-response-row {
+ .header:hover,
+ .header.closed:focus,
+ .header.closed:hover .toolbar,
+ .header.closed:focus .toolbar,
+ material-expansionpanel:not(.expanded) .main-header:focus-within,
+ material-expansionpanel:not(.expanded) .main-header:hover {
+ background-color: var(--TWPT-active-background)!important;
+ }
+ }
+
+ .filter-row,
+ .label-row,
+ ec-canned-response-row material-expansionpanel {
+ border-bottom-color: var(--TWPT-subtle-border)!important;
+ }
+
+ .create-button {
+ background: #0842a0!important;
+ color: #d3e3fd!important;
+ }
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/_drawer.scss b/src/features/ccDarkTheme/core/styles/components/_drawer.scss
new file mode 100644
index 0000000..35fefdd
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/_drawer.scss
@@ -0,0 +1,33 @@
+material-drawer, material-drawer .panel, ec-filter-drawer-item > .root, ec-forum-drawer-item material-list-item {
+ background-color: var(--TWPT-drawer-background)!important;
+}
+
+material-drawer material-expansionpanel .main-header > .header:is(:hover, :focus) {
+ background-color: var(--TWPT-active-background)!important;
+}
+
+:is(
+ ec-filter-drawer-item > .root,
+ ec-forum-drawer-item > material-list-item,
+ material-list material-list-item,
+ .drawer-section .drawer-item:not([separator=present])
+ ):is(:hover, :focus, :focus-within, .active, .drawer-item--active) {
+ background: var(--TWPT-active-background)!important;
+}
+
+material-drawer .panel {
+ border-bottom-color: #25231f!important;
+}
+
+material-drawer .drawer-section-title, material-drawer .header > material-icon {
+ color: var(--TWPT-secondary-text)!important;
+}
+
+material-drawer material-list-item,
+ material-drawer material-list-item .title {
+ color: var(--TWPT-drawer-text)!important;
+}
+
+material-drawer ec-forum-drawer-item material-checkbox material-icon {
+ filter: brightness(1.5);
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/_duplicate-thread.scss b/src/features/ccDarkTheme/core/styles/components/_duplicate-thread.scss
new file mode 100644
index 0000000..cf0858f
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/_duplicate-thread.scss
@@ -0,0 +1,17 @@
+.search-results ec-thread-option material-expansionpanel .panel {
+ background-color: var(--TWPT-primary-background)!important;
+}
+
+.search-results ec-thread-option material-expansionpanel.selected .panel,
+ .search-results ec-thread-option material-expansionpanel .panel > .main-header > .header.closed:hover,
+ .search-results ec-thread-option material-expansionpanel .panel > .main-header > .header.closed:focus {
+ background-color: #17191c!important;
+}
+
+.search-results .results-title {
+ color: var(--TWPT-primary-text-alt)!important;
+}
+
+.search-results ec-thread-option material-expansionpanel .panel > .main > .main-content .snippet {
+ color: var(--TWPT-secondary-text)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/_icon.scss b/src/features/ccDarkTheme/core/styles/components/_icon.scss
new file mode 100644
index 0000000..ccba370
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/_icon.scss
@@ -0,0 +1,22 @@
+ec-filter-drawer-item material-icon,
+ ec-filter-drawer-item ec-icon,
+ material-drawer .drawer-section material-icon,
+ material-drawer .drawer-section ec-icon,
+ material-list material-icon,
+ ec-query-builder material-icon,
+ ec-thread-summary material-expansionpanel .title material-icon,
+ .search-results ec-thread-option material-icon,
+ .search-results ec-thread-option ec-icon,
+ ec-rich-text-editor material-icon,
+ ec-editor-command material-icon,
+ ec-canned-responses ec-canned-response-row material-icon,
+ ec-ask-flow > .header material-button {
+ color: var(--TWPT-icon-color)!important;
+}
+
+material-drawer ec-icon,
+ .search-results ec-thread-option ec-icon,
+ ec-thread-summary material-expansionpanel .title ec-icon,
+ ec-announcements-menu-item ec-icon {
+ fill: var(--TWPT-icon-color)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/_index.scss b/src/features/ccDarkTheme/core/styles/components/_index.scss
new file mode 100644
index 0000000..6307f8f
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/_index.scss
@@ -0,0 +1,26 @@
+@forward 'drawer';
+@forward 'notifications';
+@forward 'tabs';
+@forward 'query-builder';
+@forward 'action-bar';
+@forward 'thread-list';
+@forward 'review-bar';
+@forward 'activity-panel';
+@forward 'thread-view';
+@forward 'stepper';
+@forward 'thread-composer';
+@forward 'profile-chart';
+@forward 'user-badge';
+@forward 'duplicate-thread';
+@forward 'buttons';
+@forward 'icon';
+@forward 'dialogs';
+@forward 'rich-text-editor';
+@forward 'thread-insert';
+@forward 'inputs';
+@forward 'menu';
+@forward 'popups';
+@forward 'canned-responses';
+@forward 'settings';
+@forward 'loading-spinner';
+@forward 'custom';
diff --git a/src/features/ccDarkTheme/core/styles/components/_loading-spinner.scss b/src/features/ccDarkTheme/core/styles/components/_loading-spinner.scss
new file mode 100644
index 0000000..ef71ebc
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/_loading-spinner.scss
@@ -0,0 +1,3 @@
+material-spinner {
+ border-color: var(--TWPT-blue-A100)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/_menu.scss b/src/features/ccDarkTheme/core/styles/components/_menu.scss
new file mode 100644
index 0000000..b0e5a02
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/_menu.scss
@@ -0,0 +1,3 @@
+material-menu material-button {
+ color: var(--TWPT-primary-text)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/_profile-chart.scss b/src/features/ccDarkTheme/core/styles/components/_profile-chart.scss
new file mode 100644
index 0000000..2312723
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/_profile-chart.scss
@@ -0,0 +1,44 @@
+ec-user bar-chart .axis text,
+ ec-unified-user .scTailwindSharedActivitychartchart .axis text {
+ fill: var(--TWPT-subtle-button-background)!important;
+}
+
+ec-user bar-chart .axis path,
+ ec-user bar-chart .axis .gridline,
+ ec-user bar-chart .axis line,
+ ec-unified-user .scTailwindSharedActivitychartchart .axis path,
+ ec-unified-user .scTailwindSharedActivitychartchart .axis .gridline,
+ ec-unified-user .scTailwindSharedActivitychartchart .axis line {
+ stroke: rgba(255, 255, 255, .12)!important;
+}
+
+ec-user bar-chart .axis line.axis-zero-tick,
+ ec-user bar-chart .axis.x .tick-mark,
+ ec-unified-user .scTailwindSharedActivitychartchart .axis line.axis-zero-tick,
+ ec-unified-user .scTailwindSharedActivitychartchart .axis.x .tick-mark {
+ stroke: rgba(255, 255, 255, .38)!important;
+}
+
+ec-user bar-chart .aplos-legend-entry,
+ ec-unified-user .scTailwindSharedActivitychartchart .aplos-legend-entry {
+ color: var(--TWPT-secondary-text)!important;
+}
+
+.aplos-hovercard {
+ color: var(--TWPT-interop-secondary-text)!important;
+ background: var(--TWPT-secondary-background)!important;
+ border: none!important;
+}
+
+.aplos-hovercard .title {
+ color: var(--TWPT-primary-text)!important;
+}
+
+.aplos-hovercard .subtitle,
+ .aplos-donut-center .subtitle,
+ .aplos-hovercard .series,
+ .aplos-donut-center .series,
+ .aplos-hovercard .value,
+ .aplos-donut-center .value {
+ color: var(--TWPT-secondary-text)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/_query-builder.scss b/src/features/ccDarkTheme/core/styles/components/_query-builder.scss
new file mode 100644
index 0000000..b7551b7
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/_query-builder.scss
@@ -0,0 +1,19 @@
+// Filters (ec-query-builder)
+material-condition-builder .compound-condition-operator {
+ color: var(--TWPT-secondary-text)!important;
+}
+
+material-condition-builder .compound-condition-operator:is(::before, ::after) {
+ border-left-color: rgba(255, 255, 255, .20)!important;
+}
+
+material-condition-builder .add-button,
+ ec-query-builder .save-filter-button:not([disabled]) {
+ color: var(--TWPT-blue-A100)!important;
+}
+
+material-condition-builder .add-condition,
+ ec-query-builder .close-button {
+ background-color: var(--TWPT-interop-blue)!important;
+ color: #1f1f1f!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/_review-bar.scss b/src/features/ccDarkTheme/core/styles/components/_review-bar.scss
new file mode 100644
index 0000000..ea94e0e
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/_review-bar.scss
@@ -0,0 +1,47 @@
+// Review bar shown above the main message or replies
+ec-review-bar {
+ background-color: var(--TWPT-active-background)!important;
+}
+
+ec-review-bar material-chip {
+ background-color: var(--TWPT-button-background)!important;
+}
+
+ec-review-bar material-chip:not(.relevant-active):not(.active) {
+ border-color: var(--TWPT-card-border)!important;
+}
+
+ec-review-bar material-chip:not(.relevant-active):not(.active) material-icon {
+ color: var(--TWPT-primary-text)!important;
+ fill: var(--TWPT-primary-text)!important;
+}
+
+ec-review-bar material-chip:not(.relevant-active):not(.active) .content {
+ color: var(--TWPT-primary-text)!important;
+}
+
+ec-review-bar material-chip.relevant-active {
+ border-color: var(--TWPT-good-text)!important;
+}
+
+ec-review-bar material-chip.relevant-active material-icon {
+ color: var(--TWPT-good-text)!important;
+ fill: var(--TWPT-good-text)!important;
+}
+
+ec-review-bar material-chip.relevant-active .content {
+ color: var(--TWPT-good-text)!important;
+}
+
+ec-review-bar material-chip.active {
+ border-color: var(--TWPT-bad-text)!important;
+}
+
+ec-review-bar material-chip.active material-icon {
+ color: var(--TWPT-bad-text)!important;
+ fill: var(--TWPT-bad-text)!important;
+}
+
+ec-review-bar material-chip.active .content {
+ color: var(--TWPT-bad-text)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/_rich-text-editor.scss b/src/features/ccDarkTheme/core/styles/components/_rich-text-editor.scss
new file mode 100644
index 0000000..2a6d818
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/_rich-text-editor.scss
@@ -0,0 +1,37 @@
+ec-editor-command material-button,
+ ec-formatting-popup material-button {
+ box-shadow: none!important;
+}
+
+ec-editor-command material-button.is-active {
+ background: var(--TWPT-active-background)!important;
+}
+
+ec-rich-text-editor .placeholder {
+ color: rgba(255, 255, 255, .38)!important;
+}
+
+ec-rich-text-editor .input-wrapper,
+ ec-rich-text-editor .spacer {
+ border-color: var(--TWPT-card-border)!important;
+}
+
+ec-rich-text-editor .input-wrapper.input-wrapper--focused {
+ border-color: var(--TWPT-blue-A100)!important;
+}
+
+ec-rich-text-editor .input {
+ color: var(--TWPT-primary-text)!important;
+}
+
+ec-rich-text-editor .hint {
+ color: var(--TWPT-subtle-button-background)!important;
+}
+
+material-select-searchbox + material-list material-list-item {
+ color: var(--TWPT-icon-color)!important;
+}
+
+ec-attachment .filename {
+ color: var(--TWPT-primary-text)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/_settings.scss b/src/features/ccDarkTheme/core/styles/components/_settings.scss
new file mode 100644
index 0000000..87ebbe0
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/_settings.scss
@@ -0,0 +1,7 @@
+ec-settings .forum-language-container {
+ border-bottom-color: var(--TWPT-subtle-border)!important;
+}
+
+ec-settings .forum-language-container :is(material-button, button) {
+ color: var(--TWPT-secondary-text)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/_stepper.scss b/src/features/ccDarkTheme/core/styles/components/_stepper.scss
new file mode 100644
index 0000000..5c035b1
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/_stepper.scss
@@ -0,0 +1,19 @@
+// The stepper is shown in the "new thread" and "edit message" views
+material-stepper {
+ border-top-color: var(--TWPT-card-border)!important;
+}
+
+material-stepper .stepper-step-name,
+ material-stepper .purpose-title {
+ color: var(--TWPT-primary-text)!important;
+}
+
+ec-ask-flow .display-name-label,
+ material-stepper .additional-details-label,
+ material-stepper .detail-label {
+ color: var(--TWPT-secondary-text)!important;
+}
+
+material-stepper .stepper-step[selectable=true]:focus {
+ background-color: rgba(60, 64, 67, .24)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/_tabs.scss b/src/features/ccDarkTheme/core/styles/components/_tabs.scss
new file mode 100644
index 0000000..e90bc72
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/_tabs.scss
@@ -0,0 +1,11 @@
+material-tab-strip tab-button {
+ color: var(--TWPT-secondary-text)!important;
+}
+
+material-tab-strip tab-button.active {
+ color: var(--TWPT-blue-A100)!important;
+}
+
+material-tab-strip .tab-indicator {
+ border-top-color: var(--TWPT-blue-A100)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/_thread-composer.scss b/src/features/ccDarkTheme/core/styles/components/_thread-composer.scss
new file mode 100644
index 0000000..b4a8cfa
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/_thread-composer.scss
@@ -0,0 +1,73 @@
+ec-thread-composer .main-content .title-label,
+ ec-thread-composer .main-content .post-label {
+ color: var(--TWPT-primary-text-alt)!important;
+}
+
+ec-thread-composer .main-content .title-input,
+ ec-thread-composer .main-content ec-rich-text-editor {
+ border-color: var(--TWPT-card-border)!important;
+}
+
+ec-thread-composer .main-content .title-alert,
+ ec-thread-composer .main-content .footer-disclaimer-error {
+ color: var(--TWPT-bad-text)!important;
+}
+
+ec-thread-composer .main-content .hero-button-container material-button {
+ border-color: var(--TWPT-input-underline);
+}
+
+ec-thread-composer .main-content .hero-button-container material-button .content {
+ color: var(--TWPT-blue-A100)!important;
+}
+
+ec-thread-composer .main-content .draft-button {
+ background: revert!important;
+ color: var(--TWPT-interop-blue);
+ border-color: var(--TWPT-card-border)!important;
+}
+
+ec-thread-composer .main-content .post-button {
+ background: var(--TWPT-interop-blue)!important;
+ color: #1f1f1f!important;
+}
+
+ec-thread-composer .main-content .post-button[disabled] {
+ background: rgba(227, 227, 227, 0.122)!important;
+}
+
+ec-thread-composer material-drawer {
+ background-color: inherit!important;
+}
+
+ec-thread-composer material-drawer .right-panel {
+ border-left-color: var(--TWPT-card-border)!important;
+}
+
+ec-thread-composer material-drawer .panel-section-title {
+ color: var(--TWPT-primary-text)!important;
+}
+
+ec-thread-composer material-drawer .panel-section-divider {
+ border-color: var(--TWPT-card-border)!important;
+}
+
+ec-thread-composer material-drawer material-radio .radio-label {
+ color: var(--TWPT-primary-text-alt)!important;
+}
+
+ec-thread-composer material-drawer material-radio .radio-description,
+ ec-thread-composer material-drawer .settings-section .panel-section-item .select-label {
+ color: var(--TWPT-secondary-text)!important;
+}
+
+material-dialog.community-video-dialog .footer material-button.cancel {
+ color: var(--TWPT-interop-blue)!important;
+}
+
+material-dialog.community-video-dialog .footer material-button.update:not([disabled]) {
+ background: var(--TWPT-interop-blue)!important;
+ color: #1f1f1f!important;
+}
+
+// Note: see _thread-view.scss. There is a rule for the thread creation footer.
diff --git a/src/features/ccDarkTheme/core/styles/components/_thread-insert.scss b/src/features/ccDarkTheme/core/styles/components/_thread-insert.scss
new file mode 100644
index 0000000..ef95c99
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/_thread-insert.scss
@@ -0,0 +1,10 @@
+// ec-thread-insert is a card with a summary of a thread when escalating it.
+ec-thread-insert .title {
+ color: var(--TWPT-primary-text)!important;
+}
+
+ec-thread-insert ec-thread-counts,
+ ec-thread-insert .details,
+ ec-thread-insert ec-relative-time {
+ color: var(--TWPT-subtle-button-background)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/_thread-list.scss b/src/features/ccDarkTheme/core/styles/components/_thread-list.scss
new file mode 100644
index 0000000..c3024d1
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/_thread-list.scss
@@ -0,0 +1,105 @@
+ec-thread-list ul.thread-group {
+ background-color: var(--TWPT-primary-background)!important;
+}
+
+ec-thread-list ec-bulk-actions, ec-thread-list ec-thread-summary material-expansionpanel {
+ border-bottom-color: var(--TWPT-subtle-border)!important;
+}
+
+ec-thread-list .no-results,
+ ec-thread-list .finished-results {
+ color: var(--TWPT-secondary-text)!important;
+}
+
+ec-thread-summary material-expansionpanel.read:not(.checked) {
+ background-color: var(--TWPT-thread-read-background)!important;
+}
+
+ec-thread-summary material-expansionpanel.read .title span:not(.icon) {
+ opacity: 0.8;
+}
+
+ec-thread-summary material-expansionpanel.read .title .icon {
+ opacity: 0.48!important;
+}
+
+ec-thread-summary material-expansionpanel.checked {
+ background-color: #2c4b77!important;
+}
+
+ec-thread-summary material-expansionpanel .title {
+ color: var(--TWPT-primary-text)!important;
+}
+
+ec-thread-summary material-expansionpanel .title .purpose-tag {
+ background-color: rgba(255, 255, 255, .06)!important;
+ color: #a8c7fa!important;
+}
+
+ec-thread-summary material-expansionpanel .title .draft-tag {
+ background-color: #0f5223!important;
+ color: #6dd58c!important;
+}
+
+ec-thread-summary material-expansionpanel ec-second-summary-line,
+ material-expansionpanel .header-content,
+ material-expansionpanel ec-thread-counts > span:not(.recommended-answers),
+ material-expansionpanel .duplicate-label {
+ color: #928e89!important;
+}
+
+material-expansionpanel .removed-label {
+ color: var(--TWPT-bad-text)!important;
+}
+
+ec-thread-summary material-expansionpanel ec-safe-html.body,
+ material-expansionpanel .issue-tracking-work-state {
+ color: var(--TWPT-primary-text)!important;
+}
+
+ec-thread-list material-fab.trigger {
+ background: rgba(124, 172, 248, 0.239)!important;
+ color: var(--TWPT-interop-blue)!important;
+}
+
+.popup-wrapper:has(.actions > .action-wrapper > material-fab.themeable) {
+ background-color: unset!important;
+}
+
+.popup-wrapper .actions > .action-wrapper > material-fab.themeable {
+ background-color: var(--TWPT-button-background)!important;
+ color: var(--TWPT-interop-blue)!important;
+}
+
+// The following section changes the styles of the checkboxes in thread lists,
+// based in the styles defined in the "Checkbox input" section.
+ec-thread-summary material-expansionpanel .action material-button:not(.starred),
+ ec-thread-list material-checkbox material-icon,
+ ec-thread-summary material-expansionpanel .star-button:not(.starred),
+ ec-thread-summary material-expansionpanel .mdc-button.mdc-icon-button material-icon {
+ color: #696867!important; // Custom value to match previous behavior
+ opacity: 1!important;
+}
+
+ec-thread-summary material-expansionpanel .action material-button.starred {
+ color: var(--TWPT-starred)!important;
+}
+
+ec-thread-list material-checkbox material-icon.filled {
+ color: #62a5ff!important; // Custom value to contrast well with the background
+}
+
+// .gm-icons is added by the SMEI_GOOGLE_MATERIAL_ICONS experiment.
+ec-thread-list material-checkbox:focus:not(.disabled).gm-icons .icon,
+ .gm-icons ec-thread-list material-checkbox:focus:not(.disabled) .icon,
+ ec-thread-list material-checkbox:hover:not(.disabled).gm-icons .icon,
+ .gm-icons ec-thread-list material-checkbox:hover:not(.disabled) .icon {
+ color: #807d7c!important; // custom value
+}
+
+ec-thread-list material-checkbox:focus:not(.disabled).gm-icons .icon.filled,
+ .gm-icons ec-thread-list material-checkbox:focus:not(.disabled) .icon.filled,
+ ec-thread-list material-checkbox:hover:not(.disabled).gm-icons .icon.filled,
+ .gm-icons ec-thread-list material-checkbox:hover:not(.disabled) .icon.filled {
+ color: #92c1ff!important; // custom value
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/_thread-view.scss b/src/features/ccDarkTheme/core/styles/components/_thread-view.scss
new file mode 100644
index 0000000..0878169
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/_thread-view.scss
@@ -0,0 +1,210 @@
+ec-question, .heading + .group, ec-message {
+ background-color: var(--TWPT-secondary-background)!important;
+}
+
+ec-thread .no-review-needed {
+ background-color: #155829!important;
+ border-color: var(--TWPT-subtle-border)!important;
+}
+
+// "Original thread" box inside escalations
+sc-tailwind-thread-question-thread-summary .scTailwindThreadQuestionThreadsummarythread-summary {
+ background: var(--TWPT-active-background)!important;
+ border-color: var(--TWPT-card-border)!important;
+}
+
+sc-tailwind-thread-question-thread-summary .scTailwindThreadQuestionThreadsummarydetails {
+ color: var(--TWPT-secondary-text)!important;
+}
+
+sc-tailwind-thread-question-thread-summary .scTailwindThreadQuestionThreadsummarytitle {
+ color: var(--TWPT-primary-text)!important;
+}
+
+ec-message-header .header, ec-question .state, ec-question ec-thread-counts > span, ec-message ec-thread-counts > span {
+ color: var(--TWPT-secondary-text)!important;
+}
+
+ec-question .alert, ec-message .alert {
+ background-color: var(--TWPT-active-background)!important;
+}
+
+ec-question .alert material-icon, ec-message .alert material-icon {
+ color: var(--TWPT-primary-text)!important;
+}
+
+ec-question .alert ec-icon, ec-message .alert ec-icon {
+ color: var(--TWPT-primary-text)!important;
+ fill: var(--TWPT-primary-text)!important;
+}
+
+ec-question .alert material-button {
+ color: var(--TWPT-link)!important;
+}
+
+ec-question .title {
+ color: var(--TWPT-primary-text-alt)!important;
+}
+
+ec-user-link .name-text {
+ color: var(--TWPT-link)!important;
+}
+
+ec-message-header ec-avatar svg, ec-message-header .role,
+ ec-message .footer .role {
+ filter: brightness(1.5);
+}
+
+ec-question .body, ec-message .body {
+ color: var(--TWPT-primary-text)!important;
+}
+
+ec-question .thread-insert {
+ background: none!important;
+}
+
+ec-question .details-heading {
+ color: var(--TWPT-primary-text-alt) !important;
+}
+
+ec-question .state-chips material-chip {
+ background-color: var(--TWPT-button-background)!important;
+ border: none!important;
+ box-shadow: 0 2px 1px -1px rgba(0, 0, 0, 0.2),
+ 0 1px 1px 0 rgba(0, 0, 0, 0.14),
+ 0 1px 3px 0 rgba(0, 0, 0, 0.12)!important;
+}
+
+ec-question .state-chips material-chip .content {
+ color: var(--TWPT-primary-text)!important;
+}
+
+ec-question .footer,
+ ec-ask-flow .content-disclaimer {
+ color: var(--TWPT-primary-text)!important;
+ background-color: var(--TWPT-active-background)!important;
+ border-top-color: var(--TWPT-card-border)!important;
+}
+
+.heading {
+ color: var(--TWPT-primary-text)!important;
+}
+
+.heading + .group,
+ .load-more-bar,
+ ec-message:not(:first-child),
+ .load-more-bar .load-more-button,
+ .load-more-bar .load-all-button {
+ border-color: var(--TWPT-card-border)!important;
+}
+
+ec-message .type {
+ color: var(--TWPT-primary-text)!important;
+}
+
+ec-message .footer ec-relative-time,
+ ec-message .footer ec-safe-html {
+ color: var(--TWPT-secondary-text)!important;
+}
+
+ec-message .helpful-prompt {
+ color: var(--TWPT-primary-text)!important;
+}
+
+ec-question .me-too-button,
+ ec-question .subscribe-button,
+ ec-message .upvote-button,
+ ec-message .downvote-button {
+ color: var(--TWPT-secondary-text)!important;
+ background-color: var(--TWPT-button-background)!important;
+}
+
+ec-message .alert {
+ color: var(--TWPT-secondary-text)!important;
+}
+
+ec-question .me-too-button.selected,
+ ec-question .subscribe-button.selected,
+ ec-message .upvote-button.selected,
+ ec-message .downvote-button.selected {
+ color: #4285f4!important;
+}
+
+.load-more-bar .load-more-button, .load-more-bar .load-all-button {
+ background-color: var(--TWPT-secondary-background)!important;
+}
+
+.locked-alert {
+ background-color: var(--TWPT-active-background)!important;
+ border: var(--TWPT-card-border)!important;
+}
+
+.locked-alert material-icon {
+ color: rgba(255, 255, 255, .38)!important;
+}
+
+ec-thread button.reply.collapsed {
+ color: var(--TWPT-secondary-text)!important;
+}
+
+ec-thread .finished-question {
+ background-color: var(--TWPT-active-background)!important;
+ border: var(--TWPT-card-border)!important;
+}
+
+ec-thread .finished-question .next-question {
+ color: var(--TWPT-link)!important;
+ border-color: var(--TWPT-link)!important;
+}
+
+.material-content .action-bar material-button.has-activity {
+ color: var(--TWPT-blue-A100)!important;
+}
+
+.material-content .action-bar material-button.showing-sidebar {
+ background-color: var(--TWPT-active-background)!important;
+}
+
+// Recommended answers - show in green where we've overwritten the colors
+.recommended-answers {
+ color: #34a853!important;
+}
+
+// Suggested answers - show brighter blue
+.suggested-icon {
+ color: var(--TWPT-blue-A100)!important;
+}
+
+// Help button (shown in the suggested answers header)
+.explanation-icon material-icon {
+ color: var(--TWPT-subtle-button-background)!important;
+}
+
+// Help button tooltip
+.popup .paper-container {
+ background: var(--TWPT-drawer-background)!important;
+}
+
+.explanation-icon material-icon:hover {
+ color: var(--TWPT-blue-A100)!important;
+}
+
+// Notice used e.g. for deleted threads
+ec-thread .notice {
+ material-icon {
+ color: var(--TWPT-icon-color)!important;
+ }
+
+ .notice-heading {
+ color: var(--TWPT-primary-text)!important;
+ }
+
+ .notice-message {
+ color: var(--TWPT-secondary-text)!important;
+ }
+
+ material-button {
+ background: var(--TWPT-interop-blue)!important;
+ color: #1f1f1f!important;
+ }
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/_user-badge.scss b/src/features/ccDarkTheme/core/styles/components/_user-badge.scss
new file mode 100644
index 0000000..3915b62
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/_user-badge.scss
@@ -0,0 +1,55 @@
+/**
+ * Some fixes for the interop PE badge components in the Community Console.
+ *
+ * The |.scTailwindThreadPost_headerUserinfotag| elements have a
+ * |style="--color:#aaaaaa"| attribute which indicates the color of the badge,
+ * and we are transforming it to the dark mode color accordingly.
+ *
+ * The | .scTailwindThreadMessageMessageinteractionsuser-label| elements have a
+ * |style="--userLabelColor: #aaaaaa"| attribute, so we do the same there.
+ *
+ * We match only the hex color instead of the whole attribute because over time
+ * the attributes have changed (spaces have been removed, for instance).
+ */
+
+// Alumnus
+.scTailwindThreadPost_headerUserinfotag[style*="#0F9D58" i],
+ .scTailwindThreadMessageMessageinteractionsuser-label[style*="#0F9D58" i] {
+ --color: #C4EED0!important;
+ --userLabelColor: #C4EED0!important;
+}
+
+// Bronze
+.scTailwindThreadPost_headerUserinfotag[style*="#896E63" i],
+ .scTailwindThreadMessageMessageinteractionsuser-label[style*="#896E63" i] {
+ --color: #B9ABA3!important;
+ --userLabelColor: #B9ABA3!important;
+}
+
+// Silver
+.scTailwindThreadPost_headerUserinfotag[style*="#5F6368" i],
+ .scTailwindThreadMessageMessageinteractionsuser-label[style*="#5F6368" i] {
+ --color: #C4C7C5!important;
+ --userLabelColor: #C4C7C5!important;
+}
+
+// Gold
+.scTailwindThreadPost_headerUserinfotag[style*="#E37400" i],
+ .scTailwindThreadMessageMessageinteractionsuser-label[style*="#E37400" i] {
+ --color: #F09D00!important;
+ --userLabelColor: #F09D00!important;
+}
+
+// Platinum
+.scTailwindThreadPost_headerUserinfotag[style*="#455A64" i],
+ .scTailwindThreadMessageMessageinteractionsuser-label[style*="#455A64" i] {
+ --color: #E3E3E3!important;
+ --userLabelColor: #E3E3E3!important;
+}
+
+// Diamond, Community Specialist, Community Manager and Google Employee
+.scTailwindThreadPost_headerUserinfotag[style*="#1A73E8" i],
+ .scTailwindThreadMessageMessageinteractionsuser-label[style*="#1A73E8" i] {
+ --color: #A8C7FA!important;
+ --userLabelColor: #A8C7FA!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/buttons/_button.scss b/src/features/ccDarkTheme/core/styles/components/buttons/_button.scss
new file mode 100644
index 0000000..b748e5d
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/buttons/_button.scss
@@ -0,0 +1,9 @@
+material-button[disabled] {
+ color: rgba(255, 255, 255, .26)!important;
+}
+
+.mdc-button {
+ --gm-colortextbutton-ink-color: var(--TWPT-interop-blue);
+ --gm-colortextbutton-ink-color--stateful: var(--TWPT-interop-blue);
+ --gm-colortextbutton-disabled-ink-color: rgba(255, 255, 255, .26);
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/buttons/_index.scss b/src/features/ccDarkTheme/core/styles/components/buttons/_index.scss
new file mode 100644
index 0000000..ab002dc
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/buttons/_index.scss
@@ -0,0 +1,4 @@
+@forward 'button';
+@forward 'yes-no';
+@forward 'reply';
+@forward 'skip-to-main';
diff --git a/src/features/ccDarkTheme/core/styles/components/buttons/_reply.scss b/src/features/ccDarkTheme/core/styles/components/buttons/_reply.scss
new file mode 100644
index 0000000..bc7aeaf
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/buttons/_reply.scss
@@ -0,0 +1,5 @@
+material-fab.reply-button,
+ material-fab.reply-fab {
+ background-color: var(--TWPT-link)!important;
+ color: var(--TWPT-primary-background)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/buttons/_skip-to-main.scss b/src/features/ccDarkTheme/core/styles/components/buttons/_skip-to-main.scss
new file mode 100644
index 0000000..17eb10f
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/buttons/_skip-to-main.scss
@@ -0,0 +1,3 @@
+.skip-to-main:focus {
+ background: revert!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/buttons/_yes-no.scss b/src/features/ccDarkTheme/core/styles/components/buttons/_yes-no.scss
new file mode 100644
index 0000000..3127b9e
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/buttons/_yes-no.scss
@@ -0,0 +1,21 @@
+material-yes-no-buttons material-button:not([disabled]).highlighted:not([raised]) {
+ color: var(--TWPT-blue-A100)!important;
+}
+
+material-yes-no-buttons material-button:not([disabled]).highlighted:not([raised]):is(:hover, :focus) {
+ background-color: revert!important;
+}
+
+material-yes-no-buttons material-button:not([disabled]).highlighted:not([raised]):is(:hover, :focus):after {
+ content: "";
+ display: block;
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: currentColor;
+ opacity: .12;
+ border-radius: inherit;
+ pointer-events: none;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/custom/_chip.scss b/src/features/ccDarkTheme/core/styles/components/custom/_chip.scss
new file mode 100644
index 0000000..f2840d3
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/custom/_chip.scss
@@ -0,0 +1,4 @@
+.TWPT-extrainfo-chip {
+ border: 1px solid var(--TWPT-interop-subtle-border)!important;
+ color: var(--TWPT-interop-secondary-text)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/custom/_index.scss b/src/features/ccDarkTheme/core/styles/components/custom/_index.scss
new file mode 100644
index 0000000..e73007c
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/custom/_index.scss
@@ -0,0 +1,3 @@
+@forward 'chip';
+@forward 'log';
+@forward 'warning';
diff --git a/src/features/ccDarkTheme/core/styles/components/custom/_log.scss b/src/features/ccDarkTheme/core/styles/components/custom/_log.scss
new file mode 100644
index 0000000..5184810
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/custom/_log.scss
@@ -0,0 +1,7 @@
+.TWPT-log {
+ background-color: #424242!important;
+}
+
+.TWPT-log-entry.TWPT-log-entry--error {
+ color: #ff8A80!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/custom/_warning.scss b/src/features/ccDarkTheme/core/styles/components/custom/_warning.scss
new file mode 100644
index 0000000..f40844a
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/custom/_warning.scss
@@ -0,0 +1,3 @@
+.TWPT-warning {
+ background-color: #670505!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/dialogs/_bug-case-links.scss b/src/features/ccDarkTheme/core/styles/components/dialogs/_bug-case-links.scss
new file mode 100644
index 0000000..0d35544
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/dialogs/_bug-case-links.scss
@@ -0,0 +1,7 @@
+.bug-case-links-dialog material-button.add-button {
+ color: var(--TWPT-blue-A100)!important;
+}
+
+ec-bug-case-link material-button {
+ color: var(--TWPT-secondary-text)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/dialogs/_dialog.scss b/src/features/ccDarkTheme/core/styles/components/dialogs/_dialog.scss
new file mode 100644
index 0000000..4f3570c
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/dialogs/_dialog.scss
@@ -0,0 +1,56 @@
+material-dialog, material-dialog .dialog-header {
+ background-color: var(--TWPT-primary-background)!important;
+}
+
+ec-movable-dialog[showminimize] material-dialog .dialog-header {
+ background-color: #d2e3fc!important;
+}
+
+material-dialog .title {
+ color: var(--TWPT-primary-text-alt)!important;
+}
+
+material-dialog header material-button:is(.close-button, [debugid="close-button"]) material-icon {
+ color: var(--TWPT-subtle-button-background)!important;
+}
+
+ec-movable-dialog[showminimize] material-dialog .dialog-header .title, ec-movable-dialog[showminimize] material-dialog header material-icon {
+ color: var(--TWPT-primary-background)!important;
+}
+
+ec-movable-dialog material-dialog :is(.header-notice, .notice), material-dialog .legal-prompt {
+ background-color: #394457!important;
+}
+
+ec-movable-dialog material-dialog .main :is(.header-notice, .notice) material-icon[icon="info_outline"] {
+ color: var(--TWPT-blue-A100)!important;
+}
+
+material-dialog .section-title,
+ material-dialog .select-label,
+ material-dialog .input-label,
+ material-dialog .btn-no,
+ ec-display-name-editor,
+ .forum-selection-label {
+ color: var(--TWPT-secondary-text)!important;
+}
+
+material-dialog main > .user {
+ border-bottom-color: var(--TWPT-card-border)!important;
+}
+
+ec-movable-dialog[showminimize] material-dialog footer > [footer] > .footer > [footer] > simple-html {
+ color: var(--TWPT-secondary-text)!important;
+ background-color: var(--TWPT-active-background)!important;
+ border-top-color: #25231f!important;
+}
+
+ec-movable-dialog[showminimize] material-dialog footer > [footer] > .footer > [footer] > simple-html a {
+ color: var(--TWPT-link)!important;
+}
+
+material-dialog .footer material-button[raised]:not([disabled]),
+ material-dialog .footer .mdc-button.submit:not(:disabled){
+ background-color: var(--TWPT-blue-A100)!important;
+ color: #1f1f1f!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/dialogs/_index.scss b/src/features/ccDarkTheme/core/styles/components/dialogs/_index.scss
new file mode 100644
index 0000000..3ec7a09
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/dialogs/_index.scss
@@ -0,0 +1,5 @@
+@forward 'dialog';
+@forward 'private-message';
+@forward 'keyboard-shortcuts';
+@forward 'bug-case-links';
+@forward 'report';
diff --git a/src/features/ccDarkTheme/core/styles/components/dialogs/_keyboard-shortcuts.scss b/src/features/ccDarkTheme/core/styles/components/dialogs/_keyboard-shortcuts.scss
new file mode 100644
index 0000000..047118b
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/dialogs/_keyboard-shortcuts.scss
@@ -0,0 +1,20 @@
+material-dialog .main.with-scroll-strokes table th {
+ color: var(--TWPT-primary-text)!important;
+}
+
+material-dialog .main.with-scroll-strokes table td {
+ color: var(--TWPT-primary-text-alt)!important;
+}
+
+material-dialog .main.with-scroll-strokes table tr,
+ material-dialog .main.with-scroll-strokes .shortcut {
+ border-color: var(--TWPT-card-border)!important;
+}
+
+material-dialog .main.with-scroll-strokes.bottom-scroll-stroke {
+ border-bottom-color: var(--TWPT-card-border)!important;
+}
+
+material-dialog .main.with-scroll-strokes.top-scroll-stroke {
+ border-top-color: var(--TWPT-card-border)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/dialogs/_private-message.scss b/src/features/ccDarkTheme/core/styles/components/dialogs/_private-message.scss
new file mode 100644
index 0000000..7e531b9
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/dialogs/_private-message.scss
@@ -0,0 +1,7 @@
+ec-movable-dialog .wrapper > .main > main > .top-row > div { // Note: this is too generic so it might match other things
+ color: var(--TWPT-primary-text)!important;
+}
+
+ec-movable-dialog .wrapper > .main > main > .top-row .recipient-container .recipient {
+ color: var(--TWPT-secondary-text)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/dialogs/_report.scss b/src/features/ccDarkTheme/core/styles/components/dialogs/_report.scss
new file mode 100644
index 0000000..8c6bb46
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/dialogs/_report.scss
@@ -0,0 +1,3 @@
+iframe[src*="reportingwidget"] {
+ color-scheme: auto;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/inputs/_checkbox.scss b/src/features/ccDarkTheme/core/styles/components/inputs/_checkbox.scss
new file mode 100644
index 0000000..657373f
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/inputs/_checkbox.scss
@@ -0,0 +1,35 @@
+// This doesn't apply to checkboxes in the drawer
+material-checkbox material-icon:not(ec-forum-drawer-item material-icon, ec-thread-list material-icon) {
+ color: var(--TWPT-secondary-text)!important;
+}
+
+material-checkbox .content:not(ec-forum-drawer-item material-icon, ec-thread-list material-icon) {
+ color: var(--TWPT-primary-text)!important;
+}
+
+material-checkbox.disabled .content:not(ec-forum-drawer-item material-icon, ec-thread-list material-icon) {
+ color: rgba(255, 255, 255, .54)!important;
+}
+
+/* .gm-icons is added by the SMEI_GOOGLE_MATERIAL_ICONS experiment. */
+material-checkbox material-icon.filled:not(ec-forum-drawer-item material-icon, ec-thread-list material-icon) {
+ color: var(--TWPT-blue-A100)!important;
+}
+
+material-checkbox:focus:not(.disabled).gm-icons .icon,
+ .gm-icons material-checkbox:focus:not(.disabled) .icon,
+ material-checkbox:hover:not(.disabled).gm-icons .icon,
+ .gm-icons material-checkbox:hover:not(.disabled) .icon {
+ color: #cfd2d8!important; /* custom value */
+}
+
+material-checkbox:focus:not(.disabled).gm-icons .icon.filled,
+ .gm-icons material-checkbox:focus:not(.disabled) .icon.filled,
+ material-checkbox:hover:not(.disabled).gm-icons .icon.filled,
+ .gm-icons material-checkbox:hover:not(.disabled) .icon.filled {
+ color: var(--TWPT-blue-100)!important;
+}
+
+.gm-icons material-checkbox .icon-container::before{
+ background-color: #dfdedb!important; /* custom value */
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/inputs/_dropdown-select.scss b/src/features/ccDarkTheme/core/styles/components/inputs/_dropdown-select.scss
new file mode 100644
index 0000000..9ea47d8
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/inputs/_dropdown-select.scss
@@ -0,0 +1,8 @@
+material-dropdown-select dropdown-button {
+ color: var(--TWPT-primary-text)!important;
+}
+
+material-dropdown-select dropdown-button .button.is-disabled .button-text,
+ material-dropdown-select dropdown-button .button.is-disabled material-icon {
+ color: rgba(255, 255, 255, .32)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/inputs/_index.scss b/src/features/ccDarkTheme/core/styles/components/inputs/_index.scss
new file mode 100644
index 0000000..a1d509b
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/inputs/_index.scss
@@ -0,0 +1,7 @@
+@forward 'checkbox';
+@forward 'dropdown-select';
+@forward 'pickers';
+@forward 'radio';
+@forward 'selector';
+@forward 'switch';
+@forward 'text';
diff --git a/src/features/ccDarkTheme/core/styles/components/inputs/_pickers.scss b/src/features/ccDarkTheme/core/styles/components/inputs/_pickers.scss
new file mode 100644
index 0000000..d551158
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/inputs/_pickers.scss
@@ -0,0 +1,18 @@
+ec-work-state-picker > button,
+ ec-symptom-picker > button {
+ color: var(--TWPT-secondary-text)!important;
+ background-color: var(--TWPT-button-background)!important;
+ border-color: var(--TWPT-subtle-border)!important;
+}
+
+.material-popup-content .popup-content {
+ header {
+ .title {
+ color: var(--TWPT-primary-text)!important;
+ }
+
+ material-button material-icon {
+ color: var(--TWPT-subtle-button-background)!important;
+ }
+ }
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/inputs/_radio.scss b/src/features/ccDarkTheme/core/styles/components/inputs/_radio.scss
new file mode 100644
index 0000000..e7b1668
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/inputs/_radio.scss
@@ -0,0 +1,12 @@
+material-radio .icon-container:not(.checked) material-icon {
+ color: var(--TWPT-secondary-text)!important;
+}
+
+material-radio .icon-container.checked material-icon {
+ color: var(--TWPT-blue-A100)!important;
+}
+
+material-radio {
+ --gm-radio-stroke-color--checked: var(--TWPT-blue-A100);
+ --gm-radio-ink-color: var(--TWPT-blue-A100);
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/inputs/_selector.scss b/src/features/ccDarkTheme/core/styles/components/inputs/_selector.scss
new file mode 100644
index 0000000..96650ac
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/inputs/_selector.scss
@@ -0,0 +1,51 @@
+// This applies not only to the selector but also to the ec-work-state-picker.
+material-list, .popup .item-group-list {
+ background-color: var(--TWPT-drawer-background)!important;
+}
+
+material-list [group]:not(.empty) + *:not(script):not(template):not(.empty),
+ .popup .item-group-list [group]:not(.empty) + *:not(script):not(template):not(.empty) {
+ box-shadow: inset 0 8px 0 0 var(--TWPT-drawer-background)!important;
+ border-top-color: #1f1f1f!important;
+}
+
+material-list material-select-item:hover,
+ material-list material-select-item:focus,
+ material-list material-select-dropdown-item:hover,
+ material-list material-select-dropdown-item:focus,
+ material-list material-select-dropdown-item.active,
+ material-list material-select-dropdown-item:not(.multiselect).selected,
+ material-select-searchbox:focus-within + material-list .single-select-item:first-of-type,
+ .popup .item-group-list material-select-item:hover,
+ .popup .item-group-list material-select-item:focus,
+ .popup .item-group-list material-select-item.active,
+ .popup .item-group-list material-select-dropdown-item:hover,
+ .popup .item-group-list material-select-dropdown-item:focus,
+ .popup .item-group-list material-select-dropdown-item.active,
+ .popup .item-group-list material-select-dropdown-item:not(.multiselect).selected {
+ background-color: var(--TWPT-highlighted-item-background)!important;
+}
+
+material-list .single-select-item,
+ material-list .menu-item-label,
+ material-list .label,
+ material-list .text-segment,
+ menu-item-groups .single-select-item,
+ menu-item-groups .menu-item-label,
+ menu-item-groups .label,
+ menu-item-groups .text-segment {
+ color: var(--TWPT-icon-color)!important;
+}
+
+.popup .item-group-list material-icon {
+ color: rgba(255, 255, 255, .7)!important;
+}
+
+material-list [group] > [label] {
+ color: #8a8a8a!important;
+}
+
+// This is shown in the new thread view
+ec-forum-language-picker .labeled-select .select-label {
+ color: var(--TWPT-secondary-text)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/inputs/_switch.scss b/src/features/ccDarkTheme/core/styles/components/inputs/_switch.scss
new file mode 100644
index 0000000..4d1f61d
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/inputs/_switch.scss
@@ -0,0 +1,15 @@
+.mdc-switch:not(.mdc-switch--checked) .mdc-switch__track {
+ background-color: #7d7d7d!important; /* custom value */
+}
+
+.mdc-switch:not(.mdc-switch--checked) .mdc-switch__thumb {
+ border-color: #fff!important; /* custom value */
+}
+
+.mdc-switch.mdc-switch--checked .mdc-switch__track {
+ background-color: var(--TWPT-blue-A100)!important;
+}
+
+.mdc-switch.mdc-switch--checked .mdc-switch__thumb {
+ border-color: var(--TWPT-blue-A100)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/inputs/_text.scss b/src/features/ccDarkTheme/core/styles/components/inputs/_text.scss
new file mode 100644
index 0000000..b61da70
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/inputs/_text.scss
@@ -0,0 +1,70 @@
+material-input input {
+ color: var(--TWPT-primary-text)!important;
+}
+
+material-input .label-text,
+ material-input .hint-text,
+ material-input .counter,
+ material-input .leading-text,
+ material-input .leading-text material-icon {
+ color: var(--TWPT-subtle-button-background)!important;
+}
+
+material-input .underline .unfocused-underline {
+ background-color: var(--TWPT-input-underline)!important;
+}
+
+material-input .underline .focused-underline {
+ background-color: var(--TWPT-blue-A100)!important;
+}
+
+:is(material-input.gm-input, .gm-input material-input) .baseline {
+ border-color: var(--gm-outlinedtextfield-outline-color)!important;
+}
+
+:is(material-input.gm-input, .gm-input material-input) .baseline:hover {
+ border-color: var(--gm-outlinedtextfield-outline-color)!important;
+}
+
+:is(material-input.gm-input, .gm-input material-input) .baseline.focused {
+ border-color: var(--gm-outlinedtextfield-outline-color--stateful)!important;
+}
+
+:is(material-input.gm-input, .gm-input material-input).invalid .baseline {
+ border-color: var(--gm-outlinedtextfield-outline-color--error)!important;
+}
+
+:is(material-input.gm-input, .gm-input material-input).invalid .error-text {
+ color: var(--gm-outlinedtextfield-helper-text-color--error)!important;
+}
+
+label .label,
+ .input-field > .label {
+ color: var(--TWPT-primary-text)!important;
+}
+
+.mdc-text-field--outlined:hover:not(.mdc-text-field--disabled):not(.mdc-text-field--focused) .mdc-floating-label {
+ color: var(--gm-outlinedtextfield-label-color)!important;
+}
+
+.mdc-text-field--outlined:hover:not(.mdc-text-field--disabled):not(.mdc-text-field--focused) .mdc-notched-outline :is(.mdc-notched-outline__leading, .mdc-notched-outline__notch, .mdc-notched-outline__trailing) {
+ border-color: var(--gm-outlinedtextfield-outline-color)!important;
+}
+
+.mdc-text-field--outlined.mdc-text-field--invalid:hover:not(.mdc-text-field--focused):not(.mdc-text-field--disabled) .mdc-floating-label {
+ color: var(--gm-outlinedtextfield-label-color--error)!important;
+}
+
+.mdc-text-field--outlined.mdc-text-field--invalid:hover:not(.mdc-text-field--disabled):not(.mdc-text-field--focused) .mdc-notched-outline :is(.mdc-notched-outline__leading, .mdc-notched-outline__notch, .mdc-notched-outline__trailing) {
+ border-color: var(--gm-outlinedtextfield-outline-color--error)!important;
+}
+
+.mdc-text-field--outlined.mdc-text-field--invalid:hover:not(.mdc-text-field--focused):not(.mdc-text-field--disabled) + .mdc-text-field-helper-line .mdc-text-field-helper-text {
+ color: var(--gm-outlinedtextfield-helper-text-color--error)!important;
+}
+
+// Input underline
+material-input .underline .unfocused-underline,
+ material-dropdown-select dropdown-button [buttondecorator] {
+ border-color: var(--TWPT-input-underline)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/notifications/_bell.scss b/src/features/ccDarkTheme/core/styles/components/notifications/_bell.scss
new file mode 100644
index 0000000..1e3d0b5
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/notifications/_bell.scss
@@ -0,0 +1,3 @@
+notification-bell:focus {
+ background-color: rgba(255, 255, 255, .10)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/notifications/_index.scss b/src/features/ccDarkTheme/core/styles/components/notifications/_index.scss
new file mode 100644
index 0000000..f5445bb
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/notifications/_index.scss
@@ -0,0 +1,2 @@
+@forward 'bell';
+@forward 'panel';
diff --git a/src/features/ccDarkTheme/core/styles/components/notifications/_panel.scss b/src/features/ccDarkTheme/core/styles/components/notifications/_panel.scss
new file mode 100644
index 0000000..6e443ec
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/notifications/_panel.scss
@@ -0,0 +1,32 @@
+.notification-panel .header {
+ border-bottom-color: var(--TWPT-card-border)!important;
+}
+
+.notification-panel .header material-button {
+ color: var(--TWPT-secondary-text)!important;
+}
+
+.notification-panel .cards-container .promo-message {
+ color: var(--TWPT-secondary-text)!important;
+}
+
+.notification-panel .cards-container .promo-message .header-text {
+ color: var(--TWPT-primary-text)!important;
+}
+
+.notification-panel .cards-container ec-notification-card-content {
+ border-bottom-color: var(--TWPT-card-border)!important;
+}
+
+.notification-panel .cards-container ec-notification-card-content .text {
+ color: var(--TWPT-primary-text)!important;
+}
+
+.notification-panel .cards-container ec-notification-card-content .text a {
+ color: var(--TWPT-link)!important;
+}
+
+.notification-panel .cards-container ec-notification-card-content .time,
+ .notification-panel .cards-container ec-notification-card-content .close material-button {
+ color: var(--TWPT-secondary-text)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/popups/_account-selector.scss b/src/features/ccDarkTheme/core/styles/components/popups/_account-selector.scss
new file mode 100644
index 0000000..f4da84b
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/popups/_account-selector.scss
@@ -0,0 +1,12 @@
+.popup-wrapper .profile .email {
+ color: var(--TWPT-subtle-button-background)!important;
+}
+
+material-gaia-picker-footer {
+ color: var(--TWPT-subtle-button-background)!important;
+ background-color: var(--TWPT-active-background)!important;
+}
+
+material-gaia-picker-footer material-button {
+ color: var(--TWPT-secondary-text)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/popups/_announcements.scss b/src/features/ccDarkTheme/core/styles/components/popups/_announcements.scss
new file mode 100644
index 0000000..03b12d1
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/popups/_announcements.scss
@@ -0,0 +1,30 @@
+ec-announcements-content .header,
+ ec-announcements-content .no-announcements,
+ ec-announcements-content .announcement {
+ border-bottom-color: var(--TWPT-card-border)!important;
+}
+
+ec-announcements-content .header .title, ec-announcements-content .announcement-title {
+ color: var(--TWPT-primary-text-alt)!important;
+}
+
+ec-announcements-content .announcement-date {
+ color: var(--TWPT-secondary-text)!important;
+}
+
+ec-announcements-content .no-announcements-message {
+ color: #c3bfbc!important;
+}
+
+ec-announcements-content .view-all-link,
+ ec-announcements-content .read-more-button {
+ color: var(--TWPT-link)!important;
+}
+
+ec-announcements-content ::-webkit-scrollbar-thumb {
+ background-color: rgba(255, 255, 255, .26)!important;
+}
+
+ec-announcements-content ::-webkit-scrollbar-thumb:hover {
+ background-color: #4285f4!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/components/popups/_index.scss b/src/features/ccDarkTheme/core/styles/components/popups/_index.scss
new file mode 100644
index 0000000..a12ea2c
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/popups/_index.scss
@@ -0,0 +1,3 @@
+@forward 'popup';
+@forward 'account-selector';
+@forward 'announcements';
diff --git a/src/features/ccDarkTheme/core/styles/components/popups/_popup.scss b/src/features/ccDarkTheme/core/styles/components/popups/_popup.scss
new file mode 100644
index 0000000..11f01e7
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/components/popups/_popup.scss
@@ -0,0 +1,8 @@
+// Generic popup (for notification bell, account selector, etc.)
+.popup-wrapper {
+ background-color: var(--TWPT-drawer-background)!important;
+
+ .header-text {
+ color: var(--TWPT-primary-text)!important;
+ }
+}
diff --git a/src/features/ccDarkTheme/core/styles/layout/_header.scss b/src/features/ccDarkTheme/core/styles/layout/_header.scss
new file mode 100644
index 0000000..8e13bac
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/layout/_header.scss
@@ -0,0 +1,34 @@
+.material-content > header {
+ background-color: var(--TWPT-primary-background)!important;
+}
+
+.material-content > header .app-title-button,
+ .material-content > header .app-title-text {
+ color: var(--TWPT-secondary-text)!important;
+}
+
+.material-content > header :is(material-button,
+ material-button material-icon,
+ .mdc-button.mdc-icon-button,
+ .mdc-button.mdc-icon-button material-icon,
+ notification-bell material-icon) {
+ color: var(--TWPT-icon-color)!important;
+}
+
+.search-box {
+ background-color: #313235!important;
+}
+
+.search-box .clear-icon {
+ opacity: 0.8;
+ color: var(--TWPT-icon-color)!important;
+}
+
+.material-content > header .bell.mixin {
+ fill: var(--TWPT-icon-color)!important;
+}
+
+// Header menus
+.popup material-list-item {
+ color: var(--TWPT-drawer-text)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/layout/_index.scss b/src/features/ccDarkTheme/core/styles/layout/_index.scss
new file mode 100644
index 0000000..c50e4e1
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/layout/_index.scss
@@ -0,0 +1,2 @@
+@forward 'header';
+@forward 'main';
diff --git a/src/features/ccDarkTheme/core/styles/layout/_main.scss b/src/features/ccDarkTheme/core/styles/layout/_main.scss
new file mode 100644
index 0000000..0f50d46
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/layout/_main.scss
@@ -0,0 +1,27 @@
+.main {
+ color: var(--TWPT-primary-text)!important;
+}
+
+// Border color for the page title bar (most pages use .title-bar although
+// some use .page-header).
+main .title-bar, main .page-header {
+ border-bottom-color: var(--TWPT-subtle-border)!important;
+}
+
+main .title-bar .title, main .page-header h1, main .header h1 {
+ color: var(--TWPT-primary-text)!important;
+}
+
+.card {
+ background-color: var(--TWPT-secondary-background)!important;
+ color: var(--TWPT-primary-text)!important;
+ border-color: var(--TWPT-card-border)!important;
+}
+
+.card .card-title, .card, .card-section-title {
+ color: var(--TWPT-primary-text)!important;
+}
+
+.card .card-section-hint, .card .card-section-checkbox-hint {
+ color: var(--TWPT-secondary-text)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/main.scss b/src/features/ccDarkTheme/core/styles/main.scss
new file mode 100644
index 0000000..34f4679
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/main.scss
@@ -0,0 +1,5 @@
+@use 'abstracts/variables';
+@use 'base/base';
+@use 'layout';
+@use 'components';
+@use 'vendors';
diff --git a/src/features/ccDarkTheme/core/styles/vendors/_index.scss b/src/features/ccDarkTheme/core/styles/vendors/_index.scss
new file mode 100644
index 0000000..c26393a
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/vendors/_index.scss
@@ -0,0 +1 @@
+@forward 'google';
diff --git a/src/features/ccDarkTheme/core/styles/vendors/google/IMPORTANT_NOTICE.txt b/src/features/ccDarkTheme/core/styles/vendors/google/IMPORTANT_NOTICE.txt
new file mode 100644
index 0000000..7825047
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/vendors/google/IMPORTANT_NOTICE.txt
@@ -0,0 +1,2 @@
+IMPORTANT NOTICE: the styles in this folder have been written by Googlers and
+thus are not included as part of the MIT license.
diff --git a/src/features/ccDarkTheme/core/styles/vendors/google/_common-interop-components.scss b/src/features/ccDarkTheme/core/styles/vendors/google/_common-interop-components.scss
new file mode 100644
index 0000000..6a9f28a
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/vendors/google/_common-interop-components.scss
@@ -0,0 +1,770 @@
+/*
+ * IMPORTANT NOTICE:
+ * Note: the following styles have been written by Googlers and thus are not
+ * included as part of the MIT license.
+ **/
+
+.scSharedCalloutroot {
+ color: var(--TWPT-interop-primary-text)!important;
+}
+
+.scSharedCallouterror {
+ background-color: #523a3b!important;
+ border-color: #f9dedc!important;
+}
+
+.scSharedCallouterror sc-shared-material-icon {
+ color: #f9dedc!important;
+}
+
+.scSharedCallouterror>.scSharedCalloutsecondary-button button {
+ color: #ec928e!important;
+}
+
+.scSharedCalloutcaution {
+ background-color: #554c33!important;
+ border-color: #ffdf99!important;
+}
+
+.scSharedCalloutcaution sc-shared-material-icon {
+ color: #ffdf99!important;
+}
+
+.scSharedCalloutcaution>.scSharedCalloutsecondary-button button {
+ color: #f09d00!important;
+}
+
+.scSharedCalloutinformational {
+ background-color: #394457!important;
+ border-color: #d3e3fd!important;
+}
+
+.scSharedCalloutinformational sc-shared-material-icon {
+ color: #d3e3fd!important;
+}
+
+.scSharedCalloutinformational>.scSharedCalloutsecondary-button button {
+ color: var(--TWPT-interop-blue)!important;
+}
+
+.scSharedCalloutsuccess {
+ background-color: #37493f!important;
+ border-color: #c4eed0!important;
+}
+
+.scSharedCalloutsuccess sc-shared-material-icon {
+ color: #c4eed0!important;
+}
+
+.scSharedCalloutsuccess>.scSharedCalloutsecondary-button button {
+ color: var(--TWPT-interop-success)!important;
+}
+
+.scSharedMaterialbuttonroot {
+ --m-btn-text-color: var(--TWPT-interop-blue);
+ --m-btn-background-color: transparent;
+ --m-btn-outline-color: var(--TWPT-interop-blue);
+ background: var(--m-btn-background-color)!important;
+ color: var(--m-btn-text-color)!important;
+}
+
+.scSharedMaterialbuttonroot:disabled {
+ color: rgba(227, 227, 227, 0.369)!important;
+}
+
+.scSharedMaterialbuttontext {
+ color: var(--TWPT-interop-blue)!important;
+}
+
+.scSharedMaterialbuttoncolor-label {
+ color: var(--TWPT-interop-secondary-text)!important;
+}
+
+.scSharedMaterialbuttoncolor-hint {
+ color: var(--TWPT-interop-secondary-text)!important;
+}
+
+.scSharedMaterialbuttonnavigational {
+ color: var(--TWPT-interop-primary-text)!important;
+}
+
+.scSharedMaterialbuttonnavigational-alt {
+ color: var(--TWPT-interop-secondary-text)!important;
+}
+
+.scSharedMaterialbuttonhairline, .scSharedMaterialbuttonpill {
+ outline: 1px solid var(--m-btn-outline-color)!important;
+}
+
+.scSharedMaterialbuttonhairline:hover, .scSharedMaterialbuttonhairline:focus, .scSharedMaterialbuttonpill:hover, .scSharedMaterialbuttonpill:focus {
+ --m-btn-outline-color: currentColor!important;
+}
+
+.scSharedMaterialbuttonhairline {
+ --m-btn-outline-color: var(--TWPT-interop-subtle-border)!important;
+}
+
+.scSharedMaterialbuttonhairline:disabled {
+ --m-btn-outline-color: rgba(227, 227, 227, 0.369)!important;
+}
+
+.scSharedMaterialbuttonhairline:active {
+ box-shadow: 0 1px 2px 0 rgba(227, 227, 227, 0.302), 0 1px 3px 1px rgba(227, 227, 227, 0.149)!important;
+}
+
+.scSharedMaterialbuttontonal {
+ color: var(--TWPT-interop-blue)!important;
+ background: #394457!important;
+ outline: 1px solid #474747!important;
+}
+
+.scSharedMaterialbuttontonal:hover {
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.302), 0 1px 3px 1px rgba(0, 0, 0, 0.149)!important;
+}
+
+.scSharedMaterialbuttontonal:active {
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.302), 0 2px 6px 2px rgba(0, 0, 0, 0.149)!important;
+}
+
+.scSharedMaterialbuttontonal:disabled {
+ background: rgba(227, 227, 227, 0.122)!important;
+}
+
+.scSharedMaterialbuttonfilled {
+ background: var(--TWPT-interop-blue)!important;
+ color: #1f1f1f!important;
+}
+
+.scSharedMaterialbuttonfilled:disabled {
+ background: rgba(227, 227, 227, 0.122)!important;
+}
+
+.scSharedMaterialbuttonfilled:hover,
+ .scSharedMaterialbuttonfilled:focus {
+ box-shadow: 0 1px 2px 0 rgba(124, 172, 248, 0.302), 0 1px 3px 1px rgba(124, 172, 248, 0.149)!important;
+}
+
+.scSharedMaterialbuttonfilled:active {
+ box-shadow: 0 1px 3px 0 rgba(124, 172, 248, 0.302), 0 4px 8px 3px rgba(124, 172, 248, 0.149)!important;
+}
+
+.scSharedMaterialbuttonprotected {
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.302), 0 1px 3px 1px rgba(0, 0, 0, 0.149)!important;
+ background: #1f1f1f!important;
+ color: var(--TWPT-interop-blue)!important;
+}
+
+.scSharedMaterialbuttonprotected:disabled {
+ background: rgba(227, 227, 227, 0.122)!important;
+}
+
+.scSharedMaterialbuttonprotected:hover {
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.302), 0 1px 3px 1px rgba(0, 0, 0, 0.149)!important;
+}
+
+.scSharedMaterialbuttonprotected:focus {
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.302), 0 2px 6px 2px rgba(0, 0, 0, 0.149)!important;
+}
+
+.scSharedMaterialbuttonprotected:active {
+ box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.302), 0 4px 8px 3px rgba(0, 0, 0, 0.149)!important;
+}
+
+.scSharedMaterialbuttonsuccess {
+ --m-btn-text-color: var(--TWPT-interop-success)!important;
+ --m-btn-outline-color: var(--TWPT-interop-success)!important;
+}
+
+.scSharedMaterialbuttonsuccess.scSharedMaterialbuttonfilled {
+ --m-btn-text-color: #1f1f1f!important;
+ --m-btn-background-color: var(--TWPT-interop-success)!important;
+}
+
+.scSharedMaterialbuttonsuccess.scSharedMaterialbuttontonal {
+ --m-btn-background-color: #0f5223
+}
+
+@media (forced-colors:active) {
+ .scSharedMaterialbuttonroot:focus {
+ outline: 2px solid #e3e3e3;
+ }
+}
+
+@media (prefers-contrast:more) {
+ .scSharedMaterialbuttonroot:focus {
+ outline: 2px solid #e3e3e3;
+ }
+}
+
+.scSharedExpandabletextexpander {
+ color: var(--TWPT-interop-blue)!important;
+}
+
+.scSharedMaterialborderfilled {
+ background: #313235!important;
+ border-bottom: 1px solid var(--TWPT-interop-secondary-text)!important;
+}
+
+.scSharedMaterialborderfilled-error {
+ border-bottom-color: #ec928e!important;
+}
+
+.scSharedMaterialborderfilled-bottom {
+ background-color: var(--TWPT-interop-blue)!important;
+}
+
+.scSharedMaterialborderfilled-label {
+ color: var(--TWPT-interop-secondary-text)!important;
+}
+
+.scSharedMaterialborderfilled-label-focused {
+ color: var(--TWPT-interop-blue)!important;
+}
+
+.scSharedMaterialborderlabel {
+ color: var(--TWPT-interop-secondary-text)!important;
+}
+
+.scSharedMaterialborderleft {
+ border-bottom-color: var(--TWPT-interop-secondary-text)!important;
+ border-left-color: var(--TWPT-interop-secondary-text)!important;
+ border-top-color: var(--TWPT-interop-secondary-text)!important;
+}
+
+.scSharedMaterialborderleft-error {
+ border-bottom-color: #ec928e!important;
+ border-left-color: #ec928e!important;
+ border-top-color: #ec928e!important;
+}
+
+.scSharedMaterialbordermid {
+ border-bottom-color: var(--TWPT-interop-secondary-text)!important;
+ border-top-color: var(--TWPT-interop-secondary-text)!important;
+}
+
+.scSharedMaterialbordermid-error {
+ border-bottom-color: #ec928e!important;
+ border-top-color: #ec928e!important;
+}
+
+.scSharedMaterialborderright {
+ border-bottom-color: var(--TWPT-interop-secondary-text)!important;
+ border-right-color: var(--TWPT-interop-secondary-text)!important;
+ border-top-color: var(--TWPT-interop-secondary-text)!important;
+}
+
+.scSharedMaterialborderright-error {
+ border-bottom-color: #ec928e!important;
+ border-right-color: #ec928e!important;
+ border-top-color: #ec928e!important;
+}
+
+.scSharedMaterialborderfocused {
+ border-color: var(--TWPT-interop-blue)!important;
+}
+
+.scSharedMaterialborderdisabled {
+ border-color: var(--TWPT-interop-subtle-border)!important;
+}
+
+.scSharedMaterialborderlabel-focused {
+ color: var(--TWPT-interop-blue)!important;
+}
+
+.scSharedMaterialborderlabel-disabled {
+ color: rgba(255, 255, 255, 0.239)!important;
+}
+
+.scSharedMaterialborderlabel-error {
+ color: #ec928e!important;
+}
+
+.scSharedMaterialcardroot {
+ background: #1f1f1f;
+ border: 1px solid var(--TWPT-interop-subtle-border);
+}
+
+.scSharedMaterialcardelevation-1 {
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.302), 0 1px 3px 1px rgba(0, 0, 0, 0.149)!important;
+ background: #2a2b2f!important;
+}
+
+.scSharedMaterialcardelevation-2 {
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.302), 0 2px 6px 2px rgba(0, 0, 0, 0.149)!important;
+ background: #303135!important;
+}
+
+.scSharedMaterialcardelevation-3 {
+ box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.302), 0 4px 8px 3px rgba(0, 0, 0, 0.149)!important;
+ background: #36383a!important;
+}
+
+.scSharedMaterialcardelevation-4 {
+ box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.302), 0 6px 10px 4px rgba(0, 0, 0, 0.149)!important;
+ background: #39393c!important;
+}
+
+.scSharedMaterialcardelevation-5 {
+ box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.302), 0 8px 12px 6px rgba(0, 0, 0, 0.149)!important;
+ background: #3c3e40!important;
+}
+
+@media (forced-colors:active) {
+ .scsharedmaterialcardroot {
+ border-color: #e3e3e3;
+ }
+}
+
+@media (prefers-contrast:more) {
+ .scsharedmaterialcardroot {
+ border-color: #e3e3e3;
+ }
+}
+
+.scSharedMaterialcheckboxcheckbox {
+ color: var(--TWPT-interop-blue)!important;
+}
+
+.scSharedMaterialcheckboxbox {
+ border-color: var(--TWPT-interop-secondary-text)!important;
+}
+
+.scSharedMaterialcheckboxnative-control:checked:disabled+.scSharedMaterialcheckboxbox,
+.scSharedMaterialcheckboxnative-control:indeterminate:disabled+.scSharedMaterialcheckboxbox {
+ background: rgba(0, 0, 0, .26);
+ border-color: transparent;
+}
+
+.scSharedMaterialcheckboxnative-control:disabled+.scSharedMaterialcheckboxbox {
+ border-color: rgba(0, 0, 0, .26);
+}
+
+.scSharedMaterialcheckboxcheckmark-path {
+ stroke: #1f1f1f!important;
+}
+
+.scSharedMaterialcheckboxmixedmark {
+ border-color: #1f1f1f!important;
+}
+
+.scSharedMaterialfabroot {
+ box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.302), 0 4px 8px 3px rgba(0, 0, 0, 0.149);
+ background: #303135;
+ color: var(--TWPT-interop-blue);
+}
+
+@media (forced-colors:active) {
+ .scSharedMaterialfabroot {
+ outline: 3px solid var(--TWPT-interop-blue);
+ }
+}
+
+.scSharedMaterialfabroot.scSharedMaterialfabgrey {
+ color: var(--TWPT-interop-secondary-text);
+}
+
+.scSharedMaterialfabroot:hover,
+.scSharedMaterialfabroot:focus {
+ box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.302), 0 6px 10px 4px rgba(0, 0, 0, 0.149);
+}
+
+.scSharedMaterialfabroot:active {
+ box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.302), 0 8px 12px 6px rgba(0, 0, 0, 0.149);
+}
+
+.scSharedMaterialfablowered {
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.302), 0 1px 3px 1px rgba(0, 0, 0, 0.149);
+}
+
+.scSharedMaterialfablowered.scSharedMaterialfabfake-focus,
+.scSharedMaterialfablowered:hover,
+.scSharedMaterialfablowered:focus {
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.302), 0 2px 6px 2px rgba(0, 0, 0, 0.149);
+}
+
+.scSharedMaterialfablowered:active {
+ box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.302), 0 4px 8px 3px rgba(0, 0, 0, 0.149);
+}
+
+.scSharedMaterialfabfilled {
+ background: rgba(124,172,248,0.239);
+ color: var(--TWPT-interop-blue);
+}
+
+.scSharedMaterialfabfilled.scSharedMaterialfabgrey {
+ background: var(--TWPT-interop-secondary-text);
+ color: #1f1f1f;
+}
+
+.scSharedMaterial_dialogDialogcontentloading-overlay {
+ background: rgba(227, 227, 227, 0.122)!important;
+}
+
+.scSharedMaterialpopupbackground {
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.302), 0 1px 3px 1px rgba(0, 0, 0, 0.149)!important;
+ background: #2a2b2f!important;
+ border: 1px solid var(--TWPT-interop-subtle-border)!important;
+}
+
+@media (forced-colors:active) {
+ .scSharedMaterialpopupbackground {
+ border-color: #e3e3e3;
+ }
+}
+
+@media (prefers-contrast:more) {
+ .scSharedMaterialpopupbackground {
+ border-color: #e3e3e3;
+ }
+}
+
+.scSharedMaterialmenuroot {
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.302), 0 1px 3px 1px rgba(0, 0, 0, 0.149)!important;
+ background: #2a2b2f!important;
+}
+
+.scSharedMaterialmenuitem {
+ color: var(--TWPT-interop-primary-text)!important;
+}
+
+.scSharedMaterialmenuitem[disabled] {
+ color: var(--TWPT-interop-subtle-border);
+}
+
+.scSharedMaterialmenuitem-separator {
+ border-top-color: var(--TWPT-interop-subtle-border)!important;
+}
+
+.scSharedMaterialmenuhighlight:focus,
+ .scSharedMaterialmenuhighlight:hover {
+ background-color: #394457!important;
+}
+
+.scSharedMaterialmenuhighlight:focus {
+ outline: auto var(--TWPT-interop-blue) 1px!important;
+}
+
+.scSharedMaterialtooltipcontainer {
+ background-color: #e3e3e3;
+ color: #1f1f1f;
+}
+
+.scSharedMaterialradioradio {
+ color: var(--TWPT-interop-blue);
+}
+
+.scSharedMaterialradioring {
+ border: 2px solid var(--TWPT-interop-secondary-text);
+}
+
+.scSharedMaterialradionative-control:disabled~.scSharedMaterialradioring {
+ border-color: rgba(0, 0, 0, .26);
+}
+
+.scSharedMaterialradiodot {
+ border-color: var(--TWPT-interop-blue);
+}
+
+.scSharedMaterialradionative-control:disabled~.scSharedMaterialradiodot {
+ background: rgba(0, 0, 0, .26);
+}
+
+.scSharedMaterialrichtooltipcontainer {
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.302), 0 1px 3px 1px rgba(0, 0, 0, 0.149);
+}
+
+.scSharedMaterialrichtooltiproot.scSharedMaterialrichtooltipstyle-normal .scSharedMaterialrichtooltipcontainer {
+ background: #2a2b2f;
+}
+
+.scSharedMaterialrichtooltiproot.scSharedMaterialrichtooltipstyle-accented .scSharedMaterialrichtooltipcontainer {
+ background: var(--TWPT-interop-blue);
+ color: #1f1f1f;
+}
+
+.scSharedMaterialrichtooltipcaret {
+ box-shadow: 1.5px 1.5px 1px -1px rgba(0, 0, 0, 0.2), .75px .75px 1px 0 rgba(0, 0, 0, 0.141), .75px .75px 3px 0 rgba(0, 0, 0, 0.122);
+ background: #2a2b2f;
+}
+
+.scSharedMaterialrichtooltiproot.scSharedMaterialrichtooltipstyle-normal .scSharedMaterialrichtooltipcaret {
+ background: #2a2b2f;
+}
+
+.scSharedMaterialrichtooltiproot.scSharedMaterialrichtooltipstyle-accented .scSharedMaterialrichtooltipcaret {
+ background: var(--TWPT-interop-blue);
+}
+
+.scSharedMaterialselectlabel {
+ color: #e3e3e3;
+}
+
+.scSharedMaterialselectarrow {
+ color: var(--TWPT-interop-secondary-text);
+}
+
+.scSharedMaterialselectactive .scSharedMaterialselectarrow {
+ color: var(--TWPT-interop-blue);
+}
+
+.scSharedMaterialselectdisabled .scSharedMaterialselectselection,
+.scSharedMaterialselectdisabled .scSharedMaterialselectarrow {
+ color: rgba(255, 255, 255, 0.239);
+}
+
+.scSharedMaterialsnackbarsnackbar {
+ background: var(--TWPT-interop-primary-text)!important;
+ color: #1f1f1f!important;
+}
+
+.scSharedMaterialsnackbaraction button {
+ color: #0b57d0!important;
+}
+
+.scSharedMaterialtabbartab {
+ color: var(--TWPT-interop-primary-text)!important;
+}
+
+.scSharedMaterialtabbartab:hover,
+ .scSharedMaterialtabbartab:focus {
+ background-color: #313235!important;
+}
+
+.scSharedMaterialtabbarselected {
+ border-bottom-color: var(--TWPT-interop-blue)!important;
+ color: var(--TWPT-interop-blue)!important;
+}
+
+.scSharedMaterialtextfieldlabel {
+ color: var(--TWPT-interop-primary-text)!important;
+}
+
+.scSharedMaterialtextfieldnative-control {
+ caret-color: var(--TWPT-interop-blue)!important;
+ color: var(--TWPT-interop-primary-text)!important;
+}
+
+.scSharedMaterialtextfieldinvalid .scSharedMaterialtextfieldnative-control {
+ caret-color: #ec928e!important;
+}
+
+.scSharedMaterialtextfieldnative-control:disabled {
+ color: var(--TWPT-interop-secondary-text)!important;
+}
+
+.scSharedMaterialtextfieldfocused .scSharedMaterialtextfieldlabel {
+ color: var(--TWPT-interop-blue)!important;
+}
+
+.scSharedMaterialtextfieldinvalid .scSharedMaterialtextfieldlabel {
+ color: #ec928e!important;
+}
+
+.scSharedMaterialtextfielddisabled .scSharedMaterialtextfieldlabel {
+ color: var(--TWPT-interop-secondary-text)!important;
+}
+
+.scSharedMaterialtextfieldhelper-text {
+ color: var(--TWPT-interop-secondary-text)!important;
+}
+
+.scSharedMaterialtextfieldhelper-text-invalid {
+ color: #ec928e!important;
+}
+
+.scSharedMaterialtextfieldhelper-text-disabled {
+ color: var(--TWPT-interop-secondary-text)!important;
+}
+
+.scTailwindSharedActivitychartroot {
+ border: 1px solid var(--TWPT-interop-subtle-border)!important;
+}
+
+.scTailwindSharedAvatarroot {
+ background-color: #f1f3f4;
+ border: .375rem solid #f1f3f4;
+}
+
+.scTailwindSharedAvatarroot.scTailwindSharedAvatarmedium.scTailwindSharedAvatarat-least-silver,
+.scTailwindSharedAvatarroot.scTailwindSharedAvatarsmall.scTailwindSharedAvatarat-least-silver {
+ border: .125rem solid #f1f3f4;
+}
+
+.scTailwindSharedAvatarsilhouette {
+ background-color: #fff;
+}
+
+.scTailwindSharedAvataravatar-loading {
+ background: #1f1f1f!important;
+}
+
+.scTailwindSharedAvataruploadedit-button {
+ background-color: rgba(0, 0, 0, 0.4);
+ color: #fff;
+}
+
+.scTailwindSharedAvataruploadroot:focus .scTailwindSharedAvataruploadedit-button,
+.scTailwindSharedAvataruploadroot:focus-within .scTailwindSharedAvataruploadedit-button,
+.scTailwindSharedAvataruploadroot:hover .scTailwindSharedAvataruploadedit-button {
+ background-color: rgba(0, 0, 0, 0.54);
+}
+
+.scTailwindSharedDisplay_name_editorDisplaynameeditorlabel {
+ color: var(--TWPT-interop-secondary-text);
+}
+
+.scTailwindSharedPiidialogfinding {
+ color: var(--TWPT-interop-secondary-text);
+}
+
+.scTailwindSharedReportabusedialogcontent .abuse-link {
+ color: var(--TWPT-interop-blue)!important;
+}
+
+.scTailwindSharedRich_text_editorAttachmentFailedoverlayroot {
+ background: rgba(0, 0, 0, 0.902);
+ color: #ec928e;
+}
+
+.scTailwindSharedRich_text_editorAttachmentLoadingoverlayroot {
+ background: rgba(227, 227, 227, 0.369);
+}
+
+.scTailwindSharedRich_text_editorAttachmentRemovebuttonremove-button {
+ background: #1f1f1f;
+ border: 1px solid #27282b;
+ color: var(--TWPT-interop-secondary-text);
+}
+
+.scTailwindSharedRich_text_editorAttachmentRemovebuttonremove-button:hover,
+.scTailwindSharedRich_text_editorAttachmentRemovebuttonremove-button:focus {
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.302), 0 1px 3px 1px rgba(0, 0, 0, 0.149);
+}
+
+.scTailwindSharedRich_text_editorAttachmentNoninlinedattachmentroot {
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.302), 0 1px 3px 1px rgba(0, 0, 0, 0.149);
+ background: #36373a;
+}
+
+.scTailwindSharedRich_text_editorAttachmentNoninlinedattachmentfilename {
+ color: #e3e3e3;
+}
+
+.scTailwindSharedRich_text_editorAttachmentNoninlinedattachmentextension {
+ color: var(--TWPT-interop-secondary-text);
+}
+
+.scTailwindSharedRich_text_editorLinktooltiproot button {
+ color: var(--TWPT-interop-blue);
+}
+
+.scTailwindSharedRichtexteditoreditor {
+ background: #1f1f1f;
+ color: #e3e3e3;
+}
+
+.scTailwindSharedRichtexteditorplaceholder {
+ color: var(--TWPT-interop-secondary-text);
+}
+
+.scTailwindSharedRichtexteditorhas-bottom-panel {
+ border-bottom: 1px solid var(--TWPT-interop-subtle-border);
+}
+
+.scTailwindSharedRichtexteditorhint {
+ color: var(--TWPT-interop-secondary-text);
+}
+
+.scTailwindSharedRich_text_editorToolbarcontrolroot {
+ color: var(--TWPT-interop-secondary-text);
+}
+
+.scTailwindSharedRich_text_editorToolbarcontrolroot:hover {
+ color: #e3e3e3;
+}
+
+.scTailwindSharedRich_text_editorToolbarcontrolroot:focus {
+ border: .125rem solid var(--TWPT-interop-blue);
+}
+
+.scTailwindSharedRich_text_editorToolbarcontrolactive {
+ background: rgba(227, 227, 227, 0.122);
+}
+
+.scTailwindSharedRich_text_editorToolbarMobiletoolbarattachment,
+.scTailwindSharedRich_text_editorToolbarMobiletoolbartext-format {
+ border-right: 1px solid var(--TWPT-interop-subtle-border);
+}
+
+.scTailwindSharedRich_text_editorToolbarMobiletoolbartext-format-button {
+ color: var(--TWPT-interop-secondary-text);
+}
+
+.scTailwindSharedRich_text_editorToolbarMobiletoolbargroup {
+ border-right: 1px solid var(--TWPT-interop-subtle-border);
+}
+
+.scTailwindSharedRich_text_editorToolbargroup:not(:first-child) {
+ border-left: 1px solid var(--TWPT-interop-subtle-border);
+}
+
+.scTailwindSharedTitlefieldhelper-text {
+ color: var(--TWPT-interop-secondary-text);
+}
+
+.sc-select {
+ border: .0625rem solid var(--TWPT-interop-secondary-text);
+ color: #e3e3e3;
+}
+
+.sc-select.keyboard-focus {
+ border-color: transparent;
+ box-shadow: 0 0 0 .125rem #a8c7fa;
+}
+
+.sc-select svg {
+ fill: var(--TWPT-interop-secondary-text);
+}
+
+.sc-select ol {
+ background: #272727;
+ box-shadow: 0 .1875rem .3125rem -.0625rem rgba(0, 0, 0, 0.4), 0 .375rem .625rem 0 rgba(0, 0, 0, 0.28), 0 .0625rem 1.125rem 0 rgba(0, 0, 0, 0.24);
+}
+
+.sc-select .sc-select-highlight {
+ background-color: #5ab3f0;
+ color: #1f1f1f;
+}
+
+.scRecommended_resourcesVideo_carouselVideocardroot {
+ background: #1f1f1f!important;
+ border: 1px solid var(--TWPT-interop-subtle-border)!important;
+}
+
+// The Community Console doesn't support the dark theme, so we need to style the
+// light components as if they were dark.
+.scRecommended_resourcesVideo_carouselVideocardlight:hover,.scRecommended_resourcesVideo_carouselVideocardlight:focus, .scRecommended_resourcesVideo_carouselVideocarddark:hover,.scRecommended_resourcesVideo_carouselVideocarddark:focus {
+ background: linear-gradient(0deg,rgba(168,199,250,.05),rgba(168,199,250,.05)),linear-gradient(0deg,rgba(199,199,199,.02),rgba(199,199,199,.02)),linear-gradient(0deg,#1f1f1f,#1f1f1f)!important;
+ border-color: transparent!important;
+}
+
+.scRecommended_resourcesVideo_carouselVideocardlight:focus, .scRecommended_resourcesVideo_carouselVideocarddark:focus {
+ outline: .125rem #fff solid!important;
+}
+
+.scRecommended_resourcesVideo_carouselVideocardtitle {
+ color: #e3e3e3!important;
+}
+
+.scRecommended_resourcesVideo_carouselVideocardicon {
+ filter: drop-shadow(0 0 24px rgba(0,0,0,.35))!important;
+}
+
+.scRecommended_resourcesVideo_carouselVideocardicon svg {
+ fill: #fff!important;
+}
+
+.scRecommended_resourcesVideo_carouselVideocardduration {
+ background-color: var(--TWPT-interop-secondary-text)!important;
+ color: #1f1f1f!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/vendors/google/_index.scss b/src/features/ccDarkTheme/core/styles/vendors/google/_index.scss
new file mode 100644
index 0000000..0e0a538
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/vendors/google/_index.scss
@@ -0,0 +1,3 @@
+@forward 'common-interop-components';
+@forward 'profile';
+@forward 'thread';
diff --git a/src/features/ccDarkTheme/core/styles/vendors/google/_profile.scss b/src/features/ccDarkTheme/core/styles/vendors/google/_profile.scss
new file mode 100644
index 0000000..4b7ca00
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/vendors/google/_profile.scss
@@ -0,0 +1,162 @@
+/*
+ * IMPORTANT NOTICE:
+ * Note: the following styles have been written by Googlers and thus are not
+ * included as part of the MIT license.
+ **/
+
+.scTailwindUser_profileAchievementsempty a,
+ .scTailwindUser_profileAchievementsempty a:visited,
+ sc-tailwind-user_profile-user-profile .link-icon {
+ color: var(--TWPT-interop-blue)!important;
+}
+
+.scTailwindUser_profileBiosectionsection-heading {
+ color: var(--TWPT-interop-secondary-text)!important;
+}
+
+.scTailwindUser_profileBiosectionbio {
+ color: var(--TWPT-interop-primary-text)!important;
+}
+
+.scTailwindUser_profileBiosectionlinks,
+ .scTailwindUser_profileBiosectionlink {
+ color: var(--TWPT-interop-blue)!important;
+}
+
+.scTailwindUser_profileBiosectioninput-label {
+ color: var(--TWPT-interop-secondary-text)!important;
+}
+
+.scTailwindUser_profileEmaildisplayemail-display {
+ color: var(--TWPT-interop-secondary-text)!important;
+}
+
+.scTailwindUser_profileEmaildisplayshow-email {
+ color: var(--TWPT-interop-blue)!important;
+}
+
+.scTailwindUser_profileMessagecardthread-link {
+ color: var(--TWPT-interop-secondary-text)!important;
+}
+
+.scTailwindUser_profileMessagecardlabel {
+ color: var(--TWPT-interop-secondary-text)!important;
+}
+
+.scTailwindUser_profileMessagecardcontent {
+ border-left: 2px solid var(--TWPT-interop-subtle-border)!important;
+ color: var(--TWPT-interop-primary-text)!important;
+}
+
+.scTailwindUser_profileMessagecardcount {
+ color: var(--TWPT-interop-secondary-text)!important;
+}
+
+.scTailwindUser_profileMessagecardrecommended-answer {
+ color: #6dd58c!important;
+}
+
+.scTailwindUser_profileMessagecardrecommended-answer .icon {
+ background-color: #6dd58c!important;
+ color: #1f1f1f!important;
+}
+
+sc-tailwind-user_profile-user-profile .notificationIcon {
+ color: var(--TWPT-interop-secondary-text)!important;
+}
+
+sc-tailwind-user_profile-user-profile .deleteIcon,
+ sc-tailwind-user_profile-user-profile .reportAbuseIcon,
+ sc-tailwind-user_profile-user-profile .reactivateIcon {
+ color: var(--TWPT-interop-secondary-text)!important;
+}
+
+.scTailwindUser_profilePosthistorysection+.scTailwindUser_profilePosthistorysection {
+ border-top-color: var(--TWPT-interop-subtle-border)!important;
+}
+
+.scTailwindUser_profilePosthistorycontent,
+ .scTailwindUser_profilePosthistoryheader,
+ .scTailwindUser_profilePosthistoryerror {
+ border-color: var(--TWPT-interop-subtle-border)!important;
+}
+
+.scTailwindUser_profileThreadcardtitle {
+ color: var(--TWPT-interop-primary-text)!important;
+}
+
+.scTailwindUser_profileThreadcardlabel {
+ color: var(--TWPT-interop-secondary-text)!important;
+}
+
+.scTailwindUser_profileThreadcardcontent {
+ color: var(--TWPT-interop-primary-text)!important;
+}
+
+.scTailwindUser_profileThreadcardcount {
+ color: var(--TWPT-interop-secondary-text)!important;
+}
+
+.scTailwindUser_profileThreadcardreply .icon {
+ color: var(--TWPT-interop-secondary-text)!important;
+}
+
+.scTailwindUser_profileThreadcardrecommended-answer {
+ color: #6dd58c!important;
+}
+
+.scTailwindUser_profileThreadcardrecommended-answer .icon {
+ background-color: #6dd58c!important;
+ color: #1f1f1f!important;
+}
+
+.scTailwindUserprofileUgcsectionroot {
+ border: 1px solid var(--TWPT-interop-subtle-border);
+}
+
+.scTailwindUserprofileUgcsectioncard-ugc-guide {
+ background-color: #1e1f20;
+}
+
+.scTailwindUserprofileUgcsectionthread-title {
+ color: #e3e3e3;
+}
+
+.scTailwindUserprofileUgcsectiondraft-tag {
+ background-color: #0f5223;
+ color: #6dd58c;
+}
+
+.scTailwindUserprofileUgcsectionthread-body {
+ color: #e3e3e3;
+}
+
+.scTailwindUser_profileUsercardroot {
+ border: 1px solid var(--TWPT-interop-subtle-border)!important;
+}
+
+.scTailwindUser_profileUsercardinput-label {
+ color: var(--TWPT-interop-secondary-text)!important;
+}
+
+.scTailwindUser_profileUsercardheadline {
+ color: var(--TWPT-interop-primary-text)!important;
+}
+
+.scTailwindUser_profileUsercarddetails {
+ color: var(--TWPT-interop-secondary-text)!important;
+}
+
+.scTailwindUser_profileUsercardlinks,
+ .scTailwindUser_profileUsercardlink {
+ color: var(--TWPT-interop-blue)!important;
+}
+
+.scTailwindUser_profileUsercardhorizontal-separator {
+ background-color: var(--TWPT-interop-subtle-border)!important;
+ color: var(--TWPT-interop-subtle-border)!important;
+}
+
+.scTailwindUser_profileUsercardsection-heading {
+ color: var(--TWPT-interop-secondary-text)!important;
+}
diff --git a/src/features/ccDarkTheme/core/styles/vendors/google/_thread.scss b/src/features/ccDarkTheme/core/styles/vendors/google/_thread.scss
new file mode 100644
index 0000000..86b370b
--- /dev/null
+++ b/src/features/ccDarkTheme/core/styles/vendors/google/_thread.scss
@@ -0,0 +1,307 @@
+/*
+ * IMPORTANT NOTICE:
+ * Note: the following styles have been written by Googlers and thus are not
+ * included as part of the MIT license.
+ **/
+
+.scTailwindThreadEditquestiondialogroot.scTailwindThreadEditquestiondialogscrollable {
+ -webkit-box-shadow: inset 0 -11px 5px -11px #000;
+ box-shadow: inset 0 -11px 5px -11px #000;
+}
+
+.scTailwindThreadEditquestiondialogerror {
+ color: #ec928e;
+}
+
+.scTailwindThreadGetlinkdialoglink-container {
+ border-bottom: 2px solid #a8c7fa;
+}
+
+.scTailwindThreadMessageHelpfulnessbuttonslabel {
+ color: #e3e3e3;
+}
+
+.scTailwindThreadMessageMessagecardsub-content {
+ background: #3c4043;
+ border-top: 1px solid var(--TWPT-interop-subtle-border);
+}
+
+.scTailwindThreadMessageMessagecardnested-reply:not(:first-child) {
+ border-top: 1px solid var(--TWPT-interop-subtle-border);
+}
+
+.scTailwindThreadMessageMessagecardtargeted {
+ border-left: .125rem solid var(--TWPT-interop-blue);
+}
+
+.scTailwindThreadMessageMessagecardcallouthelp-icon {
+ color: #c4c7c5;
+}
+
+.scTailwindThreadMessageMessagecardcalloutroot.scTailwindThreadMessageMessagecardcalloutrecommended {
+ background: #0f5223;
+ border-color: #6dd58c;
+}
+
+.scTailwindThreadMessageMessagecardcalloutroot.scTailwindThreadMessageMessagecardcalloutrelevant {
+ background: #394457;
+ border-color: var(--TWPT-interop-blue);
+}
+
+.scTailwindThreadMessageMessagetagrecommended.scTailwindThreadMessageMessagetagnormal {
+ color: #6dd58c;
+}
+
+.scTailwindThreadMessageMessagetagrecommended.scTailwindThreadMessageMessagetagstrong {
+ color: #6dd58c;
+}
+
+.scTailwindThreadMessageMessagetagrelevant.scTailwindThreadMessageMessagetagnormal {
+ color: var(--TWPT-interop-blue);
+}
+
+.scTailwindThreadMessageMessagetagrelevant.scTailwindThreadMessageMessagetagstrong {
+ color: var(--TWPT-interop-blue);
+}
+
+.scTailwindThreadMessageMessageinteractionsinteraction {
+ color: var(--TWPT-interop-secondary-text);
+}
+
+p.scTailwindThreadMessageMessagetombstoneroot {
+ color: var(--TWPT-interop-secondary-text);
+}
+
+p.scTailwindThreadMessageMessagetombstoneroot .scTailwindThreadMessageMessagetombstoneclickable {
+ color: var(--TWPT-interop-secondary-text);
+}
+
+.scTailwindThreadPostcontentroot {
+ color: #e3e3e3;
+}
+
+.scTailwindThreadPostcontentroot a {
+ color: var(--TWPT-interop-blue);
+}
+
+.scTailwindThreadPostcontentedited {
+ color: var(--TWPT-interop-secondary-text);
+}
+
+.scTailwindThreadPost_headerOverflowmenuicon {
+ color: var(--TWPT-interop-secondary-text);
+}
+
+.scTailwindThreadPost_headerPostdateroot {
+ color: var(--TWPT-interop-secondary-text);
+}
+
+.scTailwindThreadPostheaderunread {
+ color: #ec928e;
+}
+
+a .scTailwindThreadPost_headerUserinfoname {
+ color: var(--TWPT-interop-blue);
+}
+
+.scTailwindThreadPost_headerUserinfotag {
+ color: var(--color, #e3e3e3);
+}
+
+.scTailwindThreadPost_headerUserinfoheadline {
+ color: var(--TWPT-interop-secondary-text);
+}
+
+.scTailwindThreadReplyeditorroot {
+ background: #2a2b2f;
+ border-color: var(--TWPT-interop-subtle-border);
+}
+
+.scTailwindThreadReplyeditortop-row {
+ border-bottom-color: 1px solid rgba(255, 255, 255, 0.239);
+}
+
+.scTailwindThreadReplyeditorfooter {
+ background: #36373a;
+ border-top-color: rgba(255, 255, 255, 0.239);
+}
+
+.scTailwindThreadReplyeditorfooter a {
+ color: var(--TWPT-interop-blue);
+}
+
+.scTailwindThreadReplyeditorroot .scTailwindThreadReplyeditorerror {
+ color: #ec928e;
+}
+
+.scTailwindThreadReplydialogroot {
+ background: #2a2b2f;
+}
+
+.scTailwindThreadReplydialogheader {
+ background: var(--TWPT-interop-blue);
+}
+
+.scTailwindThreadReplydialogheader h1.scTailwindThreadReplydialogheading {
+ color: #1f1f1f;
+}
+
+.scTailwindThreadReplydialogheading-button {
+ color: #1f1f1f;
+}
+
+.scTailwindThreadReplydialogtop-row {
+ border-bottom: 1px solid var(--TWPT-interop-subtle-border);
+}
+
+.scTailwindThreadReplydialogfooter {
+ background: #36373a;
+}
+
+.scTailwindThreadReplydialogfooter a {
+ color: var(--TWPT-interop-blue);
+}
+
+.scTailwindThreadReplydialogminimized .scTailwindThreadReplydialogheader {
+ background: #e3e3e3;
+ color: #1f1f1f;
+}
+
+.scTailwindThreadReplydialogroot .scTailwindThreadReplydialogerror {
+ color: #ec928e;
+}
+
+@media (min-width:48.125rem) {
+ .scTailwindThreadReplydialogroot {
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.302), 0 2px 6px 2px rgba(0, 0, 0, 0.149);
+ }
+}
+
+.scTailwindThreadMessageMessagelisthelp-icon {
+ color: var(--TWPT-interop-secondary-text);
+}
+
+.scTailwindThreadMessageMessagelistrecommended-icon {
+ color: #c4eed0;
+}
+
+.scTailwindThreadMessageMessagelistrelevant-icon {
+ color: var(--TWPT-interop-blue);
+}
+
+.scTailwindThreadMorebuttondivider {
+ background: var(--TWPT-interop-subtle-border);
+}
+
+.scTailwindThreadMorebuttonbutton {
+ background: #1f1f1f;
+ border: 1px solid var(--TWPT-interop-subtle-border);
+ color: var(--TWPT-interop-secondary-text);
+}
+
+.scTailwindThreadMessagegapdivider {
+ background: var(--TWPT-interop-subtle-border);
+}
+
+.scTailwindThreadMessagegapbutton {
+ background: #1f1f1f;
+ border: 1px solid var(--TWPT-interop-subtle-border);
+ color: var(--TWPT-interop-secondary-text);
+}
+
+.scTailwindThreadMessagegapmore-nested-replies {
+ background: #3c4043;
+}
+
+.scTailwindThreadMessagegapmore-nested-replies-divider {
+ background: #27282b;
+}
+
+.scTailwindThreadPesignupdialogclose-button-row button {
+ color: #fff;
+}
+
+.scTailwindThreadPesignupdialogdialog-body p {
+ color: #e3e3e3;
+}
+
+.scTailwindThreadPesignupdialogpe-dialog-container {
+ background-color: #1f1f1f;
+ -webkit-box-shadow: 0 .063rem .188rem rgba(60, 64, 67, 0.3), 0 .25rem .5rem rgba(60, 64, 67, 0.15);
+ box-shadow: 0 .063rem .188rem rgba(60, 64, 67, 0.3), 0 .25rem .5rem rgba(60, 64, 67, 0.15);
+}
+
+.scTailwindThreadPostconfirmationdialogclose-button-row button {
+ color: #e3e3e3;
+}
+
+.scTailwindThreadPostconfirmationdialogdialog-body p {
+ color: #e3e3e3;
+}
+
+.scTailwindThreadPostconfirmationdialogdialog-container {
+ background-color: #1f1f1f;
+ -webkit-box-shadow: 0 .063rem .188rem rgba(60, 64, 67, 0.3), 0 .25rem .5rem rgba(60, 64, 67, 0.15);
+ box-shadow: 0 .063rem .188rem rgba(60, 64, 67, 0.3), 0 .25rem .5rem rgba(60, 64, 67, 0.15);
+}
+
+.scTailwindThreadQuestionQuestioncardsub-content {
+ background: #3c4043;
+ border-top: 1px solid var(--TWPT-interop-subtle-border);
+}
+
+.scTailwindThreadQuestionQuestioncardtitle {
+ color: #e3e3e3;
+}
+
+.scTailwindThreadQuestionQuestioncardbody {
+ color: #e3e3e3;
+}
+
+.scTailwindThreadQuestionQuestioncardbody a {
+ color: var(--TWPT-interop-blue);
+}
+
+.scTailwindThreadQuestionQuestioncarddisclaimer,
+.scTailwindThreadQuestionQuestioncardedited {
+ color: var(--TWPT-interop-secondary-text);
+}
+
+.scTailwindThreadQuestionQuestioncarddisclaimer a,
+.scTailwindThreadQuestionQuestioncardedited a {
+ color: var(--TWPT-interop-blue);
+}
+
+.scTailwindThreadQuestionQuestiondetailsdetail-link {
+ color: var(--TWPT-interop-blue);
+}
+
+.scTailwindThreadQuestionQuestionpurposetag {
+ background: #394457;
+ color: var(--TWPT-interop-blue);
+}
+
+.scTailwindThreadQuestionStatechipschip {
+ border: 1px solid var(--TWPT-interop-subtle-border);
+ color: var(--TWPT-interop-secondary-text);
+}
+
+.scTailwindThreadQuestionThreadcountsrecommended-answers {
+ color: #6dd58c!important;
+}
+
+.scTailwindThreadQuestionThreadcountssuggested-answers {
+ color: var(--TWPT-interop-blue)!important;
+}
+
+.scTailwindThreadQuestionThreadcountssuggested-icon {
+ background: #394457!important;
+}
+
+.scTailwindThreadQuestionUgcvideodetailsyoutube-label {
+ color: #c4c7c5!important;
+}
+
+.scTailwindThreadThreaddeleted-icon {
+ color: var(--TWPT-interop-secondary-text);
+}
diff --git a/src/features/ccDarkTheme/nodeWatcherHandlers/ecApp.handler.ts b/src/features/ccDarkTheme/nodeWatcherHandlers/ecApp.handler.ts
new file mode 100644
index 0000000..12d50bb
--- /dev/null
+++ b/src/features/ccDarkTheme/nodeWatcherHandlers/ecApp.handler.ts
@@ -0,0 +1,26 @@
+import CssSelectorNodeWatcherScriptHandler from '../../../common/architecture/scripts/nodeWatcher/handlers/CssSelectorNodeWatcherScriptHandler';
+import { NodeMutation } from '../../../common/nodeWatcher/NodeWatcherHandler';
+import { injectDarkThemeButton } from '../core/logic/darkTheme';
+import { CCDarkThemeNodeWatcherDependencies } from '../scripts/nodeWatcher.script';
+
+/**
+ * Injects the dark theme button.
+ */
+export default class CCDarkThemeEcAppHandler extends CssSelectorNodeWatcherScriptHandler<CCDarkThemeNodeWatcherDependencies> {
+ cssSelector = 'ec-app';
+
+ async onMutatedNode(mutation: NodeMutation) {
+ if (!(mutation.node instanceof Element)) return;
+
+ const optionsProvider = this.options.optionsProvider;
+ const isEnabled = await optionsProvider.isEnabled('ccdarktheme');
+ const mode = await optionsProvider.getOptionValue('ccdarktheme_mode');
+
+ // TODO(avm99963): make this feature dynamic.
+ if (isEnabled && mode === 'switch') {
+ const rightControl = mutation.node.querySelector('header .right-control');
+ if (rightControl === null) return;
+ injectDarkThemeButton(rightControl);
+ }
+ }
+}
diff --git a/src/features/ccDarkTheme/nodeWatcherHandlers/reportDialog.handler.ts b/src/features/ccDarkTheme/nodeWatcherHandlers/reportDialog.handler.ts
new file mode 100644
index 0000000..83942e5
--- /dev/null
+++ b/src/features/ccDarkTheme/nodeWatcherHandlers/reportDialog.handler.ts
@@ -0,0 +1,17 @@
+import CssSelectorNodeWatcherScriptHandler from '../../../common/architecture/scripts/nodeWatcher/handlers/CssSelectorNodeWatcherScriptHandler';
+import { NodeMutation } from '../../../common/nodeWatcher/NodeWatcherHandler';
+import { CCDarkThemeNodeWatcherDependencies } from '../scripts/nodeWatcher.script';
+
+/**
+ * Sets the report dialog iframe's theme to the appropriate theme.
+ */
+export default class CCDarkThemeReportDialogHandler extends CssSelectorNodeWatcherScriptHandler<CCDarkThemeNodeWatcherDependencies> {
+ cssSelector = 'iframe';
+
+ onMutatedNode(mutation: NodeMutation) {
+ this.options.reportDialogColorThemeFix.fixThemeIfReportDialogIframeAndApplicable(
+ mutation.node,
+ this.options.optionsProvider,
+ );
+ }
+}
diff --git a/src/features/ccDarkTheme/nodeWatcherHandlers/unifiedProfilesIframe.handler.ts b/src/features/ccDarkTheme/nodeWatcherHandlers/unifiedProfilesIframe.handler.ts
new file mode 100644
index 0000000..b71b9a7
--- /dev/null
+++ b/src/features/ccDarkTheme/nodeWatcherHandlers/unifiedProfilesIframe.handler.ts
@@ -0,0 +1,23 @@
+import CssSelectorNodeWatcherScriptHandler from '../../../common/architecture/scripts/nodeWatcher/handlers/CssSelectorNodeWatcherScriptHandler';
+import { NodeMutation } from '../../../common/nodeWatcher/NodeWatcherHandler';
+import { isDarkThemeOn } from '../core/logic/darkTheme';
+import { unifiedProfilesFix } from '../core/logic/unifiedProfiles';
+import { CCDarkThemeNodeWatcherDependencies } from '../scripts/nodeWatcher.script';
+
+/**
+ * Redirect unified profile iframe to dark version if applicable
+ */
+export default class CCDarkThemeUnifiedProfilesIframeHandler extends CssSelectorNodeWatcherScriptHandler<CCDarkThemeNodeWatcherDependencies> {
+ cssSelector = 'iframe';
+
+ async onMutatedNode(mutation: NodeMutation) {
+ const optionsValues = await this.options.optionsProvider.getOptionsValues();
+
+ if (
+ isDarkThemeOn(optionsValues) &&
+ unifiedProfilesFix.checkIframe(mutation.node)
+ ) {
+ unifiedProfilesFix.fixIframe(mutation.node);
+ }
+ }
+}
diff --git a/src/features/ccDarkTheme/scripts/injectAutoDarkTheme.script.ts b/src/features/ccDarkTheme/scripts/injectAutoDarkTheme.script.ts
new file mode 100644
index 0000000..c462a03
--- /dev/null
+++ b/src/features/ccDarkTheme/scripts/injectAutoDarkTheme.script.ts
@@ -0,0 +1,17 @@
+import { ScriptPage } from '../../../common/architecture/scripts/Script';
+import StylesheetScript from '../../../common/architecture/scripts/stylesheet/StylesheetScript';
+
+export default class InjectAutoDarkTheme extends StylesheetScript {
+ stylesheet = 'ccDarkTheme.bundle.css';
+ attributes = { media: '(prefers-color-scheme: dark)' };
+ page = ScriptPage.CommunityConsole;
+
+ async shouldBeInjected(): Promise<boolean> {
+ const ccDarkThemeEnabled =
+ await this.optionsProvider.isEnabled('ccdarktheme');
+ const ccDarkThemeMode =
+ await this.optionsProvider.getOptionValue('ccdarktheme_mode');
+
+ return ccDarkThemeEnabled && ccDarkThemeMode === 'system';
+ }
+}
diff --git a/src/features/ccDarkTheme/scripts/injectForcedDarkTheme.script.ts b/src/features/ccDarkTheme/scripts/injectForcedDarkTheme.script.ts
new file mode 100644
index 0000000..ebd221b
--- /dev/null
+++ b/src/features/ccDarkTheme/scripts/injectForcedDarkTheme.script.ts
@@ -0,0 +1,23 @@
+import { ScriptPage } from '../../../common/architecture/scripts/Script';
+import StylesheetScript from '../../../common/architecture/scripts/stylesheet/StylesheetScript';
+
+export default class InjectForcedDarkTheme extends StylesheetScript {
+ stylesheet = 'ccDarkTheme.bundle.css';
+ page = ScriptPage.CommunityConsole;
+
+ async shouldBeInjected(): Promise<boolean> {
+ const ccDarkThemeEnabled =
+ await this.optionsProvider.isEnabled('ccdarktheme');
+ const ccDarkThemeMode =
+ await this.optionsProvider.getOptionValue('ccdarktheme_mode');
+ const ccDarkThemeSwitchEnabled = await this.optionsProvider.isEnabled(
+ 'ccdarktheme_switch_status',
+ );
+
+ return (
+ ccDarkThemeEnabled &&
+ ccDarkThemeMode === 'switch' &&
+ ccDarkThemeSwitchEnabled
+ );
+ }
+}
diff --git a/src/features/ccDarkTheme/scripts/nodeWatcher.script.ts b/src/features/ccDarkTheme/scripts/nodeWatcher.script.ts
new file mode 100644
index 0000000..7a78798
--- /dev/null
+++ b/src/features/ccDarkTheme/scripts/nodeWatcher.script.ts
@@ -0,0 +1,46 @@
+import DependenciesProviderSingleton, {
+ OptionsProviderDependency,
+ ReportDialogColorThemeFixDependency,
+} from '../../../common/architecture/dependenciesProvider/DependenciesProvider';
+import {
+ ScriptEnvironment,
+ ScriptPage,
+ ScriptRunPhase,
+} from '../../../common/architecture/scripts/Script';
+import NodeWatcherScript from '../../../common/architecture/scripts/nodeWatcher/NodeWatcherScript';
+import OptionsProvider from '../../../common/options/OptionsProvider';
+import ReportDialogColorThemeFix from '../core/logic/reportDialog';
+import CCDarkThemeEcAppHandler from '../nodeWatcherHandlers/ecApp.handler';
+import CCDarkThemeReportDialogHandler from '../nodeWatcherHandlers/reportDialog.handler';
+import CCDarkThemeUnifiedProfilesIframeHandler from '../nodeWatcherHandlers/unifiedProfilesIframe.handler';
+
+export interface CCDarkThemeNodeWatcherDependencies {
+ reportDialogColorThemeFix: ReportDialogColorThemeFix;
+ optionsProvider: OptionsProvider;
+}
+
+export default class CCDarkThemeNodeWatcherScript extends NodeWatcherScript<CCDarkThemeNodeWatcherDependencies> {
+ public page = ScriptPage.CommunityConsole;
+ public environment = ScriptEnvironment.ContentScript;
+ public runPhase = ScriptRunPhase.Main;
+ public handlers = new Map([
+ ['cc-dark-theme-ec-app', CCDarkThemeEcAppHandler],
+ ['cc-dark-theme-report-dialog', CCDarkThemeReportDialogHandler],
+ [
+ 'cc-dark-theme-unified-profiles-iframe',
+ CCDarkThemeUnifiedProfilesIframeHandler,
+ ],
+ ]);
+
+ protected optionsFactory(): CCDarkThemeNodeWatcherDependencies {
+ const dependenciesProvider = DependenciesProviderSingleton.getInstance();
+ return {
+ reportDialogColorThemeFix: dependenciesProvider.getDependency(
+ ReportDialogColorThemeFixDependency,
+ ),
+ optionsProvider: dependenciesProvider.getDependency(
+ OptionsProviderDependency,
+ ),
+ };
+ }
+}