diff --git a/README.md b/README.md index dbb5858..f77c866 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,26 @@ -# A11y Elevator List for HVV +```paython +from http.server import HTTPServer, SimpleHTTPRequestHandler +import sys + + +class CORSRequestHandler(SimpleHTTPRequestHandler): + + def end_headers(self): + self.send_header('Access-Control-Allow-Origin', 'origin') + self.send_header('Access-Control-Allow-Methods', '*') + self.send_header('Access-Control-Allow-Headers', '*') + self.send_header('Cache-Control', 'no-store, no-cache, must-revalidate') + return super(CORSRequestHandler, self).end_headers() + + def do_OPTIONS(self): + self.send_response(200) + self.end_headers() + +host = sys.argv[1] if len(sys.argv) > 2 else '0.0.0.0' +port = int(sys.argv[len(sys.argv)-1]) if len(sys.argv) > 1 else 8080 + +print("Listening on {}:{}".format(host, port)) +httpd = HTTPServer((host, port), CORSRequestHandler) +httpd.serve_forever() +``` -This site provides an (at least more) accessible version of the HVV Website for (not) working elevators: https://www.hvv.de/de/aufzuege \ No newline at end of file diff --git a/about.html b/about.html index 300c57f..1265ac6 100644 --- a/about.html +++ b/about.html @@ -6,43 +6,35 @@ content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> - - - - - - hvvstuhl.de | Was ist das? + A11y Elevator List -

Barrierefreie Aufzugs-Liste

+

A11y Elevator List

-
-

Worum geht's hier?

-

- Diese Seite ermöglicht einen barrierefreien Zugang zu den Aufzugs-Informationen im HVV. - Der HVV selbst zeigt diese Informationen nur auf einer (vor allem ohne Ortskenntnis) schwer zu navigierenden - Karte an: - HVV Webseite zu Aufzügen -

-

- Dieses Projekt wurde unter der AGPL-3 Lizenz entwickelt und ist hier zu finden: - git.kritzl.dev -

-
+
+

What is this site?

+

+ This site provides an (at least more) accessible version of the HVV Website for (not) working elevators:
+ HVV Website +

+

+ bla... +

