Styling fix and scraper bug fix

This commit is contained in:
2026-06-14 18:39:55 +02:00
parent 6ed2a3ae0c
commit 566595984f
21 changed files with 2150 additions and 119 deletions
+391
View File
@@ -0,0 +1,391 @@
/* Overview Metrics */
.overview-metrics {
display: grid;
gap: var(--sp-4);
}
.overview-metrics__title {
margin: 0 0 var(--sp-4) 0;
}
.overview-metrics__list {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
gap: var(--sp-4);
}
.overview-metrics__item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: var(--sp-5);
background-color: var(--c-bg);
border-radius: var(--radius);
border: 1px solid var(--c-border);
}
.overview-metrics__value {
display: block;
font-size: var(--fs-2xl);
font-weight: 700;
color: var(--c-accent);
margin-bottom: var(--sp-2);
line-height: 1;
}
.overview-metrics__label {
font-size: var(--fs-sm);
color: var(--c-text-muted);
text-align: center;
}
/* Days Breakdown */
.days-breakdown {
width: 100%;
}
.days-breakdown__empty {
color: var(--c-text-muted);
font-size: var(--fs-sm);
text-align: center;
padding: var(--sp-5);
margin: 0;
}
.days-breakdown__table {
width: 100%;
border-collapse: collapse;
margin: 0;
}
.days-breakdown__table th {
padding: var(--sp-4);
background-color: var(--c-bg);
border-bottom: 2px solid var(--c-border);
font-weight: 600;
color: var(--c-text-muted);
text-align: left;
font-size: var(--fs-sm);
}
.days-breakdown__table td {
padding: var(--sp-3) var(--sp-4);
border-bottom: 1px solid var(--c-border);
font-size: var(--fs-base);
}
.days-breakdown__table tbody tr:hover {
background-color: rgba(47, 111, 79, 0.02);
}
.days-breakdown__table tbody tr:last-child td {
border-bottom: none;
}
.days-breakdown__table td:last-child {
text-align: right;
font-weight: 600;
color: var(--c-accent);
}
/* Parental Leave Breakdown */
.parental-leave-breakdown {
display: flex;
flex-direction: column;
gap: var(--sp-4);
}
.parental-leave-breakdown__empty {
color: var(--c-text-muted);
font-size: var(--fs-sm);
padding: var(--sp-4);
margin: 0;
}
.parental-leave-breakdown__section {
width: 100%;
overflow-x: auto;
}
.parental-leave-breakdown__table {
width: 100%;
border-collapse: collapse;
margin: 0;
}
.parental-leave-breakdown__table th {
padding: var(--sp-3) var(--sp-4);
background-color: var(--c-bg);
border-bottom: 2px solid var(--c-border);
font-weight: 600;
color: var(--c-text-muted);
text-align: left;
font-size: var(--fs-sm);
}
.parental-leave-breakdown__table td {
padding: var(--sp-3) var(--sp-4);
border-bottom: 1px solid var(--c-border);
font-size: var(--fs-sm);
}
.parental-leave-breakdown__table tbody tr:hover {
background-color: rgba(47, 111, 79, 0.02);
}
.parental-leave-breakdown__table tbody tr:last-child td {
border-bottom: none;
}
.parental-leave-breakdown__table td:nth-child(2),
.parental-leave-breakdown__table td:nth-child(3) {
text-align: right;
font-weight: 600;
}
.parental-leave-breakdown__provenance {
padding-top: var(--sp-3);
border-top: 1px solid var(--c-border);
font-size: var(--fs-sm);
color: var(--c-text-muted);
}
/* Progress Chart */
.progress-chart {
display: flex;
flex-direction: column;
gap: var(--sp-4);
}
.progress-chart__header {
display: flex;
justify-content: space-between;
align-items: baseline;
margin: 0 0 var(--sp-3) 0;
}
.progress-chart__header h3 {
margin: 0;
}
.progress-chart__age {
font-size: var(--fs-sm);
color: var(--c-text-muted);
}
.progress-chart__bar {
width: 100%;
height: 24px;
background-color: var(--c-bg);
border-radius: var(--radius);
overflow: hidden;
border: 1px solid var(--c-border);
}
.progress-chart__fill {
height: 100%;
background-color: var(--c-accent);
transition: width 0.3s ease;
}
.progress-chart__stats {
display: flex;
justify-content: space-between;
align-items: center;
font-size: var(--fs-sm);
color: var(--c-text-muted);
}
.progress-chart__percentage {
font-weight: 600;
color: var(--c-accent);
}
/* Button Styles */
button {
background-color: var(--c-accent);
color: var(--c-surface);
font-weight: 500;
}
button:hover:not(:disabled) {
background-color: #1f5a3b;
}
button:active:not(:disabled) {
background-color: #0f4a2f;
}
/* Secondary button */
.button--secondary,
button.secondary {
background-color: transparent;
color: var(--c-accent);
border: 1px solid var(--c-accent);
}
.button--secondary:hover:not(:disabled),
button.secondary:hover:not(:disabled) {
background-color: var(--c-accent-weak);
}
/* Ghost button */
.button--ghost,
button.ghost {
background-color: transparent;
color: var(--c-text);
border: 1px solid var(--c-border);
}
.button--ghost:hover:not(:disabled),
button.ghost:hover:not(:disabled) {
background-color: var(--c-bg);
border-color: var(--c-text);
}
/* Form styles */
.form-group {
margin-bottom: var(--sp-5);
}
.form-group label {
display: block;
margin-bottom: var(--sp-2);
font-weight: 500;
color: var(--c-text);
font-size: var(--fs-base);
}
.form-group input,
.form-group select,
.form-group textarea {
width: 100%;
max-width: 400px;
}
.form-group textarea {
resize: vertical;
min-height: 100px;
}
/* Input Grid */
.form-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: var(--sp-4);
}
.form-grid .form-group {
margin-bottom: 0;
}
.form-grid .form-group input,
.form-grid .form-group select {
max-width: none;
}
/* Settings Page Messages */
.settings-page__message {
padding: var(--sp-4);
border-radius: var(--radius);
margin-bottom: var(--sp-4);
font-weight: 500;
}
.settings-page__message--success {
background-color: var(--c-success-weak);
color: var(--c-success);
border-left: 4px solid var(--c-success);
}
.settings-page__message--error {
background-color: var(--c-danger-weak);
color: var(--c-danger);
border-left: 4px solid var(--c-danger);
}
/* Fieldsets */
fieldset {
border: 1px solid var(--c-border);
border-radius: var(--radius);
padding: var(--sp-4);
margin-bottom: var(--sp-5);
}
legend {
font-weight: 600;
color: var(--c-text);
padding: 0 var(--sp-2);
margin-left: calc(var(--sp-2) * -1);
}
/* Input Components */
.vacation-days-input,
.planning-goal-selector,
.break-periods-input,
.parent-profile-input,
.child-birthday-input {
margin-bottom: var(--sp-5);
}
.vacation-days-input__label,
.planning-goal-selector__label,
.break-periods-input__label,
.parent-profile-input__label,
.child-birthday-input__label {
display: block;
margin-bottom: var(--sp-2);
font-weight: 500;
color: var(--c-text);
font-size: var(--fs-base);
}
.vacation-days-input__field,
.planning-goal-selector__select,
.break-periods-input__field,
.parent-profile-input__field,
.child-birthday-input__field {
width: 100%;
max-width: 400px;
}
.vacation-days-input__range,
.break-periods-input__help,
.parent-profile-input__help,
.child-birthday-input__help {
font-size: var(--fs-sm);
color: var(--c-text-muted);
margin-top: var(--sp-2);
}
/* Responsive */
@media (max-width: 640px) {
[data-testid='metrics-list'] {
grid-template-columns: 1fr;
}
.form-group input,
.form-group select,
.form-group textarea,
.vacation-days-input__field,
.planning-goal-selector__select,
.break-periods-input__field,
.parent-profile-input__field,
.child-birthday-input__field {
max-width: none;
}
.form-grid {
grid-template-columns: 1fr;
}
.days-breakdown__table {
font-size: var(--fs-sm);
}
.days-breakdown__table th,
.days-breakdown__table td {
padding: var(--sp-2) var(--sp-3);
}
}
+343
View File
@@ -0,0 +1,343 @@
/* Component styles - must come first */
@import './components.css';
@import './modals.css';
@import './responsive.css';
/* Design Tokens */
:root {
/* Color - calm, trustworthy palette */
--c-bg: #f7f8fa;
--c-surface: #ffffff;
--c-border: #e3e6eb;
--c-text: #1c2733;
--c-text-muted: #5b6675;
--c-accent: #2f6f4f; /* calm green */
--c-accent-weak: #e8f1ec;
--c-danger: #b3261e;
--c-danger-weak: #fdeceb;
--c-success: #1e7d4f;
--c-success-weak: #e7f4ec;
--c-warning: #8a6d1f;
/* Spacing scale (8px base) */
--sp-1: 4px;
--sp-2: 8px;
--sp-3: 12px;
--sp-4: 16px;
--sp-5: 24px;
--sp-6: 32px;
--sp-8: 48px;
/* Type scale */
--fs-sm: 0.875rem;
--fs-base: 1rem;
--fs-lg: 1.25rem;
--fs-xl: 1.5rem;
--fs-2xl: 2rem;
--lh: 1.5;
/* Shape & depth */
--radius: 8px;
--shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.06);
--shadow-md: 0 4px 12px rgba(16, 24, 40, 0.08);
/* Content width */
--maxw: 960px;
color-scheme: light;
}
/* Reset & Base */
*,
*::before,
*::after {
box-sizing: border-box;
}
html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
hgroup,
main,
mark,
meter,
nav,
output,
progress,
section,
summary,
time,
video {
margin: 0;
padding: 0;
border: 0;
}
body {
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
background: var(--c-bg);
color: var(--c-text);
line-height: var(--lh);
font-size: var(--fs-base);
}
/* Headings */
h1 {
font-size: var(--fs-2xl);
font-weight: 700;
margin-bottom: var(--sp-4);
}
h2 {
font-size: var(--fs-xl);
font-weight: 700;
margin-bottom: var(--sp-3);
}
h3 {
font-size: var(--fs-lg);
font-weight: 600;
margin-bottom: var(--sp-3);
}
/* Text */
p {
margin-bottom: var(--sp-3);
}
small {
font-size: var(--fs-sm);
color: var(--c-text-muted);
}
/* Lists */
ul,
ol {
margin-left: var(--sp-5);
margin-bottom: var(--sp-3);
}
li {
margin-bottom: var(--sp-2);
}
/* Links */
a {
color: var(--c-accent);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a:focus-visible {
outline: 2px solid var(--c-accent);
outline-offset: 2px;
border-radius: 2px;
}
/* Buttons - base */
button {
font-family: inherit;
font-size: var(--fs-base);
cursor: pointer;
border: none;
border-radius: var(--radius);
padding: var(--sp-3) var(--sp-4);
transition: background-color 0.2s, color 0.2s, box-shadow 0.2s;
}
button:focus-visible {
outline: 2px solid var(--c-accent);
outline-offset: 2px;
}
button:disabled {
opacity: 0.6;
cursor: not-allowed;
}
/* Inputs & Selects */
input,
select,
textarea {
font-family: inherit;
font-size: var(--fs-base);
border: 1px solid var(--c-border);
border-radius: var(--radius);
padding: var(--sp-3) var(--sp-4);
background: var(--c-surface);
color: var(--c-text);
transition: border-color 0.2s, box-shadow 0.2s;
}
input:focus,
select:focus,
textarea:focus {
outline: none;
border-color: var(--c-accent);
box-shadow: 0 0 0 3px rgba(47, 111, 79, 0.1);
}
input:disabled,
select:disabled,
textarea:disabled {
background-color: #f0f0f0;
cursor: not-allowed;
}
/* Label */
label {
display: block;
margin-bottom: var(--sp-2);
font-weight: 500;
color: var(--c-text);
}
/* Tables */
table {
width: 100%;
border-collapse: collapse;
}
th {
text-align: left;
font-weight: 600;
padding: var(--sp-3) var(--sp-4);
background-color: var(--c-bg);
border-bottom: 1px solid var(--c-border);
color: var(--c-text-muted);
}
td {
padding: var(--sp-3) var(--sp-4);
border-bottom: 1px solid var(--c-border);
}
tr:hover td {
background-color: rgba(47, 111, 79, 0.02);
}
/* Section container */
main {
max-width: var(--maxw);
margin: 0 auto;
padding: var(--sp-5);
}
/* Utility classes for form */
.form-group {
margin-bottom: var(--sp-5);
}
.form-group label {
margin-bottom: var(--sp-2);
}
/* Message boxes */
.error-message {
padding: var(--sp-3) var(--sp-4);
background-color: var(--c-danger-weak);
color: var(--c-danger);
border-left: 4px solid var(--c-danger);
border-radius: var(--radius);
margin-bottom: var(--sp-4);
}
.success-message {
padding: var(--sp-3) var(--sp-4);
background-color: var(--c-success-weak);
color: var(--c-success);
border-left: 4px solid var(--c-success);
border-radius: var(--radius);
margin-bottom: var(--sp-4);
}
.warning-message {
padding: var(--sp-3) var(--sp-4);
background-color: #fef8e7;
color: var(--c-warning);
border-left: 4px solid var(--c-warning);
border-radius: var(--radius);
margin-bottom: var(--sp-4);
}
/* 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;
}
}
+206
View File
@@ -0,0 +1,206 @@
/* Modal Overlay */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(16, 24, 40, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
}
/* Modal Content */
.modal-content {
background-color: var(--c-surface);
border-radius: var(--radius);
box-shadow: var(--shadow-md);
max-width: 500px;
width: 90%;
max-height: 90vh;
overflow-y: auto;
padding: var(--sp-6);
}
.modal-content h2 {
margin-top: 0;
}
.modal-content h3 {
margin-top: var(--sp-5);
}
/* Modal Header */
.modal__header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: var(--sp-5);
}
.modal__title {
font-size: var(--fs-xl);
font-weight: 700;
margin: 0;
}
.modal__close {
background: none;
border: none;
font-size: var(--fs-lg);
cursor: pointer;
padding: 0;
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
border-radius: var(--radius);
transition: background-color 0.2s;
}
.modal__close:hover {
background-color: var(--c-bg);
}
.modal__close:focus-visible {
outline: 2px solid var(--c-accent);
outline-offset: 2px;
}
/* Modal Body */
.modal__body {
margin-bottom: var(--sp-5);
}
/* Modal Footer */
.modal__footer {
display: flex;
gap: var(--sp-3);
justify-content: flex-end;
padding-top: var(--sp-4);
border-top: 1px solid var(--c-border);
}
.modal__footer button {
min-width: 100px;
}
/* QRCode Modal */
.qrcode-modal__content {
text-align: center;
}
.qrcode-modal__qr {
margin: var(--sp-5) 0;
display: flex;
justify-content: center;
}
.qrcode-modal__qr img {
max-width: 300px;
width: 100%;
height: auto;
border: 1px solid var(--c-border);
border-radius: var(--radius);
background-color: var(--c-bg);
padding: var(--sp-2);
}
.qrcode-modal__status {
padding: var(--sp-4);
background-color: var(--c-bg);
border-radius: var(--radius);
margin-bottom: var(--sp-4);
font-size: var(--fs-sm);
}
.qrcode-modal__status--pending {
background-color: #fef8e7;
color: var(--c-warning);
}
.qrcode-modal__status--success {
background-color: var(--c-success-weak);
color: var(--c-success);
}
.qrcode-modal__status--error {
background-color: var(--c-danger-weak);
color: var(--c-danger);
}
.qrcode-modal__error {
padding: var(--sp-3) var(--sp-4);
background-color: var(--c-danger-weak);
color: var(--c-danger);
border-left: 4px solid var(--c-danger);
border-radius: var(--radius);
margin-bottom: var(--sp-4);
font-size: var(--fs-sm);
}
/* Loading Spinner */
[data-testid='loading-spinner'] {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: var(--sp-8);
gap: var(--sp-4);
}
[data-testid='spinner-icon'] {
font-size: 48px;
color: var(--c-accent);
animation: spin 2s linear infinite;
}
[data-testid='spinner-message'] {
font-size: var(--fs-base);
color: var(--c-text-muted);
margin: 0;
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
/* Reduce Motion */
@media (prefers-reduced-motion: reduce) {
[data-testid='spinner-icon'] {
animation: none;
}
.modal-content {
animation: none;
}
}
/* Responsive */
@media (max-width: 640px) {
.modal-content {
width: 95%;
padding: var(--sp-4);
max-height: 95vh;
}
.qrcode-modal__qr img {
max-width: 250px;
}
.modal__footer {
flex-direction: column-reverse;
}
.modal__footer button {
width: 100%;
}
}
+240
View File
@@ -0,0 +1,240 @@
/* 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 {
font-size: var(--fs-sm);
}
.days-breakdown__table th,
.days-breakdown__table td,
.parental-leave-breakdown__table th,
.parental-leave-breakdown__table td {
padding: var(--sp-2) var(--sp-3);
}
/* 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;
}
/* Progress chart */
.progress-chart__stats {
flex-direction: column;
gap: var(--sp-2);
}
/* 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);
}
}
/* 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;
}
.progress-chart__fill {
transition: 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;
}