ctucx.git: trainsearch

web based trip-planner, fork of https://cyberchaos.dev/yuka/trainsearch

commit c51a43883564187c886d2ad065cd84dd9f75c6f5
parent 233f9b7890c2b5add9460d750bc6bf32bc9c552f
Author: Katja (ctucx) <git@ctu.cx>
Date: Tue, 21 Jan 2025 12:20:57 +0100

static/style.css: big refactoring
10 files changed, 752 insertions(+), 767 deletions(-)
M
src/departuresView.js
|
14
+++++++-------
M
src/helpers.js
|
16
++++++++--------
M
src/journeyView.js
|
35
++++++++++++-----------------------
M
src/journeysView.js
|
36
+++++++++++++++++-------------------
M
src/overlays.js
|
14
+++++++-------
M
src/searchView.js
|
106
+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
M
src/settingsView.js
|
4
++--
M
src/templates.js
|
2
+-
M
src/tripView.js
|
16
++++++++--------
M
static/style.css
|
1276
+++++++++++++++++++++++++++++++++++++++----------------------------------------
diff --git a/src/departuresView.js b/src/departuresView.js
@@ -15,11 +15,11 @@ const departuresTemplate = (data, profile) => {
 	return html`
 		<div class="departures">
 			<header>
-				<a class="back icon-back invisible"></a>
-				<div class="header-content">
+				<a class="icon-back hidden"></a>
+				<div class="content">
 					<h3>Departures from ${data.name}</h3>
 				</div>
-				<a class="reload icon-reload invisible">${t("reload")}</a>
+				<a class="icon-reload hidden">${t("reload")}</a>
 			</header>
 
 			<div class="card">

@@ -27,7 +27,7 @@ const departuresTemplate = (data, profile) => {
 				<thead>
 					<tr>
 						<th>Time</th>
-						<th class="station-column"></th>
+						<th class="station"></th>
 						<th>${t('platform')}</th>
 					</tr>
 				</thead>

@@ -85,14 +85,14 @@ export const departuresView = async (match, isUpdate) => {
 };
 
 const refreshJourneyView = async (refreshToken, profile) => {
-	document.querySelector('.reload').classList.add('spinning');
+	document.querySelector('.icon-reload').classList.add('spinning');
 	try {
 		await refreshJourney(refreshToken, profile);
 	} catch(e) {
 		showAlertModal(e.toString());
-		document.querySelector('.reload').classList.remove('spinning');
+		document.querySelector('.icon-reload').classList.remove('spinning');
 		throw e;
 	}
 	journeyView([profile, refreshToken], true);
-	document.querySelector('.reload').classList.remove('spinning');
+	document.querySelector('.icon-reload').classList.remove('spinning');
 };
diff --git a/src/helpers.js b/src/helpers.js
@@ -31,6 +31,14 @@ export const isValidDate = (date) => {
 		   composedDate.getFullYear() == y;
 };
 
+export const getFrom = journeys => {
+	return journeys[0].legs[0].origin;
+};
+
+export const getTo = journeys => {
+	return journeys[0].legs[journeys[0].legs.length-1].destination;
+};
+
 export const formatDateTime = (date, format) => {
 	if (format != null) {
 		switch (format) {

@@ -85,14 +93,6 @@ export const formatFromTo = obj => {
 		};
 };
 
-export const getFrom = journeys => {
-	return journeys[0].legs[0].origin;
-};
-
-export const getTo = journeys => {
-	return journeys[0].legs[journeys[0].legs.length-1].destination;
-};
-
 export const formatPrice = price => {
 	if (!price) return '-';
 	const currencies = { USD: '$', EUR: '€', GBP: '£' };
diff --git a/src/journeyView.js b/src/journeyView.js
@@ -37,22 +37,22 @@ const legTemplate = (leg, profile) => {
 						<td colspan="4">
 							<div class="train-details">
 								${lineAdditionalName(leg.line) ? html`
-									<div class="train-detail">
+									<div>
 										Trip: ${lineAdditionalName(leg.line)}
 									</div>
 								` : ''}
 								${leg.line.trainType ? html`
-									<div class="train-detail">
+									<div>
 										Train type: ${leg.line.trainType}
 									</div>
 								` : ''}
 								${(leg.arrival && leg.departure) ? html`
-									<div class="train-detail">
+									<div>
 										${t('duration')}: ${formatDuration(leg.arrival - leg.departure)}
 									</div>
 								` : ''}
 								${leg.loadFactor ? html`
-									<div class="train-detail">
+									<div>
 										${t("load-"+leg.loadFactor)}
 									</div>
 								` : ''}

@@ -62,7 +62,7 @@ const legTemplate = (leg, profile) => {
 					<tr>
 						<th>${t('arrival')}</th>
 						<th>${t('departure')}</th>
-						<th class="station-column">${t('station')}</th>
+						<th class="station">${t('station')}</th>
 						<th>${t('platform')}</th>
 					</tr>
 				</thead>

@@ -122,15 +122,13 @@ const journeyTemplate = (data, profile) => {
 		<div class="journey">
 			<header>
 				${data.slug ? html`
-					<a class="back icon-back" href="#/${data.slug}/${settings.journeysViewMode}" title="${t('back')}">${t('back')}</a>
-				` : html`
-					<a class="back icon-back invisible"></a>
-				`}
-				<div class="header-content">
+					<a class="icon-back" href="#/${data.slug}/${settings.journeysViewMode}" title="${t('back')}">${t('back')}</a>
+				` : ''}
+				<div class="content">
 					<h3>${parseName(data.legs[0].origin)} → ${parseName(data.legs[data.legs.length - 1].destination)}</h3>
 					<p><b>${t('duration')}: ${formatDuration(duration)} | ${t('changes')}: ${changes-1} | ${t('date')}: ${formatDateTime(data.legs[0].plannedDeparture, 'date')}${settings.showPrices && data.price ? html` | ${t('price')}: <td><span>${formatPrice(data.price)}</span></td>` : ''}</b></p>
 				</div>
-				<a class="reload icon-reload" title="${t("reload")}" @click=${() => refreshJourneyView(data.refreshToken, profile)}>${t("reload")}</a>
+				<a class="icon-reload" title="${t("reload")}" @click=${() => refreshJourneyView(data.refreshToken, profile)}>${t("reload")}</a>
 			</header>
 
 			${legs.map(leg => legTemplate(leg, profile))}

@@ -163,26 +161,17 @@ export const journeyView = async (match, isUpdate) => {
 	hideOverlay();
 
 	render(journeyTemplate(data, profile), ElementById('content'));
-
-	//if (!isUpdate) refreshJourneyView(refreshToken); // update data in the background
-
-	/*const history_id = dataStorage.journeysHistory.findIndex(obj => obj.reqId === reqId);
-
-	if (dataStorage.journeysHistory[history_id] !== undefined) {
-		dataStorage.journeysHistory[history_id].journeyId = journeyId;
-		saveDataStorage();
-	}*/
 };
 
 const refreshJourneyView = async (refreshToken, profile) => {
-	document.querySelector('.reload').classList.add('spinning');
+	document.querySelector('.icon-reload').classList.add('spinning');
 	try {
 		await refreshJourney(refreshToken, profile);
 	} catch(e) {
 		showAlertModal(e.toString());
-		document.querySelector('.reload').classList.remove('spinning');
+		document.querySelector('.icon-reload').classList.remove('spinning');
 		throw e;
 	}
 	journeyView([profile, refreshToken], true);
-	document.querySelector('.reload').classList.remove('spinning');
+	document.querySelector('.icon-reload').classList.remove('spinning');
 };
