Files
F-r-ldraledigplannerare/frontend/src/styles/responsive.css
T
jacobh2 296b596778 Settle on one visual language
The interface had drifted into two of everything. The calendar and its
popovers were built around a blue accent the rest of the app had long since
replaced with green, five different sizes served the same class of small
label, and page sections were a stack of identical bordered cards that gave
no sense of what mattered most. Sections now separate by space and a hairline,
the overview leads with its headline figure at a size that says so, and the
palette, type scale and spacing live in one place as variables rather than
scattered literals.

Two things were not styled at all. The sign-in screen was an unstyled form in
the top-left corner, and the tip cards had no rules whatsoever despite their
markup already carrying a severity, so every tip rendered identically with a
plain green square for its dismiss control.

The calendar was also unusable on a narrow screen: the preset rail never
collapsed and covered the last three columns of the grid.
2026-09-18 01:39:34 +02:00

250 lines
4.5 KiB
CSS

/* S7 - Responsive & Accessibility */
/* Mobile - Small screens (max 640px) */
@media (max-width: 640px) {
/* Sticky header with less padding */
.header {
padding: var(--sp-3) var(--sp-4);
}
.header__top {
margin-bottom: var(--sp-3);
}
.header__nav {
gap: var(--sp-2);
}
.header__nav-link {
padding: var(--sp-2) var(--sp-3);
font-size: var(--fs-sm);
}
.header__title {
font-size: var(--fs-base);
}
.header__identity {
gap: var(--sp-2);
font-size: var(--fs-sm);
}
/* Main content */
[data-testid='layout-main'] {
padding: var(--sp-4);
}
.dashboard__section,
.settings-page__section,
.calendar__section,
.tips-page__section {
padding: var(--sp-4);
margin-bottom: var(--sp-4);
}
/* Metrics - single column */
.overview-metrics__list {
grid-template-columns: 1fr;
}
/* Forms - full width */
.form-group input,
.form-group select,
.form-group textarea {
max-width: none;
width: 100%;
}
.form-grid {
grid-template-columns: 1fr;
}
.form-grid .form-group input,
.form-grid .form-group select {
max-width: none;
}
/* Tables */
.days-breakdown__table,
.parental-leave-breakdown__table,
.vacation-days-table {
font-size: var(--fs-sm);
}
.days-breakdown__table th,
.days-breakdown__table td,
.parental-leave-breakdown__table th,
.parental-leave-breakdown__table td,
.vacation-days-table th,
.vacation-days-table td {
padding: var(--sp-2) var(--sp-3);
}
.vacation-days-table__input {
width: 70px;
}
/* Modals */
.qrcode-modal {
width: 95%;
padding: var(--sp-4);
max-height: 95vh;
}
.qrcode-modal__qr-image {
max-width: 250px;
}
.qrcode-modal__button-group {
flex-direction: column-reverse;
}
.qrcode-modal__button {
width: 100%;
}
/* Footer */
footer {
padding: var(--sp-4);
font-size: var(--fs-sm);
}
/* Button group */
.modal__footer {
flex-direction: column-reverse;
}
.modal__footer button {
width: 100%;
}
/* Remove max-width on modal content */
.modal-content {
width: 95%;
padding: var(--sp-4);
max-height: 95vh;
}
/* Lists */
.dashboard__break-item {
flex-direction: column;
align-items: flex-start;
gap: var(--sp-2);
}
/* Loading spinner */
.loading-spinner {
padding: var(--sp-5);
min-height: 200px;
}
.loading-spinner__icon {
font-size: 36px;
}
/* Calendar responsiveness */
.calendar__grid {
font-size: var(--fs-sm);
}
.calendar__weekday,
.calendar-day {
padding: var(--sp-2);
}
.calendar-day__number {
font-size: var(--fs-sm);
}
/* Pre-existing bug this pass also fixes: `.calendar__layout` never
* stacked, so the fixed-width preset rail sat on top of Friday/Saturday/
* Sunday's columns instead of beside them once the month grid had no room
* left. The rail moves below the grid and goes full-width. */
.calendar__layout {
flex-direction: column;
}
.preset-rail {
width: 100%;
}
}
/* Tablet - Medium screens (641px to 1024px) */
@media (min-width: 641px) and (max-width: 1024px) {
.overview-metrics__list {
grid-template-columns: repeat(2, 1fr);
}
.form-grid {
grid-template-columns: repeat(2, 1fr);
}
[data-testid='layout-main'] {
padding: var(--sp-4);
}
}
/* Accessibility - Reduced Motion */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
.loading-spinner__icon {
animation: none;
}
.header__nav-link,
.header__logout-button,
.header__child-select,
input,
select,
textarea,
button {
transition: none;
}
}
/* High Contrast Mode */
@media (prefers-contrast: more) {
:root {
--c-text: #000;
--c-accent: #1f4d2b;
--c-border: #333;
}
button:focus-visible,
a:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
outline-width: 3px;
}
}
/* Color Scheme Preference - Dark Mode (future-proofing) */
@media (prefers-color-scheme: dark) {
/* Currently not implemented, but prepared */
}
/* Keyboard Navigation */
:focus-visible {
outline: 2px solid var(--c-accent);
outline-offset: 2px;
}
/* High Contrast Focus */
button:focus-visible,
a:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
outline: 2px solid var(--c-accent);
outline-offset: 2px;
}