From 4ae422499242240dae82e1c8eacd476df2f560b6 Mon Sep 17 00:00:00 2001 From: Jos Nienhuis <6952249+joszz@users.noreply.github.com> Date: Sat, 10 Oct 2026 22:06:07 +0200 Subject: [PATCH 1/3] fix(ui): even out spacing and card titles across the views - Every card heading uses .card-title (statistics charts and the trip sidebar gain an icon), replacing three look-alike title classes. - Statistics chart cards take the 1.25rem card padding and 1.5rem section spacing; the trip log totals follow the status grid. - Page subtitles share .view-subtitle, tucked under the title. - The maintenance detail modal uses the shared modal sections. - Phones keep one 0.75rem gutter for content, topbar and footer; the extra-small breakpoint that shrank it is gone. - Form controls inherit the page font from one global rule; small buttons get side padding; radii settle on 6px for controls. Co-Authored-By: Claude Opus 5.5 --- frontend/src/assets/carDiagram.css | 12 -- frontend/src/assets/login.css | 1 - frontend/src/assets/main.css | 73 ++++----- frontend/src/assets/maintenance.css | 7 - frontend/src/assets/map.css | 9 +- frontend/src/assets/statistics.css | 8 +- frontend/src/assets/tripLog.css | 10 +- frontend/src/components/CarDiagram.vue | 2 +- frontend/src/components/LocationMapWidget.vue | 2 +- .../components/MaintenanceItemDetailModal.vue | 146 +++++++++--------- frontend/src/components/SkeletonChart.vue | 4 +- frontend/src/components/StatsChartCard.vue | 6 +- frontend/src/components/map/TripSidebar.vue | 5 +- frontend/src/views/ClimateSchedulesView.vue | 2 +- frontend/src/views/MaintenanceView.vue | 2 +- frontend/src/views/StatisticsView.vue | 7 +- frontend/src/views/TripLogView.vue | 2 +- 17 files changed, 144 insertions(+), 154 deletions(-) diff --git a/frontend/src/assets/carDiagram.css b/frontend/src/assets/carDiagram.css index 22ce9294..cb737f4a 100644 --- a/frontend/src/assets/carDiagram.css +++ b/frontend/src/assets/carDiagram.css @@ -129,18 +129,6 @@ } } -.tyre-diagram__title { - font-size: 0.85rem; - font-weight: 600; - margin-bottom: 1rem; - display: flex; - align-items: center; - gap: 0.5rem; - color: var(--color-text-muted); - text-transform: uppercase; - letter-spacing: 0.05em; -} - .tyre-diagram__wrap { display: flex; align-items: center; diff --git a/frontend/src/assets/login.css b/frontend/src/assets/login.css index 69c3c935..f100a9bf 100644 --- a/frontend/src/assets/login.css +++ b/frontend/src/assets/login.css @@ -88,7 +88,6 @@ font-size: 0.9rem; padding: 0.65rem 0.75rem 0.65rem 2.25rem; transition: border-color 0.15s; - font-family: inherit; } .login-field__input:focus { diff --git a/frontend/src/assets/main.css b/frontend/src/assets/main.css index 44cdf05d..9c14d413 100644 --- a/frontend/src/assets/main.css +++ b/frontend/src/assets/main.css @@ -61,6 +61,15 @@ /* Firefox */ * { scrollbar-width: thin; +/* Form controls take the system font from the browser rather than the page (Arial on Windows), + so every button, field and select would otherwise set itself apart from the text around it. */ +button, +input, +select, +textarea { + font-family: inherit; +} + scrollbar-color: var(--color-border) transparent; } @@ -202,7 +211,9 @@ body, color: var(--color-primary); text-decoration: none; margin-bottom: 2rem; - padding-left: 0.5rem; + + /* The nav links' own inline padding, so the logo sits in the same column as their icons. */ + padding-left: 0.75rem; } .sidebar-nav { @@ -276,6 +287,12 @@ body, .text-success { color: var(--color-success); } +/* A line about the page, tucked under its title rather than spaced like a section of its own. */ +.view-subtitle { + margin-top: -1rem; + margin-bottom: 1.5rem; +} + .text-danger { color: var(--color-danger); @@ -548,7 +565,6 @@ body, /* A row that leads somewhere else: the whole row is the button. */ .detail-list__item--link { width: 100%; - font-family: inherit; color: var(--color-text); text-align: left; cursor: pointer; @@ -639,17 +655,7 @@ body, } } -/* ── Card component ───────────────────────────────────────── */ - -.card { - background: var(--color-surface); - border: 1px solid var(--color-border); - border-radius: var(--radius); -} - -.card-body { - padding: 1rem 1.25rem; -} +/* ── Card title ───────────────────────────────────────────── */ .card-title { font-size: 0.85rem; @@ -657,7 +663,7 @@ body, color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.05em; - margin-bottom: 0.75rem; + margin-bottom: 1rem; display: flex; align-items: center; gap: 0.5rem; @@ -665,6 +671,8 @@ body, /* ── Leaflet map chrome ───────────────────────────────────── */ +/* The heading of every card that has one (overview, location, trip history, the statistics + charts): small muted capitals with the card's icon in front. */ /* Leaflet ships a light-only frame: a pale grey canvas, white zoom buttons, white popups and a white attribution strip. Over the vector basemap, which follows the theme, those read as holes punched in the map, so the chrome is re-pointed at the theme tokens and now follows dark and @@ -1021,7 +1029,7 @@ body, .btn-sm { font-size: 0.78rem; - padding: 0.3rem; + padding: 0.3rem 0.6rem; } .btn-primary { @@ -1169,6 +1177,11 @@ body, .form-control { width: 100%; +/* A button in the stack keeps its own width instead of stretching into a bar across the form. */ +.form-stack > .btn { + align-self: flex-start; +} + padding: 0.4rem 0.6rem; font-size: 0.85rem; border-radius: 6px; @@ -1179,7 +1192,6 @@ body, textarea.form-control { resize: vertical; - font-family: inherit; } /* A time of day as selects (TimeOfDaySelect): hour and minute, plus AM or PM on a 12-hour clock. */ @@ -1896,11 +1908,17 @@ textarea.form-control { .main-content { padding: 0.75rem; + /* The same gutter as the topbar, so the page title and cards line up under the menu button and + the footer under both. */ overflow-x: hidden; } /* Icon sits flush at button left so it aligns with card left edge */ .hamburger { + .app-footer { + padding: 0 0.75rem; + } + justify-content: flex-start; } @@ -1933,22 +1951,6 @@ textarea.form-control { } } -/* ── Very small phones (< 400px) ─────────────────────────── */ - -@media (width <= 399px) { - .main-content { - padding: 0.5rem; - } - - .status-grid { - gap: 0.4rem; - } - - .status-card { - padding: 0.65rem 0.75rem; - } -} - /* ── Tablet (600–1023px) ──────────────────────────────────── */ @media (width >= 600px) and (width <= 1023px) { @@ -2261,7 +2263,8 @@ textarea.form-control { gap: 0.4rem; } -.demo-panel-section { +/* Between sections only, so the panel's padding is the same at the bottom as at the top. */ +.demo-panel-section:not(:last-child) { margin-bottom: 0.75rem; } @@ -2283,7 +2286,7 @@ textarea.form-control { .demo-toggle-btn { padding: 0.25rem 0.6rem; font-size: 0.75rem; - border-radius: 4px; + border-radius: 6px; border: 1px solid var(--color-border); background-color: var(--color-surface-2); color: var(--color-text); @@ -2334,7 +2337,7 @@ textarea.form-control { width: 100%; padding: 0.3rem 0.5rem; font-size: 0.8rem; - border-radius: 4px; + border-radius: 6px; border: 1px solid var(--color-border); background-color: var(--color-surface-2); color: var(--color-text); diff --git a/frontend/src/assets/maintenance.css b/frontend/src/assets/maintenance.css index 3bd37aec..a5200f60 100644 --- a/frontend/src/assets/maintenance.css +++ b/frontend/src/assets/maintenance.css @@ -13,13 +13,6 @@ margin-bottom: 0.3rem; } -.maintenance-detail__heading { - font-size: 0.85rem; - color: var(--color-text-muted); - margin-top: 1rem; - margin-bottom: 0.2rem; -} - .maintenance-log-form { gap: 0.6rem; } diff --git a/frontend/src/assets/map.css b/frontend/src/assets/map.css index b3f3c361..89ba1fec 100644 --- a/frontend/src/assets/map.css +++ b/frontend/src/assets/map.css @@ -53,12 +53,9 @@ border-bottom: 1px solid var(--color-border); } -.trip-sidebar__title { - font-size: 0.85rem; - font-weight: 600; - color: var(--color-text-muted); - text-transform: uppercase; - letter-spacing: 0.05em; +/* The header's border does the separating here, so the title keeps none of its own margin. */ +.trip-sidebar__header .trip-sidebar__title { + margin-bottom: 0; } .trip-list { diff --git a/frontend/src/assets/statistics.css b/frontend/src/assets/statistics.css index f912e777..65797893 100644 --- a/frontend/src/assets/statistics.css +++ b/frontend/src/assets/statistics.css @@ -5,12 +5,6 @@ background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius); - padding: 1.5rem; + padding: 1.25rem; overflow: visible; } - -.chart-container h2 { - font-size: 1rem; - margin-bottom: 1rem; - color: var(--color-text-muted); -} diff --git a/frontend/src/assets/tripLog.css b/frontend/src/assets/tripLog.css index aed45f53..3914913a 100644 --- a/frontend/src/assets/tripLog.css +++ b/frontend/src/assets/tripLog.css @@ -15,11 +15,13 @@ /* ── Totals per purpose ───────────────────────────────────── */ +/* Spaced like the status grid it borrows its cards from, and set off from the trips below as the + dashboard and statistics set their summaries off from what follows. */ .trip-log-totals { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); - gap: 0.75rem; - margin-bottom: 1rem; + gap: 1rem; + margin-bottom: 1.5rem; } /* ── Classify every unclassified trip at once ─────────────── */ @@ -32,7 +34,7 @@ padding: 0.6rem 0.9rem; margin-bottom: 1rem; border: 1px solid var(--color-border); - border-radius: 8px; + border-radius: var(--radius); background: var(--color-surface); } @@ -63,7 +65,7 @@ align-items: center; padding: 0.75rem 0.9rem; border: 1px solid var(--color-border); - border-radius: 8px; + border-radius: var(--radius); background: var(--color-surface); transition: opacity 0.15s; } diff --git a/frontend/src/components/CarDiagram.vue b/frontend/src/components/CarDiagram.vue index 492fa806..5d5b7cc0 100644 --- a/frontend/src/components/CarDiagram.vue +++ b/frontend/src/components/CarDiagram.vue @@ -168,7 +168,7 @@ const motionBlurAmount = computed(() => {
-

+

{{ t('vehicle.overview') }}

diff --git a/frontend/src/components/LocationMapWidget.vue b/frontend/src/components/LocationMapWidget.vue index aba61dc0..2fe1f692 100644 --- a/frontend/src/components/LocationMapWidget.vue +++ b/frontend/src/components/LocationMapWidget.vue @@ -178,7 +178,7 @@ function openFullMap() {