Merge pull request #7 from derekslenk/feature/css-optimization
CSS Optimization
This commit is contained in:
commit
f4e5a4b37c
12 changed files with 85 additions and 103 deletions
|
@ -21,7 +21,7 @@ A community-driven web application for tracking winter road conditions and icy h
|
||||||
|
|
||||||
1. **Clone the repository:**
|
1. **Clone the repository:**
|
||||||
```bash
|
```bash
|
||||||
git clone git@github.com:deco/ice.git
|
git clone git@git.deco.sh:deco/ice.git
|
||||||
cd ice
|
cd ice
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ PORT=3000
|
||||||
|
|
||||||
2. **Deploy your application:**
|
2. **Deploy your application:**
|
||||||
```bash
|
```bash
|
||||||
git clone git@github.com:deco/ice.git /opt/ice
|
git clone git@git.deco.sh:deco/ice.git /opt/ice
|
||||||
cd /opt/ice
|
cd /opt/ice
|
||||||
npm install # This automatically builds CSS via postinstall
|
npm install # This automatically builds CSS via postinstall
|
||||||
```
|
```
|
||||||
|
@ -149,7 +149,7 @@ MIT License - see LICENSE file for details
|
||||||
## Support
|
## Support
|
||||||
|
|
||||||
This is a community safety tool. For issues or questions:
|
This is a community safety tool. For issues or questions:
|
||||||
- Create a GitHub issue
|
- Create an issue on our git repository
|
||||||
- Check existing documentation
|
- Check existing documentation
|
||||||
- Review security guidelines
|
- Review security guidelines
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,18 @@
|
||||||
<link rel="icon" type="image/svg+xml" href="https://iceymi.b-cdn.net/favicon.svg">
|
<link rel="icon" type="image/svg+xml" href="https://iceymi.b-cdn.net/favicon.svg">
|
||||||
<link rel="icon" type="image/x-icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiIgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIj4KICA8ZGVmcz4KICAgIDxzdHlsZT4KICAgICAgLnNub3dmbGFrZSB7IGZpbGw6ICMyMTk2RjM7IH0KICAgICAgLmNlbnRlciB7IGZpbGw6ICMxOTc2RDI7IH0KICAgIDwvc3R5bGU+CiAgPC9kZWZzPgogIAogIDxnIGNsYXNzPSJzbm93Zmxha2UiPgogICAgPHJlY3QgeD0iMTUiIHk9IjIiIHdpZHRoPSIyIiBoZWlnaHQ9IjI4IiAvPgogICAgPHJlY3QgeD0iMiIgeT0iMTUiIHdpZHRoPSIyOCIgaGVpZ2h0PSIyIiAvPgogICAgPHJlY3QgeD0iMTUiIHk9IjIiIHdpZHRoPSIyIiBoZWlnaHQ9IjI4IiB0cmFuc2Zvcm09InJvdGF0ZSg0NSAxNiAxNikiIC8+CiAgICA8cmVjdCB4PSIxNSIgeT0iMiIgd2lkdGg9IjIiIGhlaWdodD0iMjgiIHRyYW5zZm9ybT0icm90YXRlKC00NSAxNiAxNikiIC8+CiAgICA8cG9seWdvbiBwb2ludHM9IjE2LDIgMTQsNiAxOCw2IiAvPgogICAgPHBvbHlnb24gcG9pbnRzPSIxNiwzMCAxNCwyNiAxOCwyNiIgLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMiwxNiA2LDE0IDYsMTgiIC8+CiAgICA8cG9seWdvbiBwb2ludHM9IjMwLDE2IDI2LDE0IDI2LDE4IiAvPgogICAgPHBvbHlnb24gcG9pbnRzPSI2LjMsNi4zIDguNiw0IDkuOSw3LjciIHRyYW5zZm9ybT0icm90YXRlKDQ1IDE2IDE2KSIgLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMjUuNywyNS43IDIzLjQsMjggMjIuMSwyNC4zIiB0cmFuc2Zvcm09InJvdGF0ZSg0NSAxNiAxNikiIC8+CiAgICA8cG9seWdvbiBwb2ludHM9IjYuMywyNS43IDguNiwyOCA5LjksMjQuMyIgdHJhbnNmb3JtPSJyb3RhdGUoLTQ1IDE2IDE2KSIgLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMjUuNyw2LjMgMjMuNCw0IDIyLjEsNy43IiB0cmFuc2Zvcm09InJvdGF0ZSgtNDUgMTYgMTYpIiAvPgogIDwvZz4KICA8Y2lyY2xlIGN4PSIxNiIgY3k9IjE2IiByPSIzIiBjbGFzcz0iY2VudGVyIiAvPgo8L3N2Zz4K">
|
<link rel="icon" type="image/x-icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiIgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIj4KICA8ZGVmcz4KICAgIDxzdHlsZT4KICAgICAgLnNub3dmbGFrZSB7IGZpbGw6ICMyMTk2RjM7IH0KICAgICAgLmNlbnRlciB7IGZpbGw6ICMxOTc2RDI7IH0KICAgIDwvc3R5bGU+CiAgPC9kZWZzPgogIAogIDxnIGNsYXNzPSJzbm93Zmxha2UiPgogICAgPHJlY3QgeD0iMTUiIHk9IjIiIHdpZHRoPSIyIiBoZWlnaHQ9IjI4IiAvPgogICAgPHJlY3QgeD0iMiIgeT0iMTUiIHdpZHRoPSIyOCIgaGVpZ2h0PSIyIiAvPgogICAgPHJlY3QgeD0iMTUiIHk9IjIiIHdpZHRoPSIyIiBoZWlnaHQ9IjI4IiB0cmFuc2Zvcm09InJvdGF0ZSg0NSAxNiAxNikiIC8+CiAgICA8cmVjdCB4PSIxNSIgeT0iMiIgd2lkdGg9IjIiIGhlaWdodD0iMjgiIHRyYW5zZm9ybT0icm90YXRlKC00NSAxNiAxNikiIC8+CiAgICA8cG9seWdvbiBwb2ludHM9IjE2LDIgMTQsNiAxOCw2IiAvPgogICAgPHBvbHlnb24gcG9pbnRzPSIxNiwzMCAxNCwyNiAxOCwyNiIgLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMiwxNiA2LDE0IDYsMTgiIC8+CiAgICA8cG9seWdvbiBwb2ludHM9IjMwLDE2IDI2LDE0IDI2LDE4IiAvPgogICAgPHBvbHlnb24gcG9pbnRzPSI2LjMsNi4zIDguNiw0IDkuOSw3LjciIHRyYW5zZm9ybT0icm90YXRlKDQ1IDE2IDE2KSIgLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMjUuNywyNS43IDIzLjQsMjggMjIuMSwyNC4zIiB0cmFuc2Zvcm09InJvdGF0ZSg0NSAxNiAxNikiIC8+CiAgICA8cG9seWdvbiBwb2ludHM9IjYuMywyNS43IDguNiwyOCA5LjksMjQuMyIgdHJhbnNmb3JtPSJyb3RhdGUoLTQ1IDE2IDE2KSIgLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMjUuNyw2LjMgMjMuNCw0IDIyLjEsNy43IiB0cmFuc2Zvcm09InJvdGF0ZSgtNDUgMTYgMTYpIiAvPgogIDwvZz4KICA8Y2lyY2xlIGN4PSIxNiIgY3k9IjE2IiByPSIzIiBjbGFzcz0iY2VudGVyIiAvPgo8L3N2Zz4K">
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
|
<script>
|
||||||
|
// Apply theme immediately to prevent flash
|
||||||
|
(function() {
|
||||||
|
const savedTheme = localStorage.getItem('theme') || 'auto';
|
||||||
|
if (savedTheme === 'auto') {
|
||||||
|
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||||
|
document.documentElement.setAttribute('data-theme', prefersDark ? 'dark' : 'light');
|
||||||
|
} else {
|
||||||
|
document.documentElement.setAttribute('data-theme', savedTheme);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="admin-container">
|
<div class="admin-container">
|
||||||
|
@ -155,6 +167,8 @@
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
<!-- Load shared theme utility -->
|
||||||
|
<script src="theme-utils.js"></script>
|
||||||
<script src="utils.js"></script>
|
<script src="utils.js"></script>
|
||||||
<script src="admin.js"></script>
|
<script src="admin.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -705,7 +705,13 @@ function initializeTheme() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyTheme(theme) {
|
function applyTheme(theme) {
|
||||||
document.documentElement.setAttribute('data-theme', theme);
|
if (theme === 'auto') {
|
||||||
|
// Detect system preference and apply appropriate theme
|
||||||
|
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||||
|
document.documentElement.setAttribute('data-theme', prefersDark ? 'dark' : 'light');
|
||||||
|
} else {
|
||||||
|
document.documentElement.setAttribute('data-theme', theme);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateThemeIcon(theme, iconElement) {
|
function updateThemeIcon(theme, iconElement) {
|
||||||
|
|
|
@ -617,7 +617,13 @@ function initializeTheme() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyTheme(theme) {
|
function applyTheme(theme) {
|
||||||
document.documentElement.setAttribute('data-theme', theme);
|
if (theme === 'auto') {
|
||||||
|
// Detect system preference and apply appropriate theme
|
||||||
|
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||||
|
document.documentElement.setAttribute('data-theme', prefersDark ? 'dark' : 'light');
|
||||||
|
} else {
|
||||||
|
document.documentElement.setAttribute('data-theme', theme);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateThemeIcon(theme, iconElement) {
|
function updateThemeIcon(theme, iconElement) {
|
||||||
|
|
|
@ -8,6 +8,18 @@
|
||||||
<link rel="icon" type="image/x-icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiIgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIj4KICA8ZGVmcz4KICAgIDxzdHlsZT4KICAgICAgLnNub3dmbGFrZSB7IGZpbGw6ICMyMTk2RjM7IH0KICAgICAgLmNlbnRlciB7IGZpbGw6ICMxOTc2RDI7IH0KICAgIDwvc3R5bGU+CiAgPC9kZWZzPgogIAogIDxnIGNsYXNzPSJzbm93Zmxha2UiPgogICAgPHJlY3QgeD0iMTUiIHk9IjIiIHdpZHRoPSIyIiBoZWlnaHQ9IjI4IiAvPgogICAgPHJlY3QgeD0iMiIgeT0iMTUiIHdpZHRoPSIyOCIgaGVpZ2h0PSIyIiAvPgogICAgPHJlY3QgeD0iMTUiIHk9IjIiIHdpZHRoPSIyIiBoZWlnaHQ9IjI4IiB0cmFuc2Zvcm09InJvdGF0ZSg0NSAxNiAxNikiIC8+CiAgICA8cmVjdCB4PSIxNSIgeT0iMiIgd2lkdGg9IjIiIGhlaWdodD0iMjgiIHRyYW5zZm9ybT0icm90YXRlKC00NSAxNiAxNikiIC8+CiAgICA8cG9seWdvbiBwb2ludHM9IjE2LDIgMTQsNiAxOCw2IiAvPgogICAgPHBvbHlnb24gcG9pbnRzPSIxNiwzMCAxNCwyNiAxOCwyNiIgLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMiwxNiA2LDE0IDYsMTgiIC8+CiAgICA8cG9seWdvbiBwb2ludHM9IjMwLDE2IDI2LDE0IDI2LDE4IiAvPgogICAgPHBvbHlnb24gcG9pbnRzPSI2LjMsNi4zIDguNiw0IDkuOSw3LjciIHRyYW5zZm9ybT0icm90YXRlKDQ1IDE2IDE2KSIgLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMjUuNywyNS43IDIzLjQsMjggMjIuMSwyNC4zIiB0cmFuc2Zvcm09InJvdGF0ZSg0NSAxNiAxNikiIC8+CiAgICA8cG9seWdvbiBwb2ludHM9IjYuMywyNS43IDguNiwyOCA5LjksMjQuMyIgdHJhbnNmb3JtPSJyb3RhdGUoLTQ1IDE2IDE2KSIgLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMjUuNyw2LjMgMjMuNCw0IDIyLjEsNy43IiB0cmFuc2Zvcm09InJvdGF0ZSgtNDUgMTYgMTYpIiAvPgogIDwvZz4KICA8Y2lyY2xlIGN4PSIxNiIgY3k9IjE2IiByPSIzIiBjbGFzcz0iY2VudGVyIiAvPgo8L3N2Zz4K">
|
<link rel="icon" type="image/x-icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiIgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIj4KICA8ZGVmcz4KICAgIDxzdHlsZT4KICAgICAgLnNub3dmbGFrZSB7IGZpbGw6ICMyMTk2RjM7IH0KICAgICAgLmNlbnRlciB7IGZpbGw6ICMxOTc2RDI7IH0KICAgIDwvc3R5bGU+CiAgPC9kZWZzPgogIAogIDxnIGNsYXNzPSJzbm93Zmxha2UiPgogICAgPHJlY3QgeD0iMTUiIHk9IjIiIHdpZHRoPSIyIiBoZWlnaHQ9IjI4IiAvPgogICAgPHJlY3QgeD0iMiIgeT0iMTUiIHdpZHRoPSIyOCIgaGVpZ2h0PSIyIiAvPgogICAgPHJlY3QgeD0iMTUiIHk9IjIiIHdpZHRoPSIyIiBoZWlnaHQ9IjI4IiB0cmFuc2Zvcm09InJvdGF0ZSg0NSAxNiAxNikiIC8+CiAgICA8cmVjdCB4PSIxNSIgeT0iMiIgd2lkdGg9IjIiIGhlaWdodD0iMjgiIHRyYW5zZm9ybT0icm90YXRlKC00NSAxNiAxNikiIC8+CiAgICA8cG9seWdvbiBwb2ludHM9IjE2LDIgMTQsNiAxOCw2IiAvPgogICAgPHBvbHlnb24gcG9pbnRzPSIxNiwzMCAxNCwyNiAxOCwyNiIgLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMiwxNiA2LDE0IDYsMTgiIC8+CiAgICA8cG9seWdvbiBwb2ludHM9IjMwLDE2IDI2LDE0IDI2LDE4IiAvPgogICAgPHBvbHlnb24gcG9pbnRzPSI2LjMsNi4zIDguNiw0IDkuOSw3LjciIHRyYW5zZm9ybT0icm90YXRlKDQ1IDE2IDE2KSIgLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMjUuNywyNS43IDIzLjQsMjggMjIuMSwyNC4zIiB0cmFuc2Zvcm09InJvdGF0ZSg0NSAxNiAxNikiIC8+CiAgICA8cG9seWdvbiBwb2ludHM9IjYuMywyNS43IDguNiwyOCA5LjksMjQuMyIgdHJhbnNmb3JtPSJyb3RhdGUoLTQ1IDE2IDE2KSIgLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMjUuNyw2LjMgMjMuNCw0IDIyLjEsNy43IiB0cmFuc2Zvcm09InJvdGF0ZSgtNDUgMTYgMTYpIiAvPgogIDwvZz4KICA8Y2lyY2xlIGN4PSIxNiIgY3k9IjE2IiByPSIzIiBjbGFzcz0iY2VudGVyIiAvPgo8L3N2Zz4K">
|
||||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
|
<script>
|
||||||
|
// Apply theme immediately to prevent flash
|
||||||
|
(function() {
|
||||||
|
const savedTheme = localStorage.getItem('theme') || 'auto';
|
||||||
|
if (savedTheme === 'auto') {
|
||||||
|
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||||
|
document.documentElement.setAttribute('data-theme', prefersDark ? 'dark' : 'light');
|
||||||
|
} else {
|
||||||
|
document.documentElement.setAttribute('data-theme', savedTheme);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
@ -109,6 +121,8 @@ placeholder="Enter address, intersection (e.g., Main St & Second St, City), or l
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
||||||
|
<!-- Load shared theme utility -->
|
||||||
|
<script src="theme-utils.js"></script>
|
||||||
<script src="utils.js"></script>
|
<script src="utils.js"></script>
|
||||||
<script src="app-mapbox.js"></script>
|
<script src="app-mapbox.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -7,6 +7,18 @@
|
||||||
<link rel="icon" type="image/svg+xml" href="https://iceymi.b-cdn.net/favicon.svg">
|
<link rel="icon" type="image/svg+xml" href="https://iceymi.b-cdn.net/favicon.svg">
|
||||||
<link rel="icon" type="image/x-icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiIgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIj4KICA8ZGVmcz4KICAgIDxzdHlsZT4KICAgICAgLnNub3dmbGFrZSB7IGZpbGw6ICMyMTk2RjM7IH0KICAgICAgLmNlbnRlciB7IGZpbGw6ICMxOTc2RDI7IH0KICAgIDwvc3R5bGU+CiAgPC9kZWZzPgogIAogIDxnIGNsYXNzPSJzbm93Zmxha2UiPgogICAgPHJlY3QgeD0iMTUiIHk9IjIiIHdpZHRoPSIyIiBoZWlnaHQ9IjI4IiAvPgogICAgPHJlY3QgeD0iMiIgeT0iMTUiIHdpZHRoPSIyOCIgaGVpZ2h0PSIyIiAvPgogICAgPHJlY3QgeD0iMTUiIHk9IjIiIHdpZHRoPSIyIiBoZWlnaHQ9IjI4IiB0cmFuc2Zvcm09InJvdGF0ZSg0NSAxNiAxNikiIC8+CiAgICA8cmVjdCB4PSIxNSIgeT0iMiIgd2lkdGg9IjIiIGhlaWdodD0iMjgiIHRyYW5zZm9ybT0icm90YXRlKC00NSAxNiAxNikiIC8+CiAgICA8cG9seWdvbiBwb2ludHM9IjE2LDIgMTQsNiAxOCw2IiAvPgogICAgPHBvbHlnb24gcG9pbnRzPSIxNiwzMCAxNCwyNiAxOCwyNiIgLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMiwxNiA2LDE0IDYsMTgiIC8+CiAgICA8cG9seWdvbiBwb2ludHM9IjMwLDE2IDI2LDE0IDI2LDE4IiAvPgogICAgPHBvbHlnb24gcG9pbnRzPSI2LjMsNi4zIDguNiw0IDkuOSw3LjciIHRyYW5zZm9ybT0icm90YXRlKDQ1IDE2IDE2KSIgLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMjUuNywyNS43IDIzLjQsMjggMjIuMSwyNC4zIiB0cmFuc2Zvcm09InJvdGF0ZSg0NSAxNiAxNikiIC8+CiAgICA8cG9seWdvbiBwb2ludHM9IjYuMywyNS43IDguNiwyOCA5LjksMjQuMyIgdHJhbnNmb3JtPSJyb3RhdGUoLTQ1IDE2IDE2KSIgLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMjUuNyw2LjMgMjMuNCw0IDIyLjEsNy43IiB0cmFuc2Zvcm09InJvdGF0ZSgtNDUgMTYgMTYpIiAvPgogIDwvZz4KICA8Y2lyY2xlIGN4PSIxNiIgY3k9IjE2IiByPSIzIiBjbGFzcz0iY2VudGVyIiAvPgo8L3N2Zz4K">
|
<link rel="icon" type="image/x-icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiIgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIj4KICA8ZGVmcz4KICAgIDxzdHlsZT4KICAgICAgLnNub3dmbGFrZSB7IGZpbGw6ICMyMTk2RjM7IH0KICAgICAgLmNlbnRlciB7IGZpbGw6ICMxOTc2RDI7IH0KICAgIDwvc3R5bGU+CiAgPC9kZWZzPgogIAogIDxnIGNsYXNzPSJzbm93Zmxha2UiPgogICAgPHJlY3QgeD0iMTUiIHk9IjIiIHdpZHRoPSIyIiBoZWlnaHQ9IjI4IiAvPgogICAgPHJlY3QgeD0iMiIgeT0iMTUiIHdpZHRoPSIyOCIgaGVpZ2h0PSIyIiAvPgogICAgPHJlY3QgeD0iMTUiIHk9IjIiIHdpZHRoPSIyIiBoZWlnaHQ9IjI4IiB0cmFuc2Zvcm09InJvdGF0ZSg0NSAxNiAxNikiIC8+CiAgICA8cmVjdCB4PSIxNSIgeT0iMiIgd2lkdGg9IjIiIGhlaWdodD0iMjgiIHRyYW5zZm9ybT0icm90YXRlKC00NSAxNiAxNikiIC8+CiAgICA8cG9seWdvbiBwb2ludHM9IjE2LDIgMTQsNiAxOCw2IiAvPgogICAgPHBvbHlnb24gcG9pbnRzPSIxNiwzMCAxNCwyNiAxOCwyNiIgLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMiwxNiA2LDE0IDYsMTgiIC8+CiAgICA8cG9seWdvbiBwb2ludHM9IjMwLDE2IDI2LDE0IDI2LDE4IiAvPgogICAgPHBvbHlnb24gcG9pbnRzPSI2LjMsNi4zIDguNiw0IDkuOSw3LjciIHRyYW5zZm9ybT0icm90YXRlKDQ1IDE2IDE2KSIgLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMjUuNywyNS43IDIzLjQsMjggMjIuMSwyNC4zIiB0cmFuc2Zvcm09InJvdGF0ZSg0NSAxNiAxNikiIC8+CiAgICA8cG9seWdvbiBwb2ludHM9IjYuMywyNS43IDguNiwyOCA5LjksMjQuMyIgdHJhbnNmb3JtPSJyb3RhdGUoLTQ1IDE2IDE2KSIgLz4KICAgIDxwb2x5Z29uIHBvaW50cz0iMjUuNyw2LjMgMjMuNCw0IDIyLjEsNy43IiB0cmFuc2Zvcm09InJvdGF0ZSgtNDUgMTYgMTYpIiAvPgogIDwvZz4KICA8Y2lyY2xlIGN4PSIxNiIgY3k9IjE2IiByPSIzIiBjbGFzcz0iY2VudGVyIiAvPgo8L3N2Zz4K">
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
|
<script>
|
||||||
|
// Apply theme immediately to prevent flash
|
||||||
|
(function() {
|
||||||
|
const savedTheme = localStorage.getItem('theme') || 'auto';
|
||||||
|
if (savedTheme === 'auto') {
|
||||||
|
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||||
|
document.documentElement.setAttribute('data-theme', prefersDark ? 'dark' : 'light');
|
||||||
|
} else {
|
||||||
|
document.documentElement.setAttribute('data-theme', savedTheme);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="privacy-container">
|
<div class="privacy-container">
|
||||||
|
@ -92,8 +104,8 @@
|
||||||
<h2>Contact Information</h2>
|
<h2>Contact Information</h2>
|
||||||
<p>Questions about this privacy policy or your data?</p>
|
<p>Questions about this privacy policy or your data?</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Create an issue on our <a href="https://github.com/deco/great-lakes-ice-report" target="_blank">GitHub repository</a></li>
|
<li>Create an issue on our <a href="https://git.deco.sh/deco/ice" target="_blank" rel="noopener noreferrer">git repository</a></li>
|
||||||
<li>Review our <a href="https://www.aclu.org/know-your-rights/immigrants-rights" target="_blank">recommended rights resources</a></li>
|
<li>Review our <a href="https://www.aclu.org/know-your-rights/immigrants-rights" target="_blank" rel="noopener noreferrer">recommended rights resources</a></li>
|
||||||
<li>This is a community tool - please use responsibly</li>
|
<li>This is a community tool - please use responsibly</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -110,78 +122,9 @@
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
<!-- Load shared theme utility -->
|
||||||
|
<script src="theme-utils.js"></script>
|
||||||
<script>
|
<script>
|
||||||
// Theme toggle functionality (shared with main page)
|
|
||||||
function initializeTheme() {
|
|
||||||
const themeToggle = document.getElementById('theme-toggle');
|
|
||||||
const themeIcon = document.querySelector('.theme-icon');
|
|
||||||
|
|
||||||
if (!themeToggle || !themeIcon) {
|
|
||||||
console.warn('Theme toggle elements not found');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for saved theme preference or default to auto (follows system)
|
|
||||||
const savedTheme = localStorage.getItem('theme') || 'auto';
|
|
||||||
applyTheme(savedTheme);
|
|
||||||
|
|
||||||
// Update icon based on current theme
|
|
||||||
updateThemeIcon(savedTheme, themeIcon);
|
|
||||||
|
|
||||||
// Add click listener for cycling through themes
|
|
||||||
themeToggle.addEventListener('click', () => {
|
|
||||||
const currentTheme = localStorage.getItem('theme') || 'auto';
|
|
||||||
let newTheme;
|
|
||||||
|
|
||||||
// Cycle: auto → light → dark → auto
|
|
||||||
switch(currentTheme) {
|
|
||||||
case 'auto':
|
|
||||||
newTheme = 'light';
|
|
||||||
break;
|
|
||||||
case 'light':
|
|
||||||
newTheme = 'dark';
|
|
||||||
break;
|
|
||||||
case 'dark':
|
|
||||||
newTheme = 'auto';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
newTheme = 'auto';
|
|
||||||
}
|
|
||||||
|
|
||||||
localStorage.setItem('theme', newTheme);
|
|
||||||
applyTheme(newTheme);
|
|
||||||
updateThemeIcon(newTheme, themeIcon);
|
|
||||||
|
|
||||||
console.log(`Theme switched to: ${newTheme}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Listen for system theme changes when in auto mode
|
|
||||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
|
|
||||||
const currentTheme = localStorage.getItem('theme') || 'auto';
|
|
||||||
if (currentTheme === 'auto') {
|
|
||||||
applyTheme('auto');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function applyTheme(theme) {
|
|
||||||
document.documentElement.setAttribute('data-theme', theme);
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateThemeIcon(theme, iconElement) {
|
|
||||||
switch(theme) {
|
|
||||||
case 'auto':
|
|
||||||
iconElement.textContent = '🌍'; // Globe (auto)
|
|
||||||
break;
|
|
||||||
case 'light':
|
|
||||||
iconElement.textContent = '☀️'; // Sun (light)
|
|
||||||
break;
|
|
||||||
case 'dark':
|
|
||||||
iconElement.textContent = '🌙'; // Moon (dark)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize theme when page loads
|
// Initialize theme when page loads
|
||||||
document.addEventListener('DOMContentLoaded', initializeTheme);
|
document.addEventListener('DOMContentLoaded', initializeTheme);
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -104,7 +104,7 @@ echo ""
|
||||||
echo "🚀 Next steps to deploy Great Lakes Ice Report:"
|
echo "🚀 Next steps to deploy Great Lakes Ice Report:"
|
||||||
echo ""
|
echo ""
|
||||||
echo "1. Clone your repository:"
|
echo "1. Clone your repository:"
|
||||||
echo " git clone git@github.com:deco/great-lakes-ice-report.git /opt/great-lakes-ice-report"
|
echo " git clone git@git.deco.sh:deco/ice.git /opt/great-lakes-ice-report"
|
||||||
echo ""
|
echo ""
|
||||||
echo "2. Set up the application:"
|
echo "2. Set up the application:"
|
||||||
echo " cd /opt/great-lakes-ice-report"
|
echo " cd /opt/great-lakes-ice-report"
|
||||||
|
|
|
@ -135,17 +135,7 @@ button {
|
||||||
|
|
||||||
// Theme toggle styles (common across pages)
|
// Theme toggle styles (common across pages)
|
||||||
.theme-toggle {
|
.theme-toggle {
|
||||||
@include button($bg-color: transparent);
|
@include theme-toggle-styles;
|
||||||
border: 2px solid var(--border-color);
|
|
||||||
border-radius: $border-radius-full;
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
@include flex-center;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: var(--table-hover);
|
|
||||||
transform: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Utility classes
|
// Utility classes
|
||||||
|
|
|
@ -122,6 +122,23 @@
|
||||||
color: $text-color;
|
color: $text-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Theme Toggle Mixin (consolidates duplicated theme toggle styles)
|
||||||
|
@mixin theme-toggle-styles($width: 40px, $height: 40px) {
|
||||||
|
@include button($bg-color: transparent);
|
||||||
|
border: 2px solid var(--border-color);
|
||||||
|
border-radius: $border-radius-full;
|
||||||
|
width: $width;
|
||||||
|
height: $height;
|
||||||
|
@include flex-center;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
box-shadow: 0 2px 4px var(--shadow);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--table-hover);
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Back-link button mixin (shared component)
|
// Back-link button mixin (shared component)
|
||||||
@mixin back-link-styles {
|
@mixin back-link-styles {
|
||||||
display: inline-block;
|
display: inline-block;
|
|
@ -58,13 +58,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-toggle-admin {
|
.theme-toggle-admin {
|
||||||
|
@include theme-toggle-styles;
|
||||||
background: var(--card-bg) !important;
|
background: var(--card-bg) !important;
|
||||||
color: var(--text-color) !important;
|
color: var(--text-color) !important;
|
||||||
border: 2px solid var(--border-color) !important;
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
border-radius: $border-radius-full !important;
|
|
||||||
@include flex-center;
|
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-toggle {
|
.theme-toggle {
|
||||||
|
@include theme-toggle-styles;
|
||||||
align-self: center;
|
align-self: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,19 +23,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&__theme-toggle {
|
&__theme-toggle {
|
||||||
|
@include theme-toggle-styles;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
background: var(--card-bg);
|
|
||||||
border: 2px solid var(--border-color);
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 50px;
|
width: 50px;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
@include flex-center;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.3s ease;
|
|
||||||
box-shadow: 0 2px 4px var(--shadow);
|
|
||||||
|
|
||||||
.theme-icon {
|
.theme-icon {
|
||||||
font-size: $font-size-lg;
|
font-size: $font-size-lg;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue