Introduce deterministic CSS gradient angle and shared color palette facts

This ensures CSS output remains stable between runs, preventing unnecessary OpenResty restarts for every service caused by randomized gradients or regenerated CSS files.

Ref: https://chatgpt.com/share/69281d4b-2488-800f-8c0c-c0db44810d1d
This commit is contained in:
2025-11-27 10:44:01 +01:00
parent b80cfbdc9d
commit bee833feb4
10 changed files with 55 additions and 41 deletions

View File

@@ -1,10 +1,24 @@
- name: Generate color palette with colorscheme-generator
set_fact:
color_palette: "{{ lookup('colorscheme', CSS_BASE_COLOR, count=CSS_COUNT, shades=CSS_SHADES) }}"
CSS_COLOR_PALETTE: "{{ lookup('colorscheme', CSS_BASE_COLOR, count=CSS_COUNT, shades=CSS_SHADES) }}"
- name: Generate inverted color palette with colorscheme-generator
set_fact:
inverted_color_palette: "{{ lookup('colorscheme', CSS_BASE_COLOR, count=CSS_COUNT, shades=CSS_SHADES, invert_lightness=True) }}"
CSS_COLOR_PALETTE_INVERTED: "{{ lookup('colorscheme', CSS_BASE_COLOR, count=CSS_COUNT, shades=CSS_SHADES, invert_lightness=True) }}"
- name: "Compute deterministic gradient angle from default.css template mtime"
set_fact:
CSS_GRADIENT_ANGLE: >-
{{
(
lookup(
'local_mtime_qs',
[playbook_dir, 'roles', 'sys-front-inj-css', 'templates', 'css', 'default.css.j2'] | path_join
)
| regex_replace('^.*=', '')
| int
) % 360
}}
- name: Deploy default CSS files
template:

View File

@@ -3,7 +3,7 @@
Now using a button background that is only slightly darker than the overall background */
html[native-dark-active] .btn, .btn {
background-color: var(--color-01-87);
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-70), var(--color-01-91), var(--color-01-95), var(--color-01-95));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-70), var(--color-01-91), var(--color-01-95), var(--color-01-95));
color: var(--color-01-50);
border-color: var(--color-01-80);
cursor: pointer;
@@ -13,7 +13,7 @@ html[native-dark-active] .btn, .btn {
.navbar, .navbar-light, .navbar-dark, .navbar.bg-light {
background-color: var(--color-01-90);
/* New Gradient based on original background (90 -5, 90, 90 +1, 90 +5) */
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-85), var(--color-01-90), var(--color-01-91), var(--color-01-95));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-85), var(--color-01-90), var(--color-01-91), var(--color-01-95));
color: var(--color-01-50);
border-color: var(--color-01-85);
}
@@ -31,7 +31,7 @@ html[native-dark-active] .btn, .btn {
.card {
background-color: var(--color-01-90);
/* New Gradient based on original background (90 -5, 90, 90 +1, 90 +5) */
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-85), var(--color-01-90), var(--color-01-91), var(--color-01-95));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-85), var(--color-01-90), var(--color-01-91), var(--color-01-95));
border-color: var(--color-01-85);
color: var(--color-01-12);
}
@@ -45,7 +45,7 @@ html[native-dark-active] .btn, .btn {
.nav-item .dropdown-menu {
background-color: var(--color-01-80);
/* New Gradient based on original background (80 -5, 80, 80 +1, 80 +5) */
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-75), var(--color-01-80), var(--color-01-81), var(--color-01-85));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-75), var(--color-01-80), var(--color-01-81), var(--color-01-85));
color: var(--color-01-40);
}
@@ -57,13 +57,13 @@ html[native-dark-active] .btn, .btn {
color: var(--color-01-40);
background-color: var(--color-01-80);
/* New Gradient based on original background (80 -5, 80, 80 +1, 80 +5) */
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-75), var(--color-01-80), var(--color-01-81), var(--color-01-85));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-75), var(--color-01-80), var(--color-01-81), var(--color-01-85));
}
.dropdown-item:hover,
.dropdown-item:focus {
background-color: var(--color-01-65);
/* New Gradient based on original background (65 -5, 65, 65 +1, 65 +5) */
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-60), var(--color-01-65), var(--color-01-66), var(--color-01-70));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-60), var(--color-01-65), var(--color-01-66), var(--color-01-70));
color: var(--color-01-40);
}

View File

@@ -15,14 +15,14 @@ HINT:
/* Auto-generated by colorscheme-generator */
:root {
{% for var_name, color in color_palette.items() %}
{% for var_name, color in CSS_COLOR_PALETTE.items() %}
{{ var_name }}: {{ color }};
{% endfor %}
}
@media (prefers-color-scheme: dark) {
:root {
{% for var_name, color in inverted_color_palette.items() %}
{% for var_name, color in CSS_COLOR_PALETTE_INVERTED.items() %}
{{ var_name }}: {{ color }};
{% endfor %}
}
@@ -102,7 +102,7 @@ HINT:
/* Global Defaults (Colors Only) */
body, html[native-dark-active] {
background-color: var(--color-01-93);
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-93), var(--color-01-91), var(--color-01-95), var(--color-01-93));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-93), var(--color-01-91), var(--color-01-95), var(--color-01-93));
background-attachment: fixed;
color: var(--color-01-40);
font-family: {{design.font.type}};
@@ -147,7 +147,7 @@ input:invalid,
textarea:invalid,
select:invalid {
background-color: var(--color-01-01);
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-01), var(--color-01-10));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-01), var(--color-01-10));
/* Use Bootstrap danger color for error messages */
color: var(--bs-danger);
border-color: var(--color-01-20);
@@ -158,7 +158,7 @@ input:valid,
textarea:valid,
select:valid {
background-color: var(--color-01-80);
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-80), var(--color-01-90));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-80), var(--color-01-90));
/* Use Bootstrap success color for confirmation messages */
color: var(--bs-success);
border-color: var(--color-01-70);
@@ -169,7 +169,7 @@ input:required,
textarea:required,
select:required {
background-color: var(--color-01-50);
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-50), var(--color-01-60));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-50), var(--color-01-60));
/* Use Bootstrap warning color to indicate a required field */
color: var(--bs-warning);
border-color: var(--color-01-70);
@@ -180,7 +180,7 @@ input:optional,
textarea:optional,
select:optional {
background-color: var(--color-01-60);
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-60), var(--color-01-70));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-60), var(--color-01-70));
/* Use Bootstrap info color to indicate optional information */
color: var(--bs-info);
border-color: var(--color-01-70);
@@ -191,7 +191,7 @@ input:read-only,
textarea:read-only,
select:read-only {
background-color: var(--color-01-80);
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-90), var(--color-01-70));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-90), var(--color-01-70));
color: var(--color-01-20);
border-color: var(--color-01-50);
}
@@ -201,7 +201,7 @@ input:read-write,
textarea:read-write,
select:read-write {
background-color: var(--color-01-70);
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-70), var(--color-01-80));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-70), var(--color-01-80));
color: var(--color-01-40);
border-color: var(--color-01-70);
}
@@ -211,7 +211,7 @@ input:in-range,
textarea:in-range,
select:in-range {
background-color: var(--color-01-70);
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-70), var(--color-01-85));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-70), var(--color-01-85));
color: var(--color-01-40);
border-color: var(--color-01-70);
}
@@ -221,7 +221,7 @@ input:out-of-range,
textarea:out-of-range,
select:out-of-range {
background-color: var(--color-01-10);
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-10), var(--color-01-30));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-10), var(--color-01-30));
color: var(--color-01-10);
border-color: var(--color-01-50);
}
@@ -231,7 +231,7 @@ input:placeholder-shown,
textarea:placeholder-shown,
select:placeholder-shown {
background-color: var(--color-01-82);
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-82), var(--color-01-90));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-82), var(--color-01-90));
color: var(--color-01-40);
border-color: var(--color-01-70);
}
@@ -241,7 +241,7 @@ input:focus,
textarea:focus,
select:focus {
background-color: var(--color-01-75);
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-75), var(--color-01-85));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-75), var(--color-01-85));
color: var(--color-01-40);
border-color: var(--color-01-50);
}
@@ -251,7 +251,7 @@ input:hover,
textarea:hover,
select:hover {
background-color: var(--color-01-78);
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-78), var(--color-01-88));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-78), var(--color-01-88));
color: var(--color-01-40);
border-color: var(--color-01-65);
}
@@ -261,7 +261,7 @@ input:active,
textarea:active,
select:active {
background-color: var(--color-01-68);
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-68), var(--color-01-78));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-68), var(--color-01-78));
color: var(--color-01-40);
border-color: var(--color-01-60);
}
@@ -269,7 +269,7 @@ select:active {
/* {# Checked state: specifically for radio buttons and checkboxes when selected. #} */
input:checked {
background-color: var(--color-01-90);
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-90), var(--color-01-99));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-90), var(--color-01-99));
color: var(--color-01-40);
border-color: var(--color-01-70);
}
@@ -294,7 +294,7 @@ th, td {
thead {
background-color: var(--color-01-80);
/* New Gradient based on original background (80 -5, 80, 80 +1, 80 +5) */
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-75), var(--color-01-80), var(--color-01-81), var(--color-01-85));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-75), var(--color-01-80), var(--color-01-81), var(--color-01-85));
color: var(--color-01-40);
}

