feat(theme): Update theme colors

- Introduce the new colors for all color themes
- The colors are based on the Material 3 color but customized
This commit is contained in:
yoy 2025-04-04 09:59:49 +02:00 committed by toj
parent f164e39c94
commit 2675f20c74
73 changed files with 491 additions and 590 deletions

View file

@ -31,9 +31,9 @@ class AndroidThemeFacade(
private const val TAG = "AndroidThemeFacade"
private val LIGHT_FALLBACK_THEME = mapOf(
"themeId" to "light-fallback",
"content_bg" to "#ffffff",
"header_bg" to "#ffffff",
"navigation_bg" to "#f6f6f6",
"surface" to "#ffffff",
"surface" to "#ffffff",
"surface_container" to "#f6f6f6",
)
}
@ -103,13 +103,13 @@ class AndroidThemeFacade(
private fun doApplyTheme(theme: Theme) {
Log.d(TAG, "changeTheme: " + theme["themeId"])
@ColorInt val backgroundColor = parseColor(getColor(theme, "content_bg"))
@ColorInt val backgroundColor = parseColor(getColor(theme, "surface"))
activity.window.setBackgroundDrawable(ColorDrawable(backgroundColor))
// It is not an accident that navBg and headerBg seem to be swapped, the original color scheme was reused in
// this way.
val navBg = getColor(theme, "header_bg")
val navBg = getColor(theme, "surface")
@ColorInt val navColor = parseColor(navBg)
val isNavBarLight = navBg.isLightHexColor()
@ -121,7 +121,7 @@ class AndroidThemeFacade(
windowInsetController.isAppearanceLightNavigationBars = true
}
val headerBg = getColor(theme, "navigation_bg")
val headerBg = getColor(theme, "surface_container")
@ColorInt val statusBarColor = parseColor(headerBg)
val isStatusBarLight = headerBg.isLightHexColor()

View file

@ -31,9 +31,9 @@ class AndroidThemeFacade(
private const val TAG = "AndroidThemeFacade"
private val LIGHT_FALLBACK_THEME = mapOf(
"themeId" to "light-fallback",
"content_bg" to "#ffffff",
"header_bg" to "#ffffff",
"navigation_bg" to "#f6f6f6",
"surface" to "#ffffff",
"surface" to "#ffffff",
"surface_container" to "#f6f6f6",
)
}
@ -103,13 +103,13 @@ class AndroidThemeFacade(
private fun doApplyTheme(theme: Theme) {
Log.d(TAG, "changeTheme: " + theme["themeId"])
@ColorInt val backgroundColor = parseColor(getColor(theme, "content_bg"))
@ColorInt val backgroundColor = parseColor(getColor(theme, "surface"))
activity.window.setBackgroundDrawable(ColorDrawable(backgroundColor))
// It is not an accident that navBg and headerBg seem to be swapped, the original color scheme was reused in
// this way.
val navBg = getColor(theme, "header_bg")
val navBg = getColor(theme, "surface")
@ColorInt val navColor = parseColor(navBg)
val isNavBarLight = navBg.isLightHexColor()
@ -119,7 +119,7 @@ class AndroidThemeFacade(
windowInsetController.isAppearanceLightNavigationBars = isNavBarLight
val headerBg = getColor(theme, "navigation_bg")
val headerBg = getColor(theme, "surface_container")
@ColorInt val statusBarColor = parseColor(headerBg)
val isStatusBarLight = headerBg.isLightHexColor()

View file

@ -6,7 +6,7 @@ typealias Theme = [String: String]
private let SELECTED_THEME = "theme"
private let THEMES = "themes"
private let LIGHT_FALLBACK_THEME = ["themeId": "light-fallback", "content_bg": "#ffffff", "header_bg": "#ffffff", "navigation_bg": "f6f6f6"]
private let LIGHT_FALLBACK_THEME = ["themeId": "light-fallback", "surface": "#ffffff"]
class ThemeManager: NSObject {
private let userPreferencesProvider: UserPreferencesProvider

View file

@ -217,7 +217,7 @@ class ViewController: UIViewController, WKNavigationDelegate, UIScrollViewDelega
private func getAssetUrl() -> URL { URL(string: "asset://app/index-app.html")! }
func applyTheme(_ theme: [String: String]) {
let contentBgString = theme["content_bg"]!
let contentBgString = theme["surface"]!
let contentBg = UIColor(hex: contentBgString)!
self.isDarkTheme = !contentBg.isLight()
self.view.backgroundColor = contentBg

View file

@ -6,7 +6,7 @@ typealias Theme = [String: String]
private let SELECTED_THEME = "theme"
private let THEMES = "themes"
private let LIGHT_FALLBACK_THEME = ["themeId": "light-fallback", "content_bg": "#ffffff", "header_bg": "#ffffff", "navigation_bg": "f6f6f6"]
private let LIGHT_FALLBACK_THEME = ["themeId": "light-fallback", "surface": "#ffffff"]
class ThemeManager: NSObject {
private let userPreferencesProvider: UserPreferencesProvider

View file

@ -234,7 +234,7 @@ class ViewController: UIViewController, WKNavigationDelegate, WKUIDelegate, UISc
private func getAssetUrl() -> URL { URL(string: "asset://app/index-app.html")! }
func applyTheme(_ theme: [String: String]) {
let contentBgString = theme["content_bg"]!
let contentBgString = theme["surface"]!
let contentBg = UIColor(hex: contentBgString)!
self.isDarkTheme = !contentBg.isLight()
self.view.backgroundColor = contentBg

View file

@ -179,7 +179,7 @@ export function showCreateEditCalendarDialog({
})
.catch((e) => Dialog.message(lang.makeTranslation("error_message", e.message)))
},
class: errorMessageStream().trim() !== "" ? "mt-s no-hover button-bg" : "mt-s",
class: errorMessageStream().trim() !== "" ? "mt-s no-hover disabled-button" : "mt-s",
disabled: errorMessageStream().trim() !== "",
}),
]),

View file

@ -9,7 +9,6 @@ import { ExpanderPanel } from "../../../../common/gui/base/Expander.js"
import { theme } from "../../../../common/gui/theme.js"
import { px, size } from "../../../../common/gui/size.js"
import { styles } from "../../../../common/gui/styles.js"
import { hexToRGBAString } from "../../../../common/gui/base/Color.js"
export interface DaySelectorAttrs {
selectedDate: Date | null
@ -148,8 +147,8 @@ export class DaySelector implements Component<DaySelectorAttrs> {
circleClass = "calendar-selected-day-circle"
textClass = "calendar-selected-day-text"
} else if (isToday(date) && attrs.highlightToday) {
circleClass = "calendar-current-day-circle"
textClass = "calendar-current-day-text"
circleClass = "calendar-current-day-circle-small"
textClass = "calendar-current-day-text-small"
}
const size = this.getElementSize(attrs)
@ -197,7 +196,8 @@ export class DaySelector implements Component<DaySelectorAttrs> {
if (highlight) {
style = {
backgroundColor: hexToRGBAString(theme.primary, 0.2),
backgroundColor: theme.secondary_container,
color: theme.on_secondary_container,
height: px(styles.isDesktopLayout() ? 19 : 25),
borderRadius: px(styles.isDesktopLayout() ? 6 : 25),
width: `calc(100% - ${px(size.hpad_small)})`,

View file

@ -101,7 +101,7 @@ export class AttendeeListEditor implements Component<AttendeeListEditorAttrs> {
m(IconMessageBox, {
message: "noEntries_msg",
icon: Icons.People,
color: theme.on_surface_fade,
color: theme.on_surface_variant,
}),
]),
)

View file

@ -146,6 +146,7 @@ export class EventEditorDialog {
{
height: "100%",
"background-color": theme.surface_container,
color: theme.on_surface_variant,
},
)
.addShortcut({

View file

@ -232,7 +232,7 @@ export class EventPreviewView implements Component<EventPreviewViewAttrs> {
ariaLabel: lang.get("addComment_label"),
placeholder: lang.get("addComment_label"),
style: {
borderColor: theme.content_button,
borderColor: theme.outline,
},
} satisfies ExpandableTextAreaAttrs)
}

View file

@ -46,7 +46,7 @@ export class CalendarSearchListView implements Component<CalendarSearchListViewA
? m(ColumnEmptyMessageBox, {
icon,
message: "searchNoResults_msg",
color: theme.on_surface_fade,
color: theme.on_surface_variant,
})
: m(List, {
state: attrs.listModel.state,

View file

@ -224,7 +224,7 @@ export class CalendarSearchView extends BaseTopLevelView implements TopLevelView
? m(ColumnEmptyMessageBox, {
message: "noEventSelect_msg",
icon: BootIcons.Calendar,
color: theme.on_surface_fade,
color: theme.on_surface_variant,
backgroundColor: theme.surface_container,
})
: !this.getSanitizedPreviewData(selectedEvent).isLoaded()

View file

@ -1,13 +1,11 @@
import m, { Children, Component, Vnode } from "mithril"
import { CalendarEvent } from "../../../common/api/entities/tutanota/TypeRefs.js"
import { stateBgFocus, stateBgHover } from "../../../common/gui/builtinThemes.js"
import { theme } from "../../../common/gui/theme.js"
import { styles } from "../../../common/gui/styles.js"
import { DefaultAnimationTime } from "../../../common/gui/animation/Animations.js"
import { px } from "../../../common/gui/size.js"
import { TabIndex } from "../../../common/api/common/TutanotaConstants.js"
import { getDisplayEventTitle } from "../gui/CalendarGuiUtils.js"
import { isBirthdayEvent } from "../../../common/calendar/date/CalendarUtils.js"
export interface CalendarAgendaItemViewAttrs {
day: Date
@ -59,10 +57,10 @@ export class CalendarAgendaItemView implements Component<CalendarAgendaItemViewA
private static getBackground(isSelected: boolean, isFocused: boolean) {
if (styles.isDesktopLayout()) {
if (isSelected) {
return stateBgHover
return theme.state_bg_hover
} else {
if (isFocused) {
return stateBgFocus
return theme.state_bg_focus
} else {
return theme.surface
}

View file

@ -161,7 +161,7 @@ export class CalendarAgendaView implements Component<CalendarAgendaViewAttrs> {
return m(ColumnEmptyMessageBox, {
icon: BootIcons.Calendar,
message: "noEntries_msg",
color: theme.on_surface_fade,
color: theme.on_surface_variant,
})
} else {
return m(".flex.mb-s.col", this.renderEventsForDay(events, getTimeZone(), attrs.selectedDate, attrs))
@ -195,7 +195,7 @@ export class CalendarAgendaView implements Component<CalendarAgendaViewAttrs> {
return m(ColumnEmptyMessageBox, {
icon: BootIcons.Calendar,
message: "noEntries_msg",
color: theme.on_surface_fade,
color: theme.on_surface_variant,
bottomContent: !client.isCalendarApp()
? m(MainCreateButton, {
label: "newEvent_action",
@ -262,7 +262,7 @@ export class CalendarAgendaView implements Component<CalendarAgendaViewAttrs> {
m(ColumnEmptyMessageBox, {
icon: BootIcons.Calendar,
message: "noEventSelect_msg",
color: theme.on_surface_fade,
color: theme.on_surface_variant,
}),
)
: this.renderEventPreview(attrs),

View file

@ -338,7 +338,7 @@ export class MultiDayCalendarView implements Component<MultiDayCalendarViewAttrs
"line-height": isDesktopLayout ? px(size.calendar_hour_height) : "unset",
width: px(width),
height: px(size.calendar_hour_height),
"border-right": `1px solid ${theme.outline}`,
"border-right": `1px solid ${theme.outline_variant}`,
},
},
isDesktopLayout ? formatTime(time.toDate()) : formatShortTime(time.toDate()),

View file

@ -218,7 +218,7 @@ export class TimeView implements Component<TimeViewAttributes> {
"border-top-right-radius": event.event.startTime < timeRangeAsDate.start ? "0" : undefined,
"border-bottom-left-radius": event.event.endTime > timeRangeAsDate.end ? "0" : undefined,
"border-bottom-right-radius": event.event.endTime > timeRangeAsDate.end ? "0" : undefined,
border: event.featured ? `1.5px dashed ${theme.on_success_container}` : "none",
border: event.featured ? `1.5px dashed ${hasAnyConflict ? theme.on_warning_container : theme.on_success_container}` : "none",
"border-top": event.event.startTime < timeRangeAsDate.start ? "none" : undefined,
"border-bottom": event.event.endTime > timeRangeAsDate.end ? "none" : undefined,
"-webkit-line-clamp": 2,
@ -227,15 +227,19 @@ export class TimeView implements Component<TimeViewAttributes> {
event.featured
? m(".flex.items-start", [
m(Icon, {
icon: hasAnyConflict ? Icons.ExclamationMark : Icons.Checkmark,
icon: hasAnyConflict ? Icons.AlertCircle : Icons.Checkmark,
container: "div",
class: "mr-xxs",
size: IconSize.Normal,
style: {
fill: hasAnyConflict ? theme.on_error_container : theme.on_success_container,
fill: hasAnyConflict ? theme.on_warning_container : theme.on_success_container,
},
}),
m(".break-word.b.text-ellipsis-multi-line.lh", { style: { "-webkit-line-clamp": 2 } }, event.event.summary),
m(
".break-word.b.text-ellipsis-multi-line.lh",
{ style: { "-webkit-line-clamp": 2, color: hasAnyConflict ? theme.on_warning_container : theme.on_success_container } },
event.event.summary,
),
])
: event.event.summary,
)

View file

@ -1,11 +1,9 @@
import { DrawerMenu, DrawerMenuAttrs } from "./nav/DrawerMenu.js"
import { theme } from "./theme.js"
import m, { Children, Component, Vnode } from "mithril"
import type { TranslationKey, MaybeTranslation } from "../misc/LanguageViewModel.js"
import type { MaybeTranslation, TranslationKey } from "../misc/LanguageViewModel.js"
import { lang } from "../misc/LanguageViewModel.js"
import { AriaLandmarks, landmarkAttrs } from "./AriaUtils.js"
import type { ClickHandler } from "./base/GuiUtils.js"
import type { lazy } from "@tutao/tutanota-utils"
import { MainCreateButton } from "./MainCreateButton.js"
export type Attrs = {
@ -22,31 +20,14 @@ export class FolderColumnView implements Component<Attrs> {
m(DrawerMenu, attrs.drawer),
m(".folder-column.flex-grow.overflow-x-hidden.flex.col", landmarkAttrs(AriaLandmarks.Navigation, lang.getTranslationText(attrs.ariaLabel)), [
this.renderMainButton(attrs),
m(
".scroll.scrollbar-gutter-stable-or-fallback.visible-scrollbar.overflow-x-hidden.flex.col.flex-grow",
{
onscroll: (e: EventRedraw<Event>) => {
e.redraw = false
const target = e.target as HTMLElement
if (attrs.button == null || target.scrollTop === 0) {
target.style.borderTop = ""
} else {
target.style.borderTop = `1px solid ${theme.outline}`
}
},
},
attrs.content,
),
m(".scroll.scrollbar-gutter-stable-or-fallback.visible-scrollbar.overflow-x-hidden.flex.col.flex-grow", attrs.content),
]),
])
}
private renderMainButton(attrs: Attrs): Children {
if (attrs.button) {
return m(
".plr-button-double.scrollbar-gutter-stable-or-fallback.scroll",
m(MainCreateButton, { label: attrs.button.label, click: attrs.button.click }),
)
return m(".plr-button-double.scrollbar-gutter-stable-or-fallback", m(MainCreateButton, { label: attrs.button.label, click: attrs.button.click }))
} else {
return null
}

View file

@ -4,6 +4,7 @@ import m, { Children, Component, Vnode } from "mithril"
import { theme } from "./theme.js"
import { px, size } from "./size.js"
import { BaseButton, BaseButtonAttrs } from "./base/buttons/BaseButton.js"
import { boxShadowLow } from "./main-styles.js"
export interface MainCreateButtonAttrs {
label: TranslationKey
@ -22,10 +23,11 @@ export class MainCreateButton implements Component<MainCreateButtonAttrs> {
onclick: vnode.attrs.click,
class: `full-width border-radius-big center b flash ${vnode.attrs.class}`,
style: {
border: `2px solid ${theme.primary}`,
// matching toolbar
height: px(size.button_height + size.vpad_xs * 2),
color: theme.primary,
"background-color": theme.primary_container,
color: theme.on_primary_container,
"box-shadow": boxShadowLow,
},
} satisfies BaseButtonAttrs)
}

View file

@ -111,7 +111,7 @@ export const MobileHeaderMenuButton = pureComponent(({ newsModel, backAction }:
top: px(4),
right: px(5),
},
color: "white",
color: theme.on_primary,
background: theme.primary,
}),
])

View file

@ -1,5 +1,4 @@
import m, { ClassComponent, Vnode } from "mithril"
import { stateBgActive, stateBgHover } from "./builtinThemes.js"
import { theme } from "./theme.js"
import { styles } from "./styles.js"
import { px, size } from "./size.js"
@ -44,19 +43,19 @@ export class SelectableRowContainer implements ClassComponent<SelectableRowConta
// Highlight the row when it is tabbed into
onfocus: () => {
if (SelectableRowContainer.isUsingKeyboard()) {
this.setBackground(stateBgActive)
this.setBackground(theme.state_bg_active)
}
},
onblur: () => {
if (SelectableRowContainer.isUsingKeyboard()) {
if (this.selected && !styles.isSingleColumnLayout()) {
this.setBackground(stateBgHover)
this.setBackground(theme.state_bg_hover)
} else {
this.setBackground(theme.surface)
}
}
},
onpointerdown: () => this.setBackground(stateBgActive),
onpointerdown: () => this.setBackground(theme.state_bg_active),
onpointerup: this.updateDomBg,
onpointercancel: this.updateDomBg,
onpointerleave: this.updateDomBg,
@ -78,7 +77,7 @@ export class SelectableRowContainer implements ClassComponent<SelectableRowConta
// In the single column view, a row may be 'selected' by the URL still linking to a specific mail
// So do not highlight in that case but in just multiselect mode and keyboard navigation
const highlight = styles.isSingleColumnLayout() ? (this.isInMultiselect || isUsingKeyboard) && this.selected : this.selected
this.setBackground(highlight ? stateBgHover : theme.surface)
this.setBackground(highlight ? theme.state_bg_hover : theme.surface)
}
}

View file

@ -5,8 +5,8 @@ import Stream from "mithril/stream"
import { assertMainOrNodeBoot, isApp, isDesktop } from "../api/common/Env"
import { downcast, findAndRemove, LazyLoaded, mapAndFilterNull, typedValues } from "@tutao/tutanota-utils"
import m from "mithril"
import { BaseThemeId, Theme, ThemeId, ThemePreference } from "./theme"
import { logoDefaultGrey, themes } from "./builtinThemes"
import { BaseThemeId, theme, Theme, ThemeId, ThemePreference } from "./theme"
import { themes } from "./builtinThemes"
import { getWhitelabelCustomizations, ThemeCustomizations } from "../misc/WhitelabelCustomizations"
import { getCalendarLogoSvg, getMailLogoSvg } from "./base/Logo"
import { ThemeFacade } from "../native/common/generatedipc/ThemeFacade"
@ -293,10 +293,8 @@ export class ThemeController {
// This is a whitelabel theme where logo has not been overwritten.
// Generate a logo with muted colors. We do not want to color our logo in
// some random color.
const grayedLogo =
this.app === AppType.Calendar
? getCalendarLogoSvg(logoDefaultGrey, logoDefaultGrey, logoDefaultGrey)
: getMailLogoSvg(logoDefaultGrey, logoDefaultGrey, logoDefaultGrey)
const logoDefaultGrey = "#c5c7c7"
const grayedLogo = this.app === AppType.Calendar ? getCalendarLogoSvg(logoDefaultGrey) : getMailLogoSvg(logoDefaultGrey)
return { ...themeWithoutLogo, ...{ logo: grayedLogo } }
}
}
@ -379,7 +377,7 @@ const oldToNewColorTokenMap: Record<string, keyof Theme> = {
content_button_icon_selected: "on_primary",
content_accent: "primary",
content_border: "outline",
content_message_bg: "on_surface_fade",
content_message_bg: "on_surface_variant",
header_bg: "surface",
header_box_shadow_bg: "outline",
header_button: "on_surface_variant",
@ -387,7 +385,7 @@ const oldToNewColorTokenMap: Record<string, keyof Theme> = {
list_bg: "surface",
list_alternate_bg: "surface_container",
list_accent_fg: "primary",
list_message_bg: "on_surface_fade",
list_message_bg: "on_surface_variant",
list_border: "outline_variant",
modal_bg: "scrim",
elevated_bg: "surface",
@ -407,11 +405,10 @@ const newToOldColorTokenMap: Partial<Record<keyof Theme, string[]>> = {
on_secondary: ["button_bubble_fg", "navigation_menu_icon"],
surface: ["content_bg", "header_bg", "list_bg", "elevated_bg"],
on_surface: ["content_fg"],
on_surface_variant: ["content_button", "header_button", "navigation_button"],
on_surface_variant: ["content_button", "header_button", "navigation_button", "content_message_bg", "list_message_bg"],
primary: ["content_accent", "content_button_selected", "header_button_selected", "list_accent_fg", "navigation_button_selected"],
on_primary: ["content_button_icon", "content_button_icon_selected", "navigation_button_icon", "navigation_button_icon_selected"],
outline: ["content_border", "header_box_shadow_bg"],
on_surface_fade: ["content_message_bg", "list_message_bg"],
surface_container: ["list_alternate_bg", "navigation_bg"],
outline_variant: ["list_border", "navigation_border"],
scrim: ["modal_bg"],

View file

@ -5,6 +5,6 @@ type BadgeAttrs = {
}
export default class Badge implements Component<BadgeAttrs> {
view(vnode: Vnode<BadgeAttrs>): Children {
return m(".b.teamLabel.pl-s.pr-s.border-radius.no-wrap" + (vnode.attrs.classes || ""), vnode.children)
return m(".teamLabel.pl-s.pr-s.border-radius.no-wrap" + (vnode.attrs.classes || ""), vnode.children)
}
}

View file

@ -30,37 +30,37 @@ export function getColors(buttonColors: ButtonColor | null | undefined): {
switch (buttonColors) {
case ButtonColor.Nav:
return {
button: theme.on_surface_variant,
button: theme.on_surface,
border: theme.surface_container,
}
case ButtonColor.DrawerNav:
return {
button: theme.on_surface_variant,
button: theme.on_surface,
border: getElevatedBackground(),
}
case ButtonColor.Elevated:
return {
button: theme.on_surface_variant,
button: theme.on_surface,
border: getElevatedBackground(),
}
case ButtonColor.Fab:
return {
button: theme.surface,
button: theme.on_primary,
border: getElevatedBackground(),
}
case ButtonColor.Dialog:
return {
button: theme.content_button,
border: theme.content_border,
button: theme.on_surface,
border: theme.outline,
}
case ButtonColor.Content:
default:
return {
button: theme.on_surface_variant,
button: theme.on_surface,
border: theme.surface,
}
}

View file

@ -20,7 +20,7 @@ export type InfoMessaggeBoxAttrs = {
/** Displays a big message with an option icon above it. */
export class IconMessageBox implements Component<InfoMessaggeBoxAttrs> {
view({ attrs }: Vnode<InfoMessaggeBoxAttrs>): Children {
return m(".flex.col.items-center.justify-center.mlr", [
return m(".flex.col.items-center.justify-center.mlr.translucent", [
attrs.icon
? m(Icon, {
icon: attrs.icon,

View file

@ -120,7 +120,7 @@ export class ExpandableTextArea implements ClassComponent<ExpandableTextAreaAttr
bottom: this.initialHeight === 0 ? 0 : undefined,
margin: this.initialHeight === 0 ? "auto 0" : undefined,
right: "8px",
fill: theme.content_button,
fill: theme.on_surface_variant,
transform: `rotateZ(${this.isExpanded ? 180 : 0}deg)`,
transition: `transform ${DefaultAnimationTime}ms`,
},

View file

@ -2,7 +2,6 @@ import m, { Children, Component, Vnode, VnodeDOM } from "mithril"
import { AllIcons, Icon } from "./Icon"
import { BootIcons } from "./icons/BootIcons"
import { theme } from "../theme"
import { on_secondary_fixed, secondary_fixed } from "../builtinThemes"
import { ClickHandler } from "./GuiUtils"
import { assertNotNull } from "@tutao/tutanota-utils"
import { lang, Translation } from "../../misc/LanguageViewModel"
@ -32,7 +31,7 @@ export class FilterChip implements Component<FilterChipAttrs> {
selectors += ".pr-vpad-m"
}
const contentColor = selected ? on_secondary_fixed : theme.on_surface
const contentColor = selected ? theme.on_secondary_container : theme.on_surface
return m(
selectors,
{
@ -40,7 +39,7 @@ export class FilterChip implements Component<FilterChipAttrs> {
minHeight: px(size.button_icon_bg_size),
...(selected
? {
background: secondary_fixed,
background: theme.secondary_container,
color: contentColor,
"--state-bg-color": contentColor,
"border-color": "transparent",

View file

@ -1,8 +1,8 @@
import m, { Children, Component, Vnode } from "mithril"
import { AllIcons, Icon, IconSize } from "./Icon.js"
import { lang, MaybeTranslation } from "../../misc/LanguageViewModel.js"
import { ButtonColor, getColors } from "./Button.js"
import { px } from "../size.js"
import { theme } from "../theme.js"
export interface IconSegmentControlItem<T> {
icon: AllIcons
@ -52,7 +52,7 @@ export class IconSegmentControl<T> implements Component<IconSegmentControlAttrs<
class: "center-h",
size: IconSize.Medium,
style: {
fill: getColors(ButtonColor.Content).button,
fill: item.value === vnode.attrs.selectedValue ? theme.on_secondary_container : theme.on_surface_variant,
},
}),
)

View file

@ -46,7 +46,7 @@ export class InfoBanner implements Component<InfoBannerAttrs> {
".center-vertically.border-bottom.pr-s.pl.border-radius.mt-xs",
{
style: {
border: `solid 2px ${type === BannerType.Warning ? theme.error : theme.outline}`,
border: `solid 2px ${type === BannerType.Warning ? theme.warning : theme.outline}`,
// keep the distance to the bottom of the banner the same in the case that buttons aren't present
minHeight: buttons.length > 0 ? undefined : px(37),
},
@ -69,7 +69,7 @@ export class InfoBanner implements Component<InfoBannerAttrs> {
return m(Icon, {
icon,
style: {
fill: type === BannerType.Warning ? theme.error : theme.on_surface_variant,
fill: type === BannerType.Warning ? theme.warning : theme.on_surface_variant,
display: "block",
},
})

View file

@ -7,7 +7,7 @@ import { theme, isDarkTheme } from "../theme.js"
const supportsRelativeHslColors = typeof CSS !== "undefined" ? CSS.supports("color", `hsl(from #ccc h calc(min(50, s)) l)`) : false
export function getLabelColor(backgroundColor: string | null): string {
const labelColor = backgroundColor ?? theme.content_accent
const labelColor = backgroundColor ?? theme.primary
// make a color have the same hue and lightness with saturation capped to 50
return isDarkTheme() ? limitedSaturationColor(labelColor) : labelColor
}

View file

@ -1,8 +1,32 @@
import { assertMainOrNodeBoot } from "../../api/common/Env"
import { assertMainOrNodeBoot, isApp } from "../../api/common/Env"
import { client } from "../../misc/ClientDetector.js"
import { isColorLight } from "./Color.js"
import { theme } from "../theme.js"
assertMainOrNodeBoot()
export function getTutaLogoSvg(highlightColor: string, textColor: string): string {
export function getTutaLogo(): string {
if (isColorLight(theme.surface)) {
return getTutaLogoSvg()
}
return getTutaLogoSvg("#fff")
}
export function getAppLogo(fillColor?: string) {
if (!isApp()) {
return getTutaLogoSvg(fillColor)
}
if (client.isCalendarApp()) {
return getCalendarLogoSvg(fillColor)
}
return getMailLogoSvg(fillColor)
}
export function getTutaLogoSvg(fillColor?: string): string {
const signetColor = fillColor ?? "#850122"
const textColor = fillColor ?? "#410002"
return `<svg version="1.1" id="tuta_x5F_rgb" xmlns="http://www.w3.org/2000/svg" x="0px"
y="0px" viewBox="0 0 279.5 100" style="enable-background:new 0 0 279.5 100;" xml:space="preserve">
<g>
@ -19,42 +43,50 @@ export function getTutaLogoSvg(highlightColor: string, textColor: string): strin
c5.8,0,10.6-2.6,14.2-7.9v6.3c0,0.5,0.3,0.8,0.8,0.8h6.9c0.5,0,0.7-0.2,0.9-0.7l14-45.2c0.1-0.5-0.1-0.9-0.6-0.9H257
c-21.3,0-29.6,18.5-29.6,30.5C227.4,69.7,233.9,76.3,242.6,76.3"/>
</g>
<path style="fill: ${highlightColor};" d="M7.9,1L25,18.3c0.4,0.4,0.8,0.5,1.4,0.5h72.1c0.5,0,0.8-0.6,0.3-1.1L81.9,0.6C81.5,0.2,81.1,0,80.3,0h-72
<path style="fill: ${signetColor};" d="M7.9,1L25,18.3c0.4,0.4,0.8,0.5,1.4,0.5h72.1c0.5,0,0.8-0.6,0.3-1.1L81.9,0.6C81.5,0.2,81.1,0,80.3,0h-72
C7.6,0,7.5,0.6,7.9,1"/>
<path style="fill: ${highlightColor};" d="M5.4,99.2C5.3,99.6,5.5,100,6,100h71.1c0.7,0,1-0.3,1.2-0.9l21.5-69.4c0.2-0.7-0.1-0.9-0.7-0.9H27.8
<path style="fill: ${signetColor};" d="M5.4,99.2C5.3,99.6,5.5,100,6,100h71.1c0.7,0,1-0.3,1.2-0.9l21.5-69.4c0.2-0.7-0.1-0.9-0.7-0.9H27.8
c-0.6,0-0.8,0.2-1,0.7L5.4,99.2z"/>
<path style="fill: ${highlightColor};" d="M0,79.2c0,0.8,1,0.8,1.2,0l16.3-53.1c0.2-0.6,0.2-1-0.3-1.5L1,8.5C0.6,8.1,0,8.3,0,8.8V79.2z"/>
<path style="fill: ${signetColor};" d="M0,79.2c0,0.8,1,0.8,1.2,0l16.3-53.1c0.2-0.6,0.2-1-0.3-1.5L1,8.5C0.6,8.1,0,8.3,0,8.8V79.2z"/>
</g>
</svg>`
}
export function getMailLogoSvg(highlightColor: string, secondaryColor: string, textColor: string): string {
export function getMailLogoSvg(fillColor?: string): string {
const signetCharColor = fillColor ?? "#850122"
const signetSwitchColor = fillColor ?? "#FF2222"
const textColor = fillColor ?? "#000000"
return `<svg x="0px" y="0px" viewBox="0 0 1408 309" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M305.76 89.5037H264.83C264.319 89.5037 263.865 89.674 263.467 90.0714L161.736 188.623C160.771 189.531 159.125 189.248 158.614 187.999L129.037 90.5823C128.753 89.8443 128.072 89.3901 127.277 89.3901H85.3814C84.5299 89.3901 83.7918 89.9578 83.508 90.7526L17.5987 306.193C17.2013 307.442 18.1664 308.634 19.4721 308.634H62.4465C63.2981 308.634 64.0361 308.066 64.3199 307.271L106.045 171.025C106.613 169.322 108.941 169.151 109.679 170.854L138.177 236.082C138.461 236.764 139.142 237.275 139.937 237.275H163.156C163.666 237.275 164.121 237.104 164.518 236.707L233.266 169.265C234.685 167.845 237.013 169.322 236.445 171.195L195.117 306.249C194.776 307.498 195.684 308.69 196.99 308.69H240.021C240.873 308.69 241.611 308.123 241.895 307.328L307.804 91.9448C308.145 90.6958 307.236 89.5037 305.931 89.5037H305.76Z" fill="${highlightColor}"/>
<path d="M52.9091 75.4818L3.17909 25.9788C2.55462 25.4111 1.81662 25.4679 1.75985 25.4679C0.794772 25.4679 0 26.2627 0 27.2277V244.882C0 245.847 0.794772 246.642 1.75985 246.642C2.49786 246.642 3.17909 246.131 3.40617 245.449C3.46294 245.393 3.46294 245.279 3.51971 245.166C3.51971 245.109 3.63324 244.655 3.63324 244.598L53.8174 80.0233C54.4419 78.2635 54.4419 77.0145 52.9091 75.4818Z" fill="${secondaryColor}"/>
<path d="M24.5247 4.34958L76.8661 57.3155C78.115 58.5644 79.3072 58.8482 81.1806 58.8482H305.988C307.52 58.8482 308.372 56.8613 306.896 55.4421L254.952 2.87357C252.681 0.659564 252.511 1.00018 250.013 1.00018H25.7168C24.7517 1.00018 23.957 1.79495 23.957 2.76003C23.957 2.8168 23.9002 3.61157 24.5814 4.29281C24.5247 4.23604 24.5247 4.29281 24.5814 4.29281L24.5247 4.34958Z" fill="${secondaryColor}"/>
<path d="M305.76 89.5037H264.83C264.319 89.5037 263.865 89.674 263.467 90.0714L161.736 188.623C160.771 189.531 159.125 189.248 158.614 187.999L129.037 90.5823C128.753 89.8443 128.072 89.3901 127.277 89.3901H85.3814C84.5299 89.3901 83.7918 89.9578 83.508 90.7526L17.5987 306.193C17.2013 307.442 18.1664 308.634 19.4721 308.634H62.4465C63.2981 308.634 64.0361 308.066 64.3199 307.271L106.045 171.025C106.613 169.322 108.941 169.151 109.679 170.854L138.177 236.082C138.461 236.764 139.142 237.275 139.937 237.275H163.156C163.666 237.275 164.121 237.104 164.518 236.707L233.266 169.265C234.685 167.845 237.013 169.322 236.445 171.195L195.117 306.249C194.776 307.498 195.684 308.69 196.99 308.69H240.021C240.873 308.69 241.611 308.123 241.895 307.328L307.804 91.9448C308.145 90.6958 307.236 89.5037 305.931 89.5037H305.76Z" fill="${signetCharColor}"/>
<path d="M52.9091 75.4818L3.17909 25.9788C2.55462 25.4111 1.81662 25.4679 1.75985 25.4679C0.794772 25.4679 0 26.2627 0 27.2277V244.882C0 245.847 0.794772 246.642 1.75985 246.642C2.49786 246.642 3.17909 246.131 3.40617 245.449C3.46294 245.393 3.46294 245.279 3.51971 245.166C3.51971 245.109 3.63324 244.655 3.63324 244.598L53.8174 80.0233C54.4419 78.2635 54.4419 77.0145 52.9091 75.4818Z" fill="${signetSwitchColor}"/>
<path d="M24.5247 4.34958L76.8661 57.3155C78.115 58.5644 79.3072 58.8482 81.1806 58.8482H305.988C307.52 58.8482 308.372 56.8613 306.896 55.4421L254.952 2.87357C252.681 0.659564 252.511 1.00018 250.013 1.00018H25.7168C24.7517 1.00018 23.957 1.79495 23.957 2.76003C23.957 2.8168 23.9002 3.61157 24.5814 4.29281C24.5247 4.23604 24.5247 4.29281 24.5814 4.29281L24.5247 4.34958Z" fill="${signetSwitchColor}"/>
<path d="M753.387 179.767C753.387 152.688 773.767 120.386 808.51 120.386H834.057L824.917 149.906C814.244 185.274 797.213 207.13 776.492 207.13C761.562 207.13 753.33 196.684 753.33 179.767H753.387ZM623.385 165.007C610.612 206.562 630.084 235.174 674.251 235.174C680.666 235.174 689.181 234.55 691.622 233.925C692.814 233.641 693.439 233.017 694.063 231.484L701.67 205.654C701.954 204.121 701.67 202.872 699.513 203.213C692.814 203.837 686.74 204.462 681.233 204.462C659.036 204.462 649.897 192.483 656.595 170.911L672.093 120.443H717.168C718.36 120.443 719.326 119.819 719.893 118.286L727.784 92.1151C728.068 90.5823 727.5 89.674 725.627 89.674H681.46L687.251 70.5994C687.535 69.3505 687.251 68.4422 686.342 67.5339L662.897 46.0183C661.705 44.7693 660.172 45.11 659.547 46.9266L623.328 165.064L623.385 165.007ZM468.121 165.915C455.007 208.095 476.012 235.742 508.938 235.742C527.842 235.742 542.716 226.488 553.388 211.444L553.105 230.803C553.105 232.676 554.013 233.244 555.546 233.244H576.55C578.083 233.244 578.708 232.619 579.275 231.087L621.569 92.3421C622.193 90.4688 621.285 89.5604 619.752 89.5604H589.607C588.075 89.5604 587.166 90.1849 586.882 91.7177L568.943 150.19C557.703 186.523 540.048 207.13 521.427 207.13C502.807 207.13 494.916 192.37 501.955 169.605L525.685 92.3989C526.309 90.5255 525.401 89.6172 523.868 89.6172H493.724C492.191 89.6172 491.567 90.2417 490.999 91.7744L468.178 165.915H468.121ZM365.538 165.007C352.765 206.562 372.237 235.174 416.404 235.174C422.819 235.174 431.334 234.55 433.775 233.925C434.967 233.641 435.592 233.017 436.216 231.484L443.823 205.654C444.107 204.121 443.823 202.872 441.666 203.213C434.967 203.837 428.893 204.462 423.386 204.462C401.19 204.462 392.05 192.483 398.748 170.911L414.247 120.443H459.322C460.514 120.443 461.763 119.819 462.046 118.286L469.937 92.1151C470.221 90.5823 469.654 89.674 467.78 89.674H423.33L429.12 70.5994C429.404 69.3505 429.12 68.4422 428.212 67.5339L404.766 46.0183C403.574 44.7693 402.041 45.11 401.417 46.9266L365.482 165.064L365.538 165.007ZM765.593 235.799C783.248 235.799 797.838 227.794 808.851 211.501V230.86C808.851 232.392 809.759 233.301 811.292 233.301H832.297C833.829 233.301 834.454 232.676 835.022 231.143L877.656 92.0583C877.939 90.5255 877.372 89.2766 875.839 89.2766H809.475C744.645 89.2766 719.382 146.216 719.382 183.116C719.382 215.418 739.195 235.742 765.649 235.742L765.593 235.799Z" fill="${textColor}"/>
<path d="M953.935 233.068H928.471C927.471 233.068 926.647 232.245 926.647 231.245V91.159C926.647 90.1593 927.471 89.3359 928.471 89.3359H948.584C949.29 89.3359 949.936 89.7476 950.23 90.3357L954.582 99.2161C955.17 100.392 956.641 100.569 957.523 99.6277C960.757 96.2167 964.463 93.2762 968.638 90.6298C973.637 87.5128 979.753 85.9837 986.928 85.9837C989.751 85.9837 992.868 86.3366 996.397 87.0423C999.925 87.748 1003.51 88.9243 1007.22 90.6298C1010.92 92.3353 1014.45 94.6289 1017.86 97.5106C1020.57 99.8042 1022.98 102.686 1025.04 106.097C1025.74 107.273 1027.39 107.332 1028.15 106.097C1031.51 100.98 1036.09 96.5108 1042.03 92.6881C1048.91 88.1597 1056.32 85.9249 1064.09 85.9249C1069.26 85.9249 1074.79 86.6895 1080.61 88.3361C1086.38 89.924 1091.85 92.9234 1096.79 97.3341C1101.78 101.745 1105.9 107.861 1109.08 115.624C1112.25 123.387 1113.9 133.502 1113.9 145.911V231.128C1113.9 232.127 1113.08 232.951 1112.08 232.951H1088.43C1087.43 232.951 1086.61 232.127 1086.61 231.128V145.617C1086.61 133.208 1084.02 124.563 1078.97 119.682C1073.85 114.801 1067.15 112.331 1058.74 112.331C1052.33 112.331 1046.74 115.036 1041.92 120.447C1037.09 125.857 1034.68 134.385 1034.68 145.97V231.186C1034.68 232.186 1033.86 233.01 1032.86 233.01H1009.22C1008.22 233.01 1007.39 232.186 1007.39 231.186V145.676C1007.39 133.267 1004.81 124.622 999.749 119.741C994.632 114.86 987.928 112.39 979.518 112.39C973.519 112.39 968.285 114.683 963.757 119.329C959.228 123.916 956.582 131.15 955.817 140.913V231.245C955.817 232.245 954.994 233.068 953.994 233.068H953.935Z" fill="${highlightColor}"/>
<path d="M1284.39 91.1593V231.246C1284.39 232.245 1283.57 233.069 1282.57 233.069H1261.16C1260.34 233.069 1259.63 232.539 1259.4 231.716L1256.22 219.954C1255.81 218.542 1254.04 218.19 1253.04 219.307C1248.4 224.6 1242.75 228.658 1236.05 231.598C1228.23 235.009 1220.35 236.715 1212.35 236.715C1202.35 236.715 1193 234.774 1184.3 230.893C1175.59 227.011 1168.01 221.659 1161.48 214.837C1154.95 208.015 1149.83 200.017 1146.01 190.843C1142.19 181.61 1140.31 171.847 1140.31 161.438C1140.31 151.028 1142.19 141.266 1146.01 132.032C1149.83 122.799 1154.95 114.801 1161.48 108.038C1168.01 101.275 1175.59 95.8641 1184.3 91.9826C1193 88.1011 1202.35 86.1604 1212.35 86.1604C1220.35 86.1604 1228.05 87.6895 1235.46 90.8064C1241.93 93.5117 1247.81 97.5696 1253.1 102.98C1254.1 103.98 1255.75 103.627 1256.16 102.274L1259.4 90.7476C1259.63 89.9831 1260.34 89.395 1261.16 89.395H1282.57C1283.57 89.395 1284.39 90.2183 1284.39 91.2181V91.1593ZM1212.35 210.897C1218.11 210.897 1223.64 209.603 1228.87 207.016C1234.05 204.428 1238.58 200.841 1242.4 196.371C1246.16 191.901 1249.16 186.608 1251.4 180.61C1253.57 174.611 1254.69 168.201 1254.69 161.379C1254.69 154.557 1253.57 148.205 1251.4 142.148C1249.22 136.149 1246.22 130.915 1242.4 126.387C1238.58 121.917 1234.11 118.33 1228.87 115.742C1223.64 113.154 1218.17 111.861 1212.35 111.861C1206.53 111.861 1201.06 113.154 1195.82 115.742C1190.59 118.33 1186.12 121.917 1182.3 126.387C1178.47 130.915 1175.47 136.149 1173.3 142.148C1171.12 148.146 1170 154.557 1170 161.379C1170 168.201 1171.12 174.611 1173.3 180.61C1175.47 186.608 1178.47 191.843 1182.3 196.371C1186.06 200.899 1190.59 204.428 1195.82 207.016C1201.06 209.603 1206.53 210.897 1212.35 210.897Z" fill="${highlightColor}"/>
<path d="M1329.67 58.1078C1323.91 58.1078 1319.15 55.873 1315.33 51.3446C1312.91 48.4629 1311.38 44.7579 1311.15 40.994C1310.68 34.9954 1312.5 30.0553 1316.5 26.0562C1320.09 22.4688 1324.5 20.6456 1329.73 20.6456C1334.97 20.6456 1339.32 22.4688 1342.97 26.0562C1346.97 30.0553 1348.73 35.0542 1348.32 40.994C1348.02 44.7579 1346.55 48.4629 1344.14 51.3446C1340.32 55.873 1335.56 58.1078 1329.79 58.1078H1329.67ZM1342.85 233.069H1317.09C1316.09 233.069 1315.27 232.245 1315.27 231.245V91.1592C1315.27 90.1595 1316.09 89.3361 1317.09 89.3361H1342.55C1343.55 89.3361 1344.38 90.1595 1344.38 91.1592L1344.67 231.245C1344.67 232.245 1343.85 233.069 1342.85 233.069Z" fill="${highlightColor}"/>
<path d="M1407.72 15.8231V231.245C1407.72 232.245 1406.89 233.069 1405.89 233.069H1380.43C1379.43 233.069 1378.6 232.245 1378.6 231.245V15.8231C1378.6 14.8233 1379.43 14 1380.43 14H1405.89C1406.89 14 1407.72 14.8233 1407.72 15.8231Z" fill="${highlightColor}"/>
<path d="M953.935 233.068H928.471C927.471 233.068 926.647 232.245 926.647 231.245V91.159C926.647 90.1593 927.471 89.3359 928.471 89.3359H948.584C949.29 89.3359 949.936 89.7476 950.23 90.3357L954.582 99.2161C955.17 100.392 956.641 100.569 957.523 99.6277C960.757 96.2167 964.463 93.2762 968.638 90.6298C973.637 87.5128 979.753 85.9837 986.928 85.9837C989.751 85.9837 992.868 86.3366 996.397 87.0423C999.925 87.748 1003.51 88.9243 1007.22 90.6298C1010.92 92.3353 1014.45 94.6289 1017.86 97.5106C1020.57 99.8042 1022.98 102.686 1025.04 106.097C1025.74 107.273 1027.39 107.332 1028.15 106.097C1031.51 100.98 1036.09 96.5108 1042.03 92.6881C1048.91 88.1597 1056.32 85.9249 1064.09 85.9249C1069.26 85.9249 1074.79 86.6895 1080.61 88.3361C1086.38 89.924 1091.85 92.9234 1096.79 97.3341C1101.78 101.745 1105.9 107.861 1109.08 115.624C1112.25 123.387 1113.9 133.502 1113.9 145.911V231.128C1113.9 232.127 1113.08 232.951 1112.08 232.951H1088.43C1087.43 232.951 1086.61 232.127 1086.61 231.128V145.617C1086.61 133.208 1084.02 124.563 1078.97 119.682C1073.85 114.801 1067.15 112.331 1058.74 112.331C1052.33 112.331 1046.74 115.036 1041.92 120.447C1037.09 125.857 1034.68 134.385 1034.68 145.97V231.186C1034.68 232.186 1033.86 233.01 1032.86 233.01H1009.22C1008.22 233.01 1007.39 232.186 1007.39 231.186V145.676C1007.39 133.267 1004.81 124.622 999.749 119.741C994.632 114.86 987.928 112.39 979.518 112.39C973.519 112.39 968.285 114.683 963.757 119.329C959.228 123.916 956.582 131.15 955.817 140.913V231.245C955.817 232.245 954.994 233.068 953.994 233.068H953.935Z" fill="${signetCharColor}"/>
<path d="M1284.39 91.1593V231.246C1284.39 232.245 1283.57 233.069 1282.57 233.069H1261.16C1260.34 233.069 1259.63 232.539 1259.4 231.716L1256.22 219.954C1255.81 218.542 1254.04 218.19 1253.04 219.307C1248.4 224.6 1242.75 228.658 1236.05 231.598C1228.23 235.009 1220.35 236.715 1212.35 236.715C1202.35 236.715 1193 234.774 1184.3 230.893C1175.59 227.011 1168.01 221.659 1161.48 214.837C1154.95 208.015 1149.83 200.017 1146.01 190.843C1142.19 181.61 1140.31 171.847 1140.31 161.438C1140.31 151.028 1142.19 141.266 1146.01 132.032C1149.83 122.799 1154.95 114.801 1161.48 108.038C1168.01 101.275 1175.59 95.8641 1184.3 91.9826C1193 88.1011 1202.35 86.1604 1212.35 86.1604C1220.35 86.1604 1228.05 87.6895 1235.46 90.8064C1241.93 93.5117 1247.81 97.5696 1253.1 102.98C1254.1 103.98 1255.75 103.627 1256.16 102.274L1259.4 90.7476C1259.63 89.9831 1260.34 89.395 1261.16 89.395H1282.57C1283.57 89.395 1284.39 90.2183 1284.39 91.2181V91.1593ZM1212.35 210.897C1218.11 210.897 1223.64 209.603 1228.87 207.016C1234.05 204.428 1238.58 200.841 1242.4 196.371C1246.16 191.901 1249.16 186.608 1251.4 180.61C1253.57 174.611 1254.69 168.201 1254.69 161.379C1254.69 154.557 1253.57 148.205 1251.4 142.148C1249.22 136.149 1246.22 130.915 1242.4 126.387C1238.58 121.917 1234.11 118.33 1228.87 115.742C1223.64 113.154 1218.17 111.861 1212.35 111.861C1206.53 111.861 1201.06 113.154 1195.82 115.742C1190.59 118.33 1186.12 121.917 1182.3 126.387C1178.47 130.915 1175.47 136.149 1173.3 142.148C1171.12 148.146 1170 154.557 1170 161.379C1170 168.201 1171.12 174.611 1173.3 180.61C1175.47 186.608 1178.47 191.843 1182.3 196.371C1186.06 200.899 1190.59 204.428 1195.82 207.016C1201.06 209.603 1206.53 210.897 1212.35 210.897Z" fill="${signetCharColor}"/>
<path d="M1329.67 58.1078C1323.91 58.1078 1319.15 55.873 1315.33 51.3446C1312.91 48.4629 1311.38 44.7579 1311.15 40.994C1310.68 34.9954 1312.5 30.0553 1316.5 26.0562C1320.09 22.4688 1324.5 20.6456 1329.73 20.6456C1334.97 20.6456 1339.32 22.4688 1342.97 26.0562C1346.97 30.0553 1348.73 35.0542 1348.32 40.994C1348.02 44.7579 1346.55 48.4629 1344.14 51.3446C1340.32 55.873 1335.56 58.1078 1329.79 58.1078H1329.67ZM1342.85 233.069H1317.09C1316.09 233.069 1315.27 232.245 1315.27 231.245V91.1592C1315.27 90.1595 1316.09 89.3361 1317.09 89.3361H1342.55C1343.55 89.3361 1344.38 90.1595 1344.38 91.1592L1344.67 231.245C1344.67 232.245 1343.85 233.069 1342.85 233.069Z" fill="${signetCharColor}"/>
<path d="M1407.72 15.8231V231.245C1407.72 232.245 1406.89 233.069 1405.89 233.069H1380.43C1379.43 233.069 1378.6 232.245 1378.6 231.245V15.8231C1378.6 14.8233 1379.43 14 1380.43 14H1405.89C1406.89 14 1407.72 14.8233 1407.72 15.8231Z" fill="${signetCharColor}"/>
</svg>`
}
export function getCalendarLogoSvg(highlightColor: string, secondaryColor: string, textColor: string): string {
export function getCalendarLogoSvg(fillColor?: string): string {
const signetCharColor = fillColor ?? "#003E85"
const signetSwitchColor = fillColor ?? "#4282FF"
const textColor = fillColor ?? "#000000"
return `<svg x="0px" y="0px" viewBox="0 0 1999 308" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M753.202 178.742C753.202 151.67 773.577 119.376 808.311 119.376H833.851L824.714 148.889C814.044 184.247 797.017 206.098 776.301 206.098C761.375 206.098 753.145 195.655 753.145 178.742H753.202ZM623.232 163.986C610.462 205.53 629.929 234.135 674.085 234.135C680.498 234.135 689.011 233.511 691.452 232.887C692.644 232.603 693.268 231.979 693.892 230.446L701.498 204.622C701.781 203.09 701.498 201.841 699.341 202.182C692.644 202.806 686.571 203.431 681.066 203.431C658.874 203.431 649.737 191.455 656.434 169.888L671.928 119.433H716.992C718.184 119.433 719.149 118.808 719.716 117.276L727.605 91.1115C727.889 89.5792 727.321 88.6711 725.448 88.6711H681.293L687.082 69.6013C687.366 68.3526 687.082 67.4445 686.174 66.5365L662.734 45.0261C661.542 43.7775 660.009 44.1181 659.385 45.9342L623.175 164.042L623.232 163.986ZM468.006 164.894C454.895 207.063 475.895 234.703 508.813 234.703C527.713 234.703 542.582 225.452 553.253 210.411L552.969 229.765C552.969 231.638 553.877 232.206 555.409 232.206H576.409C577.941 232.206 578.565 231.581 579.133 230.049L621.416 91.3386C622.04 89.4656 621.132 88.5576 619.6 88.5576H589.462C587.93 88.5576 587.022 89.1819 586.738 90.7143L568.803 149.172C557.566 185.496 539.915 206.098 521.299 206.098C502.683 206.098 494.794 191.342 501.832 168.583L525.556 91.3953C526.18 89.5224 525.272 88.6143 523.74 88.6143H493.603C492.07 88.6143 491.446 89.2386 490.878 90.771L468.063 164.894H468.006ZM365.449 163.986C352.679 205.53 372.146 234.135 416.302 234.135C422.715 234.135 431.228 233.511 433.669 232.887C434.861 232.603 435.485 231.979 436.109 230.446L443.715 204.622C443.998 203.09 443.715 201.841 441.558 202.182C434.861 202.806 428.788 203.431 423.283 203.431C401.091 203.431 391.954 191.455 398.651 169.888L414.145 119.433H459.209C460.401 119.433 461.649 118.808 461.933 117.276L469.822 91.1115C470.106 89.5792 469.538 88.6711 467.665 88.6711H423.226L429.015 69.6013C429.299 68.3526 429.015 67.4445 428.107 66.5365L404.667 45.0261C403.475 43.7775 401.943 44.1181 401.318 45.9342L365.392 164.042L365.449 163.986ZM765.404 234.76C783.055 234.76 797.641 226.757 808.652 210.468V229.822C808.652 231.354 809.56 232.262 811.092 232.262H832.092C833.624 232.262 834.249 231.638 834.816 230.106L877.439 91.0548C877.723 89.5224 877.156 88.2738 875.623 88.2738H809.276C744.461 88.2738 719.205 145.199 719.205 182.091C719.205 214.384 739.013 234.703 765.461 234.703L765.404 234.76Z" fill="${textColor}"/>
<path d="M195.012 84.8116H84.5094C83.7716 84.8116 83.1472 85.2657 82.9202 85.9468C82.8635 86.2873 71.1719 124.767 71.1719 124.767C70.8313 126.016 71.7962 127.435 73.1583 127.492H121.23C122.99 127.492 124.181 129.762 122.876 130.897L76.1663 173.52C75.5988 174.031 75.4853 174.882 75.8826 175.62L88.1985 201.614C88.7093 202.749 89.9579 203.203 90.9795 202.749C95.6334 200.479 100.571 199.344 105.679 199.344C110.39 199.344 114.419 200.195 117.655 202.012C120.89 203.714 123.444 206.155 125.26 209.106C127.133 212.114 128.154 215.576 128.381 219.606C128.608 223.692 128.098 227.892 126.679 232.376C125.317 236.689 123.217 240.889 120.379 244.862C117.541 248.835 114.476 252.524 110.617 255.362C68.0503 285.669 43.5887 254.737 35.3024 248.892C34.1673 248.097 32.8619 248.438 32.4647 249.573L23.5541 277.269C23.4405 277.723 23.4405 278.177 23.6676 278.688C26.2783 284.25 29.7404 289.074 34.1106 293.218C38.9915 297.758 44.6671 301.277 51.2507 303.831C57.8343 306.442 65.2693 307.69 73.4421 307.69C83.9418 307.69 94.3848 305.647 104.828 301.674C115.214 297.701 124.919 292.139 134 285.215C142.967 278.177 150.97 270.118 157.894 260.98C164.762 251.843 169.87 242.024 173.218 231.524C177.304 218.811 178.269 206.949 176.169 195.939C174.069 184.928 169.132 175.847 161.356 168.639C156.362 164.212 150.175 161.034 142.74 158.991C141.208 158.537 140.527 156.721 141.492 155.756L190.926 106.606C190.926 106.606 191.21 106.152 191.266 105.925L197.055 87.7062C197.509 86.344 196.318 84.9252 194.955 84.9252L195.012 84.8116Z" fill="${highlightColor}"/>
<path d="M305.061 84.8116H236.841C235.99 84.8116 235.308 85.3224 235.081 86.0603L223.333 124.427C222.879 125.846 224.184 127.435 225.717 127.435H244.957C246.546 127.435 247.795 129.024 247.341 130.443L194.899 300.766C194.445 302.185 195.75 303.774 197.282 303.774H239.565C240.416 303.774 241.098 303.263 241.325 302.525L307.445 87.8197C307.899 86.4008 306.593 84.8116 305.004 84.8116H305.061Z" fill="${highlightColor}"/>
<path d="M52.8961 74.4249L3.1783 24.9909C2.55399 24.4233 1.81617 24.4801 1.75942 24.4801C0.794576 24.4801 0 25.2747 0 26.2395V243.67C0 244.634 0.794576 245.429 1.75942 245.429C2.49724 245.429 3.1783 244.918 3.40533 244.237C3.46208 244.18 3.46208 244.067 3.51884 243.953C3.51884 243.897 3.63235 243.443 3.63235 243.386L53.8041 78.9653C54.4284 77.2059 54.4284 75.9573 52.8961 74.4249Z" fill="${secondaryColor}"/>
<path d="M24.5747 3.36742L76.9032 56.3202C78.1518 57.5689 79.3437 57.8526 81.2166 57.8526H305.968C307.5 57.8526 308.352 55.8662 306.876 54.4473L254.888 1.89178C252.618 -0.321679 252.448 0.018853 249.95 0.018853H25.7098C24.745 0.018853 23.9504 0.813429 23.9504 1.77827C23.9504 1.83503 23.8936 2.6296 24.5747 3.31067C24.5179 3.25391 24.5179 3.31067 24.5747 3.31067V3.36742Z" fill="${secondaryColor}"/>
<path d="M1009.68 203.642C1003.27 207.82 996.149 209.938 988.383 209.938C982.381 209.938 976.673 208.644 971.26 206.055C965.847 203.466 961.14 199.877 957.138 195.405C953.137 190.933 949.96 185.637 947.665 179.635C945.37 173.634 944.193 167.22 944.193 160.454C944.193 153.687 945.37 147.215 947.665 141.213C949.96 135.211 953.137 130.033 957.138 125.62C961.14 121.207 965.847 117.736 971.26 115.264C976.673 112.734 982.381 111.499 988.383 111.499C995.384 111.499 1001.92 113.146 1008.04 116.441C1014.1 119.736 1019.16 124.267 1023.16 130.092L1043.57 114.205C1036.93 105.203 1028.75 98.083 1018.92 92.8462C1009.09 87.6095 998.385 85.0793 986.794 85.0793C976.791 85.0793 967.435 87.0211 958.727 90.9045C950.019 94.788 942.428 100.142 936.015 106.968C929.542 113.734 924.482 121.796 920.716 130.975C916.951 140.213 915.068 149.98 915.068 160.395C915.068 170.809 916.951 180.577 920.716 189.815C924.482 199.053 929.601 207.055 936.015 213.822C942.487 220.647 950.019 226.002 958.727 229.885C967.435 233.768 976.791 235.71 986.794 235.71C998.797 235.71 1009.92 232.827 1020.1 227.178C1030.28 221.53 1038.63 213.822 1045.05 204.231L1025.22 186.814C1021.22 193.816 1015.98 199.406 1009.62 203.642H1009.68Z" fill="${highlightColor}"/>
<path d="M1173.55 88.3743L1169.08 104.261C1163.26 97.671 1156.67 92.7873 1149.25 89.6688C1141.84 86.5502 1134.13 85.0204 1126.13 85.0204C1116.13 85.0204 1106.77 86.9621 1098.06 90.8456C1089.35 94.729 1081.76 100.083 1075.23 106.909C1068.76 113.676 1063.58 121.737 1059.76 130.916C1055.93 140.154 1054.05 149.921 1054.05 160.336C1054.05 170.751 1055.93 180.518 1059.76 189.756C1063.58 198.994 1068.7 206.996 1075.23 213.763C1081.7 220.588 1089.35 225.943 1098.06 229.826C1106.77 233.709 1116.13 235.651 1126.13 235.651C1134.13 235.651 1142.01 233.945 1149.84 230.532C1157.61 227.119 1164.02 222.118 1169.02 215.528L1173.49 232.062H1198.15V88.2566H1173.49L1173.55 88.3743ZM1165.14 179.635C1162.96 185.637 1159.96 190.874 1156.14 195.405C1152.31 199.935 1147.84 203.466 1142.6 206.055C1137.37 208.644 1131.89 209.938 1126.07 209.938C1120.24 209.938 1114.77 208.644 1109.53 206.055C1104.36 203.466 1099.83 199.876 1096 195.405C1092.18 190.933 1089.18 185.637 1087 179.635C1084.82 173.634 1083.7 167.22 1083.7 160.453C1083.7 153.687 1084.82 147.214 1087 141.213C1089.18 135.211 1092.18 129.974 1096 125.444C1099.77 120.972 1104.3 117.382 1109.53 114.794C1114.71 112.205 1120.24 110.91 1126.07 110.91C1131.89 110.91 1137.37 112.205 1142.6 114.794C1147.78 117.382 1152.31 120.972 1156.14 125.444C1159.9 129.974 1162.9 135.211 1165.14 141.213C1167.32 147.214 1168.43 153.628 1168.43 160.453C1168.43 167.279 1167.32 173.693 1165.14 179.635Z" fill="${highlightColor}"/>
<path d="M1252.63 13.0001H1223.51V232.18H1252.63V13.0001Z" fill="${highlightColor}"/>
<path d="M1405.62 133.564C1402.21 122.443 1397.44 113.323 1391.32 106.085C1385.2 98.8479 1378.02 93.5523 1369.67 90.1984C1361.37 86.7857 1352.31 85.0793 1342.48 85.0793C1332.66 85.0793 1323.89 87.0211 1315.48 90.9045C1307.06 94.788 1299.71 100.142 1293.41 106.968C1287.11 113.734 1282.11 121.796 1278.41 130.975C1274.7 140.213 1272.87 149.98 1272.87 160.395C1272.87 170.809 1274.82 180.577 1278.7 189.815C1282.58 199.053 1287.94 207.055 1294.76 213.822C1301.53 220.647 1309.53 226.002 1318.59 229.885C1327.71 233.768 1337.48 235.71 1347.9 235.71C1359.9 235.71 1370.96 233.592 1381.08 229.414C1391.2 225.237 1399.73 219.588 1406.74 212.586L1388.73 194.581C1384.14 199.17 1378.55 202.877 1372.08 205.702C1365.55 208.526 1358.55 209.879 1350.9 209.879C1345.31 209.879 1339.95 208.997 1334.83 207.173C1329.71 205.349 1325.12 202.818 1321.01 199.523C1316.89 196.228 1313.36 192.286 1310.36 187.814C1307.36 183.342 1305.12 178.459 1303.71 173.222H1410.62C1410.62 157.806 1408.91 144.567 1405.5 133.446L1405.62 133.564ZM1303.53 147.568C1304.71 142.39 1306.59 137.565 1309.06 133.152C1311.59 128.739 1314.53 124.914 1318.06 121.737C1321.54 118.559 1325.36 116.029 1329.48 114.264C1333.6 112.44 1337.95 111.557 1342.54 111.557C1348.19 111.557 1353.07 112.499 1357.43 114.441C1361.72 116.323 1365.49 118.912 1368.67 122.207C1371.84 125.503 1374.37 129.386 1376.2 133.74C1377.96 138.153 1379.08 142.743 1379.49 147.568H1303.53Z" fill="${highlightColor}"/>
<path d="M1537.42 96.4943C1531.71 92.0813 1525.59 89.0805 1518.94 87.4918C1512.35 85.9031 1506.41 85.0793 1501.23 85.0793C1493.23 85.0793 1485.82 86.5504 1478.99 89.5512C1472.22 92.552 1466.4 96.3767 1461.57 100.966L1455.57 88.3744H1432.45V232.18H1461.57V144.508C1461.57 138.506 1462.87 133.446 1465.34 129.327C1467.81 125.208 1470.87 121.854 1474.52 119.089C1478.11 116.382 1481.99 114.441 1486.05 113.264C1490.11 112.087 1493.82 111.44 1497 111.44C1501.23 111.44 1505.23 112.028 1509.18 113.087C1513.12 114.146 1516.59 116.029 1519.71 118.618C1522.83 121.207 1525.3 124.679 1527.18 128.974C1529.06 133.269 1530.06 138.506 1530.06 144.743V232.121H1557.72V145.037C1557.72 132.622 1555.78 122.561 1551.84 114.735C1547.95 106.968 1543.13 100.849 1537.42 96.4355V96.4943Z" fill="${highlightColor}"/>
<path d="M1690.05 103.967C1684.64 97.9653 1678.22 93.3169 1670.87 89.9631C1663.46 86.668 1654.75 85.0205 1644.74 85.0205C1634.74 85.0205 1625.5 86.9622 1617.09 90.8456C1608.68 94.7291 1601.38 100.084 1595.14 106.909C1588.96 113.676 1584.08 121.737 1580.55 130.916C1577.02 140.095 1575.31 149.921 1575.31 160.336C1575.31 170.751 1577.08 180.518 1580.55 189.756C1584.02 198.994 1588.9 206.996 1595.14 213.763C1601.32 220.588 1608.68 225.943 1617.09 229.826C1625.5 233.71 1634.68 235.651 1644.74 235.651C1654.81 235.651 1662.87 234.004 1670.28 230.709C1677.69 227.414 1684.28 222.883 1690.11 217.058L1696.11 232.062H1719.24V13.0001H1690.11V103.967H1690.05ZM1686.4 182.342C1684.23 188.52 1681.11 193.698 1677.22 197.817C1673.34 201.936 1668.81 204.996 1663.69 206.996C1658.57 208.997 1652.98 209.997 1646.98 209.997C1640.98 209.997 1635.62 208.702 1630.39 206.114C1625.21 203.525 1620.68 199.935 1616.85 195.463C1613.03 190.992 1610.03 185.696 1607.79 179.694C1605.56 173.693 1604.5 167.279 1604.5 160.512C1604.5 153.746 1605.62 147.273 1607.79 141.272C1609.97 135.27 1612.97 130.092 1616.85 125.679C1620.68 121.266 1625.21 117.794 1630.39 115.323C1635.62 112.793 1641.15 111.557 1646.98 111.557C1652.81 111.557 1658.57 112.44 1663.69 114.088C1668.81 115.794 1673.34 118.618 1677.22 122.502C1681.11 126.385 1684.23 131.445 1686.4 137.682C1688.58 143.861 1689.7 151.51 1689.7 160.512C1689.7 168.927 1688.58 176.223 1686.4 182.46V182.342Z" fill="${highlightColor}"/>
<path d="M1850.92 104.261C1845.1 97.671 1838.5 92.7873 1831.09 89.6688C1823.68 86.5502 1815.97 85.0204 1807.97 85.0204C1797.96 85.0204 1788.61 86.9621 1779.9 90.8456C1771.19 94.729 1763.6 100.083 1757.07 106.909C1750.6 113.676 1745.42 121.737 1741.6 130.916C1737.77 140.154 1735.89 149.921 1735.89 160.336C1735.89 170.751 1737.77 180.518 1741.6 189.756C1745.42 198.994 1750.54 206.996 1757.07 213.763C1763.54 220.588 1771.19 225.943 1779.9 229.826C1788.61 233.709 1797.96 235.651 1807.97 235.651C1815.97 235.651 1823.85 233.945 1831.68 230.532C1839.45 227.119 1845.86 222.118 1850.86 215.528L1855.33 232.062H1879.99V88.2566H1855.33L1850.86 104.143L1850.92 104.261ZM1847.04 179.635C1844.86 185.637 1841.86 190.874 1838.03 195.405C1834.21 199.935 1829.74 203.466 1824.5 206.055C1819.26 208.644 1813.79 209.938 1807.97 209.938C1802.14 209.938 1796.67 208.644 1791.43 206.055C1786.25 203.466 1781.72 199.876 1777.9 195.405C1774.07 190.933 1771.07 185.637 1768.9 179.635C1766.72 173.634 1765.6 167.22 1765.6 160.453C1765.6 153.687 1766.72 147.214 1768.9 141.213C1771.07 135.211 1774.07 129.974 1777.9 125.444C1781.67 120.972 1786.2 117.382 1791.43 114.794C1796.61 112.205 1802.14 110.91 1807.97 110.91C1813.79 110.91 1819.26 112.205 1824.5 114.794C1829.68 117.382 1834.21 120.972 1838.03 125.444C1841.8 129.974 1844.8 135.211 1847.04 141.213C1849.21 147.214 1850.33 153.628 1850.33 160.453C1850.33 167.279 1849.21 173.693 1847.04 179.635Z" fill="${highlightColor}"/>
<path d="M1976.25 85.0792C1966.42 85.0792 1958.25 86.7856 1951.77 90.316C1945.3 93.7876 1940 98.4948 1936 104.261L1930 88.3743H1906.88V232.18H1936L1936.3 146.92C1936.3 142.095 1937.36 137.565 1939.48 133.269C1941.59 128.974 1944.42 125.208 1948.01 122.031C1951.6 118.853 1955.95 116.265 1960.95 114.382C1965.95 112.499 1971.37 111.498 1977.13 111.498C1978.96 111.498 1980.66 111.675 1982.25 112.087C1983.84 112.499 1985.25 112.852 1986.43 113.264C1987.84 113.852 1989.25 114.44 1990.61 115.029L1998.14 87.727C1989.9 85.903 1982.6 85.0204 1976.19 85.0204L1976.25 85.0792Z" fill="${highlightColor}"/>
<path d="M195.012 84.8116H84.5094C83.7716 84.8116 83.1472 85.2657 82.9202 85.9468C82.8635 86.2873 71.1719 124.767 71.1719 124.767C70.8313 126.016 71.7962 127.435 73.1583 127.492H121.23C122.99 127.492 124.181 129.762 122.876 130.897L76.1663 173.52C75.5988 174.031 75.4853 174.882 75.8826 175.62L88.1985 201.614C88.7093 202.749 89.9579 203.203 90.9795 202.749C95.6334 200.479 100.571 199.344 105.679 199.344C110.39 199.344 114.419 200.195 117.655 202.012C120.89 203.714 123.444 206.155 125.26 209.106C127.133 212.114 128.154 215.576 128.381 219.606C128.608 223.692 128.098 227.892 126.679 232.376C125.317 236.689 123.217 240.889 120.379 244.862C117.541 248.835 114.476 252.524 110.617 255.362C68.0503 285.669 43.5887 254.737 35.3024 248.892C34.1673 248.097 32.8619 248.438 32.4647 249.573L23.5541 277.269C23.4405 277.723 23.4405 278.177 23.6676 278.688C26.2783 284.25 29.7404 289.074 34.1106 293.218C38.9915 297.758 44.6671 301.277 51.2507 303.831C57.8343 306.442 65.2693 307.69 73.4421 307.69C83.9418 307.69 94.3848 305.647 104.828 301.674C115.214 297.701 124.919 292.139 134 285.215C142.967 278.177 150.97 270.118 157.894 260.98C164.762 251.843 169.87 242.024 173.218 231.524C177.304 218.811 178.269 206.949 176.169 195.939C174.069 184.928 169.132 175.847 161.356 168.639C156.362 164.212 150.175 161.034 142.74 158.991C141.208 158.537 140.527 156.721 141.492 155.756L190.926 106.606C190.926 106.606 191.21 106.152 191.266 105.925L197.055 87.7062C197.509 86.344 196.318 84.9252 194.955 84.9252L195.012 84.8116Z" fill="${signetCharColor}"/>
<path d="M305.061 84.8116H236.841C235.99 84.8116 235.308 85.3224 235.081 86.0603L223.333 124.427C222.879 125.846 224.184 127.435 225.717 127.435H244.957C246.546 127.435 247.795 129.024 247.341 130.443L194.899 300.766C194.445 302.185 195.75 303.774 197.282 303.774H239.565C240.416 303.774 241.098 303.263 241.325 302.525L307.445 87.8197C307.899 86.4008 306.593 84.8116 305.004 84.8116H305.061Z" fill="${signetCharColor}"/>
<path d="M52.8961 74.4249L3.1783 24.9909C2.55399 24.4233 1.81617 24.4801 1.75942 24.4801C0.794576 24.4801 0 25.2747 0 26.2395V243.67C0 244.634 0.794576 245.429 1.75942 245.429C2.49724 245.429 3.1783 244.918 3.40533 244.237C3.46208 244.18 3.46208 244.067 3.51884 243.953C3.51884 243.897 3.63235 243.443 3.63235 243.386L53.8041 78.9653C54.4284 77.2059 54.4284 75.9573 52.8961 74.4249Z" fill="${signetSwitchColor}"/>
<path d="M24.5747 3.36742L76.9032 56.3202C78.1518 57.5689 79.3437 57.8526 81.2166 57.8526H305.968C307.5 57.8526 308.352 55.8662 306.876 54.4473L254.888 1.89178C252.618 -0.321679 252.448 0.018853 249.95 0.018853H25.7098C24.745 0.018853 23.9504 0.813429 23.9504 1.77827C23.9504 1.83503 23.8936 2.6296 24.5747 3.31067C24.5179 3.25391 24.5179 3.31067 24.5747 3.31067V3.36742Z" fill="${signetSwitchColor}"/>
<path d="M1009.68 203.642C1003.27 207.82 996.149 209.938 988.383 209.938C982.381 209.938 976.673 208.644 971.26 206.055C965.847 203.466 961.14 199.877 957.138 195.405C953.137 190.933 949.96 185.637 947.665 179.635C945.37 173.634 944.193 167.22 944.193 160.454C944.193 153.687 945.37 147.215 947.665 141.213C949.96 135.211 953.137 130.033 957.138 125.62C961.14 121.207 965.847 117.736 971.26 115.264C976.673 112.734 982.381 111.499 988.383 111.499C995.384 111.499 1001.92 113.146 1008.04 116.441C1014.1 119.736 1019.16 124.267 1023.16 130.092L1043.57 114.205C1036.93 105.203 1028.75 98.083 1018.92 92.8462C1009.09 87.6095 998.385 85.0793 986.794 85.0793C976.791 85.0793 967.435 87.0211 958.727 90.9045C950.019 94.788 942.428 100.142 936.015 106.968C929.542 113.734 924.482 121.796 920.716 130.975C916.951 140.213 915.068 149.98 915.068 160.395C915.068 170.809 916.951 180.577 920.716 189.815C924.482 199.053 929.601 207.055 936.015 213.822C942.487 220.647 950.019 226.002 958.727 229.885C967.435 233.768 976.791 235.71 986.794 235.71C998.797 235.71 1009.92 232.827 1020.1 227.178C1030.28 221.53 1038.63 213.822 1045.05 204.231L1025.22 186.814C1021.22 193.816 1015.98 199.406 1009.62 203.642H1009.68Z" fill="${signetCharColor}"/>
<path d="M1173.55 88.3743L1169.08 104.261C1163.26 97.671 1156.67 92.7873 1149.25 89.6688C1141.84 86.5502 1134.13 85.0204 1126.13 85.0204C1116.13 85.0204 1106.77 86.9621 1098.06 90.8456C1089.35 94.729 1081.76 100.083 1075.23 106.909C1068.76 113.676 1063.58 121.737 1059.76 130.916C1055.93 140.154 1054.05 149.921 1054.05 160.336C1054.05 170.751 1055.93 180.518 1059.76 189.756C1063.58 198.994 1068.7 206.996 1075.23 213.763C1081.7 220.588 1089.35 225.943 1098.06 229.826C1106.77 233.709 1116.13 235.651 1126.13 235.651C1134.13 235.651 1142.01 233.945 1149.84 230.532C1157.61 227.119 1164.02 222.118 1169.02 215.528L1173.49 232.062H1198.15V88.2566H1173.49L1173.55 88.3743ZM1165.14 179.635C1162.96 185.637 1159.96 190.874 1156.14 195.405C1152.31 199.935 1147.84 203.466 1142.6 206.055C1137.37 208.644 1131.89 209.938 1126.07 209.938C1120.24 209.938 1114.77 208.644 1109.53 206.055C1104.36 203.466 1099.83 199.876 1096 195.405C1092.18 190.933 1089.18 185.637 1087 179.635C1084.82 173.634 1083.7 167.22 1083.7 160.453C1083.7 153.687 1084.82 147.214 1087 141.213C1089.18 135.211 1092.18 129.974 1096 125.444C1099.77 120.972 1104.3 117.382 1109.53 114.794C1114.71 112.205 1120.24 110.91 1126.07 110.91C1131.89 110.91 1137.37 112.205 1142.6 114.794C1147.78 117.382 1152.31 120.972 1156.14 125.444C1159.9 129.974 1162.9 135.211 1165.14 141.213C1167.32 147.214 1168.43 153.628 1168.43 160.453C1168.43 167.279 1167.32 173.693 1165.14 179.635Z" fill="${signetCharColor}"/>
<path d="M1252.63 13.0001H1223.51V232.18H1252.63V13.0001Z" fill="${signetCharColor}"/>
<path d="M1405.62 133.564C1402.21 122.443 1397.44 113.323 1391.32 106.085C1385.2 98.8479 1378.02 93.5523 1369.67 90.1984C1361.37 86.7857 1352.31 85.0793 1342.48 85.0793C1332.66 85.0793 1323.89 87.0211 1315.48 90.9045C1307.06 94.788 1299.71 100.142 1293.41 106.968C1287.11 113.734 1282.11 121.796 1278.41 130.975C1274.7 140.213 1272.87 149.98 1272.87 160.395C1272.87 170.809 1274.82 180.577 1278.7 189.815C1282.58 199.053 1287.94 207.055 1294.76 213.822C1301.53 220.647 1309.53 226.002 1318.59 229.885C1327.71 233.768 1337.48 235.71 1347.9 235.71C1359.9 235.71 1370.96 233.592 1381.08 229.414C1391.2 225.237 1399.73 219.588 1406.74 212.586L1388.73 194.581C1384.14 199.17 1378.55 202.877 1372.08 205.702C1365.55 208.526 1358.55 209.879 1350.9 209.879C1345.31 209.879 1339.95 208.997 1334.83 207.173C1329.71 205.349 1325.12 202.818 1321.01 199.523C1316.89 196.228 1313.36 192.286 1310.36 187.814C1307.36 183.342 1305.12 178.459 1303.71 173.222H1410.62C1410.62 157.806 1408.91 144.567 1405.5 133.446L1405.62 133.564ZM1303.53 147.568C1304.71 142.39 1306.59 137.565 1309.06 133.152C1311.59 128.739 1314.53 124.914 1318.06 121.737C1321.54 118.559 1325.36 116.029 1329.48 114.264C1333.6 112.44 1337.95 111.557 1342.54 111.557C1348.19 111.557 1353.07 112.499 1357.43 114.441C1361.72 116.323 1365.49 118.912 1368.67 122.207C1371.84 125.503 1374.37 129.386 1376.2 133.74C1377.96 138.153 1379.08 142.743 1379.49 147.568H1303.53Z" fill="${signetCharColor}"/>
<path d="M1537.42 96.4943C1531.71 92.0813 1525.59 89.0805 1518.94 87.4918C1512.35 85.9031 1506.41 85.0793 1501.23 85.0793C1493.23 85.0793 1485.82 86.5504 1478.99 89.5512C1472.22 92.552 1466.4 96.3767 1461.57 100.966L1455.57 88.3744H1432.45V232.18H1461.57V144.508C1461.57 138.506 1462.87 133.446 1465.34 129.327C1467.81 125.208 1470.87 121.854 1474.52 119.089C1478.11 116.382 1481.99 114.441 1486.05 113.264C1490.11 112.087 1493.82 111.44 1497 111.44C1501.23 111.44 1505.23 112.028 1509.18 113.087C1513.12 114.146 1516.59 116.029 1519.71 118.618C1522.83 121.207 1525.3 124.679 1527.18 128.974C1529.06 133.269 1530.06 138.506 1530.06 144.743V232.121H1557.72V145.037C1557.72 132.622 1555.78 122.561 1551.84 114.735C1547.95 106.968 1543.13 100.849 1537.42 96.4355V96.4943Z" fill="${signetCharColor}"/>
<path d="M1690.05 103.967C1684.64 97.9653 1678.22 93.3169 1670.87 89.9631C1663.46 86.668 1654.75 85.0205 1644.74 85.0205C1634.74 85.0205 1625.5 86.9622 1617.09 90.8456C1608.68 94.7291 1601.38 100.084 1595.14 106.909C1588.96 113.676 1584.08 121.737 1580.55 130.916C1577.02 140.095 1575.31 149.921 1575.31 160.336C1575.31 170.751 1577.08 180.518 1580.55 189.756C1584.02 198.994 1588.9 206.996 1595.14 213.763C1601.32 220.588 1608.68 225.943 1617.09 229.826C1625.5 233.71 1634.68 235.651 1644.74 235.651C1654.81 235.651 1662.87 234.004 1670.28 230.709C1677.69 227.414 1684.28 222.883 1690.11 217.058L1696.11 232.062H1719.24V13.0001H1690.11V103.967H1690.05ZM1686.4 182.342C1684.23 188.52 1681.11 193.698 1677.22 197.817C1673.34 201.936 1668.81 204.996 1663.69 206.996C1658.57 208.997 1652.98 209.997 1646.98 209.997C1640.98 209.997 1635.62 208.702 1630.39 206.114C1625.21 203.525 1620.68 199.935 1616.85 195.463C1613.03 190.992 1610.03 185.696 1607.79 179.694C1605.56 173.693 1604.5 167.279 1604.5 160.512C1604.5 153.746 1605.62 147.273 1607.79 141.272C1609.97 135.27 1612.97 130.092 1616.85 125.679C1620.68 121.266 1625.21 117.794 1630.39 115.323C1635.62 112.793 1641.15 111.557 1646.98 111.557C1652.81 111.557 1658.57 112.44 1663.69 114.088C1668.81 115.794 1673.34 118.618 1677.22 122.502C1681.11 126.385 1684.23 131.445 1686.4 137.682C1688.58 143.861 1689.7 151.51 1689.7 160.512C1689.7 168.927 1688.58 176.223 1686.4 182.46V182.342Z" fill="${signetCharColor}"/>
<path d="M1850.92 104.261C1845.1 97.671 1838.5 92.7873 1831.09 89.6688C1823.68 86.5502 1815.97 85.0204 1807.97 85.0204C1797.96 85.0204 1788.61 86.9621 1779.9 90.8456C1771.19 94.729 1763.6 100.083 1757.07 106.909C1750.6 113.676 1745.42 121.737 1741.6 130.916C1737.77 140.154 1735.89 149.921 1735.89 160.336C1735.89 170.751 1737.77 180.518 1741.6 189.756C1745.42 198.994 1750.54 206.996 1757.07 213.763C1763.54 220.588 1771.19 225.943 1779.9 229.826C1788.61 233.709 1797.96 235.651 1807.97 235.651C1815.97 235.651 1823.85 233.945 1831.68 230.532C1839.45 227.119 1845.86 222.118 1850.86 215.528L1855.33 232.062H1879.99V88.2566H1855.33L1850.86 104.143L1850.92 104.261ZM1847.04 179.635C1844.86 185.637 1841.86 190.874 1838.03 195.405C1834.21 199.935 1829.74 203.466 1824.5 206.055C1819.26 208.644 1813.79 209.938 1807.97 209.938C1802.14 209.938 1796.67 208.644 1791.43 206.055C1786.25 203.466 1781.72 199.876 1777.9 195.405C1774.07 190.933 1771.07 185.637 1768.9 179.635C1766.72 173.634 1765.6 167.22 1765.6 160.453C1765.6 153.687 1766.72 147.214 1768.9 141.213C1771.07 135.211 1774.07 129.974 1777.9 125.444C1781.67 120.972 1786.2 117.382 1791.43 114.794C1796.61 112.205 1802.14 110.91 1807.97 110.91C1813.79 110.91 1819.26 112.205 1824.5 114.794C1829.68 117.382 1834.21 120.972 1838.03 125.444C1841.8 129.974 1844.8 135.211 1847.04 141.213C1849.21 147.214 1850.33 153.628 1850.33 160.453C1850.33 167.279 1849.21 173.693 1847.04 179.635Z" fill="${signetCharColor}"/>
<path d="M1976.25 85.0792C1966.42 85.0792 1958.25 86.7856 1951.77 90.316C1945.3 93.7876 1940 98.4948 1936 104.261L1930 88.3743H1906.88V232.18H1936L1936.3 146.92C1936.3 142.095 1937.36 137.565 1939.48 133.269C1941.59 128.974 1944.42 125.208 1948.01 122.031C1951.6 118.853 1955.95 116.265 1960.95 114.382C1965.95 112.499 1971.37 111.498 1977.13 111.498C1978.96 111.498 1980.66 111.675 1982.25 112.087C1983.84 112.499 1985.25 112.852 1986.43 113.264C1987.84 113.852 1989.25 114.44 1990.61 115.029L1998.14 87.727C1989.9 85.903 1982.6 85.0204 1976.19 85.0204L1976.25 85.0792Z" fill="${signetCharColor}"/>
</svg>`
}

View file

@ -13,7 +13,6 @@ import { Keys } from "../../api/common/TutanotaConstants"
import { isKeyPressed } from "../../misc/KeyManager"
import { DropData, DropHandler, DropType } from "./GuiUtils"
import { assertMainOrNode, isDesktop } from "../../api/common/Env"
import { stateBgHover } from "../builtinThemes.js"
import { fileListToArray } from "../../api/common/utils/FileUtils.js"
assertMainOrNode()
@ -32,6 +31,7 @@ export type NavButtonAttrs = {
centred?: boolean
leftInjection?: () => Children
disableHoverBackground?: boolean
disableSelectedBackground?: boolean
disabled?: boolean
persistentBackground?: boolean
onfocus?: () => unknown
@ -62,7 +62,7 @@ export class NavButton implements Component<NavButtonAttrs> {
icon,
class: this._getIconClass(a),
style: {
fill: isNavButtonSelected(a) || this._draggedOver ? getColors(a.colors).button_selected : getColors(a.colors).button,
fill: isNavButtonSelected(a) || this._draggedOver ? theme.primary : theme.on_surface_variant,
},
})
: null,
@ -111,17 +111,16 @@ export class NavButton implements Component<NavButtonAttrs> {
}
createButtonAttributes(a: NavButtonAttrs): RouteLinkAttrs {
const isCurrent = isNavButtonSelected(a)
const isCurrent = this._draggedOver || (isNavButtonSelected(a) && !a.disableSelectedBackground)
let attr: RouteLinkAttrs = {
role: "button",
"aria-current": isCurrent || undefined,
// role button for screen readers
href: this._getUrl(a.href),
style: {
color: isCurrent || this._draggedOver ? getColors(a.colors).button_selected : getColors(a.colors).button,
"font-size": a.fontSize ? px(a.fontSize) : "",
background: (isCurrent && a.persistentBackground) || this._draggedOver ? stateBgHover : "",
color: this._draggedOver || isNavButtonSelected(a) ? theme.primary : theme.on_surface_variant,
...(isCurrent && { background: theme.state_bg_active }),
},
title: lang.getTranslationText(a.label),
target: this._isExternalUrl(a.href) ? "_blank" : undefined,
@ -213,29 +212,6 @@ export const enum NavButtonColor {
Content = "content",
}
function getColors(buttonColors: NavButtonColor | null | undefined) {
switch (buttonColors) {
case NavButtonColor.Header:
return {
button: styles.isDesktopLayout() ? theme.on_surface_variant : theme.primary,
button_selected: styles.isDesktopLayout() ? theme.primary : theme.primary,
}
case NavButtonColor.Nav:
return {
button: theme.on_surface_variant,
button_selected: theme.primary,
}
default:
// for nav buttons in the more dropdown menu
return {
button: theme.on_surface_variant,
button_selected: theme.primary,
}
}
}
export function isNavButtonSelected(a: NavButtonAttrs): boolean {
if (typeof a.isSelectedPrefix === "boolean") {
return a.isSelectedPrefix

View file

@ -31,8 +31,8 @@ export class SegmentControl<T> implements Component<SegmentControlAttrs<T>> {
},
items.map((item) =>
m(
`button.segmentControlItem.flex.center-horizontally.center-vertically.text-ellipsis.small${
item.value === selectedValue ? ".segmentControl-border-active.content-accent-fg" : ".segmentControl-border"
`button.segmentControlItem.segmentControl-border.flex.center-horizontally.center-vertically.text-ellipsis.small${
item.value === selectedValue ? ".segmentControl-border-active" : ".segmentControl-border"
}`,
{
style: {

View file

@ -579,7 +579,7 @@ class OptionListContainer implements ClassComponent {
}
private renderNoItem(): Children {
return m("span.placeholder.text-center", { color: theme.on_surface_fade }, lang.get("noEntries_msg"))
return m("span.placeholder.text-center", { color: theme.on_surface_variant }, lang.get("noEntries_msg"))
}
setOrigin(origin: DomRectReadOnlyPolyfilled): this {

View file

@ -4,7 +4,6 @@ import { isNavButtonSelected, NavButton, NavButtonAttrs } from "./NavButton"
import { ClickHandler, DropData } from "./GuiUtils"
import type { MaybeTranslation } from "../../misc/LanguageViewModel"
import { assertNotNull } from "@tutao/tutanota-utils"
import { stateBgHover } from "../builtinThemes"
import { client } from "../../misc/ClientDetector"
import { IconButton, IconButtonAttrs } from "./IconButton"
import { theme } from "../theme"
@ -48,6 +47,7 @@ export class SidebarSectionRow implements Component<SidebarSectionRowAttrs> {
label: attrs.label,
href: () => attrs.path,
disableHoverBackground: true,
disableSelectedBackground: true,
click: attrs.onClick,
onfocus: onHover,
onkeydown: handleBackwardsTab,
@ -59,7 +59,7 @@ export class SidebarSectionRow implements Component<SidebarSectionRowAttrs> {
return m(
".folder-row.flex.flex-row.mlr-button.border-radius-small.state-bg.border-radius-small",
{
style: { background: isNavButtonSelected(navButtonAttrs) ? stateBgHover : "" },
style: { background: isNavButtonSelected(navButtonAttrs) ? theme.state_bg_hover : "" },
onmouseenter: onHover,
onmouseleave: () => {
this.hovered = false

View file

@ -1,13 +1,14 @@
import m, { Child, ClassComponent, Vnode } from "mithril"
import { theme } from "../theme.js"
interface SkeletonAttrs {
style?: Partial<Pick<CSSStyleDeclaration, "width" | "height">>
style?: Partial<Pick<CSSStyleDeclaration, "width" | "height" | "backgroundColor">>
}
export class Skeleton implements ClassComponent<SkeletonAttrs> {
view({ attrs }: Vnode<SkeletonAttrs>): Child {
return m(".skeleton.loading.rel.overflow-hidden.border-radius.navigation-menu-bg", {
style: attrs.style,
return m(".skeleton.loading.rel.overflow-hidden.border-radius", {
style: { backgroundColor: theme.surface_container_high, ...attrs.style },
} satisfies SkeletonAttrs)
}
}

View file

@ -100,11 +100,10 @@ export class TextArea implements ClassComponent<TextAreaAttrs> {
resizable?: boolean,
variant?: TextAreaVariant,
) {
const borderColor = isLightTheme() ? theme.button_bubble_bg : style?.borderColor || theme.elevated_bg
return {
...style,
resize: !resizable ? "none" : "vertical",
border: variant === "outlined" ? `2px solid ${borderColor}` : undefined,
border: variant === "outlined" ? `2px solid ${theme.outline}` : undefined,
}
}
}

View file

@ -107,7 +107,7 @@ export class TextField implements ClassComponent<TextFieldAttrs> {
const labelTransitionSpeed = DefaultAnimationTime / 2
const doShowBorder = a.doShowBorder !== false
const borderWidth = this.active ? "2px" : "1px"
const borderColor = this.active ? theme.primary : theme.outline
const borderColor = this.active ? theme.primary : theme.outline_variant
return m(
".text-field.rel.overflow-hidden",
{

View file

@ -36,7 +36,7 @@ export class LoginButton implements Component<LoginButtonAttrs> {
if (attrs.disabled) {
// This makes the button appear "disabled" (grey color, no hover) when disabled is set to true
classes.push("button-bg")
classes.push("disabled-button")
} else if (attrs.discouraged) {
// This makes the button appear outlined with a transparent background
classes.push("tutaui-button-outline")

View file

@ -1,120 +1,13 @@
/**
* @file color/theme definitions for default themes.
*/
import { getCalendarLogoSvg, getMailLogoSvg, getTutaLogoSvg } from "./base/Logo"
import type { Theme, ThemeId } from "./theme"
import { assertMainOrNodeBoot, isApp } from "../api/common/Env"
import { client } from "../misc/ClientDetector.js"
import { assertMainOrNodeBoot } from "../api/common/Env"
import { getAppLogo } from "./base/Logo.js"
import { client } from "../misc/ClientDetector"
assertMainOrNodeBoot()
/**
* semantic colors light as defined in Figma primitives
*/
const SONNE = "#FFCB00"
/**
* semantic colors dark as defined in Figma primitives
*/
const SONNE_70 = "#FFECB7"
/**
* semantic error ghost color light as defined in Figma primitives
*/
const SONNE_GHOST = "#FFCB007F" //7F = 50% from 255
/**
* semantic error ghost color dark as defined in Figma primitives
*/
const SONNE_GHOST_70 = "#FFECB7D9" //D9 = 85% from 255
/**
* Highlight color
*/
const highlight = "#FFDDB2"
/*
* Semantic success color light as defined in figma primitives
*/
const GREEN = "#39D9C1"
/*
* Semantic ghost success color light as defined in figma primitives
*/
const GREEN_GHOST = "#39D9C166" //66 = 40% from 255
/*
* Semantic success color dark as defined in figma primitives
*/
const GREEN_70 = "#99D2C5"
/*
* Semantic success color dark as defined in figma primitives
*/
const GREEN_GHOST_70 = "#99D2C5E5" //E5 = 90% from 255
// Base color name
const PEACH = "#FFF2EA"
const DARK_PEACH = "#C9C6C5"
const RED_DUNKEL = "#410002"
const RED_NOTA = "#D93951"
const BLUE_DUNKEL = "#001641"
const BLUE_FIGHTER = "#0040FF"
/**
* light theme background
*/
const light_white = "#ffffff"
const grey_lighter_4 = "#f6f6f6"
const grey_lighter_3 = "#eaeaea"
const grey_lighter_2 = "#e1e1e1"
const grey_lighter_1 = "#d5d5d5"
const grey_lighter_0 = "#b8b8b8"
const grey = "#868686"
const grey_darker_0 = "#707070"
const grey_darker_1 = "#303030"
const red = "#850122"
const secondary_red = "#FF2222"
const red_nota = "#d93951"
const dunkel = "#410002"
const blue = "#003E85"
const secondary_blue = "#4282FF"
const blue_nota = "#3964d9"
const light_blue = "#ACC7FF"
const dark_purple = "#AC3E80"
const light_purple = "#FCBFDE"
/**
* dark theme background
*
* Assuming the background is black #000000 (rgb(0,0,0)) and text is white #000000 (rgb(255, 255, 255)) and recommended opacity of 87%
* we get (x1 being foreground, x2 being background, x3 being result)
* x3 = x2 + (x1-x2)*a1 or x3 = 0 + (255 - 0) * 0.87 = 221
* rgb(221, 221, 221) = #DDDDDD
* https://stackoverflow.com/questions/12228548/finding-equivalent-color-with-opacity
*
*/
const light_lighter_1 = "#DDDDDD"
const light_lighter_0 = "#aeaeae"
const light_grey = "#999999"
const dark_lighter_2 = "#4e4e4e"
const dark_lighter_1 = "#363636"
const dark_lighter_0 = "#232323"
const dark = "#222222"
const dark_darker_0 = "#111111"
const light_red = "#E99497"
const logo_text_bright_grey = "#c5c7c7"
const black = "#000000"
// Secondary colors
export const secondary_fixed = "#FFDDB2"
export const on_secondary_fixed = "#291800"
// These are constants that have been chosen because they work across themes
// This is even lighter than hover, for special cases like inactive search bar background
export const stateBgLike = "rgba(139,139,139,0.18)"
export const stateBgHover = "rgba(139,139,139,0.22)"
export const stateBgFocus = "rgba(139,139,139,0.29)"
export const stateBgActive = "rgba(139,139,139,0.38)"
export const logoDefaultGrey = logo_text_bright_grey
export const tutaRed = red
export const tutaDunkel = dunkel
export const goEuropeanBlue = blue
type Themes = Record<ThemeId, Theme>
const semanticColorsLight = {
@ -148,21 +41,6 @@ const semanticColorsDark = {
on_success_container: "#93D5AA",
}
const getLogo = (isDark: boolean, isDefault: boolean) => {
const isDarkOrDefault = isDark || !isDefault
if (!isApp()) {
return isDarkOrDefault ? getTutaLogoSvg(logo_text_bright_grey, logo_text_bright_grey) : getTutaLogoSvg(red, dunkel)
}
if (client.isCalendarApp()) {
return isDarkOrDefault
? getCalendarLogoSvg(logo_text_bright_grey, logo_text_bright_grey, logo_text_bright_grey)
: getCalendarLogoSvg(blue, secondary_blue, black)
}
return isDarkOrDefault ? getMailLogoSvg(logo_text_bright_grey, logo_text_bright_grey, logo_text_bright_grey) : getMailLogoSvg(red, secondary_red, black)
}
/**
* Color token definitions for each built-in theme.
* We follow the color roles from Material 3 to define the names of the tokens,
@ -176,148 +54,167 @@ export const themes = (): Themes => {
const isCalendarApp = client.isCalendarApp()
const lightRed = Object.freeze<Theme>({
...semanticColorsLight,
themeId: !isCalendarApp ? "light" : "light_secondary",
logo: getLogo(false, !isCalendarApp),
// Campaign colors
tuta_color_nota: red_nota,
content_accent_tuta_bday: dark_purple,
content_accent_secondary_tuta_bday: light_purple,
content_bg_tuta_bday: dark,
themeId: isCalendarApp ? "light_secondary" : "light",
logo: getAppLogo(),
// Basic color tokens
primary: red,
on_primary: light_white,
secondary: grey_lighter_3,
on_secondary: grey_darker_1,
error: SONNE,
error_container: SONNE_GHOST,
on_error_container: dark_lighter_0,
surface: light_white,
surface_container: grey_lighter_4,
on_surface_fade: grey_lighter_0,
on_surface: grey_darker_1,
on_surface_variant: grey_darker_0,
outline: grey_lighter_1,
outline_variant: grey_lighter_3,
scrim: grey_darker_1,
experimental_primary_container: PEACH,
experimental_on_primary_container: RED_DUNKEL,
experimental_tertiary: RED_NOTA,
highlight_bg: highlight,
highlight_fg: black,
primary: "#8F4A4E",
on_primary: "#FFFFFF",
primary_container: "#F4D2D2",
on_primary_container: "#733337",
secondary: "#87521B",
on_secondary: "#FFFFFF",
secondary_container: "#FFDCC1",
on_secondary_container: "#6B3B04",
tertiary: "#63568F",
on_tertiary: "#FFFFFF",
tertiary_container: "#E7DEFF",
on_tertiary_container: "#4B3E76",
surface: "#FFFFFF",
on_surface: "#221A14",
surface_container: "#FCF9F6",
surface_container_high: "#F5EEEA",
surface_container_highest: "#EFE0D5",
on_surface_variant: "#524343",
outline: "#857373",
outline_variant: "#D7C1C1",
scrim: "#000000",
experimental_primary_container: "#FFF2EA",
experimental_on_primary_container: "#410002",
experimental_tertiary: "#D93951",
// state colors; based on outline_variant, with alpha
state_bg_hover: "#D7C1C144",
state_bg_focus: "#D7C1C155",
state_bg_active: "#D7C1C166",
// Campaign colors
tuta_color_nota: "#D93951",
content_accent_tuta_bday: "#AC3E80",
content_accent_secondary_tuta_bday: "#FCBFDE",
content_bg_tuta_bday: "#222222",
go_european: goEuropeanBlue,
on_go_european: light_white,
success: GREEN,
success_container: GREEN_GHOST_70,
on_success_container: dark_lighter_0,
on_go_european: "#FFFFFF",
})
const darkRed = Object.freeze<Theme>({
...semanticColorsDark,
themeId: !isCalendarApp ? "dark" : "dark_secondary",
logo: getLogo(true, !isCalendarApp),
// Campaign colors
tuta_color_nota: red_nota,
content_accent_tuta_bday: light_purple,
content_accent_secondary_tuta_bday: dark_purple,
content_bg_tuta_bday: light_white,
themeId: isCalendarApp ? "dark_secondary" : "dark",
logo: getAppLogo("#9F8C8CAA"),
// Basic color tokens
primary: light_red,
on_primary: dark_lighter_0,
secondary: dark_lighter_2,
on_secondary: light_lighter_1,
error: SONNE_70,
error_container: SONNE_GHOST_70,
on_error_container: dark_lighter_0,
surface: dark_darker_0,
surface_container: dark_lighter_0,
on_surface_fade: dark_lighter_2,
on_surface: light_lighter_1,
on_surface_variant: light_lighter_0,
outline: dark_lighter_1,
outline_variant: dark_lighter_1,
scrim: dark_darker_0,
experimental_primary_container: DARK_PEACH,
experimental_on_primary_container: dark_lighter_0,
experimental_tertiary: RED_NOTA,
highlight_bg: highlight,
highlight_fg: black,
go_european: light_blue,
on_go_european: dark_darker_0,
success: GREEN_70,
success_container: GREEN_GHOST_70,
on_success_container: dark_lighter_0,
primary: "#FFB3B5",
on_primary: "#561D22",
primary_container: "#733337",
on_primary_container: "#FFDADA",
secondary: "#F3BD6E",
on_secondary: "#442B00",
secondary_container: "#624000",
on_secondary_container: "#FFDDB2",
tertiary: "#CDBDFF",
on_tertiary: "#34275E",
tertiary_container: "#4B3E76",
on_tertiary_container: "#E7DEFF",
surface: "#1A1111",
surface_container: "#271D1D",
surface_container_high: "#322828",
surface_container_highest: "#433737",
on_surface: "#F5EBEB",
on_surface_variant: "#D7C1C1",
outline: "#9F8C8C",
outline_variant: "#524343",
scrim: "#000000",
experimental_primary_container: "#C9C6C5",
experimental_on_primary_container: "#232323",
experimental_tertiary: "#D93951",
// state colors; based on outline_variant, with alpha
state_bg_hover: "#52434377",
state_bg_focus: "#52434399",
state_bg_active: "#524343AA",
// Campaign colors
tuta_color_nota: "#D93951",
content_accent_tuta_bday: "#FCBFDE",
content_accent_secondary_tuta_bday: "#AC3E80",
content_bg_tuta_bday: "#FFFFFF",
go_european: goEuropeanLightBlue,
on_go_european: "#111111",
})
const lightBlue = Object.freeze<Theme>({
...semanticColorsLight,
themeId: isCalendarApp ? "light" : "light_secondary",
// blue is not really our brand color, treat blue like whitelabel color
logo: getLogo(false, isCalendarApp),
// Campaign colors
tuta_color_nota: red_nota,
content_accent_tuta_bday: dark_purple,
content_accent_secondary_tuta_bday: light_purple,
content_bg_tuta_bday: dark,
logo: getAppLogo(isCalendarApp ? undefined : "#C4C6D0EE"),
// Basic color tokens
primary: blue,
on_primary: light_white,
secondary: grey_lighter_3,
on_secondary: grey_darker_1,
error: SONNE,
error_container: SONNE_GHOST,
on_error_container: dark_lighter_0,
surface: light_white,
surface_container: grey_lighter_4,
on_surface_fade: grey_lighter_0,
on_surface: grey_darker_1,
on_surface_variant: grey_darker_0,
outline: grey_lighter_1,
outline_variant: grey_lighter_3,
scrim: grey_darker_1,
experimental_primary_container: PEACH,
experimental_on_primary_container: BLUE_DUNKEL,
experimental_tertiary: BLUE_FIGHTER,
highlight_bg: highlight,
highlight_fg: black,
primary: "#435E91",
on_primary: "#FFFFFF",
primary_container: "#D2DAF3",
on_primary_container: "#2A4678",
secondary: "#7F4D7B",
on_secondary: "#FFFFFF",
secondary_container: "#FFD6F7",
on_secondary_container: "#643662",
tertiary: "#006A65",
on_tertiary: "#FFFFFF",
tertiary_container: "#9DF2EA",
on_tertiary_container: "#00504C",
surface: "#FFFFFF",
surface_container: "#F7F9FC",
surface_container_high: "#EBEEF5",
surface_container_highest: "#E0E3E8",
on_surface: "#221A14",
on_surface_variant: "#44474E",
outline: "#74777F",
outline_variant: "#C4C6D0",
scrim: "#000000",
experimental_primary_container: "#FFF2EA",
experimental_on_primary_container: "#001641",
experimental_tertiary: "#0040FF",
// state colors; based on outline_variant, with alpha
state_bg_hover: "#C4C6D044",
state_bg_focus: "#C4C6D055",
state_bg_active: "#C4C6D066",
// Campaign colors
tuta_color_nota: "#d93951",
content_accent_tuta_bday: "#AC3E80",
content_accent_secondary_tuta_bday: "#FCBFDE",
content_bg_tuta_bday: "#222222",
go_european: goEuropeanBlue,
on_go_european: light_white,
success: GREEN,
success_container: GREEN_GHOST,
on_success_container: dark_lighter_0,
on_go_european: "#FFFFFF",
})
const darkBlue = Object.freeze<Theme>({
...semanticColorsDark,
themeId: isCalendarApp ? "dark" : "dark_secondary",
logo: getLogo(true, isCalendarApp),
// Campaign colors
tuta_color_nota: red_nota,
content_accent_tuta_bday: light_purple,
content_accent_secondary_tuta_bday: dark_purple,
content_bg_tuta_bday: light_white,
logo: getAppLogo("#8E9099AA"),
// Basic color tokens
primary: light_blue,
on_primary: dark_lighter_0,
secondary: dark_lighter_2,
on_secondary: light_lighter_1,
error: SONNE_70,
error_container: SONNE_GHOST_70,
on_error_container: dark_lighter_0,
surface: dark_darker_0,
surface_container: dark_lighter_0,
on_surface_fade: dark_lighter_2,
on_surface: light_lighter_1,
on_surface_variant: light_lighter_0,
outline: dark_lighter_1,
outline_variant: dark_lighter_1,
scrim: dark_darker_0,
experimental_primary_container: DARK_PEACH,
experimental_on_primary_container: dark_lighter_0,
experimental_tertiary: BLUE_FIGHTER,
highlight_bg: highlight,
highlight_fg: black,
go_european: light_blue,
on_go_european: dark_darker_0,
success: GREEN_70,
success_container: GREEN_GHOST_70,
on_success_container: dark_lighter_0,
primary: "#ACC7FF",
on_primary: "#0E2F60",
primary_container: "#244173",
on_primary_container: "#D7E2FF",
secondary: "#F0B3E8",
on_secondary: "#4B1F4A",
secondary_container: "#643662",
on_secondary_container: "#FFD6F7",
tertiary: "#81D5CE",
on_tertiary: "#003734",
tertiary_container: "#00504C",
on_tertiary_container: "#9DF2EA",
surface: "#101418",
surface_container: "#1C2024",
surface_container_high: "#272A2F",
surface_container_highest: "#33373D",
on_surface: "#E0E2E8",
on_surface_variant: "#C4C6D0",
outline: "#8E9099",
outline_variant: "#44474E",
scrim: "#000000",
experimental_primary_container: "#C9C6C5",
experimental_on_primary_container: "#232323",
experimental_tertiary: "#0040FF",
// state colors; based on outline_variant, with alpha
state_bg_hover: "#44474E77",
state_bg_focus: "#44474E99",
state_bg_active: "#44474EAA",
// Campaign colors
tuta_color_nota: "#D93951",
content_accent_tuta_bday: "#FCBFDE",
content_accent_secondary_tuta_bday: "#AC3E80",
content_bg_tuta_bday: "#FFFFFF",
go_european: goEuropeanLightBlue,
on_go_european: "#111111",
})
return {
@ -327,3 +224,7 @@ export const themes = (): Themes => {
dark_secondary: isCalendarApp ? darkRed : darkBlue,
}
}
// Fixed campaign colors
export const goEuropeanBlue = "#003E85"
export const goEuropeanLightBlue = "#ACC7FF"

View file

@ -5,7 +5,7 @@ import { lang } from "../misc/LanguageViewModel"
import { noselect, position_absolute } from "./mixins"
import { assertMainOrNode, isAdminClient, isApp, isElectronClient } from "../api/common/Env"
import { getElevatedBackground, getNavigationMenuBg, theme } from "./theme"
import { goEuropeanBlue, stateBgActive, stateBgFocus, stateBgHover, stateBgLike } from "./builtinThemes.js"
import { goEuropeanBlue } from "./builtinThemes.js"
import { FontIcons } from "./base/icons/FontIcons.js"
import { DefaultAnimationTime } from "./animation/Animations.js"
import { locator } from "../api/main/CommonLocator.js"
@ -32,9 +32,9 @@ export function getFonts(): string {
return fonts.join(", ")
}
export const boxShadowHigh = `0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23)`
const boxShadowMedium = "0px 0px 4px 2px rgba(0, 0, 0, 0.22)"
const boxShadowLow = "0px 2px 4px rgb(0, 0, 0, 0.12)"
export const boxShadowHigh = `0 10px 20px rgba(0,0,0,0.10), 0 6px 6px rgba(0,0,0,0.10)`
export const boxShadowMedium = "0px 0px 4px 2px rgba(0, 0, 0, 0.12)"
export const boxShadowLow = "0px 2px 4px rgb(0, 0, 0, 0.08)"
const scrollbarWidthHeight = px(18)
styles.registerStyle("main", () => {
@ -233,7 +233,7 @@ styles.registerStyle("main", () => {
"font-weight": "normal",
},
".navigation-menu-bg": {
background: theme.secondary,
background: theme.surface_container_high,
},
".navigation-menu-icon-bg": {
background: theme.on_secondary,
@ -303,7 +303,7 @@ styles.registerStyle("main", () => {
border: `1px solid ${theme.outline}`,
},
".border-top": {
"border-top": `1px solid ${theme.outline}`,
"border-top": `1px solid ${theme.outline_variant}`,
},
"#shadow-mail-body.break-pre pre": {
"white-space": "pre-wrap",
@ -796,13 +796,13 @@ styles.registerStyle("main", () => {
},
// borders
".border-bottom": {
"border-bottom": `1px solid ${theme.outline}`,
"border-bottom": `1px solid ${theme.outline_variant}`,
},
".border-right": {
"border-right": `1px solid ${theme.outline}`,
},
".border-left": {
"border-left": `1px solid ${theme.outline}`,
"border-left": `1px solid ${theme.outline_variant}`,
},
// colors
".bg-transparent": {
@ -847,12 +847,6 @@ styles.registerStyle("main", () => {
".no-hover": {
"pointer-events": "none",
},
".content-message-bg": {
"background-color": theme.on_surface_fade,
},
".button-bubble-bg": {
"background-color": theme.secondary,
},
".elevated-bg": {
"background-color": getElevatedBackground(),
},
@ -871,14 +865,9 @@ styles.registerStyle("main", () => {
".list-border-bottom": {
"border-bottom": `1px solid ${theme.outline_variant}`,
},
".accent-bg-translucent": {
background: `${theme.primary}2C`,
color: theme.primary,
},
".button-bg": {
background: theme.on_surface_variant,
color: theme.surface_container,
opacity: "0.5",
".disabled-button": {
background: `${hexToRGBAString(theme.on_surface, 0.1)}`,
color: `${hexToRGBAString(theme.on_surface, 0.38)}`,
},
".accent-bg": {
"background-color": theme.primary,
@ -1032,7 +1021,7 @@ styles.registerStyle("main", () => {
"padding-right": "16px",
},
".dropdown-info + .dropdown-button": {
"border-top": `1px solid ${theme.outline}`,
"border-top": `1px solid ${theme.outline_variant}`,
},
".dropdown-info + .dropdown-info": {
"padding-top": "0",
@ -1418,10 +1407,10 @@ styles.registerStyle("main", () => {
},
".search-bar": {
transition: "all 200ms",
"background-color": stateBgLike,
"background-color": theme.surface_container_high,
},
".search-bar:hover": {
"background-color": stateBgHover,
"background-color": theme.state_bg_hover,
},
".search-bar[focused=true]": {
"background-color": theme.surface,
@ -1541,7 +1530,7 @@ styles.registerStyle("main", () => {
"will-change": "border-width, border-color, color, background-color",
},
".wizard-breadcrumb-line": {
"border-top": `3px dotted ${theme.outline}`,
"border-top": `3px dotted ${theme.outline_variant}`,
height: 0,
transition: `border-top-color ${DefaultAnimationTime}ms ease-out`,
"will-change": "border-top-style, border-top-color",
@ -1569,22 +1558,25 @@ styles.registerStyle("main", () => {
// undoing our default button styling
opacity: "1 !important",
},
".state-bg.selected": {
background: theme.state_bg_active,
},
// Only enable hover for mouse and keyboard navigation (not touch) because
// :hover will bet stuck after the touch on mobile.
// Use :where() to not count towards specificity, otherwise this is more specific
// than :active (which is unconditional
":where(.mouse-nav) .state-bg:hover, :where(.keyboard-nav) .state-bg:hover": {
background: stateBgHover,
background: theme.state_bg_hover,
"transition-duration": ".3s",
},
":where(.keyboard-nav) .state-bg:focus": {
background: stateBgFocus,
background: theme.state_bg_focus,
"transition-duration": ".3s",
// disable default focus indicator because we have our own for this element
outline: "none",
},
".state-bg:active, .state-bg[pressed=true]": {
background: stateBgActive,
background: theme.state_bg_active,
"transition-duration": ".3s",
},
// State layer roughly like in Material 3.
@ -1676,7 +1668,7 @@ styles.registerStyle("main", () => {
to set all nav elements to border-box, we must make sure to not break any existing styling
*/
"box-sizing": "border-box",
"border-top": `1px solid ${theme.outline}`,
"border-top": `1px solid ${theme.outline_variant}`,
height: `calc(${size.bottom_nav_bar}px + env(safe-area-inset-bottom))`,
background: theme.surface,
"padding-bottom": "env(safe-area-inset-bottom)",
@ -1722,7 +1714,7 @@ styles.registerStyle("main", () => {
width: "0px",
height: "22px",
"margin-left": "2px",
"border-color": theme.outline,
"border-color": theme.outline_variant,
"border-width": "1px",
"border-style": "solid",
},
@ -1743,7 +1735,7 @@ styles.registerStyle("main", () => {
"max-width": px(350),
},
".dialog-header": {
"border-bottom": `1px solid ${theme.outline}`,
"border-bottom": `1px solid ${theme.outline_variant}`,
height: px(size.button_height + 1),
},
".dialog-header-line-height": {
@ -1767,13 +1759,13 @@ styles.registerStyle("main", () => {
height: "auto",
},
".dialog-buttons": {
"border-top": `1px solid ${theme.outline}`,
"border-top": `1px solid ${theme.outline_variant}`,
},
".dialog-buttons > button": {
flex: "1",
},
".dialog-buttons > button:not(:first-child)": {
"border-left": `1px solid ${theme.outline}`,
"border-left": `1px solid ${theme.outline_variant}`,
"margin-left": "0",
},
".dialog-height-small": {
@ -1842,6 +1834,9 @@ styles.registerStyle("main", () => {
".input": {
outline: "none",
},
".input::placeholder": {
color: theme.on_surface_variant,
},
"blockquote.tutanota_quote, blockquote[type=cite]": {
"border-left": `1px solid ${theme.primary}`,
"padding-left": px(size.hpad),
@ -1874,7 +1869,6 @@ styles.registerStyle("main", () => {
".list-loading": {
bottom: 0,
},
// mail list
".teamLabel": {
color: theme.on_primary,
"background-color": theme.primary,
@ -2022,26 +2016,28 @@ styles.registerStyle("main", () => {
},
".bubble": {
"border-radius": px(size.border_radius),
"background-color": theme.secondary,
color: theme.on_secondary,
"background-color": theme.surface_container_high,
color: theme.on_surface,
},
".keyword-bubble": {
"max-width": "300px",
"border-radius": px(size.border_radius),
"margin-bottom": px(size.vpad_small / 2),
"margin-right": px(size.vpad_small / 2),
"background-color": theme.secondary,
"background-color": theme.surface_container_high,
color: theme.on_surface,
padding: `${px(size.vpad_small / 2)} ${px(size.vpad_small)} ${px(size.vpad_small / 2)} ${px(size.vpad_small)}`,
},
".keyword-bubble-no-padding": {
"max-width": "300px",
"border-radius": px(size.border_radius),
margin: px(size.vpad_small / 2),
"background-color": theme.secondary,
"background-color": theme.surface_container_high,
color: theme.on_surface,
},
".bubble-color": {
"background-color": theme.secondary,
color: theme.on_secondary,
"background-color": theme.surface_container_high,
color: theme.on_surface,
},
mark: {
"background-color": theme.primary,
@ -2054,17 +2050,13 @@ styles.registerStyle("main", () => {
},
".segmentControl-border": {
border: `1px solid ${theme.outline}`,
"padding-top": px(1),
"padding-bottom": px(1),
"padding-left": px(1),
"padding-right": px(1),
padding: "1px",
},
".segmentControl-border-active": {
border: `2px solid ${theme.primary}`,
"padding-top": px(0),
"padding-bottom": px(0),
"padding-left": px(0),
"padding-right": px(0),
color: theme.primary,
"font-weight": "bold",
padding: "2px",
},
".segmentControlItem": {
cursor: "pointer",
@ -2085,27 +2077,28 @@ styles.registerStyle("main", () => {
},
".icon-segment-control-item": {
// Make thin border between items via border-right
"border-top": `1px solid ${stateBgHover}`,
"border-bottom": `1px solid ${stateBgHover}`,
"border-right": `0.5px solid ${stateBgHover}`,
"border-top": `1px solid ${theme.outline_variant}`,
"border-bottom": `1px solid ${theme.outline_variant}`,
"border-right": `0.5px solid ${theme.outline_variant}`,
width: px(size.icon_segment_control_button_width),
height: px(size.icon_segment_control_button_height),
cursor: "pointer",
background: "transparent",
},
".icon-segment-control-item[active]": {
background: stateBgHover,
background: theme.secondary_container,
color: theme.on_secondary_container,
"transition-duration": ".3s",
},
".icon-segment-control-item:first-child": {
"border-bottom-left-radius": px(size.border_radius),
"border-top-left-radius": px(size.border_radius),
"border-left": `1px solid ${stateBgHover}`,
"border-left": `1px solid ${theme.outline_variant}`,
},
".icon-segment-control-item:last-child": {
"border-bottom-right-radius": px(size.border_radius),
"border-top-right-radius": px(size.border_radius),
"border-right": `1px solid ${stateBgHover}`,
"border-right": `1px solid ${theme.outline_variant}`,
},
".payment-logo": {
// that's the size of the SVG and it seems to be a good size
@ -2177,7 +2170,7 @@ styles.registerStyle("main", () => {
width: "100%",
},
".table-header-border tr:first-child": {
"border-bottom": `1px solid ${theme.outline}`,
"border-bottom": `1px solid ${theme.outline_variant}`,
},
".table td": {
"vertical-align": "middle",
@ -2379,7 +2372,7 @@ styles.registerStyle("main", () => {
display: "block",
width: px(size.checkbox_size),
height: px(size.checkbox_size),
border: `${px(size.checkbox_border_size)} solid ${theme.on_surface_variant}`,
border: `${px(size.checkbox_border_size)} solid ${theme.outline}`,
"border-radius": "3px",
position: "relative",
transition: `border ${DefaultAnimationTime}ms cubic-bezier(.4,.0,.23,1)`,
@ -2430,10 +2423,10 @@ styles.registerStyle("main", () => {
left: "-15px",
},
".checkbox:hover:before": {
background: stateBgHover,
background: theme.state_bg_hover,
},
".checkbox:active:before": {
background: stateBgActive,
background: theme.state_bg_active,
},
".list-checkbox": {
opacity: "0.4",
@ -2451,7 +2444,7 @@ styles.registerStyle("main", () => {
opacity: 0,
},
".calendar-hour": {
"border-bottom": `1px solid ${theme.outline}`,
"border-bottom": `1px solid ${theme.outline_variant}`,
height: px(size.calendar_hour_height),
flex: "1 0 auto",
},
@ -2504,10 +2497,13 @@ styles.registerStyle("main", () => {
"box-sizing": "content-box",
},
".calendar-current-day-circle": {
"background-color": theme.on_surface_variant,
"background-color": theme.primary,
},
".calendar-current-day-circle-small": {
"background-color": theme.primary,
},
".calendar-selected-day-circle": {
"background-color": theme.primary,
"background-color": theme.secondary_container,
},
".weekday-button-unselected-circle": {
border: `${px(1)} solid ${theme.primary}`,
@ -2520,11 +2516,15 @@ styles.registerStyle("main", () => {
height: "44px",
},
".calendar-current-day-text": {
color: theme.surface,
color: theme.on_primary,
"font-weight": "bold",
},
".calendar-current-day-text-small": {
color: theme.on_primary,
"font-weight": "bold",
},
".calendar-selected-day-text": {
color: theme.surface,
color: theme.on_secondary_container,
"font-weight": "bold",
},
".animation-reverse": {
@ -2628,7 +2628,7 @@ styles.registerStyle("main", () => {
},
".calendar-long-events-header": {
overflow: "hidden",
"border-bottom": `1px solid ${theme.outline}`,
"border-bottom": `1px solid ${theme.outline_variant}`,
},
".calendar-month-week-number": {
"font-size": "12px",
@ -2662,7 +2662,7 @@ styles.registerStyle("main", () => {
".custom-color-container .inputWrapper:before": {
// slash in content is content alt. so that it's ignored by screen readers
content: '"#" / ""',
color: theme.on_surface_fade,
color: theme.on_surface_variant,
},
".success-container": {
"background-color": theme.success_container,
@ -2948,7 +2948,7 @@ styles.registerStyle("main", () => {
color: theme.on_surface_variant,
},
".faded-text": {
color: theme.on_surface_fade,
color: theme.on_surface_variant,
},
".svg-text-content-bg text": {
fill: theme.surface,
@ -2999,16 +2999,16 @@ styles.registerStyle("main", () => {
outline: "medium invert color",
},
".tutaui-text-field:focus, .child-text-editor [role='textbox']:focus": {
"background-color": theme.secondary,
"background-color": theme.surface_container_high,
},
".tutaui-text-field::placeholder": {
color: theme.on_surface_fade,
color: theme.on_surface_variant,
},
".text-editor-placeholder": {
position: "absolute",
top: px(size.vpad_small),
left: px(size.vpad_small),
color: theme.on_surface_fade,
color: theme.on_surface_variant,
},
".tutaui-switch": {
display: "flex",
@ -3020,8 +3020,9 @@ styles.registerStyle("main", () => {
display: "block",
width: "45.5px",
height: "28px",
"background-color": theme.on_surface_fade,
"background-color": theme.surface_container_high,
"border-radius": px(size.vpad_small * 4),
border: `2px solid ${theme.outline}`,
transition: `background-color ${DefaultAnimationTime}ms ease-out`,
},
".tutaui-toggle-pill:after": {
@ -3035,7 +3036,7 @@ styles.registerStyle("main", () => {
"-ms-transform": "translateY(-50%)",
transform: "translateY(-50%)",
margin: "0 4px",
"background-color": "#fff",
"background-color": theme.outline,
"border-radius": "50%",
left: 0,
transition: `left ${DefaultAnimationTime}ms ease-out`,
@ -3048,9 +3049,11 @@ styles.registerStyle("main", () => {
},
".tutaui-toggle-pill.checked": {
"background-color": theme.primary,
border: `2px solid ${theme.primary}`,
},
".tutaui-toggle-pill.checked:after": {
left: "calc(100% - 29px)",
"background-color": theme.on_primary,
},
".tutaui-toggle-pill input[type='checkbox']": {
"z-index": "-1",
@ -3173,21 +3176,21 @@ styles.registerStyle("main", () => {
},
".search-highlight": {
"font-weight": "bold",
"background-color": theme.highlight_bg,
color: theme.highlight_fg,
"background-color": theme.secondary_container,
color: theme.on_secondary_container,
"border-radius": "3px",
},
".clip": {
overflow: "clip",
},
".skeleton-bg-1": {
background: theme.outline_variant,
background: theme.surface_container_high,
},
".skeleton-bg-2": {
background: theme.surface_container,
background: theme.surface,
},
".skeleton-border-1": {
"border-color": theme.outline_variant,
"border-color": theme.surface_container_high,
},
".skeleton:after": {
position: "absolute",
@ -3195,9 +3198,9 @@ styles.registerStyle("main", () => {
width: "100%",
height: "100%",
background: `linear-gradient(90deg,
${hexToRGBAString(theme.on_primary, 0)},
${hexToRGBAString(theme.on_primary, 0.3)},
${hexToRGBAString(theme.on_primary, 0)})`,
${hexToRGBAString(theme.on_surface_variant, 0)},
${hexToRGBAString(theme.on_surface_variant, 0.1)},
${hexToRGBAString(theme.on_surface_variant, 0)})`,
transform: "translateX(-100%)",
animation: "1.5s loading ease-in-out infinite",
},

View file

@ -60,7 +60,7 @@ export class DrawerMenu implements Component<DrawerMenuAttrs> {
top: px(0),
right: px(3),
},
color: "white",
color: theme.on_primary,
background: theme.primary,
})
: null,

View file

@ -37,7 +37,7 @@ class Styles {
} else {
this.themeColorMeta = document.createElement("meta")
this.themeColorMeta.name = "theme-color"
this.themeColorMeta.content = theme.navigation_bg
this.themeColorMeta.content = theme.surface_container
document.head.appendChild(this.themeColorMeta)
}
@ -132,7 +132,7 @@ class Styles {
this.updateDomStyle(entry[0], entry[1])
})
assertNotNull(this.themeColorMeta).content = theme.navigation_bg
assertNotNull(this.themeColorMeta).content = theme.surface_container
log(Cat.css, "creation time", time())
}

View file

@ -1,7 +1,5 @@
import { assertMainOrNodeBoot } from "../api/common/Env"
import { isColorLight } from "./base/Color"
import { logoDefaultGrey, tutaDunkel, tutaRed } from "./builtinThemes"
import { getTutaLogoSvg } from "./base/Logo.js"
assertMainOrNodeBoot()
@ -22,39 +20,25 @@ export type Theme = {
// Basic color tokens
primary: string
on_primary: string
primary_container: string
on_primary_container: string
secondary: string
on_secondary: string
error: string
secondary_container: string
on_secondary_container: string
tertiary: string
on_tertiary: string
tertiary_container: string
on_tertiary_container: string
surface: string
surface_container: string
/**
* @deprecated This token should not be used.
* It was created temporarily for the purpose of color theme migration.
*/
on_surface_fade: string
surface_container_high: string
surface_container_highest: string
on_surface: string
on_surface_variant: string
outline: string
outline_variant: string
scrim: string
// Campaign colors
content_bg_tuta_bday: string
content_accent_tuta_bday: string
content_accent_secondary_tuta_bday: string
error_container: string
on_error_container: string
success: string
success_container: string
on_success_container: string
tuta_color_nota: string
highlight_bg: string
highlight_fg: string
// Experimental colors; using material 3 color tokens which will be introduced in the future
experimental_primary_container: string
experimental_on_primary_container: string
experimental_tertiary: string
go_european: string
on_go_european: string
// semantic colors
error: string
on_error: string
@ -68,6 +52,29 @@ export type Theme = {
on_success: string
success_container: string
on_success_container: string
// State colors; These are not the Material 3 color tokens. We are not following the M3 guideline to simplify state representations.
state_bg_hover: string
state_bg_focus: string
state_bg_active: string
// Campaign colors; These colors are ONLY for campaign use.
content_bg_tuta_bday: string
content_accent_tuta_bday: string
content_accent_secondary_tuta_bday: string
tuta_color_nota: string
/**
* @deprecated Use not experimental color tokens instead.
*/
experimental_primary_container: string
/**
* @deprecated Use not experimental color tokens instead.
*/
experimental_on_primary_container: string
/**
* @deprecated Use not experimental color tokens instead.
*/
experimental_tertiary: string
go_european: string
on_go_european: string
}
const themeSingleton = {}
@ -108,7 +115,7 @@ export function getElevatedBackground(): string {
}
export function getNavigationMenuBg(): string {
return isColorLight(theme.surface) ? theme.secondary : theme.surface
return isColorLight(theme.surface) ? theme.surface_container_high : theme.surface
}
export function isDefaultLightTheme(): boolean {
@ -119,7 +126,7 @@ export function isDefaultLightTheme(): boolean {
* @return true if the current theme is a light theme
*/
export function isLightTheme(): boolean {
return isColorLight(theme.content_bg)
return isColorLight(theme.surface)
}
/**
@ -128,13 +135,3 @@ export function isLightTheme(): boolean {
export function isDarkTheme(): boolean {
return !isLightTheme()
}
export function getLightOrDarkTutaLogo(isCalendarApp: boolean): string {
// Use tuta logo with our brand colors
const isCalendarTheme = (theme.themeId === "light" && isCalendarApp) || (theme.themeId === "light_secondary" && !isCalendarApp)
if (isDefaultLightTheme() && !isCalendarTheme) {
return getTutaLogoSvg(tutaRed, tutaDunkel)
} else {
return getTutaLogoSvg(logoDefaultGrey, logoDefaultGrey)
}
}

View file

@ -21,7 +21,7 @@ export class NewsList implements Component<NewsListAttrs> {
return m(ColumnEmptyMessageBox, {
message: "noNews_msg",
icon: Icons.Bulb,
color: theme.on_surface_fade,
color: theme.on_surface_variant,
})
}

View file

@ -1,6 +1,5 @@
import m, { Children, Component, Vnode } from "mithril"
import { Button, ButtonType } from "../gui/base/Button.js"
import { getLightOrDarkTutaLogo } from "../gui/theme.js"
import { showUserError } from "../misc/ErrorHandlerImpl.js"
import { locator } from "../api/main/CommonLocator.js"
import { InfoLink } from "../misc/LanguageViewModel.js"
@ -10,7 +9,7 @@ import { clientInfoString, getLogAttachments } from "../misc/ErrorReporter.js"
import { ExternalLink } from "../gui/base/ExternalLink.js"
import { isApp } from "../api/common/Env.js"
import { px, size } from "../gui/size.js"
import { client } from "../misc/ClientDetector.js"
import { getTutaLogo } from "../gui/base/Logo.js"
interface AboutDialogAttrs {
onShowSetupWizard: () => unknown
@ -29,7 +28,7 @@ export class AboutDialog implements Component<AboutDialogAttrs> {
margin: px(size.vpad_xl),
},
},
m.trust(getLightOrDarkTutaLogo(client.isCalendarApp())),
m.trust(getTutaLogo()),
),
m(".flex.justify-center.flex-wrap", [
m(ExternalLink, {

View file

@ -119,7 +119,7 @@ export class UserListView implements UpdatableSettingsViewer {
},
this.listModel.isEmptyAndDone()
? m(ColumnEmptyMessageBox, {
color: theme.on_surface_fade,
color: theme.on_surface_variant,
icon: BootIcons.User,
message: "noEntries_msg",
})

View file

@ -67,7 +67,7 @@ export class FingerprintMismatchInfoPage implements Component<VerificationErrorI
size: IconSize.Medium,
class: "mr-s flex-center",
style: {
fill: theme.content_button_icon_selected,
fill: theme.on_primary,
},
}),
}),

View file

@ -62,7 +62,7 @@ export class SenderKeyVerificationRecoveryInfoPage implements Component<Verifica
size: IconSize.Large,
class: "mr-s flex-center",
style: {
fill: theme.content_button_icon_selected,
fill: theme.on_primary,
},
}),
}),

View file

@ -75,13 +75,13 @@ function getOutlineColor(isSelected: boolean) {
if (isSelected) {
return "transparent"
} else {
return theme.on_surface
return theme.outline_variant
}
} else {
if (isSelected) {
return "transparent"
} else {
return theme.on_surface
return theme.outline_variant
}
}
}

View file

@ -62,7 +62,7 @@ export class SetupLeavingUserSurveyPage implements Component<SetupLeavingUserSur
m(LoginButton, {
label: vnode.attrs.nextButtonLabel,
onclick: () => vnode.attrs.closeAction(),
class: vnode.attrs.nextButtonEnabled ? "no-hover button-bg" : "",
class: vnode.attrs.nextButtonEnabled ? "no-hover disabled-button" : "",
disabled: vnode.attrs.nextButtonEnabled,
}),
),

View file

@ -43,7 +43,7 @@ export class ContactListRecipientView implements Component<ContactListViewAttrs>
},
listModel == null || listModel.isEmptyAndDone()
? m(ColumnEmptyMessageBox, {
color: theme.on_surface_fade,
color: theme.on_surface_variant,
message: "noEntries_msg",
icon: Icons.People,
})

View file

@ -32,7 +32,7 @@ export class ContactListView implements ClassComponent<ContactListViewAttrs> {
},
contactViewModel.listModel.isEmptyAndDone()
? m(ColumnEmptyMessageBox, {
color: theme.on_surface_fade,
color: theme.on_surface_variant,
message: "noContacts_msg",
icon: BootIcons.Contacts,
})

View file

@ -412,7 +412,7 @@ export class ContactView extends BaseTopLevelView implements TopLevelView<Contac
? m(ColumnEmptyMessageBox, {
message: getContactListEntriesSelectionMessage(entries),
icon: Icons.People,
color: theme.on_surface_fade,
color: theme.on_surface_variant,
bottomContent:
entries.length > 0
? m(Button, {

View file

@ -23,7 +23,7 @@ export class MultiContactViewer implements Component<MultiContactViewerAttrs> {
m(ColumnEmptyMessageBox, {
message: getContactSelectionMessage(attrs.selectedEntities.length),
icon: BootIcons.Contacts,
color: theme.on_surface_fade,
color: theme.on_surface_variant,
bottomContent:
attrs.selectedEntities.length > 0
? m(Button, {

View file

@ -3,6 +3,7 @@ import m from "mithril"
import { styles } from "../../common/gui/styles"
import { px, size } from "../../common/gui/size"
import { Skeleton } from "../../common/gui/base/Skeleton"
import { theme } from "../../common/gui/theme.js"
export const EventBannerSkeleton = pureComponent(() =>
m(
@ -28,18 +29,21 @@ export const EventBannerSkeleton = pureComponent(() =>
style: {
width: "25px",
height: "20px",
backgroundColor: theme.surface_container_highest,
},
}),
m(Skeleton, {
style: {
width: "36px",
height: "40px",
backgroundColor: theme.surface_container_highest,
},
}),
m(Skeleton, {
style: {
width: "25px",
height: "20px",
backgroundColor: theme.surface_container_highest,
},
}),
]),

View file

@ -132,12 +132,12 @@ export class EventBannerImpl implements ClassComponent<EventBannerImplAttrs> {
"grid-template-columns": "min-content 1fr",
"grid-template-rows": "auto 1fr",
"max-width": "100%",
"border-color": bannerColor,
"border-color": theme.surface_container_high,
}
: {
"grid-template-columns": recipientIsOrganizer ? "min-content max-content" : "min-content min-content 1fr",
"max-width": recipientIsOrganizer ? "max-content" : px(size.two_column_layout_width),
"border-color": bannerColor,
"border-color": theme.surface_container_high,
},
},
[
@ -147,7 +147,8 @@ export class EventBannerImpl implements ClassComponent<EventBannerImplAttrs> {
{
class: styles.isSingleColumnLayout() ? "plr-vpad" : "pr-vpad-l pl-vpad-l",
style: {
"background-color": bannerColor,
"background-color": theme.surface_container_high,
color: theme.on_surface_variant,
},
},
[
@ -183,7 +184,8 @@ export class EventBannerImpl implements ClassComponent<EventBannerImplAttrs> {
{
class: styles.isSingleColumnLayout() ? "border-sm border-left-none border-right-none border-bottom-none" : "border-left-sm",
style: {
"border-color": bannerColor,
"border-color": theme.surface_container_high,
color: theme.on_surface,
},
},
[
@ -204,7 +206,9 @@ export class EventBannerImpl implements ClassComponent<EventBannerImplAttrs> {
icon: hasConflict ? Icons.AlertCircle : Icons.CheckCircleFilled,
container: "div",
class: "mr-xsm",
style: { fill: hasConflict ? theme.error : theme.success }, // TODO [colors] Use new material like colors tokens
style: {
fill: hasConflict ? theme.warning : theme.success,
}, // TODO [colors] Use new material like colors tokens
size: IconSize.Medium,
}),
this.renderConflictInfoText(agenda.conflictCount, agenda.allDayEvents),
@ -246,10 +250,14 @@ export class EventBannerImpl implements ClassComponent<EventBannerImplAttrs> {
)
: null,
isNotEmpty(allDayEvents)
? m("span.border-radius.button-bubble-bg.pt-xxs.pb-xxs.plr-sm.text-break", [
? m(
"span.border-radius.pt-xxs.pb-xxs.plr-sm.text-break",
{ style: { color: theme.on_warning_container, "background-color": theme.warning_container } },
[
m("strong", allDayEvents.length === 1 ? `1 ${lang.get("allDay_label").toLowerCase()}: ` : `${allDayEvents.length} `),
allDayEvents.length === 1 ? allDayEvents[0].event.summary : lang.get("allDay_label").toLowerCase(),
])
],
)
: null,
],
)
@ -268,7 +276,7 @@ export class EventBannerImpl implements ClassComponent<EventBannerImplAttrs> {
const children: Children = [] as ChildArray
const viewOnCalendarButton = m(BannerButton, {
borderColor: theme.on_surface,
borderColor: theme.outline,
color: theme.on_surface,
click: () => this.handleViewOnCalendarAction(agenda, event),
text: {
@ -535,7 +543,7 @@ export async function loadEventsAroundInvite(
}
if (eventList.conflictCount > 0) {
eventList.main.color = theme.error_container
eventList.main.color = theme.warning_container
}
eventToAgenda.set(iCalEvent.uid ?? "", eventList)
}

View file

@ -24,7 +24,7 @@ export class KnowledgeBaseListEntry implements Component<KnowledgebaseListEntryA
m(".text-ellipsis.mb-xs.b", title),
m(".flex.badge-line-height.text-ellipsis", [
keywords.map((keyword) => {
return m(".b.small.teamLabel.pl-s.pr-s.border-radius.no-wrap.small.mr-s.min-content", keyword.keyword)
return m("small.teamLabel.pl-s.pr-s.border-radius.no-wrap.small.mr-s.min-content", keyword.keyword)
}),
]),
],

View file

@ -393,7 +393,7 @@ export class MailEditor implements Component<MailEditorAttrs> {
elementToReplace.replaceWith(quoteWrap)
const quoteIndicator = document.createElement("div")
quoteIndicator.style.borderLeft = `2px solid ${theme.content_border}`
quoteIndicator.style.borderLeft = `2px solid ${theme.outline}`
quoteIndicator.style.paddingLeft = "2px"
quoteIndicator.style.marginTop = px(size.vpad)
@ -404,7 +404,7 @@ export class MailEditor implements Component<MailEditorAttrs> {
{
style: {
borderRadius: "25%",
border: `1px solid ${theme.list_border}`,
border: `1px solid ${theme.outline}`,
},
},
m(IconButton, {

View file

@ -7,7 +7,6 @@ import { px, size } from "../../../common/gui/size"
import { IconButton, IconButtonAttrs } from "../../../common/gui/base/IconButton.js"
import { Icon, IconSize } from "../../../common/gui/base/Icon.js"
import { Icons } from "../../../common/gui/base/icons/Icons.js"
import { stateBgHover } from "../../../common/gui/builtinThemes.js"
import { client } from "../../../common/misc/ClientDetector.js"
import { lang } from "../../../common/misc/LanguageViewModel.js"
import { MailFolder } from "../../../common/api/entities/tutanota/TypeRefs"
@ -60,7 +59,7 @@ export class MailFolderRow implements Component<MailFolderRowAttrs> {
".folder-row.flex.flex-row.mlr-button.border-radius-small.state-bg",
{
style: {
background: isNavButtonSelected(button) ? stateBgHover : "",
background: isNavButtonSelected(button) ? theme.state_bg_hover : "",
},
title: lang.getTranslationText(button.label),
onmouseenter: onHover,
@ -116,6 +115,7 @@ export class MailFolderRow implements Component<MailFolderRowAttrs> {
...button,
onfocus: onHover,
onkeydown: handleBackwardsTab,
disableSelectedBackground: true,
}),
// show the edit button in either edit mode or on hover (excluding hover on mobile)
rightButton && (editMode || (!client.isMobileDevice() && this.hovered))
@ -139,7 +139,7 @@ export class MailFolderRow implements Component<MailFolderRowAttrs> {
}
private renderHierarchyLine({ indentationLevel, numberOfPreviousRows, isLastSibling, onSelectedPath }: MailFolderRowAttrs, indentationMargin: number) {
const lineSize = 2
const lineSize = 1
const border = `${lineSize}px solid ${theme.outline}`
const verticalOffsetInsideRow = size.button_height / 2 + 1
const verticalOffsetForParent = (size.button_height - size.icon_size_large) / 2

View file

@ -362,7 +362,7 @@ export class MailListView implements Component<MailListViewAttrs> {
? m(ColumnEmptyMessageBox, {
icon: BootIcons.Mail,
message: "noMails_msg",
color: theme.on_surface_fade,
color: theme.on_surface_variant,
})
: m(List, {
state: listModel.stateStream(),

View file

@ -272,7 +272,7 @@ export class MailViewer implements Component<MailViewerAttrs> {
return m(IconMessageBox, {
message: "corrupted_msg",
icon: Icons.Warning,
color: theme.on_surface_fade,
color: theme.on_surface_variant,
})
}

View file

@ -30,7 +30,7 @@ export class MultiItemViewer<T> implements Component<MultiItemViewerAttrs<T>> {
m(ColumnEmptyMessageBox, {
message: attrs.getSelectionMessage(selectedEntities),
icon: BootIcons.Mail,
color: theme.on_surface_fade,
color: theme.on_surface_variant,
backgroundColor: theme.surface_container,
bottomContent: this.renderEmptyMessageButtons(attrs),
}),

View file

@ -61,7 +61,7 @@ export class SearchListView implements Component<SearchListViewAttrs> {
? m(ColumnEmptyMessageBox, {
icon,
message: "searchNoResults_msg",
color: theme.on_surface_fade,
color: theme.on_surface_variant,
})
: m(List, {
state: attrs.listModel.state,

View file

@ -750,7 +750,7 @@ export class SearchView extends BaseTopLevelView implements TopLevelView<SearchV
? m(ColumnEmptyMessageBox, {
message: "noEventSelect_msg",
icon: BootIcons.Calendar,
color: theme.on_surface_fade,
color: theme.on_surface_variant,
backgroundColor: theme.surface_container,
})
: this.renderEventPreview(selectedEvent),
@ -764,7 +764,7 @@ export class SearchView extends BaseTopLevelView implements TopLevelView<SearchV
".flex-grow.rel.overflow-hidden",
m(ColumnEmptyMessageBox, {
message: "noSelection_msg",
color: theme.on_surface_fade,
color: theme.on_surface_variant,
backgroundColor: theme.surface_container,
}),
),

View file

@ -50,7 +50,7 @@ export class DummyTemplateListView implements Component<DummyTemplateListViewAtt
m(
".fill-absolute.overflow-hidden",
m(ColumnEmptyMessageBox, {
color: theme.on_surface_fade,
color: theme.on_surface_variant,
icon: Icons.ListAlt,
message: "noEntries_msg",
}),

View file

@ -143,7 +143,7 @@ export class KnowledgeBaseListView implements UpdatableSettingsViewer {
},
this.listModel.isEmptyAndDone()
? m(ColumnEmptyMessageBox, {
color: theme.on_surface_fade,
color: theme.on_surface_variant,
icon: Icons.Book,
message: "noEntries_msg",
})

View file

@ -142,7 +142,7 @@ export class TemplateListView implements UpdatableSettingsViewer {
},
this.listModel.isEmptyAndDone()
? m(ColumnEmptyMessageBox, {
color: theme.on_surface_fade,
color: theme.on_surface_variant,
icon: Icons.ListAlt,
message: "noEntries_msg",
})

View file

@ -105,7 +105,7 @@ export class GroupListView implements UpdatableSettingsViewer {
},
this.listModel.isEmptyAndDone()
? m(ColumnEmptyMessageBox, {
color: theme.on_surface_fade,
color: theme.on_surface_variant,
icon: Icons.People,
message: "noEntries_msg",
})

View file

@ -31,7 +31,6 @@ import {
} from "../../../../src/common/api/common/utils/EntityUtils"
import { PageSize } from "../../../../src/common/gui/base/ListUtils"
import { createTestEntity } from "../../TestUtils"
import { tutaDunkel, tutaRed } from "../../../../src/common/gui/builtinThemes"
import { EntityUpdateData, PrefetchStatus } from "../../../../src/common/api/common/utils/EntityUpdateUtils"
import { MailboxDetail } from "../../../../src/common/mailFunctionality/MailboxModel"
import { GroupInfoTypeRef, GroupTypeRef } from "../../../../src/common/api/entities/sys/TypeRefs"
@ -39,6 +38,7 @@ import { ConnectionError } from "../../../../src/common/api/common/error/RestErr
import { assertNotNull, clamp, lastThrow, pad } from "@tutao/tutanota-utils"
import { LoadedMail } from "../../../../src/mail-app/mail/model/MailSetListModel"
import { ConversationListModel } from "../../../../src/mail-app/mail/model/ConversationListModel"
import { theme } from "../../../../src/common/gui/theme.js"
import { ListLoadingState } from "../../../../src/common/gui/base/List"
import { getMailFilterForType, MailFilterType } from "../../../../src/mail-app/mail/view/MailViewerUtils"
@ -61,17 +61,17 @@ o.spec("ConversationListModel", () => {
const labels: MailFolder[] = [
createTestEntity(MailFolderTypeRef, {
_id: ["mailFolderList", "tutaRed"],
color: tutaRed,
_id: ["mailFolderList", "tutaPrimary"],
color: theme.primary,
folderType: MailSetKind.LABEL,
name: "Tuta Red Label",
name: "Tuta Primary Label",
parentFolder: null,
}),
createTestEntity(MailFolderTypeRef, {
_id: ["mailFolderList", "tutaDunkel"],
color: tutaDunkel,
_id: ["mailFolderList", "tutaSecondary"],
color: theme.secondary,
folderType: MailSetKind.LABEL,
name: "Tuta Dunkel Label",
name: "Tuta Secondary Label",
parentFolder: null,
}),
]

View file

@ -31,7 +31,6 @@ import {
} from "../../../../src/common/api/common/utils/EntityUtils"
import { PageSize } from "../../../../src/common/gui/base/ListUtils"
import { createTestEntity } from "../../TestUtils"
import { tutaDunkel, tutaRed } from "../../../../src/common/gui/builtinThemes"
import { EntityUpdateData, PrefetchStatus } from "../../../../src/common/api/common/utils/EntityUpdateUtils"
import { MailboxDetail } from "../../../../src/common/mailFunctionality/MailboxModel"
import { GroupInfoTypeRef, GroupTypeRef } from "../../../../src/common/api/entities/sys/TypeRefs"
@ -39,6 +38,7 @@ import { ConnectionError } from "../../../../src/common/api/common/error/RestErr
import { clamp, pad } from "@tutao/tutanota-utils"
import { LoadedMail } from "../../../../src/mail-app/mail/model/MailSetListModel"
import { getMailFilterForType, MailFilterType } from "../../../../src/mail-app/mail/view/MailViewerUtils"
import { theme } from "../../../../src/common/gui/theme.js"
o.spec("MailListModel", () => {
let model: MailListModel
@ -59,17 +59,17 @@ o.spec("MailListModel", () => {
const labels: MailFolder[] = [
createTestEntity(MailFolderTypeRef, {
_id: ["mailFolderList", "tutaRed"],
color: tutaRed,
_id: ["mailFolderList", "tutaPrimary"],
color: theme.primary,
folderType: MailSetKind.LABEL,
name: "Tuta Red Label",
name: "Tuta Primary Label",
parentFolder: null,
}),
createTestEntity(MailFolderTypeRef, {
_id: ["mailFolderList", "tutaDunkel"],
color: tutaDunkel,
_id: ["mailFolderList", "tutaSecondary"],
color: theme.secondary,
folderType: MailSetKind.LABEL,
name: "Tuta Dunkel Label",
name: "Tuta Secondary Label",
parentFolder: null,
}),
]

View file

@ -18,7 +18,7 @@ o.spec("SimpleColorEditor", function () {
let defaultTheme
// These customizations should always be set if no changes are made
const defaultCustomizations: ThemeCustomizations = downcast({
primary: "#850122",
primary: "#8F4A4E",
base: "light",
})
let entityClient: EntityClient
@ -57,7 +57,7 @@ o.spec("SimpleColorEditor", function () {
entityClient,
loginController,
)
o(model.accentColor).equals("#850122")
o(model.accentColor).equals("#8F4A4E")
o(model.baseThemeId).equals("light")
o(themeController.applyCustomizations.callCount).equals(1)
})