parent
1f169b0131
commit
ba4866919e
9 changed files with 479 additions and 2 deletions
61
.forgejo/workflows/build-dark.yml
Normal file
61
.forgejo/workflows/build-dark.yml
Normal file
|
@ -0,0 +1,61 @@
|
|||
name: Build and Deploy Dark-theme Static Site
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: docker
|
||||
container: git.private.coffee/privatecoffee/static-site-builder:latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python3 -m pip install -r requirements.txt --break-system-packages
|
||||
|
||||
- name: Generate static site
|
||||
run: python3 main.py --theme dark --domains dark.private.coffee
|
||||
|
||||
- name: Deploy to pages-pride branch
|
||||
run: |
|
||||
# Configure Git
|
||||
git config --global user.name "Forgejo"
|
||||
git config --global user.email "noreply@private.coffee"
|
||||
|
||||
# Move generated static site files to a temporary location
|
||||
mv build ../static_site_temp
|
||||
cp .gitignore ../static_site_temp
|
||||
|
||||
# Create a new orphan branch named 'pages-dark'
|
||||
git checkout --orphan pages-dark
|
||||
|
||||
# Remove all files from the working directory
|
||||
git rm -rf .
|
||||
|
||||
# Move the static site files back to the working directory
|
||||
mv ../static_site_temp/* ./
|
||||
mv ../static_site_temp/.* ./ 2>/dev/null || true
|
||||
|
||||
# Add and commit the static site files
|
||||
git add .
|
||||
git commit -m "Deploy static site"
|
||||
|
||||
# Set the URL again
|
||||
git remote set-url origin "https://${{ secrets.FORGEJO_USER }}:${{ secrets.FORGEJO_TOKEN }}@git.private.coffee/PrivateCoffee/privatecoffee-website.git"
|
||||
|
||||
# Force push to the 'pages-dark' branch
|
||||
git push origin pages-dark --force
|
||||
|
||||
- name: Save as artifact
|
||||
uses: https://code.forgejo.org/forgejo/upload-artifact@v4
|
||||
with:
|
||||
name: static-site.zip
|
||||
path: .
|
|
@ -1,4 +1,4 @@
|
|||
name: Build and Deploy Static Site
|
||||
name: Build and Deploy Development Static Site
|
||||
|
||||
on:
|
||||
push:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
name: Build and Deploy Static Site
|
||||
name: Build and Deploy Pride-Theme Static Site
|
||||
|
||||
on:
|
||||
push:
|
||||
|
|
|
@ -390,4 +390,36 @@ h5 {
|
|||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
}
|
||||
|
||||
/* Theme toggle styles */
|
||||
.theme-toggle-container {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.theme-toggle-container .btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
padding: 0;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.theme-toggle-container .btn svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
/* Dark theme specific toggle styles */
|
||||
[data-bs-theme="dark"] .theme-toggle-container .btn-outline-primary {
|
||||
color: #f785c4;
|
||||
border-color: #f785c4;
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .theme-toggle-container .btn-outline-primary:hover {
|
||||
background-color: #f785c4;
|
||||
color: #121212;
|
||||
}
|
357
assets/css/theme/dark.css
Normal file
357
assets/css/theme/dark.css
Normal file
|
@ -0,0 +1,357 @@
|
|||
/* Dark theme */
|
||||
:root,
|
||||
[data-bs-theme="dark"] {
|
||||
--bs-primary: #d25ea0;
|
||||
--bs-primary-rgb: 210, 94, 160;
|
||||
--bs-primary-text-emphasis: #e07eb4;
|
||||
--bs-primary-bg-subtle: #3d2936;
|
||||
--bs-primary-border-subtle: #5e3e52;
|
||||
|
||||
--bs-body-color: #e0e0e0;
|
||||
--bs-body-color-rgb: 224, 224, 224;
|
||||
--bs-body-bg: #2a2a2a;
|
||||
--bs-body-bg-rgb: 42, 42, 42;
|
||||
|
||||
--bs-secondary-color: rgba(224, 224, 224, 0.75);
|
||||
--bs-secondary-color-rgb: 224, 224, 224;
|
||||
--bs-tertiary-color: rgba(224, 224, 224, 0.5);
|
||||
--bs-tertiary-color-rgb: 224, 224, 224;
|
||||
|
||||
--bs-emphasis-color: #fff;
|
||||
--bs-emphasis-color-rgb: 255, 255, 255;
|
||||
|
||||
--bs-border-color: #444444;
|
||||
--bs-border-color-translucent: rgba(255, 255, 255, 0.1);
|
||||
|
||||
--bs-light-rgb: 50, 50, 50;
|
||||
--bs-dark-rgb: 34, 34, 34;
|
||||
--bs-white-rgb: 42, 42, 42;
|
||||
}
|
||||
|
||||
/* Background gradient */
|
||||
.bg-primary-gradient {
|
||||
background: linear-gradient(135deg, #3d2936, #4d3946);
|
||||
}
|
||||
|
||||
/* Logo images */
|
||||
#logoContainer {
|
||||
background-image: url(../../img/logo-white.svg);
|
||||
}
|
||||
|
||||
#smallLogoContainer {
|
||||
background-image: url(../../img/logo-white.svg);
|
||||
}
|
||||
|
||||
/* Card and accordion styles */
|
||||
.card, .accordion {
|
||||
background-color: #333333;
|
||||
border-color: #444444;
|
||||
}
|
||||
|
||||
.card-body, .accordion-body {
|
||||
color: var(--bs-body-color);
|
||||
}
|
||||
|
||||
.accordion-header {
|
||||
background-color: #3a3a3a;
|
||||
color: var(--bs-body-color);
|
||||
}
|
||||
|
||||
.accordion-header:hover {
|
||||
background-color: #444444;
|
||||
}
|
||||
|
||||
/* Dropdown styles */
|
||||
.dropdown-content {
|
||||
background-color: #333333;
|
||||
border: 1px solid #444444;
|
||||
}
|
||||
|
||||
.dropdown-content a {
|
||||
color: var(--bs-body-color);
|
||||
}
|
||||
|
||||
.dropdown-content a:hover {
|
||||
background-color: #444444;
|
||||
}
|
||||
|
||||
/* Table styles */
|
||||
.transparency-start-balance-row>td {
|
||||
background-color: rgba(61, 41, 54, 0.3) !important;
|
||||
}
|
||||
|
||||
.table {
|
||||
color: var(--bs-body-color);
|
||||
}
|
||||
|
||||
.table-light {
|
||||
--bs-table-bg: #3a3a3a;
|
||||
--bs-table-color: var(--bs-body-color);
|
||||
}
|
||||
|
||||
.table-secondary {
|
||||
--bs-table-bg: #444444;
|
||||
--bs-table-color: var(--bs-body-color);
|
||||
}
|
||||
|
||||
.table-bordered {
|
||||
border-color: #444444;
|
||||
}
|
||||
|
||||
/* Button styles */
|
||||
.btn-primary {
|
||||
--bs-btn-color: #222222;
|
||||
--bs-btn-bg: #d25ea0;
|
||||
--bs-btn-border-color: #d25ea0;
|
||||
--bs-btn-hover-color: #222222;
|
||||
--bs-btn-hover-bg: #db74ab;
|
||||
--bs-btn-hover-border-color: #d868a6;
|
||||
--bs-btn-focus-shadow-rgb: 210, 94, 160;
|
||||
--bs-btn-active-color: #222222;
|
||||
--bs-btn-active-bg: #e07eb4;
|
||||
--bs-btn-active-border-color: #d868a6;
|
||||
}
|
||||
|
||||
.btn-outline-primary {
|
||||
--bs-btn-color: #d25ea0;
|
||||
--bs-btn-border-color: #d25ea0;
|
||||
--bs-btn-hover-color: #222222;
|
||||
--bs-btn-hover-bg: #d25ea0;
|
||||
--bs-btn-hover-border-color: #d25ea0;
|
||||
--bs-btn-active-color: #222222;
|
||||
--bs-btn-active-bg: #d25ea0;
|
||||
--bs-btn-active-border-color: #d25ea0;
|
||||
}
|
||||
|
||||
/* Link styles */
|
||||
a {
|
||||
color: #d25ea0;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #e07eb4;
|
||||
}
|
||||
|
||||
/* Text styles */
|
||||
.text-muted {
|
||||
color: #aaaaaa !important; /* My thoughts. */
|
||||
}
|
||||
|
||||
.fancy-text-primary {
|
||||
background: -webkit-linear-gradient(45deg, #d25ea0, #e07eb4);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
/* Navbar styles */
|
||||
.navbar-light {
|
||||
background-color: #333333 !important;
|
||||
}
|
||||
|
||||
.navbar-light .navbar-nav .nav-link {
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
.navbar-light .navbar-nav .nav-link:hover,
|
||||
.navbar-light .navbar-nav .nav-link.active {
|
||||
color: #d25ea0;
|
||||
}
|
||||
|
||||
/* Fix for navbar brand text color */
|
||||
.navbar-brand p {
|
||||
color: #e0e0e0 !important;
|
||||
}
|
||||
|
||||
.navbar-brand span[style*="color: rgb(35, 35, 35)"] {
|
||||
color: #e0e0e0 !important;
|
||||
}
|
||||
|
||||
/* Footer styles */
|
||||
footer.bg-primary-gradient {
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
footer a {
|
||||
color: #d25ea0;
|
||||
}
|
||||
|
||||
footer a:hover {
|
||||
color: #e07eb4;
|
||||
}
|
||||
|
||||
footer .text-muted {
|
||||
color: #aaaaaa !important;
|
||||
}
|
||||
|
||||
/* Alert styles */
|
||||
.alert-warning {
|
||||
background-color: #3d3223;
|
||||
border-color: #594832;
|
||||
color: #e0c088;
|
||||
}
|
||||
|
||||
.alert-warning .alert-link {
|
||||
color: #e0c088;
|
||||
}
|
||||
|
||||
/* Icon styles */
|
||||
.bs-icon.bs-icon-primary svg {
|
||||
fill: #d25ea0 !important;
|
||||
}
|
||||
|
||||
.bs-icon-circle.bs-icon-primary {
|
||||
background-color: #3d2936;
|
||||
}
|
||||
|
||||
.bs-icon-circle.bs-icon-primary svg {
|
||||
fill: #d25ea0 !important;
|
||||
}
|
||||
|
||||
/* Fix for service icons */
|
||||
.bs-icon-sm.bs-icon-circle.homemade svg,
|
||||
.bs-icon-sm.bs-icon-circle.upstream svg,
|
||||
.bs-icon-sm.bs-icon-circle.fork svg,
|
||||
.bs-icon-sm.bs-icon-circle.members-only svg {
|
||||
fill: #d25ea0 !important;
|
||||
}
|
||||
|
||||
.bs-icon-sm.bs-icon-circle.homemade,
|
||||
.bs-icon-sm.bs-icon-circle.upstream,
|
||||
.bs-icon-sm.bs-icon-circle.fork,
|
||||
.bs-icon-sm.bs-icon-circle.members-only {
|
||||
background-color: #3d2936 !important;
|
||||
border: 1px solid #d25ea0;
|
||||
}
|
||||
|
||||
/* Fix for icon in accordion headers */
|
||||
.accordion-header .bs-icon svg {
|
||||
fill: #d25ea0 !important;
|
||||
}
|
||||
|
||||
/* Background color overrides */
|
||||
.bg-light {
|
||||
background-color: #333333 !important;
|
||||
}
|
||||
|
||||
.bg-white {
|
||||
background-color: #2a2a2a !important;
|
||||
}
|
||||
|
||||
.bg-secondary-subtle {
|
||||
background-color: #3a3a3a !important;
|
||||
}
|
||||
|
||||
.bg-primary-subtle {
|
||||
background-color: #3d2936 !important;
|
||||
}
|
||||
|
||||
/* Theme toggle styles */
|
||||
.theme-toggle-container {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.theme-toggle-container .btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
padding: 0;
|
||||
border-radius: 50%;
|
||||
background-color: transparent;
|
||||
border: 2px solid #d25ea0; /* Toned down from #f570b9 */
|
||||
color: #d25ea0; /* Toned down from #f570b9 */
|
||||
}
|
||||
|
||||
.theme-toggle-container .btn:hover {
|
||||
background-color: #d25ea0; /* Toned down from #f570b9 */
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.theme-toggle-container .btn svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
/* Fix for any remaining white sections */
|
||||
section.bg-white {
|
||||
background-color: #2a2a2a !important;
|
||||
}
|
||||
|
||||
section.bg-light {
|
||||
background-color: #333333 !important;
|
||||
}
|
||||
|
||||
.container.bg-white {
|
||||
background-color: #2a2a2a !important;
|
||||
}
|
||||
|
||||
[class*="bg-white"] {
|
||||
background-color: #2a2a2a !important;
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
code {
|
||||
color: #d25ea0; /* Toned down from #f570b9 */
|
||||
background-color: #333333;
|
||||
padding: 0.2em 0.4em;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: #333333;
|
||||
color: #e0e0e0;
|
||||
border: 1px solid #444444;
|
||||
border-radius: 4px;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
/* Input fields */
|
||||
input, textarea, select {
|
||||
background-color: #3a3a3a !important;
|
||||
border-color: #444444 !important;
|
||||
color: #e0e0e0 !important;
|
||||
}
|
||||
|
||||
input::placeholder, textarea::placeholder {
|
||||
color: #888888 !important;
|
||||
}
|
||||
|
||||
/* Blockquotes */
|
||||
blockquote {
|
||||
border-left: 4px solid #3d2936;
|
||||
padding-left: 1em;
|
||||
color: #cccccc;
|
||||
}
|
||||
|
||||
/* Fix for inline styles that might set text to black */
|
||||
[style*="color: rgb(35, 35, 35)"] {
|
||||
color: #e0e0e0 !important;
|
||||
}
|
||||
|
||||
[style*="color: #232323"] {
|
||||
color: #e0e0e0 !important;
|
||||
}
|
||||
|
||||
/* Make sure the body background is consistently applied */
|
||||
body {
|
||||
background-color: #2a2a2a;
|
||||
}
|
||||
|
||||
/* Ensure header bar is lighter */
|
||||
#mainNav {
|
||||
background-color: #333333 !important;
|
||||
}
|
||||
|
||||
/* Legend section icons */
|
||||
.col .d-flex .bs-icon-md svg {
|
||||
fill: #d25ea0 !important; /* Toned down from #f570b9 */
|
||||
}
|
||||
|
||||
/* Fix for any SVG icons that might be hard to see */
|
||||
svg {
|
||||
fill: currentColor;
|
||||
}
|
1
assets/dist/icons/moon.svg
vendored
Normal file
1
assets/dist/icons/moon.svg
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="#000000" viewBox="0 0 256 256"><path d="M233.54,142.23a8,8,0,0,0-8-2,88.08,88.08,0,0,1-109.8-109.8,8,8,0,0,0-10-10,104.84,104.84,0,0,0-52.91,37A104,104,0,0,0,136,224a103.09,103.09,0,0,0,62.52-20.88,104.84,104.84,0,0,0,37-52.91A8,8,0,0,0,233.54,142.23ZM188.9,190.34A88,88,0,0,1,65.66,67.11a89,89,0,0,1,31.4-26A106,106,0,0,0,96,56,104.11,104.11,0,0,0,200,160a106,106,0,0,0,14.92-1.06A89,89,0,0,1,188.9,190.34Z"></path></svg>
|
After Width: | Height: | Size: 491 B |
1
assets/dist/icons/sun.svg
vendored
Normal file
1
assets/dist/icons/sun.svg
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="#000000" viewBox="0 0 256 256"><path d="M120,40V16a8,8,0,0,1,16,0V40a8,8,0,0,1-16,0Zm72,88a64,64,0,1,1-64-64A64.07,64.07,0,0,1,192,128Zm-16,0a48,48,0,1,0-48,48A48.05,48.05,0,0,0,176,128ZM58.34,69.66A8,8,0,0,0,69.66,58.34l-16-16A8,8,0,0,0,42.34,53.66Zm0,116.68-16,16a8,8,0,0,0,11.32,11.32l16-16a8,8,0,0,0-11.32-11.32ZM192,72a8,8,0,0,0,5.66-2.34l16-16a8,8,0,0,0-11.32-11.32l-16,16A8,8,0,0,0,192,72Zm5.66,114.34a8,8,0,0,0-11.32,11.32l16,16a8,8,0,0,0,11.32-11.32ZM48,128a8,8,0,0,0-8-8H16a8,8,0,0,0,0,16H40A8,8,0,0,0,48,128Zm80,80a8,8,0,0,0-8,8v24a8,8,0,0,0,16,0V216A8,8,0,0,0,128,208Zm112-88H216a8,8,0,0,0,0,16h24a8,8,0,0,0,0-16Z"></path></svg>
|
After Width: | Height: | Size: 709 B |
14
main.py
14
main.py
|
@ -67,10 +67,24 @@ env.filters["month_name"] = month_name
|
|||
|
||||
|
||||
def render_template_to_file(template_name, output_name, **kwargs):
|
||||
"""Render a template to a file.
|
||||
|
||||
Args:
|
||||
template_name (str): The name of the template file.
|
||||
output_name (str): The name of the output file.
|
||||
**kwargs: Additional keyword arguments to pass to the template.
|
||||
"""
|
||||
try:
|
||||
template = env.get_template(template_name)
|
||||
output_path = output_dir / output_name
|
||||
kwargs.setdefault("theme", "plain")
|
||||
|
||||
path = "/" + output_name
|
||||
if path.endswith("/index.html"):
|
||||
path = path[:-10]
|
||||
elif path == "/index.html":
|
||||
path = "/"
|
||||
kwargs.setdefault("request", {"path": path})
|
||||
|
||||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
|
|
@ -79,6 +79,17 @@
|
|||
<a class="nav-link" href="https://status.private.coffee/">Status</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="theme-toggle-container me-2">
|
||||
{% if theme == 'dark' %}
|
||||
<a href="https://private.coffee{{ request.path }}"
|
||||
class="btn btn-outline-primary"
|
||||
aria-label="Switch to light theme">{{ "sun" | icon | safe }}</a>
|
||||
{% else %}
|
||||
<a href="https://dark.private.coffee{{ request.path }}"
|
||||
class="btn btn-outline-primary"
|
||||
aria-label="Switch to dark theme">{{ "moon" | icon | safe }}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<a class="btn btn-primary shadow navbar-btn"
|
||||
role="button"
|
||||
href="/membership.html">JOIN & SUPPORT</a>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue