style: Phase 1 - Simple light dark themes (#1006)

## Summary

* **What is the goal of this PR?** (e.g., Implements the new feature for
file uploading.)

Implement automatic dark theme on server files.

Instead of a big change proposed in
https://github.com/crosspoint-reader/crosspoint-reader/pull/837, this PR
introduces a simple implementation of light/dark themes.

* **What changes are included?**

- Choose `#6e9a82` as accent color (taken from
![logo](https://avatars.githubusercontent.com/u/254441081?s=48&v=4))
- Implement a very basic media query for dark themes (`@media
(prefers-color-scheme: dark)`)
- Update style using CSS variables 

## Additional Context

* Add any other information that might be helpful for the reviewer
(e.g., performance implications, potential risks,
  specific areas to focus on).

We can think of it as a incremental enhancement, this is the first phase
of a series of PRs (hopefully).

Next steps/Phases:
1. Light/Dark themes (this PR)
2. Load external CSS file to avoid duplication
3. HTML enhancement (for example, use dialog element instead of divs)
4. Use SVG instead of emojis
5. Use Vite + Typescript to improve DX and have better minification

---

### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _**< YES | PARTIALLY | NO
>**_

---------

Co-authored-by: carlosbonadeo <carlosbonadeo@skyscanner.net>
This commit is contained in:
Carlos Bonadeo
2026-02-22 05:45:19 +00:00
committed by GitHub
parent 3696794591
commit 88537769f6
3 changed files with 146 additions and 81 deletions

View File

@@ -5,25 +5,47 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>CrossPoint Reader - Files</title> <title>CrossPoint Reader - Files</title>
<style> <style>
:root {
--font-color: #333;
--bg: #f5f5f5;
--title-color: #2c3e50;
--card-bg: #FFF;
--label-color: #7f8c8d;
--border-color: #eee;
--accent-color: rgb(110, 154, 130);
--accent-color-10: rgba(110, 154, 130, 0.1);
--accent-hover-color: #5a8c73;
}
@media (prefers-color-scheme: dark) {
:root {
--font-color: #f5f5f5;
--bg: #333;
--title-color: #ecf0f1;
--card-bg: #444;
--label-color: #bdc3c7;
--border-color: #555;
color-scheme: dark;
}
}
body { body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Oxygen, Ubuntu, sans-serif; Oxygen, Ubuntu, sans-serif;
max-width: 800px; max-width: 800px;
margin: 0 auto; margin: 0 auto;
padding: 20px; padding: 20px;
background-color: #f5f5f5; background-color: var(--bg);
color: #333; color: var(--font-color);
} }
h1 { h1 {
color: #2c3e50; color: var(--title-color);
margin-bottom: 5px; margin-bottom: 5px;
} }
h2 { h2 {
color: #34495e; color: var(--title-color);
margin-top: 0; margin-top: 0;
} }
.card { .card {
background: white; background: var(--card-bg);
border-radius: 8px; border-radius: 8px;
padding: 20px; padding: 20px;
margin: 15px 0; margin: 15px 0;
@@ -37,7 +59,7 @@
gap: 15px; gap: 15px;
margin-bottom: 20px; margin-bottom: 20px;
padding-bottom: 15px; padding-bottom: 15px;
border-bottom: 2px solid #3498db; border-bottom: 2px solid var(--accent-color);
} }
.page-header-left { .page-header-left {
display: flex; display: flex;
@@ -46,11 +68,11 @@
flex-wrap: wrap; flex-wrap: wrap;
} }
.breadcrumb-inline { .breadcrumb-inline {
color: #7f8c8d; color: var(--label-color);
font-size: 1.1em; font-size: 1.1em;
} }
.breadcrumb-inline a { .breadcrumb-inline a {
color: #3498db; color: var(--accent-color);
text-decoration: none; text-decoration: none;
} }
.breadcrumb-inline a:hover { .breadcrumb-inline a:hover {
@@ -58,26 +80,30 @@
} }
.breadcrumb-inline .sep { .breadcrumb-inline .sep {
margin: 0 6px; margin: 0 6px;
color: #bdc3c7; color: var(--border-color);
} }
.breadcrumb-inline .current { .breadcrumb-inline .current {
color: #2c3e50; color: var(--title-color);
font-weight: 500; font-weight: 500;
} }
.nav-links { .nav-links {
margin: 20px 0; margin: 20px 0;
display: flex;
gap: 10px;
} }
.nav-links a { .nav-links a {
display: inline-block;
padding: 10px 20px; padding: 10px 20px;
background-color: #3498db; color: var(--font-color);
color: white;
text-decoration: none; text-decoration: none;
border-radius: 4px; border-radius: 4px;
margin-right: 10px;
} }
.nav-links a:hover { .nav-links a.active {
background-color: #2980b9; background-color: var(--accent-color);
color: white;
}
.nav-links a:not(.active):hover {
background-color: var(--accent-hover-color);
color: white;
} }
/* Action buttons */ /* Action buttons */
.action-buttons { .action-buttons {
@@ -125,7 +151,7 @@
display: flex; display: flex;
} }
.modal { .modal {
background: white; background: var(--card-bg);
border-radius: 8px; border-radius: 8px;
padding: 25px; padding: 25px;
max-width: 450px; max-width: 450px;
@@ -134,7 +160,7 @@
} }
.modal h3 { .modal h3 {
margin: 0 0 15px 0; margin: 0 0 15px 0;
color: #2c3e50; color: var(--title-color);
} }
.modal-close { .modal-close {
float: right; float: right;
@@ -142,11 +168,11 @@
border: none; border: none;
font-size: 1.5em; font-size: 1.5em;
cursor: pointer; cursor: pointer;
color: #7f8c8d; color: var(--label-color);
line-height: 1; line-height: 1;
} }
.modal-close:hover { .modal-close:hover {
color: #2c3e50; color: var(--title-color);
} }
.file-table { .file-table {
width: 100%; width: 100%;
@@ -156,27 +182,14 @@
.file-table td { .file-table td {
padding: 12px; padding: 12px;
text-align: left; text-align: left;
border-bottom: 1px solid #eee; border-bottom: 1px solid var(--border-color);
} }
.file-table th { .file-table th {
background-color: #f8f9fa;
font-weight: 600; font-weight: 600;
color: #7f8c8d; color: var(--label-color);
} }
.file-table tr:hover { .file-table tr:hover {
background-color: #f8f9fa; background-color: var(--accent-color-10);
}
.epub-file {
background-color: #e8f6e9 !important;
}
.epub-file:hover {
background-color: #d4edda !important;
}
.folder-row {
background-color: #fff9e6 !important;
}
.folder-row:hover {
background-color: #fff3cd !important;
} }
.epub-badge { .epub-badge {
display: inline-block; display: inline-block;
@@ -200,12 +213,12 @@
margin-right: 8px; margin-right: 8px;
} }
.folder-link { .folder-link {
color: #2c3e50; color: var(--accent-color);
text-decoration: none; text-decoration: none;
cursor: pointer; cursor: pointer;
} }
.folder-link:hover { .folder-link:hover {
color: #3498db; color: var(--accent-hover-color);
text-decoration: underline; text-decoration: underline;
} }
.upload-form { .upload-form {
@@ -233,7 +246,7 @@
cursor: not-allowed; cursor: not-allowed;
} }
.file-info { .file-info {
color: #7f8c8d; color: var(--label-color);
font-size: 0.85em; font-size: 0.85em;
margin: 8px 0; margin: 8px 0;
} }
@@ -267,11 +280,11 @@
.contents-title { .contents-title {
font-size: 1.1em; font-size: 1.1em;
font-weight: 600; font-weight: 600;
color: #34495e; color: var(--title-color);
margin: 0; margin: 0;
} }
.summary-inline { .summary-inline {
color: #7f8c8d; color: var(--label-color);
font-size: 0.9em; font-size: 0.9em;
} }
#progress-container { #progress-container {
@@ -295,7 +308,7 @@
text-align: center; text-align: center;
margin-top: 5px; margin-top: 5px;
font-size: 0.9em; font-size: 0.9em;
color: #7f8c8d; color: var(--label-color);
} }
.folder-form { .folder-form {
margin-top: 10px; margin-top: 10px;
@@ -455,7 +468,7 @@
} }
.delete-item-name { .delete-item-name {
font-weight: 600; font-weight: 600;
color: #2c3e50; color: var(--title-color);
word-break: break-all; word-break: break-all;
} }
.delete-btn-confirm { .delete-btn-confirm {
@@ -483,7 +496,7 @@
margin-top: 10px; margin-top: 10px;
} }
.delete-btn-cancel:hover { .delete-btn-cancel:hover {
background-color: #7f8c8d; background-color: var(--label-color);
} }
.rename-btn-confirm { .rename-btn-confirm {
background-color: #3498db; background-color: #3498db;
@@ -627,7 +640,7 @@
<body> <body>
<div class="nav-links"> <div class="nav-links">
<a href="/">Home</a> <a href="/">Home</a>
<a href="/files">File Manager</a> <a href="/files" class="active">File Manager</a>
<a href="/settings">Settings</a> <a href="/settings">Settings</a>
</div> </div>

View File

@@ -5,26 +5,47 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>CrossPoint Reader</title> <title>CrossPoint Reader</title>
<style> <style>
:root {
--font-color: #333;
--bg: #f5f5f5;
--title-color: #2c3e50;
--card-bg: #FFF;
--label-color: #7f8c8d;
--border-color: #eee;
--accent-color: rgb(110, 154, 130);
--accent-hover-color: #5a8c73;
}
@media (prefers-color-scheme: dark) {
:root {
--font-color: #f5f5f5;
--bg: #333;
--title-color: #ecf0f1;
--card-bg: #444;
--label-color: #bdc3c7;
--border-color: #555;
color-scheme: dark;
}
}
body { body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Oxygen, Ubuntu, sans-serif; Oxygen, Ubuntu, sans-serif;
max-width: 800px; max-width: 800px;
margin: 0 auto; margin: 0 auto;
padding: 20px; padding: 20px;
background-color: #f5f5f5; background-color: var(--bg);
color: #333; color: var(--font-color);
} }
h1 { h1 {
color: #2c3e50; color: var(--title-color);
border-bottom: 2px solid #3498db; border-bottom: 2px solid var(--accent-color);
padding-bottom: 10px; padding-bottom: 10px;
} }
h2 { h2 {
color: #34495e; color: var(--title-color);
margin-top: 0; margin-top: 0;
} }
.card { .card {
background: white; background: var(--card-bg);
border-radius: 8px; border-radius: 8px;
padding: 20px; padding: 20px;
margin: 15px 0; margin: 15px 0;
@@ -33,18 +54,19 @@
.info-row { .info-row {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center;
padding: 8px 0; padding: 8px 0;
border-bottom: 1px solid #eee; border-bottom: 1px solid var(--border-color);
} }
.info-row:last-child { .info-row:last-child {
border-bottom: none; border-bottom: none;
} }
.label { .label {
font-weight: 600; font-weight: 600;
color: #7f8c8d; color: var(--label-color);
} }
.value { .value {
color: #2c3e50; color: var(--title-color);
} }
.status { .status {
display: inline-block; display: inline-block;
@@ -56,18 +78,22 @@
} }
.nav-links { .nav-links {
margin: 20px 0; margin: 20px 0;
display: flex;
gap: 10px;
} }
.nav-links a { .nav-links a {
display: inline-block;
padding: 10px 20px; padding: 10px 20px;
background-color: #3498db; color: var(--font-color);
color: white;
text-decoration: none; text-decoration: none;
border-radius: 4px; border-radius: 4px;
margin-right: 10px;
} }
.nav-links a:hover { .nav-links a.active {
background-color: #2980b9; background-color: var(--accent-color);
color: white;
}
.nav-links a:not(.active):hover {
background-color: var(--accent-hover-color);
color: white;
} }
</style> </style>
</head> </head>
@@ -75,7 +101,7 @@
<h1>📚 CrossPoint Reader</h1> <h1>📚 CrossPoint Reader</h1>
<div class="nav-links"> <div class="nav-links">
<a href="/">Home</a> <a href="/" class="active">Home</a>
<a href="/files">File Manager</a> <a href="/files">File Manager</a>
<a href="/settings">Settings</a> <a href="/settings">Settings</a>
</div> </div>

View File

@@ -5,26 +5,49 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>CrossPoint Reader - Settings</title> <title>CrossPoint Reader - Settings</title>
<style> <style>
:root {
--font-color: #333;
--bg: #f5f5f5;
--title-color: #2c3e50;
--card-bg: #FFF;
--label-color: #7f8c8d;
--border-color: #eee;
--accent-color: rgb(110, 154, 130);
--accent-hover-color: #5a8c73;
--toggle-bg: #ccc;
}
@media (prefers-color-scheme: dark) {
:root {
--font-color: #f5f5f5;
--bg: #333;
--title-color: #ecf0f1;
--card-bg: #444;
--label-color: #bdc3c7;
--border-color: #555;
--toggle-bg: #666;
color-scheme: dark;
}
}
body { body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Oxygen, Ubuntu, sans-serif; Oxygen, Ubuntu, sans-serif;
max-width: 800px; max-width: 800px;
margin: 0 auto; margin: 0 auto;
padding: 20px; padding: 20px;
background-color: #f5f5f5; background-color: var(--bg);
color: #333; color: var(--font-color);
} }
h1 { h1 {
color: #2c3e50; color: var(--title-color);
border-bottom: 2px solid #3498db; border-bottom: 2px solid var(--accent-color);
padding-bottom: 10px; padding-bottom: 10px;
} }
h2 { h2 {
color: #34495e; color: var(--title-color);
margin-top: 0; margin-top: 0;
} }
.card { .card {
background: white; background: var(--card-bg);
border-radius: 8px; border-radius: 8px;
padding: 20px; padding: 20px;
margin: 15px 0; margin: 15px 0;
@@ -32,32 +55,36 @@
} }
.nav-links { .nav-links {
margin: 20px 0; margin: 20px 0;
display: flex;
gap: 10px;
} }
.nav-links a { .nav-links a {
display: inline-block;
padding: 10px 20px; padding: 10px 20px;
background-color: #3498db; color: var(--font-color);
color: white;
text-decoration: none; text-decoration: none;
border-radius: 4px; border-radius: 4px;
margin-right: 10px;
} }
.nav-links a:hover { .nav-links a.active {
background-color: #2980b9; background-color: var(--accent-color);
color: white;
}
.nav-links a:not(.active):hover {
background-color: var(--accent-hover-color);
color: white;
} }
.setting-row { .setting-row {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: 10px 0; padding: 10px 0;
border-bottom: 1px solid #eee; border-bottom: 1px solid var(--border-color);
} }
.setting-row:last-child { .setting-row:last-child {
border-bottom: none; border-bottom: none;
} }
.setting-name { .setting-name {
font-weight: 500; font-weight: 500;
color: #2c3e50; color: var(--label-color);
flex: 1; flex: 1;
min-width: 0; min-width: 0;
padding-right: 12px; padding-right: 12px;
@@ -73,7 +100,7 @@
border: 1px solid #ddd; border: 1px solid #ddd;
border-radius: 4px; border-radius: 4px;
font-size: 0.95em; font-size: 0.95em;
background: white; background: var(--card-bg);
} }
.setting-control select { .setting-control select {
min-width: 160px; min-width: 160px;
@@ -101,7 +128,7 @@
position: absolute; position: absolute;
cursor: pointer; cursor: pointer;
top: 0; left: 0; right: 0; bottom: 0; top: 0; left: 0; right: 0; bottom: 0;
background-color: #ccc; background-color: var(--toggle-bg);
border-radius: 26px; border-radius: 26px;
transition: 0.3s; transition: 0.3s;
} }
@@ -117,7 +144,7 @@
transition: 0.3s; transition: 0.3s;
} }
.toggle-switch input:checked + .toggle-slider { .toggle-switch input:checked + .toggle-slider {
background-color: #27ae60; background-color: var(--accent-color);
} }
.toggle-switch input:checked + .toggle-slider:before { .toggle-switch input:checked + .toggle-slider:before {
transform: translateX(22px); transform: translateX(22px);
@@ -194,7 +221,6 @@
} }
.nav-links a { .nav-links a {
padding: 8px 12px; padding: 8px 12px;
margin-right: 6px;
font-size: 0.9em; font-size: 0.9em;
} }
.setting-row { .setting-row {
@@ -205,7 +231,7 @@
.setting-control input[type="text"], .setting-control input[type="text"],
.setting-control input[type="password"] { .setting-control input[type="password"] {
min-width: 0; min-width: 0;
width: 100%; width: unset;
} }
} }
</style> </style>
@@ -216,7 +242,7 @@
<div class="nav-links"> <div class="nav-links">
<a href="/">Home</a> <a href="/">Home</a>
<a href="/files">File Manager</a> <a href="/files">File Manager</a>
<a href="/settings">Settings</a> <a href="/settings" class="active">Settings</a>
</div> </div>
<div id="message" class="message"></div> <div id="message" class="message"></div>