View File

@@ -104,6 +104,6 @@ a.pf-v5-c-nav__link{
div#app header{
background-color: var(--color-01-60);
/* New Gradient based on original background (60 -5, 60, 60 +1, 60 +5) */
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-55), var(--color-01-60), var(--color-01-61), var(--color-01-65));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-55), var(--color-01-60), var(--color-01-61), var(--color-01-65));
color: var(--color-01-98);
}

View File

@@ -37,7 +37,7 @@ ul.lam-tab-navigation {
.titleBar {
background-image: linear-gradient(var(--color-01-83), var(--color-01-92));
/* New Gradient based on original background (83 -5, 83, 83 +1, 83 +5) */
background-image: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-78), var(--color-01-83), var(--color-01-84), var(--color-01-88));
background-image: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-78), var(--color-01-83), var(--color-01-84), var(--color-01-88));
border-top-color: var(--color-01-78);
border-left-color: var(--color-01-87);
border-right-color: var(--color-01-87);
@@ -46,6 +46,6 @@ ul.lam-tab-navigation {
div.statusInfo {
background-color: var(--color-01-81);
/* New Gradient based on original background (81 -5, 81, 81 +1, 81 +5) */
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-76), var(--color-01-81), var(--color-01-82), var(--color-01-86));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-76), var(--color-01-81), var(--color-01-82), var(--color-01-86));
color: var(--color-01-23);
}

View File

@@ -1,18 +1,18 @@
[class*=sidebar-dark-], .bg-mailu-logo {
background-color: var(--color-01-90);
/* New Gradient based on original background (90 -5, 90, 90 +1, 90 +5) */
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-85), var(--color-01-90), var(--color-01-91), var(--color-01-95));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-85), var(--color-01-90), var(--color-01-91), var(--color-01-95));
}
div.statusError {
background-color: var(--color-01-60);
/* New Gradient based on original background (60 -5, 60, 60 +1, 60 +5) */
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-55), var(--color-01-60), var(--color-01-61), var(--color-01-65));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-55), var(--color-01-60), var(--color-01-61), var(--color-01-65));
}
div.wrapper footer.main-footer, div.wrapper div.content-wrapper{
background-color: var(--color-01-85);
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-89), var(--color-01-85), var(--color-01-80), var(--color-01-79));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-89), var(--color-01-85), var(--color-01-80), var(--color-01-79));
color: var(--color-01-39);
}

