From 1ddc84b68a654469a442af2b3c39204ebd4a67fd Mon Sep 17 00:00:00 2001 From: nfloser <102595695+nfloser@users.noreply.github.com> Date: Sat, 10 Oct 2026 22:07:12 +0200 Subject: [PATCH 1/5] Add system-aware medical blue dark mode --- docs/development/DEMO_ABNAHME.de.md | 10 ++++++ frontend/e2e/clinical-workspace.spec.mjs | 2 +- frontend/e2e/theme.spec.mjs | 35 ++++++++++++++++++ frontend/src/ThemeControl.tsx | 14 ++++++++ frontend/src/WorkspaceMenu.tsx | 3 +- frontend/src/de.json | 7 ++++ frontend/src/style.css | 45 ++++++++++++++++++++++++ frontend/tests/contrast.test.mjs | 11 ++++++ 8 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 frontend/e2e/theme.spec.mjs create mode 100644 frontend/src/ThemeControl.tsx diff --git a/docs/development/DEMO_ABNAHME.de.md b/docs/development/DEMO_ABNAHME.de.md index c0ec7db..49fbd02 100644 --- a/docs/development/DEMO_ABNAHME.de.md +++ b/docs/development/DEMO_ABNAHME.de.md @@ -99,3 +99,13 @@ zu prüfen; Konfliktverhalten bleibt durch die vorhandenen API-Tests abgedeckt. Fallbezeichnungen verwenden in jeder Tabellenzeile einen gleich breiten Lesezeichenplatz. Das Setzen oder Entfernen des Sterns verschiebt weder den Textanfang noch die Spalten; optionale Notizen beginnen auf derselben Textkante. + +### Helle und dunkle Darstellung + +„Farbschema“ rechts im Menüband bietet System, Hell und Dunkel. System reagiert +auf die Betriebssystemeinstellung; eine explizite Auswahl hat Vorrang. Die Auswahl +bleibt beim Wechsel des Arbeitsbereichs in dieser Sitzung erhalten. Sie wird +nicht in localStorage, sessionStorage oder Cookies gespeichert; dauerhafte +benutzergebundene Ansichten bleiben Aufgabe #281. PDF-/Scanseiten behalten ihre +Originalfarben. Die umgebende Dokumentenansicht, Tabellen, Fallakten, Kontextmenüs, +Dialoge und Extras verwenden die dunklen medizinisch-blauen Farben. diff --git a/frontend/e2e/clinical-workspace.spec.mjs b/frontend/e2e/clinical-workspace.spec.mjs index 9d72407..c3daefb 100644 --- a/frontend/e2e/clinical-workspace.spec.mjs +++ b/frontend/e2e/clinical-workspace.spec.mjs @@ -37,7 +37,7 @@ for(const viewport of [{width:1920,height:1080},{width:1366,height:768}]){ await expect(explorer.locator('.page-stage')).toHaveAttribute('data-zoom-mode','width'); await expect(explorer.locator('.viewer-page')).toHaveCount(2); await expect(explorer.getByLabel('Seitenzahl')).toHaveValue('2'); - const image=await explorer.locator('.pdf-page-image').first().boundingBox();expect(image.width).toBeGreaterThan(600); + await expect.poll(async()=> (await explorer.locator('.pdf-page-image').first().boundingBox())?.width??0).toBeGreaterThan(600); await expect(explorer.getByLabel('Dokument auswählen')).toHaveCount(0); await page.screenshot({path:`test-results/clinical-documents-${viewport.width}.png`}); await explorer.getByLabel('Zoommodus').selectOption('150'); diff --git a/frontend/e2e/theme.spec.mjs b/frontend/e2e/theme.spec.mjs new file mode 100644 index 0000000..4e2c3a8 --- /dev/null +++ b/frontend/e2e/theme.spec.mjs @@ -0,0 +1,35 @@ +import {test,expect} from '@playwright/test'; +test('theme follows the system until explicitly changed and survives workspace navigation',async({page})=>{ + await page.emulateMedia({colorScheme:'dark'});await page.goto('/#work-queues'); + const scheme=page.getByLabel('Farbschema');await expect(scheme).toHaveValue('system'); + await expect(page.locator('html')).toHaveAttribute('data-theme','dark'); + await scheme.selectOption('light');await page.emulateMedia({colorScheme:'dark'}); + await expect(page.locator('html')).toHaveAttribute('data-theme','light'); + await scheme.selectOption('system');await expect(page.locator('html')).toHaveAttribute('data-theme','dark'); + await page.emulateMedia({colorScheme:'light'});await expect(page.locator('html')).toHaveAttribute('data-theme','light'); + await scheme.selectOption('dark');await page.getByRole('navigation',{name:'Arbeitsbereiche'}).getByText('Extras',{exact:true}).click();await page.locator('.workspace-extras-list a[href="#workbench"]').click(); + await expect(scheme).toHaveValue('dark');await expect(page.locator('html')).toHaveAttribute('data-theme','dark'); + expect(await page.evaluate(()=>[localStorage.length,sessionStorage.length])).toEqual([0,0]); + await page.screenshot({path:'test-results/dark-workbench.png'}); +}); +for(const width of [1366,1920])test(`dark case file, sources and dialogs remain readable at ${width}`,async({page})=>{ + await page.setViewportSize({width,height:1080});await page.goto('/#work-queues'); + await page.getByLabel('Farbschema').selectOption('dark'); + const explorer=page.getByRole('region',{name:'Fallverwaltung'}); + await expect(explorer.locator('.explorer-tree')).toHaveCSS('background-color','rgb(15, 27, 40)'); + await page.getByLabel('Fälle suchen').fill('reference-care-complete'); + await explorer.locator('tbody tr').dblclick(); + await expect(explorer.getByRole('heading',{name:'Prüfergebnis: Voraussetzungen erfüllt',exact:true})).toBeVisible(); + await page.screenshot({path:`test-results/dark-case-${width}.png`}); + await explorer.getByRole('button',{name:'Dokumente',exact:true}).click(); + await expect(explorer.locator('.pdf-page-image').first()).toHaveCSS('filter','none'); + await page.screenshot({path:`test-results/dark-documents-${width}.png`}); + await explorer.getByRole('button',{name:'Neuer Ordner',exact:true}).click(); + await expect(page.getByRole('dialog')).toHaveCSS('background-color','rgb(23, 38, 53)'); + await page.screenshot({path:`test-results/dark-dialog-${width}.png`}); + await page.getByRole('dialog').getByRole('button',{name:'Abbrechen'}).click(); + await explorer.getByRole('button',{name:'← Liste',exact:true}).click(); + await explorer.locator('tbody tr').click({button:'right'}); + await expect(page.getByRole('menu',{name:'Fallaktionen'})).toHaveCSS('background-color','rgb(23, 38, 53)'); + await page.screenshot({path:`test-results/dark-context-${width}.png`}); +}); diff --git a/frontend/src/ThemeControl.tsx b/frontend/src/ThemeControl.tsx new file mode 100644 index 0000000..66ec1ca --- /dev/null +++ b/frontend/src/ThemeControl.tsx @@ -0,0 +1,14 @@ +import {useEffect,useState} from 'react'; +import de from './de.json'; +type Mode='system'|'light'|'dark'; +/** Session-only display preference: no case data or browser persistence. */ +export function ThemeControl(){ + const [mode,setMode]=useState('system'); + useEffect(()=>{ + const media=window.matchMedia('(prefers-color-scheme: dark)'); + const apply=()=>{document.documentElement.dataset.theme=mode==='system'?(media.matches?'dark':'light'):mode;}; + apply();media.addEventListener('change',apply); + return()=>media.removeEventListener('change',apply); + },[mode]); + return ; +} diff --git a/frontend/src/WorkspaceMenu.tsx b/frontend/src/WorkspaceMenu.tsx index 6653ef0..0b4edda 100644 --- a/frontend/src/WorkspaceMenu.tsx +++ b/frontend/src/WorkspaceMenu.tsx @@ -1,5 +1,6 @@ import {useEffect,useState} from 'react'; import de from './de.json'; +import {ThemeControl} from './ThemeControl'; const ui=de.clinicalWorkspace; export function workspaceAction(action:string){window.dispatchEvent(new CustomEvent('normacase-workspace-action',{detail:action}));} export function WorkspaceMenu({view}:{view:string}){ @@ -12,5 +13,5 @@ export function WorkspaceMenu({view}:{view:string}){ [ui.view,[['detail',ui.detail],['orientation',ui.orientation],['navigation',ui.navigation],['density',ui.density],['columns',ui.columns],['reset',ui.reset],['refresh',ui.refresh]]], [ui.cases,[['folder',ui.newFolder],['move',ui.move],['bookmark',ui.bookmark],['confirm',ui.confirm],['dispatch',ui.dispatch]]], ] as const; - return ; + return ; } diff --git a/frontend/src/de.json b/frontend/src/de.json index 61c591e..fc76adf 100644 --- a/frontend/src/de.json +++ b/frontend/src/de.json @@ -648,5 +648,12 @@ "dispatchHelp": "Erstellt und lädt ein lokales Versandpaket herunter. Anschließend erscheint der Fall in „Versand simuliert“. Es wird nichts extern übermittelt.", "confirmedNext": "Versandpaket erstellen", "completeNext": "Lokales Versandpaket erstellt" + }, + "theme": { + "label": "Farbschema", + "system": "System", + "light": "Hell", + "dark": "Dunkel", + "help": "Farbschema für diese Sitzung. System folgt der Darstellungseinstellung des Betriebssystems." } } diff --git a/frontend/src/style.css b/frontend/src/style.css index d1159df..a6282e1 100644 --- a/frontend/src/style.css +++ b/frontend/src/style.css @@ -531,3 +531,48 @@ h2,h3,h4,h5{font-size:14px;font-weight:600}strong{font-weight:600}main p{line-he .case-bookmark-slot{display:inline-flex;align-items:center;justify-content:center;width:16px;min-width:16px;flex:0 0 16px} .case-label{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} .case-explorer .explorer-table td .case-note{padding-left:20px} + +/* Medical blue themes share geometry and leave document pixels unchanged. */ +:root{color-scheme:light} +:root[data-theme=dark]{ + color-scheme:dark; + --nc-primary:#b5d9ff;--nc-action:#81baff;--nc-light:#20384f;--nc-background:#0f1b28;--nc-surface:#172635;--nc-line:#3c5268;--nc-button-border:#61778f;--nc-text:#e1ebf5;--nc-muted:#acbbcc;--nc-selected:#284d70;--nc-viewer:#0a1520; + --nc-shadow:0 4px 12px rgba(0,0,0,.45); +} +.theme-control{display:flex;align-items:center;flex-shrink:0;margin-left:8px} +.theme-control select{width:85px;height:24px;min-height:24px;font-size:var(--nc-small);background:var(--nc-surface);color:var(--nc-text)} +html[data-theme=dark] :is(.card,.opened-case,.case-result-view,.explorer-table-scroll,.document-case-file,.case-context-menu,.context-submenu-panel,.explorer-dialog,.workspace-extras-list,.workspace-help,.case-analysis-panel,.document-text,.workflow-tools,.reviewed-work-queues){background:var(--nc-surface);color:var(--nc-text);border-color:var(--nc-line)} +html[data-theme=dark] :is(input,select,textarea){background:var(--nc-background);color:var(--nc-text);border-color:var(--nc-button-border);accent-color:var(--nc-action)} +html[data-theme=dark] :is(p,dt,dd,small,summary,.field,.source,.source>span,.workflow-help,.section-head p,.eyebrow,.case-note,.queue-badge,.reader-help,.review-notice,.local){color:var(--nc-muted)} +html[data-theme=dark] :is(h1,h2,h3,h4,h5,strong,button.case-title-button){color:inherit} +html[data-theme=dark] :is(a,.text-button,.source-page-link){color:var(--nc-action)} +html[data-theme=dark] :is(.secondary,.case-context-menu button,.context-submenu-panel button){background:transparent;color:var(--nc-primary);border-color:var(--nc-button-border)} +html[data-theme=dark] :is(.case-context-menu button,.context-submenu-panel button,.secondary):hover:not(:disabled){background:var(--nc-light)} +html[data-theme=dark] .primary{background:#256da8;color:#fff} +html[data-theme=dark] .primary:hover:not(:disabled){background:#1d5687} +html[data-theme=dark] :is(pre,.notice,.explorer-notice,.opened-case-status,.queue-card,.queue-case,.workflow-history,.source){background:var(--nc-light);color:var(--nc-text);border-color:var(--nc-line)} +html[data-theme=dark] :is(.missing,.outcome.incomplete,.outcome.human_review){background:#403621;color:#ffebbf;border-color:#a08348} +html[data-theme=dark] :is(.error,.outcome.not_supported){background:#462730;color:#ffd9d1;border-color:#ac7280} +html[data-theme=dark] .outcome{background:#183e38;color:var(--nc-text);border-color:#4b867a} +html[data-theme=dark] :is(.section-head,.source,.document-observations td,.recorded-criteria td){border-color:var(--nc-line)} +html[data-theme=dark] .case-explorer .explorer-table th{background:var(--nc-light)} +html[data-theme=dark] .case-explorer .explorer-table tbody tr{background:var(--nc-surface);color:var(--nc-text)} +html[data-theme=dark] .case-explorer .explorer-table td{border-color:var(--nc-line)} +html[data-theme=dark] .case-explorer .explorer-table.status-row-colors tbody tr:is([data-status=approval],[data-status=complete]){background:#183e38} +html[data-theme=dark] .case-explorer .explorer-table.status-row-colors tbody tr[data-status=clarification]{background:#403621} +html[data-theme=dark] .case-explorer .explorer-table.status-row-colors tbody tr[data-status=review]{background:#493126} +html[data-theme=dark] .case-explorer .explorer-table.status-row-colors tbody tr[data-status=technical]{background:#462730} +html[data-theme=dark] .case-explorer .explorer-table.status-row-colors tbody tr[data-status=documents]{background:#343048} +html[data-theme=dark] .case-explorer .explorer-table tbody tr[aria-selected=true]{background:#256da8!important;color:#fff} +html[data-theme=dark] .case-explorer .explorer-table tbody tr[aria-selected=true] :is(.case-title-button,.case-identifier,.queue-badge){color:#fff} +html[data-theme=dark] .case-explorer .explorer-footer{background:var(--nc-background)} +html[data-theme=dark] .brandmark{color:var(--nc-background)} +html[data-theme=dark] dialog::backdrop{background:rgba(0,0,0,.6)} +html[data-theme=dark] :is(.pdf-page-image,.document-reader img){filter:none} + +html[data-theme=dark] :is(.batch-review,.workload-summary,.identity-list li,.batch-warning){background:var(--nc-light);color:var(--nc-text);border-color:var(--nc-line)} +html[data-theme=dark] :is(.batch-choice,.batch-result span,.workload-total span,.workload-counts span,.queue-more){color:var(--nc-muted)} +html[data-theme=dark] .workload-total strong{color:var(--nc-primary)} +html[data-theme=dark] input::placeholder{color:var(--nc-muted)} + +html[data-theme=dark] .workspace-extras-list a:hover{background:var(--nc-light)} diff --git a/frontend/tests/contrast.test.mjs b/frontend/tests/contrast.test.mjs index b002de8..87d2a51 100644 --- a/frontend/tests/contrast.test.mjs +++ b/frontend/tests/contrast.test.mjs @@ -15,3 +15,14 @@ test('reading, help and action colors meet WCAG AA on their actual surfaces',()= assert.ok(contrast('ffffff','256da8')>=4.5); assert.ok(contrast('123c63','eaf3f9')>=4.5); }); + +test('dark theme reading and status colors meet AA contrast',()=>{ + const block=css.match(/:root\[data-theme=dark\]\{([^}]+)\}/)[1]; + const token=name=>block.match(new RegExp('--nc-'+name+':#([0-9a-f]{6})'))[1]; + for(const bg of [token('surface'),token('background'),token('light'),'183e38','403621','493126','462730','343048']){ + assert.ok(contrast(token('text'),bg)>=4.5); + assert.ok(contrast(token('muted'),bg)>=4.5); + } + assert.ok(contrast(token('action'),token('surface'))>=4.5); + assert.ok(contrast(token('button-border'),token('background'))>=3); +}); From 81469338ca76847f65ad3ead42b185f52d76fe9b Mon Sep 17 00:00:00 2001 From: nfloser <102595695+nfloser@users.noreply.github.com> Date: Sat, 10 Oct 2026 22:11:47 +0200 Subject: [PATCH 2/5] Theme folder highlights, menu headings and auxiliary case lists --- frontend/src/style.css | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/frontend/src/style.css b/frontend/src/style.css index a6282e1..1cfc2cd 100644 --- a/frontend/src/style.css +++ b/frontend/src/style.css @@ -576,3 +576,10 @@ html[data-theme=dark] .workload-total strong{color:var(--nc-primary)} html[data-theme=dark] input::placeholder{color:var(--nc-muted)} html[data-theme=dark] .workspace-extras-list a:hover{background:var(--nc-light)} +html[data-theme=dark] .workspace-extras>summary{background:transparent;color:var(--nc-primary);border-color:var(--nc-line)} +html[data-theme=dark] .case-explorer .custom-folder>.tree-filter[aria-pressed=true]{background:var(--nc-selected)} +html[data-theme=dark] .case-explorer .context-submenu-panel .menu-custom-color{color:var(--nc-primary)} +html[data-theme=dark] .case-explorer .context-submenu.touch-submenu .context-submenu-panel.is-open{background:var(--nc-surface)} +html[data-theme=dark] .case-list-panel{background:var(--nc-background);border-color:var(--nc-line)} +html[data-theme=dark] .case-empty{color:var(--nc-muted)} +html[data-theme=dark] .workspace-navigation a[aria-current=page]{background:#256da8;color:#fff} From 74d6803ebfbaf946e3b84246622b77c36914a14e Mon Sep 17 00:00:00 2001 From: nfloser <102595695+nfloser@users.noreply.github.com> Date: Sat, 10 Oct 2026 22:16:08 +0200 Subject: [PATCH 3/5] Keep theme controls inside narrow workspace bounds --- frontend/e2e/theme.spec.mjs | 7 +++++++ frontend/src/style.css | 3 +++ 2 files changed, 10 insertions(+) diff --git a/frontend/e2e/theme.spec.mjs b/frontend/e2e/theme.spec.mjs index 4e2c3a8..b65fdc6 100644 --- a/frontend/e2e/theme.spec.mjs +++ b/frontend/e2e/theme.spec.mjs @@ -1,4 +1,11 @@ import {test,expect} from '@playwright/test'; +test('theme control stays reachable without widening a narrow workspace',async({page})=>{ + await page.setViewportSize({width:390,height:844});await page.goto('/#workbench'); + await expect.poll(()=>page.evaluate(()=>document.documentElement.scrollWidth<=innerWidth)).toBeTruthy(); + await page.getByLabel('Farbschema').selectOption('dark'); + await expect(page.locator('html')).toHaveAttribute('data-theme','dark'); + await expect.poll(()=>page.evaluate(()=>document.documentElement.scrollWidth<=innerWidth)).toBeTruthy(); +}); test('theme follows the system until explicitly changed and survives workspace navigation',async({page})=>{ await page.emulateMedia({colorScheme:'dark'});await page.goto('/#work-queues'); const scheme=page.getByLabel('Farbschema');await expect(scheme).toHaveValue('system'); diff --git a/frontend/src/style.css b/frontend/src/style.css index 1cfc2cd..c16bc7f 100644 --- a/frontend/src/style.css +++ b/frontend/src/style.css @@ -540,6 +540,9 @@ h2,h3,h4,h5{font-size:14px;font-weight:600}strong{font-weight:600}main p{line-he --nc-shadow:0 4px 12px rgba(0,0,0,.45); } .theme-control{display:flex;align-items:center;flex-shrink:0;margin-left:8px} +.application-workspace{width:100%;min-width:0} +.application-workspace .workspace-navigation{min-width:0;max-width:100%} +html[data-theme=dark] .empty-symbol{background:var(--nc-light);color:var(--nc-primary)} .theme-control select{width:85px;height:24px;min-height:24px;font-size:var(--nc-small);background:var(--nc-surface);color:var(--nc-text)} html[data-theme=dark] :is(.card,.opened-case,.case-result-view,.explorer-table-scroll,.document-case-file,.case-context-menu,.context-submenu-panel,.explorer-dialog,.workspace-extras-list,.workspace-help,.case-analysis-panel,.document-text,.workflow-tools,.reviewed-work-queues){background:var(--nc-surface);color:var(--nc-text);border-color:var(--nc-line)} html[data-theme=dark] :is(input,select,textarea){background:var(--nc-background);color:var(--nc-text);border-color:var(--nc-button-border);accent-color:var(--nc-action)} From f933db4459b82915621711ddfd0356b91c2ae543 Mon Sep 17 00:00:00 2001 From: nfloser <102595695+nfloser@users.noreply.github.com> Date: Sat, 10 Oct 2026 22:17:01 +0200 Subject: [PATCH 4/5] Darken document navigation and folder color choices --- frontend/e2e/theme.spec.mjs | 1 + frontend/src/style.css | 3 +++ 2 files changed, 4 insertions(+) diff --git a/frontend/e2e/theme.spec.mjs b/frontend/e2e/theme.spec.mjs index b65fdc6..6e454d7 100644 --- a/frontend/e2e/theme.spec.mjs +++ b/frontend/e2e/theme.spec.mjs @@ -29,6 +29,7 @@ for(const width of [1366,1920])test(`dark case file, sources and dialogs remain await expect(explorer.getByRole('heading',{name:'Prüfergebnis: Voraussetzungen erfüllt',exact:true})).toBeVisible(); await page.screenshot({path:`test-results/dark-case-${width}.png`}); await explorer.getByRole('button',{name:'Dokumente',exact:true}).click(); + await expect(explorer.locator('.document-case-summary')).toHaveCSS('background-color','rgb(15, 27, 40)'); await expect(explorer.locator('.pdf-page-image').first()).toHaveCSS('filter','none'); await page.screenshot({path:`test-results/dark-documents-${width}.png`}); await explorer.getByRole('button',{name:'Neuer Ordner',exact:true}).click(); diff --git a/frontend/src/style.css b/frontend/src/style.css index c16bc7f..b7e34ff 100644 --- a/frontend/src/style.css +++ b/frontend/src/style.css @@ -543,6 +543,9 @@ h2,h3,h4,h5{font-size:14px;font-weight:600}strong{font-weight:600}main p{line-he .application-workspace{width:100%;min-width:0} .application-workspace .workspace-navigation{min-width:0;max-width:100%} html[data-theme=dark] .empty-symbol{background:var(--nc-light);color:var(--nc-primary)} +html[data-theme=dark] .document-case-summary{background:var(--nc-background);color:var(--nc-text)} +html[data-theme=dark] .case-file-list button[aria-pressed=true]{background:var(--nc-selected)} +html[data-theme=dark] .color-presets button{background:var(--nc-surface);color:var(--nc-text);border-color:var(--nc-button-border)} .theme-control select{width:85px;height:24px;min-height:24px;font-size:var(--nc-small);background:var(--nc-surface);color:var(--nc-text)} html[data-theme=dark] :is(.card,.opened-case,.case-result-view,.explorer-table-scroll,.document-case-file,.case-context-menu,.context-submenu-panel,.explorer-dialog,.workspace-extras-list,.workspace-help,.case-analysis-panel,.document-text,.workflow-tools,.reviewed-work-queues){background:var(--nc-surface);color:var(--nc-text);border-color:var(--nc-line)} html[data-theme=dark] :is(input,select,textarea){background:var(--nc-background);color:var(--nc-text);border-color:var(--nc-button-border);accent-color:var(--nc-action)} From 88e2c5e5a33b52edba9067aa01f1339f6c2e6050 Mon Sep 17 00:00:00 2001 From: nfloser <102595695+nfloser@users.noreply.github.com> Date: Sat, 10 Oct 2026 22:20:34 +0200 Subject: [PATCH 5/5] Contain the theme control accessible label in its scrollable menu --- frontend/src/style.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/style.css b/frontend/src/style.css index b7e34ff..b596b40 100644 --- a/frontend/src/style.css +++ b/frontend/src/style.css @@ -539,7 +539,7 @@ h2,h3,h4,h5{font-size:14px;font-weight:600}strong{font-weight:600}main p{line-he --nc-primary:#b5d9ff;--nc-action:#81baff;--nc-light:#20384f;--nc-background:#0f1b28;--nc-surface:#172635;--nc-line:#3c5268;--nc-button-border:#61778f;--nc-text:#e1ebf5;--nc-muted:#acbbcc;--nc-selected:#284d70;--nc-viewer:#0a1520; --nc-shadow:0 4px 12px rgba(0,0,0,.45); } -.theme-control{display:flex;align-items:center;flex-shrink:0;margin-left:8px} +.theme-control{position:relative;display:flex;align-items:center;flex-shrink:0;margin-left:8px} .application-workspace{width:100%;min-width:0} .application-workspace .workspace-navigation{min-width:0;max-width:100%} html[data-theme=dark] .empty-symbol{background:var(--nc-light);color:var(--nc-primary)}