From 1b792b14f6fc47c7afd1379a7a767a4da6230b53 Mon Sep 17 00:00:00 2001 From: FlorianEisenmenger Date: Wed, 17 Jun 2026 15:12:51 +0200 Subject: [PATCH] mobile optimization --- httpdocs/assets/styles/atoms/_mixins.scss | 8 +++ httpdocs/assets/styles/atoms/_variables.scss | 4 ++ .../assets/styles/components/_account.scss | 38 +++++++++++ httpdocs/assets/styles/components/_crud.scss | 9 +++ .../assets/styles/components/_entry-form.scss | 27 ++++++++ .../assets/styles/components/_entry-list.scss | 14 +++++ .../assets/styles/components/_greeting.scss | 3 + httpdocs/assets/styles/components/_login.scss | 18 ++++++ .../assets/styles/components/_main-nav.scss | 3 + .../styles/components/_month-calendar.scss | 5 ++ .../assets/styles/components/_register.scss | 4 ++ .../assets/styles/components/_stopwatch.scss | 6 ++ httpdocs/assets/styles/components/_team.scss | 7 +++ .../assets/styles/components/_week-nav.scss | 11 ++++ httpdocs/assets/styles/sections/_home.scss | 6 ++ httpdocs/assets/styles/sections/_report.scss | 63 +++++++++++++++++++ .../assets/styles/sections/_timetracking.scss | 11 ++++ httpdocs/assets/styles/themes/_minimal.scss | 18 +++++- httpdocs/templates/base.html.twig | 1 + 19 files changed, 255 insertions(+), 1 deletion(-) diff --git a/httpdocs/assets/styles/atoms/_mixins.scss b/httpdocs/assets/styles/atoms/_mixins.scss index 02e28f1..bd57704 100644 --- a/httpdocs/assets/styles/atoms/_mixins.scss +++ b/httpdocs/assets/styles/atoms/_mixins.scss @@ -51,3 +51,11 @@ white-space: nowrap; } +@mixin tablet { + @media (max-width: $bp-tablet) { @content; } +} + +@mixin mobile { + @media (max-width: $bp-mobile) { @content; } +} + diff --git a/httpdocs/assets/styles/atoms/_variables.scss b/httpdocs/assets/styles/atoms/_variables.scss index 084a009..b1a4874 100644 --- a/httpdocs/assets/styles/atoms/_variables.scss +++ b/httpdocs/assets/styles/atoms/_variables.scss @@ -95,6 +95,10 @@ $transition-fast: 0.15s ease; $transition-base: 0.2s ease; $transition-slow: 0.3s ease; +// ─── Breakpoints ───────────────────────────────────────────────────────────── +$bp-tablet: 980px; +$bp-mobile: 600px; + // ─── Layout ────────────────────────────────────────────────────────────────── $header-height: 88px; $content-max-width: 860px; diff --git a/httpdocs/assets/styles/components/_account.scss b/httpdocs/assets/styles/components/_account.scss index 6429eb9..1d485ad 100644 --- a/httpdocs/assets/styles/components/_account.scss +++ b/httpdocs/assets/styles/components/_account.scss @@ -10,6 +10,12 @@ .account-header { @include section-header; padding: $space-6; + + @include tablet { + flex-direction: column; + align-items: stretch; + gap: $space-3; + } } .account-header__title { @@ -27,12 +33,21 @@ gap: $space-1; backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); + + @include tablet { + width: 100%; + } } .account-tab { display: inline-flex; align-items: center; padding: $space-2 $space-5; + + @include tablet { + flex: 1; + justify-content: center; + } font-size: $font-size-sm; font-weight: $font-weight-medium; color: var(--header-text-muted); @@ -63,12 +78,18 @@ display: flex; flex-direction: column; gap: $space-6; + + @include tablet { + padding: 0 $space-4; + } } // ─── Karte ─────────────────────────────────────────────────────────────────── .account-card { @include card; padding: $space-8; + + @include tablet { padding: $space-6 $space-5; } } // ─── Formular-Grid ─────────────────────────────────────────────────────────── @@ -77,12 +98,23 @@ grid-template-columns: 160px 1fr; gap: $space-4 $space-6; align-items: start; + + @include tablet { + grid-template-columns: 1fr; + gap: $space-3; + } } .account-form__label { @include form-label; font-weight: $font-weight-medium; padding-top: 7px; + + @include tablet { + text-align: left; + padding-right: 0; + padding-top: 0; + } } .account-form__field { @@ -148,6 +180,12 @@ margin-top: $space-2; padding-top: $space-4; border-top: 1px solid $color-border; + + @include tablet { + flex-direction: column; + + .btn { width: 100%; } + } } // ─── Toast ─────────────────────────────────────────────────────────────────── diff --git a/httpdocs/assets/styles/components/_crud.scss b/httpdocs/assets/styles/components/_crud.scss index 881de00..29967e8 100644 --- a/httpdocs/assets/styles/components/_crud.scss +++ b/httpdocs/assets/styles/components/_crud.scss @@ -6,6 +6,8 @@ max-width: $content-max-width; margin: 0 auto; padding: $space-6; + + @include tablet { padding: $space-4; } } .crud-page__header { @@ -52,6 +54,8 @@ padding: $space-4 $space-6; transition: background $transition-fast; + @include tablet { padding: $space-4; } + &:hover { background: rgba(var(--color-primary-rgb), 0.05); @@ -95,6 +99,7 @@ &--delete:hover{ background: rgba($color-error, 0.1); color: $color-error; } @media (hover: none) { opacity: 1; } + @include tablet { opacity: 1; } } // ─── Edit-Formular innerhalb der Zeile ───────────────────────────────────────── @@ -102,6 +107,8 @@ padding: $space-4 $space-6; background: rgba(var(--color-primary-rgb), 0.04); border-top: 1px solid rgba($color-border, 0.5); + + @include tablet { padding: $space-4; } } // ─── Create-Formular oben ────────────────────────────────────────────────────── @@ -112,6 +119,8 @@ display: none; &--visible { display: block; } + + @include tablet { padding: $space-4; } } // ─── Tabs (Aktiv / Archiviert) ───────────────────────────────────────────────── diff --git a/httpdocs/assets/styles/components/_entry-form.scss b/httpdocs/assets/styles/components/_entry-form.scss index 9d60626..daf4000 100644 --- a/httpdocs/assets/styles/components/_entry-form.scss +++ b/httpdocs/assets/styles/components/_entry-form.scss @@ -5,6 +5,8 @@ .entry-form { @include card($color-card); padding: $space-6 $space-8; + + @include tablet { padding: $space-5 $space-4; } } .entry-form__grid { @@ -12,6 +14,11 @@ grid-template-columns: 120px 1fr; gap: $space-4 $space-6; align-items: center; + + @include tablet { + grid-template-columns: 1fr; + gap: $space-3; + } } .entry-form__label { @@ -21,6 +28,11 @@ text-align: right; padding-right: $space-2; white-space: nowrap; + + @include tablet { + text-align: left; + padding-right: 0; + } } .entry-form__field { @@ -51,6 +63,15 @@ flex: 1; min-width: 180px; } + + @include tablet { + flex-direction: column; + + .select { + min-width: 0; + width: 100%; + } + } } .entry-form__actions { @@ -59,6 +80,12 @@ align-items: center; gap: $space-4; padding-top: $space-2; + + @include tablet { + grid-column: 1; + + .btn { width: 100%; } + } } // ─── Rate Mode (Radio: Default / Custom) ──────────────────────────────────── diff --git a/httpdocs/assets/styles/components/_entry-list.scss b/httpdocs/assets/styles/components/_entry-list.scss index 3a332ee..2ca5a4b 100644 --- a/httpdocs/assets/styles/components/_entry-list.scss +++ b/httpdocs/assets/styles/components/_entry-list.scss @@ -29,6 +29,8 @@ justify-content: flex-end; padding: $space-3 calc(#{$space-8} + #{$icon-btn-size} + #{$icon-btn-size} + #{$space-2} + #{$space-2}); border-top: 1px solid $color-border; + + @include tablet { padding: $space-3 $space-4; } } .entry-list__total { @@ -75,6 +77,10 @@ .entry-row__btn { opacity: 1; } } + + @include tablet { + padding: $space-4; + } } .entry-row__info { @@ -126,6 +132,7 @@ &--delete:hover{ background: rgba($color-error, 0.1); color: $color-error; } @media (hover: none) { opacity: 1; } + @include tablet { opacity: 1; } } // ─── Lock-Indikator (invoiced) ──────────────────────────────────────────── @@ -152,6 +159,8 @@ padding: $space-4 $space-8; background: rgba(var(--color-primary-rgb), 0.04); border-top: 1px solid rgba($color-border, 0.5); + + @include tablet { padding: $space-4; } } .entry-form__grid--inline { @@ -159,4 +168,9 @@ grid-template-columns: 130px 1fr; gap: $space-3 $space-6; align-items: center; + + @include tablet { + grid-template-columns: 1fr; + gap: $space-3; + } } diff --git a/httpdocs/assets/styles/components/_greeting.scss b/httpdocs/assets/styles/components/_greeting.scss index 5d7b49e..3054c8a 100644 --- a/httpdocs/assets/styles/components/_greeting.scss +++ b/httpdocs/assets/styles/components/_greeting.scss @@ -1,4 +1,5 @@ @use '../atoms/variables' as *; +@use '../atoms/mixins' as *; // ─── Begrüßung zwischen Header und Formular ─────────────────────────────────── .greeting { @@ -7,6 +8,8 @@ margin: 0 auto; padding: $space-5 $space-6 0; + @include tablet { padding: $space-4 $space-4 0; } + &__text { font-size: $font-size-lg; font-weight: $font-weight-bold; diff --git a/httpdocs/assets/styles/components/_login.scss b/httpdocs/assets/styles/components/_login.scss index deaa333..abbbef8 100644 --- a/httpdocs/assets/styles/components/_login.scss +++ b/httpdocs/assets/styles/components/_login.scss @@ -16,6 +16,12 @@ padding: $space-10 $space-12; width: 100%; max-width: 540px; + + @include tablet { + padding: $space-8 $space-5; + margin: $space-4; + max-width: calc(100% - #{$space-8}); + } } .login-card__title { @@ -43,11 +49,21 @@ gap: $space-5 $space-4; align-items: center; margin-bottom: $space-5; + + @include mobile { + grid-template-columns: 1fr; + gap: $space-3; + } } .login-form__label { @include form-label; font-size: $font-size-base; + + @include mobile { + text-align: left; + padding-right: 0; + } } .login-form__field { @@ -138,4 +154,6 @@ .login-form__submit { padding: $space-3 $space-10; font-size: $font-size-md; + + @include tablet { width: 100%; } } diff --git a/httpdocs/assets/styles/components/_main-nav.scss b/httpdocs/assets/styles/components/_main-nav.scss index b6b343a..616c472 100644 --- a/httpdocs/assets/styles/components/_main-nav.scss +++ b/httpdocs/assets/styles/components/_main-nav.scss @@ -1,4 +1,5 @@ @use '../atoms/variables' as *; +@use '../atoms/mixins' as *; // ─── Dunkle Top-Navigation ──────────────────────────────────────────────────── .main-nav { @@ -12,6 +13,8 @@ position: sticky; top: 0; z-index: 200; + + @include tablet { display: none; } } .main-nav__left, diff --git a/httpdocs/assets/styles/components/_month-calendar.scss b/httpdocs/assets/styles/components/_month-calendar.scss index a743bcf..5004232 100644 --- a/httpdocs/assets/styles/components/_month-calendar.scss +++ b/httpdocs/assets/styles/components/_month-calendar.scss @@ -17,6 +17,11 @@ opacity 0.28s ease, transform 0.28s ease; + @include mobile { + width: calc(100vw - #{$space-8}); + right: -#{$space-4}; + } + &--hidden { opacity: 0; transform: scaleY(0.92) translateY(-8px); diff --git a/httpdocs/assets/styles/components/_register.scss b/httpdocs/assets/styles/components/_register.scss index f11cda9..9ad4093 100644 --- a/httpdocs/assets/styles/components/_register.scss +++ b/httpdocs/assets/styles/components/_register.scss @@ -19,6 +19,8 @@ .register-card { @include card($color-card-white, $radius-xl); padding: $space-10 $space-12; + + @include tablet { padding: $space-8 $space-5; } } .register-card__brand { @@ -114,6 +116,8 @@ grid-template-columns: 1fr 1fr; gap: $space-4; margin-bottom: $space-5; + + @include mobile { grid-template-columns: 1fr; } } // ─── Actions ────────────────────────────────────────────────────────────────── diff --git a/httpdocs/assets/styles/components/_stopwatch.scss b/httpdocs/assets/styles/components/_stopwatch.scss index 26a8535..e860be4 100644 --- a/httpdocs/assets/styles/components/_stopwatch.scss +++ b/httpdocs/assets/styles/components/_stopwatch.scss @@ -88,6 +88,12 @@ gap: $space-3; box-shadow: $shadow-calendar; + @include mobile { + width: calc(100vw - #{$space-8}); + left: 0; + transform: none; + } + &::before { content: ''; position: absolute; diff --git a/httpdocs/assets/styles/components/_team.scss b/httpdocs/assets/styles/components/_team.scss index b39d90e..aa41053 100644 --- a/httpdocs/assets/styles/components/_team.scss +++ b/httpdocs/assets/styles/components/_team.scss @@ -33,6 +33,11 @@ max-width: 460px; padding: 0; overflow: hidden; + + @include tablet { + margin: $space-4; + max-width: calc(100% - #{$space-8}); + } } .modal-card__header { @@ -78,6 +83,8 @@ display: grid; grid-template-columns: 1fr 1fr; gap: $space-4; + + @include mobile { grid-template-columns: 1fr; } } .form-field { diff --git a/httpdocs/assets/styles/components/_week-nav.scss b/httpdocs/assets/styles/components/_week-nav.scss index c02307b..9295700 100644 --- a/httpdocs/assets/styles/components/_week-nav.scss +++ b/httpdocs/assets/styles/components/_week-nav.scss @@ -11,6 +11,11 @@ padding: $space-1 $space-2; backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); + + @include tablet { + width: 100%; + justify-content: center; + } } // ─── Pfeile ────────────────────────────────────────────────────────────────── @@ -58,6 +63,12 @@ transition: background $transition-fast; user-select: none; + @include tablet { + width: auto; + flex: 1; + min-width: 0; + } + &:hover:not(.week-nav__day--active) { background: var(--header-overlay); } diff --git a/httpdocs/assets/styles/sections/_home.scss b/httpdocs/assets/styles/sections/_home.scss index 413449b..72a6b8a 100644 --- a/httpdocs/assets/styles/sections/_home.scss +++ b/httpdocs/assets/styles/sections/_home.scss @@ -37,6 +37,8 @@ align-items: center; justify-content: center; padding: $space-12 $space-8; + + @include tablet { padding: $space-8 $space-4; } } .home-hero__inner { @@ -50,6 +52,8 @@ color: $color-text-dark; line-height: 1.2; margin-bottom: $space-6; + + @include mobile { font-size: 2rem; } } .home-hero__sub { @@ -62,4 +66,6 @@ .home-hero__cta { font-size: $font-size-md; padding: $space-4 $space-10; + + @include tablet { width: 100%; } } diff --git a/httpdocs/assets/styles/sections/_report.scss b/httpdocs/assets/styles/sections/_report.scss index d5e83a2..a7d6bd6 100644 --- a/httpdocs/assets/styles/sections/_report.scss +++ b/httpdocs/assets/styles/sections/_report.scss @@ -10,6 +10,12 @@ .report-header { @include section-header; padding: $space-4 $space-6; + + @include tablet { + flex-direction: column; + align-items: stretch; + gap: $space-3; + } } .report-header__title { @@ -22,6 +28,10 @@ display: flex; align-items: center; gap: $space-4; + + @include tablet { + flex-wrap: wrap; + } } // ─── Account-Name Anzeige ──────────────────────────────────────────────────── @@ -61,12 +71,18 @@ width: 100%; margin: $space-6 auto; padding: 0 $space-6; + + @include tablet { + padding: 0 $space-4; + } } // ─── Karte ─────────────────────────────────────────────────────────────────── .report-card { @include card; overflow: hidden; + + @include tablet { overflow-x: auto; } } // ─── Toolbar ───────────────────────────────────────────────────────────────── @@ -76,6 +92,11 @@ justify-content: space-between; padding: $space-3 $space-5; border-bottom: 1px solid $color-border; + + @include tablet { + flex-wrap: wrap; + gap: $space-3; + } } .report-toolbar__left { @@ -135,6 +156,8 @@ // ─── Tabelle ───────────────────────────────────────────────────────────────── .report-table { width: 100%; + + @include tablet { min-width: 900px; } } .report-table__head, @@ -254,6 +277,8 @@ svg { width: $icon-svg-size; height: $icon-svg-size; } + @include tablet { opacity: 1; } + &:hover { color: $color-text-muted; background: rgba($color-text-dark, 0.06); @@ -301,10 +326,20 @@ gap: $space-3 $space-5; align-items: center; max-width: 680px; + + @include tablet { + grid-template-columns: 1fr; + gap: $space-3; + } } .report-row__edit-label { @include form-label; + + @include tablet { + text-align: left; + padding-right: 0; + } } .report-row__edit-field { @@ -319,6 +354,15 @@ flex: 1; min-width: 160px; } + + @include tablet { + flex-direction: column; + + .select { + min-width: 0; + width: 100%; + } + } } .textarea { @@ -331,6 +375,12 @@ display: flex; gap: $space-3; padding-top: $space-2; + + @include tablet { + grid-column: 1; + + .btn { flex: 1; } + } } // ─── Pagination-Footer ──────────────────────────────────────────────────────── @@ -409,12 +459,19 @@ button.report-toolbar__action { .report-filter__body { display: flex; gap: $space-10; + + @include tablet { + flex-direction: column; + gap: $space-6; + } } .report-filter__col { flex: 1; min-width: 0; max-width: 66%; + + @include tablet { max-width: 100%; } } .report-filter__heading { @@ -437,6 +494,10 @@ button.report-toolbar__action { &:last-child { border-bottom: none; } + @include mobile { + grid-template-columns: 1fr; + } + &--inactive { .filter-select, .filter-note-input, @@ -505,6 +566,8 @@ button.report-toolbar__action { .filter-note-input { width: 300px; max-width: 100%; + + @include tablet { width: 100%; } } &--period { diff --git a/httpdocs/assets/styles/sections/_timetracking.scss b/httpdocs/assets/styles/sections/_timetracking.scss index e6e99a8..f3c8d9e 100644 --- a/httpdocs/assets/styles/sections/_timetracking.scss +++ b/httpdocs/assets/styles/sections/_timetracking.scss @@ -14,6 +14,13 @@ position: sticky; top: 0; z-index: 100; + + @include tablet { + flex-direction: column; + align-items: stretch; + gap: $space-3; + min-height: auto; + } } .tt-header__meta { @@ -44,4 +51,8 @@ display: flex; flex-direction: column; gap: $space-4; + + @include tablet { + padding: $space-4; + } } diff --git a/httpdocs/assets/styles/themes/_minimal.scss b/httpdocs/assets/styles/themes/_minimal.scss index 26cf182..d79e601 100644 --- a/httpdocs/assets/styles/themes/_minimal.scss +++ b/httpdocs/assets/styles/themes/_minimal.scss @@ -173,8 +173,15 @@ body[data-theme="minimal"] { // ─── Hamburger-Nav (immer im DOM, per CSS im Standard versteckt) ────────────── .hamburger-nav { - display: none; // Standard: versteckt + display: none; position: relative; + + @include tablet { + display: flex; + align-items: center; + justify-content: space-between; + padding: $space-3 $space-4; + } } .hamburger-nav__toggle { @@ -369,6 +376,10 @@ body[data-theme="minimal"] { display: flex; gap: $space-3; flex-wrap: wrap; + + @include tablet { + flex-direction: column; + } } .theme-option { @@ -383,6 +394,11 @@ body[data-theme="minimal"] { transition: border-color $transition-fast, background $transition-fast; user-select: none; + @include tablet { + min-width: 0; + width: 100%; + } + input[type="radio"] { display: none; } &:hover { border-color: var(--color-primary-light); background: rgba($color-primary, 0.02); } diff --git a/httpdocs/templates/base.html.twig b/httpdocs/templates/base.html.twig index cfe63f4..b355746 100644 --- a/httpdocs/templates/base.html.twig +++ b/httpdocs/templates/base.html.twig @@ -2,6 +2,7 @@ + {% block title %}Welcome!{% endblock %} {% block stylesheets %}