From d98a016087378cf44a51d4aa0dcd992369091b1e Mon Sep 17 00:00:00 2001 From: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Tue, 12 Apr 2022 19:21:55 -0700 Subject: [PATCH 1/4] Initial build of primary color contrast --- src-ui/src/app/services/settings.service.ts | 14 ++ src-ui/src/app/utils/color.ts | 19 +- src-ui/src/styles.scss | 20 +- src-ui/src/theme.scss | 192 ++++++++++++++++++++ src-ui/src/theme_dark.scss | 171 ----------------- 5 files changed, 237 insertions(+), 179 deletions(-) delete mode 100644 src-ui/src/theme_dark.scss diff --git a/src-ui/src/app/services/settings.service.ts b/src-ui/src/app/services/settings.service.ts index b3447ee26..e9017d147 100644 --- a/src-ui/src/app/services/settings.service.ts +++ b/src-ui/src/app/services/settings.service.ts @@ -132,8 +132,22 @@ export class SettingsService { : this.renderer.removeClass(this.document.body, 'color-scheme-dark') } + // remove these in case they were there + this.renderer.removeClass(this.document.body, 'text-bg-dark') + this.renderer.removeClass(this.document.body, 'text-bg-light') + if (themeColor) { const hsl = hexToHsl(themeColor) + const useDarkTextColor = + parseInt(themeColor.replace('#', ''), 16) > 0xffffff / 1.5 + + if (useDarkTextColor) { + this.renderer.addClass(this.document.body, 'text-bg-dark') + this.renderer.removeClass(this.document.body, 'text-bg-light') + } else { + this.renderer.addClass(this.document.body, 'text-bg-light') + this.renderer.removeClass(this.document.body, 'text-bg-dark') + } this.renderer.setStyle( document.documentElement, '--pngx-primary', diff --git a/src-ui/src/app/utils/color.ts b/src-ui/src/app/utils/color.ts index 79d237f27..5c083c2b9 100644 --- a/src-ui/src/app/utils/color.ts +++ b/src-ui/src/app/utils/color.ts @@ -1,4 +1,4 @@ -import { HSL } from 'ngx-color' +import { HSL, RGB } from 'ngx-color' function componentToHex(c) { var hex = Math.floor(c).toString(16) @@ -86,14 +86,19 @@ export function rgbToHsl(r, g, b) { } export function hexToHsl(hex: string): HSL { + const rgb = hexToRGB(hex) + const hsl = rgbToHsl(rgb.r, rgb.g, rgb.b) + return { h: hsl[0], s: hsl[1], l: hsl[2] } +} + +export function hexToRGB(hex: string): RGB { hex = hex.replace('#', '') let aRgbHex = hex.match(/.{1,2}/g) - const hsl = rgbToHsl( - parseInt(aRgbHex[0], 16), - parseInt(aRgbHex[1], 16), - parseInt(aRgbHex[2], 16) - ) - return { h: hsl[0], s: hsl[1], l: hsl[2] } + return { + r: parseInt(aRgbHex[0], 16), + g: parseInt(aRgbHex[1], 16), + b: parseInt(aRgbHex[2], 16), + } } export function randomColor() { diff --git a/src-ui/src/styles.scss b/src-ui/src/styles.scss index 6c6d5f965..6922e3d7c 100644 --- a/src-ui/src/styles.scss +++ b/src-ui/src/styles.scss @@ -4,7 +4,6 @@ $enable-negative-margins: true; @import "node_modules/bootstrap/scss/bootstrap"; @import "~@ng-select/ng-select/themes/default.theme.css"; @import "theme"; -@import "theme_dark"; @import "print"; // Paperless-ngx styles @@ -36,9 +35,19 @@ svg.logo { .bg-primary { background-color: var(--bs-primary) !important; + color: var(--pngx-primary-text-contrast); +} + +.navbar-brand { + color: var(--pngx-primary-text-contrast) !important; +} + +.navbar .dropdown .btn { + color: var(--pngx-primary-text-contrast) !important; } .btn-primary { + color: var(--pngx-primary-text-contrast); background-color: var(--bs-primary); border-color: var(--bs-primary); @@ -48,6 +57,7 @@ svg.logo { } &:disabled, &.disabled { + color: var(--pngx-primary-text-contrast); background-color: var(--pngx-primary-darken-10) !important; border-color: var(--pngx-primary-darken-10) !important; } @@ -350,6 +360,14 @@ table.table { } } +.toast { + color: var(--pngx-primary-text-contrast); + + .toast-header { + color: var(--pngx-primary-text-contrast); + } +} + .close { color: var(--bs-body-color); } diff --git a/src-ui/src/theme.scss b/src-ui/src/theme.scss index f52fba1f5..ea7995be8 100644 --- a/src-ui/src/theme.scss +++ b/src-ui/src/theme.scss @@ -15,3 +15,195 @@ --pngx-bg-darker: var(--bs-gray-100); --pngx-focus-alpha: 0.3; } + +// Dark text colors allow for maintain contrast with theme color changes +$text-color-light-bg: #212529; +$text-color-dark-bg: #abb2bf; +$text-color-dark-bg-accent: lighten($text-color-dark-bg, 10%); +// Taken from bootstrap +$form-check-input-checked-bg-image-dark: url("data:image/svg+xml,"); +$form-check-radio-checked-bg-image-dark: url("data:image/svg+xml,"); + +.text-bg-light { + --pngx-primary-text-contrast: #{$text-color-light-bg} !important; + + .form-check-input:checked[type=checkbox] { + background-image: escape-svg($form-check-input-checked-bg-image-dark); + } + + .form-check-input:checked[type=radio] { + background-image: escape-svg($form-check-radio-checked-bg-image-dark); + } +} + +.text-bg-dark { + --pngx-primary-text-contrast: #{$text-color-dark-bg} !important; +} + +// Dark mode +$primary-dark-mode: #45973a; +$primary-dark-mode-rgb: 69, 151, 58; +$primary-dark-mode-darken-10: darken($primary-dark-mode, 10%); +$danger-dark-mode: #b71631; +$danger-dark-mode-rgb: 183, 22, 49; +$bg-dark-mode: #161618; +$bg-dark-mode-rgb: 22, 22, 24; +$bg-dark-mode-accent: #101216; +$bg-dark-mode-alt: #242529; +$bg-light-dark-mode: #1c1c1f; +$bg-light-dark-mode-rgb: 28, 28, 31; +$border-color-dark-mode: #47494f; + +@mixin dark-mode { + --bs-primary: hsl(var(--pngx-primary), calc(var(--pngx-primary-lightness) + 10%)); + --bs-body-color: #{$text-color-dark-bg}; + --pngx-body-color-accent: #{$text-color-dark-bg-accent}; + --bs-danger: #{$danger-dark-mode}; + --bs-danger-rgb: #{$danger-dark-mode-rgb}; + --bs-body-bg: #{$bg-dark-mode}; + --bs-body-bg-rgb: #{$bg-dark-mode-rgb}; + --bs-light: #{$bg-light-dark-mode}; + --bs-light-rgb: #{$bg-light-dark-mode-rgb}; + --bs-border-color: #{$border-color-dark-mode}; + --pngx-bg-darker: #{$bg-dark-mode-accent}; + --pngx-bg-alt: #{$bg-dark-mode-alt}; + --pngx-focus-alpha: 0.7; + --pngx-primary-faded: var(--pngx-primary-darken-15); + --pngx-primary-text-contrast: var(--bs-body-color); + + .navbar.bg-primary { + --bs-primary: hsl(var(--pngx-primary),var(--pngx-primary-lightness)); + --bs-primary-rgb: var(--bs-primary); + } + + .border { + border-color: var(--bs-border-color) !important; + } + + .border-end { + border-right: 1px solid var(--bs-border-color) !important; + } + + .border-start { + border-left: 1px solid var(--bs-border-color) !important; + } + + .border-bottom { + border-bottom: 1px solid var(--bs-border-color) !important; + } + + .text-dark, .text-light { + color: var(--bs-body-color) !important; + } + + .btn-outline-primary, .btn-primary { + &:hover, &:focus, &.active, &:active { + color: var(--bs-light) !important; + } + } + + .btn-outline-secondary { + &:hover, &:focus, &.active, &:active { + background-color: var(--pngx-bg-darker); + color: var(--bs-primary); + } + } + + .search-form-container { + input, input:focus { + color: var(--bs-body-color) !important; + } + } + + .card { + background-color: var(--bs-body-bg); + + .card-header { + background-color: rgba(0, 0, 0, 0.12); + } + } + + .modal-content, .modal-header, .modal-body, .modal-footer { + background-color: var(--bs-body-bg); + border-color: var(--bs-border-color); + } + + app-tag .badge { + filter: brightness(.8); + } + + .doc-img-container { + border: none !important; + border-top-left-radius: .25rem; + border-top-right-radius: .25rem; + overflow: hidden; + } + + .doc-img { + mix-blend-mode: normal; + border-radius: 0; + border-color: var(--bs-border-color); + filter: invert(10%); + + &.border-end { + border-right: none !important; + } + } + + .doc-img.inverted { + filter: invert(95%) hue-rotate(180deg); + } + + .card-selected .doc-img { + mix-blend-mode: luminosity; + } + + .ng-dropdown-panel .ng-dropdown-panel-items .ng-option:hover, + .ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-marked { + background-color: $bg-light-dark-mode; + } + + table { + .des, + .asc { + &::after { + filter: invert(0.8); /* arrow is a black inline png bkgd image (!) so use filter */ + } + } + + &.table-hover > tbody > tr:hover > * { + background-color: $bg-light-dark-mode; + color: var(--pngx-body-color-accent); + } + + } + + .table-striped > tbody > tr:nth-of-type(odd) > * { + color: var(--pngx-body-color-accent); + } + + .close, .modal .btn-close, .alert .btn-close { + text-shadow: 0 1px 0 #666; + } + + .modal .btn-close, .alert .btn-close { + filter: invert(1) grayscale(100%) brightness(200%); + } + + .toast { + background-color: hsla(var(--pngx-primary), calc(var(--pngx-primary-lightness) - 18%), 0.9); + } + + .toast-header { + background-color: hsla(var(--pngx-primary), calc(var(--pngx-primary-lightness) - 10%), 0.9); + } +} + +body.color-scheme-dark { + @include dark-mode; +} +body.color-scheme-system { + @media (prefers-color-scheme: dark) { + @include dark-mode; + } +} diff --git a/src-ui/src/theme_dark.scss b/src-ui/src/theme_dark.scss deleted file mode 100644 index 240312845..000000000 --- a/src-ui/src/theme_dark.scss +++ /dev/null @@ -1,171 +0,0 @@ -$primary-dark-mode: #45973a; -$primary-dark-mode-rgb: 69, 151, 58; -$primary-dark-mode-darken-10: darken($primary-dark-mode, 10%); -$danger-dark-mode: #b71631; -$danger-dark-mode-rgb: 183, 22, 49; -$bg-dark-mode: #161618; -$bg-dark-mode-rgb: 22, 22, 24; -$bg-dark-mode-accent: #101216; -$bg-dark-mode-alt: #242529; -$bg-light-dark-mode: #1c1c1f; -$bg-light-dark-mode-rgb: 28, 28, 31; -$text-color-dark-mode: #abb2bf; -$text-color-dark-mode-accent: lighten($text-color-dark-mode, 10%); -$border-color-dark-mode: #47494f; - -@mixin dark-mode { - --bs-primary: hsl(var(--pngx-primary), calc(var(--pngx-primary-lightness) + 10%)); - --bs-danger: #{$danger-dark-mode}; - --bs-danger-rgb: #{$danger-dark-mode-rgb}; - --bs-body-bg: #{$bg-dark-mode}; - --bs-body-bg-rgb: #{$bg-dark-mode-rgb}; - --bs-body-color: #{$text-color-dark-mode}; - --bs-light: #{$bg-light-dark-mode}; - --bs-light-rgb: #{$bg-light-dark-mode-rgb}; - --bs-border-color: #{$border-color-dark-mode}; - --pngx-bg-darker: #{$bg-dark-mode-accent}; - --pngx-bg-alt: #{$bg-dark-mode-alt}; - --pngx-body-color-accent: #{$text-color-dark-mode-accent}; - --pngx-focus-alpha: 0.7; - --pngx-primary-faded: var(--pngx-primary-darken-15); - --pngx-primary-text-contrast: var(--bs-body-color); - - .navbar.bg-primary{ - --bs-primary: hsl(var(--pngx-primary),var(--pngx-primary-lightness)); - --bs-primary-rgb: var(--bs-primary); - } - - .navbar-brand { - color: var(--bs-body-color); - } - - .border { - border-color: var(--bs-border-color) !important; - } - - .border-end { - border-right: 1px solid var(--bs-border-color) !important; - } - - .border-start { - border-left: 1px solid var(--bs-border-color) !important; - } - - .border-bottom { - border-bottom: 1px solid var(--bs-border-color) !important; - } - - .text-dark, .text-light { - color: var(--bs-body-color) !important; - } - - .btn-outline-primary, .btn-primary { - &:hover, &:focus, &.active, &:active { - color: var(--bs-light) !important; - } - } - - .btn-outline-secondary { - &:hover, &:focus, &.active, &:active { - background-color: var(--pngx-bg-darker); - color: var(--bs-primary); - } - } - - .search-form-container { - input, input:focus { - color: var(--bs-body-color) !important; - } - } - - .card { - background-color: var(--bs-body-bg); - - .card-header { - background-color: rgba(0, 0, 0, 0.12); - } - } - - .modal-content, .modal-header, .modal-body, .modal-footer { - background-color: var(--bs-body-bg); - border-color: var(--bs-border-color); - } - - app-tag .badge { - filter: brightness(.8); - } - - .doc-img-container { - border: none !important; - border-top-left-radius: .25rem; - border-top-right-radius: .25rem; - overflow: hidden; - } - - .doc-img { - mix-blend-mode: normal; - border-radius: 0; - border-color: var(--bs-border-color); - filter: invert(10%); - - &.border-end { - border-right: none !important; - } - } - - .doc-img.inverted { - filter: invert(95%) hue-rotate(180deg); - } - - .card-selected .doc-img { - mix-blend-mode: luminosity; - } - - .ng-dropdown-panel .ng-dropdown-panel-items .ng-option:hover, - .ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-marked { - background-color: $bg-light-dark-mode; - } - - table { - .des, - .asc { - &::after { - filter: invert(0.8); /* arrow is a black inline png bkgd image (!) so use filter */ - } - } - - &.table-hover > tbody > tr:hover > * { - background-color: $bg-light-dark-mode; - color: $text-color-dark-mode-accent; - } - } - - .table-striped > tbody > tr:nth-of-type(odd) > * { - color: $text-color-dark-mode-accent; - } - - .close, .modal .btn-close, .alert .btn-close { - text-shadow: 0 1px 0 #666; - } - - .modal .btn-close, .alert .btn-close { - filter: invert(1) grayscale(100%) brightness(200%); - } - - .toast { - background-color: hsla(var(--pngx-primary), calc(var(--pngx-primary-lightness) - 18%), 0.9); - } - - .toast-header { - background-color: hsla(var(--pngx-primary), calc(var(--pngx-primary-lightness) - 10%), 0.9); - } -} - -body.color-scheme-dark { - @include dark-mode; -} -body.color-scheme-system { - @media (prefers-color-scheme: dark) { - @include dark-mode; - } -} From 1c2699b16ee122d9c0bcf88003ab659a47fb0b25 Mon Sep 17 00:00:00 2001 From: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Tue, 12 Apr 2022 22:23:00 -0700 Subject: [PATCH 2/4] Refactor contrast to use luminance function --- src-ui/src/app/services/settings.service.ts | 11 +++++--- src-ui/src/app/utils/color.ts | 28 +++++++++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src-ui/src/app/services/settings.service.ts b/src-ui/src/app/services/settings.service.ts index e9017d147..747c21fb7 100644 --- a/src-ui/src/app/services/settings.service.ts +++ b/src-ui/src/app/services/settings.service.ts @@ -9,7 +9,11 @@ import { } from '@angular/core' import { Meta } from '@angular/platform-browser' import { CookieService } from 'ngx-cookie-service' -import { hexToHsl } from 'src/app/utils/color' +import { + BRIGHTNESS, + estimateBrightnessForColor, + hexToHsl, +} from 'src/app/utils/color' export interface PaperlessSettings { key: string @@ -138,10 +142,9 @@ export class SettingsService { if (themeColor) { const hsl = hexToHsl(themeColor) - const useDarkTextColor = - parseInt(themeColor.replace('#', ''), 16) > 0xffffff / 1.5 + const bgBrightnessEstimate = estimateBrightnessForColor(themeColor) - if (useDarkTextColor) { + if (bgBrightnessEstimate == BRIGHTNESS.DARK) { this.renderer.addClass(this.document.body, 'text-bg-dark') this.renderer.removeClass(this.document.body, 'text-bg-light') } else { diff --git a/src-ui/src/app/utils/color.ts b/src-ui/src/app/utils/color.ts index 5c083c2b9..e23a91c5f 100644 --- a/src-ui/src/app/utils/color.ts +++ b/src-ui/src/app/utils/color.ts @@ -1,5 +1,10 @@ import { HSL, RGB } from 'ngx-color' +export const BRIGHTNESS = { + LIGHT: 'light', + DARK: 'dark', +} + function componentToHex(c) { var hex = Math.floor(c).toString(16) return hex.length == 1 ? '0' + hex : hex @@ -101,6 +106,29 @@ export function hexToRGB(hex: string): RGB { } } +export function computeLuminance(color: RGB) { + // Formula: http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef + const colorKeys = Object.keys(color) + for (var i = 0; i < 3; i++) { + var rgb = color[colorKeys[i]] + rgb /= 255 + rgb = rgb < 0.03928 ? rgb / 12.92 : Math.pow((rgb + 0.055) / 1.055, 2.4) + color[i] = rgb + } + return 0.2126 * color[0] + 0.7152 * color[1] + 0.0722 * color[2] +} + +export function estimateBrightnessForColor(colorHex: string) { + // See + // Adapted from https://api.flutter.dev/flutter/material/ThemeData/estimateBrightnessForColor.html + const rgb = hexToRGB(colorHex) + const luminance = computeLuminance(rgb) + const kThreshold = 0.15 + return (luminance + 0.05) * (luminance + 0.05) > kThreshold + ? BRIGHTNESS.LIGHT + : BRIGHTNESS.DARK +} + export function randomColor() { let rgb = hslToRgb(Math.random(), 0.6, Math.random() * 0.4 + 0.4) return `#${componentToHex(rgb[0])}${componentToHex(rgb[1])}${componentToHex( From 1d7ddcc10d38d71a61965f034b22b8c55bc91066 Mon Sep 17 00:00:00 2001 From: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Wed, 13 Apr 2022 08:43:35 -0700 Subject: [PATCH 3/4] Remove unneeded imports since change to css vars --- src-ui/src/app/components/app-frame/app-frame.component.scss | 1 - .../filterable-dropdown/filterable-dropdown.component.scss | 2 -- .../upload-file-widget/upload-file-widget.component.scss | 2 -- .../document-card-large/document-card-large.component.scss | 2 -- .../document-card-small/document-card-small.component.scss | 2 -- .../app/components/document-list/document-list.component.scss | 2 -- 6 files changed, 11 deletions(-) diff --git a/src-ui/src/app/components/app-frame/app-frame.component.scss b/src-ui/src/app/components/app-frame/app-frame.component.scss index bcf87a12a..5511a29b0 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.scss +++ b/src-ui/src/app/components/app-frame/app-frame.component.scss @@ -1,4 +1,3 @@ -@import "/src/theme"; /* * Sidebar */ diff --git a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.scss b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.scss index a72473112..dfb989fea 100644 --- a/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.scss +++ b/src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.scss @@ -1,5 +1,3 @@ -@import "/src/theme"; - .badge-corner { position: absolute; top: -8px; diff --git a/src-ui/src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.scss b/src-ui/src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.scss index cd3afe46f..0e81d8bb5 100644 --- a/src-ui/src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.scss +++ b/src-ui/src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.scss @@ -1,5 +1,3 @@ -@import "/src/theme"; - form { position: relative; } diff --git a/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.scss b/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.scss index 33deebc37..e3398c245 100644 --- a/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.scss +++ b/src-ui/src/app/components/document-list/document-card-large/document-card-large.component.scss @@ -1,5 +1,3 @@ -@import "/src/theme"; - .result-content { overflow-wrap: anywhere; } diff --git a/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.scss b/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.scss index ae89ea9d6..4d03d0a4d 100644 --- a/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.scss +++ b/src-ui/src/app/components/document-list/document-card-small/document-card-small.component.scss @@ -1,5 +1,3 @@ -@import "/src/theme"; - .card-text { font-size: 90%; } diff --git a/src-ui/src/app/components/document-list/document-list.component.scss b/src-ui/src/app/components/document-list/document-list.component.scss index 616069b08..b2d138d7f 100644 --- a/src-ui/src/app/components/document-list/document-list.component.scss +++ b/src-ui/src/app/components/document-list/document-list.component.scss @@ -1,5 +1,3 @@ -@import "/src/theme"; - ::ng-deep app-document-list app-page-header > div.mb-3 { margin-bottom: 0 !important; } From 6478db13e6446c458e280609b029bf2bc99fa928 Mon Sep 17 00:00:00 2001 From: Michael Shamoon <4887959+shamoon@users.noreply.github.com> Date: Wed, 13 Apr 2022 09:29:23 -0700 Subject: [PATCH 4/4] miscellaneous css fixes / reorganization --- .../app-frame/app-frame.component.scss | 7 +++- src-ui/src/app/services/settings.service.ts | 12 +++--- src-ui/src/styles.scss | 40 +++++++++++++----- src-ui/src/theme.scss | 42 ++++--------------- 4 files changed, 50 insertions(+), 51 deletions(-) diff --git a/src-ui/src/app/components/app-frame/app-frame.component.scss b/src-ui/src/app/components/app-frame/app-frame.component.scss index 5511a29b0..5fe408660 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.scss +++ b/src-ui/src/app/components/app-frame/app-frame.component.scss @@ -35,10 +35,15 @@ .sidebar .nav-link { font-weight: 500; - &:hover, &.active { + &:hover, &.active, &:focus { color: var(--bs-primary); } + &:focus-visible { + outline: none; + background-color: var(--bs-body-bg); + } + &.active { font-weight: bold; } diff --git a/src-ui/src/app/services/settings.service.ts b/src-ui/src/app/services/settings.service.ts index 747c21fb7..a6e972168 100644 --- a/src-ui/src/app/services/settings.service.ts +++ b/src-ui/src/app/services/settings.service.ts @@ -137,19 +137,19 @@ export class SettingsService { } // remove these in case they were there - this.renderer.removeClass(this.document.body, 'text-bg-dark') - this.renderer.removeClass(this.document.body, 'text-bg-light') + this.renderer.removeClass(this.document.body, 'primary-dark') + this.renderer.removeClass(this.document.body, 'primary-light') if (themeColor) { const hsl = hexToHsl(themeColor) const bgBrightnessEstimate = estimateBrightnessForColor(themeColor) if (bgBrightnessEstimate == BRIGHTNESS.DARK) { - this.renderer.addClass(this.document.body, 'text-bg-dark') - this.renderer.removeClass(this.document.body, 'text-bg-light') + this.renderer.addClass(this.document.body, 'primary-dark') + this.renderer.removeClass(this.document.body, 'primary-light') } else { - this.renderer.addClass(this.document.body, 'text-bg-light') - this.renderer.removeClass(this.document.body, 'text-bg-dark') + this.renderer.addClass(this.document.body, 'primary-light') + this.renderer.removeClass(this.document.body, 'primary-dark') } this.renderer.setStyle( document.documentElement, diff --git a/src-ui/src/styles.scss b/src-ui/src/styles.scss index 6922e3d7c..0838661ae 100644 --- a/src-ui/src/styles.scss +++ b/src-ui/src/styles.scss @@ -25,6 +25,27 @@ svg.logo { } } +.navbar.bg-primary { + --bs-primary: hsl(var(--pngx-primary),var(--pngx-primary-lightness)); + --bs-primary-rgb: var(--bs-primary); +} + +.border { + border-color: var(--bs-border-color) !important; +} + +.border-end { + border-right: 1px solid var(--bs-border-color) !important; +} + +.border-start { + border-left: 1px solid var(--bs-border-color) !important; +} + +.border-bottom { + border-bottom: 1px solid var(--bs-border-color) !important; +} + .nav-link, .list-group-item { color: var(--bs-body-color); } @@ -100,9 +121,9 @@ svg.logo { background-image: escape-svg(url("data:image/svg+xml,")); } -.nav-link:focus-visible, .nav-item a:focus-visible { +.nav-item a:focus-visible { outline: none; - background-color: var(--pngx-bg-darker); + background-color: var(--bs-body-bg); } a.navbar-brand:focus-visible { @@ -335,6 +356,13 @@ textarea, } } +.doc-img-container { + border: none !important; + border-top-left-radius: .25rem; + border-top-right-radius: .25rem; + overflow: hidden; +} + // icons .toolbaricon { width: 1.2em; @@ -360,14 +388,6 @@ table.table { } } -.toast { - color: var(--pngx-primary-text-contrast); - - .toast-header { - color: var(--pngx-primary-text-contrast); - } -} - .close { color: var(--bs-body-color); } diff --git a/src-ui/src/theme.scss b/src-ui/src/theme.scss index ea7995be8..a24586879 100644 --- a/src-ui/src/theme.scss +++ b/src-ui/src/theme.scss @@ -24,7 +24,7 @@ $text-color-dark-bg-accent: lighten($text-color-dark-bg, 10%); $form-check-input-checked-bg-image-dark: url("data:image/svg+xml,"); $form-check-radio-checked-bg-image-dark: url("data:image/svg+xml,"); -.text-bg-light { +.primary-light { --pngx-primary-text-contrast: #{$text-color-light-bg} !important; .form-check-input:checked[type=checkbox] { @@ -36,7 +36,7 @@ $form-check-radio-checked-bg-image-dark: url("data:image/svg+xml,