From aeb7c9dae22b574bc6c76fa70b74102e26ff339c Mon Sep 17 00:00:00 2001 From: Gwendolyn Date: Tue, 17 Sep 2024 15:56:54 +0200 Subject: [PATCH] theming stuff in preparation for ef28 cyberpunk theme --- src/c3nav/editor/templates/editor/base.html | 3 +- src/c3nav/mapdata/models/theme.py | 32 +-- src/c3nav/settings.py | 2 +- src/c3nav/site/static/site/css/c3nav.scss | 241 +++++++++++++++----- src/c3nav/site/static/site/js/c3nav.js | 14 +- src/c3nav/site/templates/site/base.html | 3 +- src/c3nav/site/templates/site/map.html | 6 +- src/c3nav/site/themes.py | 26 ++- src/c3nav/static/milligram/_Button.sass | 44 +--- 9 files changed, 227 insertions(+), 144 deletions(-) diff --git a/src/c3nav/editor/templates/editor/base.html b/src/c3nav/editor/templates/editor/base.html index 2ad5f786..c1f9a38e 100644 --- a/src/c3nav/editor/templates/editor/base.html +++ b/src/c3nav/editor/templates/editor/base.html @@ -28,13 +28,14 @@ } {% endif %} - + {% compress css %} {% endcompress %} + diff --git a/src/c3nav/mapdata/models/theme.py b/src/c3nav/mapdata/models/theme.py index eaf98066..88cc2c9e 100644 --- a/src/c3nav/mapdata/models/theme.py +++ b/src/c3nav/mapdata/models/theme.py @@ -58,22 +58,22 @@ class Theme(TitledMixin, models.Model): def css_vars(self): return { - 'initial': self.color_css_initial or settings.BASE_THEME['css']['initial'], - 'primary': self.color_css_primary or settings.BASE_THEME['css']['primary'], - 'secondary': self.color_css_secondary or settings.BASE_THEME['css']['secondary'], - 'tertiary': self.color_css_tertiary or settings.BASE_THEME['css']['tertiary'], - 'quaternary': self.color_css_quaternary or settings.BASE_THEME['css']['quaternary'], - 'quinary': self.color_css_quinary or settings.BASE_THEME['css']['quinary'], - 'header-background': self.color_css_header_background or settings.BASE_THEME['css']['header-background'], - 'header-text': self.color_css_header_text or settings.BASE_THEME['css']['header-text'], - 'header-text-hover': self.color_css_header_text_hover or settings.BASE_THEME['css']['header-text-hover'], - 'shadow': self.color_css_shadow or settings.BASE_THEME['css']['shadow'], - 'overlay-background': self.color_css_overlay_background or settings.BASE_THEME['css']['overlay-background'], - 'grid': self.color_css_grid or settings.BASE_THEME['css']['grid'], - 'modal-backdrop': self.color_css_modal_backdrop or settings.BASE_THEME['css']['modal-backdrop'], - 'route-dots-shadow': self.color_css_route_dots_shadow or settings.BASE_THEME['css']['route-dots-shadow'], - 'leaflet-background': self.color_background or settings.BASE_THEME['css']['leaflet-background'], - 'logo': self.color_logo or settings.BASE_THEME['css']['logo'], + 'initial': self.color_css_initial, + 'primary': self.color_css_primary, + 'secondary': self.color_css_secondary, + 'tertiary': self.color_css_tertiary, + 'quaternary': self.color_css_quaternary, + 'quinary': self.color_css_quinary, + 'header-background': self.color_css_header_background, + 'header-text': self.color_css_header_text, + 'header-text-hover': self.color_css_header_text_hover, + 'shadow': self.color_css_shadow, + 'overlay-background': self.color_css_overlay_background, + 'grid': self.color_css_grid, + 'modal-backdrop': self.color_css_modal_backdrop, + 'route-dots-shadow': self.color_css_route_dots_shadow, + 'leaflet-background': self.color_background, + 'logo': self.color_logo, } class Meta: diff --git a/src/c3nav/settings.py b/src/c3nav/settings.py index 1cea21d7..b7690487 100644 --- a/src/c3nav/settings.py +++ b/src/c3nav/settings.py @@ -611,7 +611,7 @@ BASE_THEME = { 'obstacles_default_border': config.get('theme', 'map_obstacles_default_border', fallback='#888888'), 'highlight': config.get('theme', 'css_primary', fallback='#9b4dca'), }, - 'css': { + 'css_vars': { 'initial': config.get('theme', 'css_initial', fallback='#ffffff'), 'primary': config.get('theme', 'css_primary', fallback='#9b4dca'), 'logo': config.get('theme', 'css_logo', fallback=None), diff --git a/src/c3nav/site/static/site/css/c3nav.scss b/src/c3nav/site/static/site/css/c3nav.scss index 66370846..0dc2c60b 100644 --- a/src/c3nav/site/static/site/css/c3nav.scss +++ b/src/c3nav/site/static/site/css/c3nav.scss @@ -10,19 +10,45 @@ --color-control: var(--color-secondary); --color-control-background: var(--color-initial); --color-control-background-hover: var(--color-tertiary); + --color-control-hover: var(--color-foreground); --color-control-active: var(--color-tertiary); --color-control-divider: var(--color-quaternary); --color-control-disabled: var(--color-quaternary); --color-icon: var(--color-secondary); --color-icon-light: var(--color-quaternary); --color-button: var(--color-quaternary); + --color-primary-button: var(--color-primary); --color-button-border-hover: var(--color-quaternary); --color-button-hover: var(--color-quinary); + --color-focus: var(--color-foreground); + + --color-map-overlay: var(--color-primary); + --color-route-dashes: #888888; + + + --color-pin: var(--color-foreground); + --color-pin-background: transparent; + --color-pin-background-active: var(--color-quinary); + --color-pin-active: var(--color-foreground); + --color-pin-hover: var(--color-foreground); + --color-pin-background-hover: var(--color-tertiary); + + --color-shadow: var(--color-quaternary); + + --shadow-size: 4px; + + --border-radius: 2px; + --border-radius-small: 2px; + --border-radius-leaflet-control: 4px; } - @import 'milligram/milligram.sass'; +::selection { + background-color: var(--color-primary); + color: white; +} + body { font-weight: normal; display: flex; @@ -35,6 +61,7 @@ body { right: 0; } + header { padding: 10px; height: 60px; @@ -55,6 +82,7 @@ header h1 a { display: block; height: 50px; } + header h1 a, header h1 a:hover { color: var(--color-primary); } @@ -93,7 +121,7 @@ header #user:hover { color: var(--color-header-text-hover); } -input { +input, textarea, select { font-family: inherit; color: inherit; } @@ -196,6 +224,7 @@ main.account form { max-width: 420px; pointer-events: none; display: flex; + gap: 1.5rem; flex-direction: column; overflow: hidden; } @@ -207,23 +236,28 @@ main.account form { } #sidebar section { + position: relative; pointer-events: auto; background-color: var(--color-background); - box-shadow: 1px 1px 3px var(--color-shadow); - border-radius: 2px; + border-radius: var(--border-radius); overflow: hidden; - margin-bottom: 10px; +} + +#sidebar section:not(:empty) { + border: 2px solid var(--color-control-border); + box-shadow: var(--color-shadow) 0 0 var(--shadow-size); } #sidebar section > div { border: 0 var(--color-sidebar-border) solid; border-top-width: 1px; - transition: margin-bottom 150ms, opacity 150ms; + transition: margin-bottom 150ms, opacity 150ms, background-color 150ms ease-in-out, color 150ms ease-in-out; + overflow: hidden; } #sidebar section > div:first-child { - margin-top: -1px; + border-top-width: 0; } #search { @@ -307,6 +341,10 @@ main:not([data-view^=route]) #origin-input, opacity: 0; } +main:not([data-view^=route]) #destination-input { + border-top-width: 0; +} + main:not([data-view=location]) #location-buttons, main:not([data-view=route-search]) #route-search-buttons, main:not([data-view=route-result]) #route-result-buttons { @@ -532,7 +570,7 @@ main.show-options #resultswrapper #route-options { .location-answers .location.location-form-value, .location-answers a { margin-bottom: 5px; - color: var(--color-secondary); + color: var(--color-foreground); display: block; } @@ -562,6 +600,11 @@ main.show-options #resultswrapper #route-options { .location.focus { background-color: var(--color-tertiary); + color: var(--color-focus); + + .icon { + color: var(--color-focus); + } } #autocomplete .location { @@ -574,13 +617,14 @@ main.show-options #resultswrapper #route-options { .location-label-text { line-height: 100%; - border-radius: 2px; + border-radius: var(--border-radius-small); white-space: nowrap; transform: translateX(-50%) translateY(-50%); text-align: center; span { line-height: 100%; + color: var(--color-overlay-text); background-color: var(--color-overlay-background); vertical-align: 12%; } @@ -623,7 +667,7 @@ main.show-options #resultswrapper #route-options { position: absolute; top: 0; left: 1px; - content: "\e8b6"; /* unicode code point for the "seach" ligature, so android 4.3.3 gets it */ + content: "\e8b6"; /* unicode code point for the "search" ligature, so android 4.3.3 gets it */ color: var(--color-icon-light); transition: color 150ms; } @@ -681,9 +725,9 @@ main[data-view^=route] button.random, .locationinput:not(.empty) button.random { #route-dots { position: absolute; - top: 53px; - left: 25px; - text-shadow: 2px 0 1px var(--color-route-dots-shadow), -2px 0 1px var(--color-route-dots-shadow); + top: 43px; + left: 15px; + text-shadow: 2px 0 1px var(--color-route-dashes-shadow), -2px 0 1px var(--color-route-dashes-shadow); transition: top 150ms, opacity 150ms, color 150ms, transform 150ms; color: var(--color-route-dots); pointer-events: none; @@ -734,7 +778,7 @@ main:not([data-view=route-result]) #route-dots { .location-popup .leaflet-popup-content { font-size: 16px; - color: var(--color-secondary); + color: var(--color-foreground); overflow: hidden; line-height: 1.6; margin: 15px 10px 10px; @@ -743,10 +787,51 @@ main:not([data-view=route-result]) #route-dots { .leaflet-popup-content-wrapper, .leaflet-popup-tip { background-color: var(--color-background); - box-shadow: 1px 1px 3px var(--color-shadow); - border-radius: 2px; + box-shadow: var(--color-shadow) 0 0 var(--shadow-size); } +.leaflet-popup-content-wrapper { + border-radius: var(--border-radius-small); +} + +button, .button { + color: var(--color-background); + background-color: var(--color-primary-button); + border-color: var(--color-primary-button); + + &:hover, &:active { + background-color: var(--color-button-hover); + border-color: var(--color-button-hover); + color: var(--color-background); + } + + &.button-clear { + color: var(--color-primary-button); + background-color: transparent; + border-color: transparent; + + &:hover, &:active { + color: var(--color-button-hover); + background-color: transparent; + border-color: transparent; + } + } + + &.button-outline { + color: var(--color-primary-button); + background-color: transparent; + border-color: var(--color-primary-button); + + &:hover, &:active { + color: var(--color-button-hover); + background-color: transparent; + border-color: var(--color-button-hover); + } + } + +} + + .location-popup { .leaflet-popup-content-wrapper { padding: 0; @@ -891,8 +976,12 @@ main:not([data-view=route-result]) #route-summary { height: 37px; border-width: 0; font-size: 36px; - color: var(--color-button); line-height: 1; + color: var(--color-button); + + &:hover { + color: var(--color-button-hover); + } } @media not all and (min-height: 700px) and (min-width: 1100px) { @@ -941,7 +1030,8 @@ main:not([data-view=route-result]) #route-summary { .leaflet-control-levels a.current { font-weight: bold; - background-color: var(--color-control-active); + color: var(--color-control-active); + background-color: var(--color-control-background-active); } .leaflet-container { @@ -950,14 +1040,14 @@ main:not([data-view=route-result]) #route-summary { .leaflet-container .leaflet-control-attribution { background-color: var(--color-overlay-background); - color: var(--color-secondary); + color: var(--color-foreground); a { color: var(--color-primary); } a:hover { - color: var(--color-secondary); + color: var(--color-foreground); text-decoration: none; } } @@ -966,8 +1056,12 @@ main:not([data-view=route-result]) #route-summary { font-size: 20px; } -.leaflet-bar { - box-shadow: 0 1px 5px var(--color-control-shadow); +.leaflet-bar, .leaflet-control-key { + overflow: hidden; + background-color: var(--color-control-background); + border-radius: var(--border-radius-leaflet-control); + border: 2px solid var(--color-control-border); + box-shadow: var(--color-control-shadow) 0 0 var(--shadow-size); } .leaflet-bar a { @@ -976,9 +1070,13 @@ main:not([data-view=route-result]) #route-summary { border-bottom-color: var(--color-control-divider); } +.leaflet-bar a:first-child, .leaflet-bar a:last-child { + border-radius: 0; +} + .leaflet-bar a:hover { background-color: var(--color-control-background-hover); - color: var(--color-control); + color: var(--color-control-hover); border-bottom-color: var(--color-control-divider); } @@ -986,12 +1084,12 @@ main:not([data-view=route-result]) #route-summary { color: var(--color-control); } -.leaflet-bar a.leaflet-disabled { +.leaflet-bar a.leaflet-disabled, { color: var(--color-control-disabled); background-color: var(--color-control-background); // todo: special disabled background color #f4f4f4 ? } -.leaflet-bar .control-disabled, .leaflet-bar .control-disabled:hover, .leaflet-bar .control-disabled:focus { +.leaflet-bar .control-disabled, .leaflet-bar .control-disabled:focus { color: var(--color-control-disabled); // TODO: is this even used? } @@ -1086,8 +1184,9 @@ main:not([data-view=route-result]) #route-summary { } #modal-content { - box-shadow: 1px 1px 3px var(--color-shadow); - border-radius: 2px; + box-shadow: var(--color-shadow) 0 0 var(--shadow-size); + border: 2px solid var(--color-modal-border); + border-radius: var(--border-radius); background-color: var(--color-background); width: 380px; min-height: 150px; @@ -1169,34 +1268,34 @@ ul.messages { ul.messages li { padding: 1.0rem; - border-radius: .4rem; - border: 0.1rem solid #666666; - background-color: #EEEEEE; + border-radius: var(--border-radius); pointer-events: auto; + + --message-color-bg: var(--color-background); + --message-color-fg: var(--color-foreground); + --message-color-border: var(--message-color-fg); + --message-color-shadow: var(--message-color-fg); + + color: var(--message-color-fg); + box-shadow: var(--message-color-shadow) 0 0 calc(var(--shadow-size) * 3), inset var(--message-color-shadow) 0 0 var(--shadow-size); + border: 2px solid var(--message-color-border); + background-color: var(--message-color-bg); } ul.messages li.alert-info { - color: #006688; - border-color: #006688; - background-color: #DDE4FF; + --message-color-fg: #00dbff; } ul.messages li.alert-success { - color: #338800; - border-color: #339900; - background-color: #E4FFDD; + --message-color-fg: #56ff27; } ul.messages li.alert-warning { - color: #CC6600; - border-color: #FF9900; - background-color: #FFFFDD; + --message-color-fg: #ff8f3f; } ul.messages li.alert-danger { - color: #CC0000; - border-color: #CC0000; - background-color: #FFEEEE; + --message-color-fg: #ff4677; } .app-ads { @@ -1212,8 +1311,8 @@ ul.messages li.alert-danger { .app-ads div { background-color: var(--color-background); - box-shadow: 1px 1px 3px var(--color-shadow); - border-radius: 2px; + box-shadow: 0 0 var(--shadow-size) var(--color-shadow); + border-radius: var(--border-radius-small); overflow: hidden; display: inline-block; margin: 0 10px 25px; @@ -1347,11 +1446,13 @@ main .narrow form button, main .narrow form .button { width: 100%; } -main form > p, #modal form > p { - margin-bottom: 15px; +main form, #modal form { + > p { + margin-bottom: 15px; - > :last-child { - margin-bottom: 0; + > :last-child { + margin-bottom: 0; + } } .helptext { @@ -1361,9 +1462,14 @@ main form > p, #modal form > p { color: var(--color-helptext); } + input[type=text], textarea { + border: 1px solid var(--color-border); + } + textarea { resize: none; height: 100px; + color: var(--color-foreground); } select[multiple] { @@ -1375,6 +1481,7 @@ main form > p, #modal form > p { } } + .user-permissions-form label { font-weight: 400; width: auto; @@ -1562,9 +1669,6 @@ blink { } .leaflet-control-key { - background-color: white; - border-radius: 0.5rem; - box-shadow: 0 1px 5px var(--color-control-shadow); background-clip: padding-box; &.leaflet-control-key-expanded > .collapsed-toggle { @@ -1576,6 +1680,7 @@ blink { height: 26px; line-height: 26px; text-align: center; + &::before { font-family: 'Material Symbols Outlined'; content: 'legend_toggle'; @@ -1587,24 +1692,32 @@ blink { > .pin-toggle { display: none; position: absolute; - right: 0.5rem; - color: black; - font-size: 1.5rem; top: 0.5rem; + right: 0.5rem; + color: var(--color-pin); + font-size: 1.5rem; width: 2.5rem; height: 2.5rem; line-height: 2.2rem; - box-shadow: inset 0 0 2px black; - border-radius: 0.5rem; + border-radius: var(--border-radius-leaflet-control); text-align: center; cursor: pointer; + background: var(--color-pin-background); + border: 1px solid var(--color-pin-border); + box-shadow: inset 0 0 2px black; + &.active { - background: #DCDCDC; + background: var(--color-pin-background-active); + color: var(--color-pin-active); + border-color: var(--color-pin-border-active); + box-shadow: inset var(--color-shadow) 0 0 var(--shadow-size); } &:hover { - background: #D0D0D0; + color: var(--color-pin-hover); + background: var(--color-pin-background-hover); + border-color: var(--color-pin-border-hover); } } @@ -1614,17 +1727,21 @@ blink { > .content { display: none; - padding: 1rem; + padding: 1rem 3rem 1rem 1rem; gap: 1rem; - grid-template-columns: 26px 1fr; + grid-template-columns: 2rem 1fr; > .key { display: grid; grid-column: span 2; grid-template-columns: subgrid; + line-height: 2rem; + > .key-color { - width: 100%; - height: 100%; + border-radius: var(--border-radius-small); + width: 2rem; + height: 2rem; + box-shadow: var(--color-foreground) 0 0 var(var(--shadow-size) / 2), inset var(--color-foreground) 0 0 2px; } } } diff --git a/src/c3nav/site/static/site/js/c3nav.js b/src/c3nav/site/static/site/js/c3nav.js index 41c572c1..fa7f8b8e 100644 --- a/src/c3nav/site/static/site/js/c3nav.js +++ b/src/c3nav/site/static/site/js/c3nav.js @@ -496,7 +496,7 @@ c3nav = { if (data.geometry && data.level) { L.geoJSON(data.geometry, { style: { - color: 'var(--color-primary)', + color: 'var(--color-map-overlay)', fillOpacity: 0.1, } }).addTo(c3nav._routeLayers[data.level]); @@ -657,13 +657,14 @@ c3nav = { point = [destination[0] + Math.cos(angle) * offset, destination[1] + Math.sin(angle) * offset]; return [origin, point, destination]; }, - _add_line_to_route: function (level, coords, gray, link_to_level) { + _add_line_to_route: function (level, coords, dots, link_to_level) { if (coords.length < 2) return; var latlngs = L.GeoJSON.coordsToLatLngs(c3nav._smooth_line(coords)), routeLayer = c3nav._routeLayers[level]; line = L.polyline(latlngs, { - color: gray ? '#888888' : 'var(--color-primary)', - dashArray: (gray || link_to_level) ? '7' : null, + className: dots ? 'c3nav-route-dashes' : 'c3nav-route-line', + color: dots ? 'var(--color-route-dashes)' : 'var(--color-map-overlay)', + dashArray: (dots || link_to_level) ? '7' : null, interactive: false, smoothFactor: 0.5 }).addTo(routeLayer); @@ -1495,7 +1496,8 @@ c3nav = { c3nav_api.post('settings/theme/?id=' + id); localStorageWrapper.setItem('c3nav-theme', c3nav.theme); // TODO: instead (or additionally?) do a request to save it in the session! } - document.querySelector('#c3nav-theme-vars').innerText = theme.css; + document.querySelector('#c3nav-theme-css-vars').innerText = theme.css_vars; + document.querySelector('#c3nav-theme-css-extra').innerText = theme.css_extra; document.querySelector('#theme-color-meta-dark').content = theme.theme_color_dark; document.querySelector('#theme-color-meta-light').content = theme.theme_color_light; @@ -1782,7 +1784,7 @@ c3nav = { if (data.geometry.type === "Point") return; L.geoJSON(data.geometry, { style: { - color: 'var(--color-primary)', + color: 'var(--color-map-overlay)', fillOpacity: 0.2, interactive: false, } diff --git a/src/c3nav/site/templates/site/base.html b/src/c3nav/site/templates/site/base.html index f5e50d94..52896a9e 100644 --- a/src/c3nav/site/templates/site/base.html +++ b/src/c3nav/site/templates/site/base.html @@ -31,7 +31,7 @@ } {% endif %} - + {{ themes|json_script:"c3nav-themes" }} {{ active_theme_id|json_script:"c3nav-active-theme" }} {% compress css %} @@ -41,6 +41,7 @@ {% endcompress %} + {% block head %} {% endblock %} {% if header_logo and header_logo_mask_mode %} diff --git a/src/c3nav/site/templates/site/map.html b/src/c3nav/site/templates/site/map.html index 7647ed65..a9f47bd9 100644 --- a/src/c3nav/site/templates/site/map.html +++ b/src/c3nav/site/templates/site/map.html @@ -118,7 +118,6 @@