some major improvements
- filter by station type - sort by distance (WIP) - detect old data structure and clear localStorage if not compatible - add substitue coordinates for stations without valid osm node - improve responsive styles
This commit is contained in:
parent
af50e0f04d
commit
14a514e3e4
5 changed files with 726 additions and 128 deletions
377
elevators.js
377
elevators.js
|
@ -3,8 +3,64 @@ const internalData = {
|
||||||
stations: [],
|
stations: [],
|
||||||
};
|
};
|
||||||
let geolocationPermission = false;
|
let geolocationPermission = false;
|
||||||
let geolocation = [null, null];
|
let geolocation = null;
|
||||||
const openStations = new Set();
|
const openStations = new Set();
|
||||||
|
let sortByDistance = false;
|
||||||
|
|
||||||
|
const substituteCoordinates = [
|
||||||
|
{
|
||||||
|
name: 'Borgweg (Stadtpark)',
|
||||||
|
coordinates: [53.5907696, 10.0147719],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Emilienstraße',
|
||||||
|
coordinates: [53.5716862, 9.9525424],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Garstedt',
|
||||||
|
coordinates: [53.6844739, 9.9860415],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Hagenbecks Tierpark',
|
||||||
|
coordinates: [53.5925874, 9.9440359],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(String.prototype, 'capitalize', {
|
Object.defineProperty(String.prototype, 'capitalize', {
|
||||||
|
@ -15,12 +71,17 @@ Object.defineProperty(String.prototype, 'capitalize', {
|
||||||
});
|
});
|
||||||
|
|
||||||
async function loadElevators() {
|
async function loadElevators() {
|
||||||
const res = await fetch('https://www.hvv.de/elevators', {referrer: ""});
|
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 data = await res.json();
|
const data = await res.json();
|
||||||
|
|
||||||
const stations = data['stations'];
|
const stations = data['stations'];
|
||||||
stations.sort(sortStations)
|
stations.sort(sortStations);
|
||||||
internalData.lastUpdate = new Date(data['lastUpdate']);
|
internalData.lastUpdate = new Date(data['lastUpdate']);
|
||||||
|
|
||||||
let stationIndex = 0;
|
let stationIndex = 0;
|
||||||
|
@ -102,7 +163,10 @@ async function loadElevators() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
localStorage.setItem("internal_data", JSON.stringify(internalData));
|
localStorage.setItem("internal_data", JSON.stringify({
|
||||||
|
api: 'v1',
|
||||||
|
...internalData
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
const dateTimeStyle = new Intl.DateTimeFormat('de-DE', {
|
const dateTimeStyle = new Intl.DateTimeFormat('de-DE', {
|
||||||
|
@ -119,12 +183,55 @@ async function loadOsmData() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const osmData = await fetch(`https://overpass-api.de/api/interpreter?data=[out:json];node(id:${nodeIdList.join(',')});out%20body;`, {});
|
const osmResponse = await fetch(`https://overpass-api.de/api/interpreter?data=[out:json];node(id:${nodeIdList.join(',')});out%20body;`, {});
|
||||||
const osmJson = await osmData.json();
|
const osmJson = await osmResponse.json();
|
||||||
|
|
||||||
if (!osmJson.hasOwnProperty('elements')) return;
|
if (!osmJson.hasOwnProperty('elements')) return;
|
||||||
|
|
||||||
localStorage.setItem("osm_data", JSON.stringify(osmJson));
|
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 = substituteCoordinates.filter(subs => subs.name === internalData.stations[stationIndex].name)
|
||||||
|
if (substitute.length) {
|
||||||
|
internalData.stations[stationIndex]['coordinates'] = substitute[0].coordinates;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
localStorage.setItem("osm_data", JSON.stringify({
|
||||||
|
api: 'v1',
|
||||||
|
lastUpdate: new Date(),
|
||||||
|
nodes: osmNodes
|
||||||
|
}));
|
||||||
|
localStorage.setItem("internal_data", JSON.stringify({
|
||||||
|
api: 'v1',
|
||||||
|
...internalData
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
function distance([lat1, lon1], [lat2, lon2]) {
|
function distance([lat1, lon1], [lat2, lon2]) {
|
||||||
|
@ -145,9 +252,12 @@ function distance([lat1, lon1], [lat2, lon2]) {
|
||||||
|
|
||||||
function registerGeolocationWatcher() {
|
function registerGeolocationWatcher() {
|
||||||
navigator.geolocation.watchPosition((pos) => {
|
navigator.geolocation.watchPosition((pos) => {
|
||||||
geolocation = [pos.coords.latitude, pos.coords.longitude]
|
if (geolocation === null) {
|
||||||
|
geolocation = [pos.coords.latitude, pos.coords.longitude];
|
||||||
|
renderData(geolocation);
|
||||||
|
}
|
||||||
}, (e) => {
|
}, (e) => {
|
||||||
console.log(e)
|
console.warn(e)
|
||||||
}, {
|
}, {
|
||||||
enableHighAccuracy: true,
|
enableHighAccuracy: true,
|
||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
|
@ -177,8 +287,6 @@ function allowGeolocation() {
|
||||||
|
|
||||||
checkGeolocationPermission()
|
checkGeolocationPermission()
|
||||||
|
|
||||||
document.querySelector('#stationsNearMe').addEventListener('click', allowGeolocation)
|
|
||||||
|
|
||||||
function sortStations(stationA, stationB) {
|
function sortStations(stationA, stationB) {
|
||||||
const nameA = stationA.mainSubStation.stationName.toUpperCase(); // ignore upper and lowercase
|
const nameA = stationA.mainSubStation.stationName.toUpperCase(); // ignore upper and lowercase
|
||||||
const nameB = stationB.mainSubStation.stationName.toUpperCase(); // ignore upper and lowercase
|
const nameB = stationB.mainSubStation.stationName.toUpperCase(); // ignore upper and lowercase
|
||||||
|
@ -193,6 +301,20 @@ function sortStations(stationA, stationB) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sortStationsByDistance(stationA, stationB) {
|
||||||
|
const distanceA = stationA.distance; // ignore upper and lowercase
|
||||||
|
const distanceB = stationB.distance; // ignore upper and lowercase
|
||||||
|
if (distanceA < distanceB) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (distanceA > distanceB) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// names must be equal
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
function getType(line) {
|
function getType(line) {
|
||||||
const type = line.replace(/[^A-z]/g, "");
|
const type = line.replace(/[^A-z]/g, "");
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -218,7 +340,7 @@ function getTypes(lines) {
|
||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderData() {
|
function renderData(location = null) {
|
||||||
const ls = JSON.parse(localStorage.getItem("internal_data"));
|
const ls = JSON.parse(localStorage.getItem("internal_data"));
|
||||||
if (!ls) return;
|
if (!ls) return;
|
||||||
internalData.lastUpdate = ls['lastUpdate'];
|
internalData.lastUpdate = ls['lastUpdate'];
|
||||||
|
@ -230,6 +352,18 @@ function renderData() {
|
||||||
return;
|
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('#updateInfo').classList.remove('hidden');
|
||||||
document.querySelector('#loadElevators').classList.remove('hidden');
|
document.querySelector('#loadElevators').classList.remove('hidden');
|
||||||
document.querySelector('#filters').classList.remove('hidden');
|
document.querySelector('#filters').classList.remove('hidden');
|
||||||
|
@ -241,18 +375,57 @@ function renderData() {
|
||||||
//clear list before update
|
//clear list before update
|
||||||
listContainer.innerHTML = '';
|
listContainer.innerHTML = '';
|
||||||
|
|
||||||
const stations = internalData['stations'];
|
let stations = [...internalData['stations']];
|
||||||
|
|
||||||
for (const stationIndex in stations) {
|
for (const stationIndex in stations) {
|
||||||
const station = stations[stationIndex];
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 elevatorsTemplate = '';
|
||||||
let previewTemplate = '';
|
let previewTemplate = '';
|
||||||
|
|
||||||
for (const elevator of station.elevators) {
|
for (const elevator of station.elevators) {
|
||||||
let linesTemplate = '<div class="lineList">Linien: ';
|
const stateTemplate = `<span data-icon="${elevator.working || elevator.stateUnavailable ? 'elevator' : 'elevator-slash'}"
|
||||||
for (const line of elevator.lines) {
|
class="stateIcon size-xl ${elevator.working ? 'text-green' : elevator.stateUnavailable ? 'text-orange' : 'text-red'}"
|
||||||
linesTemplate += `<span data-type="${line.type}" data-line="${line.line}" class="lineChip">${line.line}</span>`;
|
role="img"
|
||||||
|
aria-label="${elevator.stateUnavailable
|
||||||
|
? 'Status nicht verfügbar.'
|
||||||
|
: elevator.working
|
||||||
|
? 'Funktionsfähig'
|
||||||
|
: 'Außer Betrieb'}">
|
||||||
|
</span>`;
|
||||||
|
|
||||||
|
let linesTemplate = '';
|
||||||
|
linesTemplate = `<div class="firstRow hiddenOnDesktop">${stateTemplate}`;
|
||||||
|
if (elevator.lines.length) {
|
||||||
|
linesTemplate = `<div class="firstRow">${stateTemplate}`;
|
||||||
|
linesTemplate += `<div class="lineList">Linien: `;
|
||||||
|
for (const line of elevator.lines) {
|
||||||
|
linesTemplate += `<span data-type="${line.type}" data-line="${line.line}" class="lineChip">${line.line}</span>`;
|
||||||
|
}
|
||||||
|
linesTemplate += '</div>';
|
||||||
}
|
}
|
||||||
linesTemplate += '</div>';
|
linesTemplate += '</div>';
|
||||||
|
|
||||||
|
@ -264,41 +437,32 @@ function renderData() {
|
||||||
|
|
||||||
let osmTemplate = '';
|
let osmTemplate = '';
|
||||||
if (osmData) {
|
if (osmData) {
|
||||||
const nodes = osmData.elements.filter(node => node.id === elevator.osmNodeId)
|
const node = osmData.nodes[elevator.osmNodeId]
|
||||||
if (nodes.length) {
|
if (node) {
|
||||||
const nodeInfo = nodes[0];
|
|
||||||
if (nodeInfo.hasOwnProperty('tags')) {
|
|
||||||
const tags = nodeInfo['tags'];
|
|
||||||
if (tags['highway'] === 'elevator') {
|
|
||||||
osmTemplate = '<dl>';
|
|
||||||
osmTemplate += `<div>
|
|
||||||
<dt><span data-icon="location" class="size-l"></span>Link zur Karte</dt>
|
|
||||||
<dd>
|
|
||||||
<a href="https://www.openstreetmap.org/node/${elevator.osmNodeId}" target="_blank">
|
|
||||||
Auf Karte anzeigen
|
|
||||||
</a>
|
|
||||||
</dd>
|
|
||||||
</div>`;
|
|
||||||
if (tags.hasOwnProperty('description')) {
|
|
||||||
osmTemplate += `<div><dt><span data-icon="info" class="size-l"></span>Beschreibung</dt><dd>${tags['description']}</dd></div>`;
|
|
||||||
}
|
|
||||||
if (tags.hasOwnProperty('level')) {
|
|
||||||
osmTemplate += `<div><dt><span data-icon="up-down" class="size-l"></span>Ebenen</dt><dd>${tags['level'].split(';').sort().join(', ')}</dd></div>`;
|
|
||||||
}
|
|
||||||
if (tags.hasOwnProperty('wheelchair')) {
|
|
||||||
osmTemplate += `<div><dt><span data-icon="wheelchair" class="size-l"></span>Rollstühle</dt><dd>${tags['wheelchair'] === 'yes' ? 'Ja' : 'Nein'}</dd></div>`;
|
|
||||||
}
|
|
||||||
if (tags.hasOwnProperty('bicycle')) {
|
|
||||||
osmTemplate += `<div><dt><span data-icon="bicycle" class="size-l"></span>Fahrräder</dt><dd>${tags['bicycle'] === 'yes' ? 'Ja' : 'Nein'}</dd></div>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
osmTemplate += '</dl>';
|
osmTemplate = '<dl>';
|
||||||
} else {
|
osmTemplate += `<div>
|
||||||
console.warn(`OSM Node is not an elevator. At:\t${station.name}\t${elevator.label} (NodeID: ${elevator.osmNodeId})`);
|
<dt><span data-icon="location" class="size-l"></span>Link zur Karte</dt>
|
||||||
}
|
<dd>
|
||||||
} else {
|
<a href="https://www.openstreetmap.org/node/${elevator.osmNodeId}" target="_blank">
|
||||||
console.warn(`OSM Node has no Tags. At:\t${station.name}\t${elevator.label} (NodeID: ${elevator.osmNodeId})`);
|
Auf Karte anzeigen
|
||||||
|
</a>
|
||||||
|
</dd>
|
||||||
|
</div>`;
|
||||||
|
if (node.tags.hasOwnProperty('description')) {
|
||||||
|
osmTemplate += `<div><dt><span data-icon="info" class="size-l"></span>Beschreibung</dt><dd>${node.tags['description']}</dd></div>`;
|
||||||
}
|
}
|
||||||
|
if (node.tags.hasOwnProperty('level')) {
|
||||||
|
osmTemplate += `<div><dt><span data-icon="up-down" class="size-l"></span>Ebenen</dt><dd>${node.tags['level'].split(';').sort().join(', ')}</dd></div>`;
|
||||||
|
}
|
||||||
|
if (node.tags.hasOwnProperty('wheelchair')) {
|
||||||
|
osmTemplate += `<div><dt><span data-icon="wheelchair" class="size-l"></span>Rollstühle</dt><dd>${node.tags['wheelchair'] === 'yes' ? 'Ja' : 'Nein'}</dd></div>`;
|
||||||
|
}
|
||||||
|
if (node.tags.hasOwnProperty('bicycle')) {
|
||||||
|
osmTemplate += `<div><dt><span data-icon="bicycle" class="size-l"></span>Fahrräder</dt><dd>${node.tags['bicycle'] === 'yes' ? 'Ja' : 'Nein'}</dd></div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
osmTemplate += '</dl>';
|
||||||
} else {
|
} else {
|
||||||
console.warn(`OSM Node not found (deleted). At:\t${station.name}\t${elevator.label} (NodeID: ${elevator.osmNodeId})`);
|
console.warn(`OSM Node not found (deleted). At:\t${station.name}\t${elevator.label} (NodeID: ${elevator.osmNodeId})`);
|
||||||
}
|
}
|
||||||
|
@ -310,19 +474,10 @@ function renderData() {
|
||||||
previewTemplate += `<span data-icon="${elevator.working || elevator.stateUnavailable ? 'elevator' : 'elevator-slash'}"
|
previewTemplate += `<span data-icon="${elevator.working || elevator.stateUnavailable ? 'elevator' : 'elevator-slash'}"
|
||||||
class="size-l ${elevator.working ? 'text-green' : elevator.stateUnavailable ? 'text-orange' : 'text-red'}"></span>`
|
class="size-l ${elevator.working ? 'text-green' : elevator.stateUnavailable ? 'text-orange' : 'text-red'}"></span>`
|
||||||
|
|
||||||
|
|
||||||
elevatorsTemplate += `<li class="elevator">
|
elevatorsTemplate += `<li class="elevator">
|
||||||
<span data-icon="${elevator.working || elevator.stateUnavailable ? 'elevator' : 'elevator-slash'}"
|
${stateTemplate}
|
||||||
class="size-xl ${elevator.working ? 'text-green' : elevator.stateUnavailable ? 'text-orange' : 'text-red'}"
|
|
||||||
role="img"
|
|
||||||
aria-label="${elevator.stateUnavailable
|
|
||||||
? 'Status nicht verfügbar.'
|
|
||||||
: elevator.working
|
|
||||||
? 'Funktionsfähig'
|
|
||||||
: 'Außer Betrieb'}">
|
|
||||||
</span>
|
|
||||||
<div class="elevatorData">
|
<div class="elevatorData">
|
||||||
${elevator.lines.length ? `${linesTemplate}` : ''}
|
${linesTemplate}
|
||||||
${elevator.instCause !== '' ? `<div class="elevatorInfo">${elevator.instCause}</div>` : ''}
|
${elevator.instCause !== '' ? `<div class="elevatorInfo">${elevator.instCause}</div>` : ''}
|
||||||
${elevator.levels.length ? levelsTemplate : elevator.description}
|
${elevator.levels.length ? levelsTemplate : elevator.description}
|
||||||
<dl>
|
<dl>
|
||||||
|
@ -365,11 +520,14 @@ function renderData() {
|
||||||
</li>`;
|
</li>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const template = `<li class="station" id="station_${stationIndex}">
|
const template = `<li class="station" id="station_${station.id}">
|
||||||
<div class="stationSummary">
|
<div class="stationSummary">
|
||||||
|
<div class="symbol">
|
||||||
<div class="typeList">
|
<div class="typeList">
|
||||||
${station.types.sort().map(t => `<span class="typeChip" data-type="${t}">${t}</span>`).join('')}
|
${station.types.sort().map(t => `<span class="typeChip" data-type="${t}">${t}</span>`).join('')}
|
||||||
</div>
|
</div>
|
||||||
|
${typeof station.distance !== 'undefined' ? `<div class="distance"><b>${Math.round(station.distance / 100) / 10}</b><br>km</div>` : ''}
|
||||||
|
</div>
|
||||||
<div class="stationTitle">
|
<div class="stationTitle">
|
||||||
<h3>${station.name}</h3>
|
<h3>${station.name}</h3>
|
||||||
<div class="elevator-preview" role="img"
|
<div class="elevator-preview" role="img"
|
||||||
|
@ -380,11 +538,11 @@ ${station.state.unavailable ? `Bei ${station.state.unavailable} ${station.state.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<details data-stationid="${stationIndex}" ${openStations.has(stationIndex) ? 'open' : ''}>
|
<details data-stationid="${station.id}" ${openStations.has(station.id) ? 'open' : ''}>
|
||||||
<summary>
|
<summary>
|
||||||
Aufzüge anzeigen
|
Aufzüge anzeigen
|
||||||
</summary>
|
</summary>
|
||||||
<ul class="elevatorList collapsed" aria-expanded="false" id="station_${stationIndex}_elevatorList">
|
<ul class="elevatorList collapsed" aria-expanded="false" id="station_${station.id}_elevatorList">
|
||||||
${elevatorsTemplate}
|
${elevatorsTemplate}
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
|
@ -393,7 +551,7 @@ ${station.state.unavailable ? `Bei ${station.state.unavailable} ${station.state.
|
||||||
|
|
||||||
//immediate invocation
|
//immediate invocation
|
||||||
(function () {
|
(function () {
|
||||||
listContainer.querySelectorAll(`#station_${stationIndex} .loadOSM`).forEach(e => {
|
listContainer.querySelectorAll(`#station_${station.id} .loadOSM`).forEach(e => {
|
||||||
e.addEventListener('click', (ev) => {
|
e.addEventListener('click', (ev) => {
|
||||||
ev.target.querySelector('.spinner').classList.remove('hidden');
|
ev.target.querySelector('.spinner').classList.remove('hidden');
|
||||||
loadOsmData().then(() => {
|
loadOsmData().then(() => {
|
||||||
|
@ -416,6 +574,8 @@ ${station.state.unavailable ? `Bei ${station.state.unavailable} ${station.state.
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
|
filterData();
|
||||||
}
|
}
|
||||||
|
|
||||||
document.querySelector('#loadElevators')
|
document.querySelector('#loadElevators')
|
||||||
|
@ -424,7 +584,6 @@ document.querySelector('#loadElevators')
|
||||||
loadElevators().then(() => {
|
loadElevators().then(() => {
|
||||||
e.target.querySelector('.spinner').classList.add('hidden');
|
e.target.querySelector('.spinner').classList.add('hidden');
|
||||||
renderData();
|
renderData();
|
||||||
filterData();
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -434,19 +593,65 @@ document.querySelector('#initialLoad')
|
||||||
loadElevators().then(() => {
|
loadElevators().then(() => {
|
||||||
e.target.classList.add('hidden');
|
e.target.classList.add('hidden');
|
||||||
renderData();
|
renderData();
|
||||||
filterData();
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
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 {
|
||||||
|
// If geolocation is already set.
|
||||||
|
// If not the location watcher will re-render our data.
|
||||||
|
if (geolocation !== null) {
|
||||||
|
renderData(geolocation)
|
||||||
|
}
|
||||||
|
sortByDistance = e.target.ariaPressed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sortByDistance = e.target.ariaPressed = false;
|
||||||
|
|
||||||
|
renderData();
|
||||||
|
}
|
||||||
|
e.target.querySelector('.spinner').classList.add('hidden');
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
function filterData() {
|
function filterData() {
|
||||||
const searchString = document.querySelector('#searchStation').value;
|
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.ariaPressed === 'true') activeTypes.push('U');
|
||||||
|
if(typeS.ariaPressed === 'true') activeTypes.push('S');
|
||||||
|
if(typeA.ariaPressed === 'true') activeTypes.push('A');
|
||||||
|
if(typeR.ariaPressed === 'true') activeTypes.push('R');
|
||||||
if (internalData) {
|
if (internalData) {
|
||||||
for (const stationIndex in internalData.stations) {
|
for (const stationIndex in internalData.stations) {
|
||||||
const matches = internalData.stations[stationIndex].name.toLowerCase().search(searchString.toLowerCase()) >= 0;
|
const matchesSearch = internalData.stations[stationIndex].name.toLowerCase().search(searchString.toLowerCase()) >= 0;
|
||||||
document.querySelector(`#station_${stationIndex}`).classList.toggle('hidden', !matches);
|
let matchesType = false;
|
||||||
|
internalData.stations[stationIndex].types.forEach(type => {
|
||||||
|
if(activeTypes.includes(type)) matchesType = true;
|
||||||
|
})
|
||||||
|
document.querySelector(`#station_${stationIndex}`).classList.toggle('hidden', !(matchesSearch && matchesType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -455,4 +660,36 @@ document.querySelector('#searchStation').addEventListener('input', (e) => {
|
||||||
filterData();
|
filterData();
|
||||||
})
|
})
|
||||||
|
|
||||||
filterData()
|
document.querySelectorAll('button.typeChip').forEach(e => {
|
||||||
|
e.addEventListener('click', (event) => {
|
||||||
|
e.ariaPressed = e.ariaPressed === 'true' ? 'false' : 'true';
|
||||||
|
filterData();
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
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')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 === 'v1') {
|
||||||
|
if (check_osm === null || check_osm.hasOwnProperty('api') && check_osm.api === 'v1') {
|
||||||
|
renderData();
|
||||||
|
} else {
|
||||||
|
console.log('osm_data: version mismatch')
|
||||||
|
localStorage.removeItem('osm_data');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log('internal_data: version mismatch')
|
||||||
|
localStorage.removeItem('internal_data');
|
||||||
|
}
|
||||||
|
|
37
index.html
37
index.html
|
@ -37,10 +37,17 @@
|
||||||
|
|
||||||
<div class="hidden" id="filters">
|
<div class="hidden" id="filters">
|
||||||
<input placeholder="Station suchen" id="searchStation">
|
<input placeholder="Station suchen" id="searchStation">
|
||||||
<button id="stationsNearMe">
|
<button id="stationsNearMe" aria-pressed="false">
|
||||||
<span data-icon="location-searching" class="size-m"></span>
|
<span data-icon="location-searching" class="size-m"></span>
|
||||||
Nach Entfernung sortieren
|
Nach Entfernung sortieren
|
||||||
|
<span data-icon="load" class="size-m spinner hidden"></span>
|
||||||
</button>
|
</button>
|
||||||
|
<div id="typeFilter">
|
||||||
|
<button class="typeChip" data-type="U" aria-pressed="true">U</button>
|
||||||
|
<button class="typeChip" data-type="S" aria-pressed="true">S</button>
|
||||||
|
<button class="typeChip" data-type="A" aria-pressed="true">A</button>
|
||||||
|
<button class="typeChip" data-type="R" aria-pressed="true">R</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button id="initialLoad">
|
<button id="initialLoad">
|
||||||
|
@ -48,12 +55,38 @@
|
||||||
<span data-icon="load" class="size-m spinner hidden"></span>
|
<span data-icon="load" class="size-m spinner hidden"></span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<div class="hidden" id="errorMessage">
|
||||||
|
Leider ist ein Fehler beim Abrufen der Daten aufgetreten.
|
||||||
|
</div>
|
||||||
|
|
||||||
<ul id="stationList">
|
<ul id="stationList">
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
<footer>
|
<footer>
|
||||||
Website by <a href="https://kritzl.dev/">kritzl</a> • <a href="https://mafiasi.de/base/imprint" target="_blank">Impressum</a>
|
<p>
|
||||||
|
hvvstuhl v0.4 •
|
||||||
|
Entwickelt von <a href="https://kritzl.dev/">kritzl</a> & <a href="https://traumweh.dev/">traumweh</a> •
|
||||||
|
Betrieben von <a href="https://mafiasi.de/">mafiasi</a> •
|
||||||
|
<a href="https://mafiasi.de/base/imprint">Impressum</a>
|
||||||
|
</p>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
<div id="dialog_layer" class="dialogs">
|
||||||
|
<div role="dialog" id="dialog_osm" aria-labelledby="dialog_osm_label" aria-modal="true" class="">
|
||||||
|
<h2 id="dialog_osm_label" class="dialog_label">IPv4 RDAP Info</h2>
|
||||||
|
<button onclick="closeDialog('#dialog_osm')" class="close-modal">x</button>
|
||||||
|
<hr>
|
||||||
|
<p>
|
||||||
|
Um die Stationen nach Entfernung sortieren zu können müssen zusätzliche Daten von OpenStreetMap geladen
|
||||||
|
werden.
|
||||||
|
</p>
|
||||||
|
<button id="loadOsm">
|
||||||
|
Zusätzliche Daten von OpenStreetMap abrufen
|
||||||
|
<span data-icon="load" class="size-m spinner hidden"></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<script type="text/javascript" src="elevators.js"></script>
|
<script type="text/javascript" src="elevators.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
209
style.css
209
style.css
|
@ -10,6 +10,18 @@
|
||||||
--color-gray-800: hsl(12, 6%, 15%);
|
--color-gray-800: hsl(12, 6%, 15%);
|
||||||
--color-gray-900: hsl(24, 10%, 10%);
|
--color-gray-900: hsl(24, 10%, 10%);
|
||||||
--color-gray-950: hsl(20, 14%, 4%);
|
--color-gray-950: hsl(20, 14%, 4%);
|
||||||
|
--color-red: #971616;
|
||||||
|
--color-orange: #cc6300;
|
||||||
|
--color-green: #19942e;
|
||||||
|
--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);
|
||||||
--bg: var(--color-gray-50);
|
--bg: var(--color-gray-50);
|
||||||
--text: var(--color-gray-950);
|
--text: var(--color-gray-950);
|
||||||
--text-secondary: var(--color-gray-700);
|
--text-secondary: var(--color-gray-700);
|
||||||
|
@ -52,23 +64,64 @@
|
||||||
--station-border: var(--color-gray-600);
|
--station-border: var(--color-gray-600);
|
||||||
--station-border-hover: var(--color-gray-400);
|
--station-border-hover: var(--color-gray-400);
|
||||||
--elevator-bg: var(--color-gray-900);
|
--elevator-bg: var(--color-gray-900);
|
||||||
|
--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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
background: rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
.dialogs.active {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
[role=dialog] {
|
||||||
|
box-sizing: border-box;
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 1rem;
|
||||||
|
background-color: var(--background);
|
||||||
|
color: var(--color);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
[role=dialog] button.close-modal {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.hidden {
|
.hidden {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-red {
|
.text-red {
|
||||||
color: #971616;
|
color: var(--color-red);
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-orange {
|
.text-orange {
|
||||||
color: #cc6300;
|
color: var(--color-orange);
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-green {
|
.text-green {
|
||||||
color: #19942e;
|
color: var(--color-green);
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
@ -125,6 +178,8 @@ main {
|
||||||
}
|
}
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
margin: 1em auto;
|
margin: 1em auto;
|
||||||
max-width: 960px;
|
max-width: 960px;
|
||||||
}
|
}
|
||||||
|
@ -147,6 +202,9 @@ button:hover {
|
||||||
background-color: var(--station-bg-hover);
|
background-color: var(--station-bg-hover);
|
||||||
border-color: var(--station-border-hover);
|
border-color: var(--station-border-hover);
|
||||||
}
|
}
|
||||||
|
button[aria-pressed=true] {
|
||||||
|
background-color: var(--nav-bg-visited);
|
||||||
|
}
|
||||||
button.size-s {
|
button.size-s {
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
padding: var(--space-s) var(--space-m);
|
padding: var(--space-s) var(--space-m);
|
||||||
|
@ -168,12 +226,23 @@ div#updateInfo {
|
||||||
|
|
||||||
div#filters {
|
div#filters {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
gap: var(--space-m);
|
gap: var(--space-m);
|
||||||
justify-items: stretch;
|
justify-content: stretch;
|
||||||
}
|
}
|
||||||
div#filters button, div#filters input {
|
div#filters button, div#filters input {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
}
|
}
|
||||||
|
div#filters > * {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 576px) {
|
||||||
|
div#filters > * {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
button#initialLoad {
|
button#initialLoad {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
|
@ -183,6 +252,14 @@ button.loadOSM {
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div#errorMessage {
|
||||||
|
border: solid 2px var(--color-red);
|
||||||
|
border-radius: var(--item-radius);
|
||||||
|
padding: var(--space-xl) var(--space-xl);
|
||||||
|
margin-top: var(--space-l);
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
ul#stationList {
|
ul#stationList {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
@ -202,9 +279,20 @@ ul#stationList > li.station > div.stationSummary {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: var(--space-m);
|
gap: var(--space-m);
|
||||||
}
|
}
|
||||||
ul#stationList > li.station > div.stationSummary div.typeList {
|
ul#stationList > li.station > div.stationSummary div.symbol {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
ul#stationList > li.station > div.stationSummary div.symbol div.typeList {
|
||||||
flex-shrink: 0;
|
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 {
|
ul#stationList > li.station > div.stationSummary div.stationTitle {
|
||||||
align-self: stretch;
|
align-self: stretch;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
@ -286,19 +374,26 @@ ul#stationList > li.station > details > ul > li.elevator {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: start;
|
align-items: start;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
padding: var(--space-m);
|
|
||||||
gap: var(--space-m);
|
gap: var(--space-m);
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 0 1rem 1rem;
|
margin: 0 var(--space-s) var(--space-s);
|
||||||
padding-right: var(--space-2xl);
|
padding: var(--space-s);
|
||||||
}
|
}
|
||||||
@media screen and (min-width: 576px) {
|
@media screen and (min-width: 576px) {
|
||||||
ul#stationList > li.station > details > ul > li.elevator {
|
ul#stationList > li.station > details > ul > li.elevator {
|
||||||
margin: 0 var(--space-2xl) 1rem;
|
margin: 0 var(--space-2xl) 1rem;
|
||||||
|
padding: var(--space-m);
|
||||||
|
padding-right: var(--space-2xl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ul#stationList > li.station > details > ul > li.elevator > span {
|
ul#stationList > li.station > details > ul > li.elevator > .stateIcon {
|
||||||
flex-shrink: 0;
|
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:not(:first-child):before {
|
ul#stationList > li.station > details > ul > li.elevator:not(:first-child):before {
|
||||||
content: "";
|
content: "";
|
||||||
|
@ -326,11 +421,25 @@ ul#stationList > li.station > details > ul > li.elevator > div.elevatorData .ele
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
grid-column: 1/-1;
|
grid-column: 1/-1;
|
||||||
}
|
}
|
||||||
ul#stationList > li.station > details > ul > li.elevator > div.elevatorData .lineList {
|
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 {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: var(--space-m);
|
gap: var(--space-m);
|
||||||
align-items: center;
|
align-items: center;
|
||||||
grid-column: 1/-1;
|
|
||||||
min-height: var(--space-2xl);
|
min-height: var(--space-2xl);
|
||||||
}
|
}
|
||||||
ul#stationList > li.station > details > ul > li.elevator > div.elevatorData hr {
|
ul#stationList > li.station > details > ul > li.elevator > div.elevatorData hr {
|
||||||
|
@ -350,6 +459,7 @@ ul#stationList > li.station > details > ul > li.elevator > div.elevatorData .osm
|
||||||
ul#stationList > li.station > details > ul > li.elevator > div.elevatorData .osm .osmHeading {
|
ul#stationList > li.station > details > ul > li.elevator > div.elevatorData .osm .osmHeading {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
gap: var(--space-l);
|
gap: var(--space-l);
|
||||||
margin-bottom: var(--space-l);
|
margin-bottom: var(--space-l);
|
||||||
}
|
}
|
||||||
|
@ -414,7 +524,7 @@ ul#stationList > li.station > details > ul > li.elevator > div.elevatorData dl d
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
min-width: 15ch;
|
min-width: 15ch;
|
||||||
}
|
}
|
||||||
@media (max-width: 576px) {
|
@media (max-width: 400px) {
|
||||||
ul#stationList > li.station > details > ul > li.elevator > div.elevatorData dl div dt {
|
ul#stationList > li.station > details > ul > li.elevator > div.elevatorData dl div dt {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
@ -430,66 +540,101 @@ ul#stationList > li.station > details > ul > li.elevator > div.elevatorData dl d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
span.lineChip, span.typeChip {
|
span.lineChip, span.typeChip, button.typeChip {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
span.lineChip[data-type=U], span.typeChip[data-type=U] {
|
span.lineChip[data-type=U], span.typeChip[data-type=U], button.typeChip[data-type=U] {
|
||||||
background-color: #006ab3;
|
background-color: var(--bg-type-u);
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
span.lineChip[data-type=U][data-line=U1], span.typeChip[data-type=U][data-line=U1] {
|
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: #006ab3;
|
background-color: #006ab3;
|
||||||
}
|
}
|
||||||
span.lineChip[data-type=U][data-line=U2], span.typeChip[data-type=U][data-line=U2] {
|
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: #e2001a;
|
background-color: #e2001a;
|
||||||
}
|
}
|
||||||
span.lineChip[data-type=U][data-line=U3], span.typeChip[data-type=U][data-line=U3] {
|
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: #ffdd00;
|
background-color: #ffdd00;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
}
|
}
|
||||||
span.lineChip[data-type=U][data-line=U4], span.typeChip[data-type=U][data-line=U4] {
|
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: #0098a1;
|
background-color: #0098a1;
|
||||||
}
|
}
|
||||||
span.lineChip[data-type=S], span.typeChip[data-type=S] {
|
span.lineChip[data-type=S], span.typeChip[data-type=S], button.typeChip[data-type=S] {
|
||||||
background-color: #1a962b;
|
background-color: var(--bg-type-s);
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
span.lineChip[data-type=S][data-line=S1], span.typeChip[data-type=S][data-line=S1] {
|
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: #1a962b;
|
background-color: #1a962b;
|
||||||
}
|
}
|
||||||
span.lineChip[data-type=S][data-line=S2], span.typeChip[data-type=S][data-line=S2] {
|
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: #b51143;
|
background-color: #b51143;
|
||||||
}
|
}
|
||||||
span.lineChip[data-type=S][data-line=S3], span.typeChip[data-type=S][data-line=S3] {
|
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: #622181;
|
background-color: #622181;
|
||||||
}
|
}
|
||||||
span.lineChip[data-type=S][data-line=S4], span.typeChip[data-type=S][data-line=S4] {
|
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: #be148e;
|
background-color: #be148e;
|
||||||
}
|
}
|
||||||
span.lineChip[data-type=S][data-line=S5], span.typeChip[data-type=S][data-line=S5] {
|
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: #0089bb;
|
background-color: #0089bb;
|
||||||
}
|
}
|
||||||
span.lineChip[data-type=S][data-line=S6], span.typeChip[data-type=S][data-line=S6] {
|
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: #d3da00;
|
background-color: #d3da00;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
}
|
}
|
||||||
span.lineChip[data-type=A], span.typeChip[data-type=A] {
|
span.lineChip[data-type=A], span.typeChip[data-type=A], button.typeChip[data-type=A] {
|
||||||
background-color: #f39100;
|
background-color: var(--bg-type-a);
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
span.lineChip[data-type=R], span.typeChip[data-type=R] {
|
span.lineChip[data-type=R], span.typeChip[data-type=R], button.typeChip[data-type=R] {
|
||||||
background-color: #000000;
|
background-color: var(--bg-type-r);
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
span.lineChip[data-type=R], span.typeChip[data-type=R] {
|
span.lineChip[data-type=R], span.typeChip[data-type=R], button.typeChip[data-type=R] {
|
||||||
border: solid 2px #ffffff;
|
border: solid 2px #ffffff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div#typeFilter {
|
||||||
|
display: flex;
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
flex-shrink: 0;
|
||||||
|
min-height: var(--space-2xl);
|
||||||
|
gap: var(--space-m);
|
||||||
|
}
|
||||||
|
div#typeFilter button.typeChip {
|
||||||
|
padding: 0;
|
||||||
|
height: 100%;
|
||||||
|
aspect-ratio: 1/1;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
div#typeFilter button.typeChip[data-type=U], div#typeFilter button.typeChip[data-type=S], div#typeFilter button.typeChip[data-type=A], div#typeFilter button.typeChip[data-type=R] {
|
||||||
|
border: solid 2px var(--station-border);
|
||||||
|
}
|
||||||
|
div#typeFilter button.typeChip[data-type=U][aria-pressed=false], div#typeFilter button.typeChip[data-type=S][aria-pressed=false], div#typeFilter button.typeChip[data-type=A][aria-pressed=false], div#typeFilter button.typeChip[data-type=R][aria-pressed=false] {
|
||||||
|
background-color: var(--color-gray-500);
|
||||||
|
color: var(--color-type-disabled);
|
||||||
|
}
|
||||||
|
div#typeFilter button.typeChip[data-type=U][aria-pressed=false][data-type=U], div#typeFilter button.typeChip[data-type=S][aria-pressed=false][data-type=U], div#typeFilter button.typeChip[data-type=A][aria-pressed=false][data-type=U], div#typeFilter button.typeChip[data-type=R][aria-pressed=false][data-type=U] {
|
||||||
|
background-color: var(--bg-type-u-disabled);
|
||||||
|
}
|
||||||
|
div#typeFilter button.typeChip[data-type=U][aria-pressed=false][data-type=S], div#typeFilter button.typeChip[data-type=S][aria-pressed=false][data-type=S], div#typeFilter button.typeChip[data-type=A][aria-pressed=false][data-type=S], div#typeFilter button.typeChip[data-type=R][aria-pressed=false][data-type=S] {
|
||||||
|
background-color: var(--bg-type-s-disabled);
|
||||||
|
}
|
||||||
|
div#typeFilter button.typeChip[data-type=U][aria-pressed=false][data-type=A], div#typeFilter button.typeChip[data-type=S][aria-pressed=false][data-type=A], div#typeFilter button.typeChip[data-type=A][aria-pressed=false][data-type=A], div#typeFilter button.typeChip[data-type=R][aria-pressed=false][data-type=A] {
|
||||||
|
background-color: var(--bg-type-a-disabled);
|
||||||
|
}
|
||||||
|
div#typeFilter button.typeChip[data-type=U][aria-pressed=false][data-type=R], div#typeFilter button.typeChip[data-type=S][aria-pressed=false][data-type=R], div#typeFilter button.typeChip[data-type=A][aria-pressed=false][data-type=R], div#typeFilter button.typeChip[data-type=R][aria-pressed=false][data-type=R] {
|
||||||
|
background-color: var(--bg-type-r-disabled);
|
||||||
|
}
|
||||||
|
|
||||||
span.lineChip {
|
span.lineChip {
|
||||||
padding: 0.3em 0.6em;
|
padding: 0.3em 0.6em;
|
||||||
min-width: 4ch;
|
min-width: 4ch;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"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;EACA;;AAzBA;EA/BF;IAgCI;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;;;AAcJ;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;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;;AAGF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;AAGF;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;EAKA;;AAJA;EATF;IAUI;;;AAMF;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;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAQA;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;;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;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;EACE;IACE","file":"style.css"}
|
{"version":3,"sourceRoot":"","sources":["style.scss"],"names":[],"mappings":"AAMA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EAOA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EA0BA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAhCA;EAjDF;IAkDI;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;;;;AAgBF;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAKJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGE;EACE;EACA;EACA;;;AAKN;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;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;;AACA;EAJF;IAKI;;;;AAKN;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAWA;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;;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;EAEA;EACA;;AACA;EATF;IAUI;IACA;IACA;;;AAIF;EACE;EACA;;AACA;EAHF;IAII;;;AAKJ;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;;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;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AACA;EACE;;AACA;EACE;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;;AAQV;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;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;EACE;IACE","file":"style.css"}
|
229
style.scss
229
style.scss
|
@ -1,4 +1,7 @@
|
||||||
|
@use 'sass:color';
|
||||||
|
|
||||||
$mobileBreakpoint: 576px;
|
$mobileBreakpoint: 576px;
|
||||||
|
$smallBreakpoint: 400px;
|
||||||
$mediumBreakpoint: 800px;
|
$mediumBreakpoint: 800px;
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
|
@ -14,6 +17,24 @@ $mediumBreakpoint: 800px;
|
||||||
--color-gray-900: hsl(24, 10%, 10%);
|
--color-gray-900: hsl(24, 10%, 10%);
|
||||||
--color-gray-950: hsl(20, 14%, 4%);
|
--color-gray-950: hsl(20, 14%, 4%);
|
||||||
|
|
||||||
|
--color-red: #971616;
|
||||||
|
--color-orange: #cc6300;
|
||||||
|
--color-green: #19942e;
|
||||||
|
|
||||||
|
|
||||||
|
$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);
|
||||||
|
|
||||||
--bg: var(--color-gray-50);
|
--bg: var(--color-gray-50);
|
||||||
--text: var(--color-gray-950);
|
--text: var(--color-gray-950);
|
||||||
|
@ -47,6 +68,13 @@ $mediumBreakpoint: 800px;
|
||||||
--station-border: var(--color-gray-600);
|
--station-border: var(--color-gray-600);
|
||||||
--station-border-hover: var(--color-gray-400);
|
--station-border-hover: var(--color-gray-400);
|
||||||
--elevator-bg: var(--color-gray-900);
|
--elevator-bg: var(--color-gray-900);
|
||||||
|
|
||||||
|
--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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
--elevator-list-gap: 3rem;
|
--elevator-list-gap: 3rem;
|
||||||
|
@ -60,20 +88,63 @@ $mediumBreakpoint: 800px;
|
||||||
--space-2xl: 3rem;
|
--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;
|
||||||
|
background: rgb(0 0 0 / 30%);
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[role="dialog"] {
|
||||||
|
box-sizing: border-box;
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 1rem;
|
||||||
|
background-color: var(--background);
|
||||||
|
color: var(--color);
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
button {
|
||||||
|
&.close-modal {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.hidden {
|
.hidden {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-red {
|
.text-red {
|
||||||
color: #971616;
|
color: var(--color-red);
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-orange {
|
.text-orange {
|
||||||
color: #cc6300;
|
color: var(--color-orange);
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-green {
|
.text-green {
|
||||||
color: #19942e;
|
color: var(--color-green);
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
@ -142,6 +213,8 @@ main {
|
||||||
}
|
}
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
margin: 1em auto;
|
margin: 1em auto;
|
||||||
max-width: 960px;
|
max-width: 960px;
|
||||||
}
|
}
|
||||||
|
@ -165,6 +238,10 @@ button {
|
||||||
border-color: var(--station-border-hover);
|
border-color: var(--station-border-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&[aria-pressed='true'] {
|
||||||
|
background-color: var(--nav-bg-visited);
|
||||||
|
}
|
||||||
|
|
||||||
&.size-s {
|
&.size-s {
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
padding: var(--space-s) var(--space-m);
|
padding: var(--space-s) var(--space-m);
|
||||||
|
@ -189,12 +266,22 @@ div#updateInfo {
|
||||||
|
|
||||||
div#filters {
|
div#filters {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
gap: var(--space-m);
|
gap: var(--space-m);
|
||||||
justify-items: stretch;
|
justify-content: stretch;
|
||||||
|
|
||||||
button, input {
|
button, input {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
> * {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
@media screen and (min-width: $mobileBreakpoint) {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
button#initialLoad {
|
button#initialLoad {
|
||||||
|
@ -205,6 +292,14 @@ button.loadOSM {
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div#errorMessage {
|
||||||
|
border: solid 2px var(--color-red);
|
||||||
|
border-radius: var(--item-radius);
|
||||||
|
padding: var(--space-xl) var(--space-xl);
|
||||||
|
margin-top: var(--space-l);
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
ul#stationList {
|
ul#stationList {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
@ -220,12 +315,35 @@ ul#stationList {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: var(--space-m);
|
padding: var(--space-m);
|
||||||
|
|
||||||
|
//div.distance {
|
||||||
|
// display: flex;
|
||||||
|
// justify-content: center;
|
||||||
|
// font-size: 0.8rem;
|
||||||
|
// color: var(--text-secondary);
|
||||||
|
// position: absolute;
|
||||||
|
// width: 100%;
|
||||||
|
//}
|
||||||
|
|
||||||
> div.stationSummary {
|
> div.stationSummary {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: var(--space-m);
|
gap: var(--space-m);
|
||||||
|
|
||||||
div.typeList {
|
div.symbol {
|
||||||
flex-shrink: 0;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -318,20 +436,24 @@ ul#stationList {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: start;
|
align-items: start;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
padding: var(--space-m);
|
|
||||||
gap: var(--space-m);
|
gap: var(--space-m);
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
margin: 0 1rem 1rem;
|
margin: 0 var(--space-s) var(--space-s);
|
||||||
|
padding: var(--space-s);
|
||||||
@media screen and (min-width: $mobileBreakpoint) {
|
@media screen and (min-width: $mobileBreakpoint) {
|
||||||
margin: 0 var(--space-2xl) 1rem;
|
margin: 0 var(--space-2xl) 1rem;
|
||||||
|
padding: var(--space-m);
|
||||||
|
padding-right: var(--space-2xl);
|
||||||
}
|
}
|
||||||
|
|
||||||
padding-right: var(--space-2xl);
|
|
||||||
|
|
||||||
// elevator icon
|
// elevator icon
|
||||||
> span {
|
> .stateIcon {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
display: none;
|
||||||
|
@media screen and (min-width: $mobileBreakpoint) {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// divider between elevators
|
// divider between elevators
|
||||||
|
@ -362,14 +484,33 @@ ul#stationList {
|
||||||
grid-column: 1 / -1;
|
grid-column: 1 / -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lineList {
|
div.firstRow {
|
||||||
|
grid-column: 1 / -1;
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: var(--space-m);
|
gap: var(--space-m);
|
||||||
align-items: center;
|
|
||||||
grid-column: 1 / -1;
|
&.hiddenOnDesktop {
|
||||||
min-height: var(--space-2xl);
|
@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 {
|
hr {
|
||||||
grid-column: 1 / -1;
|
grid-column: 1 / -1;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -385,9 +526,10 @@ ul#stationList {
|
||||||
border-radius: var(--item-radius);
|
border-radius: var(--item-radius);
|
||||||
padding: var(--space-l);
|
padding: var(--space-l);
|
||||||
|
|
||||||
.osmHeading{
|
.osmHeading {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
gap: var(--space-l);
|
gap: var(--space-l);
|
||||||
margin-bottom: var(--space-l);
|
margin-bottom: var(--space-l);
|
||||||
|
|
||||||
|
@ -397,7 +539,6 @@ ul#stationList {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dl {
|
dl {
|
||||||
div {
|
div {
|
||||||
dt {
|
dt {
|
||||||
|
@ -474,7 +615,7 @@ ul#stationList {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
min-width: 15ch;
|
min-width: 15ch;
|
||||||
|
|
||||||
@media (max-width: $mobileBreakpoint) {
|
@media (max-width: $smallBreakpoint) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -498,14 +639,14 @@ ul#stationList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
span.lineChip, span.typeChip {
|
span.lineChip, span.typeChip, button.typeChip {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
&[data-type="U"] {
|
&[data-type="U"] {
|
||||||
background-color: #006ab3;
|
background-color: var(--bg-type-u);
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
|
|
||||||
&[data-line="U1"] {
|
&[data-line="U1"] {
|
||||||
|
@ -527,7 +668,7 @@ span.lineChip, span.typeChip {
|
||||||
}
|
}
|
||||||
|
|
||||||
&[data-type="S"] {
|
&[data-type="S"] {
|
||||||
background-color: #1a962b;
|
background-color: var(--bg-type-s);
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
|
|
||||||
&[data-line="S1"] {
|
&[data-line="S1"] {
|
||||||
|
@ -557,12 +698,12 @@ span.lineChip, span.typeChip {
|
||||||
}
|
}
|
||||||
|
|
||||||
&[data-type="A"] {
|
&[data-type="A"] {
|
||||||
background-color: #f39100;
|
background-color: var(--bg-type-a);
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
&[data-type="R"] {
|
&[data-type="R"] {
|
||||||
background-color: #000000;
|
background-color: var(--bg-type-r);
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
|
@ -571,6 +712,48 @@ span.lineChip, span.typeChip {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
div#typeFilter{
|
||||||
|
display: flex;
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
flex-shrink: 0;
|
||||||
|
min-height: var(--space-2xl);
|
||||||
|
gap: var(--space-m);
|
||||||
|
|
||||||
|
button.typeChip {
|
||||||
|
padding: 0;
|
||||||
|
height: 100%;
|
||||||
|
aspect-ratio: 1/1;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
&[data-type="U"], &[data-type="S"], &[data-type="A"], &[data-type="R"] {
|
||||||
|
border: solid 2px var(--station-border);
|
||||||
|
&[aria-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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
span.lineChip {
|
span.lineChip {
|
||||||
padding: 0.3em 0.6em;
|
padding: 0.3em 0.6em;
|
||||||
min-width: 4ch;
|
min-width: 4ch;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue