enhance(theme): derive theme colors with color-mix and unify shades (#40113)

Derive theme colors from a few base colors with `color-mix(in srgb, …)`
and make the colorful palette coherent, so custom themes that import a
Gitea theme can override a base color and get matching shades.

- Every `-light`, `-dark-1` and `-dark-2` shade follows one rule for all
hues, fixing dark orange shades copied from the light theme, black
shades that barely moved and neon tints
- Base colors move at most 4 OKLab units toward a common lightness, the
median in dark and red in light, yellow stays unchanged
- Text, secondary, console, message, surface and alpha colors derive
from their own base, alpha variants now match their names
- Added and removed diff colors share one lightness per level in all
themes, including colorblind ones
- Chart.js and the external render iframe resolve `color-mix()` values
to hex through `getComputedStyle`
- Remove unused `secondary-dark-12`, `-13`, `shadow-opaque` and
`workflow-edge-hover`

Fixes: https://github.com/go-gitea/gitea/issues/30160

<img width="880" alt="Components with the largest color changes, dark
and light, before and after"
src="https://github.com/user-attachments/assets/a9d27636-e3bb-46fa-a3ac-3fec33fd9806"
/>
<img width="880" alt="All theme colors per family, before and after,
unchanged ones dimmed"
src="https://github.com/user-attachments/assets/9977dde3-0749-4926-b110-18c0dc31d632"
/>

---------

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
silverwind
2026-11-07 23:39:15 +00:00
committed by GitHub
parent c54ec52f0f
commit bd8fd71bc1
13 changed files with 357 additions and 345 deletions

View File

@@ -8,12 +8,12 @@ gitea-theme-meta-info {
/* red/green colorblind-friendly colors */
:root {
--color-diff-added-fg: #58a6ff;
--color-diff-added-linenum-bg: #243d5d;
--color-diff-added-row-bg: #132339;
--color-diff-added-word-bg: #214d87;
--color-diff-removed-fg: #f0883e;
--color-diff-removed-linenum-bg: #5b361c;
--color-diff-removed-row-bg: #3c2419;
--color-diff-removed-word-bg: #824e1f;
--color-diff-added-fg: #509ef6;
--color-diff-added-linenum-bg: #274161;
--color-diff-added-row-bg: #18283e;
--color-diff-added-word-bg: #1c4882;
--color-diff-removed-fg: #e37c30;
--color-diff-removed-linenum-bg: #5a351b;
--color-diff-removed-row-bg: #382116;
--color-diff-removed-word-bg: #6c3a04;
}

View File

@@ -8,8 +8,8 @@ gitea-theme-meta-info {
/* blue/yellow colorblind-friendly colors */
:root {
--color-diff-added-fg: #58a6ff;
--color-diff-added-linenum-bg: #243d5d;
--color-diff-added-row-bg: #132339;
--color-diff-added-word-bg: #214d87;
--color-diff-added-fg: #509ef6;
--color-diff-added-linenum-bg: #274161;
--color-diff-added-row-bg: #18283e;
--color-diff-added-word-bg: #1c4882;
}

View File

@@ -7,120 +7,118 @@ gitea-theme-meta-info {
--is-dark-theme: true;
--color-primary: #4183c4;
--color-primary-contrast: #ffffff;
--color-primary-dark-1: #548fca;
--color-primary-dark-2: #679cd0;
--color-primary-dark-3: #7aa8d6;
--color-primary-dark-4: #8db5dc;
--color-primary-dark-5: #b3cde7;
--color-primary-dark-6: #d9e6f3;
--color-primary-dark-7: #f4f8fb;
--color-primary-light-1: #3876b3;
--color-primary-light-2: #31699f;
--color-primary-light-3: #2b5c8b;
--color-primary-light-4: #254f77;
--color-primary-light-5: #193450;
--color-primary-light-6: #0c1a28;
--color-primary-light-7: #04080c;
--color-primary-alpha-10: #4183c419;
--color-primary-alpha-20: #4183c433;
--color-primary-alpha-30: #4183c44b;
--color-primary-alpha-40: #4183c466;
--color-primary-alpha-50: #4183c480;
--color-primary-alpha-60: #4183c499;
--color-primary-alpha-70: #4183c4b3;
--color-primary-alpha-80: #4183c4cc;
--color-primary-alpha-90: #4183c4e1;
--color-primary-dark-1: color-mix(in srgb, var(--color-primary) 90%, white);
--color-primary-dark-2: color-mix(in srgb, var(--color-primary) 80%, white);
--color-primary-dark-3: color-mix(in srgb, var(--color-primary) 70%, white);
--color-primary-dark-4: color-mix(in srgb, var(--color-primary) 60%, white);
--color-primary-dark-5: color-mix(in srgb, var(--color-primary) 40%, white);
--color-primary-dark-6: color-mix(in srgb, var(--color-primary) 20%, white);
--color-primary-dark-7: color-mix(in srgb, var(--color-primary) 6%, white);
--color-primary-light-1: color-mix(in srgb, var(--color-primary) 90%, black);
--color-primary-light-2: color-mix(in srgb, var(--color-primary) 80%, black);
--color-primary-light-3: color-mix(in srgb, var(--color-primary) 70%, black);
--color-primary-light-4: color-mix(in srgb, var(--color-primary) 60%, black);
--color-primary-light-5: color-mix(in srgb, var(--color-primary) 40%, black);
--color-primary-light-6: color-mix(in srgb, var(--color-primary) 20%, black);
--color-primary-light-7: color-mix(in srgb, var(--color-primary) 6%, black);
--color-primary-alpha-10: color-mix(in srgb, var(--color-primary) 10%, transparent);
--color-primary-alpha-20: color-mix(in srgb, var(--color-primary) 20%, transparent);
--color-primary-alpha-30: color-mix(in srgb, var(--color-primary) 30%, transparent);
--color-primary-alpha-40: color-mix(in srgb, var(--color-primary) 40%, transparent);
--color-primary-alpha-50: color-mix(in srgb, var(--color-primary) 50%, transparent);
--color-primary-alpha-60: color-mix(in srgb, var(--color-primary) 60%, transparent);
--color-primary-alpha-70: color-mix(in srgb, var(--color-primary) 70%, transparent);
--color-primary-alpha-80: color-mix(in srgb, var(--color-primary) 80%, transparent);
--color-primary-alpha-90: color-mix(in srgb, var(--color-primary) 90%, transparent);
--color-primary-hover: var(--color-primary-light-1);
--color-primary-active: var(--color-primary-light-2);
--color-secondary: #3f4248;
--color-secondary-dark-1: #46494f;
--color-secondary-dark-2: #4f5259;
--color-secondary-dark-3: #5e626a;
--color-secondary-dark-4: #6f747d;
--color-secondary-dark-5: #7d828c;
--color-secondary-dark-6: #8b8f98;
--color-secondary-dark-7: #999da4;
--color-secondary-dark-8: #a8abb1;
--color-secondary-dark-9: #aeb1b8;
--color-secondary-dark-10: #bbbec3;
--color-secondary-dark-11: #c8cacf;
--color-secondary-dark-12: #d2d4d7;
--color-secondary-dark-13: #d5d6d9;
--color-secondary-light-1: #35373c;
--color-secondary-light-2: #2c2e32;
--color-secondary-light-3: #1f2124;
--color-secondary-light-4: #191a1c;
--color-secondary-alpha-10: #3f424819;
--color-secondary-alpha-20: #3f424833;
--color-secondary-alpha-30: #3f42484b;
--color-secondary-alpha-40: #3f424866;
--color-secondary-alpha-50: #3f424880;
--color-secondary-alpha-60: #3f424899;
--color-secondary-alpha-70: #3f4248b3;
--color-secondary-alpha-80: #3f4248cc;
--color-secondary-alpha-90: #3f4248e1;
--color-secondary-dark-1: color-mix(in srgb, var(--color-secondary) 96%, var(--color-text-dark));
--color-secondary-dark-2: color-mix(in srgb, var(--color-secondary) 91%, var(--color-text-dark));
--color-secondary-dark-3: color-mix(in srgb, var(--color-secondary) 82%, var(--color-text-dark));
--color-secondary-dark-4: color-mix(in srgb, var(--color-secondary) 73%, var(--color-text-dark));
--color-secondary-dark-5: color-mix(in srgb, var(--color-secondary) 65%, var(--color-text-dark));
--color-secondary-dark-6: color-mix(in srgb, var(--color-secondary) 58%, var(--color-text-dark));
--color-secondary-dark-7: color-mix(in srgb, var(--color-secondary) 50%, var(--color-text-dark));
--color-secondary-dark-8: color-mix(in srgb, var(--color-secondary) 42%, var(--color-text-dark));
--color-secondary-dark-9: color-mix(in srgb, var(--color-secondary) 39%, var(--color-text-dark));
--color-secondary-dark-10: color-mix(in srgb, var(--color-secondary) 32%, var(--color-text-dark));
--color-secondary-dark-11: color-mix(in srgb, var(--color-secondary) 25%, var(--color-text-dark));
--color-secondary-light-1: color-mix(in srgb, var(--color-secondary) 84%, black);
--color-secondary-light-2: color-mix(in srgb, var(--color-secondary) 70%, black);
--color-secondary-light-3: color-mix(in srgb, var(--color-secondary) 50%, black);
--color-secondary-light-4: color-mix(in srgb, var(--color-secondary) 39%, black);
--color-secondary-alpha-10: color-mix(in srgb, var(--color-secondary) 10%, transparent);
--color-secondary-alpha-20: color-mix(in srgb, var(--color-secondary) 20%, transparent);
--color-secondary-alpha-30: color-mix(in srgb, var(--color-secondary) 30%, transparent);
--color-secondary-alpha-40: color-mix(in srgb, var(--color-secondary) 40%, transparent);
--color-secondary-alpha-50: color-mix(in srgb, var(--color-secondary) 50%, transparent);
--color-secondary-alpha-60: color-mix(in srgb, var(--color-secondary) 60%, transparent);
--color-secondary-alpha-70: color-mix(in srgb, var(--color-secondary) 70%, transparent);
--color-secondary-alpha-80: color-mix(in srgb, var(--color-secondary) 80%, transparent);
--color-secondary-alpha-90: color-mix(in srgb, var(--color-secondary) 90%, transparent);
--color-secondary-button: var(--color-secondary-dark-4);
--color-secondary-hover: var(--color-secondary-dark-3);
--color-secondary-active: var(--color-secondary-dark-2);
/* console colors - used for actions console and console files */
--color-console-fg: #f8f8f8;
--color-console-fg-subtle: #c1c3c8;
--color-console-bg: #191a1c;
--color-console-hover-bg: #2a2c30;
--color-console-active-bg: #313338;
--color-console-link: #969aa1;
--color-console-fg-subtle: color-mix(in srgb, var(--color-console-fg) 76%, var(--color-console-bg));
--color-console-bg: color-mix(in srgb, var(--color-secondary) 39%, black);
--color-console-hover-bg: color-mix(in srgb, var(--color-console-fg) 8%, var(--color-console-bg));
--color-console-active-bg: color-mix(in srgb, var(--color-console-fg) 11%, var(--color-console-bg));
--color-console-link: color-mix(in srgb, var(--color-console-fg) 58%, var(--color-console-bg));
/* named colors */
--color-red: #cc4848;
--color-orange: #cc580c;
--color-red: #d65150;
--color-orange: #d05c14;
--color-yellow: #cc9903;
--color-olive: #91a313;
--color-green: #87ab63;
--color-teal: #00918a;
--color-olive: #859605;
--color-green: #7b9e57;
--color-teal: #149790;
--color-blue: #3a8ac6;
--color-violet: #906ae1;
--color-purple: #b259d0;
--color-pink: #d22e8b;
--color-brown: #a47252;
--color-violet: #8e68df;
--color-purple: #b057cd;
--color-pink: #da3792;
--color-brown: #a97756;
--color-black: #202225;
/* light variants - produced via Sass scale-color(color, $lightness: +10%) */
--color-red-light: #d15a5a;
--color-orange-light: #f6a066;
--color-yellow-light: #eaaf03;
--color-olive-light: #abc016;
--color-green-light: #93b373;
--color-teal-light: #00b6ad;
--color-blue-light: #4e96cc;
--color-violet-light: #9b79e4;
--color-purple-light: #ba6ad5;
--color-pink-light: #d74397;
--color-brown-light: #b08061;
--color-black-light: #45484e;
--color-red-light: color-mix(in srgb, var(--color-red) 88%, white);
--color-orange-light: color-mix(in srgb, var(--color-orange) 88%, white);
--color-yellow-light: color-mix(in srgb, var(--color-yellow) 85%, white);
--color-olive-light: color-mix(in srgb, var(--color-olive) 89%, white);
--color-green-light: color-mix(in srgb, var(--color-green) 89%, white);
--color-teal-light: color-mix(in srgb, var(--color-teal) 88%, white);
--color-blue-light: color-mix(in srgb, var(--color-blue) 89%, white);
--color-violet-light: color-mix(in srgb, var(--color-violet) 89%, white);
--color-purple-light: color-mix(in srgb, var(--color-purple) 89%, white);
--color-pink-light: color-mix(in srgb, var(--color-pink) 86%, white);
--color-brown-light: color-mix(in srgb, var(--color-brown) 90%, white);
--color-black-light: color-mix(in srgb, var(--color-black) 96%, white);
/* dark 1 variants - produced via Sass scale-color(color, $lightness: -10%) */
--color-red-dark-1: #c23636;
--color-orange-dark-1: #f38236;
--color-yellow-dark-1: #b88a03;
--color-olive-dark-1: #839311;
--color-green-dark-1: #7a9e55;
--color-teal-dark-1: #00837c;
--color-blue-dark-1: #347cb3;
--color-violet-dark-1: #7b4edb;
--color-purple-dark-1: #a742c9;
--color-pink-dark-1: #be297d;
--color-brown-dark-1: #94674a;
--color-black-dark-1: #2e3033;
--color-red-dark-1: color-mix(in srgb, var(--color-red) 90%, black);
--color-orange-dark-1: color-mix(in srgb, var(--color-orange) 90%, black);
--color-yellow-dark-1: color-mix(in srgb, var(--color-yellow) 91%, black);
--color-olive-dark-1: color-mix(in srgb, var(--color-olive) 91%, black);
--color-green-dark-1: color-mix(in srgb, var(--color-green) 91%, black);
--color-teal-dark-1: color-mix(in srgb, var(--color-teal) 90%, black);
--color-blue-dark-1: color-mix(in srgb, var(--color-blue) 90%, black);
--color-violet-dark-1: color-mix(in srgb, var(--color-violet) 90%, black);
--color-purple-dark-1: color-mix(in srgb, var(--color-purple) 90%, black);
--color-pink-dark-1: color-mix(in srgb, var(--color-pink) 90%, black);
--color-brown-dark-1: color-mix(in srgb, var(--color-brown) 90%, black);
--color-black-dark-1: color-mix(in srgb, var(--color-black) 69%, black);
/* dark 2 variants - produced via Sass scale-color(color, $lightness: -20%) */
--color-red-dark-2: #ad3030;
--color-orange-dark-2: #f16e17;
--color-yellow-dark-2: #a37a02;
--color-olive-dark-2: #74820f;
--color-green-dark-2: #6c8c4c;
--color-teal-dark-2: #00746e;
--color-blue-dark-2: #2e6e9f;
--color-violet-dark-2: #6733d6;
--color-purple-dark-2: #9834b9;
--color-pink-dark-2: #a9246f;
--color-brown-dark-2: #835b42;
--color-black-dark-2: #292b2e;
--color-red-dark-2: color-mix(in srgb, var(--color-red) 80%, black);
--color-orange-dark-2: color-mix(in srgb, var(--color-orange) 80%, black);
--color-yellow-dark-2: color-mix(in srgb, var(--color-yellow) 83%, black);
--color-olive-dark-2: color-mix(in srgb, var(--color-olive) 81%, black);
--color-green-dark-2: color-mix(in srgb, var(--color-green) 81%, black);
--color-teal-dark-2: color-mix(in srgb, var(--color-teal) 80%, black);
--color-blue-dark-2: color-mix(in srgb, var(--color-blue) 80%, black);
--color-violet-dark-2: color-mix(in srgb, var(--color-violet) 80%, black);
--color-purple-dark-2: color-mix(in srgb, var(--color-purple) 80%, black);
--color-pink-dark-2: color-mix(in srgb, var(--color-pink) 80%, black);
--color-brown-dark-2: color-mix(in srgb, var(--color-brown) 80%, black);
--color-black-dark-2: color-mix(in srgb, var(--color-black) 40%, black);
/* ansi colors used for actions console and console files */
--color-ansi-black: #202225;
--color-ansi-red: #cc4848;
@@ -130,12 +128,12 @@ gitea-theme-meta-info {
--color-ansi-magenta: #d22e8b;
--color-ansi-cyan: #00918a;
--color-ansi-white: var(--color-console-fg-subtle);
--color-ansi-bright-black: #45484e;
--color-ansi-bright-red: #d15a5a;
--color-ansi-bright-green: #93b373;
--color-ansi-bright-black: color-mix(in srgb, var(--color-ansi-black) 83%, white);
--color-ansi-bright-red: color-mix(in srgb, var(--color-ansi-red) 90%, white);
--color-ansi-bright-green: color-mix(in srgb, var(--color-ansi-green) 90%, white);
--color-ansi-bright-yellow: #eaaf03;
--color-ansi-bright-blue: #4e96cc;
--color-ansi-bright-magenta: #d74397;
--color-ansi-bright-blue: color-mix(in srgb, var(--color-ansi-blue) 90%, white);
--color-ansi-bright-magenta: color-mix(in srgb, var(--color-ansi-magenta) 90%, white);
--color-ansi-bright-cyan: #00b6ad;
--color-ansi-bright-white: var(--color-console-fg);
/* 16-color series */
@@ -156,87 +154,86 @@ gitea-theme-meta-info {
--color-series-16-14: #103aad;
--color-series-16-15: #982e85;
/* other colors */
--color-grey: #3d3f44;
--color-grey-light: #898d96;
--color-grey: color-mix(in srgb, var(--color-secondary) 95%, black);
--color-grey-light: color-mix(in srgb, var(--color-secondary) 59%, var(--color-text-dark));
--color-gold: #b1983b;
--color-white: #ffffff;
--color-diff-added-fg: #93b373;
--color-diff-added-linenum-bg: #274227;
--color-diff-added-row-bg: #203224;
--color-diff-added-fg: color-mix(in srgb, var(--color-green) 90%, white);
--color-diff-added-linenum-bg: #2c472c;
--color-diff-added-row-bg: #1a2c1f;
--color-diff-added-row-border: #314a37;
--color-diff-added-word-bg: #3c653c;
--color-diff-added-word-bg: #2b542c;
--color-diff-moved-row-bg: #818044;
--color-diff-moved-row-border: #bcca6f;
--color-diff-removed-fg: #fb5f5b;
--color-diff-removed-linenum-bg: #482121;
--color-diff-removed-row-bg: #301e1e;
--color-diff-removed-linenum-bg: #5b3231;
--color-diff-removed-row-bg: #342222;
--color-diff-removed-row-border: #634343;
--color-diff-removed-word-bg: #6f3333;
--color-diff-inactive: #25272a;
--color-error-border: #763232;
--color-error-bg: #322226;
--color-error-bg-active: #49262a;
--color-error-bg-hover: #3c2427;
--color-diff-removed-word-bg: #703434;
--color-diff-inactive: color-mix(in srgb, var(--color-secondary) 59%, black);
--color-error-border: color-mix(in srgb, var(--color-error-text) 38%, var(--color-body));
--color-error-bg: color-mix(in srgb, var(--color-error-text) 13%, var(--color-body));
--color-error-bg-active: color-mix(in srgb, var(--color-error-text) 23%, var(--color-body));
--color-error-bg-hover: color-mix(in srgb, var(--color-error-text) 18%, var(--color-body));
--color-error-text: #f85149;
--color-success-border: #225633;
--color-success-bg: #1c3329;
--color-success-border: color-mix(in srgb, var(--color-success-text) 38%, var(--color-body));
--color-success-bg: color-mix(in srgb, var(--color-success-text) 13%, var(--color-body));
--color-success-text: #3fb950;
--color-warning-border: #5f481a;
--color-warning-bg: #342e1f;
--color-warning-border: color-mix(in srgb, var(--color-warning-text) 38%, var(--color-body));
--color-warning-bg: color-mix(in srgb, var(--color-warning-text) 13%, var(--color-body));
--color-warning-text: #d29922;
--color-info-border: #254a7e;
--color-info-bg: #1b283a;
--color-info-border: color-mix(in srgb, var(--color-info-text) 38%, var(--color-body));
--color-info-bg: color-mix(in srgb, var(--color-info-text) 13%, var(--color-body));
--color-info-text: #2f81f7;
--color-priority-border: #4a268d;
--color-priority-bg: #251c39;
--color-priority-text: #a371f7;
--color-red-badge: #db2828;
--color-red-badge-bg: #db28281a;
--color-red-badge-hover-bg: #db28284d;
--color-red-badge-bg: color-mix(in srgb, var(--color-red-badge) 10%, transparent);
--color-red-badge-hover-bg: color-mix(in srgb, var(--color-red-badge) 30%, transparent);
--color-green-badge: #21ba45;
--color-green-badge-bg: #21ba451a;
--color-green-badge-hover-bg: #21ba454d;
--color-green-badge-bg: color-mix(in srgb, var(--color-green-badge) 10%, transparent);
--color-green-badge-hover-bg: color-mix(in srgb, var(--color-green-badge) 30%, transparent);
--color-yellow-badge: #fbbd08;
--color-yellow-badge-bg: #fbbd081a;
--color-yellow-badge-hover-bg: #fbbd084d;
--color-yellow-badge-bg: color-mix(in srgb, var(--color-yellow-badge) 10%, transparent);
--color-yellow-badge-hover-bg: color-mix(in srgb, var(--color-yellow-badge) 30%, transparent);
--color-orange-badge: #f2711c;
--color-orange-badge-bg: #f2711c1a;
--color-orange-badge-hover-bg: #f2711c4d;
--color-orange-badge-bg: color-mix(in srgb, var(--color-orange-badge) 10%, transparent);
--color-orange-badge-hover-bg: color-mix(in srgb, var(--color-orange-badge) 30%, transparent);
--color-git: #f05133;
--color-logo: #609926;
/* target-based colors */
--color-body: #1e1f20;
--color-box-header: #1b1c1e;
--color-box-body: #161718;
--color-box-body-highlight: #202124;
--color-box-header: color-mix(in srgb, var(--color-secondary) 42%, black);
--color-box-body: color-mix(in srgb, var(--color-body) 74%, black);
--color-box-body-highlight: color-mix(in srgb, var(--color-primary) 2%, var(--color-body));
--color-text-dark: #f8f8f8;
--color-text: #d2d4d8;
--color-text-light: #c0c2c7;
--color-text-light-1: #aaadb4;
--color-text-light-2: #969aa1;
--color-text-light-3: #80858f;
--color-text: color-mix(in srgb, var(--color-text-dark) 80%, var(--color-secondary));
--color-text-light: color-mix(in srgb, var(--color-text-dark) 71%, var(--color-secondary));
--color-text-light-1: color-mix(in srgb, var(--color-text-dark) 59%, var(--color-secondary));
--color-text-light-2: color-mix(in srgb, var(--color-text-dark) 48%, var(--color-secondary));
--color-text-light-3: color-mix(in srgb, var(--color-text-dark) 37%, var(--color-secondary));
--color-footer: var(--color-nav-bg);
--color-timeline: #383b40;
--color-timeline: color-mix(in srgb, var(--color-secondary) 89%, black);
--color-input-text: var(--color-text-dark);
--color-input-background: #191a1c;
--color-input-toggle-background: #323438;
--color-input-background: color-mix(in srgb, var(--color-secondary) 39%, black);
--color-input-toggle-background: color-mix(in srgb, var(--color-secondary) 78%, black);
--color-input-border: var(--color-secondary-dark-1);
--color-light: #0b0b0c28;
--color-light-border: #f3f3f428;
--color-hover: #f3f3f419;
--color-hover-opaque: #232528; /* TODO: color-mix(in srgb, var(--color-body), var(--color-hover)); */
--color-hover-opaque: color-mix(in srgb, var(--color-secondary) 56%, black);
--color-active: #f3f3f424;
--color-menu: #191a1c;
--color-card: #191a1c;
--color-menu: color-mix(in srgb, var(--color-secondary) 39%, black);
--color-card: color-mix(in srgb, var(--color-secondary) 39%, black);
--color-markup-table-row: #f3f3f40f;
--color-markup-code-block: #f3f3f412;
--color-markup-code-inline: #f3f3f428;
--color-button: #191a1c;
--color-code-bg: #161718;
--color-button: color-mix(in srgb, var(--color-secondary) 39%, black);
--color-code-bg: color-mix(in srgb, var(--color-body) 74%, black);
--color-shadow: #0b0b0c58;
--color-shadow-opaque: #0b0b0c;
--color-secondary-bg: #2e3033;
--color-expand-button: #333539;
--color-secondary-bg: color-mix(in srgb, var(--color-secondary) 72%, black);
--color-expand-button: color-mix(in srgb, var(--color-secondary) 80%, black);
--color-placeholder-text: var(--color-text-light-3);
--color-editor-line-highlight: var(--color-secondary-alpha-40);
--color-editor-selection: var(--color-primary-alpha-50);
@@ -246,14 +243,14 @@ gitea-theme-meta-info {
--color-reaction-hover-bg: var(--color-primary-light-4);
--color-reaction-active-bg: var(--color-primary-light-5);
--color-tooltip-text: #fafafa;
--color-tooltip-bg: #2b2e33;
--color-nav-bg: #18191b;
--color-tooltip-bg: color-mix(in srgb, var(--color-secondary) 70%, black);
--color-nav-bg: color-mix(in srgb, var(--color-secondary) 38%, black);
--color-nav-hover-bg: var(--color-secondary-light-1);
--color-nav-text: var(--color-text);
--color-secondary-nav-bg: #1a1b1e;
--color-secondary-nav-bg: color-mix(in srgb, var(--color-secondary) 41%, black);
--color-label-text: var(--color-text);
--color-label-bg: #7a7f8a4b;
--color-label-hover-bg: #7a7f8aa0;
--color-label-bg: color-mix(in srgb, var(--color-label-active-bg) 30%, transparent);
--color-label-hover-bg: color-mix(in srgb, var(--color-label-active-bg) 63%, transparent);
--color-label-active-bg: #7a7f8aff;
--color-accent: var(--color-primary-light-1);
--color-small-accent: var(--color-primary-light-5);
@@ -263,7 +260,6 @@ gitea-theme-meta-info {
--color-danger: var(--color-red);
--color-transparency-grid-light: #2a2a2a;
--color-transparency-grid-dark: #1a1a1a;
--color-workflow-edge-hover: #666a73;
--color-syntax-keyword: #ff8854;
--color-syntax-bool: #25bbc9;
--color-syntax-control: #dd9e17;
@@ -290,8 +286,8 @@ gitea-theme-meta-info {
--color-syntax-name-pseudo: #c792ff;
--color-syntax-comment-special: #b89de4;
--color-syntax-text: #c9d1d9;
--color-syntax-text-alt: #b9bcc7;
--color-syntax-punctuation: #d2d4db;
--color-syntax-text-alt: color-mix(in srgb, var(--color-syntax-whitespace) 55%, white);
--color-syntax-punctuation: color-mix(in srgb, var(--color-syntax-whitespace) 35%, white);
--color-syntax-whitespace: #7f8699;
--color-syntax-diff-fg: #ffffff;
--color-syntax-deleted-bg: #5f3737;
@@ -303,8 +299,8 @@ gitea-theme-meta-info {
--color-syntax-output: #8898b0;
--color-syntax-prompt: #e29b33;
--color-syntax-traceback: #ff8686;
--color-syntax-matching-bracket-bg: #00918a48;
--color-syntax-nonmatching-bracket-bg: #cc484848;
--color-syntax-matching-bracket-bg: color-mix(in srgb, var(--color-teal) 28%, transparent);
--color-syntax-nonmatching-bracket-bg: color-mix(in srgb, var(--color-red) 28%, transparent);
accent-color: var(--color-accent);
color-scheme: dark;
}

View File

@@ -10,10 +10,10 @@ gitea-theme-meta-info {
:root {
--color-diff-added-fg: #0860cc;
--color-diff-added-linenum-bg: #b6e3ff;
--color-diff-added-row-bg: #ddf4ff;
--color-diff-added-row-bg: #dff5ff;
--color-diff-added-word-bg: #b6e3ff;
--color-diff-removed-fg: #a84400;
--color-diff-removed-linenum-bg: #ffd8b5;
--color-diff-removed-row-bg: #fff1e5;
--color-diff-removed-word-bg: #ffd8b5;
--color-diff-removed-linenum-bg: #fad3b0;
--color-diff-removed-row-bg: #fceee2;
--color-diff-removed-word-bg: #fad3b0;
}

View File

@@ -10,6 +10,6 @@ gitea-theme-meta-info {
:root {
--color-diff-added-fg: #0860cc;
--color-diff-added-linenum-bg: #b6e3ff;
--color-diff-added-row-bg: #ddf4ff;
--color-diff-added-row-bg: #dff5ff;
--color-diff-added-word-bg: #b6e3ff;
}

View File

@@ -7,120 +7,118 @@ gitea-theme-meta-info {
--is-dark-theme: false;
--color-primary: #4183c4;
--color-primary-contrast: #ffffff;
--color-primary-dark-1: #3876b3;
--color-primary-dark-2: #31699f;
--color-primary-dark-3: #2b5c8b;
--color-primary-dark-4: #254f77;
--color-primary-dark-5: #193450;
--color-primary-dark-6: #0c1a28;
--color-primary-dark-7: #04080c;
--color-primary-light-1: #548fca;
--color-primary-light-2: #679cd0;
--color-primary-light-3: #7aa8d6;
--color-primary-light-4: #8db5dc;
--color-primary-light-5: #b3cde7;
--color-primary-light-6: #d9e6f3;
--color-primary-light-7: #f4f8fb;
--color-primary-alpha-10: #4183c419;
--color-primary-alpha-20: #4183c433;
--color-primary-alpha-30: #4183c44b;
--color-primary-alpha-40: #4183c466;
--color-primary-alpha-50: #4183c480;
--color-primary-alpha-60: #4183c499;
--color-primary-alpha-70: #4183c4b3;
--color-primary-alpha-80: #4183c4cc;
--color-primary-alpha-90: #4183c4e1;
--color-primary-dark-1: color-mix(in srgb, var(--color-primary) 90%, black);
--color-primary-dark-2: color-mix(in srgb, var(--color-primary) 80%, black);
--color-primary-dark-3: color-mix(in srgb, var(--color-primary) 70%, black);
--color-primary-dark-4: color-mix(in srgb, var(--color-primary) 60%, black);
--color-primary-dark-5: color-mix(in srgb, var(--color-primary) 40%, black);
--color-primary-dark-6: color-mix(in srgb, var(--color-primary) 20%, black);
--color-primary-dark-7: color-mix(in srgb, var(--color-primary) 6%, black);
--color-primary-light-1: color-mix(in srgb, var(--color-primary) 90%, white);
--color-primary-light-2: color-mix(in srgb, var(--color-primary) 80%, white);
--color-primary-light-3: color-mix(in srgb, var(--color-primary) 70%, white);
--color-primary-light-4: color-mix(in srgb, var(--color-primary) 60%, white);
--color-primary-light-5: color-mix(in srgb, var(--color-primary) 40%, white);
--color-primary-light-6: color-mix(in srgb, var(--color-primary) 20%, white);
--color-primary-light-7: color-mix(in srgb, var(--color-primary) 6%, white);
--color-primary-alpha-10: color-mix(in srgb, var(--color-primary) 10%, transparent);
--color-primary-alpha-20: color-mix(in srgb, var(--color-primary) 20%, transparent);
--color-primary-alpha-30: color-mix(in srgb, var(--color-primary) 30%, transparent);
--color-primary-alpha-40: color-mix(in srgb, var(--color-primary) 40%, transparent);
--color-primary-alpha-50: color-mix(in srgb, var(--color-primary) 50%, transparent);
--color-primary-alpha-60: color-mix(in srgb, var(--color-primary) 60%, transparent);
--color-primary-alpha-70: color-mix(in srgb, var(--color-primary) 70%, transparent);
--color-primary-alpha-80: color-mix(in srgb, var(--color-primary) 80%, transparent);
--color-primary-alpha-90: color-mix(in srgb, var(--color-primary) 90%, transparent);
--color-primary-hover: var(--color-primary-dark-1);
--color-primary-active: var(--color-primary-dark-2);
--color-secondary: #d0d7de;
--color-secondary-dark-1: #c7ced5;
--color-secondary-dark-2: #b9c0c7;
--color-secondary-dark-3: #99a0a7;
--color-secondary-dark-4: #899097;
--color-secondary-dark-5: #7a8188;
--color-secondary-dark-6: #6a7178;
--color-secondary-dark-7: #5b6269;
--color-secondary-dark-8: #4b5259;
--color-secondary-dark-9: #3c434a;
--color-secondary-dark-10: #2c333a;
--color-secondary-dark-11: #1d242b;
--color-secondary-dark-12: #0d141b;
--color-secondary-dark-13: #00040b;
--color-secondary-light-1: #dee5ec;
--color-secondary-light-2: #e4ebf2;
--color-secondary-light-3: #ebf2f9;
--color-secondary-light-4: #f1f8ff;
--color-secondary-alpha-10: #d0d7de19;
--color-secondary-alpha-20: #d0d7de33;
--color-secondary-alpha-30: #d0d7de4b;
--color-secondary-alpha-40: #d0d7de66;
--color-secondary-alpha-50: #d0d7de80;
--color-secondary-alpha-60: #d0d7de99;
--color-secondary-alpha-70: #d0d7deb3;
--color-secondary-alpha-80: #d0d7decc;
--color-secondary-alpha-90: #d0d7dee1;
--color-secondary-dark-1: color-mix(in srgb, var(--color-secondary) 96%, var(--color-text-dark));
--color-secondary-dark-2: color-mix(in srgb, var(--color-secondary) 89%, var(--color-text-dark));
--color-secondary-dark-3: color-mix(in srgb, var(--color-secondary) 74%, var(--color-text-dark));
--color-secondary-dark-4: color-mix(in srgb, var(--color-secondary) 66%, var(--color-text-dark));
--color-secondary-dark-5: color-mix(in srgb, var(--color-secondary) 59%, var(--color-text-dark));
--color-secondary-dark-6: color-mix(in srgb, var(--color-secondary) 51%, var(--color-text-dark));
--color-secondary-dark-7: color-mix(in srgb, var(--color-secondary) 44%, var(--color-text-dark));
--color-secondary-dark-8: color-mix(in srgb, var(--color-secondary) 36%, var(--color-text-dark));
--color-secondary-dark-9: color-mix(in srgb, var(--color-secondary) 29%, var(--color-text-dark));
--color-secondary-dark-10: color-mix(in srgb, var(--color-secondary) 22%, var(--color-text-dark));
--color-secondary-dark-11: color-mix(in srgb, var(--color-secondary) 15%, var(--color-text-dark));
--color-secondary-light-1: color-mix(in srgb, var(--color-secondary) 65%, white);
--color-secondary-light-2: color-mix(in srgb, var(--color-secondary) 53%, white);
--color-secondary-light-3: color-mix(in srgb, var(--color-secondary) 34%, white);
--color-secondary-light-4: color-mix(in srgb, var(--color-secondary) 19%, white);
--color-secondary-alpha-10: color-mix(in srgb, var(--color-secondary) 10%, transparent);
--color-secondary-alpha-20: color-mix(in srgb, var(--color-secondary) 20%, transparent);
--color-secondary-alpha-30: color-mix(in srgb, var(--color-secondary) 30%, transparent);
--color-secondary-alpha-40: color-mix(in srgb, var(--color-secondary) 40%, transparent);
--color-secondary-alpha-50: color-mix(in srgb, var(--color-secondary) 50%, transparent);
--color-secondary-alpha-60: color-mix(in srgb, var(--color-secondary) 60%, transparent);
--color-secondary-alpha-70: color-mix(in srgb, var(--color-secondary) 70%, transparent);
--color-secondary-alpha-80: color-mix(in srgb, var(--color-secondary) 80%, transparent);
--color-secondary-alpha-90: color-mix(in srgb, var(--color-secondary) 90%, transparent);
--color-secondary-button: var(--color-secondary-dark-4);
--color-secondary-hover: var(--color-secondary-dark-5);
--color-secondary-active: var(--color-secondary-dark-6);
/* console colors - used for actions console and console files */
--color-console-fg: #0d1117;
--color-console-fg-subtle: #40474d;
--color-console-fg-subtle: color-mix(in srgb, var(--color-console-fg) 78%, var(--color-console-bg));
--color-console-bg: #ffffff;
--color-console-hover-bg: #f1f3f5;
--color-console-active-bg: #d0d7de;
--color-console-link: #5c656d;
--color-console-hover-bg: color-mix(in srgb, var(--color-secondary) 30%, white);
--color-console-active-bg: color-mix(in srgb, var(--color-console-fg) 17%, var(--color-console-bg));
--color-console-link: color-mix(in srgb, var(--color-console-fg) 65%, var(--color-console-bg));
/* named colors */
--color-red: #db2828;
--color-orange: #f2711c;
--color-orange: #e36501;
--color-yellow: #fbbd08;
--color-olive: #b5cc18;
--color-green: #21ba45;
--color-teal: #00b5ad;
--color-blue: #2185d0;
--color-violet: #6435c9;
--color-purple: #a333c8;
--color-pink: #e03997;
--color-brown: #a5673f;
--color-olive: #a9bf04;
--color-green: #01ad39;
--color-teal: #01a7a0;
--color-blue: #167ec9;
--color-violet: #6f43d7;
--color-purple: #ab3cd0;
--color-pink: #d2288b;
--color-brown: #a66840;
--color-black: #1d2328;
/* light variants - produced via Sass scale-color(color, $lightness: +25%) */
--color-red-light: #e45e5e;
--color-orange-light: #f59555;
--color-yellow-light: #fcce46;
--color-olive-light: #d3e942;
--color-green-light: #46de6a;
--color-teal-light: #08fff4;
--color-blue-light: #51a5e3;
--color-violet-light: #8b67d7;
--color-purple-light: #bb64d8;
--color-pink-light: #e86bb1;
--color-brown-light: #c58b66;
--color-black-light: #4b5b68;
--color-red-light: color-mix(in srgb, var(--color-red) 71%, white);
--color-orange-light: color-mix(in srgb, var(--color-orange) 75%, white);
--color-yellow-light: color-mix(in srgb, var(--color-yellow) 75%, white);
--color-olive-light: color-mix(in srgb, var(--color-olive) 77%, white);
--color-green-light: color-mix(in srgb, var(--color-green) 74%, white);
--color-teal-light: color-mix(in srgb, var(--color-teal) 75%, white);
--color-blue-light: color-mix(in srgb, var(--color-blue) 77%, white);
--color-violet-light: color-mix(in srgb, var(--color-violet) 77%, white);
--color-purple-light: color-mix(in srgb, var(--color-purple) 76%, white);
--color-pink-light: color-mix(in srgb, var(--color-pink) 73%, white);
--color-brown-light: color-mix(in srgb, var(--color-brown) 79%, white);
--color-black-light: color-mix(in srgb, var(--color-black) 82%, white);
/* dark 1 variants - produced via Sass scale-color(color, $lightness: -10%) */
--color-red-dark-1: #c82121;
--color-orange-dark-1: #e6630d;
--color-yellow-dark-1: #e5ac04;
--color-olive-dark-1: #a3b816;
--color-green-dark-1: #1ea73e;
--color-teal-dark-1: #00a39c;
--color-blue-dark-1: #1e78bb;
--color-violet-dark-1: #5a30b5;
--color-purple-dark-1: #932eb4;
--color-pink-dark-1: #db228a;
--color-brown-dark-1: #955d39;
--color-black-dark-1: #2c3339;
--color-red-dark-1: color-mix(in srgb, var(--color-red) 89%, black);
--color-orange-dark-1: color-mix(in srgb, var(--color-orange) 91%, black);
--color-yellow-dark-1: color-mix(in srgb, var(--color-yellow) 93%, black);
--color-olive-dark-1: color-mix(in srgb, var(--color-olive) 92%, black);
--color-green-dark-1: color-mix(in srgb, var(--color-green) 91%, black);
--color-teal-dark-1: color-mix(in srgb, var(--color-teal) 91%, black);
--color-blue-dark-1: color-mix(in srgb, var(--color-blue) 89%, black);
--color-violet-dark-1: color-mix(in srgb, var(--color-violet) 88%, black);
--color-purple-dark-1: color-mix(in srgb, var(--color-purple) 89%, black);
--color-pink-dark-1: color-mix(in srgb, var(--color-pink) 90%, black);
--color-brown-dark-1: color-mix(in srgb, var(--color-brown) 89%, black);
--color-black-dark-1: color-mix(in srgb, var(--color-black) 69%, black);
/* dark 2 variants - produced via Sass scale-color(color, $lightness: -20%) */
--color-red-dark-2: #b11e1e;
--color-orange-dark-2: #cc580c;
--color-yellow-dark-2: #cc9903;
--color-olive-dark-2: #91a313;
--color-green-dark-2: #1a9537;
--color-teal-dark-2: #00918a;
--color-blue-dark-2: #1a6aa6;
--color-violet-dark-2: #502aa1;
--color-purple-dark-2: #8229a0;
--color-pink-dark-2: #c21e7b;
--color-brown-dark-2: #845232;
--color-black-dark-2: #131619;
--color-red-dark-2: color-mix(in srgb, var(--color-red) 79%, black);
--color-orange-dark-2: color-mix(in srgb, var(--color-orange) 82%, black);
--color-yellow-dark-2: color-mix(in srgb, var(--color-yellow) 86%, black);
--color-olive-dark-2: color-mix(in srgb, var(--color-olive) 84%, black);
--color-green-dark-2: color-mix(in srgb, var(--color-green) 82%, black);
--color-teal-dark-2: color-mix(in srgb, var(--color-teal) 82%, black);
--color-blue-dark-2: color-mix(in srgb, var(--color-blue) 79%, black);
--color-violet-dark-2: color-mix(in srgb, var(--color-violet) 76%, black);
--color-purple-dark-2: color-mix(in srgb, var(--color-purple) 79%, black);
--color-pink-dark-2: color-mix(in srgb, var(--color-pink) 79%, black);
--color-brown-dark-2: color-mix(in srgb, var(--color-brown) 79%, black);
--color-black-dark-2: color-mix(in srgb, var(--color-black) 40%, black);
/* ansi colors used for actions console and console files */
--color-ansi-black: #1e2327;
--color-ansi-red: #cc4848;
@@ -130,12 +128,12 @@ gitea-theme-meta-info {
--color-ansi-magenta: #d22e8b;
--color-ansi-cyan: #00918a;
--color-ansi-white: var(--color-console-fg-subtle);
--color-ansi-bright-black: #46494d;
--color-ansi-bright-red: #d15a5a;
--color-ansi-bright-green: #93b373;
--color-ansi-bright-black: color-mix(in srgb, var(--color-ansi-black) 83%, white);
--color-ansi-bright-red: color-mix(in srgb, var(--color-ansi-red) 90%, white);
--color-ansi-bright-green: color-mix(in srgb, var(--color-ansi-green) 90%, white);
--color-ansi-bright-yellow: #eaaf03;
--color-ansi-bright-blue: #4e96cc;
--color-ansi-bright-magenta: #d74397;
--color-ansi-bright-blue: color-mix(in srgb, var(--color-ansi-blue) 90%, white);
--color-ansi-bright-magenta: color-mix(in srgb, var(--color-ansi-magenta) 90%, white);
--color-ansi-bright-cyan: #00b6ad;
--color-ansi-bright-white: var(--color-console-fg);
/* 16-color series */
@@ -156,23 +154,23 @@ gitea-theme-meta-info {
--color-series-16-14: #103aad;
--color-series-16-15: #982e85;
/* other colors */
--color-grey: #697077;
--color-grey-light: #7c838a;
--color-grey: color-mix(in srgb, var(--color-secondary) 51%, var(--color-text-dark));
--color-grey-light: color-mix(in srgb, var(--color-secondary) 60%, var(--color-text-dark));
--color-gold: #a1882b;
--color-white: #ffffff;
--color-diff-added-fg: #177231;
--color-diff-added-linenum-bg: #d1f8d9;
--color-diff-added-row-bg: #e6ffed;
--color-diff-added-fg: #217938;
--color-diff-added-linenum-bg: #aceebb;
--color-diff-added-row-bg: #dafbe1;
--color-diff-added-row-border: #e6ffed;
--color-diff-added-word-bg: #acf2bd;
--color-diff-added-word-bg: #aceebb;
--color-diff-moved-row-bg: #f1f8d1;
--color-diff-moved-row-border: #d0e27f;
--color-diff-removed-fg: #c61f2b;
--color-diff-removed-fg: #be1124;
--color-diff-removed-linenum-bg: #ffcecb;
--color-diff-removed-row-bg: #ffeef0;
--color-diff-removed-row-bg: #ffebe9;
--color-diff-removed-row-border: #f1c0c0;
--color-diff-removed-word-bg: #fdb8c0;
--color-diff-inactive: #f0f2f4;
--color-diff-removed-word-bg: #ffcecb;
--color-diff-inactive: color-mix(in srgb, var(--color-secondary) 32%, white);
--color-error-border: #ff818266;
--color-error-bg: #ffebe9;
--color-error-bg-active: #ffcecb;
@@ -191,30 +189,30 @@ gitea-theme-meta-info {
--color-priority-bg: #f3e7ff;
--color-priority-text: #8250df;
--color-red-badge: #db2828;
--color-red-badge-bg: #db28281a;
--color-red-badge-hover-bg: #db28284d;
--color-red-badge-bg: color-mix(in srgb, var(--color-red-badge) 10%, transparent);
--color-red-badge-hover-bg: color-mix(in srgb, var(--color-red-badge) 30%, transparent);
--color-green-badge: #21ba45;
--color-green-badge-bg: #21ba451a;
--color-green-badge-hover-bg: #21ba454d;
--color-green-badge-bg: color-mix(in srgb, var(--color-green-badge) 10%, transparent);
--color-green-badge-hover-bg: color-mix(in srgb, var(--color-green-badge) 30%, transparent);
--color-yellow-badge: #fbbd08;
--color-yellow-badge-bg: #fbbd081a;
--color-yellow-badge-hover-bg: #fbbd084d;
--color-yellow-badge-bg: color-mix(in srgb, var(--color-yellow-badge) 10%, transparent);
--color-yellow-badge-hover-bg: color-mix(in srgb, var(--color-yellow-badge) 30%, transparent);
--color-orange-badge: #f2711c;
--color-orange-badge-bg: #f2711c1a;
--color-orange-badge-hover-bg: #f2711c4d;
--color-orange-badge-bg: color-mix(in srgb, var(--color-orange-badge) 10%, transparent);
--color-orange-badge-hover-bg: color-mix(in srgb, var(--color-orange-badge) 30%, transparent);
--color-git: #f05133;
--color-logo: #609926;
/* target-based colors */
--color-body: #ffffff;
--color-box-header: #f1f3f5;
--color-box-header: color-mix(in srgb, var(--color-secondary) 30%, white);
--color-box-body: #ffffff;
--color-box-body-highlight: #ecf5fd;
--color-box-body-highlight: color-mix(in srgb, var(--color-primary) 9%, var(--color-body));
--color-text-dark: #01050a;
--color-text: #181c21;
--color-text-light: #30363b;
--color-text-light-1: #40474d;
--color-text-light-2: #5b6167;
--color-text-light-3: #747c84;
--color-text: color-mix(in srgb, var(--color-text-dark) 89%, var(--color-secondary));
--color-text-light: color-mix(in srgb, var(--color-text-dark) 77%, var(--color-secondary));
--color-text-light-1: color-mix(in srgb, var(--color-text-dark) 69%, var(--color-secondary));
--color-text-light-2: color-mix(in srgb, var(--color-text-dark) 56%, var(--color-secondary));
--color-text-light-3: color-mix(in srgb, var(--color-text-dark) 44%, var(--color-secondary));
--color-footer: var(--color-nav-bg);
--color-timeline: #d0d7de;
--color-input-text: var(--color-text-dark);
@@ -224,18 +222,17 @@ gitea-theme-meta-info {
--color-light: #00001706;
--color-light-border: #0000171d;
--color-hover: #00001708;
--color-hover-opaque: #f1f3f5; /* TODO: color-mix(in srgb, var(--color-body), var(--color-hover)); */
--color-hover-opaque: color-mix(in srgb, var(--color-secondary) 30%, white);
--color-active: #00001714;
--color-menu: #f8f9fb;
--color-card: #f8f9fb;
--color-menu: color-mix(in srgb, var(--color-secondary) 14%, white);
--color-card: color-mix(in srgb, var(--color-secondary) 14%, white);
--color-markup-table-row: #0030600a;
--color-markup-code-block: #00306010;
--color-markup-code-inline: #00306012;
--color-button: #f8f9fb;
--color-code-bg: #fafdff;
--color-button: color-mix(in srgb, var(--color-secondary) 14%, white);
--color-code-bg: color-mix(in srgb, var(--color-secondary) 6%, var(--color-body));
--color-shadow: #00001726;
--color-shadow-opaque: #c7ced5;
--color-secondary-bg: #f2f5f8;
--color-secondary-bg: color-mix(in srgb, var(--color-secondary) 25%, white);
--color-expand-button: #cfe8fa;
--color-placeholder-text: var(--color-text-light-3);
--color-editor-line-highlight: var(--color-secondary-alpha-30);
@@ -246,14 +243,14 @@ gitea-theme-meta-info {
--color-reaction-hover-bg: var(--color-primary-light-5);
--color-reaction-active-bg: var(--color-primary-light-6);
--color-tooltip-text: #fbfdff;
--color-tooltip-bg: #25292e;
--color-nav-bg: #f6f7fa;
--color-tooltip-bg: color-mix(in srgb, var(--color-text-dark) 83%, var(--color-secondary));
--color-nav-bg: color-mix(in srgb, var(--color-secondary) 18%, white);
--color-nav-hover-bg: var(--color-secondary-light-1);
--color-nav-text: var(--color-text);
--color-secondary-nav-bg: #f9fafb;
--color-secondary-nav-bg: color-mix(in srgb, var(--color-secondary) 13%, white);
--color-label-text: var(--color-text);
--color-label-bg: #949da64b;
--color-label-hover-bg: #949da6a0;
--color-label-bg: color-mix(in srgb, var(--color-label-active-bg) 30%, transparent);
--color-label-hover-bg: color-mix(in srgb, var(--color-label-active-bg) 63%, transparent);
--color-label-active-bg: #949da6ff;
--color-accent: var(--color-primary-light-1);
--color-small-accent: var(--color-primary-light-6);
@@ -263,7 +260,6 @@ gitea-theme-meta-info {
--color-danger: var(--color-red);
--color-transparency-grid-light: #fafafa;
--color-transparency-grid-dark: #e2e2e2;
--color-workflow-edge-hover: #b1b7bd;
--color-syntax-keyword: #a73a00;
--color-syntax-bool: #076872;
--color-syntax-control: #7d5700;
@@ -292,7 +288,7 @@ gitea-theme-meta-info {
--color-syntax-text: inherit;
--color-syntax-text-alt: #47525b;
--color-syntax-punctuation: inherit;
--color-syntax-whitespace: #bbbbbb;
--color-syntax-whitespace: color-mix(in srgb, var(--color-syntax-namespace) 40%, white);
--color-syntax-diff-fg: #000000;
--color-syntax-deleted-bg: #ffdddd;
--color-syntax-inserted-bg: #ddffdd;
@@ -303,8 +299,8 @@ gitea-theme-meta-info {
--color-syntax-output: #506070;
--color-syntax-prompt: #944a00;
--color-syntax-traceback: #c00000;
--color-syntax-matching-bracket-bg: #00b5ad38;
--color-syntax-nonmatching-bracket-bg: #db282838;
--color-syntax-matching-bracket-bg: color-mix(in srgb, var(--color-teal) 22%, transparent);
--color-syntax-nonmatching-bracket-bg: color-mix(in srgb, var(--color-red) 22%, transparent);
accent-color: var(--color-accent);
color-scheme: light;
}

View File

@@ -1,7 +1,7 @@
<script lang="ts" setup>
import {onMounted, onUnmounted, toRaw, useTemplateRef, watch, type ShallowRef} from 'vue';
import {_adapters, BarController, Chart, LinearScale, LineController, TimeScale, type ChartData, type ChartOptions, type TimeUnit} from 'chart.js';
import {chartJsColors} from '../utils/color.ts';
import {chartJsColor} from '../utils/color.ts';
import dayjs from 'dayjs';
import advancedFormat from 'dayjs/plugin/advancedFormat.js';
import quarterOfYear from 'dayjs/plugin/quarterOfYear.js';
@@ -10,8 +10,8 @@ import type {ConfigType, ManipulateType} from 'dayjs';
dayjs.extend(advancedFormat); // the quarter format needs the `Q` token
dayjs.extend(quarterOfYear);
Chart.defaults.color = chartJsColors.text;
Chart.defaults.borderColor = chartJsColors.border;
Chart.defaults.color = chartJsColor('text');
Chart.defaults.borderColor = chartJsColor('border');
Chart.register(BarController, LineController, LinearScale, TimeScale);
// minimal port of chartjs-adapter-dayjs-4, MIT license, Copyright (c) 2022 bolstycjw

View File

@@ -18,7 +18,7 @@ import {
type DayData,
type DayDataObject,
} from '../utils/time.ts';
import {chartJsColors} from '../utils/color.ts';
import {chartJsColor} from '../utils/color.ts';
import {errorMessage} from '../modules/errors.ts';
import {sleep} from '../utils.ts';
import {computed, onMounted, shallowRef} from 'vue';
@@ -88,7 +88,7 @@ function toGraphData(data: DayData[]): ChartData<'line'> {
pointHitRadius: 0,
fill: true,
label: 'Additions',
backgroundColor: chartJsColors['additions'],
backgroundColor: chartJsColor('additions'),
borderWidth: 0,
tension: 0.3,
},
@@ -98,7 +98,7 @@ function toGraphData(data: DayData[]): ChartData<'line'> {
pointHitRadius: 0,
fill: true,
label: 'Deletions',
backgroundColor: chartJsColors['deletions'],
backgroundColor: chartJsColor('deletions'),
borderWidth: 0,
tension: 0.3,
},

View File

@@ -15,7 +15,7 @@ import {
type Plugin,
} from 'chart.js';
import zoomPlugin from 'chartjs-plugin-zoom';
import {chartJsColors} from '../utils/color.ts';
import {chartJsColor} from '../utils/color.ts';
import {
startDaysBetween,
firstStartDateAfterDate,
@@ -239,7 +239,7 @@ function toGraphData(data: DayData[]): ChartData<'line'> {
pointRadius: 0,
pointHitRadius: 0,
fill: 'start',
backgroundColor: chartJsColors[type.value],
backgroundColor: chartJsColor(type.value),
borderWidth: 0,
tension: 0.3,
},

View File

@@ -17,7 +17,7 @@ import {
type DayData,
type DayDataObject,
} from '../utils/time.ts';
import {chartJsColors} from '../utils/color.ts';
import {chartJsColor} from '../utils/color.ts';
import {errorMessage} from '../modules/errors.ts';
import {sleep} from '../utils.ts';
import {computed, onMounted, shallowRef} from 'vue';
@@ -81,7 +81,7 @@ function toGraphData(data: DayData[]): ChartData<'bar'> {
{
data: data.map((i) => ({x: i.week, y: i.commits})),
label: 'Commits',
backgroundColor: chartJsColors['commits'],
backgroundColor: chartJsColor('commits'),
borderWidth: 0,
tension: 0.3,
} as unknown as ChartDataset<'bar'>,

View File

@@ -1,6 +1,7 @@
import {generateElemId} from '../utils/dom.ts';
import {errorMessage} from '../modules/errors.ts';
import {isDarkTheme} from '../utils.ts';
import {resolveCssColor} from '../utils/color.ts';
function safeRenderIframeLink(link: any): string | null {
try {
@@ -36,7 +37,7 @@ function getRealBackgroundColor(el: HTMLElement) {
const bgColor = style.backgroundColor;
// 'rgba(0, 0, 0, 0)' is how most browsers represent transparent
if (bgColor !== 'rgba(0, 0, 0, 0)' && bgColor !== 'transparent') {
return bgColor;
return resolveCssColor(bgColor);
}
}
return '';

View File

@@ -1,4 +1,4 @@
import {contrastColor} from './color.ts';
import {contrastColor, resolveCssColor} from './color.ts';
test('contrastColor', () => {
expect(contrastColor('#d73a4a')).toBe('#fff');
@@ -22,3 +22,12 @@ test('contrastColor', () => {
expect(contrastColor('#807070')).toBe('#fff');
expect(contrastColor('#84b6eb')).toBe('#000');
});
test('resolveCssColor', () => {
expect(resolveCssColor('#4183c4')).toBe('#4183c4');
expect(resolveCssColor('color-mix(in srgb, #ff0000 20%, black)')).toBe('#330000');
expect(resolveCssColor('color-mix(in srgb, #ffffff 40%, transparent)')).toBe('#ffffff66');
expect(resolveCssColor('color(srgb 0 0.2 1)')).toBe('#0033ff');
expect(resolveCssColor('#4183c499')).toBe('#4183c499');
expect(resolveCssColor('oklab(1 0 0)')).toBe('#ffffff');
});

View File

@@ -23,16 +23,26 @@ export function contrastColor(backgroundColor: AnyColor): string {
return useLightText(backgroundColor) ? '#fff' : '#000';
}
function resolveColors(obj: Record<string, string>): Record<string, string> {
const styles = window.getComputedStyle(document.documentElement);
const getColor = (name: string) => styles.getPropertyValue(name).trim();
return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, getColor(value)]));
/** Resolves any CSS color, including var() and color-mix(), to hex for consumers that only parse hex or rgb(). */
export function resolveCssColor(color: string): string {
const probe = document.createElement('div');
probe.style.color = `color-mix(in srgb, ${color} 100%, transparent)`;
document.documentElement.append(probe);
const computed = getComputedStyle(probe).color; // "color(srgb r g b / a)" with 0..1 channels, or "rgb()" in some engines
probe.remove();
const [r, g, b, a = 1] = computed.match(/-?[\d.]+(?:e-?\d+)?/g)!.map(Number);
const scale = computed.startsWith('color(') ? 255 : 1;
return colord({r: r * scale, g: g * scale, b: b * scale, a}).toHex();
}
export const chartJsColors = resolveColors({
text: '--color-text',
border: '--color-secondary-alpha-60',
commits: '--color-primary-alpha-60',
additions: '--color-green',
deletions: '--color-red',
});
const chartColorVars = {
text: 'text',
border: 'secondary-alpha-60',
commits: 'primary-alpha-60',
additions: 'green',
deletions: 'red',
};
export function chartJsColor(name: keyof typeof chartColorVars): string {
return resolveCssColor(`var(--color-${chartColorVars[name]})`);
}