diff --git a/_sass/_base.scss b/_sass/_base.scss index e02e272..8b529ae 100644 --- a/_sass/_base.scss +++ b/_sass/_base.scss @@ -3,25 +3,17 @@ html { } body { - color: $color-gray300; + color: var(--color-content-secondary); font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,Arial,sans-serif; font-weight: 400; font-size: 1.8rem; line-height: 2.8rem; - - @media (prefers-color-scheme: dark) { - color: $color-gray400; - } } -*:focus, -*:focus-visible { +*:not(main):focus, +*:not(main):focus-visible { outline: none; - box-shadow: 0 0 0 3px $color-action-light; - - @media (prefers-color-scheme: dark) { - box-shadow: 0 0 0 3px $color-action-dark; - } + box-shadow: 0 0 0 3px var(--color-action) !important; } .button { @@ -30,59 +22,34 @@ body { align-items: center; gap: 1rem; padding: 0.8rem 2rem 0.8rem 1.6rem; - color: $color-gray100; - border: 1px solid $color-gray500; + color: var(--color-content-lead); + border: 1px solid var(--color-background-contrast); border-radius: 4rem; - color: inherit; text-decoration: none; transition: all ease-out 0.15s; backdrop-filter: blur(10px); - @media (prefers-color-scheme: dark) { - color: #FFF; - border-color: $color-gray300; - } - &:hover, &:focus { - border-color: $color-gray400; + border-color: var(--color-background-contrast--hover); text-decoration: none; transform: scale3d(1.02,1.02,1); - box-shadow: 0 0 8px 0 rgba($color-action-light, 0.1); - - @media (prefers-color-scheme: dark) { - border-color: $color-gray400; - box-shadow: 0 0 8px 0 rgba($color-action-dark, 0.1); - } + box-shadow: 0 0 8px 0 color-mix(in srgb, var(--color-action) 10%, transparent); } &.highlight-button { - background: $color-gray500; - color: $color-gray100; - - @media (prefers-color-scheme: dark) { - background: $color-gray200; - color: white - } + background: var(--color-background-highlight); + color: var(--color-content-lead); } &.action-button { - background-color: $color-action-light; - color: white; + background-color: var(--color-action); + color: var(--color-background-main); border: none; - @media (prefers-color-scheme: dark) { - background-color: $color-action-dark; - color: black; - } - &:hover, &:focus { - box-shadow: 0 0 12px 0 rgba($color-action-light, 0.3); - - @media (prefers-color-scheme: dark) { - box-shadow: 0 0 12px 0 rgba($color-action-dark, 0.3); - } + box-shadow: 0 0 12px 0 color-mix(in srgb, var(--color-action) 30%, transparent); } } @@ -117,14 +84,10 @@ body { .content { a:not(.button) { font-weight: 500; - color: $color-action-light; + color: var(--color-action); text-decoration: none; transition: all ease-out 0.2s; - @media (prefers-color-scheme: dark) { - color: $color-action-dark; - } - &:focus, &:hover { border-bottom: 2px solid currentColor; @@ -138,11 +101,7 @@ body { h5, h6 { text-rendering: optimizeLegibility; - color: $color-gray100; - - @media (prefers-color-scheme: dark) { - color: #FFF; - } + color: var(--color-content-lead); a:not(.button) { font-weight: inherit; @@ -198,11 +157,7 @@ body { margin-left: -3.2rem; font-weight: 400; text-align: center; - color: $color-gray300; - - @media (prefers-color-scheme: dark) { - color: $color-gray400; - } + color: var(--color-content-secondary); } } @@ -241,7 +196,6 @@ body { line-height: 1.143em; font-weight: 700; margin-bottom: 0.571em; - color: #FFF; } dd { @@ -255,22 +209,18 @@ body { height: 1px; margin: 1.6rem 0; padding: 0; - background: $color-gray500; + background: var(--color-background-contrast); border: 0; - - @media (prefers-color-scheme: dark) { - background: $color-gray300; - } } blockquote { margin: 1.6rem 0; padding: 0 1.6rem; box-sizing: border-box; - border-left: 4px solid rgba(255, 255, 255, 0.25); + border-left: 4px solid var(--color-background-contrast); font-style: italic; font-weight: 400; - color: $color-gray400; + color: var(--color-content-primary); background: transparent; * { @@ -296,32 +246,20 @@ body { b, strong { font-weight: 700; - color: $color-gray200; - - @media (prefers-color-scheme: dark) { - color: $color-gray600; - } + color: var(--color-content-primary); } small { font-size: inherit; - color: $color-gray400; - - @media (prefers-color-scheme: dark) { - color: $color-gray300; - } + color: var(--color-content-primary); } mark { - background-color: $color-action-dark; + background-color: var(--color-action); } pre { - color: $color-gray300; - - @media (prefers-color-scheme: dark) { - color: $color-gray400; - } + color: var(--color-content-secondary); } code, @@ -335,7 +273,7 @@ body { font-size: 0.875em; line-height: 1.143em; white-space: pre; - background: rgba(255, 255, 255, 0.1); + background: var(--color-background-highlight); font-weight: 400; border-radius: 2px; } @@ -345,14 +283,14 @@ body { max-width: 100%; margin: 1.6rem 0; background-color: transparent; - border: 1px solid rgba(255, 255, 255, 0.25); + border: 1px solid var(--color-background-contrast); td, th { position: relative; padding: 1.2rem; text-align: left; - border: 1px solid rgba(255, 255, 255, 0.25); + border: 1px solid var(--color-background-contrast); } th { diff --git a/_sass/_icons.scss b/_sass/_icons.scss deleted file mode 100644 index 505721f..0000000 --- a/_sass/_icons.scss +++ /dev/null @@ -1,63 +0,0 @@ -@font-face { - font-family: 'icons'; - src: url('/assets/styles/icons.eot?76519686'); - src: url('/assets/styles/icons.eot?76519686#iefix') format('embedded-opentype'), - url('/assets/styles/icons.woff2?76519686') format('woff2'), - url('/assets/styles/icons.woff?76519686') format('woff'), - url('/assets/styles/icons.ttf?76519686') format('truetype'), - url('/assets/styles/icons.svg?76519686#icons') format('svg'); - font-weight: normal; - font-style: normal; -} - -/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */ -/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */ -/* -@media screen and (-webkit-min-device-pixel-ratio:0) { - @font-face { - font-family: 'icons'; - src: url('../font/icons.svg?71350588#icons') format('svg'); - } -} -*/ - -[class^="icon-"]:before, -[class*=" icon-"]:before { - font-family: "icons"; - font-style: normal; - font-weight: normal; - speak: none; - - display: inline-block; - text-decoration: inherit; - width: 1em; - margin-right: .2em; - text-align: center; - /* opacity: .8; */ - - /* For safety - reset parent styles, that can break glyph codes*/ - font-variant: normal; - text-transform: none; - - /* fix buttons height, for twitter bootstrap */ - line-height: 1em; - - /* Animation center compensation - margins should be symmetric */ - /* remove if not needed */ - margin-left: .2em; - - /* you can be more comfortable with increased icons size */ - /* font-size: 120%; */ - - /* Font smoothing. That was taken from TWBS */ - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - - /* Uncomment for 3D effect */ - /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */ -} - -.icon-twitter:before { content: '\f099'; } -.icon-github:before { content: '\f09b'; } -.icon-instagram:before { content: '\f16d'; } -.icon-facebook:before { content: '\f230'; } diff --git a/_sass/_layout.scss b/_sass/_layout.scss index 5520106..e902de5 100644 --- a/_sass/_layout.scss +++ b/_sass/_layout.scss @@ -3,14 +3,10 @@ body { height: 100%; padding: 0; margin: 0; - background: #FFF; + background: var(--color-background-main); text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; overflow-x: hidden; - - @media (prefers-color-scheme: dark) { - background: $color-gray100; - } } .inner { @@ -77,12 +73,6 @@ body { width: 100%; z-index: 9999; box-sizing: border-box; - background: linear-gradient(#FFF,rgba(255,255,255,.5)); - backdrop-filter: blur(10px); - - @media (prefers-color-scheme: dark) { - background: linear-gradient(rgba(26,26,26,1),rgba(26,26,26,.75)); - } .inner { display: flex; @@ -165,11 +155,7 @@ body { font-size: 1.8rem; line-height: 2rem; font-weight: 700; - color: black; - - @media (prefers-color-scheme: dark) { - color: white; - } + color: var(--color-content-lead); } .rating { @@ -178,11 +164,7 @@ body { font-weight: 500; span { - color: $color-action-light; - - @media (prefers-color-scheme: dark) { - color: $color-action-dark; - } + color: var(--color-action); } &.rating-ios, @@ -199,48 +181,43 @@ body { //============================================================ .footer { - padding: 4rem 0; + padding: 4rem 0 8vw; - background: $color-gray100; - color: $color-gray400; - - .footer-navigation { - display: flex; - - @media only screen and (max-width: $screen-small) { - flex-direction: column; - } + .footer-navigation { + display: flex; - ul { - display: flex; - flex-wrap: wrap; - gap: 2rem; - margin: 0; - padding: 0; - list-style: none; - } + @media only screen and (max-width: $screen-small) { + flex-direction: column; } - a { - color: $color-gray400; - text-decoration: none; - font-weight: 400; + ul { + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 2rem; + width: 100%; + margin: 0; + padding: 0; + list-style: none; + } + } - &:hover, - &:focus { - color: $color-gray600; - text-decoration: none; - } + a { + color: var(--color-content-secondary); + text-decoration: none; + font-weight: 400; - &.active { - font-weight: 600; - color: #fff; + &:hover, + &:focus { + color: var(--color-content-primary); + text-decoration: none; + } - @media (prefers-color-scheme: dark) { - color: #FFF; - } - } + &.active { + color: var(--color-content-main); + font-weight: 600; } + } } //============================================================ @@ -260,13 +237,9 @@ body { margin-bottom: 2rem; font-size: 10vw; line-height: 1em; - color: $color-gray100; + color: var(--color-content-lead); font-weight: 800; - @media (prefers-color-scheme: dark) { - color: #FFF; - } - @media only screen and (min-width: $screen-large) { font-size: 10rem; } @@ -322,14 +295,9 @@ body { text-align: center; font-size: 2.4rem; color: white; - background: $color-action-light; - border-radius: 4rem; + background: var(--color-action); + border-radius: var(--radius-full); pointer-events: none; - - @media (prefers-color-scheme: dark) { - color: black; - background: $color-action-dark - } } } @@ -340,21 +308,13 @@ body { .download-text--tagline { font-size: 1.2rem; line-height: 1em; - color: $color-gray300; - - @media (prefers-color-scheme: dark) { - color: $color-gray400; - } + color: var(--color-content-secondary); } .download-text--title { font-size: 1.8rem; line-height: 1.5em; - color: $color-gray100; - - @media (prefers-color-scheme: dark) { - color: #FFF; - } + color: var(--color-content-lead); } } } @@ -403,20 +363,17 @@ body { margin-top: -20rem; margin-right: -10rem; pointer-events: none; - color: $color-action-dark; + color: var(--color-action-reverse); @media only screen and (max-width: $screen-small) { margin-right: -16rem; } - @media (prefers-color-scheme: dark) { - color: $color-action-light; - } - svg { display: block; width: 100%; height: auto; + opacity: 0.5; } } } @@ -451,7 +408,7 @@ body { position: relative; display: block; padding: 3rem; - border-radius: 2rem; + border-radius: var(--radius-box); box-sizing: border-box; overflow: hidden; @@ -466,7 +423,7 @@ body { z-index: 20; margin-bottom: 2rem; padding: 0.4em 1.2em 0.4em 0.6em; - border-radius: 4rem; + border-radius: var(--radius-full); font-size: 0.8em; line-height: 1em; font-weight: 600; @@ -522,13 +479,8 @@ body { .support-box--statistics { grid-row: span 3; - background: $color-action-light; - color: white; - - @media (prefers-color-scheme: dark) { - background: $color-action-dark; - color: black; - } + background: var(--color-action); + color: var(--color-background-main); .support-box--background { position: absolute; @@ -540,7 +492,7 @@ body { object-fit: cover; mix-blend-mode: plus-lighter; opacity: 0.5; - border-radius: 2rem; + border-radius: var(--radius-box); @media (prefers-color-scheme: dark) { mix-blend-mode: plus-darker; @@ -578,11 +530,11 @@ body { .support-box--introduction { grid-row: span 8; - background: $color-gray200; - color: $color-gray600; + background: var(--color-gray200); + color: var(--color-gray600); .support-box--label { - background: $color-gray100; + background: var(--color-gray100); svg { color: hotpink; @@ -601,22 +553,22 @@ body { .support-box--collective { grid-row: span 4; - background: rgb(229, 243, 255); - color: rgb(52, 73, 116); + background: hsl(220, 100%, 95%); + color: hsl(220, 35%, 33%); @media (prefers-color-scheme: dark) { - background: rgb(25, 35, 55); - color: rgb(130, 158, 212); + background: hsl(220, 35%, 15%); + color: hsl(220, 50%, 75%); } .support-box--label { - color: rgb(16, 65, 163); + color: hsl(220, 80%, 30%); background: white; font-weight: 700; @media (prefers-color-scheme: dark) { - background: rgb(11, 19, 35); - color: rgb(170, 189, 227); + background: hsl(220, 50%, 10%); + color: hsl(220, 50%, 85%); } } @@ -631,12 +583,12 @@ body { .button { border: 0; - background: rgb(16, 65, 163); + background: hsl(220, 82%, 35%); color: white; &:hover, &:focus { - background: rgb(10, 46, 119); + background: hsl(220, 84%, 25%); } } @@ -664,17 +616,17 @@ body { width: 100%; height: calc(100% - 8rem); background-attachment: scroll; - background-image: - repeating-linear-gradient(90deg, #ffffff22 0 1px, #0000 1px 25px), - repeating-linear-gradient(#ffffff22 0 1px, #0000 1px 25px), - repeating-linear-gradient(90deg, #ffffff44 0 1px, #0000 1px 100px), + background-image: + repeating-linear-gradient(90deg, #ffffff22 0 1px, #0000 1px 25px), + repeating-linear-gradient(#ffffff22 0 1px, #0000 1px 25px), + repeating-linear-gradient(90deg, #ffffff44 0 1px, #0000 1px 100px), repeating-linear-gradient(#ffffff44 0 1px, #0000 1px 100px); @media (prefers-color-scheme: dark) { - background-image: - repeating-linear-gradient(90deg, #ffffff08 0 1px, #0000 1px 25px), - repeating-linear-gradient(#ffffff08 0 1px, #0000 1px 25px), - repeating-linear-gradient(90deg, #ffffff1a 0 1px, #0000 1px 100px), + background-image: + repeating-linear-gradient(90deg, #ffffff08 0 1px, #0000 1px 25px), + repeating-linear-gradient(#ffffff08 0 1px, #0000 1px 25px), + repeating-linear-gradient(90deg, #ffffff1a 0 1px, #0000 1px 100px), repeating-linear-gradient(#ffffff1a 0 1px, #0000 1px 100px); } background-position: @@ -702,7 +654,7 @@ body { top: 4rem; width: 100%; height: calc(100% - 8rem); - background-color: $color-action-light; + background-color: var(--color-action); background-image: url('../images/map-background-light.webp'); background-position: top center; background-size: cover; @@ -710,7 +662,6 @@ body { background-attachment: scroll; @media (prefers-color-scheme: dark) { - background-color: $color-action-dark; background-image: url('../images/map-background-dark.webp'); } @@ -741,7 +692,7 @@ body { max-height: 80vh; box-sizing: border-box; overflow: hidden; - border-radius: 2rem; + border-radius: var(--radius-box); box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.04), 0px 2px 8px rgba(0, 0, 0, 0.06), @@ -757,7 +708,7 @@ body { .map-wrapper { box-shadow: none; - border-radius: 0; + border-radius: none; } } @@ -789,7 +740,7 @@ body { @media (prefers-color-scheme: dark) { background: rgba(26,26,26,75); - color: #FFF; + color: white; } a { @@ -798,15 +749,14 @@ body { } .leaflet-bar { - background: linear-gradient(#FFF,rgba(255,255,255,.5)); + background: var(--background-map-ui); backdrop-filter: blur(10px); box-shadow: 0 1px 2px rgba(0,0,0,0.2); - border-radius: 4rem; + border-radius: var(--radius-full); border: 0; @media (prefers-color-scheme: dark) { - background: linear-gradient(rgba(26,26,26,.75),rgba(26,26,26,1)); - color: #FFF; + color: white; } } @@ -826,31 +776,23 @@ body { align-items: center; justify-content: center; border: 0; - border-radius: 2rem; + border-radius: var(--radius-box); background: transparent; - color: $color-gray200; + color: var(--color-content-primary); cursor: pointer; transition: all ease-out 0.2s; &:hover, &:focus { - background: $color-gray600; - - @media (prefers-color-scheme: dark) { - background: $color-gray200; - } + background: var(--color-background-contrast); } svg { width: 24px; height: 24px; - fill: $color-gray200;; + fill: var(--color-content-primary); transition: fill ease-out 0.2s; - - @media (prefers-color-scheme: dark) { - fill: #fff; - } } } } @@ -892,17 +834,12 @@ body { .leaflet-bar a { background-color: transparent; - border-bottom: 1px solid $color-gray500; + border-bottom: 1px solid var(--color-background-contrast); width: 4rem; height: 4rem; line-height: 4rem; - color: $color-gray100; + color: var(--color-content-lead); transition: all ease-out 0.2s; - - @media (prefers-color-scheme: dark) { - border-color: $color-gray200; - color: $color-gray500; - } } .leaflet-bar a span { @@ -912,11 +849,7 @@ body { .leaflet-bar a:hover, .leaflet-bar a:focus { - background-color: $color-gray600; - - @media (prefers-color-scheme: dark) { - background-color: $color-gray200; - } + background-color: var(--color-background-highlight); } .leaflet-bar a:first-child { @@ -934,11 +867,7 @@ body { .leaflet-bar a.leaflet-disabled { background-color: transparent; - color: $color-gray400; - - @media (prefers-color-scheme: dark) { - color: $color-gray300; - } + color: var(--color-content-primary); } .leaflet-touch .leaflet-bar a { @@ -968,23 +897,18 @@ body { bottom: 0; margin-bottom: 1.2rem; padding: 1rem; - border-radius: 4rem; + border-radius: var(--radius-full); box-shadow: 0 1px 2px rgba(0,0,0,0.2); font-size: 1.4rem; line-height: 1.6rem; font-weight: 400; text-align: center; - background: linear-gradient(#FFF,rgba(255,255,255,.5)); + color: var(--color-content-primary); + background: var(--background-map-ui); backdrop-filter: blur(10px); - color: $color-gray200; z-index: 500; box-sizing: border-box; - @media (prefers-color-scheme: dark) { - background: linear-gradient(rgba(26,26,26,.75),rgba(26,26,26,1)); - color: #FFF; - } - @media only screen and (max-width: $screen-small) { margin-bottom: 2.4rem; } @@ -996,20 +920,12 @@ body { span { font-weight: 700; - color: $color-action-light; - - @media (prefers-color-scheme: dark) { - color: $color-action-dark; - } + color: var(--color-action); } } .map-count-online { - border-right: 1px solid $color-gray500; - - @media (prefers-color-scheme: dark) { - border-color: $color-gray300; - } + border-right: 1px solid var(--color-background-contrast); } } @@ -1025,7 +941,13 @@ body { .navigation { position: absolute; + background: linear-gradient(white,hsla(220, 02%, 96%, 0.5)); box-shadow: 0 1px 2px rgba(0,0,0,0.2); + backdrop-filter: blur(10px); + + @media (prefers-color-scheme: dark) { + background: linear-gradient(hsl(220, 15%, 10%), hsla(220, 15%, 10%, 0.75)); + } .inner { padding: 1.6rem; diff --git a/_sass/_vars.scss b/_sass/_vars.scss index bf25166..63ff806 100644 --- a/_sass/_vars.scss +++ b/_sass/_vars.scss @@ -1,12 +1,49 @@ $screen-small: 40rem; $screen-large: 64rem; -$color-gray100: #1a1a1a; -$color-gray200: #262626; -$color-gray300: #45474d; -$color-gray400: #909399; -$color-gray500: #dadce0; -$color-gray600: #fafafa; - -$color-action-dark: #ffd633; -$color-action-light: rgba(68,0,255,1); +:root { + --radius-full: 4rem; + --radius-box: 2rem; + + --background-map-ui: linear-gradient(white,hsla(220, 02%, 96%, 0.5)); + + --color-gray100: hsl(220, 15%, 10%); + --color-gray200: hsl(220, 15%, 15%); + --color-gray300: hsl(220, 12%, 28%); + --color-gray400: hsl(220, 06%, 58%); + --color-gray500: hsl(220, 04%, 83%); + --color-gray600: hsl(220, 02%, 96%); + + --color-action-dark: hsl(48, 100%, 60%); + --color-action-light: hsl(256, 100%, 50%); + + --color-background-main: white; + --color-background-highlight: var(--color-gray600); + --color-background-contrast: var(--color-gray500); + --color-background-contrast--hover: var(--color-gray400); + + --color-content-lead: black; + --color-content-primary: var(--color-gray200); + --color-content-secondary: var(--color-gray300); + + --color-action: var(--color-action-light); + --color-action-reverse: var(--color-action-dark); +} + +@media (prefers-color-scheme: dark) { + :root { + --background-map-ui: linear-gradient(hsla(220, 15%, 10%, 0.75),hsl(220, 15%, 10%)); + + --color-background-main: var(--color-gray100);; + --color-background-highlight: var(--color-gray200); + --color-background-contrast: var(--color-gray300); + --color-background-contrast--hover: var(--color-gray400); + + --color-content-lead: white; + --color-content-primary: var(--color-gray600); + --color-content-secondary: var(--color-gray500); + + --color-action: var(--color-action-dark); + --color-action-reverse: var(--color-action-light); + } +} \ No newline at end of file diff --git a/assets/js/application.js b/assets/js/application.js index 1e0d4ec..c15131c 100644 --- a/assets/js/application.js +++ b/assets/js/application.js @@ -1,6 +1,5 @@ document.addEventListener('DOMContentLoaded', function () { var currentMarkers = []; - var isDarkMode = false; var isMapFullscreen = false; // fullscreen animation state var _fullscreenSavedCenter = null; @@ -148,7 +147,6 @@ document.addEventListener('DOMContentLoaded', function () { var mapboxLayer = null; function applyMapStyle(useDark) { - isDarkMode = !!useDark; // remove existing layer if present if (mapboxLayer) { try { bikeMap.removeLayer(mapboxLayer); } catch (e) { /* ignore */ } @@ -158,8 +156,8 @@ document.addEventListener('DOMContentLoaded', function () { attribution: '© MapTiler © OpenStreetMap contributors', style: useDark ? darkStyleUrl : lightStyleUrl }).addTo(bikeMap); - // update existing markers to match theme (yellow in dark mode) - var markerColor = isDarkMode ? '#ffd633' : '#4400ff'; + // update existing markers to match theme + var markerColor = getComputedStyle(document.documentElement).getPropertyValue('--color-action').trim(); currentMarkers.forEach(function (m) { try { m.setStyle({ fillColor: markerColor, color: markerColor }); } catch (e) { /* ignore */ } }); @@ -645,8 +643,6 @@ document.addEventListener('DOMContentLoaded', function () { if (rafId) cancelAnimationFrame(rafId); rafId = null; }); - - // hover handlers removed — markers no longer affect meatball state on mouseover })(); function saveHashToElements() { @@ -676,8 +672,8 @@ document.addEventListener('DOMContentLoaded', function () { currentMarkers = [] //add new markers as SVG circleMarkers (use shared svgRenderer) + var markerColor = getComputedStyle(document.documentElement).getPropertyValue('--color-action').trim(); locationsArray.forEach(function (coordinate) { - var markerColor = isDarkMode ? '#ffd633' : '#4400ff'; var circle = L.circleMarker([coordinate.latitude, coordinate.longitude], { renderer: svgRenderer, radius: 12,