Frontend-Umgestaltung: Pill-Navigation, freischwebende Bottom-Bar, fette Abfahrtstafel
Die letzten beiden Commits waren zu zaghaft, um wirklich aufzufallen - unter
anderem, weil zwei der Änderungen durch spätere, unconditioneller stehende
Regeln in der Cascade wieder überschrieben wurden (die Desktop-Breite von
.app-main und die Raster-Spalten von .favorite-cards/.more-grid/
.nearby-preview haben durch die Reihenfolge in der Datei praktisch nichts
bewirkt). Diesmal echte strukturelle Änderungen statt nur zusätzlicher
Schatten, an den tatsächlich wirksamen Stellen im Stylesheet:
- Navigation umgestellt von Unterstrichen-Tabs auf eine segmentierte
Pill-Leiste (Desktop) - aktiver Tab bekommt den vollen Amber-Verlauf als
Hintergrund statt nur eine andere Textfarbe.
- Mobile Bottom-Nav ist jetzt eine freischwebende Glas-Leiste (abgesetzt vom
Rand, abgerundet, Weichzeichner-Hintergrund wie Header/Toasts) statt eines
am Bildschirmrand klebenden Balkens. Aktiver Eintrag bekommt eine
Hintergrund-Pille statt nur Textfarbe. Bottom-Offsets von Toast/Footer
entsprechend angepasst.
- Abfahrtstafel: Uhrzeit deutlich größer/fetter (Kernaussage der Zeile),
Linien-Badge etwas kräftiger, dickerer farbiger Rand pro Zeile.
- Logo/Marke: kleines Icon-Badge davor, größer und fetter - dabei einen
echten Bug gefunden und behoben (eine spätere `.brand { font: inherit }`
-Regel hat die Typografie der Marke bisher komplett überschrieben, sie lief
also die ganze Zeit in der Browser-Standardschrift statt der eigentlich
vorgesehenen).
- Eckenradius global etwas großzügiger (10→13px / 18→22px).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01De7H8hR1Q9DdgyuS2ukN6y
This commit is contained in:
1 file changed
+98
-35
+98
-35
@@ -21,9 +21,9 @@
|
|||||||
--font-body: 'IBM Plex Sans', -apple-system, sans-serif;
|
--font-body: 'IBM Plex Sans', -apple-system, sans-serif;
|
||||||
--font-label: 'IBM Plex Sans Condensed', sans-serif;
|
--font-label: 'IBM Plex Sans Condensed', sans-serif;
|
||||||
|
|
||||||
--radius: 10px;
|
--radius: 13px;
|
||||||
--radius-lg: 18px;
|
--radius-lg: 22px;
|
||||||
--header-height: 64px;
|
--header-height: 68px;
|
||||||
|
|
||||||
--shadow-sm: 0 2px 10px rgba(0, 0, 0, 0.22);
|
--shadow-sm: 0 2px 10px rgba(0, 0, 0, 0.22);
|
||||||
--shadow-md: 0 10px 26px rgba(0, 0, 0, 0.32);
|
--shadow-md: 0 10px 26px rgba(0, 0, 0, 0.32);
|
||||||
@@ -155,9 +155,26 @@ button {
|
|||||||
.brand {
|
.brand {
|
||||||
font-family: var(--font-display);
|
font-family: var(--font-display);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-size: 18px;
|
font-size: 20px;
|
||||||
letter-spacing: 0.06em;
|
letter-spacing: 0.04em;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand::before {
|
||||||
|
content: '🚏';
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
border-radius: 9px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
font-size: 15px;
|
||||||
|
background: linear-gradient(155deg, #ffc158, var(--signal-amber) 65%);
|
||||||
|
box-shadow: var(--shadow-glow-amber);
|
||||||
}
|
}
|
||||||
|
|
||||||
.brand__mark {
|
.brand__mark {
|
||||||
@@ -396,18 +413,6 @@ button {
|
|||||||
to { opacity: 1; transform: translateY(0); }
|
to { opacity: 1; transform: translateY(0); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ab hier: großzügigere Nutzung des Platzes auf breiten Bildschirmen -
|
|
||||||
Mobile bleibt die Grundlage (Layout unten bricht bei 700px zusammen),
|
|
||||||
aber die Karten-Raster sollen auf dem Desktop nicht wie eine einzelne
|
|
||||||
schmale Spalte in der Mitte wirken. */
|
|
||||||
@media (min-width: 960px) {
|
|
||||||
.app-main { max-width: 900px; padding: 32px 24px 48px; }
|
|
||||||
.favorite-cards { grid-template-columns: repeat(3, minmax(0,1fr)); gap: 12px; }
|
|
||||||
.more-grid { grid-template-columns: repeat(4, minmax(0,1fr)); gap: 12px; }
|
|
||||||
.nearby-preview { grid-template-columns: repeat(4, minmax(0,1fr)); }
|
|
||||||
.welcome-panel p { max-width: 560px; }
|
|
||||||
.journey-card-form { padding: 18px 22px; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ============================================================
|
/* ============================================================
|
||||||
Abfahrtstafel (Signature-Element)
|
Abfahrtstafel (Signature-Element)
|
||||||
@@ -1168,7 +1173,6 @@ button:active { transform: translateY(1px); }
|
|||||||
border: 0;
|
border: 0;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font: inherit;
|
|
||||||
}
|
}
|
||||||
.search-box--global { max-width: 620px; }
|
.search-box--global { max-width: 620px; }
|
||||||
.search-box--global input { padding: 12px 42px 12px 42px; font-size: 15px; }
|
.search-box--global input { padding: 12px 42px 12px 42px; font-size: 15px; }
|
||||||
@@ -1229,16 +1233,43 @@ button:active { transform: translateY(1px); }
|
|||||||
}
|
}
|
||||||
|
|
||||||
.favorites-bar { display: none; }
|
.favorites-bar { display: none; }
|
||||||
|
|
||||||
|
/* Segmentierte Pill-Navigation statt schlichter Unterstreichung - der aktive
|
||||||
|
Tab bekommt einen vollen Amber-Verlauf-Hintergrund (dieselbe Formsprache
|
||||||
|
wie der primäre Such-Button), statt nur eine andere Textfarbe zu haben. */
|
||||||
.tab-nav {
|
.tab-nav {
|
||||||
max-width: 1120px;
|
max-width: 1120px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 0 20px;
|
padding: 14px 20px;
|
||||||
border-bottom: 1px solid var(--line);
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
.tab-button { padding: 14px 18px; display: inline-flex; gap: 8px; align-items: center; }
|
.tab-nav__list {
|
||||||
.tab-button__icon { filter: grayscale(.35); }
|
display: inline-flex;
|
||||||
|
gap: 2px;
|
||||||
|
background: var(--panel);
|
||||||
|
border: 1px solid var(--line);
|
||||||
|
border-radius: 999px;
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
.tab-button {
|
||||||
|
padding: 10px 18px;
|
||||||
|
display: inline-flex;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 999px;
|
||||||
|
border-bottom: none;
|
||||||
|
transition: background .18s ease, color .18s ease, box-shadow .18s ease;
|
||||||
|
}
|
||||||
|
.tab-button__icon { filter: grayscale(.35); transition: filter .18s ease; }
|
||||||
|
.tab-button:hover:not(.is-active) { color: var(--ink); }
|
||||||
|
.tab-button.is-active {
|
||||||
|
background: linear-gradient(155deg, #ffc158, var(--signal-amber) 65%);
|
||||||
|
color: #1a1206;
|
||||||
|
box-shadow: var(--shadow-glow-amber);
|
||||||
|
}
|
||||||
|
.tab-button.is-active .tab-button__icon { filter: none; }
|
||||||
|
|
||||||
.app-main { max-width: 920px; padding: 30px 20px 50px; }
|
.app-main { max-width: 960px; padding: 30px 20px 50px; }
|
||||||
|
|
||||||
.welcome-panel {
|
.welcome-panel {
|
||||||
padding: 28px;
|
padding: 28px;
|
||||||
@@ -1454,8 +1485,9 @@ button:active { transform: translateY(1px); }
|
|||||||
}
|
}
|
||||||
.favorite-toggle { padding: 8px 12px; }
|
.favorite-toggle { padding: 8px 12px; }
|
||||||
|
|
||||||
.flap-row { grid-template-columns: 82px minmax(0,1fr) 82px 112px; padding: 14px 16px 14px 13px; }
|
.flap-row { grid-template-columns: 82px minmax(0,1fr) 82px 118px; padding: 16px 18px 16px 15px; border-left-width: 5px; }
|
||||||
.flap-cell--time { font-size: 17px; }
|
.flap-cell--time { font-size: 21px; letter-spacing: -.01em; }
|
||||||
|
.flap-cell--line { font-size: 17px; padding: 6px 10px; }
|
||||||
.flap-cell--direction { font-size: 15px; font-weight: 600; }
|
.flap-cell--direction { font-size: 15px; font-weight: 600; }
|
||||||
.flap-cell--platform { font-size: 14px; }
|
.flap-cell--platform { font-size: 14px; }
|
||||||
.station-disruption { background: rgba(255,93,108,.08); border: 1px solid rgba(255,93,108,.3); color: var(--ink); border-radius: 9px; padding: 12px; margin-top: 14px; font-size: 12px; }
|
.station-disruption { background: rgba(255,93,108,.08); border: 1px solid rgba(255,93,108,.3); color: var(--ink); border-radius: 9px; padding: 12px; margin-top: 14px; font-size: 12px; }
|
||||||
@@ -1593,6 +1625,17 @@ button:active { transform: translateY(1px); }
|
|||||||
.more-card > span { grid-row: span 2; font-size: 23px; }
|
.more-card > span { grid-row: span 2; font-size: 23px; }
|
||||||
.more-card small { color: var(--ink-muted); font-size: 12px; }
|
.more-card small { color: var(--ink-muted); font-size: 12px; }
|
||||||
.more-card:hover { border-color: var(--signal-amber); }
|
.more-card:hover { border-color: var(--signal-amber); }
|
||||||
|
|
||||||
|
/* Breitere Bildschirme sollen die Karten-Raster wirklich nutzen, statt wie
|
||||||
|
eine schmale Spalte in der Mitte zu wirken. */
|
||||||
|
@media (min-width: 960px) {
|
||||||
|
.favorite-cards { grid-template-columns: repeat(3, minmax(0,1fr)); gap: 12px; }
|
||||||
|
.more-grid { grid-template-columns: repeat(4, minmax(0,1fr)); gap: 12px; }
|
||||||
|
.nearby-preview { grid-template-columns: repeat(4, minmax(0,1fr)); }
|
||||||
|
.welcome-panel p { max-width: 560px; }
|
||||||
|
.journey-card-form { padding: 18px 22px; }
|
||||||
|
}
|
||||||
|
|
||||||
.recent-section { margin-top: 28px; }
|
.recent-section { margin-top: 28px; }
|
||||||
.recent-searches { display: flex; flex-wrap: wrap; gap: 8px; }
|
.recent-searches { display: flex; flex-wrap: wrap; gap: 8px; }
|
||||||
.recent-item {
|
.recent-item {
|
||||||
@@ -2363,9 +2406,10 @@ html.simple-mode .when-choice { min-height: 46px; }
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 700px) {
|
@media (max-width: 700px) {
|
||||||
body { padding-bottom: 66px; }
|
body { padding-bottom: 84px; }
|
||||||
.app-header { height: auto; min-height: 64px; padding: 10px 12px; gap: 8px; }
|
.app-header { height: auto; min-height: 64px; padding: 10px 12px; gap: 8px; }
|
||||||
.brand { font-size: 15px; }
|
.brand { font-size: 15px; gap: 7px; }
|
||||||
|
.brand::before { width: 24px; height: 24px; border-radius: 7px; font-size: 12px; }
|
||||||
.search-box--global { min-width: 0; }
|
.search-box--global { min-width: 0; }
|
||||||
.search-box--global input { font-size: 14px; padding: 10px 38px; }
|
.search-box--global input { font-size: 14px; padding: 10px 38px; }
|
||||||
.header-icon-btn { width: 34px; height: 34px; font-size: 15px; }
|
.header-icon-btn { width: 34px; height: 34px; font-size: 15px; }
|
||||||
@@ -2376,31 +2420,50 @@ html.simple-mode .when-choice { min-height: 46px; }
|
|||||||
.favorite-cards, .nearby-preview, .more-grid { grid-template-columns: 1fr; }
|
.favorite-cards, .nearby-preview, .more-grid { grid-template-columns: 1fr; }
|
||||||
.board-header { align-items: flex-start; }
|
.board-header { align-items: flex-start; }
|
||||||
.board-station-name { font-size: 20px; }
|
.board-station-name { font-size: 20px; }
|
||||||
.flap-row { grid-template-columns: 64px minmax(0,1fr) 58px 82px; gap: 14px; padding: 11px 10px; }
|
.flap-row { grid-template-columns: 60px minmax(0,1fr) 54px 78px; gap: 12px; padding: 12px 12px 12px 10px; border-left-width: 4px; }
|
||||||
.flap-label { font-size: 9px; }
|
.flap-label { font-size: 9px; }
|
||||||
.flap-cell--direction { font-size: 12px; }
|
.flap-cell--direction { font-size: 12px; }
|
||||||
.flap-cell--platform { font-size: 12px; }
|
.flap-cell--platform { font-size: 12px; }
|
||||||
.flap-cell--time { font-size: 14px; }
|
.flap-cell--line { font-size: 14px; padding: 4px 8px; }
|
||||||
|
.flap-cell--time { font-size: 17px; letter-spacing: -.01em; }
|
||||||
.journey-options-row { display: block; }
|
.journey-options-row { display: block; }
|
||||||
.journey-options-row .journey-submit { width: 100%; margin-top: 8px; }
|
.journey-options-row .journey-submit { width: 100%; margin-top: 8px; }
|
||||||
.journey-options-row .mode-filter { margin-bottom: 8px; }
|
.journey-options-row .mode-filter { margin-bottom: 8px; }
|
||||||
.journey-via-row__fields { flex-direction: column; align-items: stretch; }
|
.journey-via-row__fields { flex-direction: column; align-items: stretch; }
|
||||||
.journey-via-wait select { width: 100%; }
|
.journey-via-wait select { width: 100%; }
|
||||||
|
/* Freischwebende Glas-Leiste statt einer am Rand klebenden Balken -
|
||||||
|
abgesetzt vom Bildschirmrand, mit Weichzeichner-Hintergrund wie der
|
||||||
|
Header/die Toasts, damit sie wie eine eigene Ebene über dem Inhalt
|
||||||
|
wirkt statt wie ein angeklebtes Steuerelement. */
|
||||||
.mobile-nav {
|
.mobile-nav {
|
||||||
display: block; position: fixed; bottom: 0; left: 0; right: 0;
|
display: block; position: fixed; left: 10px; right: 10px;
|
||||||
|
bottom: calc(10px + env(safe-area-inset-bottom));
|
||||||
/* Muss über der (jetzt display-breiten) Live-Karte liegen - Leaflet nutzt
|
/* Muss über der (jetzt display-breiten) Live-Karte liegen - Leaflet nutzt
|
||||||
für seine eigenen Steuerelemente (Zoom-Buttons etc.) intern z-index-
|
für seine eigenen Steuerelemente (Zoom-Buttons etc.) intern z-index-
|
||||||
Werte bis ~1000, das HUD/die Navigation soll aber immer sichtbar und
|
Werte bis ~1000, das HUD/die Navigation soll aber immer sichtbar und
|
||||||
bedienbar bleiben, unabhängig von der Karte. */
|
bedienbar bleiben, unabhängig von der Karte. */
|
||||||
z-index: 1100; background: rgba(23,30,38,.97); border-top: 1px solid var(--line); padding: 5px 4px calc(5px + env(safe-area-inset-bottom));
|
z-index: 1100;
|
||||||
|
background: rgba(20, 26, 33, 0.82);
|
||||||
|
backdrop-filter: blur(18px) saturate(1.4);
|
||||||
|
-webkit-backdrop-filter: blur(18px) saturate(1.4);
|
||||||
|
border: 1px solid var(--line);
|
||||||
|
border-radius: 20px;
|
||||||
|
box-shadow: var(--shadow-lg);
|
||||||
|
padding: 6px 4px;
|
||||||
}
|
}
|
||||||
.mobile-nav__list { display: grid; grid-template-columns: repeat(6, 1fr); }
|
.mobile-nav__list { display: grid; grid-template-columns: repeat(6, 1fr); }
|
||||||
.mobile-nav__item { border: 0; background: transparent; color: var(--ink-muted); padding: 5px 1px; display: flex; flex-direction: column; align-items: center; gap: 2px; }
|
.mobile-nav__item {
|
||||||
|
position: relative;
|
||||||
|
border: 0; background: transparent; color: var(--ink-muted);
|
||||||
|
padding: 7px 1px; display: flex; flex-direction: column; align-items: center; gap: 2px;
|
||||||
|
border-radius: 14px;
|
||||||
|
transition: color .15s ease, background .15s ease;
|
||||||
|
}
|
||||||
.mobile-nav__item span { font-size: 16px; line-height: 1.1; }
|
.mobile-nav__item span { font-size: 16px; line-height: 1.1; }
|
||||||
.mobile-nav__item small { font-size: 8.5px; }
|
.mobile-nav__item small { font-size: 8.5px; }
|
||||||
.mobile-nav__item.is-active { color: var(--signal-amber); }
|
.mobile-nav__item.is-active { color: var(--signal-amber); background: var(--signal-amber-soft); }
|
||||||
.toast-container { bottom: calc(64px + env(safe-area-inset-bottom) + 12px); }
|
.toast-container { bottom: calc(66px + env(safe-area-inset-bottom) + 20px); }
|
||||||
.global-disclaimer { padding-bottom: calc(28px + 64px + env(safe-area-inset-bottom)); }
|
.global-disclaimer { padding-bottom: calc(28px + 66px + env(safe-area-inset-bottom) + 20px); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 430px) {
|
@media (max-width: 430px) {
|
||||||
|
|||||||
Reference in new issue
Block a user