aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FrontEnd/src/views/common/AppBar.css7
-rw-r--r--FrontEnd/src/views/common/button/Button.css21
-rw-r--r--FrontEnd/src/views/common/button/FlatButton.css6
-rw-r--r--FrontEnd/src/views/common/index.css4
-rw-r--r--FrontEnd/src/views/common/theme-color.css64
-rw-r--r--FrontEnd/src/views/common/theme.css30
-rw-r--r--FrontEnd/tools/theme-generator.ts230
7 files changed, 245 insertions, 117 deletions
diff --git a/FrontEnd/src/views/common/AppBar.css b/FrontEnd/src/views/common/AppBar.css
index 67fd9516..c278aa1e 100644
--- a/FrontEnd/src/views/common/AppBar.css
+++ b/FrontEnd/src/views/common/AppBar.css
@@ -37,18 +37,19 @@
display: flex;
align-items: center;
padding: 0 1em;
+ transition: all 0.5s;
}
.app-bar.desktop a:hover {
- filter: brightness(var(--cru-hover-brightness));
+ background-color: var(--cru-primary-1-color);
}
.app-bar.desktop a:focus {
- filter: brightness(var(--cru-focus-brightness));
+ background-color: var(--cru-primary-1-color);
}
.app-bar.desktop a:active {
- filter: brightness(var(--cru-press-brightness));
+ background-color: var(--cru-primary-2-color);
}
.app-bar.desktop .app-bar-user-area {
diff --git a/FrontEnd/src/views/common/button/Button.css b/FrontEnd/src/views/common/button/Button.css
index dacea3e1..55563e00 100644
--- a/FrontEnd/src/views/common/button/Button.css
+++ b/FrontEnd/src/views/common/button/Button.css
@@ -14,15 +14,18 @@
}
.cru-button:not(.outline):hover {
- filter: brightness(var(--cru-hover-darkness));
+ background-color: var(--cru-key-1-color);
+ border-color: var(--cru-key-1-color);
}
.cru-button:not(.outline):focus {
- filter: brightness(var(--cru-focus-darkness));
+ background-color: var(--cru-key-1-color);
+ border-color: var(--cru-key-1-color);
}
.cru-button:not(.outline):active {
- filter: brightness(var(--cru-press-darkness));
+ background-color: var(--cru-key-2-color);
+ border-color: var(--cru-key-2-color);
}
.cru-button:not(.outline):disabled {
@@ -33,20 +36,22 @@
.cru-button.outline {
color: var(--cru-key-color);
- border: var(--cru-key-color) 1px solid;
- background-color: var(--cru-surface-color);
+ border-color: var(--cru-key-color);
}
.cru-button.outline:hover {
- filter: brightness(var(--cru-hover-brightness));
+ color: var(--cru-key-1-color);
+ border-color: var(--cru-key-1-color);
}
.cru-button.outline:focus {
- filter: brightness(var(--cru-focus-brightness));
+ color: var(--cru-key-1-color);
+ border-color: var(--cru-key-1-color);
}
.cru-button.outline:active {
- filter: brightness(var(--cru-press-brightness));
+ color: var(--cru-key-2-color);
+ border-color: var(--cru-key-2-color);
}
.cru-button.outline:disabled {
diff --git a/FrontEnd/src/views/common/button/FlatButton.css b/FrontEnd/src/views/common/button/FlatButton.css
index f9a7d772..921fafe4 100644
--- a/FrontEnd/src/views/common/button/FlatButton.css
+++ b/FrontEnd/src/views/common/button/FlatButton.css
@@ -10,15 +10,15 @@
}
.cru-flat-button:hover {
- filter: brightness(var(--cru-hover-darkness));
+ background-color: var(--cru-surface-1-color);
}
.cru-flat-button:focus {
- filter: brightness(var(--cru-focus-darkness));
+ background-color: var(--cru-surface-1-color);
}
.cru-flat-button:active {
- filter: brightness(var(--cru-press-darkness));
+ background-color: var(--cru-surface-2-color);
}
.cru-flat-button.disabled {
diff --git a/FrontEnd/src/views/common/index.css b/FrontEnd/src/views/common/index.css
index f87fdfd2..789a0f05 100644
--- a/FrontEnd/src/views/common/index.css
+++ b/FrontEnd/src/views/common/index.css
@@ -12,6 +12,10 @@ body {
color: var(--cru-surface-on-color);
}
+button {
+ background-color: unset;
+}
+
.cru-text-center {
text-align: center;
}
diff --git a/FrontEnd/src/views/common/theme-color.css b/FrontEnd/src/views/common/theme-color.css
index 7cb9a8f8..24a7e267 100644
--- a/FrontEnd/src/views/common/theme-color.css
+++ b/FrontEnd/src/views/common/theme-color.css
@@ -2,27 +2,49 @@
:root {
--cru-primary-color: hsl(210 100% 40%);
+ --cru-primary-1-color: hsl(210 100% 37%);
+ --cru-primary-2-color: hsl(210 100% 34%);
--cru-primary-on-color: hsl(210 100% 100%);
--cru-primary-container-color: hsl(210 100% 90%);
+ --cru-primary-container-1-color: hsl(210 100% 80%);
+ --cru-primary-container-2-color: hsl(210 100% 70%);
--cru-primary-on-container-color: hsl(210 100% 10%);
--cru-secondary-color: hsl(40 100% 40%);
+ --cru-secondary-1-color: hsl(40 100% 37%);
+ --cru-secondary-2-color: hsl(40 100% 34%);
--cru-secondary-on-color: hsl(40 100% 100%);
--cru-secondary-container-color: hsl(40 100% 90%);
+ --cru-secondary-container-1-color: hsl(40 100% 80%);
+ --cru-secondary-container-2-color: hsl(40 100% 70%);
--cru-secondary-on-container-color: hsl(40 100% 10%);
--cru-tertiary-color: hsl(160 100% 40%);
+ --cru-tertiary-1-color: hsl(160 100% 37%);
+ --cru-tertiary-2-color: hsl(160 100% 34%);
--cru-tertiary-on-color: hsl(160 100% 100%);
--cru-tertiary-container-color: hsl(160 100% 90%);
+ --cru-tertiary-container-1-color: hsl(160 100% 80%);
+ --cru-tertiary-container-2-color: hsl(160 100% 70%);
--cru-tertiary-on-container-color: hsl(160 100% 10%);
--cru-danger-color: hsl(0 100% 40%);
+ --cru-danger-1-color: hsl(0 100% 37%);
+ --cru-danger-2-color: hsl(0 100% 34%);
--cru-danger-on-color: hsl(0 100% 100%);
--cru-danger-container-color: hsl(0 100% 90%);
+ --cru-danger-container-1-color: hsl(0 100% 80%);
+ --cru-danger-container-2-color: hsl(0 100% 70%);
--cru-danger-on-container-color: hsl(0 100% 10%);
--cru-success-color: hsl(120 60% 40%);
+ --cru-success-1-color: hsl(120 60% 37%);
+ --cru-success-2-color: hsl(120 60% 34%);
--cru-success-on-color: hsl(120 60% 100%);
--cru-success-container-color: hsl(120 60% 90%);
+ --cru-success-container-1-color: hsl(120 60% 80%);
+ --cru-success-container-2-color: hsl(120 60% 70%);
--cru-success-on-container-color: hsl(120 60% 10%);
--cru-surface-dim-color: hsl(0 0% 87%);
--cru-surface-color: hsl(0 0% 98%);
+ --cru-surface-1-color: hsl(0 0% 90%);
+ --cru-surface-2-color: hsl(0 0% 82%);
--cru-surface-bright-color: hsl(0 0% 98%);
--cru-surface-container-lowest-color: hsl(0 0% 100%);
--cru-surface-container-low-color: hsl(0 0% 96%);
@@ -38,27 +60,49 @@
@media (prefers-color-scheme: dark) {
:root {
--cru-primary-color: hsl(210 100% 80%);
+ --cru-primary-1-color: hsl(210 100% 75%);
+ --cru-primary-2-color: hsl(210 100% 68%);
--cru-primary-on-color: hsl(210 100% 20%);
--cru-primary-container-color: hsl(210 100% 30%);
+ --cru-primary-container-1-color: hsl(210 100% 25%);
+ --cru-primary-container-2-color: hsl(210 100% 20%);
--cru-primary-on-container-color: hsl(210 100% 90%);
--cru-secondary-color: hsl(40 100% 80%);
+ --cru-secondary-1-color: hsl(40 100% 75%);
+ --cru-secondary-2-color: hsl(40 100% 68%);
--cru-secondary-on-color: hsl(40 100% 20%);
--cru-secondary-container-color: hsl(40 100% 30%);
+ --cru-secondary-container-1-color: hsl(40 100% 25%);
+ --cru-secondary-container-2-color: hsl(40 100% 20%);
--cru-secondary-on-container-color: hsl(40 100% 90%);
--cru-tertiary-color: hsl(160 100% 80%);
+ --cru-tertiary-1-color: hsl(160 100% 75%);
+ --cru-tertiary-2-color: hsl(160 100% 68%);
--cru-tertiary-on-color: hsl(160 100% 20%);
--cru-tertiary-container-color: hsl(160 100% 30%);
+ --cru-tertiary-container-1-color: hsl(160 100% 25%);
+ --cru-tertiary-container-2-color: hsl(160 100% 20%);
--cru-tertiary-on-container-color: hsl(160 100% 90%);
--cru-danger-color: hsl(0 100% 80%);
+ --cru-danger-1-color: hsl(0 100% 75%);
+ --cru-danger-2-color: hsl(0 100% 68%);
--cru-danger-on-color: hsl(0 100% 20%);
--cru-danger-container-color: hsl(0 100% 30%);
+ --cru-danger-container-1-color: hsl(0 100% 25%);
+ --cru-danger-container-2-color: hsl(0 100% 20%);
--cru-danger-on-container-color: hsl(0 100% 90%);
--cru-success-color: hsl(120 60% 80%);
+ --cru-success-1-color: hsl(120 60% 75%);
+ --cru-success-2-color: hsl(120 60% 68%);
--cru-success-on-color: hsl(120 60% 20%);
--cru-success-container-color: hsl(120 60% 30%);
+ --cru-success-container-1-color: hsl(120 60% 25%);
+ --cru-success-container-2-color: hsl(120 60% 20%);
--cru-success-on-container-color: hsl(120 60% 90%);
--cru-surface-dim-color: hsl(0 0% 6%);
--cru-surface-color: hsl(0 0% 6%);
+ --cru-surface-1-color: hsl(0 0% 25%);
+ --cru-surface-2-color: hsl(0 0% 40%);
--cru-surface-bright-color: hsl(0 0% 24%);
--cru-surface-container-lowest-color: hsl(0 0% 4%);
--cru-surface-container-low-color: hsl(0 0% 10%);
@@ -74,36 +118,56 @@
.cru-primary {
--cru-key-color: var(--cru-primary-color);
+ --cru-key-1-color: var(--cru-primary-1-color);
+ --cru-key-2-color: var(--cru-primary-2-color);
--cru-key-on-color: var(--cru-primary-on-color);
--cru-key-container-color: var(--cru-primary-container-color);
+ --cru-key-container-1-color: var(--cru-primary-container-1-color);
+ --cru-key-container-2-color: var(--cru-primary-container-2-color);
--cru-key-on-container-color: var(--cru-primary-on-container-color);
}
.cru-secondary {
--cru-key-color: var(--cru-secondary-color);
+ --cru-key-1-color: var(--cru-secondary-1-color);
+ --cru-key-2-color: var(--cru-secondary-2-color);
--cru-key-on-color: var(--cru-secondary-on-color);
--cru-key-container-color: var(--cru-secondary-container-color);
+ --cru-key-container-1-color: var(--cru-secondary-container-1-color);
+ --cru-key-container-2-color: var(--cru-secondary-container-2-color);
--cru-key-on-container-color: var(--cru-secondary-on-container-color);
}
.cru-tertiary {
--cru-key-color: var(--cru-tertiary-color);
+ --cru-key-1-color: var(--cru-tertiary-1-color);
+ --cru-key-2-color: var(--cru-tertiary-2-color);
--cru-key-on-color: var(--cru-tertiary-on-color);
--cru-key-container-color: var(--cru-tertiary-container-color);
+ --cru-key-container-1-color: var(--cru-tertiary-container-1-color);
+ --cru-key-container-2-color: var(--cru-tertiary-container-2-color);
--cru-key-on-container-color: var(--cru-tertiary-on-container-color);
}
.cru-danger {
--cru-key-color: var(--cru-danger-color);
+ --cru-key-1-color: var(--cru-danger-1-color);
+ --cru-key-2-color: var(--cru-danger-2-color);
--cru-key-on-color: var(--cru-danger-on-color);
--cru-key-container-color: var(--cru-danger-container-color);
+ --cru-key-container-1-color: var(--cru-danger-container-1-color);
+ --cru-key-container-2-color: var(--cru-danger-container-2-color);
--cru-key-on-container-color: var(--cru-danger-on-container-color);
}
.cru-success {
--cru-key-color: var(--cru-success-color);
+ --cru-key-1-color: var(--cru-success-1-color);
+ --cru-key-2-color: var(--cru-success-2-color);
--cru-key-on-color: var(--cru-success-on-color);
--cru-key-container-color: var(--cru-success-container-color);
+ --cru-key-container-1-color: var(--cru-success-container-1-color);
+ --cru-key-container-2-color: var(--cru-success-container-2-color);
--cru-key-on-container-color: var(--cru-success-on-container-color);
}
diff --git a/FrontEnd/src/views/common/theme.css b/FrontEnd/src/views/common/theme.css
index 6cbc06b4..9c9e1645 100644
--- a/FrontEnd/src/views/common/theme.css
+++ b/FrontEnd/src/views/common/theme.css
@@ -1,36 +1,6 @@
@import "./theme-color.css";
:root {
- --cru-hover-lightness-change: 4%;
- --cru-focus-lightness-change: 10%;
- --cru-press-lightness-change: 10%;
- --cru-drag-lightness-change: 15%;
-
- --cru-hover-darkness: calc(100% - var(--cru-hover-lightness-change));
- --cru-focus-darkness: calc(100% - var(--cru-focus-lightness-change));
- --cru-press-darkness: calc(100% - var(--cru-press-lightness-change));
- --cru-drag-darkness: calc(100% - var(--cru-drag-lightness-change));
- --cru-hover-brightness: calc(100% + var(--cru-hover-lightness-change));
- --cru-focus-brightness: calc(100% + var(--cru-focus-lightness-change));
- --cru-press-brightness: calc(100% + var(--cru-press-lightness-change));
- --cru-drag-brightness: calc(100% + var(--cru-drag-lightness-change));
-}
-
-/*
-:hover {
- filter: brightness(var(--cru-hover-darkness));
-}
-
-:focus {
- filter: brightness(var(--cru-focus-darkness));
-}
-
-:active {
- filter: brightness(var(--cru-press-darkness));
-}
-*/
-
-:root {
--cru-default-font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
--cru-card-border-radius: 8px;
} \ No newline at end of file
diff --git a/FrontEnd/tools/theme-generator.ts b/FrontEnd/tools/theme-generator.ts
index c1036d80..3583d240 100644
--- a/FrontEnd/tools/theme-generator.ts
+++ b/FrontEnd/tools/theme-generator.ts
@@ -96,7 +96,7 @@ abstract class ColorGroup implements CssSegment {
}
interface LightnessVariantInfo {
- variant: string;
+ name: string;
lightness: number;
}
@@ -105,7 +105,7 @@ class LightnessVariantColorGroup extends ColorGroup {
public prefix: string,
public name: string,
public baseColor: HslColor,
- public lightnessVariants: LightnessVariantInfo[],
+ public variants: LightnessVariantInfo[],
) {
super();
}
@@ -113,11 +113,11 @@ class LightnessVariantColorGroup extends ColorGroup {
getColorVariables(): ColorVariableDefinition[] {
const result: ColorVariableDefinition[] = [];
- for (const lightnessVariant of this.lightnessVariants) {
- const color = this.baseColor.withLightness(lightnessVariant.lightness);
+ for (const variant of this.variants) {
+ const color = this.baseColor.withLightness(variant.lightness);
result.push(
new ColorVariableDefinition(
- new ColorVariable(this.prefix, this.name, lightnessVariant.variant),
+ new ColorVariable(this.prefix, this.name, variant.name),
color,
),
);
@@ -165,181 +165,265 @@ class CompositeColorGroup extends ColorGroup {
}
}
-interface ThemeColors {
+interface ThemeColorsInfo {
keyColors: { name: string; color: HslColor }[];
neutralColor: HslColor;
}
type ColorMode = "light" | "dark";
-interface ColorModeColorVariant {
- variant: string;
- lightness: { light: number; dark: number };
+type ThemeColorVariantLightnessVariantsInfo =
+ | number
+ | number[]
+ | {
+ base: number;
+ direction: "darker" | "lighter";
+ levels: number;
+ step: number;
+ };
+
+interface ThemeColorVariantInfo {
+ name: string;
+ variants: {
+ light: ThemeColorVariantLightnessVariantsInfo;
+ dark: ThemeColorVariantLightnessVariantsInfo;
+ };
+}
+
+class ThemeColorVariant {
+ constructor(
+ public name: string,
+ public variants: {
+ light: ThemeColorVariantLightnessVariantsInfo;
+ dark: ThemeColorVariantLightnessVariantsInfo;
+ },
+ ) {}
+ getLightnessVariants(mode: ColorMode): LightnessVariantInfo[] {
+ const { name, variants } = this;
+ const list = variants[mode];
+
+ function variantName(i: number) {
+ if (name.length === 0) {
+ return i === 0 ? "" : String(i);
+ } else {
+ return i === 0 ? name : `${name}-${i}`;
+ }
+ }
+
+ function fromList(list: number[]): LightnessVariantInfo[] {
+ return list.map((l, i) => ({
+ name: variantName(i),
+ lightness: l,
+ }));
+ }
+
+ if (typeof list === "number") {
+ return fromList([list]);
+ } else if (Array.isArray(list)) {
+ return fromList(list);
+ } else {
+ const l = [list.base];
+ for (let i = 1; i <= list.levels; i++) {
+ if (list.direction === "darker") {
+ l.push(list.base - i * list.step);
+ } else {
+ l.push(list.base + i * list.step);
+ }
+ }
+ return fromList(l);
+ }
+ }
+
+ static from(info: ThemeColorVariantInfo): ThemeColorVariant {
+ return new ThemeColorVariant(info.name, info.variants);
+ }
+}
+
+class ThemeColor {
+ variants: ThemeColorVariant[];
+
+ constructor(
+ public prefix: string,
+ public name: string,
+ public color: HslColor,
+ variants: ThemeColorVariantInfo[],
+ ) {
+ this.variants = variants.map((v) => ThemeColorVariant.from(v));
+ }
+
+ getLightnessVariants(mode: ColorMode): LightnessVariantInfo[] {
+ return this.variants.flatMap((v) => v.getLightnessVariants(mode));
+ }
+
+ getLightnessVariantColorGroup(mode: ColorMode): LightnessVariantColorGroup {
+ return new LightnessVariantColorGroup(
+ this.prefix,
+ this.name,
+ this.color,
+ this.getLightnessVariants(mode),
+ );
+ }
}
class Theme {
- static keyColorVariants: ColorModeColorVariant[] = [
+ static keyColorVariants: ThemeColorVariantInfo[] = [
{
- variant: "",
- lightness: {
- light: 40,
- dark: 80,
+ name: "",
+ variants: {
+ light: [40, 37, 34],
+ dark: [80, 75, 68],
},
},
{
- variant: "on",
- lightness: {
+ name: "on",
+ variants: {
light: 100,
dark: 20,
},
},
{
- variant: "container",
- lightness: {
- light: 90,
- dark: 30,
+ name: "container",
+ variants: {
+ light: [90, 80, 70],
+ dark: [30, 25, 20],
},
},
{
- variant: "on-container",
- lightness: {
+ name: "on-container",
+ variants: {
light: 10,
dark: 90,
},
},
];
- static surfaceColorVariants: ColorModeColorVariant[] = [
+ static surfaceColorVariants: ThemeColorVariantInfo[] = [
{
- variant: "dim",
- lightness: {
+ name: "dim",
+ variants: {
light: 87,
dark: 6,
},
},
{
- variant: "",
- lightness: {
- light: 98,
- dark: 6,
+ name: "",
+ variants: {
+ light: [98, 90, 82],
+ dark: [6, 25, 40],
},
},
{
- variant: "bright",
- lightness: {
+ name: "bright",
+ variants: {
light: 98,
dark: 24,
},
},
{
- variant: "container-lowest",
- lightness: {
+ name: "container-lowest",
+ variants: {
light: 100,
dark: 4,
},
},
{
- variant: "container-low",
- lightness: {
+ name: "container-low",
+ variants: {
light: 96,
dark: 10,
},
},
{
- variant: "container",
- lightness: {
+ name: "container",
+ variants: {
light: 94,
dark: 12,
},
},
{
- variant: "container-high",
- lightness: {
+ name: "container-high",
+ variants: {
light: 92,
dark: 17,
},
},
{
- variant: "container-highest",
- lightness: {
+ name: "container-highest",
+ variants: {
light: 90,
dark: 22,
},
},
{
- variant: "on",
- lightness: {
+ name: "on",
+ variants: {
light: 10,
dark: 90,
},
},
{
- variant: "on-variant",
- lightness: {
+ name: "on-variant",
+ variants: {
light: 30,
dark: 80,
},
},
{
- variant: "outline",
- lightness: {
+ name: "outline",
+ variants: {
light: 50,
dark: 60,
},
},
{
- variant: "outline-variant",
- lightness: {
+ name: "outline-variant",
+ variants: {
light: 80,
dark: 30,
},
},
];
- static getLightnessVariants(
- mode: ColorMode,
- colorModeColorVariants: ColorModeColorVariant[],
- ): LightnessVariantInfo[] {
- return colorModeColorVariants.map((v) => ({
- variant: v.variant,
- lightness: v.lightness[mode],
- }));
- }
-
constructor(
public prefix: string,
- public themeColors: ThemeColors,
- public levels = 3,
+ public themeColors: ThemeColorsInfo,
) {}
getColorModeColorDefinitions(mode: ColorMode): ColorGroup {
const groups: ColorGroup[] = [];
for (const { name, color } of this.themeColors.keyColors) {
- const colorGroup = new LightnessVariantColorGroup(
+ const themeColor = new ThemeColor(
this.prefix,
name,
color,
- Theme.getLightnessVariants(mode, Theme.keyColorVariants),
+ Theme.keyColorVariants,
);
- groups.push(colorGroup);
+ groups.push(themeColor.getLightnessVariantColorGroup(mode));
}
- groups.push(
- new LightnessVariantColorGroup(
- this.prefix,
- "surface",
- this.themeColors.neutralColor,
- Theme.getLightnessVariants(mode, Theme.surfaceColorVariants),
- ),
+ const neutralThemeColor = new ThemeColor(
+ this.prefix,
+ "surface",
+ this.themeColors.neutralColor,
+ Theme.surfaceColorVariants,
);
+ groups.push(neutralThemeColor.getLightnessVariantColorGroup(mode));
return new CompositeColorGroup(groups);
}
getAliasColorDefinitions(name: string): ColorGroup {
+ const sampleThemeColor = this.themeColors.keyColors[0];
+ const themeColor = new ThemeColor(
+ this.prefix,
+ sampleThemeColor.name,
+ sampleThemeColor.color,
+ Theme.keyColorVariants,
+ );
+ const sampleMode = "light";
return new VarAliasColorGroup(
this.prefix,
"key",
name,
- Theme.keyColorVariants.map((v) => v.variant),
+ themeColor.getLightnessVariants(sampleMode).map((v) => v.name),
);
}
@@ -370,7 +454,7 @@ class Theme {
(function main() {
const prefix = "cru";
- const themeColors: ThemeColors = {
+ const themeColors: ThemeColorsInfo = {
keyColors: [
{ name: "primary", color: new HslColor(210, 100, 50) },
{ name: "secondary", color: new HslColor(40, 100, 50) },