+
\ No newline at end of file diff --git a/colors.css b/colors.css deleted file mode 100644 index f48e716..0000000 --- a/colors.css +++ /dev/null @@ -1,3 +0,0 @@ - - -/*# sourceMappingURL=colors.css.map */ diff --git a/colors.css.map b/colors.css.map deleted file mode 100644 index 6ee84d1..0000000 --- a/colors.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sourceRoot":"","sources":[],"names":[],"mappings":"","file":"colors.css"} \ No newline at end of file diff --git a/colors.scss b/colors.scss deleted file mode 100644 index 5c32430..0000000 --- a/colors.scss +++ /dev/null @@ -1,271 +0,0 @@ -@mixin tailwindColors { - /* Colors from Tailwind CSS: https://github.com/tailwindlabs/tailwindcss - - MIT License - - Copyright (c) Tailwind Labs, Inc. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ - --color-black: #000; - --color-white: #fff; - --color-slate-50: #f8fafc; - --color-slate-100: #f1f5f9; - --color-slate-200: #e2e8f0; - --color-slate-300: #cbd5e1; - --color-slate-400: #94a3b8; - --color-slate-500: #64748b; - --color-slate-600: #475569; - --color-slate-700: #334155; - --color-slate-800: #1e293b; - --color-slate-900: #0f172a; - --color-slate-950: #020617; - --color-gray-50: #f9fafb; - --color-gray-100: #f3f4f6; - --color-gray-200: #e5e7eb; - --color-gray-300: #d1d5db; - --color-gray-400: #9ca3af; - --color-gray-500: #6b7280; - --color-gray-600: #4b5563; - --color-gray-700: #374151; - --color-gray-800: #1f2937; - --color-gray-900: #111827; - --color-gray-950: #030712; - --color-zinc-50: #fafafa; - --color-zinc-100: #f4f4f5; - --color-zinc-200: #e4e4e7; - --color-zinc-300: #d4d4d8; - --color-zinc-400: #a1a1aa; - --color-zinc-500: #71717a; - --color-zinc-600: #52525b; - --color-zinc-700: #3f3f46; - --color-zinc-800: #27272a; - --color-zinc-900: #18181b; - --color-zinc-950: #09090b; - --color-neutral-50: #fafafa; - --color-neutral-100: #f5f5f5; - --color-neutral-200: #e5e5e5; - --color-neutral-300: #d4d4d4; - --color-neutral-400: #a3a3a3; - --color-neutral-500: #737373; - --color-neutral-600: #525252; - --color-neutral-700: #404040; - --color-neutral-800: #262626; - --color-neutral-900: #171717; - --color-neutral-950: #0a0a0a; - --color-stone-50: #fafaf9; - --color-stone-100: #f5f5f4; - --color-stone-200: #e7e5e4; - --color-stone-300: #d6d3d1; - --color-stone-400: #a8a29e; - --color-stone-500: #78716c; - --color-stone-600: #57534e; - --color-stone-700: #44403c; - --color-stone-800: #292524; - --color-stone-900: #1c1917; - --color-stone-950: #0c0a09; - --color-red-50: #fef2f2; - --color-red-100: #fee2e2; - --color-red-200: #fecaca; - --color-red-300: #fca5a5; - --color-red-400: #f87171; - --color-red-500: #ef4444; - --color-red-600: #dc2626; - --color-red-700: #b91c1c; - --color-red-800: #991b1b; - --color-red-900: #7f1d1d; - --color-red-950: #450a0a; - --color-orange-50: #fff7ed; - --color-orange-100: #ffedd5; - --color-orange-200: #fed7aa; - --color-orange-300: #fdba74; - --color-orange-400: #fb923c; - --color-orange-500: #f97316; - --color-orange-600: #ea580c; - --color-orange-700: #c2410c; - --color-orange-800: #9a3412; - --color-orange-900: #7c2d12; - --color-orange-950: #431407; - --color-amber-50: #fffbeb; - --color-amber-100: #fef3c7; - --color-amber-200: #fde68a; - --color-amber-300: #fcd34d; - --color-amber-400: #fbbf24; - --color-amber-500: #f59e0b; - --color-amber-600: #d97706; - --color-amber-700: #b45309; - --color-amber-800: #92400e; - --color-amber-900: #78350f; - --color-amber-950: #451a03; - --color-yellow-50: #fefce8; - --color-yellow-100: #fef9c3; - --color-yellow-200: #fef08a; - --color-yellow-300: #fde047; - --color-yellow-400: #facc15; - --color-yellow-500: #eab308; - --color-yellow-600: #ca8a04; - --color-yellow-700: #a16207; - --color-yellow-800: #854d0e; - --color-yellow-900: #713f12; - --color-yellow-950: #422006; - --color-lime-50: #f7fee7; - --color-lime-100: #ecfccb; - --color-lime-200: #d9f99d; - --color-lime-300: #bef264; - --color-lime-400: #a3e635; - --color-lime-500: #84cc16; - --color-lime-600: #65a30d; - --color-lime-700: #4d7c0f; - --color-lime-800: #3f6212; - --color-lime-900: #365314; - --color-lime-950: #1a2e05; - --color-green-50: #f0fdf4; - --color-green-100: #dcfce7; - --color-green-200: #bbf7d0; - --color-green-300: #86efac; - --color-green-400: #4ade80; - --color-green-500: #22c55e; - --color-green-600: #16a34a; - --color-green-700: #15803d; - --color-green-800: #166534; - --color-green-900: #14532d; - --color-green-950: #052e16; - --color-emerald-50: #ecfdf5; - --color-emerald-100: #d1fae5; - --color-emerald-200: #a7f3d0; - --color-emerald-300: #6ee7b7; - --color-emerald-400: #34d399; - --color-emerald-500: #10b981; - --color-emerald-600: #059669; - --color-emerald-700: #047857; - --color-emerald-800: #065f46; - --color-emerald-900: #064e3b; - --color-emerald-950: #022c22; - --color-teal-50: #f0fdfa; - --color-teal-100: #ccfbf1; - --color-teal-200: #99f6e4; - --color-teal-300: #5eead4; - --color-teal-400: #2dd4bf; - --color-teal-500: #14b8a6; - --color-teal-600: #0d9488; - --color-teal-700: #0f766e; - --color-teal-800: #115e59; - --color-teal-900: #134e4a; - --color-teal-950: #042f2e; - --color-cyan-50: #ecfeff; - --color-cyan-100: #cffafe; - --color-cyan-200: #a5f3fc; - --color-cyan-300: #67e8f9; - --color-cyan-400: #22d3ee; - --color-cyan-500: #06b6d4; - --color-cyan-600: #0891b2; - --color-cyan-700: #0e7490; - --color-cyan-800: #155e75; - --color-cyan-900: #164e63; - --color-cyan-950: #083344; - --color-sky-50: #f0f9ff; - --color-sky-100: #e0f2fe; - --color-sky-200: #bae6fd; - --color-sky-300: #7dd3fc; - --color-sky-400: #38bdf8; - --color-sky-500: #0ea5e9; - --color-sky-600: #0284c7; - --color-sky-700: #0369a1; - --color-sky-800: #075985; - --color-sky-900: #0c4a6e; - --color-sky-950: #082f49; - --color-blue-50: #eff6ff; - --color-blue-100: #dbeafe; - --color-blue-200: #bfdbfe; - --color-blue-300: #93c5fd; - --color-blue-400: #60a5fa; - --color-blue-500: #3b82f6; - --color-blue-600: #2563eb; - --color-blue-700: #1d4ed8; - --color-blue-800: #1e40af; - --color-blue-900: #1e3a8a; - --color-blue-950: #172554; - --color-indigo-50: #eef2ff; - --color-indigo-100: #e0e7ff; - --color-indigo-200: #c7d2fe; - --color-indigo-300: #a5b4fc; - --color-indigo-400: #818cf8; - --color-indigo-500: #6366f1; - --color-indigo-600: #4f46e5; - --color-indigo-700: #4338ca; - --color-indigo-800: #3730a3; - --color-indigo-900: #312e81; - --color-indigo-950: #1e1b4b; - --color-violet-50: #f5f3ff; - --color-violet-100: #ede9fe; - --color-violet-200: #ddd6fe; - --color-violet-300: #c4b5fd; - --color-violet-400: #a78bfa; - --color-violet-500: #8b5cf6; - --color-violet-600: #7c3aed; - --color-violet-700: #6d28d9; - --color-violet-800: #5b21b6; - --color-violet-900: #4c1d95; - --color-violet-950: #2e1065; - --color-purple-50: #faf5ff; - --color-purple-100: #f3e8ff; - --color-purple-200: #e9d5ff; - --color-purple-300: #d8b4fe; - --color-purple-400: #c084fc; - --color-purple-500: #a855f7; - --color-purple-600: #9333ea; - --color-purple-700: #7e22ce; - --color-purple-800: #6b21a8; - --color-purple-900: #581c87; - --color-purple-950: #3b0764; - --color-fuchsia-50: #fdf4ff; - --color-fuchsia-100: #fae8ff; - --color-fuchsia-200: #f5d0fe; - --color-fuchsia-300: #f0abfc; - --color-fuchsia-400: #e879f9; - --color-fuchsia-500: #d946ef; - --color-fuchsia-600: #c026d3; - --color-fuchsia-700: #a21caf; - --color-fuchsia-800: #86198f; - --color-fuchsia-900: #701a75; - --color-fuchsia-950: #4a044e; - --color-pink-50: #fdf2f8; - --color-pink-100: #fce7f3; - --color-pink-200: #fbcfe8; - --color-pink-300: #f9a8d4; - --color-pink-400: #f472b6; - --color-pink-500: #ec4899; - --color-pink-600: #db2777; - --color-pink-700: #be185d; - --color-pink-800: #9d174d; - --color-pink-900: #831843; - --color-pink-950: #500724; - --color-rose-50: #fff1f2; - --color-rose-100: #ffe4e6; - --color-rose-200: #fecdd3; - --color-rose-300: #fda4af; - --color-rose-400: #fb7185; - --color-rose-500: #f43f5e; - --color-rose-600: #e11d48; - --color-rose-700: #be123c; - --color-rose-800: #9f1239; - --color-rose-900: #881337; - --color-rose-950: #4c0519; - /* End: Colors from Tailwind CSS */ -} \ No newline at end of file diff --git a/elevators.js b/elevators.js index 4908cfb..466f760 100644 --- a/elevators.js +++ b/elevators.js @@ -1,120 +1,188 @@ -const internalData = { - lastUpdate: 0, - stations: [], -}; -let geolocationPermission = false; -let geolocation = null; -const openStations = new Set(); -let sortByDistance = false; - -const substituteData = [ - { - name: 'Borgweg (Stadtpark)', - coordinates: [53.5907696, 10.0147719], +Object.defineProperty(String.prototype, 'capitalize', { + value: function () { + return this.charAt(0).toUpperCase() + this.toLowerCase().slice(1); }, - { - name: 'Emilienstraße', - coordinates: [53.5716862, 9.9525424], - }, - { - name: 'Garstedt', - coordinates: [53.6844739, 9.9860415], - }, - { - name: 'Hagenbecks Tierpark', - coordinates: [53.5925874, 9.9440359], - }, - { - name: 'Hamburg Hbf', - searchTarget: "Hauptbahnhof", - }, - { - name: 'Jungfernstieg', - searchTarget: "Rathaus", - }, - { - name: 'Rathaus', - searchTarget: "Jungfernstieg", - }, - { - name: 'Stephansplatz (Oper/CCH)', - searchTarget: "Dammtor (Messe/CCH)", - }, - { - name: 'Dammtor (Messe/CCH)', - searchTarget: "Stephansplatz (Oper/CCH)", - }, - { - name: 'Hauptbahnhof Nord', - coordinates: [53.5541197, 10.0061270], - }, - { - name: 'Hoheneichen', - coordinates: [53.6355141, 10.0677176], - }, - { - name: 'Kornweg (Klein Borstel)', - coordinates: [53.6324430, 10.0541722], - }, - { - name: 'Lauenbrück', - coordinates: [53.1971209, 9.5640765], - }, - { - name: 'Lutterothstraße', - coordinates: [53.5819938, 9.9476215], - }, - { - name: 'Meckelfeld', - coordinates: [53.4248897, 10.0291223], - }, - { - name: 'Sengelmannstraße (City Nord)', - coordinates: [53.6093953, 10.0220004], - }, - { - name: 'St.Pauli', - coordinates: [53.5507957, 9.9700752], - }, - { - name: 'Winsen(Luhe)', - coordinates: [53.3534304, 10.2086841], - }, -] + enumerable: false +}); async function loadElevators() { - document.querySelector('#errorMessage').classList.add('hidden'); - const res = await fetch('https://www.hvv.de/elevators', { - referrer: "", - }).catch(e => { - document.querySelector('#errorMessage').classList.remove('hidden'); - }); + const res = await fetch('https://www.hvv.de/elevators', {referrer: ""}); const data = await res.json(); + localStorage.setItem("elevator_data", JSON.stringify(data)); +} - const stations = data['stations']; - stations.sort(sortStations); - internalData.lastUpdate = new Date(data['lastUpdate']); +const dateTimeStyle = new Intl.DateTimeFormat('de-DE', { + dateStyle: 'medium', + timeStyle: 'medium', + timeZone: 'Europe/Berlin', +}) + +const internalData = [] +let geolocationPermission = false; +let geolocation = [null, null]; + +async function loadOsmData() { + const elevatorNodes = document.querySelectorAll('.elevator'); + for (const elevator of elevatorNodes) { + elevator.querySelector('.osm').insertAdjacentHTML("beforeend", '
loading...
') + + } + + for (const elevator of elevatorNodes) { + const osmContainer = elevator.querySelector('.osmTags'); + const nodeId = elevator.querySelector('.osm').dataset.nodeid; + const osmData = await fetch(`https://overpass-api.de/api/interpreter?data=[out:json];node(${nodeId});out%20body;`, {}); + const responseData = await osmData.json(); + + if (responseData.elements.length) { + const node = responseData.elements[0]; + const tags = node['tags']; + console.log(tags) + if (tags['highway'] === 'elevator') { + let osmTemplate = ''; + osmTemplate += `
Link zur Karte
+Auf Karte anzeigen +
`; + if (tags.hasOwnProperty('description')) { + osmTemplate += `
Beschreibung
${tags['description']}
`; + } + if (tags.hasOwnProperty('level')) { + osmTemplate += `
Ebenen
${tags['level'].split(';').sort().join(', ')}
`; + } + if (tags.hasOwnProperty('wheelchair')) { + osmTemplate += `
Rollstühle
${tags['wheelchair'] === 'yes' ? 'Ja' : 'Nein'}
`; + } + if (tags.hasOwnProperty('bicycle')) { + osmTemplate += `
Fahrräder
${tags['bicycle'] === 'yes' ? 'Ja' : 'Nein'}
`; + } + osmContainer.innerHTML = ''; // clear loading state + osmContainer.insertAdjacentHTML('beforeend', osmTemplate); + } + + } + } +} + +function distance([lat1, lon1], [lat2, lon2]) { + if (!lat1 || !lat2 || !lon1 || !lon2) return null + const R = 6371e3; // metres + const phi1 = lat1 * Math.PI / 180; // φ, λ in radians + const phi2 = lat2 * Math.PI / 180; + const dPhi = (lat2 - lat1) * Math.PI / 180; + const dLambda = (lon2 - lon1) * Math.PI / 180; + + const a = Math.sin(dPhi / 2) * Math.sin(dPhi / 2) + + Math.cos(phi1) * Math.cos(phi2) * + Math.sin(dLambda / 2) * Math.sin(dLambda / 2); + const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + + return R * c; // in metres +} + +function registerGeolocationWatcher() { + navigator.geolocation.watchPosition((pos) => { + geolocation = [pos.coords.latitude, pos.coords.longitude] + }, (e) => { + console.log(e) + }, { + enableHighAccuracy: true, + timeout: 5000, + maximumAge: 0, + }) +} + +function checkGeolocationPermission() { + navigator.permissions.query({name: "geolocation"}).then((result) => { + geolocationPermission = result.state + if (result.state === 'granted') { + registerGeolocationWatcher() + } + }); +} + +function allowGeolocation() { + navigator.geolocation.getCurrentPosition(() => { + console.log('success') + }, () => { + console.log('error') + }); + + checkGeolocationPermission() + registerGeolocationWatcher() +} + +checkGeolocationPermission() + +document.querySelector('#stationsNearMe').addEventListener('click', allowGeolocation) + +function sortStations(stationA, stationB) { + const nameA = stationA.mainSubStation.stationName.toUpperCase(); // ignore upper and lowercase + const nameB = stationB.mainSubStation.stationName.toUpperCase(); // ignore upper and lowercase + if (nameA < nameB) { + return -1; + } + if (nameA > nameB) { + return 1; + } + + // names must be equal + return 0; +} + +function getType(line) { + const type = line.replace(/[^A-z]/g, ""); + switch (type) { + case 'RE': + case 'RB': + case 'R': + case 'DB': + return 'R'; + case 'S': + return 'S'; + case 'U': + return 'U'; + case 'A': + return 'A'; + } +} + +function getTypes(lines) { + const types = new Set(); + for (const line of lines) { + types.add(getType(line)) + } + return types; +} + +function renderData() { + const data = JSON.parse(localStorage.getItem("elevator_data")); + + if (!data) { + console.error('No Data available!') + return; + } + + let stations = data.stations; + stations.sort(sortStations) + const date = new Date(data.lastUpdate); + + document.querySelector('#loadElevators').innerHTML = 'Daten aktualisieren'; + const listContainer = document.querySelector('#stationList'); + const dateContainer = document.querySelector('#lastUpdated'); + + dateContainer.innerHTML = dateTimeStyle.format(date); let stationIndex = 0; - for (const station of stations) { - const stationName = station['mainSubStation']['stationName']; - const stationComment = station['mainSubStation']['comment']; - let searchTarget = undefined; - - const substitute = substituteData.filter(subs => subs.name === stationName) - - if (substitute.length && substitute[0].hasOwnProperty('searchTarget')) { - searchTarget = substitute[0].searchTarget; - } + const stationName = station.mainSubStation.stationName; const lines = new Set(); const elevators = []; for (const elevatorKey of Object.keys(station.elevators)) { const elevatorApi = station.elevators[elevatorKey]; const elevatorLines = []; for (let line of elevatorApi.lines) { - line = line.replace(/[()]/g, ""); + line = line.replace(/[\(\)]/g, ""); lines.add(line); elevatorLines.push({ line: line, @@ -154,320 +222,19 @@ async function loadElevators() { elevators.push(elevator); } + const stationTypes = getTypes(Array.from(lines)); + + let elevatorsTemplate = ''; + let previewTemplate = ''; let stationState = { unavailable: 0, working: 0, outOfOrder: 0, } - for (const elevator of elevators) { - if (elevator.stateUnavailable) { - stationState.unavailable++; - } else if (elevator.working) { - stationState.working++; - } else { - stationState.outOfOrder++; - } - } - - const stationLines = Array.from(lines); - const stationTypes = Array.from(getTypes(stationLines)); - - internalData.stations[stationIndex++] = { - name: stationName, - comment: stationComment, - searchTarget: searchTarget, - state: stationState, - lines: stationLines, - types: stationTypes, - elevators: elevators, - } - } - - localStorage.setItem("internal_data", JSON.stringify({ - api: minorVersion, - ...internalData - })); -} - -async function loadOsmData() { - const nodeIdList = []; - for (const station of internalData.stations) { - for (const elevator of station.elevators) { - nodeIdList.push(elevator.osmNodeId) - } - } - - const osmResponse = await fetch(`https://overpass-api.de/api/interpreter?data=[out:json];node(id:${nodeIdList.join(',')});out%20body;`, {}); - const osmJson = await osmResponse.json(); - - if (!osmJson.hasOwnProperty('elements')) return; - - const osmNodes = {}; - for await (const node of osmJson.elements) { - if (node.hasOwnProperty('tags')) { - const tags = node['tags']; - if (tags['highway'] === 'elevator') { - osmNodes[node['id']] = node; - } else { - console.warn(`OSM Node is not an elevator. (NodeID: ${node['id']})`); - } - } else { - console.warn(`OSM Node has no Tags. (NodeID: ${node['id']})`); - } - } - - //update coordinates in stations - for (const stationIndex in internalData.stations) { - const station = internalData.stations[stationIndex]; - for (const elevator of station.elevators) { - const node = osmNodes[elevator.osmNodeId] - if (node) { - internalData.stations[stationIndex]['coordinates'] = [ - node['lat'], - node['lon'], - ] - } - } - - if (!internalData.stations[stationIndex].hasOwnProperty('coordinates')) { - const substitute = substituteData.filter(subs => subs.name === internalData.stations[stationIndex].name) - console.log(substitute) - if (substitute.length && substitute[0].hasOwnProperty('coordinates')) { - internalData.stations[stationIndex]['coordinates'] = substitute[0].coordinates; - } - } - } - - localStorage.setItem("osm_data", JSON.stringify({ - api: minorVersion, - lastUpdate: new Date(), - nodes: osmNodes - })); - localStorage.setItem("internal_data", JSON.stringify({ - api: minorVersion, - ...internalData - })); -} - -function distance([lat1, lon1], [lat2, lon2]) { - if (!lat1 || !lat2 || !lon1 || !lon2) return null - const R = 6371e3; // metres - const phi1 = lat1 * Math.PI / 180; // φ, λ in radians - const phi2 = lat2 * Math.PI / 180; - const dPhi = (lat2 - lat1) * Math.PI / 180; - const dLambda = (lon2 - lon1) * Math.PI / 180; - - const a = Math.sin(dPhi / 2) * Math.sin(dPhi / 2) + - Math.cos(phi1) * Math.cos(phi2) * - Math.sin(dLambda / 2) * Math.sin(dLambda / 2); - const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); - - return R * c; // in metres -} - -function registerGeolocationWatcher() { - navigator.geolocation.watchPosition((pos) => { - if (geolocation === null) { - geolocation = [pos.coords.latitude, pos.coords.longitude]; - renderData(geolocation); - } - }, (e) => { - console.warn(e) - }, { - enableHighAccuracy: true, - timeout: 5000, - maximumAge: 0, - }) -} - -function checkGeolocationPermission() { - navigator.permissions.query({name: "geolocation"}).then((result) => { - geolocationPermission = result.state - if (result.state === 'granted') { - registerGeolocationWatcher() - } - }); -} - -function allowGeolocation() { - navigator.geolocation.getCurrentPosition(() => { - console.log('success') - }, () => { - console.log('error') - }); - - checkGeolocationPermission() - registerGeolocationWatcher() -} - -checkGeolocationPermission() - -function sortStations(stationA, stationB) { - const nameA = stationA.mainSubStation.stationName.toUpperCase(); // ignore upper and lowercase - const nameB = stationB.mainSubStation.stationName.toUpperCase(); // ignore upper and lowercase - if (nameA < nameB) { - return -1; - } - if (nameA > nameB) { - return 1; - } - - // names must be equal - return 0; -} - -function sortInt(valueA, valueB) { - const a = parseInt(valueA) - const b = parseInt(valueB) - if (a < b) { - return -1; - } - if (a > b) { - return 1; - } - - // names must be equal - return 0; -} - -function sortStationsByDistance(stationA, stationB) { - const distanceA = stationA.distance ?? 0; // ignore upper and lowercase - const distanceB = stationB.distance ?? 0; // ignore upper and lowercase - if (distanceA < distanceB) { - return -1; - } - if (distanceA > distanceB) { - return 1; - } - - // names must be equal - return 0; -} - -function getType(line) { - const type = line.replace(/[^A-z]/g, ""); - switch (type) { - case 'RE': - case 'RB': - case 'R': - case 'DB': - return 'R'; - case 'S': - return 'S'; - case 'U': - return 'U'; - case 'A': - return 'A'; - } -} - -function getTypes(lines) { - const types = new Set(); - for (const line of lines) { - types.add(getType(line)) - } - return types; -} - -function renderData(location = null) { - const ls = JSON.parse(localStorage.getItem("internal_data")); - if (!ls) return; - internalData.lastUpdate = ls['lastUpdate']; - internalData.stations = ls['stations']; - const osmData = JSON.parse(localStorage.getItem("osm_data")); - - if (!internalData || !internalData.stations.length) { - console.error('No Data available!') - return; - } - - if ( - location !== null - && ( - location.length !== 2 - || typeof location[0] !== 'number' - || typeof location[1] !== 'number' - ) - ) { - console.error('No valid location provided') - return; - } - - document.querySelector('#updateInfo').classList.remove('hidden'); - document.querySelector('#loadElevators').classList.remove('hidden'); - document.querySelector('#filters').classList.remove('hidden'); - document.querySelector('#initialLoad').classList.add('hidden'); - const dateContainer = document.querySelector('#lastUpdated'); - const oldDataWarning = document.querySelector('#oldDataWarning'); - - const lastUpdate = new Date(internalData.lastUpdate); - const now = new Date(); - dateContainer.innerHTML = dateTimeStyle.format(lastUpdate); - oldDataWarning.classList.add('hidden'); - if (now - lastUpdate > 86400 * 1000) { - const days = numberFormat.format((now - lastUpdate) / (86400 * 1000)); - oldDataWarning.classList.remove('hidden'); - oldDataWarning.innerHTML = `Daten ${days} Tag${days !== '1' ? 'e' : ''} alt!`; - } - - const listContainer = document.querySelector('#stationList'); - //clear list before update - listContainer.innerHTML = ''; - - let stations = [...internalData['stations']]; - - for (const stationIndex in stations) { - const station = stations[stationIndex]; - station.id = stationIndex; - - if (location !== null) { - if (station.hasOwnProperty('coordinates')) { - station.distance = distance(location, station.coordinates); - } else { - console.log('station has no position:', station.name); - } - } - } - - if (sortByDistance) { - stations = stations.sort(sortStationsByDistance); - } - - for (const stationIndex in stations) { - const station = stations[stationIndex]; - - if (location !== null) { - if (station.hasOwnProperty('coordinates')) { - station.distance = distance(location, station.coordinates); - } else { - console.log('station has no position:', station.name); - } - } - - let elevatorsTemplate = ''; - let previewTemplate = ''; - - for (const elevator of station.elevators) { - const stateTemplate = ` - `; - - let linesTemplate = ''; - linesTemplate = `
${stateTemplate}`; - if (elevator.lines.length) { - linesTemplate = `
${stateTemplate}`; - linesTemplate += `
Linien: `; - for (const line of elevator.lines) { - linesTemplate += `${line.line}`; - } - linesTemplate += '
'; + let linesTemplate = '
Linien: '; + for (const line of elevator.lines) { + linesTemplate += `${line.line}`; } linesTemplate += '
'; @@ -477,49 +244,28 @@ function renderData(location = null) { } levelsTemplate += ''; - let osmTemplate = ''; - if (osmData) { - const node = osmData.nodes[elevator.osmNodeId] - if (node) { - - osmTemplate = '
'; - osmTemplate += `
-
Link zur Karte
-
- - Auf Karte anzeigen - -
-
`; - if (node.tags.hasOwnProperty('description')) { - osmTemplate += `
Beschreibung
${node.tags['description']}
`; - } - if (node.tags.hasOwnProperty('level')) { - osmTemplate += `
Ebenen
${node.tags['level'].split(';').sort(sortInt).join(', ')}
`; - } - if (node.tags.hasOwnProperty('wheelchair')) { - osmTemplate += `
Rollstühle
${node.tags['wheelchair'] === 'yes' ? 'Ja' : 'Nein'}
`; - } - if (node.tags.hasOwnProperty('bicycle')) { - osmTemplate += `
Fahrräder
${node.tags['bicycle'] === 'yes' ? 'Ja' : 'Nein'}
`; - } - - osmTemplate += '
'; - } else { - console.warn(`OSM Node not found (deleted). At:\t${station.name}\t${elevator.label} (NodeID: ${elevator.osmNodeId})`); - } - } else { - console.warn(`Elevator has no OSM Node id:\t${station.name}\t${elevator}`); - } - - previewTemplate += `` + if (elevator.stateUnavailable) { + stationState.unavailable++; + } else if (elevator.working) { + stationState.working++; + } else { + stationState.outOfOrder++; + } + elevatorsTemplate += `
  • - ${stateTemplate} + +
    - ${linesTemplate} ${elevator.instCause !== '' ? `
    ${elevator.instCause}
    ` : ''} ${elevator.levels.length ? levelsTemplate : elevator.description}
    @@ -544,202 +290,74 @@ function renderData(location = null) {
    ${elevator.speaker === -1 ? 'unbekannt' : elevator.speaker ? `verfügbar` : 'nicht verfügbar'}
    - - ${osmTemplate ? `
    -
    -

    Daten von OpenStreetMap

    - -
    - ${osmTemplate} -
    ` : ``} + ${elevator.lines.length ? `${linesTemplate}` : ''} +
    +

    Daten von OpenStreetMap

    +
  • `; } - const template = `
  • + const template = `
  • -
    - ${station.types.sort().map(t => `${t}`).join('')} -
    - ${sortByDistance - ? typeof station.distance !== 'undefined' - ? `
    ${Math.round(station.distance / 100) / 10}
    km
    ` - : '
    ? km
    ' - : ''} + ${Array.from(stationTypes).sort().map(t => `${t}`).join('')}
    -

    ${station.name}

    +

    ${stationName}

    -
    +
    - Details / Aufzüge anzeigen + Aufzüge anzeigen - ${station.comment ? `

    ${station.comment}

    ` : ''} -
  • `; listContainer.insertAdjacentHTML('beforeend', template); - //immediate invocation - (function () { - listContainer.querySelectorAll(`#station_${station.id} .loadOSM`).forEach(e => { - e.addEventListener('click', (ev) => { - ev.target.querySelector('.spinner').classList.remove('hidden'); - loadOsmData().then(() => { - ev.target.classList.add('hidden'); - renderData(); - }); - }) - }) - }()); + // immediate invocation + // (function () { + // const stationId = stationIndex; + // listContainer.querySelector(`#station_${stationIndex}`) + // .addEventListener('click', () => toggleElevatorList(stationId)) + // }()); + + internalData[stationIndex++] = { + name: stationName, + state: stationState, + elevators: elevators, + } } - - listContainer.insertAdjacentHTML('beforeend', `
  • -0 von 0 Stationen durch Filter ausgeblendet. -
  • `); - - listContainer.querySelectorAll(`details`).forEach(e => { - e.addEventListener("toggle", (event) => { - const stationId = event.target.dataset['stationid']; - if (event.target.open) { - openStations.add(stationId); - } else { - openStations.delete(stationId); - } - }); - }) - - filterData(); } document.querySelector('#loadElevators') .addEventListener('click', (e) => { - e.target.querySelector('.spinner').classList.remove('hidden'); - loadElevators().then(() => { - e.target.querySelector('.spinner').classList.add('hidden'); - renderData(); - }); + loadElevators().then(() => renderData()); }) -document.querySelector('#initialLoad') - .addEventListener('click', (e) => { - e.target.querySelector('.spinner').classList.remove('hidden'); - loadElevators().then(() => { - e.target.classList.add('hidden'); - renderData(); - }); - }) - -document.querySelector('#loadOsm') - .addEventListener('click', (e) => { - e.target.querySelector('.spinner').classList.remove('hidden'); - loadOsmData().then(() => { - e.target.querySelector('.spinner').classList.add('hidden'); - renderData(); - closeDialog('#dialog_osm'); - }); - }) - -document.querySelector('#stationsNearMe') - .addEventListener('click', async (e) => { - e.target.querySelector('.spinner').classList.remove('hidden'); - if (!sortByDistance) { - if (JSON.parse(localStorage.getItem("osm_data")) === null) { - openDialog('#dialog_osm'); - } else { - if (geolocationPermission !== 'granted') { - allowGeolocation(); - } else { - sortByDistance = e.target.ariaPressed = true; - - // If geolocation is already set. - // If not the location watcher will re-render our data. - if (geolocation !== null) { - renderData(geolocation) - } - } - } - } else { - sortByDistance = e.target.ariaPressed = false; - - renderData(); - } - e.target.querySelector('.spinner').classList.add('hidden'); - }) +renderData(); -function filterData() { - const searchString = document.querySelector('#searchStation').value; - const typeU = document.querySelector('button.typeChip[data-type="U"]'); - const typeS = document.querySelector('button.typeChip[data-type="S"]'); - const typeA = document.querySelector('button.typeChip[data-type="A"]'); - const typeR = document.querySelector('button.typeChip[data-type="R"]'); - const activeTypes = []; - if (typeU.dataset.pressed === 'true') activeTypes.push('U'); - if (typeS.dataset.pressed === 'true') activeTypes.push('S'); - if (typeA.dataset.pressed === 'true') activeTypes.push('A'); - if (typeR.dataset.pressed === 'true') activeTypes.push('R'); - const stationCount = internalData.stations.length; - let filteredStations = 0; - if (internalData) { - for (const stationIndex in internalData.stations) { - const matchesName = internalData.stations[stationIndex].name.toLowerCase().search(searchString.toLowerCase()) >= 0; - const matchesSearchTarget = internalData.stations[stationIndex].hasOwnProperty('searchTarget') - ? internalData.stations[stationIndex].searchTarget.toLowerCase().search(searchString.toLowerCase()) >= 0 - : false; - let matchesType = false; - internalData.stations[stationIndex].types.forEach(type => { - if (activeTypes.includes(type)) matchesType = true; - }) - const filtered = !((matchesName || matchesSearchTarget) && matchesType); - document.querySelector(`#station_${stationIndex}`).classList.toggle('hidden', filtered); - if (filtered) filteredStations++; - } +function filterData(searchString) { + for (const stationIndex in internalData) { + const matches = internalData[stationIndex].name.toLowerCase().search(searchString.toLowerCase()) >= 0; + document.querySelector(`#station_${stationIndex}`).classList.toggle('hidden', !matches); - document.querySelector('#stationCount').innerHTML = stationCount; - document.querySelector('#filteredCount').innerHTML = filteredStations; } } document.querySelector('#searchStation').addEventListener('input', (e) => { - filterData(); + filterData(e.target.value); }) -document.querySelectorAll('button.typeChip').forEach(e => { - e.addEventListener('click', (event) => { - e.ariaPressed = e.dataset.pressed = e.dataset.pressed === 'true' ? 'false' : 'true'; - filterData(); - }) -}) - -// data api version check -const check_internal = JSON.parse(localStorage.getItem("internal_data")); -const check_osm = JSON.parse(localStorage.getItem("osm_data")); -if (check_internal === null || check_internal.hasOwnProperty('api') && check_internal.api === minorVersion) { - if (check_osm === null || check_osm.hasOwnProperty('api') && check_osm.api === minorVersion) { - renderData(); - } else { - console.log('osm_data: version mismatch') - localStorage.removeItem('osm_data'); - } -} else { - console.log('internal_data: version mismatch') - localStorage.removeItem('internal_data'); -} +filterData(document.querySelector('#searchStation').value) \ No newline at end of file diff --git a/icons/192.png b/icons/192.png deleted file mode 100644 index a329713..0000000 Binary files a/icons/192.png and /dev/null differ diff --git a/icons/512-maskable.png b/icons/512-maskable.png deleted file mode 100644 index 6122f35..0000000 Binary files a/icons/512-maskable.png and /dev/null differ diff --git a/icons/512-transparent.png b/icons/512-transparent.png deleted file mode 100644 index c6eed8c..0000000 Binary files a/icons/512-transparent.png and /dev/null differ diff --git a/icons/512.png b/icons/512.png deleted file mode 100644 index 79acdc4..0000000 Binary files a/icons/512.png and /dev/null differ diff --git a/icons/favicon-maskable.svg b/icons/favicon-maskable.svg deleted file mode 100644 index cb8cda2..0000000 --- a/icons/favicon-maskable.svg +++ /dev/null @@ -1,58 +0,0 @@ - - - - diff --git a/icons/favicon-transparent.svg b/icons/favicon-transparent.svg deleted file mode 100644 index dcea345..0000000 --- a/icons/favicon-transparent.svg +++ /dev/null @@ -1,55 +0,0 @@ - - - - diff --git a/icons/favicon.ico b/icons/favicon.ico deleted file mode 100644 index 29e9f5e..0000000 Binary files a/icons/favicon.ico and /dev/null differ diff --git a/icons/favicon.svg b/icons/favicon.svg deleted file mode 100644 index 4222b18..0000000 --- a/icons/favicon.svg +++ /dev/null @@ -1,58 +0,0 @@ - - - - diff --git a/icons/favicon_source.svg b/icons/favicon_source.svg deleted file mode 100644 index 028ef75..0000000 --- a/icons/favicon_source.svg +++ /dev/null @@ -1,85 +0,0 @@ - - - - diff --git a/images/screenshot-desktop.png b/images/screenshot-desktop.png deleted file mode 100644 index 4856c04..0000000 Binary files a/images/screenshot-desktop.png and /dev/null differ diff --git a/images/screenshot-mobile.png b/images/screenshot-mobile.png deleted file mode 100644 index 2856686..0000000 Binary files a/images/screenshot-mobile.png and /dev/null differ diff --git a/index.html b/index.html index 2099374..5df658a 100644 --- a/index.html +++ b/index.html @@ -6,96 +6,43 @@ content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> - - - - - - hvvstuhl.de + A11y Elevator List -

    Barrierefreie Aufzugs-Liste

    +

    A11y Elevator List

    -

    Liste aller Stationen mit Aufzug im HVV

    -
    - - -
    - -
    - \ No newline at end of file diff --git a/main.js b/main.js deleted file mode 100644 index dff3f0b..0000000 --- a/main.js +++ /dev/null @@ -1,51 +0,0 @@ -const version = '0.6.4' -const minorVersion = version.split('.').splice(0, 2).join('.'); -const numberFormat = new Intl.NumberFormat('de-DE', { - maximumFractionDigits: 1 -}); - -Object.defineProperty(String.prototype, 'capitalize', { - value: function () { - return this.charAt(0).toUpperCase() + this.toLowerCase().slice(1); - }, - enumerable: false -}); - -const dateTimeStyle = new Intl.DateTimeFormat('de-DE', { - dateStyle: 'medium', - timeStyle: 'medium', - timeZone: 'Europe/Berlin', -}) - -// set version -document.querySelector('#version').innerHTML = `v${version}`; - - -function openDialog(selector) { - document.querySelector('body').classList.add('has-dialog') - document.querySelector('#dialog_layer').classList.add('active') - document.querySelector(selector).classList.remove('hidden') -} - -function closeDialog(selector) { - document.querySelector('body').classList.remove('has-dialog') - document.querySelector('#dialog_layer').classList.remove('active') - document.querySelector(selector).classList.add('hidden') -} - -if ("serviceWorker" in navigator) { - navigator.serviceWorker.register("/sw.js") - .then((registration) => { - if (registration.installing) { - console.log('New Service Worker is installing...'); - } else if (registration.waiting) { - console.log('Installed new service worker. Waiting for Update (up to 24h).'); - } else if (registration.active) { - console.log('Service Worker is up to date.'); - } - }) - .catch((error) => { - // registration failed - console.error(`Registration failed with ${error}`); - }); -} diff --git a/manifest.json b/manifest.json deleted file mode 100644 index 662cd51..0000000 --- a/manifest.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "hvvstuhl.de", - "short_name": "hvvstuhl", - "start_url": ".", - "display": "standalone", - "background_color": "#030712", - "theme_color": "#65a30d", - "description": "Barrierefreie Aufzugs-Liste", - "icons": [ - { - "src": "/icons/192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "/icons/512.png", - "sizes": "512x512", - "type": "image/png" - }, - { - "src": "/icons/512-maskable.png", - "sizes": "512x512", - "type": "image/png", - "purpose": "maskable" - }, - { - "src": "/icons/512-transparent.png", - "sizes": "512x512", - "type": "image/png", - "purpose": "monochrome" - } - ], - "screenshots" : [ - { - "src": "images/screenshot-mobile.png", - "sizes": "430x900", - "type": "image/png", - "form_factor": "narrow", - "label": "Stationsliste" - }, - { - "src": "images/screenshot-desktop.png", - "sizes": "1280x720", - "type": "image/png", - "form_factor": "wide", - "label": "Stationsliste" - } - ] -} diff --git a/md_icons/close.svg b/md_icons/close.svg deleted file mode 100644 index 555e083..0000000 --- a/md_icons/close.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/md_icons/load.svg b/md_icons/load.svg deleted file mode 100644 index 3a1bc93..0000000 --- a/md_icons/load.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/style.css b/style.css index 331675e..e308c41 100644 --- a/style.css +++ b/style.css @@ -1,307 +1,31 @@ :root { - /* Colors from Tailwind CSS: https://github.com/tailwindlabs/tailwindcss - - MIT License - - Copyright (c) Tailwind Labs, Inc. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ - --color-black: #000; - --color-white: #fff; - --color-slate-50: #f8fafc; - --color-slate-100: #f1f5f9; - --color-slate-200: #e2e8f0; - --color-slate-300: #cbd5e1; - --color-slate-400: #94a3b8; - --color-slate-500: #64748b; - --color-slate-600: #475569; - --color-slate-700: #334155; - --color-slate-800: #1e293b; - --color-slate-900: #0f172a; - --color-slate-950: #020617; - --color-gray-50: #f9fafb; - --color-gray-100: #f3f4f6; - --color-gray-200: #e5e7eb; - --color-gray-300: #d1d5db; - --color-gray-400: #9ca3af; - --color-gray-500: #6b7280; - --color-gray-600: #4b5563; - --color-gray-700: #374151; - --color-gray-800: #1f2937; - --color-gray-900: #111827; - --color-gray-950: #030712; - --color-zinc-50: #fafafa; - --color-zinc-100: #f4f4f5; - --color-zinc-200: #e4e4e7; - --color-zinc-300: #d4d4d8; - --color-zinc-400: #a1a1aa; - --color-zinc-500: #71717a; - --color-zinc-600: #52525b; - --color-zinc-700: #3f3f46; - --color-zinc-800: #27272a; - --color-zinc-900: #18181b; - --color-zinc-950: #09090b; - --color-neutral-50: #fafafa; - --color-neutral-100: #f5f5f5; - --color-neutral-200: #e5e5e5; - --color-neutral-300: #d4d4d4; - --color-neutral-400: #a3a3a3; - --color-neutral-500: #737373; - --color-neutral-600: #525252; - --color-neutral-700: #404040; - --color-neutral-800: #262626; - --color-neutral-900: #171717; - --color-neutral-950: #0a0a0a; - --color-stone-50: #fafaf9; - --color-stone-100: #f5f5f4; - --color-stone-200: #e7e5e4; - --color-stone-300: #d6d3d1; - --color-stone-400: #a8a29e; - --color-stone-500: #78716c; - --color-stone-600: #57534e; - --color-stone-700: #44403c; - --color-stone-800: #292524; - --color-stone-900: #1c1917; - --color-stone-950: #0c0a09; - --color-red-50: #fef2f2; - --color-red-100: #fee2e2; - --color-red-200: #fecaca; - --color-red-300: #fca5a5; - --color-red-400: #f87171; - --color-red-500: #ef4444; - --color-red-600: #dc2626; - --color-red-700: #b91c1c; - --color-red-800: #991b1b; - --color-red-900: #7f1d1d; - --color-red-950: #450a0a; - --color-orange-50: #fff7ed; - --color-orange-100: #ffedd5; - --color-orange-200: #fed7aa; - --color-orange-300: #fdba74; - --color-orange-400: #fb923c; - --color-orange-500: #f97316; - --color-orange-600: #ea580c; - --color-orange-700: #c2410c; - --color-orange-800: #9a3412; - --color-orange-900: #7c2d12; - --color-orange-950: #431407; - --color-amber-50: #fffbeb; - --color-amber-100: #fef3c7; - --color-amber-200: #fde68a; - --color-amber-300: #fcd34d; - --color-amber-400: #fbbf24; - --color-amber-500: #f59e0b; - --color-amber-600: #d97706; - --color-amber-700: #b45309; - --color-amber-800: #92400e; - --color-amber-900: #78350f; - --color-amber-950: #451a03; - --color-yellow-50: #fefce8; - --color-yellow-100: #fef9c3; - --color-yellow-200: #fef08a; - --color-yellow-300: #fde047; - --color-yellow-400: #facc15; - --color-yellow-500: #eab308; - --color-yellow-600: #ca8a04; - --color-yellow-700: #a16207; - --color-yellow-800: #854d0e; - --color-yellow-900: #713f12; - --color-yellow-950: #422006; - --color-lime-50: #f7fee7; - --color-lime-100: #ecfccb; - --color-lime-200: #d9f99d; - --color-lime-300: #bef264; - --color-lime-400: #a3e635; - --color-lime-500: #84cc16; - --color-lime-600: #65a30d; - --color-lime-700: #4d7c0f; - --color-lime-800: #3f6212; - --color-lime-900: #365314; - --color-lime-950: #1a2e05; - --color-green-50: #f0fdf4; - --color-green-100: #dcfce7; - --color-green-200: #bbf7d0; - --color-green-300: #86efac; - --color-green-400: #4ade80; - --color-green-500: #22c55e; - --color-green-600: #16a34a; - --color-green-700: #15803d; - --color-green-800: #166534; - --color-green-900: #14532d; - --color-green-950: #052e16; - --color-emerald-50: #ecfdf5; - --color-emerald-100: #d1fae5; - --color-emerald-200: #a7f3d0; - --color-emerald-300: #6ee7b7; - --color-emerald-400: #34d399; - --color-emerald-500: #10b981; - --color-emerald-600: #059669; - --color-emerald-700: #047857; - --color-emerald-800: #065f46; - --color-emerald-900: #064e3b; - --color-emerald-950: #022c22; - --color-teal-50: #f0fdfa; - --color-teal-100: #ccfbf1; - --color-teal-200: #99f6e4; - --color-teal-300: #5eead4; - --color-teal-400: #2dd4bf; - --color-teal-500: #14b8a6; - --color-teal-600: #0d9488; - --color-teal-700: #0f766e; - --color-teal-800: #115e59; - --color-teal-900: #134e4a; - --color-teal-950: #042f2e; - --color-cyan-50: #ecfeff; - --color-cyan-100: #cffafe; - --color-cyan-200: #a5f3fc; - --color-cyan-300: #67e8f9; - --color-cyan-400: #22d3ee; - --color-cyan-500: #06b6d4; - --color-cyan-600: #0891b2; - --color-cyan-700: #0e7490; - --color-cyan-800: #155e75; - --color-cyan-900: #164e63; - --color-cyan-950: #083344; - --color-sky-50: #f0f9ff; - --color-sky-100: #e0f2fe; - --color-sky-200: #bae6fd; - --color-sky-300: #7dd3fc; - --color-sky-400: #38bdf8; - --color-sky-500: #0ea5e9; - --color-sky-600: #0284c7; - --color-sky-700: #0369a1; - --color-sky-800: #075985; - --color-sky-900: #0c4a6e; - --color-sky-950: #082f49; - --color-blue-50: #eff6ff; - --color-blue-100: #dbeafe; - --color-blue-200: #bfdbfe; - --color-blue-300: #93c5fd; - --color-blue-400: #60a5fa; - --color-blue-500: #3b82f6; - --color-blue-600: #2563eb; - --color-blue-700: #1d4ed8; - --color-blue-800: #1e40af; - --color-blue-900: #1e3a8a; - --color-blue-950: #172554; - --color-indigo-50: #eef2ff; - --color-indigo-100: #e0e7ff; - --color-indigo-200: #c7d2fe; - --color-indigo-300: #a5b4fc; - --color-indigo-400: #818cf8; - --color-indigo-500: #6366f1; - --color-indigo-600: #4f46e5; - --color-indigo-700: #4338ca; - --color-indigo-800: #3730a3; - --color-indigo-900: #312e81; - --color-indigo-950: #1e1b4b; - --color-violet-50: #f5f3ff; - --color-violet-100: #ede9fe; - --color-violet-200: #ddd6fe; - --color-violet-300: #c4b5fd; - --color-violet-400: #a78bfa; - --color-violet-500: #8b5cf6; - --color-violet-600: #7c3aed; - --color-violet-700: #6d28d9; - --color-violet-800: #5b21b6; - --color-violet-900: #4c1d95; - --color-violet-950: #2e1065; - --color-purple-50: #faf5ff; - --color-purple-100: #f3e8ff; - --color-purple-200: #e9d5ff; - --color-purple-300: #d8b4fe; - --color-purple-400: #c084fc; - --color-purple-500: #a855f7; - --color-purple-600: #9333ea; - --color-purple-700: #7e22ce; - --color-purple-800: #6b21a8; - --color-purple-900: #581c87; - --color-purple-950: #3b0764; - --color-fuchsia-50: #fdf4ff; - --color-fuchsia-100: #fae8ff; - --color-fuchsia-200: #f5d0fe; - --color-fuchsia-300: #f0abfc; - --color-fuchsia-400: #e879f9; - --color-fuchsia-500: #d946ef; - --color-fuchsia-600: #c026d3; - --color-fuchsia-700: #a21caf; - --color-fuchsia-800: #86198f; - --color-fuchsia-900: #701a75; - --color-fuchsia-950: #4a044e; - --color-pink-50: #fdf2f8; - --color-pink-100: #fce7f3; - --color-pink-200: #fbcfe8; - --color-pink-300: #f9a8d4; - --color-pink-400: #f472b6; - --color-pink-500: #ec4899; - --color-pink-600: #db2777; - --color-pink-700: #be185d; - --color-pink-800: #9d174d; - --color-pink-900: #831843; - --color-pink-950: #500724; - --color-rose-50: #fff1f2; - --color-rose-100: #ffe4e6; - --color-rose-200: #fecdd3; - --color-rose-300: #fda4af; - --color-rose-400: #fb7185; - --color-rose-500: #f43f5e; - --color-rose-600: #e11d48; - --color-rose-700: #be123c; - --color-rose-800: #9f1239; - --color-rose-900: #881337; - --color-rose-950: #4c0519; - /* End: Colors from Tailwind CSS */ - --bg-type-u: #006ab3; - --bg-type-s: #1a962b; - --bg-type-a: #f39100; - --bg-type-r: #000000; - --bg-type-u-disabled: #c3cfd7; - --bg-type-s-disabled: #c6d4c8; - --bg-type-a-disabled: #dfd8cf; - --bg-type-r-disabled: #b3b3b3; - --color-type-disabled: var(--color-gray-400); - --color-line-U1: #006ab3; - --color-line-U2: #e2001a; - --color-line-U3: #ffdd00; - --color-line-U4: #0098a1; - --color-line-S1: #1a962b; - --color-line-S2: #b51143; - --color-line-S3: #622181; - --color-line-S4: #be148e; - --color-line-S5: #0089bb; - --color-line-S6: #d3da00; + --color-gray-50: hsl(60, 9%, 98%); + --color-gray-100: hsl(60, 5%, 96%); + --color-gray-200: hsl(20, 6%, 90%); + --color-gray-300: hsl(24, 6%, 83%); + --color-gray-400: hsl(24, 5%, 64%); + --color-gray-500: hsl(25, 5%, 45%); + --color-gray-600: hsl(33, 5%, 32%); + --color-gray-700: hsl(30, 6%, 25%); + --color-gray-800: hsl(12, 6%, 15%); + --color-gray-900: hsl(24, 10%, 10%); + --color-gray-950: hsl(20, 14%, 4%); --bg: var(--color-gray-50); --text: var(--color-gray-950); --text-secondary: var(--color-gray-700); - --nav-bg: var(--color-indigo-400); - --nav-bg-hover: var(--color-indigo-200); - --nav-bg-visited: var(--color-purple-400); - --link: var(--color-indigo-600); - --link-hover: var(--color-indigo-800); - --link-visited: var(--color-purple-600); + --nav-bg: hsl(210, 60%, 50%); + --nav-bg-hover: hsl(210, 60%, 30%); + --nav-bg-visited: hsl(250, 60%, 50%); + --nav-text-visited: hsl(250, 60%, 93%); + --nav-text: hsl(210, 60%, 93%); + --link: hsl(210, 60%, 30%); + --link-hover: hsl(210, 60%, 10%); + --link-visited: hsl(250, 60%, 30%); --station-bg: var(--color-gray-50); --station-bg-hover: var(--color-gray-400); --station-border: var(--color-gray-400); --station-border-hover: var(--color-gray-600); --elevator-bg: var(--color-gray-100); - --backdrop: rgb(0 0 0 / 20%); --elevator-list-gap: 3rem; --item-radius: 1.5rem; --btn-radius: 0.8rem; @@ -310,101 +34,45 @@ --space-m: 0.5rem; --space-l: 1rem; --space-xl: 2rem; - --space-2xl: 3rem; } @media (prefers-color-scheme: dark) { :root { - --bg-type-u-disabled: #627f93; - --bg-type-s-disabled: #688b6d; - --bg-type-a-disabled: #aa987f; - --bg-type-r-disabled: #333333; - --color-type-disabled: var(--color-gray-200); --bg: var(--color-gray-950); --text: var(--color-gray-50); --text-secondary: var(--color-gray-400); - --nav-bg: var(--color-indigo-800); - --nav-bg-hover: var(--color-indigo-950); - --nav-bg-visited: var(--color-purple-800); - --link: var(--color-indigo-400); - --link-hover: var(--color-indigo-200); - --link-visited: var(--color-purple-400); + --nav-bg: hsl(210, 60%, 30%); + --nav-bg-hover: hsl(210, 60%, 10%); + --nav-bg-visited: hsl(250, 60%, 30%); + --link: hsl(210, 60%, 60%); + --link-hover: hsl(210, 60%, 60%); + --link-visited: hsl(250, 60%, 70%); --station-bg: var(--color-gray-950); --station-bg-hover: var(--color-gray-600); --station-border: var(--color-gray-600); --station-border-hover: var(--color-gray-400); --elevator-bg: var(--color-gray-900); - --backdrop: rgb(100% 100% 100% / 20%); } } -body.has-dialog { - overflow: hidden; -} - -.dialogs { - display: none; - position: fixed; - overflow-y: auto; - max-width: 100vw; - padding: 1em; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 99; - background: var(--backdrop); -} -.dialogs.active { - display: block; -} -.dialogs [role=dialog] { - box-sizing: border-box; - max-width: 800px; - margin: 0 auto; - padding: var(--space-xl); - padding-bottom: var(--space-2xl); - background-color: var(--bg); - color: var(--text); - overflow: hidden; - position: absolute; - right: 0; - bottom: 0; - left: 0; - border-radius: var(--item-radius) var(--item-radius) 0 0; -} -@media screen and (min-width: 576px) { - .dialogs [role=dialog] { - position: relative; - border-radius: var(--item-radius); - } -} -.dialogs [role=dialog] button.close-modal { - position: absolute; - top: 0; - right: 0; - border-radius: 0 0 0 var(--btn-radius); - border: none; -} - .hidden { - display: none !important; + display: none; } .text-red { - color: var(--color-red-800); + color: #e32d2d; } .text-orange { - color: var(--color-orange-500); + color: #cc6300; } .text-green { - color: var(--color-green-600); + color: #19942e; } body { font-family: system-ui, ui-sans-serif, sans-serif; - font-size: 1rem; + font-size: 1.2rem; background-color: var(--bg); color: var(--text); } @@ -417,7 +85,7 @@ a { color: var(--link); text-decoration: none; } -a:hover, a:visited:hover { +a:hover { text-decoration: underline; color: var(--link-hover); } @@ -435,18 +103,18 @@ nav ul { } nav ul li a { font-weight: bold; - color: var(--text); + color: var(--nav-text); text-decoration: none; background-color: var(--nav-bg); padding: var(--space-m) var(--space-l); cursor: pointer; } -nav ul li a:hover, nav ul li a:visited:hover { +nav ul li a:hover { text-decoration: underline; background-color: var(--nav-bg-hover); } nav ul li a:visited { - color: var(--text); + color: var(--nav-text-visited); background-color: var(--nav-bg-visited); } @@ -455,13 +123,6 @@ main { max-width: 960px; } -footer { - display: flex; - justify-content: center; - margin: 1em auto; - max-width: 960px; -} - button, input { background-color: var(--station-bg); color: var(--text); @@ -472,7 +133,7 @@ button, input { button { cursor: pointer; - display: inline-flex; + display: flex; align-items: center; gap: var(--space-m); } @@ -480,124 +141,13 @@ button:hover { background-color: var(--station-bg-hover); border-color: var(--station-border-hover); } -button[aria-pressed=true] { - background-color: var(--nav-bg-visited); -} -button.size-s { - font-size: 0.8rem; - padding: var(--space-s) var(--space-m); -} -button.size-m { - padding: var(--space-m) var(--space-l); -} -button.size-l { - font-size: 1.5rem; - padding: var(--space-m) var(--space-l); -} -div#updateInfo { +div.filters { display: flex; - align-items: center; gap: var(--space-m); - justify-content: end; - flex-direction: column; - margin-bottom: var(--space-l); + justify-items: stretch; } -@media screen and (min-width: 576px) { - div#updateInfo { - flex-direction: row; - } -} -div#updateInfo #oldDataWarning { - color: var(--color-red-600); - font-weight: bold; -} - -div#filters { - display: flex; - flex-wrap: wrap; - gap: var(--space-m); - justify-content: center; -} -div#filters > * { - width: 100%; - justify-content: center; - text-align: center; -} -@media screen and (min-width: 576px) { - div#filters > * { - width: auto; - min-width: 0; - } -} -div#filters input#searchStation { - flex-grow: 1; - font-size: 1.5rem; - min-width: 10ch; -} -div#filters button#stationsNearMe { - font-size: 1.5rem; -} -div#filters div#typeFilter { - font-size: 1.5rem; - display: flex; - justify-content: center; - flex-shrink: 0; - min-height: var(--space-2xl); - gap: var(--space-m); -} -div#filters div#typeFilter button.typeChip { - flex-shrink: 0; - padding: 0; - height: var(--space-2xl); - aspect-ratio: 1/1; - justify-content: center; - align-items: center; - position: relative; - overflow: hidden; - border-radius: 9999px; -} -div#filters div#typeFilter button.typeChip[data-type=U], div#filters div#typeFilter button.typeChip[data-type=S], div#filters div#typeFilter button.typeChip[data-type=A], div#filters div#typeFilter button.typeChip[data-type=R] { - border: solid 2px var(--text); -} -div#filters div#typeFilter button.typeChip[data-type=U][data-pressed=false], div#filters div#typeFilter button.typeChip[data-type=S][data-pressed=false], div#filters div#typeFilter button.typeChip[data-type=A][data-pressed=false], div#filters div#typeFilter button.typeChip[data-type=R][data-pressed=false] { - background-color: var(--color-gray-500); - color: var(--color-type-disabled); -} -div#filters div#typeFilter button.typeChip[data-type=U][data-pressed=false][data-type=U], div#filters div#typeFilter button.typeChip[data-type=S][data-pressed=false][data-type=U], div#filters div#typeFilter button.typeChip[data-type=A][data-pressed=false][data-type=U], div#filters div#typeFilter button.typeChip[data-type=R][data-pressed=false][data-type=U] { - background-color: var(--bg-type-u-disabled); -} -div#filters div#typeFilter button.typeChip[data-type=U][data-pressed=false][data-type=S], div#filters div#typeFilter button.typeChip[data-type=S][data-pressed=false][data-type=S], div#filters div#typeFilter button.typeChip[data-type=A][data-pressed=false][data-type=S], div#filters div#typeFilter button.typeChip[data-type=R][data-pressed=false][data-type=S] { - background-color: var(--bg-type-s-disabled); -} -div#filters div#typeFilter button.typeChip[data-type=U][data-pressed=false][data-type=A], div#filters div#typeFilter button.typeChip[data-type=S][data-pressed=false][data-type=A], div#filters div#typeFilter button.typeChip[data-type=A][data-pressed=false][data-type=A], div#filters div#typeFilter button.typeChip[data-type=R][data-pressed=false][data-type=A] { - background-color: var(--bg-type-a-disabled); -} -div#filters div#typeFilter button.typeChip[data-type=U][data-pressed=false][data-type=R], div#filters div#typeFilter button.typeChip[data-type=S][data-pressed=false][data-type=R], div#filters div#typeFilter button.typeChip[data-type=A][data-pressed=false][data-type=R], div#filters div#typeFilter button.typeChip[data-type=R][data-pressed=false][data-type=R] { - background-color: var(--bg-type-r-disabled); -} -div#filters div#typeFilter button.typeChip[data-type=U][data-pressed=false]::after, div#filters div#typeFilter button.typeChip[data-type=S][data-pressed=false]::after, div#filters div#typeFilter button.typeChip[data-type=A][data-pressed=false]::after, div#filters div#typeFilter button.typeChip[data-type=R][data-pressed=false]::after { - position: absolute; - content: ""; - width: 144%; - height: 0.4rem; - background-color: var(--color-gray-700); - transform: rotate(-45deg); -} - -button#initialLoad { - font-size: 1.5rem; -} - -button.loadOSM { - width: fit-content; -} - -div#errorMessage { - border: solid 2px var(--color-red-600); - border-radius: var(--item-radius); - padding: var(--space-xl) var(--space-xl); - margin-top: var(--space-l); +div.filters button, div.filters input { font-size: 1.5rem; } @@ -608,11 +158,6 @@ ul#stationList { flex-direction: column; gap: var(--space-m); } -ul#stationList li#filterInfo { - text-align: center; - padding: var(--space-l) var(--space-xl); - font-style: italic; -} ul#stationList > li.station { background-color: var(--station-bg); border-radius: var(--item-radius); @@ -625,20 +170,9 @@ ul#stationList > li.station > div.stationSummary { display: flex; gap: var(--space-m); } -ul#stationList > li.station > div.stationSummary div.symbol { - position: relative; -} -ul#stationList > li.station > div.stationSummary div.symbol div.typeList { +ul#stationList > li.station > div.stationSummary div.typeList { flex-shrink: 0; } -ul#stationList > li.station > div.stationSummary div.symbol div.distance { - position: absolute; - width: 100%; - bottom: -2lh; - text-align: center; - color: var(--text-secondary); - font-size: 0.9em; -} ul#stationList > li.station > div.stationSummary div.stationTitle { align-self: stretch; flex-grow: 1; @@ -673,23 +207,17 @@ ul#stationList > li.station > div.stationSummary div.stationTitle > div.elevator } ul#stationList > li.station > details { width: 100%; - display: flex; - flex-direction: column; } ul#stationList > li.station > details summary { - width: 100%; list-style: none; - display: inline-flex; - cursor: pointer; - margin-left: calc(var(--space-m) + var(--type-icon-size)); -} -ul#stationList > li.station > details summary > span { border: solid 2px var(--station-border); display: inline-flex; padding: var(--space-m) var(--space-l); border-radius: var(--btn-radius); + cursor: pointer; + margin-left: calc(var(--space-m) + var(--type-icon-size)); } -ul#stationList > li.station > details summary:hover > span { +ul#stationList > li.station > details summary:hover { background-color: var(--station-bg-hover); border-color: var(--station-border-hover); } @@ -712,20 +240,6 @@ ul#stationList > li.station > details summary::after { ul#stationList > li.station > details[open] summary { margin-bottom: 1rem; } -ul#stationList > li.station > details > div.comment { - position: relative; - z-index: 20; - display: inline-flex; - margin-left: calc(var(--space-m) + var(--type-icon-size)); - padding-bottom: var(--space-m); - border-bottom: solid 2px var(--station-border); -} -ul#stationList > li.station > details > div.comment > p { - display: block; - border: solid 2px var(--nav-bg); - border-radius: var(--btn-radius); - padding: var(--space-l); -} ul#stationList > li.station > details > ul { padding: 0; list-style: none; @@ -740,29 +254,18 @@ ul#stationList > li.station > details > ul > li.elevator { display: flex; align-items: start; flex-wrap: nowrap; + padding: var(--space-m); gap: var(--space-m); position: relative; - margin: 0 var(--space-s) var(--space-s); - padding: var(--space-s); + margin: 0 1rem 1rem; } @media screen and (min-width: 576px) { ul#stationList > li.station > details > ul > li.elevator { - margin: 0 var(--space-2xl) 1rem; - padding: var(--space-m); - padding-right: var(--space-2xl); + margin: 0 3rem 1rem; } } -ul#stationList > li.station > details > ul > li.elevator > .stateIcon { +ul#stationList > li.station > details > ul > li.elevator > span { flex-shrink: 0; - display: none; -} -@media screen and (min-width: 576px) { - ul#stationList > li.station > details > ul > li.elevator > .stateIcon { - display: inline; - } -} -ul#stationList > li.station > details > ul > li.elevator:first-child { - padding-top: var(--space-l); } ul#stationList > li.station > details > ul > li.elevator:not(:first-child):before { content: ""; @@ -790,50 +293,15 @@ ul#stationList > li.station > details > ul > li.elevator > div.elevatorData .ele font-weight: bold; grid-column: 1/-1; } -ul#stationList > li.station > details > ul > li.elevator > div.elevatorData div.firstRow { - grid-column: 1/-1; - display: flex; - gap: var(--space-m); -} -@media screen and (min-width: 576px) { - ul#stationList > li.station > details > ul > li.elevator > div.elevatorData div.firstRow.hiddenOnDesktop { - display: none; - } -} -@media screen and (min-width: 576px) { - ul#stationList > li.station > details > ul > li.elevator > div.elevatorData div.firstRow .stateIcon { - display: none; - } -} -ul#stationList > li.station > details > ul > li.elevator > div.elevatorData div.firstRow .lineList { +ul#stationList > li.station > details > ul > li.elevator > div.elevatorData .lineList { display: flex; gap: var(--space-m); align-items: center; - min-height: var(--space-2xl); -} -ul#stationList > li.station > details > ul > li.elevator > div.elevatorData hr { grid-column: 1/-1; - width: 100%; - margin: 0; - border: none; - border-bottom: dashed 2px var(--station-border); } ul#stationList > li.station > details > ul > li.elevator > div.elevatorData .osm { grid-column: 1/-1; color: var(--text-secondary); - border: dashed 2px var(--station-border); - border-radius: var(--item-radius); - padding: var(--space-l); -} -ul#stationList > li.station > details > ul > li.elevator > div.elevatorData .osm .osmHeading { - display: flex; - align-items: center; - flex-wrap: wrap; - gap: var(--space-l); - margin-bottom: var(--space-l); -} -ul#stationList > li.station > details > ul > li.elevator > div.elevatorData .osm .osmHeading h4 { - margin: 0; } ul#stationList > li.station > details > ul > li.elevator > div.elevatorData .osm dl div dt { min-width: 18ch; @@ -893,15 +361,14 @@ ul#stationList > li.station > details > ul > li.elevator > div.elevatorData dl d font-weight: bold; min-width: 15ch; } -@media (max-width: 400px) { +@media (max-width: 576px) { ul#stationList > li.station > details > ul > li.elevator > div.elevatorData dl div dt { width: 100%; } } ul#stationList > li.station > details > ul > li.elevator > div.elevatorData dl div dd { - width: 0; - flex-grow: 1; - margin-left: var(--space-2xl); + flex-shrink: 0; + margin-left: 3rem; } @media screen and (min-width: 576px) { ul#stationList > li.station > details > ul > li.elevator > div.elevatorData dl div dd { @@ -909,66 +376,63 @@ ul#stationList > li.station > details > ul > li.elevator > div.elevatorData dl d } } -span.lineChip, span.typeChip, button.typeChip { +span.lineChip, span.typeChip { font-weight: bold; font-size: 0.8em; text-align: center; box-sizing: border-box; } -span.lineChip[data-type=U], span.typeChip[data-type=U], button.typeChip[data-type=U] { - background-color: var(--bg-type-u); - color: var(--color-white); +span.lineChip[data-type=U], span.typeChip[data-type=U] { + background-color: #006ab3; + color: #ffffff; } -span.lineChip[data-type=U][data-line=U1], span.typeChip[data-type=U][data-line=U1], button.typeChip[data-type=U][data-line=U1] { - background-color: var(--color-line-U1); +span.lineChip[data-type=U][data-line=U1], span.typeChip[data-type=U][data-line=U1] { + background-color: #006ab3; } -span.lineChip[data-type=U][data-line=U2], span.typeChip[data-type=U][data-line=U2], button.typeChip[data-type=U][data-line=U2] { - background-color: var(--color-line-U2); +span.lineChip[data-type=U][data-line=U2], span.typeChip[data-type=U][data-line=U2] { + background-color: #e2001a; } -span.lineChip[data-type=U][data-line=U3], span.typeChip[data-type=U][data-line=U3], button.typeChip[data-type=U][data-line=U3] { - background-color: var(--color-line-U3); - color: var(--color-black); +span.lineChip[data-type=U][data-line=U3], span.typeChip[data-type=U][data-line=U3] { + background-color: #ffdd00; + color: #000000; } -span.lineChip[data-type=U][data-line=U4], span.typeChip[data-type=U][data-line=U4], button.typeChip[data-type=U][data-line=U4] { - background-color: var(--color-line-U4); +span.lineChip[data-type=U][data-line=U4], span.typeChip[data-type=U][data-line=U4] { + background-color: #0098a1; } -span.lineChip[data-type=U][data-line=U5], span.typeChip[data-type=U][data-line=U5], button.typeChip[data-type=U][data-line=U5] { - background-color: var(--color-line-U5); +span.lineChip[data-type=S], span.typeChip[data-type=S] { + background-color: #1a962b; + color: #ffffff; } -span.lineChip[data-type=S], span.typeChip[data-type=S], button.typeChip[data-type=S] { - background-color: var(--bg-type-s); - color: var(--color-white); +span.lineChip[data-type=S][data-line=S1], span.typeChip[data-type=S][data-line=S1] { + background-color: #1a962b; } -span.lineChip[data-type=S][data-line=S1], span.typeChip[data-type=S][data-line=S1], button.typeChip[data-type=S][data-line=S1] { - background-color: var(--color-line-S1); +span.lineChip[data-type=S][data-line=S2], span.typeChip[data-type=S][data-line=S2] { + background-color: #b51143; } -span.lineChip[data-type=S][data-line=S2], span.typeChip[data-type=S][data-line=S2], button.typeChip[data-type=S][data-line=S2] { - background-color: var(--color-line-S2); +span.lineChip[data-type=S][data-line=S3], span.typeChip[data-type=S][data-line=S3] { + background-color: #622181; } -span.lineChip[data-type=S][data-line=S3], span.typeChip[data-type=S][data-line=S3], button.typeChip[data-type=S][data-line=S3] { - background-color: var(--color-line-S3); +span.lineChip[data-type=S][data-line=S4], span.typeChip[data-type=S][data-line=S4] { + background-color: #be148e; } -span.lineChip[data-type=S][data-line=S4], span.typeChip[data-type=S][data-line=S4], button.typeChip[data-type=S][data-line=S4] { - background-color: var(--color-line-S4); +span.lineChip[data-type=S][data-line=S5], span.typeChip[data-type=S][data-line=S5] { + background-color: #0089bb; } -span.lineChip[data-type=S][data-line=S5], span.typeChip[data-type=S][data-line=S5], button.typeChip[data-type=S][data-line=S5] { - background-color: var(--color-line-S5); +span.lineChip[data-type=S][data-line=S6], span.typeChip[data-type=S][data-line=S6] { + background-color: #d3da00; + color: #000000; } -span.lineChip[data-type=S][data-line=S6], span.typeChip[data-type=S][data-line=S6], button.typeChip[data-type=S][data-line=S6] { - background-color: var(--color-line-S6); - color: var(--color-black); +span.lineChip[data-type=A], span.typeChip[data-type=A] { + background-color: #f39100; + color: #ffffff; } -span.lineChip[data-type=A], span.typeChip[data-type=A], button.typeChip[data-type=A] { - background-color: var(--bg-type-a); - color: var(--color-white); -} -span.lineChip[data-type=R], span.typeChip[data-type=R], button.typeChip[data-type=R] { - background-color: var(--bg-type-r); - color: var(--color-white); +span.lineChip[data-type=R], span.typeChip[data-type=R] { + background-color: #000000; + color: #ffffff; } @media (prefers-color-scheme: dark) { - span.lineChip[data-type=R], span.typeChip[data-type=R], button.typeChip[data-type=R] { - border: solid 2px var(--color-white); + span.lineChip[data-type=R], span.typeChip[data-type=R] { + border: solid 2px #ffffff; } } @@ -1078,27 +542,5 @@ span[data-icon][data-icon=up-down] { span[data-icon][data-icon=location-searching] { mask-image: url(/md_icons/location-searching.svg); } -span[data-icon][data-icon=load] { - mask-image: url(/md_icons/load.svg); -} -span[data-icon][data-icon=close] { - mask-image: url(/md_icons/close.svg); -} -span[data-icon].spinner { - animation-delay: 0s; - animation-direction: normal; - animation-duration: 1s; - animation-fill-mode: none; - animation-iteration-count: infinite; - animation-name: spinner; - animation-play-state: running; - animation-timing-function: linear; -} - -@keyframes spinner { - to { - transform: rotate(360deg); - } -} /*# sourceMappingURL=style.css.map */ diff --git a/style.css.map b/style.css.map index 56af578..108bf0f 100644 --- a/style.css.map +++ b/style.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["style.scss","colors.scss"],"names":[],"mappings":"AAMA;ACLE;;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAwBA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AACA;ED/PA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAIA;EACA;EACA;EAEA;EACA;EACA;EAEA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EAEA;EAgCA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAtCA;EApDF;IAsDI;IACA;IACA;IACA;IACA;IAGA;IACA;IACA;IAEA;IACA;IACA;IAEA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IAEA;;;;AAeF;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAfF;IAgBI;IACA;;;AAIA;EACE;EACA;EACA;EACA;EACA;;;AAMR;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EAGA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGE;EACE;EACA;EACA;EAEA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;;AAOV;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;AAGF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EARF;IASI;;;AAGF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AACA;EAJF;IAKI;IACA;;;AAIJ;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAQZ;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EAEA;EACA;EACA;;AAKJ;EACE;EACA;EAEA;EACA;EACA;;AAEA;EACE;EACA;EACA;EAEA;;AAEA;EAPF;IAQI;;;AAIJ;EACE;EAEA;EACA;EACA;EACA;;AAEA;EARF;IASI;IACA;IACA;;;AAMR;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAIA;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EAjCF;IAkCI;;;AAIJ;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EAEA;EACA;;AACA;EATF;IAUI;IACA;IACA;;;AAIF;EACE;EACA;;AACA;EAHF;IAII;;;AAKJ;EACE;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EAEA;;AACA;EARF;IASI;;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGE;EADF;IAEI;;;AAKF;EADF;IAEI;;;AAKJ;EACE;EACA;EACA;EACA;;AAKJ;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAOA;EACE;;AAMR;EACE;EACA;EACA;EAEA;EACA;;AAEA;EACE;EAEA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EACE;;AAKF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAKN;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EARF;IASI;;;AAIJ;EACE;EACA;EAEA;;AAEA;EANF;IAOI;;;;AAYpB;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;AAIJ;EACE;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAIJ;EACE;EACA;;AAGF;EACE;EACA;;AAEA;EAJF;IAKI;;;;AAMN;EACE;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EAEE;EAMA;EACA;EACA;EACA;EACA;EACA;EACA;;AAVA;EACE;;AAWF;EAIE;EACA;;;AAMJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;EACE;IACE","file":"style.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["style.scss"],"names":[],"mappings":"AAGA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAmBA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAxBA;EA/BF;IAgCI;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;;;AAaJ;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EAGA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGE;EACE;EACA;EACA;EAEA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;;AAOV;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAIF;EACE;EACA;EAEA;EACA;EACA;;AAEA;EACE;EACA;EACA;EAEA;;AAEA;EAPF;IAQI;;;AAIJ;EACE;EAEA;EACA;EACA;EACA;;AAEA;EARF;IASI;IACA;IACA;;;AAMR;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EA1BF;IA2BI;;;AAIJ;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EAEA;;AACA;EATF;IAUI;;;AAIF;EACE;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EAEA;;AACA;EARF;IASI;;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAII;EACE;;AAMR;EACE;EACA;EACA;EAEA;EACA;;AAEA;EACE;EAEA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIA;EACE;;AAKF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAKN;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EARF;IASI;;;AAIJ;EACE;EACA;;AAEA;EAJF;IAKI;;;;AAYpB;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;AAIJ;EACE;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAIJ;EACE;EACA;;AAGF;EACE;EACA;;AAEA;EAJF;IAKI;;;;AAKN;EACE;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EAEE;EAMA;EACA;EACA;EACA;EACA;EACA;EACA;;AAVA;EACE;;AAWF;EAIE;EACA;;;AAMJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE","file":"style.css"} \ No newline at end of file diff --git a/style.scss b/style.scss index 49a4971..aa5694a 100644 --- a/style.scss +++ b/style.scss @@ -1,89 +1,52 @@ -@import "colors"; - $mobileBreakpoint: 576px; -$smallBreakpoint: 400px; $mediumBreakpoint: 800px; :root { - @include tailwindColors(); - - // LineType Colors - $colorTypeU: #006ab3; - $colorTypeS: #1a962b; - $colorTypeA: #f39100; - $colorTypeR: #000000; - --bg-type-u: #{$colorTypeU}; - --bg-type-s: #{$colorTypeS}; - --bg-type-a: #{$colorTypeA}; - --bg-type-r: #{$colorTypeR}; - --bg-type-u-disabled: #{scale-color($colorTypeU, $saturation: -80%, $lightness: +70%)}; - --bg-type-s-disabled: #{scale-color($colorTypeS, $saturation: -80%, $lightness: +70%)}; - --bg-type-a-disabled: #{scale-color($colorTypeA, $saturation: -80%, $lightness: +70%)}; - --bg-type-r-disabled: #{scale-color($colorTypeR, $saturation: -80%, $lightness: +70%)}; - --color-type-disabled: var(--color-gray-400); - - // Line Colors - --color-line-U1: #006ab3; - --color-line-U2: #e2001a; - --color-line-U3: #ffdd00; - --color-line-U4: #0098a1; - --color-line-S1: #1a962b; - --color-line-S2: #b51143; - --color-line-S3: #622181; - --color-line-S4: #be148e; - --color-line-S5: #0089bb; - --color-line-S6: #d3da00; + --color-gray-50: hsl(60, 9%, 98%); + --color-gray-100: hsl(60, 5%, 96%); + --color-gray-200: hsl(20, 6%, 90%); + --color-gray-300: hsl(24, 6%, 83%); + --color-gray-400: hsl(24, 5%, 64%); + --color-gray-500: hsl(25, 5%, 45%); + --color-gray-600: hsl(33, 5%, 32%); + --color-gray-700: hsl(30, 6%, 25%); + --color-gray-800: hsl(12, 6%, 15%); + --color-gray-900: hsl(24, 10%, 10%); + --color-gray-950: hsl(20, 14%, 4%); - // Component Styles --bg: var(--color-gray-50); --text: var(--color-gray-950); --text-secondary: var(--color-gray-700); - - --nav-bg: var(--color-indigo-400); - --nav-bg-hover: var(--color-indigo-200); - --nav-bg-visited: var(--color-purple-400); - - --link: var(--color-indigo-600); - --link-hover: var(--color-indigo-800); - --link-visited: var(--color-purple-600); - + --nav-bg: hsl(210, 60%, 50%); + --nav-bg-hover: hsl(210, 60%, 30%); + --nav-bg-visited: hsl(250, 60%, 50%); + --nav-text-visited: hsl(250, 60%, 93%); + --nav-text: hsl(210, 60%, 93%); + --link: hsl(210, 60%, 30%); + --link-hover: hsl(210, 60%, 10%); + --link-visited: hsl(250, 60%, 30%); --station-bg: var(--color-gray-50); --station-bg-hover: var(--color-gray-400); --station-border: var(--color-gray-400); --station-border-hover: var(--color-gray-600); --elevator-bg: var(--color-gray-100); - --backdrop: rgb(0 0 0 / 20%); - @media (prefers-color-scheme: dark) { - // LineType Colors - --bg-type-u-disabled: #{scale-color($colorTypeU, $saturation: -80%, $lightness: +20%)}; - --bg-type-s-disabled: #{scale-color($colorTypeS, $saturation: -80%, $lightness: +20%)}; - --bg-type-a-disabled: #{scale-color($colorTypeA, $saturation: -80%, $lightness: +20%)}; - --bg-type-r-disabled: #{scale-color($colorTypeR, $saturation: -80%, $lightness: +20%)}; - --color-type-disabled: var(--color-gray-200); - - // Component Styles --bg: var(--color-gray-950); --text: var(--color-gray-50); --text-secondary: var(--color-gray-400); - - --nav-bg: var(--color-indigo-800); - --nav-bg-hover: var(--color-indigo-950); - --nav-bg-visited: var(--color-purple-800); - - --link: var(--color-indigo-400); - --link-hover: var(--color-indigo-200); - --link-visited: var(--color-purple-400); - + --nav-bg: hsl(210, 60%, 30%); + --nav-bg-hover: hsl(210, 60%, 10%); + --nav-bg-visited: hsl(250, 60%, 30%); + --link: hsl(210, 60%, 60%); + --link-hover: hsl(210, 60%, 60%); + --link-visited: hsl(250, 60%, 70%); --station-bg: var(--color-gray-950); --station-bg-hover: var(--color-gray-600); --station-border: var(--color-gray-600); --station-border-hover: var(--color-gray-400); --elevator-bg: var(--color-gray-900); - - --backdrop: rgb(100% 100% 100% / 20%); } --elevator-list-gap: 3rem; @@ -94,84 +57,27 @@ $mediumBreakpoint: 800px; --space-m: 0.5rem; --space-l: 1rem; --space-xl: 2rem; - --space-2xl: 3rem; -} - -body { - &.has-dialog { - overflow: hidden; - } -} - -.dialogs { - display: none; - position: fixed; - overflow-y: auto; - max-width: 100vw; - padding: 1em; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 99; - background: var(--backdrop); - - &.active { - display: block; - } - - - [role="dialog"] { - box-sizing: border-box; - max-width: 800px; - margin: 0 auto; - padding: var(--space-xl); - padding-bottom: var(--space-2xl); - background-color: var(--bg); - color: var(--text); - overflow: hidden; - position: absolute; - right: 0; - bottom: 0; - left: 0; - border-radius: var(--item-radius) var(--item-radius) 0 0; - - @media screen and (min-width: $mobileBreakpoint) { - position: relative; - border-radius: var(--item-radius); - } - - button { - &.close-modal { - position: absolute; - top: 0; - right: 0; - border-radius: 0 0 0 var(--btn-radius); - border: none; - } - } - } } .hidden { - display: none !important; + display: none; } .text-red { - color: var(--color-red-800); + color: #e32d2d; } .text-orange { - color: var(--color-orange-500); + color: #cc6300; } .text-green { - color: var(--color-green-600); + color: #19942e; } body { font-family: system-ui, ui-sans-serif, sans-serif; - font-size: 1rem; + font-size: 1.2rem; // colors background-color: var(--bg); @@ -186,7 +92,7 @@ a { color: var(--link); text-decoration: none; - &:hover, &:visited:hover { + &:hover { text-decoration: underline; color: var(--link-hover); } @@ -208,20 +114,20 @@ nav { li { a { font-weight: bold; - color: var(--text); + color: var(--nav-text); text-decoration: none; background-color: var(--nav-bg); padding: var(--space-m) var(--space-l); cursor: pointer; - &:hover, &:visited:hover { + &:hover { text-decoration: underline; background-color: var(--nav-bg-hover); } &:visited { - color: var(--text); + color: var(--nav-text-visited); background-color: var(--nav-bg-visited); } } @@ -234,13 +140,6 @@ main { max-width: 960px; } -footer { - display: flex; - justify-content: center; - margin: 1em auto; - max-width: 960px; -} - button, input { background-color: var(--station-bg); color: var(--text); @@ -251,7 +150,7 @@ button, input { button { cursor: pointer; - display: inline-flex; + display: flex; align-items: center; gap: var(--space-m); @@ -259,140 +158,16 @@ button { background-color: var(--station-bg-hover); border-color: var(--station-border-hover); } - - &[aria-pressed='true'] { - background-color: var(--nav-bg-visited); - } - - &.size-s { - font-size: 0.8rem; - padding: var(--space-s) var(--space-m); - } - - &.size-m { - padding: var(--space-m) var(--space-l); - } - - &.size-l { - font-size: 1.5rem; - padding: var(--space-m) var(--space-l); - } } -div#updateInfo { +div.filters { display: flex; - align-items: center; gap: var(--space-m); - justify-content: end; - flex-direction: column; - margin-bottom: var(--space-l); + justify-items: stretch; - @media screen and (min-width: $mobileBreakpoint) { - flex-direction: row; - } - - #oldDataWarning { - color: var(--color-red-600); - font-weight: bold; - } -} - -div#filters { - display: flex; - flex-wrap: wrap; - gap: var(--space-m); - justify-content: center; - - > * { - width: 100%; - justify-content: center; - text-align: center; - @media screen and (min-width: $mobileBreakpoint) { - width: auto; - min-width: 0; - } - } - - input#searchStation { - flex-grow: 1; - font-size: 1.5rem; - min-width: 10ch; - } - - button#stationsNearMe { + button, input { font-size: 1.5rem; } - - div#typeFilter { - font-size: 1.5rem; - display: flex; - justify-content: center; - flex-shrink: 0; - min-height: var(--space-2xl); - gap: var(--space-m); - - button.typeChip { - flex-shrink: 0; - padding: 0; - height: var(--space-2xl); - aspect-ratio: 1/1; - justify-content: center; - align-items: center; - position: relative; - overflow: hidden; - border-radius: 9999px; - - &[data-type="U"], &[data-type="S"], &[data-type="A"], &[data-type="R"] { - border: solid 2px var(--text); - - &[data-pressed="false"] { - background-color: var(--color-gray-500); - color: var(--color-type-disabled); - - &[data-type="U"] { - background-color: var(--bg-type-u-disabled); - } - - &[data-type="S"] { - background-color: var(--bg-type-s-disabled); - } - - &[data-type="A"] { - background-color: var(--bg-type-a-disabled); - } - - &[data-type="R"] { - background-color: var(--bg-type-r-disabled); - } - - &::after { - position: absolute; - content: ''; - width: 144%; - height: 0.4rem; - background-color: var(--color-gray-700); - transform: rotate(-45deg); - } - } - } - } - } -} - -button#initialLoad { - font-size: 1.5rem; -} - -button.loadOSM { - width: fit-content; -} - -div#errorMessage { - border: solid 2px var(--color-red-600); - border-radius: var(--item-radius); - padding: var(--space-xl) var(--space-xl); - margin-top: var(--space-l); - font-size: 1.5rem; } ul#stationList { @@ -402,12 +177,6 @@ ul#stationList { flex-direction: column; gap: var(--space-m); - li#filterInfo { - text-align: center; - padding: var(--space-l) var(--space-xl); - font-style: italic; - } - > li.station { background-color: var(--station-bg); border-radius: var(--item-radius); @@ -420,22 +189,8 @@ ul#stationList { display: flex; gap: var(--space-m); - div.symbol { - position: relative; - - div.typeList { - flex-shrink: 0; - } - - div.distance { - position: absolute; - width: 100%; - bottom: -2lh; - - text-align: center; - color: var(--text-secondary); - font-size: 0.9em; - } + div.typeList { + flex-shrink: 0; } @@ -478,28 +233,19 @@ ul#stationList { > details { width: 100%; - display: flex; - flex-direction: column; summary { - width: 100%; list-style: none; + border: solid 2px var(--station-border); display: inline-flex; + padding: var(--space-m) var(--space-l); + border-radius: var(--btn-radius); cursor: pointer; margin-left: calc(var(--space-m) + var(--type-icon-size)); - > span { - border: solid 2px var(--station-border); - display: inline-flex; - padding: var(--space-m) var(--space-l); - border-radius: var(--btn-radius); - } - &:hover { - > span { - background-color: var(--station-bg-hover); - border-color: var(--station-border-hover); - } + background-color: var(--station-bg-hover); + border-color: var(--station-border-hover); } &::after { @@ -523,22 +269,6 @@ ul#stationList { margin-bottom: 1rem; } - > div.comment { - position: relative; - z-index: 20; - display: inline-flex; - margin-left: calc(var(--space-m) + var(--type-icon-size)); - padding-bottom: var(--space-m); - border-bottom: solid 2px var(--station-border); - - > p { - display: block; - border: solid 2px var(--nav-bg); - border-radius: var(--btn-radius); - padding: var(--space-l); - } - } - > ul { padding: 0; list-style: none; @@ -553,29 +283,18 @@ ul#stationList { display: flex; align-items: start; flex-wrap: nowrap; + padding: var(--space-m); gap: var(--space-m); position: relative; - margin: 0 var(--space-s) var(--space-s); - padding: var(--space-s); + margin: 0 1rem 1rem; @media screen and (min-width: $mobileBreakpoint) { - margin: 0 var(--space-2xl) 1rem; - padding: var(--space-m); - padding-right: var(--space-2xl); + margin: 0 3rem 1rem; } // elevator icon - > .stateIcon { + > span { flex-shrink: 0; - display: none; - @media screen and (min-width: $mobileBreakpoint) { - display: inline; - } - } - - // space above first elevator - &:first-child { - padding-top: var(--space-l); } // divider between elevators @@ -606,60 +325,16 @@ ul#stationList { grid-column: 1 / -1; } - div.firstRow { - grid-column: 1 / -1; + .lineList { display: flex; gap: var(--space-m); - - &.hiddenOnDesktop { - @media screen and (min-width: $mobileBreakpoint) { - display: none; - } - } - - .stateIcon { - @media screen and (min-width: $mobileBreakpoint) { - display: none; - } - } - - - .lineList { - display: flex; - gap: var(--space-m); - align-items: center; - min-height: var(--space-2xl); - } - } - - - hr { + align-items: center; grid-column: 1 / -1; - width: 100%; - margin: 0; - border: none; - border-bottom: dashed 2px var(--station-border); } .osm { grid-column: 1 / -1; color: var(--text-secondary); - border: dashed 2px var(--station-border); - border-radius: var(--item-radius); - padding: var(--space-l); - - .osmHeading { - display: flex; - align-items: center; - flex-wrap: wrap; - gap: var(--space-l); - margin-bottom: var(--space-l); - - h4 { - margin: 0; - } - } - dl { div { @@ -737,16 +412,14 @@ ul#stationList { font-weight: bold; min-width: 15ch; - @media (max-width: $smallBreakpoint) { + @media (max-width: $mobileBreakpoint) { width: 100%; } } dd { - width: 0; - flex-grow: 1; - - margin-left: var(--space-2xl); + flex-shrink: 0; + margin-left: 3rem; @media screen and (min-width: $mobileBreakpoint) { margin-left: 1rem; @@ -761,84 +434,79 @@ ul#stationList { } } -span.lineChip, span.typeChip, button.typeChip { +span.lineChip, span.typeChip { font-weight: bold; font-size: 0.8em; text-align: center; box-sizing: border-box; &[data-type="U"] { - background-color: var(--bg-type-u); - color: var(--color-white); + background-color: #006ab3; + color: #ffffff; &[data-line="U1"] { - background-color: var(--color-line-U1); + background-color: #006ab3; } &[data-line="U2"] { - background-color: var(--color-line-U2); + background-color: #e2001a; } &[data-line="U3"] { - background-color: var(--color-line-U3); - color: var(--color-black); + background-color: #ffdd00; + color: #000000; } &[data-line="U4"] { - background-color: var(--color-line-U4); - } - - &[data-line="U5"] { - background-color: var(--color-line-U5); + background-color: #0098a1; } } &[data-type="S"] { - background-color: var(--bg-type-s); - color: var(--color-white); + background-color: #1a962b; + color: #ffffff; &[data-line="S1"] { - background-color: var(--color-line-S1); + background-color: #1a962b; } &[data-line="S2"] { - background-color: var(--color-line-S2); + background-color: #b51143; } &[data-line="S3"] { - background-color: var(--color-line-S3); + background-color: #622181; } &[data-line="S4"] { - background-color: var(--color-line-S4); + background-color: #be148e; } &[data-line="S5"] { - background-color: var(--color-line-S5); + background-color: #0089bb; } &[data-line="S6"] { - background-color: var(--color-line-S6); - color: var(--color-black); + background-color: #d3da00; + color: #000000; } } &[data-type="A"] { - background-color: var(--bg-type-a); - color: var(--color-white); + background-color: #f39100; + color: #ffffff; } &[data-type="R"] { - background-color: var(--bg-type-r); - color: var(--color-white); + background-color: #000000; + color: #ffffff; @media (prefers-color-scheme: dark) { - border: solid 2px var(--color-white); + border: solid 2px #ffffff; } } } - span.lineChip { padding: 0.3em 0.6em; min-width: 4ch; @@ -973,29 +641,4 @@ span[data-icon] { &[data-icon="location-searching"] { mask-image: url(/md_icons/location-searching.svg); } - - &[data-icon="load"] { - mask-image: url(/md_icons/load.svg); - } - - &[data-icon="close"] { - mask-image: url(/md_icons/close.svg); - } - - &.spinner { - animation-delay: 0s; - animation-direction: normal; - animation-duration: 1s; - animation-fill-mode: none; - animation-iteration-count: infinite; - animation-name: spinner; - animation-play-state: running; - animation-timing-function: linear - } -} - -@keyframes spinner { - to { - transform: rotate(360deg); - } } diff --git a/sw.js b/sw.js deleted file mode 100644 index 8b19416..0000000 --- a/sw.js +++ /dev/null @@ -1,101 +0,0 @@ -const version = '0.6.4' -const consolePrefix = `[SW v${version}] ` - -const cacheName = `hvvstuhl-${version}`; -const contentToCache = [ - '/', - '/index.html', - '/about.html', - '/main.js', - '/elevators.js', - '/style.css', - '/icons/192.png', - '/icons/512.png', - '/icons/512-maskable.png', - '/icons/512-transparent.png', - '/icons/favicon.ico', - '/icons/favicon.svg', - '/icons/favicon-maskable.svg', - '/icons/favicon-transparent.svg', - '/md_icons/bicycle.svg', - '/md_icons/braille.svg', - '/md_icons/door_sliding.svg', - '/md_icons/elevator.svg', - '/md_icons/elevator-slash.svg', - '/md_icons/fit_width.svg', - '/md_icons/height.svg', - '/md_icons/info.svg', - '/md_icons/load.svg', - '/md_icons/location.svg', - '/md_icons/location-searching.svg', - '/md_icons/speaker.svg', - '/md_icons/up-down.svg', - '/md_icons/wheelchair.svg', - '/md_icons/width.svg', -]; - -// Service worker Install: Cache all files -self.addEventListener("install", (e) => { - console.log(`${consolePrefix}Wird installiert....`); - e.waitUntil( - (async () => { - const cache = await caches.open(cacheName); - console.log(`${consolePrefix} Cache wird aufgebaut...`); - await cache.addAll(contentToCache); - console.log(`${consolePrefix} > FERTIG`); - console.log(`${consolePrefix} Versuche Wartezeit zu überspringen...`); - await self.skipWaiting(); - console.log(`${consolePrefix} > Erfolgreich`); - })(), - ); -}); - - -// delete old caches -const deleteCache = async (key) => { - await caches.delete(key); -}; -const deleteOldCaches = async () => { - const keyList = await caches.keys(); - const cachesToDelete = keyList.filter((key) => key !== cacheName); - await Promise.all(cachesToDelete.map(deleteCache)); -}; -self.addEventListener("activate", (event) => { - event.waitUntil( - (async () => { - await deleteOldCaches(); - console.log(`${consolePrefix}Versuche Clients zu beanspruchen...`); - await self.clients.claim(); - console.log(`${consolePrefix} > Erfolgreich`); - })(), - ); -}); - - - -// Respond with data from cache when offline -self.addEventListener("fetch", (e) => { - e.respondWith( - (async () => { - const path = new URL(e.request.url).pathname - - if(contentToCache.includes(path)){ - console.log(`${consolePrefix}Anfrage: ${path}`); - - const r = await caches.match(e.request); - if (r) { - console.log(`${consolePrefix} > Im Cache gefunden.`); - return r; - } - const response = await fetch(e.request); - const cache = await caches.open(cacheName); - console.log(`${consolePrefix} > Nicht gefunden. Aktualisiere Cache: ${path}`); - await cache.put(e.request, response.clone()); - return response; - }else{ - console.log(`${consolePrefix}Anfrage übersprungen: ${e.request.url}`); - return await fetch(e.request); - } - })(), - ); -}); \ No newline at end of file