Implemented Global CSS draft

This commit is contained in:
2025-02-07 13:39:46 +01:00
parent 44438dab64
commit 9efca268c9
43 changed files with 327 additions and 68 deletions

View File

@@ -0,0 +1,43 @@
# 🌍 Nginx Global Theming Role
This **Ansible role** provides a **global theming solution** for Nginx-based web applications. It ensures a **consistent look and feel** across multiple applications by injecting a **unified global.css** with customizable theming options.
---
## 🚀 Features
**Automatic CSS Deployment** Injects `global.css` into all Nginx-served applications.
**Dynamic Theming** Uses `global_theming.css.colors` from Ansible variables for **full customization**.
**Bootstrap Override Support** Ensures Bootstrap-based apps use the **unified global styles**.
**Versioning System** Prevents caching issues with automatic **timestamp-based versioning**.
**Dark Mode Support** Automatically adapts to user preferences.
**Runs Once Per Deployment** Avoids redundant executions with `run_once_nginx_global_css`.
---
## 📂 File Structure
```
.
├── tasks/
│ ├── main.yml # Main Ansible tasks for deploying the global CSS
├── vars/
│ ├── main.yml # Global variables (CSS paths, file names, etc.)
├── templates/
│ ├── global.css.j2 # Jinja2 template for generating the global CSS
│ ├── location.conf.j2 # Nginx configuration for serving global.css
│ ├── sub_filter.conf.j2 # Injects the global CSS link into served pages
└── README.md # You are here 🚀
```
---
## 🎨 Theming Details
The **CSS template (`global.css.j2`)** dynamically applies the defined theme colors and ensures **Bootstrap, buttons, alerts, forms, and other UI elements** follow the **unified design**.
## 🛠️ Contribution
Feel free to **fork, modify, and improve** this role! Contributions are always welcome. 🛠️🔥
---
🚀 **Happy Theming!** 🎨✨
*Created by [Kevin Veen-Birkenbach](https://www.veen.world) with the assistance of [ChatGPT](https://chatgpt.com/share/67a5fea3-4d5c-800f-8bc4-605712c02c9b).

View File

@@ -0,0 +1,28 @@
- name: Get the current Unix timestamp as version
set_fact:
global_css_version: "{{ ansible_date_time.epoch }}"
when: run_once_nginx_global_css is not defined
- name: Ensure {{nginx.directories.global}} directory exists
file:
path: "{{nginx.directories.global}}"
state: directory
owner: "{{nginx.user}}"
group: "{{nginx.user}}"
mode: '0755'
when: run_once_nginx_global_css is not defined
- name: Deploy global.css from template
template:
src: global.css.j2
dest: "{{global_css_destination}}"
owner: "{{nginx.user}}"
group: "{{nginx.user}}"
mode: '0644'
when: run_once_nginx_global_css is not defined
- name: run the global css tasks once
set_fact:
run_once_nginx_global_css: true
when: run_once_nginx_global_css is not defined

View File

@@ -0,0 +1,151 @@
/* Global Theming Styles - Overrides Application Defaults */
:root {
--primary-color: {{ global_theming.css.colors.primary }};
--secondary-color: {{ global_theming.css.colors.secondary }};
--background-color: {{ global_theming.css.colors.background }};
--background-dark-color: {{ global_theming.css.colors.background_dark }};
--text-color: {{ global_theming.css.colors.text }};
--accent-color: {{ global_theming.css.colors.accent }};
--success-color: {{ global_theming.css.colors.success }};
--warning-color: {{ global_theming.css.colors.warning }};
--error-color: {{ global_theming.css.colors.error }};
--info-color: {{ global_theming.css.colors.info }};
--link-color: {{ global_theming.css.colors.link }};
--button-text-color: {{ global_theming.css.colors.button_text }};
--shadow-color: {{ global_theming.css.colors.shadow }};
--border-color: {{ global_theming.css.colors.border }};
}
/* Bootstrap Overrides */
:root {
--bs-primary: var(--primary-color);
--bs-secondary: var(--secondary-color);
--bs-body-bg: var(--background-color);
--bs-body-color: var(--text-color);
--bs-danger: var(--error-color);
--bs-warning: var(--warning-color);
--bs-success: var(--success-color);
--bs-info: var(--info-color);
--bs-link-color: var(--link-color);
--bs-btn-color: var(--button-text-color);
}
/* Ensure Styles Take Priority */
*,
*::before,
*::after {
all: unset;
all: revert;
}
/* Global Defaults */
body {
background-color: var(--background-color) !important;
color: var(--text-color) !important;
font-family: Arial, sans-serif;
line-height: 1.6;
}
/* Links */
a {
color: var(--link-color) !important;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
/* Buttons */
button, .btn {
background-color: var(--primary-color) !important;
color: var(--button-text-color) !important;
border: 1px solid var(--border-color) !important;
box-shadow: 2px 2px 5px var(--shadow-color) !important;
padding: 10px 15px;
border-radius: 5px;
font-weight: bold;
cursor: pointer;
}
button:hover, .btn:hover {
filter: brightness(0.9);
}
/* Success, Warning, Error States */
.success, .alert-success {
background-color: var(--success-color) !important;
color: white !important;
}
.warning, .alert-warning {
background-color: var(--warning-color) !important;
color: black !important;
}
.error, .alert-danger {
background-color: var(--error-color) !important;
color: white !important;
}
.info, .alert-info {
background-color: var(--info-color) !important;
color: white !important;
}
/* Inputs & Forms */
input, textarea, select {
background-color: var(--background-color) !important;
color: var(--text-color) !important;
border: 1px solid var(--border-color) !important;
padding: 8px;
border-radius: 4px;
}
input:focus, textarea:focus, select:focus {
border-color: var(--primary-color) !important;
outline: none;
box-shadow: 0 0 5px var(--shadow-color);
}
/* Navigation */
.navbar, .navbar-light, .navbar-dark {
background-color: var(--primary-color) !important;
color: var(--button-text-color) !important;
}
.navbar a {
color: var(--button-text-color) !important;
}
/* Tables */
table {
width: 100%;
border-collapse: collapse;
}
th, td {
padding: 10px;
border: 1px solid var(--border-color);
}
thead {
background-color: var(--primary-color);
color: var(--button-text-color);
}
/* Cards / Containers */
.card {
background-color: var(--background-color) !important;
box-shadow: 2px 2px 10px var(--shadow-color) !important;
border: 1px solid var(--border-color);
border-radius: 8px;
}
/* Dark Mode */
@media (prefers-color-scheme: dark) {
body {
background-color: var(--background-dark-color) !important;
color: var(--text-color) !important;
}
input, textarea, select {
background-color: var(--background-dark-color) !important;
color: var(--text-color) !important;
}
}
/* Enforce Style Priority */
html, body, * {
!important;
}

View File

@@ -0,0 +1,3 @@
location = /global.css {
root {{nginx.directories.global}};
}

View File

@@ -0,0 +1 @@
sub_filter '<head>' '<head><link rel="stylesheet" type="text/css" href="/global.css?version={{global_css_version}}">';

View File

@@ -0,0 +1 @@
global_css_destination: "{{nginx.directories.global}}global.css"