mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-09-09 19:57:16 +02:00
feat(frontend): rename inj roles to sys-front-*, add sys-svc-cdn, cache-busting lookup
Introduce sys-svc-cdn (cdn_paths/cdn_urls/cdn_dirs) and ensure CDN directories + latest symlink. Rename sys-srv-web-inj-* → sys-front-inj-*; update includes/templates; serve shared/per-app CSS & JS via CDN. Add lookup_plugins/local_mtime_qs.py for mtime-based cache busting; split CSS into default.css/bootstrap.css + optional per-app style.css. CSP: use style-src-elem; drop unsafe-inline for styles. Services: fix SYS_SERVICE_ALL_ENABLED bool and controlled flush. BREAKING CHANGE: role names changed; replace includes and references accordingly. Conversation: https://chatgpt.com/share/68b55494-9ec4-800f-b559-44707029141d
This commit is contained in:
69
roles/sys-front-inj-css/templates/css/bootstrap.css.j2
Normal file
69
roles/sys-front-inj-css/templates/css/bootstrap.css.j2
Normal file
@@ -0,0 +1,69 @@
|
||||
|
||||
/* Buttons (Background, Text, Border, and Shadow)
|
||||
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));
|
||||
color: var(--color-01-50);
|
||||
border-color: var(--color-01-80);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Navigation (Background and Text Colors) */
|
||||
.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));
|
||||
color: var(--color-01-50);
|
||||
border-color: var(--color-01-85);
|
||||
}
|
||||
|
||||
.navbar a {
|
||||
color: var(--color-01-40);
|
||||
}
|
||||
|
||||
.navbar a.dropdown-item {
|
||||
color: var(--color-01-43);
|
||||
}
|
||||
|
||||
/* Cards / Containers (Background, Border, and Shadow)
|
||||
Cards now use a slightly lighter background and a bold, clear shadow */
|
||||
.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));
|
||||
border-color: var(--color-01-85);
|
||||
color: var(--color-01-12);
|
||||
}
|
||||
|
||||
.card-body {
|
||||
color: var(--color-01-40);
|
||||
}
|
||||
|
||||
/* Dropdown Menu and Submenu (Background, Text, and Shadow) */
|
||||
.navbar .dropdown-menu,
|
||||
.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));
|
||||
color: var(--color-01-40);
|
||||
}
|
||||
|
||||
.navbar-nav {
|
||||
--bs-nav-link-hover-color: var(--color-01-17);
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
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));
|
||||
}
|
||||
|
||||
.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));
|
||||
color: var(--color-01-40);
|
||||
}
|
297
roles/sys-front-inj-css/templates/css/default.css.j2
Normal file
297
roles/sys-front-inj-css/templates/css/default.css.j2
Normal file
@@ -0,0 +1,297 @@
|
||||
/***
|
||||
|
||||
Global Theming Styles – Color and Shadow Variables
|
||||
|
||||
HINT:
|
||||
- Better overwritte CSS variables instead of individual elements.
|
||||
- Don't use !important. If possible use a specific selector.
|
||||
|
||||
*/
|
||||
|
||||
{% if design.font.import_url %}
|
||||
@import url('{{ design.font.import_url }}');
|
||||
{% endif %}
|
||||
|
||||
/* Auto-generated by colorscheme-generator */
|
||||
|
||||
:root {
|
||||
{% for var_name, color in color_palette.items() %}
|
||||
{{ var_name }}: {{ color }};
|
||||
{% endfor %}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
{% for var_name, color in inverted_color_palette.items() %}
|
||||
{{ var_name }}: {{ color }};
|
||||
{% endfor %}
|
||||
}
|
||||
}
|
||||
|
||||
:root, ::after, ::before, ::backdrop {
|
||||
/* For Dark Mode Plugin
|
||||
* @See https://chromewebstore.google.com/detail/dark-mode/dmghijelimhndkbmpgbldicpogfkceaj
|
||||
*/
|
||||
--native-dark-accent-color: var(--color-01-60); /* was #a9a9a9 */
|
||||
--native-dark-bg-color: var(--color-01-10); /* was #292929 */
|
||||
--native-dark-bg-image-color: rgba(var(--color-01-rgb-01), 0.10); /* remains the same, or adjust if needed */
|
||||
--native-dark-border-color: var(--color-01-40); /* was #555555 */
|
||||
--native-dark-box-shadow: 0 0 0 1px rgb(var(--color-01-rgb-99), / 10%);
|
||||
--native-dark-cite-color: var(--color-01-70); /* was #92de92 – you might adjust if a green tone is needed */
|
||||
--native-dark-fill-color: var(--color-01-50); /* was #7d7d7d */
|
||||
--native-dark-font-color: var(--color-01-95); /* was #dcdcdc */
|
||||
--native-dark-link-color: var(--color-01-80); /* was #8db2e5 */
|
||||
--native-dark-visited-link-color: var(--color-01-85); /* was #c76ed7 */
|
||||
}
|
||||
|
||||
/* Bootstrap Overrides (Color/Shadow Variables Only) */
|
||||
:root {
|
||||
--bs-black: var(--color-01-01); /* Original tone: Black (#000) */
|
||||
--bs-white: var(--color-01-99); /* Original tone: White (#fff) */
|
||||
--bs-gray: var(--color-01-50); /* Original tone: Gray (#6c757d) */
|
||||
--bs-gray-dark: var(--color-01-20); /* Original tone: Dark Gray (#343a40) */
|
||||
{% for i in range(1, 10) %}
|
||||
{# @see https://chatgpt.com/share/67bcd94e-bb44-800f-bf63-06d1ae0f5096 #}
|
||||
{% set gray = i * 100 %}
|
||||
{% set color = 100 - i * 10 %}
|
||||
--bs-gray-{{ gray }}: var(--color-01-{{ "%02d" % color }});
|
||||
{% endfor %}
|
||||
--bs-primary: var(--color-01-65); /* Original tone: Blue (#0d6efd) */
|
||||
--bs-light: var(--color-01-95); /* Original tone: Light (#f8f9fa) */
|
||||
--bs-dark: var(--color-01-10); /* Original tone: Dark (#212529) */
|
||||
--bs-primary-rgb: var(--color-01-rgb-65); /* Original tone: Blue (13, 110, 253) */
|
||||
--bs-secondary-rgb: var(--color-01-rgb-50); /* Original tone: Grayish (#6c757d / 108, 117, 125) */
|
||||
--bs-light-rgb: var(--color-01-rgb-95); /* Original tone: Light (248, 249, 250) */
|
||||
--bs-dark-rgb: var(--color-01-rgb-10); /* Original tone: Dark (33, 37, 41) */
|
||||
--bs-white-rgb: var(--color-01-rgb-99); /* Original tone: White (255, 255, 255) */
|
||||
--bs-black-rgb: var(--color-01-rgb-01); /* Original tone: Black (0, 0, 0) */
|
||||
--bs-body-color-rgb: var(--color-01-rgb-10); /* Original tone: Dark (#212529 / 33, 37, 41) */
|
||||
--bs-body-bg-rgb: var(--color-01-rgb-99); /* Original tone: White (#fff / 255, 255, 255) */
|
||||
--bs-body-color: var(--color-01-10); /* Original tone: Dark (#212529) */
|
||||
--bs-body-bg: var(--color-01-99); /* Original tone: White (#fff) */
|
||||
--bs-border-color: var(--color-01-85); /* Original tone: Gray (#dee2e6) */
|
||||
--bs-link-color: var(--color-01-65); /* Original tone: Blue (#0d6efd) */
|
||||
--bs-link-hover-color: var(--color-01-60); /* Original tone: Darker Blue (#0a58ca) */
|
||||
--bs-code-color: var(--color-01-55); /* Original tone: Pink (#d63384) */
|
||||
--bs-highlight-bg: var(--color-01-93); /* Original tone: Light Yellow (#fff3cd) */
|
||||
--bs-list-group-bg: var(--color-01-40);
|
||||
--bs-emphasis-color: var(--color-01-01); /* Gemappt von #000 */
|
||||
--bs-emphasis-color-rgb: var(--color-01-rgb-01); /* Gemappt von 0, 0, 0 */
|
||||
--bs-secondary-color: rgba(var(--color-01-rgb-10), 0.75); /* Gemappt von rgba(33, 37, 41, 0.75) */
|
||||
--bs-secondary-color-rgb: var(--color-01-rgb-10); /* Gemappt von 33, 37, 41 */
|
||||
--bs-secondary-bg: var(--color-01-90); /* Gemappt von #e9ecef */
|
||||
--bs-secondary-bg-rgb: var(--color-01-rgb-90); /* Gemappt von 233, 236, 239 */
|
||||
--bs-tertiary-color: rgba(var(--color-01-rgb-10), 0.5); /* Gemappt von rgba(33, 37, 41, 0.5) */
|
||||
--bs-tertiary-color-rgb: var(--color-01-rgb-10); /* Gemappt von 33, 37, 41 */
|
||||
--bs-tertiary-bg: var(--color-01-95); /* Gemappt von #f8f9fa */
|
||||
--bs-tertiary-bg-rgb: var(--color-01-rgb-95); /* Gemappt von 248, 249, 250 */
|
||||
--bs-link-color-rgb: var(--color-01-rgb-65); /* Gemappt von 13, 110, 253 */
|
||||
--bs-link-hover-color-rgb: var(--color-01-rgb-60); /* Gemappt von 10, 88, 202 */
|
||||
--bs-highlight-color: var(--color-01-10); /* Gemappt von #212529 */
|
||||
--bs-border-color-translucent: rgba(var(--color-01-rgb-01), 0.175); /* Gemappt von rgba(0, 0, 0, 0.175) */
|
||||
--bs-focus-ring-color: rgba(var(--color-01-rgb-65), 0.25); /* Gemappt von rgba(13, 110, 253, 0.25) */
|
||||
|
||||
--bs-table-color: var(--bs-emphasis-color);
|
||||
--bs-table-bg: var(--color-01-99); /* White (#fff) */
|
||||
--bs-table-border-color: var(--color-01-99); /* White (#fff) */
|
||||
--bs-table-striped-bg: var(--color-01-85); /* Light Gray (entspricht ca. #dee2e6) */
|
||||
--bs-table-hover-color: var(--color-01-01); /* Black (#000) */
|
||||
--bs-table-hover-bg: rgba(var(--bs-emphasis-color-rgb), 0.075);
|
||||
}
|
||||
|
||||
/* 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-attachment: fixed;
|
||||
color: var(--color-01-40);
|
||||
font-family: {{design.font.type}};
|
||||
}
|
||||
|
||||
{# All links (applies to all anchor elements regardless of state) #}
|
||||
a {
|
||||
color: var(--color-01-50);
|
||||
}
|
||||
|
||||
{# Unvisited links (applies only to links that have not been visited) #}
|
||||
a:link {
|
||||
color: var(--color-01-55);
|
||||
}
|
||||
|
||||
{# Visited links (applies only to links that have been visited) #}
|
||||
a:visited {
|
||||
color: var(--color-01-45);
|
||||
}
|
||||
|
||||
{# Hover state (applies when the mouse pointer is over the link) #}
|
||||
a:hover {
|
||||
color: var(--color-01-60);
|
||||
}
|
||||
|
||||
{# Active state (applies during the time the link is being activated, e.g., on click) #}
|
||||
a:active {
|
||||
color: var(--color-01-65);
|
||||
}
|
||||
|
||||
/** Set default buttons transparent **/
|
||||
html[native-dark-active] button, button{
|
||||
background-color: var(--color-01-87);
|
||||
}
|
||||
|
||||
button:hover, .btn:hover {
|
||||
filter: brightness(0.9);
|
||||
}
|
||||
|
||||
/* {# Invalid state: when the input value fails validation criteria. Use danger color for error indication. #} */
|
||||
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));
|
||||
/* Use Bootstrap danger color for error messages */
|
||||
color: var(--bs-danger);
|
||||
border-color: var(--color-01-20);
|
||||
}
|
||||
|
||||
/* {# Valid state: when the input value meets all validation criteria. Use success color for confirmation. #} */
|
||||
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));
|
||||
/* Use Bootstrap success color for confirmation messages */
|
||||
color: var(--bs-success);
|
||||
border-color: var(--color-01-70);
|
||||
}
|
||||
|
||||
/* {# Required field: applied to elements that must be filled out by the user. Use warning color for emphasis. #} */
|
||||
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));
|
||||
/* Use Bootstrap warning color to indicate a required field */
|
||||
color: var(--bs-warning);
|
||||
border-color: var(--color-01-70);
|
||||
}
|
||||
|
||||
/* {# Optional field: applied to elements that are not mandatory. Use info color to denote additional information. #} */
|
||||
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));
|
||||
/* Use Bootstrap info color to indicate optional information */
|
||||
color: var(--bs-info);
|
||||
border-color: var(--color-01-70);
|
||||
}
|
||||
|
||||
/* {# Read-only state: when an element is not editable by the user. #} */
|
||||
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));
|
||||
color: var(--color-01-20);
|
||||
border-color: var(--color-01-50);
|
||||
}
|
||||
|
||||
/* {# Read-write state: when an element is editable by the user. #} */
|
||||
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));
|
||||
color: var(--color-01-40);
|
||||
border-color: var(--color-01-70);
|
||||
}
|
||||
|
||||
/* {# In-range: for inputs with a defined range, when the value is within the allowed limits. #} */
|
||||
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));
|
||||
color: var(--color-01-40);
|
||||
border-color: var(--color-01-70);
|
||||
}
|
||||
|
||||
/* {# Out-of-range: for inputs with a defined range, when the value falls outside the allowed limits. #} */
|
||||
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));
|
||||
color: var(--color-01-10);
|
||||
border-color: var(--color-01-50);
|
||||
}
|
||||
|
||||
/* {# Placeholder-shown: when the input field is displaying its placeholder text. #} */
|
||||
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));
|
||||
color: var(--color-01-40);
|
||||
border-color: var(--color-01-70);
|
||||
}
|
||||
|
||||
/* {# Focus state: when the element is focused by the user. #} */
|
||||
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));
|
||||
color: var(--color-01-40);
|
||||
border-color: var(--color-01-50);
|
||||
}
|
||||
|
||||
/* {# Hover state: when the mouse pointer is over the element. #} */
|
||||
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));
|
||||
color: var(--color-01-40);
|
||||
border-color: var(--color-01-65);
|
||||
}
|
||||
|
||||
/* {# Active state: when the element is being activated (e.g., clicked). #} */
|
||||
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));
|
||||
color: var(--color-01-40);
|
||||
border-color: var(--color-01-60);
|
||||
}
|
||||
|
||||
/* {# 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));
|
||||
color: var(--color-01-40);
|
||||
border-color: var(--color-01-70);
|
||||
}
|
||||
|
||||
option {
|
||||
background-color: var(--color-01-82);
|
||||
color: var(--color-01-07);
|
||||
}
|
||||
|
||||
/* Tables (Borders and Header Colors) */
|
||||
th, td {
|
||||
border-color: var(--color-01-70);
|
||||
}
|
||||
|
||||
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));
|
||||
color: var(--color-01-40);
|
||||
}
|
||||
|
||||
/* Headings (Text Color) */
|
||||
h1, h2, h3, h4, h5, h6, p{
|
||||
color: var(--color-01-10);
|
||||
}
|
8
roles/sys-front-inj-css/templates/head_sub.j2
Normal file
8
roles/sys-front-inj-css/templates/head_sub.j2
Normal file
@@ -0,0 +1,8 @@
|
||||
{% set __css_tpl_dir = [playbook_dir, 'roles', 'sys-front-inj-css', 'templates', 'css'] | path_join %}
|
||||
|
||||
{% for css_file in ['default.css','bootstrap.css'] %}
|
||||
<link rel="stylesheet" href="{{ [ cdn_urls.shared.css, css_file, lookup('local_mtime_qs', [__css_tpl_dir, css_file ~ '.j2'] | path_join)] | url_join }}">
|
||||
{% endfor %}
|
||||
{% if app_style_present | bool %}
|
||||
<link rel="stylesheet" href="{{ [ cdn_urls.role.release.css, 'style.css', lookup('local_mtime_qs', app_style_src)] | url_join }}">
|
||||
{% endif %}
|
Reference in New Issue
Block a user