commit c51a43883564187c886d2ad065cd84dd9f75c6f5
parent 233f9b7890c2b5add9460d750bc6bf32bc9c552f
Author: Katja (ctucx) <git@ctu.cx>
Date: Tue, 21 Jan 2025 12:20:57 +0100
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
|
106
+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
M
|
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>'); }