View File

@@ -40,7 +40,7 @@
body.skin-vector,
.skin-vector .mw-page-container {
background-color: var(--mw-surface);
background-image: linear-gradient({{ range(0, 361) | random }}deg,
background-image: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg,
var(--mw-surface),
var(--mw-surface-variant),
var(--mw-surface-muted),
@@ -54,7 +54,7 @@ body.skin-vector,
.skin-vector .vector-header-container,
.skin-vector .mw-header {
background-color: var(--color-01-80);
background-image: linear-gradient({{ range(0, 361) | random }}deg,
background-image: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg,
var(--color-01-75), var(--color-01-80), var(--color-01-81), var(--color-01-85)
);
color: var(--color-01-17);
@@ -211,7 +211,7 @@ table.wikitable > * > tr > td {
table.wikitable > * > tr > th {
background-color: var(--color-01-80);
background-image: linear-gradient({{ range(0, 361) | random }}deg,
background-image: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg,
var(--color-01-75), var(--color-01-80), var(--color-01-81), var(--color-01-85)
);
color: var(--mw-heading);

View File

@@ -14,7 +14,7 @@
html.ng-csp header#header{
background-color: var(--color-01-80);
/* New Gradient based on original background (80 -5, 80, 80 +1, 80 +5) */
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-75), var(--color-01-80), var(--color-01-81), var(--color-01-85));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-75), var(--color-01-80), var(--color-01-81), var(--color-01-85));
color: var(--color-01-17);
}
@@ -40,7 +40,7 @@ div#mastodon .column-back-button {
div#mastodon textarea, div#mastodon input, div#mastodon .compose-form__highlightable {
background-color: var(--color-01-89);
/* New Gradient based on original background (89 -5, 89, 89 +1, 89 +5) */
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-84), var(--color-01-89), var(--color-01-90), var(--color-01-94));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-84), var(--color-01-89), var(--color-01-90), var(--color-01-94));
color: var(--color-01-19);
}
@@ -57,7 +57,7 @@ div#mastodon .dropdown-button{
div#mastodon .button, div#mastodon .button:active, div#mastodon .button:focus, div#mastodon .button:hover{
background-color: var(--color-01-71);
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-66), var(--color-01-71), var(--color-01-72), var(--color-01-76));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-66), var(--color-01-71), var(--color-01-72), var(--color-01-76));
}
.compose-form__actions .icon-button {

View File

@@ -1,6 +1,6 @@
header.op-app-header{
background-color: var(--color-01-40);
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-35), var(--color-01-40), var(--color-01-41), var(--color-01-45));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-35), var(--color-01-40), var(--color-01-41), var(--color-01-45));
color: var(--color-01-40);
}

View File

@@ -20,7 +20,7 @@ section.main.kanban{
div.master, div.kanban-header, div.kanban-table-inner, section.kanban button,a.dropdown-project-list-projects{
background-color: var(--color-01-92);
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-87), var(--color-01-92), var(--color-01-93), var(--color-01-97));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-87), var(--color-01-92), var(--color-01-93), var(--color-01-97));
color: var(--color-01-40);
}
@@ -30,14 +30,14 @@ section.kanban h1, section.kanban h2{
.home-project {
background: var(--color-01-88);
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-83), var(--color-01-88), var(--color-01-89), var(--color-01-93));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-83), var(--color-01-88), var(--color-01-89), var(--color-01-93));
border-color: var(--color-01-60);
color: var(--color-01-12);
}
.home-wrapper .title-bar {
background: var(--color-01-75);
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-01-70), var(--color-01-75), var(--color-01-76), var(--color-01-80));
background: linear-gradient({{ CSS_GRADIENT_ANGLE }}deg, var(--color-01-70), var(--color-01-75), var(--color-01-76), var(--color-01-80));
}
.kanban.swimlane .kanban-header {