diff --git a/src/journeysView.js b/src/journeysView.js
@@ -10,24 +10,22 @@ import { showAlertModal, showLoader, hideOverlay } from './overlays.js';
 const journeysTemplate = (data) => html`
 	<div class="journeys">
 		<header id="header">
-			<a class="back icon-back" href="#/" title="${t('back')}">${t('back')}</a>
-			<div class="header-content">
+			<a class="icon-back" href="#/" title="${t('back')}">${t('back')}</a>
+			<div class="content">
 				<h3>${t('from')}: ${parseName(getFrom(data.journeys))}</h3>
-				<div>
-					<h3>${t('to')}: ${parseName(getTo(data.journeys))}</h3>
-					<div class="mode-changers">
-						<a href="#/${data.slug}/table" class="${settings.journeysViewMode === 'table' ? 'active' : ''}">
-							<div class="icon-table"></div>
-							<span>${t('table-view')}</span>
-						</a>
-						<a href="#/${data.slug}/canvas" class="${settings.journeysViewMode === 'canvas' ? 'active' : ''}">
-							<div class="icon-canvas"></div>
-							<span>${t('canvas-view')}</span>
-						</a>
-					</div>
+				<h3>${t('to')}: ${parseName(getTo(data.journeys))}</h3>
+				<div class="mode-changers">
+					<a href="#/${data.slug}/table" class="${settings.journeysViewMode === 'table' ? 'active' : ''}">
+						<div class="icon-table"></div>
+						<span>${t('table-view')}</span>
+					</a>
+					<a href="#/${data.slug}/canvas" class="${settings.journeysViewMode === 'canvas' ? 'active' : ''}">
+						<div class="icon-canvas"></div>
+						<span>${t('canvas-view')}</span>
+					</a>
 				</div>
 			</div>
-			<a class="reload icon-reload" title="${t("reload")}" @click=${() => refreshJourneysView(data.slug)}>${t("reload")}</a>
+			<a class="icon-reload" title="${t("reload")}" @click=${() => refreshJourneysView(data.slug)}>${t("reload")}</a>
 		</header>
 
 		${settings.journeysViewMode === 'canvas' ? html`

@@ -111,7 +109,7 @@ const journeyOverviewTemplate = (profile, entry, slug, key) => {
 		<td><span>${changes-1}</span></td>
 		<td><span>${productsString}</span></td>
 		${settings.showPrices ? html`<td><span>${formatPrice(entry.price)}</span></td>` : ''}
-		<td><a class="details-button icon-arrow3"></a></td>
+		<td><a class="icon-arrow1"></a></td>
 	</tr>`;
 };
 

@@ -162,14 +160,14 @@ export const moreJourneys = async (slug, mode) => {
 };
 
 const refreshJourneysView = async (slug) => {
-	document.querySelector('.reload').classList.add('spinning');
+	document.querySelector('.icon-reload').classList.add('spinning');
 	try {
 		await refreshJourneys(slug, true);
 	} catch(e) {
 		showAlertModal(e.toString());
-		document.querySelector('.reload').classList.remove('spinning');
+		document.querySelector('.icon-reload').classList.remove('spinning');
 		throw e;
 	}
 	journeysView([slug, settings.journeysViewMode], true);
-	document.querySelector('.reload').classList.remove('spinning');
+	document.querySelector('.icon-reload').classList.remove('spinning');
 };
diff --git a/src/overlays.js b/src/overlays.js
@@ -8,7 +8,7 @@ export const showAlertModal = (text) => {
 			<div class="modal">
 				<div class="box alert">
 					${text}
-					<div class="button" @click=${() => { hideOverlay(); resolve(); }}>OK</div>
+					<br><button @click=${() => { hideOverlay(); resolve(); }}>OK</button>
 				</div>
 			</div>
 		`, ElementById('overlay'));

