From 37d8eedd641bb04c086797010292bcb25240d56d Mon Sep 17 00:00:00 2001 From: Ariel Costas Guerrero Date: Thu, 6 Nov 2025 23:36:52 +0100 Subject: Refactor styles and add alert color variables; implement scroll management for timetable --- src/frontend/app/components/SchedulesTable.css | 55 +++-- src/frontend/app/components/StopAlert.css | 50 +++-- src/frontend/app/components/StopAlert.tsx | 9 +- src/frontend/app/components/StopItemSkeleton.tsx | 2 +- src/frontend/app/components/StopSheetSkeleton.tsx | 4 +- src/frontend/app/components/TimetableSkeleton.tsx | 2 +- src/frontend/app/root.css | 32 +++ src/frontend/app/root.tsx | 12 ++ src/frontend/app/routes/map.tsx | 21 +- src/frontend/app/routes/timetable-$id.css | 2 - src/frontend/app/routes/timetable-$id.tsx | 235 ++++++++++++--------- src/frontend/public/maps/spritesheet/sprite.json | 16 ++ src/frontend/public/maps/spritesheet/sprite.png | Bin 1515 -> 2987 bytes .../public/maps/spritesheet/sprite@2x.json | 16 ++ src/frontend/public/maps/spritesheet/sprite@2x.png | Bin 2878 -> 7056 bytes 15 files changed, 295 insertions(+), 161 deletions(-) (limited to 'src/frontend') diff --git a/src/frontend/app/components/SchedulesTable.css b/src/frontend/app/components/SchedulesTable.css index 8980fb4..6d2f201 100644 --- a/src/frontend/app/components/SchedulesTable.css +++ b/src/frontend/app/components/SchedulesTable.css @@ -7,7 +7,7 @@ margin-bottom: 1rem; text-align: left; font-size: 1.1rem; - color: var(--text-primary, #333); + color: var(--text-primary); } .timetable-cards { @@ -18,17 +18,36 @@ } .timetable-card { - background-color: var(--surface-future, #fff); - border: 1px solid var(--card-border, #e0e0e0); + background-color: var(--surface-future); + border: 1px solid var(--card-border); border-radius: 10px; padding: 1.25rem; transition: background-color 0.2s ease, border 0.2s ease; } +/* Next upcoming service: slight emphasis */ +.timetable-card.timetable-next { + background-color: var(--surface-next); + border-color: var(--card-border); + position: relative; +} + +.timetable-card.timetable-next::before { + content: ""; + position: absolute; + left: 0; + top: 0; + bottom: 0; + width: 4px; + border-top-left-radius: 10px; + border-bottom-left-radius: 10px; + background: var(--accent-next); +} + .timetable-card.timetable-past { - background-color: var(--surface-past, #f3f3f3); - color: var(--text-secondary, #aaa); - border: 1px solid #e0e0e0; + background-color: var(--surface-past); + color: var(--text-secondary); + border: 1px solid var(--card-border); } .card-header { @@ -46,7 +65,7 @@ flex: 1; text-align: left; margin: 0 1rem; - color: var(--text-primary, #333); + color: var(--text-primary); } .destination-info strong { @@ -54,7 +73,7 @@ } .timetable-card.timetable-past .destination-info { - color: var(--text-secondary, #aaa); + color: var(--text-secondary); } .time-info { @@ -68,11 +87,11 @@ font-weight: bold; font-family: monospace; font-size: 1.1rem; - color: var(--text-primary, #333); + color: var(--text-primary); } .timetable-card.timetable-past .departure-time { - color: var(--text-secondary, #aaa); + color: var(--text-secondary); } .card-body { @@ -81,7 +100,7 @@ .route-streets { font-size: 0.85rem; - color: var(--text-secondary, #666); + color: var(--text-secondary); line-height: 1.8; word-break: break-word; } @@ -89,8 +108,8 @@ .service-id { font-family: monospace; font-size: 0.8rem; - color: var(--text-secondary, #666); - background: var(--service-background, #f0f0f0); + color: var(--text-secondary); + background: var(--service-background); padding: 0.15rem 0.4rem; border-radius: 3px; font-weight: 500; @@ -99,18 +118,18 @@ } .timetable-card.timetable-past .service-id { - color: var(--text-secondary, #bbb); - background: #e8e8e8; + color: var(--text-secondary); + background: var(--service-background-past); } .no-data { text-align: center; - color: var(--text-secondary, #666); + color: var(--text-secondary); font-style: italic; padding: 2rem; - background: var(--card-background, #f8f9fa); + background: var(--card-background); border-radius: 8px; - border: 1px solid var(--card-border, #e0e0e0); + border: 1px solid var(--card-border); } /* Responsive design */ diff --git a/src/frontend/app/components/StopAlert.css b/src/frontend/app/components/StopAlert.css index 0032d09..2ba3baa 100644 --- a/src/frontend/app/components/StopAlert.css +++ b/src/frontend/app/components/StopAlert.css @@ -1,3 +1,25 @@ +/* Alert color variables */ +:root { + --alert-info-bg: rgba(59, 130, 246, 0.1); + --alert-info-border: rgba(59, 130, 246, 0.5); + --alert-info-text: #1e40af; + + --alert-error-bg: rgba(239, 68, 68, 0.1); + --alert-error-border: rgba(239, 68, 68, 0.5); + --alert-error-text: #991b1b; +} + +/* Dark mode overrides use data-mode */ +[data-mode="dark"] { + --alert-info-bg: rgba(59, 130, 246, 0.15); + --alert-info-border: rgba(59, 130, 246, 0.4); + --alert-info-text: #93c5fd; + + --alert-error-bg: rgba(239, 68, 68, 0.15); + --alert-error-border: rgba(239, 68, 68, 0.4); + --alert-error-text: #fca5a5; +} + .stop-alert { display: flex; align-items: flex-start; @@ -9,20 +31,20 @@ } .stop-alert-info { - background-color: rgba(59, 130, 246, 0.1); - border-color: rgba(59, 130, 246, 0.3); - color: #1e40af; + background-color: var(--alert-info-bg); + border-color: var(--alert-info-border); + color: var(--alert-info-text); } .stop-alert-error { - background-color: rgba(239, 68, 68, 0.1); - border-color: rgba(239, 68, 68, 0.3); - color: #991b1b; + background-color: var(--alert-error-bg); + border-color: var(--alert-error-border); + color: var(--alert-error-text); } .stop-alert-compact { padding: 0.5rem; - margin: 0.5rem 0; + margin: 1.5rem 0 0.5rem 0; font-size: 0.875rem; } @@ -73,17 +95,3 @@ font-size: 0.75rem; } -/* Dark mode support */ -@media (prefers-color-scheme: dark) { - .stop-alert-info { - background-color: rgba(59, 130, 246, 0.15); - border-color: rgba(59, 130, 246, 0.4); - color: #93c5fd; - } - - .stop-alert-error { - background-color: rgba(239, 68, 68, 0.15); - border-color: rgba(239, 68, 68, 0.4); - color: #fca5a5; - } -} diff --git a/src/frontend/app/components/StopAlert.tsx b/src/frontend/app/components/StopAlert.tsx index 69ecc22..a96f93e 100644 --- a/src/frontend/app/components/StopAlert.tsx +++ b/src/frontend/app/components/StopAlert.tsx @@ -19,17 +19,10 @@ export const StopAlert: React.FC = ({ stop, compact = false }) = return (
-
- {isError ? : } -
+ {isError ? : }
{stop.title &&
{stop.title}
} {stop.message &&
{stop.message}
} - {stop.alternateCodes && stop.alternateCodes.length > 0 && ( -
- Alternative stops: {stop.alternateCodes.join(", ")} -
- )}
); diff --git a/src/frontend/app/components/StopItemSkeleton.tsx b/src/frontend/app/components/StopItemSkeleton.tsx index 72f7506..9133393 100644 --- a/src/frontend/app/components/StopItemSkeleton.tsx +++ b/src/frontend/app/components/StopItemSkeleton.tsx @@ -12,7 +12,7 @@ const StopItemSkeleton: React.FC = ({ stopId }) => { return ( - +
  • diff --git a/src/frontend/app/components/StopSheetSkeleton.tsx b/src/frontend/app/components/StopSheetSkeleton.tsx index 651efa5..6870af2 100644 --- a/src/frontend/app/components/StopSheetSkeleton.tsx +++ b/src/frontend/app/components/StopSheetSkeleton.tsx @@ -13,7 +13,7 @@ export const StopSheetSkeleton: React.FC = ({ const { t } = useTranslation(); return ( - +

    {t("estimates.next_arrivals", "Next arrivals")} @@ -53,7 +53,7 @@ export const StopSheetSkeleton: React.FC = ({

    diff --git a/src/frontend/app/components/TimetableSkeleton.tsx b/src/frontend/app/components/TimetableSkeleton.tsx index 01956ee..79c7725 100644 --- a/src/frontend/app/components/TimetableSkeleton.tsx +++ b/src/frontend/app/components/TimetableSkeleton.tsx @@ -13,7 +13,7 @@ export const TimetableSkeleton: React.FC = ({ const { t } = useTranslation(); return ( - +
    diff --git a/src/frontend/app/root.css b/src/frontend/app/root.css index 202e6f1..fb955eb 100644 --- a/src/frontend/app/root.css +++ b/src/frontend/app/root.css @@ -10,6 +10,22 @@ --star-color: #ffcc00; --message-background-color: #f8f9fa; + /* Skeletons */ + --skeleton-base: #f0f0f0; + --skeleton-highlight: #e0e0e0; + + /* Timetable component variables */ + --text-primary: var(--text-color); + --text-secondary: #666666; + --surface-future: var(--background-color); + --surface-next: #eef6ff; /* slightly accented surface for next card */ + --surface-past: hsl(0 0% 25% / 1); + --accent-next: #1e88e5; /* accent color for next card left border */ + --card-border: var(--border-color); + --card-background: #f8f9fa; + --service-background: #f0f0f0; + --service-background-past: #e8e8e8; + color-scheme: light; font-family: "Roboto Variable", Roboto, Arial, sans-serif; } @@ -26,6 +42,22 @@ --star-color: #ffcc00; --message-background-color: #333333; + /* Skeletons (dark) */ + --skeleton-base: #2a2a2a; + --skeleton-highlight: #3a3a3a; + + /* Timetable component dark overrides */ + --text-primary: var(--text-color); + --text-secondary: #bbbbbb; + --surface-future: #1e1e1e; + --surface-next: #17212b; + --surface-past: #1a1a1a; + --accent-next: #64b5f6; + --card-border: var(--border-color); + --card-background: #1e1e1e; + --service-background: #222222; + --service-background-past: #1f1f1f; + color-scheme: dark; } diff --git a/src/frontend/app/root.tsx b/src/frontend/app/root.tsx index 4815d2f..9bc69e4 100644 --- a/src/frontend/app/root.tsx +++ b/src/frontend/app/root.tsx @@ -76,6 +76,18 @@ export function Layout({ children }: { children: React.ReactNode }) { Busurbano + {/* Set theme early to avoid flash of wrong theme (especially skeletons) */} +