@@ -33,13 +33,13 @@ export const showModal = (title, content) => {
 	showDiv('overlay');
 	return new Promise(resolve => {
 		render(html`
-			<div class="modal-dialog">
-				<div id="modal-content" class="modal-content">
-					<div class="modal-header">
-						<div class="modal-close" @click=${() => { hideOverlay(); resolve(); }}></div>
-						<h4 class="modal-title">${title}</h4>
+			<div class="modal">
+				<div class="box dialog">
+					<div class="header">
+						<div class="close" title="Close" @click=${() => { hideOverlay(); resolve(); }}></div>
+						<h4>${title}</h4>
 					</div>
-					<div class="modal-body">${content}</div>
+					<div class="body">${content}</div>
 				</div>
 			</div>
 		`, ElementById('overlay'));
diff --git a/src/searchView.js b/src/searchView.js
@@ -60,22 +60,31 @@ const iconFor = id => {
 };
 
 const searchTemplate = (journeysHistory) => html`
-	<div id="searchView" class="center">
-		<form class="search" onsubmit="return false;">
-			<div class="title">
-				<div class="logo icon-logo"></div>
-				<h1>TrainSearch</h1>
+	<div id="searchView">
+		<div class="title">
+			<div class="icon-logo"></div>
+			<h1>TrainSearch</h1>
+		</div>
+		<form onsubmit="return false;">
+			<div class="row nowrap">
+				<label for="from">${t('from')}:</label>
+				<input type="text" name="from" id="from" placeholder="${t('from')}" value="${fromValue}" autocomplete="off" @focus=${startTyping} @blur=${stopTyping} @keyup=${onKeyup} @keydown=${onKeydown} required>
+				<div class="button icon-arrow2" id="viaButton" title="Via" @click=${toggleVia}></div>
 			</div>
-			<label for="from">${t('from')}:</label>
-			<input type="text" name="from" id="from" placeholder="${t('from')}" value="${fromValue}" autocomplete="off" @focus=${startTyping} @blur=${stopTyping} @keyup=${onKeyup} @keydown=${onKeydown} required>
 			<div class="suggestions" id="fromSuggestions"></div>
 
-			<label for="via" class="hidden">${t('via')}:</label>
-			<input type="text" name="via" id="via" placeholder="${t('via')} ${t('optional')}" value="${viaValue}" autocomplete="off" @focus=${startTyping} @blur=${stopTyping} @keyup=${onKeyup} @keydown=${onKeydown} required class="hidden">
-			<div class="suggestions" id="viaSuggestions" class="hidden"></div>
+			<div class="row hidden" id="viaRow">
+				<label for="via">${t('via')}:</label>
+				<input type="text" name="via" id="via" placeholder="${t('via')}" value="${viaValue}" autocomplete="off" @focus=${startTyping} @blur=${stopTyping} @keyup=${onKeyup} @keydown=${onKeydown} required>
+			</div>
+			<div class="suggestions" id="viaSuggestions"></div>
+
 
-			<label for="to">${t('to')}:</label>
-			<input type="text" name="to" id="to" placeholder="${t('to')}" value="${toValue}" autocomplete="off" @focus=${startTyping} @blur=${stopTyping} @keyup=${onKeyup} @keydown=${onKeydown} required>
+			<div class="row nowrap">
+				<label for="to">${t('to')}:</label>
+				<input type="text" name="to" id="to" placeholder="${t('to')}" value="${toValue}" autocomplete="off" @focus=${startTyping} @blur=${stopTyping} @keyup=${onKeyup} @keydown=${onKeydown} required>
+				<div class="button icon-swap" title="${t('swap')}" @click=${swapFromTo}></div>
+			</div>
 			<div class="suggestions" id="toSuggestions"></div>
 
 			<div class="row">

@@ -114,43 +123,38 @@ const searchTemplate = (journeysHistory) => html`
 					<label class="icon-weelchair" for="accessibilityComplete" title="${t('access_full')}">${t('access_full')}<br></label>
 				</div>
 
-				<div class="selector rectangular">
-					<div class="btn icon-swap" title="${t('swap')}" @click=${swapFromTo}></div>
-					<div class="btn icon-settings" title="${t('settings')}" @click=${showSettings}></div>
-				</div>
+				<div class="filler"></div>
 
-				<div class="btn go" tabindex="0" id="go" @click=${search}>
+				<div class="button icon-settings" title="${t('settings')}" @click=${showSettings}></div>
+				<div class="button go" tabindex="0" id="go" @click=${search}>
 					${t('search')}
 					<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 2L4.5 20.29l.71.71L12 18l6.79 3 .71-.71z"/></svg>
 				</div>
 			</div>
 
-
-		${journeysHistory.length ? html`
-			<input type="checkbox" id="btn-history" class="btn history hidden">
-			<label for="btn-history" class="loadMore icon-arrow2"></label>
-			${journeysHistoryTemplate(journeysHistory)}
-		` : ''}
-
-		</div>
+			${journeysHistory.length ? html`
+				<div id="historyButton" class="loadMore icon-arrow2" title="History" @click=${toggleHistory}></div>
+			` : ''}
+		</form>
+		${journeysHistoryTemplate(journeysHistory)}
 	</div>
 `;
 
 const journeysHistoryTemplate = (journeysHistory) => html`
-	<div class="history">
+	<div id="history" class="history hidden">
 		${journeysHistory.map(element => html`
-		<div class="row history" @click="${() => {journeysHistoryAction(journeysHistory, element);}}">
-			<div class="history from">
+		<div class="row" @click="${() => {journeysHistoryAction(journeysHistory, element);}}">
+			<div class="from">
 				<small>${t('from')}:</small><br>
 				${parseName(element.fromPoint)}
 				${element.viaPoint ? html`
-					<div class="history via">
+					<div class="via">
 						<small>${t('via')} ${parseName(element.viaPoint)}</small>
 					</div>
 				` : ''}
 			</div>
-			<div class="history arrow icon-arrow1"></div>
-			<div class="history to">
+			<div class="icon-arrow1"></div>
+			<div class="to">
 				<small>${t('to')}:</small><br>
 				${parseName(element.toPoint)}
 			</div>

@@ -163,9 +167,6 @@ const journeysHistoryAction = (journeysHistory, element) => {
 	showSelectModal(html`
 		<a @click=${() => {setFromHistory(journeysHistory.length - 1 - journeysHistory.indexOf(element));hideOverlay();}}>${t('setfromto')}</a>
 		<a @click=${() => {go('/'+element.slug+'/'+settings.journeysViewMode);hideOverlay();}}>${t('journeyoverview')}</a>
-		${element.journeyId === '' ? '' : html`
-			<a @click=${() => {go('/'+element.slug+'/'+element.journeyId);hideOverlay();}}>${t('lastjourney')}</a>
-		`}
 	`);
 };
 

@@ -207,6 +208,10 @@ export const search = async (requestId) => {
 	timeValue = ElementById('time').value;
 	isArrValue = ElementById('arrival').checked;
 
+
+	if (fromValue === '') { showAlertModal('From can\'t be empty!'); return; }
+	if (toValue   === '') { showAlertModal('To can\'t be empty!');   return; }
+
 	if (date !== '') {
 		if (!isValidDate(date)) {
 			showAlertModal('Invalid date');

@@ -300,7 +305,7 @@ export const search = async (requestId) => {
 };
 
 const suggestionsTemplate = (data, inputId) => html`
-	<div class="suggestionsbox" @mouseover=${mouseOverSuggestions} @mouseout=${stopMouseOverSuggestions}>
+	<div class="box" @mouseover=${mouseOverSuggestions} @mouseout=${stopMouseOverSuggestions}>
 		${data.map(element => html`
 			<p class="suggestion" @click=${() => setSuggestion(encodeURI(JSON.stringify(element)), inputId)}>${parseName(element)}</p>
 		`)}

@@ -350,6 +355,27 @@ export const setSuggestion = (data, inputId) => {
 	}
 };
 
+export const toggleHistory = () => {
+	const historyElement = ElementById('history');
+	const buttonElement  = ElementById('historyButton');
+
+	const show = () => {
+		buttonElement.classList.add('flipped');
+		historyElement.classList.remove('hidden');
+	};
+
+	const hide = () => {
+		buttonElement.classList.remove('flipped');
+		historyElement.classList.add('hidden');
+	};
+
+	if (!historyElement.classList.contains('hidden')) {
+		hide();
+	} else {
+		show();
+	}
+}
+
 export const toggleVia = ( mode ) => {
 	const rowElement    = ElementById('viaRow');
 	const buttonElement = ElementById('viaButton');

@@ -447,7 +473,7 @@ const onKeydown = (e) => {
 
 	if (which == 13) { // enter
 		if (!ElementById('selected')) {
-			document.querySelector(`#${e.target.id}Suggestions>.suggestionsbox>:first-child`).click();
+			document.querySelector(`#${e.target.id}Suggestions>.box>:first-child`).click();
 			if (e.target.id === 'to') ElementById('go').click();
 		} else {
 			const elem = ElementById('selected');

@@ -459,13 +485,13 @@ const onKeydown = (e) => {
 
 	if (which == 40) { // keydown
 		if (!ElementById('selected')) {
-			document.querySelector(`#${e.target.id}Suggestions>.suggestionsbox>:first-child`).id = 'selected';
+			document.querySelector(`#${e.target.id}Suggestions>.box>:first-child`).id = 'selected';
 		} else {
 			const currElem = ElementById('selected');
 			let nextElem = currElem.nextElementSibling;
 
 			if (nextElem == null) {
-				nextElem = document.querySelector(`#${e.target.id}Suggestions>.suggestionsbox>:first-child`).id = 'selected';
+				nextElem = document.querySelector(`#${e.target.id}Suggestions>.box>:first-child`).id = 'selected';
 			}
 
 			currElem.id = '';

@@ -477,13 +503,13 @@ const onKeydown = (e) => {
 
 	if (which == 38) { // keydown
 		if (!ElementById('selected')) {
-			document.querySelector(`#${e.target.id}Suggestions>.suggestionsbox>:first-child`).id = 'selected';
+			document.querySelector(`#${e.target.id}Suggestions>.box>:first-child`).id = 'selected';
 		} else {
 			const currElem = ElementById('selected');
 			let prevElem = currElem.previousElementSibling;
 
 			if (prevElem == null) {
-				prevElem = document.querySelector(`#${e.target.id}Suggestions>.suggestionsbox>:last-child`).id = 'selected';
+				prevElem = document.querySelector(`#${e.target.id}Suggestions>.box>:last-child`).id = 'selected';
 			}
 
 			currElem.id = '';
diff --git a/src/settingsView.js b/src/settingsView.js
@@ -30,8 +30,8 @@ const settingsTemplate = () => html`
 		<label><input type="checkbox" ?checked=${settings.showDS100} id="showDS100"> ${t('showds100')}</label><br>
 		<label><input type="checkbox" ?checked=${settings.showPrices} id="showPrices"> ${t('show-prices')} (${t("experimental")})</label><br>
 		<br>
-		<button class="button" id="save" @click=${saveSettings}><span>${t('save')}</span></button>
-		<button class="button" style="float:right;" id="clear" @click=${clearDataStorage}><span>${t('clearstorage')}</span></button>
+		<button id="save" @click=${saveSettings}>${t('save')}</button>
+		<button style="float:right;" id="clear" @click=${clearDataStorage}>${t('clearstorage')}</button>
 	</div>
 `;
 
diff --git a/src/templates.js b/src/templates.js
@@ -9,7 +9,7 @@ export const remarksModalTemplate = (type, remarks) => html`
 		${remarks.map(element => html`
 			<tr>
 			<td>
-				<span class="remark icon-${type}"></span>
+				<span class="icon-${type}"></span>
 				<span>${element.text}</span>
 			</td>
 			</tr>
diff --git a/src/tripView.js b/src/tripView.js
@@ -30,11 +30,11 @@ const tripTemplate = (data, profile) => {
 	return html`
 		<div class="journey">
 			<header>
-				<a class="back icon-back invisible"></a>
-				<div class="header-content">
+				<a class="icon-back hidden"></a>
+				<div class="content">
 					<h3>Trip of ${lineDisplayName(data.line)}</h3>
 				</div>
-				<a class="reload icon-reload invisible">${t("reload")}</a>
+				<a class="icon-reload hidden">${t("reload")}</a>
 			</header>
 
 			<div class="card">

@@ -55,20 +55,20 @@ const tripTemplate = (data, profile) => {
 						<td colspan="4">
 							<div class="train-details">
 								${lineAdditionalName(data.line) ? html`
-									<div class="train-detail">
+									<div>
 										Trip: ${lineAdditionalName(data.line)}
 									</div>
 								` : ''}
 								${data.line.trainType ? html`
-									<div class="train-detail">
+									<div>
 										Train type: ${data.line.trainType}
 									</div>
 								` : ''}
-								<div class="train-detail ${data.cancelled ? 'cancelled' : ''}">
+								<div ${data.cancelled ? 'cancelled' : ''}">
 									${t('duration')}: ${formatDuration(data.arrival - (data.departure ? data.departure : data.plannedDeparture))} ${data.departure ? '' : ('(' + t('planned') + ')')}
 								</div>
 								${data.loadFactor ? html`
-									<div class="train-detail">
+									<div
 										${t("load-"+data.loadFactor)}
 									</div>
 								` : ''}

@@ -78,7 +78,7 @@ const tripTemplate = (data, profile) => {
 					<tr>
 						<th>${t('arrival')}</th>
 						<th>${t('departure')}</th>
-						<th class="station-column">${t('station')}</th>
+						<th class="station-">${t('station')}</th>
 						<th>${t('platform')}</th>
 					</tr>
 				</thead>
diff --git a/static/style.css b/static/style.css
@@ -2,7 +2,7 @@ font-face {
 	font-family: 'varelaregular';
 	src: url('./varela-regular-webfont.woff2') format('woff2');
 	font-weight: normal;
-	font-style: normal;
+	font-tyle: normal;
 }
 
 * {

@@ -22,28 +22,16 @@ a {
 	color: inherit;
 }
 
-header {
-	position: relative;
-	color: white;
-	background-color: #222;
-	bottom-border: 1px solid rgba(255, 255, 255, .3);
-	display: flex;
-	flex-direction: row;
-	justify-content: center;
+.pointer {
+	cursor: pointer;
 }
 
-.header-content {
-	max-width: 1000px;
-	width: 80vw;
-	display: flex;
-	flex-direction: row;
-	flex-wrap: wrap;
+.hidden {
+	display: none !important;
 }
-.header-content>div {
-	display: flex;
-	flex-direction: row;
-	flex-grow: 1;
-	flex-wrap: wrap;
+
+.flipped {
+	transform: rotate(180deg);
 }
 
 .row {

@@ -54,27 +42,12 @@ header {
 .cancelled {
 	text-decoration-line: line-through;
 }
+
 .cancelled-text {
 	font-weight: bold;
 	color: red !important;
 }
 
-.pointer {
-	cursor: pointer;
-}
-
-.invisible {
-	visibility: hidden;
-}
-.back,
-.reload {
-	cursor: pointer;
-	width: 32px;
-	height: 32px;
-	margin: 12px;
-	user-select: none;
-}
-
 .spinner {
 	margin: calc(50vh - 60px) auto;
 	border: 5px solid rgba(255, 255, 255, .4);

@@ -84,6 +57,7 @@ header {
 	height: 120px;
 	animation: spin 2s linear infinite;
 }
+
 .spinning {
 	animation: spin 2s linear infinite;
 }

@@ -103,217 +77,417 @@ header {
 	filter: invert();
 }
 
-.loadMore.flipped {
-	transform: rotate(180deg);
-	margin-top: 45px;
-}
+.remarks {
+	/*background: #000000d0;*/
+	padding: 0;
+	width: 100%;
+	margin: 0;
 
-:checked ~ label[for=btn-history] {
-	transform: rotateX(180deg);
-}
+	td {
+		margin: 0 10px;
+		text-align: left;
+		display: block;
+	}
 
-table {
-	border-bottom: 1px solid rgba(0, 0, 0, 0.3);
-	width: 100%;
-	background-color: #fff;
-	min-width: 390px;
-	max-width: 1000px;
-}
-div.card {
-	overflow-x: auto;
-}
-tbody tr {
-	border-top: 1px solid #ccc;
-}
-tr {
-	background-color: #fff;
-	margin: 0 0 15px 0;
+	span {
+		vertical-align: middle;
+	}
 }
 
-td, th {
-	text-align: center;
-	overflow: hidden;
-}
+header {
+	position: relative;
+	display: flex;
+	flex-direction: row;
+	justify-content: center;
+	color: white;
+	background-color: #222;
+	bottom-border: 1px solid rgba(255, 255, 255, .3);
 
-th {
-	padding: 5px 3px;
-}
+	h3 {
+		margin-right: 1.5em;
+	}
+
+	.content {
+		display: flex;
+		flex-direction: row;
+		flex-wrap: wrap;
+		flex-grow: 1;
+		max-width: 1000px;
+		width: 80vw;
+	}
 
+	.icon-back,
+	.icon-reload {
+		cursor: pointer;
+		width: 32px;
+		height: 32px;
+		margin: 12px;
+		user-select: none;
+	}
 
-thead tr:not(:last-child) {
-	background-color: #eee;
+	.mode-changers {
+		display: flex;
+		margin-left: auto;
+	
+		a.active {
+			border-bottom: 3px solid white;
+		}
+	
+		a {
+			border-bottom: 3px solid transparent;
+			align-items: center;
+			display: flex;
+			padding: 0 1em;
+			cursor: pointer;
+			text-decoration: none;
+	
+		 	span {
+				font-weight: bold;
+				margin: 1em .4em;
+			}
+		}
+	}
+	
 }
 
+#content {
+	display: flex;
+	flex-direction: column;
+	min-height: 100vh;
+}
 
-tbody tr:hover {
-	background-color: #ddd;
+#overlay {
+	position: fixed;
+	z-index: 1;
+	left: 0;
+	top: 0;
+	width: 100%;
+	height: 100%;
+	overflow: auto;
+	background-color: rgba(0,0,0,0.4);
+	backdrop-filter: blur(10px);
 }
 
-tbody tr:hover td {
-	background-color: transparent;
+#settingsView {
+	margin: 1em;
+	overflow: auto;
 }
 
-@supports (display: flex) {
-	input[type="date"],
-	input[type="time"],
-	input[type="text"] {
-		cursor: pointer;
-		box-sizing: border-box;
-		padding: .3em .5em;
-		font-size: 1.5em;
-		padding: 7px;
-		border: none;
-		outline: none;
-		background-color: white;
-		color: black;
-		margin-top: 8px;
-		border-radius: 0;
+#searchView {	
+	background-color: #222;
+	flex-grow: 1;
+	padding-bottom: 5em;
+
+	.title {
+		display: flex;
+		justify-content: center;
+		align-items: center;
+
+		.icon-logo {
+			background-color: #7171e5;
+			border-radius: 15%;
+			width: 50px;
+			height: 50px;
+			margin: 0;
+			padding: 5px 5px 2px 6px;
+		}
+
+		h1 {
+			color: white;
+			font-weight: normal;
+			margin-left: .5em;
+			margin: .7em .3em .5em .3em;
+		}
+
+		h1:hover {
+			-webkit-text-fill-color: transparent;
+			-webkit-background-clip: text !important;
+			background: linear-gradient(90deg, #b4dcff 20%, pink 20%, pink 40%, white 40%, white 60%, pink 60%, pink 80%, #b4dcff 80%, #b4dcff 100%);
+		}
 	}
-	input[type="time"] {
-		flex-grow: 1;
+
+	.row {
+		margin-top: 8px;
 	}
-	input[type="text"] {
-		border: 1px solid transparent;
+
+	form {
+		color: white;
+		display: flex;
+		flex-direction: column;
+
+		label[for=from], label[for=via], label[for=to], label[for=date], label[for=time] {
+			display: none;
+		}
+
+		table {
+			width: 100%;
+			color: black;
+		}
+
+		#time, #date {
+			flex-grow: 1;
+		}
+
+		#from, #to, #via {
+			width: 100%;
+		}
+
+		#via {
+			margin-right: 53px;
+		}
+
+		.button.icon-arrow1,
+		.button.icon-arrow2,
+		.button.icon-swap {
+			padding: 0;
+			margin-left: 8px;
+		}
+		
+		.button.go,
+		.button.icon-settings {
+			float: right;
+			height: 32px;
+			display: flex;
+			justify-content: center;
+			align-items: center;
+		}
+
+		.filler {
+			flex: auto;
+		}
+
+		.button.icon-settings {
+			width: 32px;
+			margin-right: 8px;
+			padding: 3px;
+		}
+		
+		.btn.go {
+			margin: 8px 0;
+			font-size: 20px;
+		
+			svg {
+				margin-left: 5px;
+				fill: #5050ff;
+			}
+		}
+	}
+
+	.suggestions {
+		position: relative;
+		display: none;
+		overflow: visible;
+		z-index: 999;
+		height: 0;
+
+		.box {
+			border-radius: 3px;
+			width: 100%;
+
+			p {
+				font-size: 1.2em;
+				background-color: white;
+				color: black;
+				margin: 0;
+				border-top: 1px solid rgba(0, 0, 0, .2);
+				padding: .3em .6em;
+				cursor: pointer;
+			}
+
+			p:first-child {
+				border-top: 0px;
+			}
+
+			p:hover {
+				background-color: #d3d3d3;
+			}
+		}
+
+		#selected {
+			background-color: #bfbfbf !important;
+		}
 	}
-	input[type="text"]:focus {
-		border-bottom: 1px solid rgba(0, 0, 0, .2);
+
+	.suggestions.typing,
+	.suggestions.mouseover {
+		display: block;
 	}
 
-	.btn,
-	.selector label {
-		cursor: pointer;
-		background-color: white;
-		display: inline-block;
+	.history {
+		margin-top: 8px;
+		overflow: hidden;
+		margin-bottom: 1em;
 		user-select: none;
-		color: black;
-		padding: 0 10px;
+
+		.row {
+			font-size: 1.2em;
+			background-color: white;
+			color: black;
+			margin: 0;
+			border-top: 1px solid rgba(0, 0, 0, .2);
+			padding: .3em .6em .3em .3em;
+			cursor: pointer;
+
+			display: flex;
+			justify-content: space-between;
+		}
+
+		:first-child {
+			border-top: 0px;
+		}
+
+		.via {
+			font-weight: 200;
+		}
+
+		.from,
+		.to {
+			width: 40%;
+		}
+
+		.to {
+			text-align: right;
+		}
+
+		.icon-arrow1 {
+			width: 25px;
+		}
 	}
-	.selector.rectangular {
-		margin-bottom: 8px;
+}
+
+.card {
+	overflow-x: auto;
+
+	.train-details {
+		display: flex;
+		justify-content: center;
+		flex-wrap: wrap;
+	
+		div {
+			margin: .4em 2em;
+		}
 	}
-	.selector.rectangular label,
-	.selector.rectangular .btn {
-		height: 32px;
-		font-weight: bold;
-		font-size: 0;
-		width: 32px;
-		padding: 3px;
-		overflow: hidden;
+
+	table {
+		border-bottom: 1px solid rgba(0, 0, 0, 0.3);
+		width: 100%;
+		background-color: #fff;
+		min-width: 390px;
+		max-width: 1000px;
 	}
-	.selector div:not(:last-child),
-	.selector label:not(:last-child) {
-		border-right: 1px solid #bbb;
+	
+	thead tr:not(:last-child) {
+		background-color: #eee;
 	}
 
-	.selector {
-		margin-top: 8px;
-		margin-right: auto;
-		display: flex;
+	tbody {
+		tr {
+			border-top: 1px solid #ccc;
+		}
+
+		tr:hover {
+			background-color: #ddd;
+		}
+
+		tr:hover td {
+			background-color: transparent;
+		}
 	}
 
-	.selector > label {
-		user-select: none;
+	tr {
+		background-color: #fff;
+		margin: 0 0 15px 0;
 	}
 
-	.selector > input {
-		display: none;
+	td, th {
+		text-align: center;
+		overflow: hidden;
 	}
 
-	.selector input + label {
-		background: #d3d3d3;
+	th {
+		padding: 5px 3px;
 	}
 
-	.selector input:checked + label {
-		background: #fff;
+	th.station {
+		width: 60%;
 	}
 }
 
-@media (min-width: 576px) {
+.journeys {
+	min-height: 100vh;
 
-}
-@media (max-width: 575px) {
-	.selector:nth-child(2) {
-		flex-basis: 100%;
+	.loadMore.flipped {
+		margin-top: 45px;
 	}
-}
 
-.journey,
-.journeys,
-.departures {
-	display: flex;
-	flex-direction: column;
-	min-height: 100vh;
-}
-.journeys tbody tr,
-.departures tbody tr {
-	cursor: pointer;
+	.icon-arrow1 {
+		height: 30px;
+		padding: 0;
+	}
 }
 
-.search {
-	color: white;
-	display: flex;
-	flex-direction: column;
-	margin-bottom: 5em;
-}
+.journey {
+	tbody:not(:last-child) {
+		border-bottom: 1px solid rgba(0, 0, 0, .2);
+	}
 
-.search table {
-	width: 100%;
-	color: black;
-}
+	thead>tr:nth-child(2) {
+		border-bottom: 2px solid #ccc;
+	}
 
-.search #date {
-	flex-grow: 1;
-	margin-left: 8px;
-}
+	p {
+		color: white;
+		width: 100%;
+	}
 
-.search>.title {
-	display: flex;
-	justify-content: center;
-	align-items: center;
-}
+	p::before {
+		filter: drop-shadow( 0 0 5px rgba(0, 0, 0, .6) );
+		margin-right: 4px;
+		vertical-align: sub;
+	}
 
-.search>.title>h1 {
-	font-weight: normal;
-	margin-left: .5em;
-	margin: .7em .3em .5em .3em;
-}
-.search>.title>h1:hover {
-	-webkit-text-fill-color: transparent;
-	-webkit-background-clip: text !important;
-	background: linear-gradient(90deg, #b4dcff 20%, pink 20%, pink 40%, white 40%, white 60%, pink 60%, pink 80%, #b4dcff 80%, #b4dcff 100%);
-}
+	p.change,
+	p.walk,
+	p.transfer {
+		text-shadow: 0 0 15px rgba(0, 0, 0, .6);
+		text-align: center;
+	}
 
-.search>.title>.logo {
-	background-color: #7171e5;
-	border-radius: 15%;
-	width: 50px;
-	height: 50px;
-	margin: 0;
-	padding: 5px 5px 2px 6px;
-}
+	p.change::before {
+		content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path style="fill: white;" d="M9 3L5 6.99h3V14h2V6.99h3L9 3zm7 14.01V10h-2v7.01h-3L15 21l4-3.99h-3z"/><path d="M0 0h24v24H0z" fill="none"/></svg>');
+	}
 
-.search .btn.go {
-	height: 32px;
-	margin: 8px 0;
-	display: flex;
-	justify-content: center;
-	align-items: center;
-	font-size: 20px;
-}
+	p.walk::before {
+		content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path style="fill: white;" d="M13.5 5.5c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zM9.8 8.9L7 23h2.1l1.8-8 2.1 2v6h2v-7.5l-2.1-2 .6-3C14.8 12 16.8 13 19 13v-2c-1.9 0-3.5-1-4.3-2.4l-1-1.6c-.4-.6-1-1-1.7-1-.3 0-.5.1-.8.1L6 8.3V13h2V9.6l1.8-.7"/></svg>');
+	}
 
-.search .btn.go label {
-	cursor: pointer;
-}
+	p.transfer::before {
+		content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path style="fill: white;" d="M21.71 11.29l-9-9c-.39-.39-1.02-.39-1.41 0l-9 9c-.39.39-.39 1.02 0 1.41l9 9c.39.39 1.02.39 1.41 0l9-9c.39-.38.39-1.01 0-1.41zM14 14.5V12h-4v3H8v-4c0-.55.45-1 1-1h5V7.5l3.5 3.5-3.5 3.5z"/><path d="M0 0h24v24H0z" fill="none"/></svg>');
+	}
 
-.search .btn.go svg {
-	margin-left: 5px;
-	fill: #5050ff;
+	.link {
+		vertical-align: bottom;
+		cursor: pointer;
+		max-inline-size: 22px;
+		margin: 0 .3em;
+	}
 }
 
+.journey,
+.journeys,
+.departures {
+	display: flex;
+	flex-direction: column;
+	min-height: 100vh;
 
+	tbody td:nth-child(2) span {
+	        justify-content: start;
+	}
+}
 
-.journeys {
-	min-height: 100vh;
+.journeys tbody tr,
+.departures tbody tr {
+	cursor: pointer;
 }
 
 .journeys table a,

@@ -338,143 +512,311 @@ tbody tr:hover td {
 	color: black;
 }
 
-.journeys a.details-button {
-	height: 30px;
-	padding: 0;
+.modal {
+	display: flex;
+	position: fixed;
+	top: 0;
+	right: 0;
+	bottom: 0;
+	left: 0;
+	z-index: 1050;
+	overflow: hidden;
+	-webkit-overflow-scrolling: touch;
+	outline: 0;
+
+	.box {
+		margin: auto;
+		background-color: white;
+		width: max-content;
+		padding: 15px;
+		border-radius: 4px;
+	}
+
+	.alert button {
+		float: right;
+	}
+
+	.select {
+		a {
+			display: block;
+			text-decoration: none;
+			background-color: rgba(20, 30, 255, .7);
+			color: white;
+			width: 100%;
+			padding: 8px 20px;
+			margin-left: auto;
+			margin-top: 10px;
+			text-align: center;
+			transition: background-color 300ms;
+		}
+
+		a:first-child {
+			margin-top: 0px;
+		}
+
+		a:hover {
+			background-color: rgba(70, 100, 255, .8);
+			cursor: pointer;
+		}
+	}
+
+	.dialog {
+		padding: unset;
+		border: 1px solid rgba(0, 0, 0, .4);
+
+		.header {
+			border-top-right-radius: 3px;
+			border-top-left-radius:  3px;
+			background-color: #5a5a5a;
+			color: white;
+			min-height: 16.4;
+			padding: 15px;
+
+			h4 {
+				margin: 0;
+				line-height: 1.4;
+	 		}
+
+			.close {
+				float: right;
+				width: 53px;
+				height: 53px;
+				margin: -15px;
+				padding: 10px;
+				border-left: 1px solid rgba(0, 0, 0, .4);
+				cursor: pointer;
+				content: url("data:image/svg+xml,%3Csvg width='30' height='30' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M5.293 5.293a1 1 0 0 1 1.414 0L12 10.586l5.293-5.293a1 1 0 1 1 1.414 1.414L13.414 12l5.293 5.293a1 1 0 0 1-1.414 1.414L12 13.414l-5.293 5.293a1 1 0 0 1-1.414-1.414L10.586 12 5.293 6.707a1 1 0 0 1 0-1.414' fill='%23fff'/%3E%3C/svg%3E");
+			}
+
+			.close:hover {
+				border-top-right-radius: 3px;
+				background: rgba(0, 0, 0, .4);
+			}
+		}
+	}
+}
+
+input[type="date"],
+input[type="time"],
+input[type="text"] {
+	cursor: pointer;
+	box-sizing: border-box;
+	padding: .3em .5em;
+	font-size: 1.5em;
+	padding: 7px;
+	border: none;
+	outline: none;
+	background-color: white;
+	color: black;
+	border-radius: 0;
 }
 
-.departures tbody td:nth-child(2) span {
-        justify-content: start;
+input[type="text"] {
+	border: 1px solid transparent;
 }
 
-.journey tbody:not(:last-child) {
+input[type="text"]:focus {
 	border-bottom: 1px solid rgba(0, 0, 0, .2);
 }
 
-.journey p {
+button {
+	border-radius: 4px;
+	background-color: rgba(20, 30, 255, .7);
 	color: white;
-	width: 100%;
+	width: max-content;
+	padding: 8px 20px;
+	margin-left: auto;
+	margin-top: 10px;
+	transition: background-color 300ms;
+	border: none;
 }
 
-.journey p::before {
-	filter: drop-shadow( 0 0 5px rgba(0, 0, 0, .6) );
-	margin-right: 4px;
-	vertical-align: sub;
+button:hover {
+	background-color: rgba(70, 100, 255, .8);
+	cursor: pointer;
 }
 
-.journey p.change,
-.journey p.walk,
-.journey p.transfer {
-	text-shadow: 0 0 15px rgba(0, 0, 0, .6);
-	text-align: center;
+button:not(:first-child) {
+	margin-left: .2em;
 }
 
-.journey p.change::before {
-	content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path style="fill: white;" d="M9 3L5 6.99h3V14h2V6.99h3L9 3zm7 14.01V10h-2v7.01h-3L15 21l4-3.99h-3z"/><path d="M0 0h24v24H0z" fill="none"/></svg>');
+button:not(:last-child) {
+	margin-right: .2em;
 }
 
-.journey p.walk::before {
-	content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path style="fill: white;" d="M13.5 5.5c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zM9.8 8.9L7 23h2.1l1.8-8 2.1 2v6h2v-7.5l-2.1-2 .6-3C14.8 12 16.8 13 19 13v-2c-1.9 0-3.5-1-4.3-2.4l-1-1.6c-.4-.6-1-1-1.7-1-.3 0-.5.1-.8.1L6 8.3V13h2V9.6l1.8-.7"/></svg>');
-}
-
-.journey p.transfer::before {
-	content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path style="fill: white;" d="M21.71 11.29l-9-9c-.39-.39-1.02-.39-1.41 0l-9 9c-.39.39-.39 1.02 0 1.41l9 9c.39.39 1.02.39 1.41 0l9-9c.39-.38.39-1.01 0-1.41zM14 14.5V12h-4v3H8v-4c0-.55.45-1 1-1h5V7.5l3.5 3.5-3.5 3.5z"/><path d="M0 0h24v24H0z" fill="none"/></svg>');
+.button,
+.selector label {
+	cursor: pointer;
+	background-color: white;
+	display: inline-block;
+	user-select: none;
+	color: black;
+	padding: 0 10px;
 }
 
+.selector {
+	display: flex;
+	margin-right: 8px;
 
-.suggestionsbox {
-	border-radius: 3px;
-	width: 100%;
-}
+	input {
+		display: none;
+	}
 
-.suggestionsbox p:first-child {
-	border-top: 0px;
-}
+	input + label {
+		background: #d3d3d3;
+	}
 
-.suggestionsbox p {
-	font-size: 1.2em;
-	background-color: white;
-	color: black;
-	margin: 0;
-	border-top: 1px solid rgba(0, 0, 0, .2);
-	padding: .3em .6em;
-	cursor: pointer;
-}
+	input:checked + label {
+		background: #fff;
+	}
 
-.suggestions {
-	position: relative;
-	display: none;
-	overflow: visible;
-	z-index: 999;
-	height: 0;
+	label {
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		user-select: none;
+	}
+
+	label:after {
+		font-size: .9rem;
+		color: black;
+		text-align: center;
+		line-height: .9rem;
+		margin-top: 2px;
+	}
+
+	label.icon-ice,
+	label.icon-ic,
+	label.icon-icice,
+	label.icon-dzug,
+	label.icon-regional {
+		font-style: italic;
+	}
+
+	label.icon-tram:after,
+	label.icon-bus:after,
+	label.icon-ferry:after,
+	label.icon-taxi:after {
+		font-size: 0.6rem;
+	}
+
+	div:not(:last-child),
+	label:not(:last-child) {
+		border-right: 1px solid #bbb;
+	}
+
+
+	.icon-ice:after      { content: 'ICE'; }
+	.icon-ic:after       { content: 'IC'; }
+	.icon-icice:after    { content: 'IC ICE'; }
+	.icon-dzug:after     { content: 'D'; }
+	.icon-regional:after { content: 'NV'; }
+	.icon-suburban:after { content: 'S'; }
+	.icon-subway:after   { content: 'U'; }
+	.icon-tram:after     { content: 'Tram'; }
+	.icon-bus:after      { content: 'Bus'; }
+	.icon-ferry:after    { content: 'Ferry'; }
+	.icon-taxi:after     { content: 'Taxi'; }
 }
 
-.suggestions.typing,
-.suggestions.mouseover {
-	display: block;
+.selector.rectangular label {
+	height: 32px;
+	width: 32px;
+	padding: 3px;
+	font-weight: bold;
+	font-size: 0;
+	overflow: hidden;
 }
 
+@media (max-width: 650px) {
+	.filler {
+		flex: unset !important;
+	}
 
+	.selector.rectangular,
+	.button.icon-settings,
+	.button.go {
+		margin-bottom: 8px;
+	}
+
+	.button.go {
+		flex-basis: 100%;
+		margin-right: auto;
+	}
+}
 
 @media (max-width: 799px) {
-	.header-content {
-		flex-grow: 1;
+	.header {
+		.content {
+			flex-grow: 1;
+		}
+
+		.icon-back {
+			left: 10px;
+		}
 	}
-	.search {
+
+	#searchView {
 		padding: 10px;
-	}
 
-	.back {
-		left: 10px;
+		#time {
+			margin-top: 8px;
+			width: 100%;
+			flex-shrink: 0;
+		}
 	}
 
 	.row {
 		flex-wrap: wrap;
 	}
 
-	.search #date {
-		width: 30%;
+	.row.nowrap {
+		flex-wrap: unset;
 	}
 
-	.search #time {
-		width: 100%;
-		flex-shrink: 0;
-	}
 	.loadMore.flipped {
 		margin-top: 15px;
 	}
+
 	.loadMore {
 		width: 48px;
 	}
+
 }
 
 @media (min-width: 800px) {
-	.journeys table {
-		margin: 15px auto;
-	}
-
 	#content {
 		justify-content: center;
 	}
-	.center {
+
+	#searchView {
 		display: flex;
 		justify-content: center;
 		align-items: center;
-	}
+		flex-direction: column;
 
-	.search {
-		width: 80vw;
-		max-width: 700px;
-		color: white;
-	}
+		form,
+		.history {
+			width: 80vw;
+			max-width: 700px;
+			color: white;
+		}
 
-	.search #date {
-		margin-right: 8px;
-		width: 50%;
-	}
+		#date {
+			margin-right: 8px;
+			width: 50%;
+		}
 
-	.search #time {
-		width: 30%;
+		#time {
+			width: 30%;
+		}
+	}
+	
+	table {
+		overflow: hidden;
+		border: none;
+		margin: 50px auto;
+		width: 80vw;
 	}
 
 	td p {

@@ -485,253 +827,18 @@ tbody tr:hover td {
 	th {
 		padding: 10px 5px;
 	}
-	.journeys table a {
-		padding: 10px 5px;
-	}
 
-	table {
-		overflow: hidden;
-		border: none;
-		margin: 50px auto;
-		width: 80vw;
+	.journeys table {
+		margin: 15px auto;
+		
+		a {
+			padding: 10px 5px;
+		}
 	}
-}
-
-.hidden {
-	display: none !important;
-}
-
-label[for=from], label[for=via], label[for=to], label[for="date"], label[for=time] {
-	display: none;
-}
-
-#settingsView {
-	margin: 1em;
-	overflow: auto;
-}
-
-#overlay {
-	position: fixed;
-	z-index: 1;
-	left: 0;
-	top: 0;
-	width: 100%;
-	height: 100%;
-	overflow: auto;
-	background-color: rgba(0,0,0,0.4);
-	backdrop-filter: blur(10px);
-}
-
-
-.modal {
-	display: flex;
-	position: fixed;
-	top: 0;
-	right: 0;
-	bottom: 0;
-	left: 0;
-	z-index: 1050;
-	overflow: hidden;
-	-webkit-overflow-scrolling: touch;
-	outline: 0;
-}
-
-.modal-alert {
-	margin: auto;
-	border-radius: 4px;
-	background-color: white;
-	width: max-content;
-	padding: 15px;
-}
-
-.button:not(:first-child) {
-	margin-left: .2em;
-}
-.button:not(:last-child) {
-	margin-right: .2em;
-}
-.button {
-	border-radius: 4px;
-	background-color: rgba(20, 30, 255, .7);
-	color: white;
-	width: max-content;
-	padding: 8px 20px;
-	margin-left: auto;
-	margin-top: 10px;
-	transition: background-color 300ms;
-	border: none;
-}
-
-.button:hover {
-	background-color: rgba(70, 100, 255, .8);
-	cursor: pointer;
-}
-
-.modal-header {
-	background-color: #5a5a5a;
-	color: white;
-	min-height: 16.4;
-	padding: 15px;
-	border-bottom: 1px solid #e5e5e5;
-}
-
-.modal-header .close {
-	margin-top: -2px;
-}
-
-.modal-header .modal-close {
-	width:53px;
-	float:right;
-	margin:-15px;
-	margin-left:0px;
-	height:53px;
-	border-left: 1px solid #00000040;
-	background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAAAsTAAALEwEAmpwYAAABO0lEQVR42u3bURKDIAwEUNiLoyfXC3Ss4mYTh81Xv4R90wqEad+2ra1caIuXAQxgAAMYwAAGMIABDGAAA0zVGOMYYxzqibPGxdtJ/PqsCM8aF4xJKBHY40IxwcrPngbY970rJ3r1zKu5hH4DVAhR4Sk/gWiEyPC0d0AUQnR46kuQjaAIT18FWAiq8CHL4FsEZfiws8Asgjp86GHoKUJG+PDT4F2ErPCttdYVd4OzS2F0eFk/YCaIIry0IfIkkCq8FOBuMGV4OUDFkgK83Qh9GoC1Ff4kAPsw9CmAf5scdWdJCnB3h5eJgOzw2QioED4TAVXCZyGgUvgMBFQLr0ZAxfBKBFQNr0JA5fAKBFQPH40gbYtXfDb1dljRzGCPS7sdVnZymON2/2Nk8TKAAQxgAAMYwAAGMIABDLBmnWRS+u5G6HkFAAAAAElFTkSuQmCC') center no-repeat;
-	background-size:30px;
-	cursor:pointer;
-}
 
-.modal-header .modal-close:hover {
-	background: rgba(0, 0, 0, .4) url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAAAsTAAALEwEAmpwYAAABO0lEQVR42u3bURKDIAwEUNiLoyfXC3Ss4mYTh81Xv4R90wqEad+2ra1caIuXAQxgAAMYwAAGMIABDGAAA0zVGOMYYxzqibPGxdtJ/PqsCM8aF4xJKBHY40IxwcrPngbY970rJ3r1zKu5hH4DVAhR4Sk/gWiEyPC0d0AUQnR46kuQjaAIT18FWAiq8CHL4FsEZfiws8Asgjp86GHoKUJG+PDT4F2ErPCttdYVd4OzS2F0eFk/YCaIIry0IfIkkCq8FOBuMGV4OUDFkgK83Qh9GoC1Ff4kAPsw9CmAf5scdWdJCnB3h5eJgOzw2QioED4TAVXCZyGgUvgMBFQLr0ZAxfBKBFQNr0JA5fAKBFQPH40gbYtXfDb1dljRzGCPS7sdVnZymON2/2Nk8TKAAQxgAAMYwAAGMIABDLBmnWRS+u5G6HkFAAAAAElFTkSuQmCC') center no-repeat;
-	background-size:30px;
-}
-
-.modal-title {
-	margin: 0;
-	line-height: 1.4;
-}
-
-.modal-dialog {
-	position: relative;
-	width: auto;
-	margin: 10px;
-}
-
-.modal-content {
-	position: relative;
-	background-color: #fff;
-	background-clip: padding-box;
-	border: 1px solid #999;
-	border: 1px solid rgba(0, 0, 0, .2);
-	outline: 0;
-}
-
-.modal-body {
-	position: relative;
-}
-
-@media (min-width: 768px) {
-	.modal-dialog {
+	.modal .dialog {
 		width: 600px;
-		margin: 30px auto;
 	}
-
-	.modal-content {
-	}
-}
-
-.row.history:first-child {
-	border-top: 0px;
-}
-
-form>div.history {
-	margin-top: 8px;
-	overflow: hidden;
-	display: none;
-	margin-bottom: 1em;
-	user-select: none;
-}
-:checked ~ .history {
-	display: block;
-}
-.row.history {
-	font-size: 1.2em;
-	background-color: white;
-	color: black;
-	margin: 0;
-	border-top: 1px solid rgba(0, 0, 0, .2);
-	padding: .3em .6em .3em .3em;
-	cursor: pointer;
-
-	display: flex;
-	justify-content: space-between;
-}
-
-.history.via {
-	font-weight: 200;
-}
-.history.from,
-.history.to {
-	width: 40%;
-}
-.history.to {
-	text-align: right;
-}
-
-.history.arrow {
-	width: 25px;
-}
-
-.station-column {
-	width: 60%;
-}
-
-.modal {
-	display: flex;
-}
-
-.box {
-	margin: auto;
-	background-color: white;
-	width: max-content;
-	padding: 15px;
-}
-
-.select a {
-	display: block;
-	text-decoration: none;
-	background-color: rgba(20, 30, 255, .7);
-	color: white;
-	width: 100%;
-	padding: 8px 20px;
-	margin-left: auto;
-	margin-top: 10px;
-	text-align: center;
-	transition: background-color 300ms;
-}
-
-.select a:first-child {
-	margin-top: 0px;
-}
-
-.select a:hover {
-	background-color: rgba(70, 100, 255, .8);
-	cursor: pointer;
-}
-
-.journey .link {
-	vertical-align: bottom;
-	cursor: pointer;
-	max-inline-size: 22px;
-	margin: 0 .3em;
-}
-
-.remark {
-	vertical-align: middle;
-}
-
-.remarks td {
-	margin: 0 10px;
-	text-align: left;
-	display: block;
-}
-
-.remarks {
-	/*background: #000000d0;*/
-	border: 1px solid #ddd;
-	padding: 0;
-	width: 100%;
-	margin: 0;
 }
 
 .icon-back {

@@ -762,10 +869,6 @@ form>div.history {
 	content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z"/><path d="M0 0h24v24H0z" fill="none"/></svg>');
 }
 
-.icon-arrow3 {
-	content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="black" width="18px" height="18px"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/><path d="M0 0h24v24 H0z" fill="none"/></svg>');
-}
-
 .icon-swap {
 	content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M16 17.01V10h-2v7.01h-3L15 21l4-3.99h-3zM9 3L5 6.99h3V14h2V6.99h3L9 3z"/><path d="M0 0h24v24H0z" fill="none"/></svg>');
 }

@@ -790,141 +893,10 @@ form>div.history {
 	content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path style="fill: white;" d="M12 2c-4 0-8 .5-8 4v9.5C4 17.43 5.57 19 7.5 19L6 20.5v.5h2.23l2-2H14l2 2h2v-.5L16.5 19c1.93 0 3.5-1.57 3.5-3.5V6c0-3.5-3.58-4-8-4zM7.5 17c-.83 0-1.5-.67-1.5-1.5S6.67 14 7.5 14s1.5.67 1.5 1.5S8.33 17 7.5 17zm3.5-7H6V6h5v4zm2 0V6h5v4h-5zm3.5 7c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"/><path fill="none" d="M0 0h24v24H0V0z"/></svg>')
 }
 
-
-.selector label {
-	display: flex;
-	justify-content: center;
-	align-items: center;
-}
-.selector label:after {
-	font-size: .9rem;
-	color: black;
-	text-align: center;
-	line-height: .9rem;
-	margin-top: 2px;
-}
-
-.selector label.icon-ice,
-.selector label.icon-ic,
-.selector label.icon-icice,
-.selector label.icon-dzug,
-.selector label.icon-regional {
-	font-style: italic;
-}
-
-.selector label.icon-tram:after,
-.selector label.icon-bus:after,
-.selector label.icon-ferry:after,
-.selector label.icon-taxi:after {
-	font-size: 0.6rem;
-}
-
-.icon-ice:after {
-	content: 'ICE';
-}
-
-.icon-ic:after {
-	content: 'IC';
-}
-
-.icon-icice:after {
-	content: 'IC ICE';
-}
-
-.icon-dzug:after {
-	content: 'D';
-}
-
-.icon-regional:after {
-	content: 'NV';
-}
-
-.icon-suburban:after {
-	content: 'S';
-}
-
-.icon-subway:after {
-	content: 'U';
-}
-
-.icon-tram:after {
-	content: 'Tram';
-}
-
-.icon-bus:after {
-	content: 'Bus';
-}
-
-.icon-ferry:after {
-	content: 'Ferry';
-}
-
-.icon-taxi:after {
-	content: 'Taxi';
-}
-
-#selected {
-	background-color: #bfbfbf !important;
-}
-
-#content {
-	display: flex;
-	flex-direction: column;
-	min-height: 100vh;
-
-}
-
-/* table */
 .icon-table {
-        content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M3 9h14V7H3v2zm0 4h14v-2H3v2zm0 4h14v-2H3v2zm16 0h2v-2h-2v2zm0-10v2h2V7h-2zm0 6h2v-2h-2v2z"/></svg>');
-	filter: invert();
+	content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path fill="white" d="M3 9h14V7H3v2zm0 4h14v-2H3v2zm0 4h14v-2H3v2zm16 0h2v-2h-2v2zm0-10v2h2V7h-2zm0 6h2v-2h-2v2z"/></svg>');
 }
-/* canvas */
 .icon-canvas {
 	transform: rotate(90deg);
-	content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M5 13h14v-2H5v2zm-2 4h14v-2H3v2zM7 7v2h14V7H7z"/></svg>');
-	filter: invert();
-}
-
-.mode-changers {
-	display: flex;
-	margin-left: auto;
-}
-.mode-changers a.active {
-	border-bottom: 3px solid white;
-}
-.mode-changers a {
-	border-bottom: 3px solid transparent;
-	align-items: center;
-	display: flex;
-	padding: 0 1em;
-	cursor: pointer;
-	text-decoration: none;
-}
-.mode-changers a span {
-	font-weight: bold;
-	margin: 1em .4em;
-}
-
-header h3 {
-	margin-right: 1.5em;
-}
-
-.train-details {
-	display: flex;
-	justify-content: center;
-	flex-wrap: wrap;
-}
-
-.journey thead>tr:nth-child(2) {
-	border-bottom: 2px solid #ccc;
-}
-
-.train-detail {
-	margin: .4em 2em;
-}
-
-#searchView {
-	background-color: #222;
-	flex-grow: 1;
+	content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path fill="white" d="M5 13h14v-2H5v2zm-2 4h14v-2H3v2zM7 7v2h14V7H7z"/></svg>');
 }