feat(manacore/web): complete mobile responsiveness for all modules and shared components

ListViews (25 remaining modules):
- All module ListViews now have responsive container padding (p-3 sm:p-4)
- All interactive items have min-h-[44px] touch targets on mobile
- Picture/Moodlit grids: grid-cols-2 on mobile, grid-cols-3 on desktop

DetailViews (17 modules):
- All DetailViews have reduced padding on mobile (0.75rem vs 1rem)
- All buttons, inputs, selects have min-height: 44px on mobile

Modals (14 components):
- Shared Modal.svelte: bottom-sheet pattern on mobile (slides up from bottom)
- 13 app-specific modals: same bottom-sheet treatment
- Reduced padding, larger close buttons, max-h-[95vh] on mobile

Shared UI components:
- GlobalSpotlight: bottom-sheet on mobile, prevents iOS zoom, hides keyboard hints
- PillDropdown: full-width bottom-sheet on mobile with backdrop
- AppDrawer: 44px touch targets on buttons and search
- TagStrip: 44px min-height on all pill buttons
- ToastContainer: larger touch targets, safe-area positioning

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-04-05 18:24:07 +02:00
parent a5f5c8b63f
commit 92d8275704
61 changed files with 499 additions and 81 deletions

View file

@ -39,10 +39,14 @@
{#if show}
<!-- svelte-ignore a11y_click_events_have_key_events a11y_no_static_element_interactions -->
<div
class="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4"
class="fixed inset-0 bg-black/50 flex items-end sm:items-center justify-center z-50 p-0 sm:p-4"
onclick={handleBackdropClick}
>
<div class="bg-card rounded-xl shadow-xl max-w-md w-full" role="dialog" aria-modal="true">
<div
class="bg-card rounded-t-xl sm:rounded-xl shadow-xl max-w-md w-full max-h-[95vh] sm:max-h-[90vh]"
role="dialog"
aria-modal="true"
>
{#if deleteResult}
<!-- Success State -->
<div class="p-6">

View file

@ -108,11 +108,11 @@
{#if show}
<!-- svelte-ignore a11y_click_events_have_key_events a11y_no_static_element_interactions -->
<div
class="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4"
class="fixed inset-0 bg-black/50 flex items-end sm:items-center justify-center z-50 p-0 sm:p-4"
onclick={handleBackdropClick}
>
<div
class="bg-card rounded-xl shadow-xl max-w-md w-full max-h-[90vh] overflow-y-auto"
class="bg-card rounded-t-xl sm:rounded-xl shadow-xl max-w-md w-full max-h-[95vh] sm:max-h-[90vh] overflow-y-auto"
role="dialog"
aria-modal="true"
>

View file

@ -78,10 +78,14 @@
{#if show}
<!-- svelte-ignore a11y_click_events_have_key_events a11y_no_static_element_interactions -->
<div
class="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4"
class="fixed inset-0 bg-black/50 flex items-end sm:items-center justify-center z-50 p-0 sm:p-4"
onclick={handleBackdropClick}
>
<div class="bg-card rounded-xl shadow-xl max-w-md w-full" role="dialog" aria-modal="true">
<div
class="bg-card rounded-t-xl sm:rounded-xl shadow-xl max-w-md w-full max-h-[95vh] sm:max-h-[90vh]"
role="dialog"
aria-modal="true"
>
<div class="p-6">
<div class="flex items-center gap-3 mb-6">
<div

View file

@ -71,10 +71,14 @@
{#if show}
<!-- svelte-ignore a11y_click_events_have_key_events a11y_no_static_element_interactions -->
<div
class="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4"
class="fixed inset-0 bg-black/50 flex items-end sm:items-center justify-center z-50 p-0 sm:p-4"
onclick={handleBackdropClick}
>
<div class="bg-card rounded-xl shadow-xl max-w-md w-full" role="dialog" aria-modal="true">
<div
class="bg-card rounded-t-xl sm:rounded-xl shadow-xl max-w-md w-full max-h-[95vh] sm:max-h-[90vh]"
role="dialog"
aria-modal="true"
>
<div class="p-6">
<div class="flex items-center gap-3 mb-4">
<div

View file

@ -141,10 +141,14 @@
{#if show}
<!-- svelte-ignore a11y_click_events_have_key_events a11y_no_static_element_interactions -->
<div
class="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4"
class="fixed inset-0 bg-black/50 flex items-end sm:items-center justify-center z-50 p-0 sm:p-4"
onclick={handleBackdropClick}
>
<div class="bg-card rounded-xl shadow-xl max-w-md w-full" role="dialog" aria-modal="true">
<div
class="bg-card rounded-t-xl sm:rounded-xl shadow-xl max-w-md w-full max-h-[95vh] sm:max-h-[90vh]"
role="dialog"
aria-modal="true"
>
<div class="p-6">
<div class="flex items-center gap-3 mb-6">
<div class="h-10 w-10 rounded-full bg-primary/10 flex items-center justify-center">

View file

@ -701,4 +701,14 @@
color: var(--color-muted-foreground);
margin: 0 0 0.5rem;
}
@media (max-width: 640px) {
.automations-view {
padding: 0.5rem;
}
.auto-card {
padding: 0.75rem;
min-height: 44px;
}
}
</style>

View file

@ -49,7 +49,7 @@
}
</script>
<div class="flex h-full flex-col gap-4 p-4">
<div class="flex h-full flex-col gap-4 p-3 sm:p-4">
<!-- Display -->
<div class="rounded-md bg-white/5 p-3 text-right">
<p class="text-xs text-white/40">{expression || ' '}</p>

View file

@ -484,4 +484,18 @@
background: rgba(255, 255, 255, 0.06);
color: #e5e7eb;
}
@media (max-width: 640px) {
.detail-view {
padding: 0.75rem;
}
.action-btn,
.tag-pill {
min-height: 44px;
}
.prop-input,
.allday-label {
min-height: 44px;
}
}
</style>

View file

@ -47,7 +47,7 @@
}
</script>
<div class="flex h-full flex-col gap-3 p-4">
<div class="flex h-full flex-col gap-3 p-3 sm:p-4">
<div class="flex items-center justify-between">
<p class="text-xs text-white/40">{decks.length} Decks</p>
<p class="text-xs text-amber-400/70">{dueForReview()} fällig</p>
@ -62,7 +62,7 @@
_siblingIds: decks.map((d) => d.id),
_siblingKey: 'deckId',
})}
class="mb-2 w-full rounded-md border border-white/10 px-3 py-2.5 text-left transition-colors hover:bg-white/5"
class="mb-2 w-full rounded-md border border-white/10 px-3 py-2.5 text-left transition-colors hover:bg-white/5 min-h-[44px]"
>
<div class="flex items-center gap-2">
<div class="h-3 w-3 rounded" style="background: {deck.color}"></div>

View file

@ -51,11 +51,11 @@
<!-- svelte-ignore a11y_click_events_have_key_events -->
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div
class="fixed inset-0 z-50 flex items-center justify-center bg-black/50"
class="fixed inset-0 z-50 flex items-end sm:items-center justify-center bg-black/50"
onclick={handleClose}
>
<div
class="mx-4 w-full max-w-md rounded-xl border border-border bg-card p-6 shadow-xl"
class="w-full max-w-md rounded-t-xl sm:rounded-xl border border-border bg-card p-6 shadow-xl max-h-[95vh] sm:max-h-[90vh] sm:mx-4"
onclick={(e) => e.stopPropagation()}
>
<h2 class="mb-4 text-xl font-semibold text-foreground">Neues Deck erstellen</h2>

View file

@ -378,4 +378,15 @@
background: rgba(255, 255, 255, 0.06);
color: #e5e7eb;
}
@media (max-width: 640px) {
.detail-view {
padding: 0.75rem;
}
.action-btn,
.toggle-btn,
.color-input {
min-height: 44px;
}
}
</style>

View file

@ -55,7 +55,7 @@
};
</script>
<div class="flex h-full flex-col gap-3 p-4">
<div class="flex h-full flex-col gap-3 p-3 sm:p-4">
<div class="flex gap-3 text-xs text-white/40">
<span>{locations.length} Orte</span>
<span>{favorites.length} Favoriten</span>
@ -70,7 +70,7 @@
_siblingIds: locations.map((l) => l.id),
_siblingKey: 'locationId',
})}
class="flex w-full items-start gap-2 rounded-md px-2 py-2 transition-colors hover:bg-white/5 cursor-pointer text-left"
class="flex w-full min-h-[44px] items-start gap-2 rounded-md px-2 py-2 transition-colors hover:bg-white/5 cursor-pointer text-left"
>
<div
class="mt-0.5 h-2.5 w-2.5 shrink-0 rounded-full"

View file

@ -409,4 +409,18 @@
background: rgba(255, 255, 255, 0.06);
color: #e5e7eb;
}
@media (max-width: 640px) {
.detail-view {
padding: 0.75rem;
}
.fav-btn,
.action-btn {
min-height: 44px;
}
.prop-select,
.prop-input {
min-height: 44px;
}
}
</style>

View file

@ -629,4 +629,19 @@
background: rgba(255, 255, 255, 0.06);
color: #e5e7eb;
}
@media (max-width: 640px) {
.detail-view {
padding: 0.75rem;
}
.fav-btn,
.action-btn,
.tag-pill {
min-height: 44px;
}
.field-input,
.name-input {
min-height: 44px;
}
}
</style>

View file

@ -45,7 +45,7 @@
};
</script>
<div class="flex h-full flex-col gap-3 p-4">
<div class="flex h-full flex-col gap-3 p-3 sm:p-4">
<div class="flex gap-3 text-xs text-white/40">
<span>{spaces.length} Spaces</span>
<span>{documents.length} Dokumente</span>
@ -56,7 +56,7 @@
{#if spaces.filter((s) => s.pinned).length > 0}
<h3 class="mb-2 text-xs font-medium text-white/50">Angepinnte Spaces</h3>
{#each spaces.filter((s) => s.pinned) as space (space.id)}
<div class="mb-1 rounded-md px-3 py-2 transition-colors hover:bg-white/5">
<div class="mb-1 min-h-[44px] rounded-md px-3 py-2 transition-colors hover:bg-white/5">
<p class="text-sm font-medium text-white/80">{space.name}</p>
{#if space.description}
<p class="truncate text-xs text-white/30">{space.description}</p>
@ -69,7 +69,7 @@
<h3 class="mb-2 mt-3 text-xs font-medium text-white/50">Zuletzt bearbeitet</h3>
{#each recentDocs as doc (doc.id)}
<div
class="flex items-center gap-2 rounded-md px-2 py-1.5 transition-colors hover:bg-white/5"
class="flex min-h-[44px] items-center gap-2 rounded-md px-2 py-1.5 transition-colors hover:bg-white/5"
>
<span class="text-sm">{@html typeIcons[doc.type] ?? '&#128196;'}</span>
<div class="min-w-0 flex-1">

View file

@ -470,4 +470,14 @@
font-size: 0.8125rem;
color: #9ca3af;
}
@media (max-width: 640px) {
.app-view {
padding: 0.75rem;
}
.tx-item {
padding: 0.625rem 0.375rem;
min-height: 44px;
}
}
</style>

View file

@ -558,4 +558,14 @@
box-shadow: 0 0 0 12px rgba(139, 92, 246, 0);
}
}
@media (max-width: 640px) {
.habits-list-view {
padding: 0.5rem;
}
.tally-item {
padding: 0.625rem 0.375rem;
min-height: 44px;
}
}
</style>

View file

@ -47,7 +47,7 @@
});
</script>
<div class="flex h-full flex-col gap-3 p-4">
<div class="flex h-full flex-col gap-3 p-3 sm:p-4">
<div class="flex gap-3 text-xs text-white/40">
<span>{items.length} Gegenstände</span>
{#if totalValue() > 0}
@ -64,7 +64,7 @@
_siblingIds: collections.map((c) => c.id),
_siblingKey: 'collectionId',
})}
class="mb-2 w-full rounded-md border border-white/10 px-3 py-2.5 text-left transition-colors hover:bg-white/5"
class="mb-2 w-full rounded-md border border-white/10 px-3 py-2.5 text-left transition-colors hover:bg-white/5 min-h-[44px]"
>
<div class="flex items-center gap-2">
{#if collection.icon}

View file

@ -356,4 +356,16 @@
background: rgba(255, 255, 255, 0.06);
color: #e5e7eb;
}
@media (max-width: 640px) {
.detail-view {
padding: 0.75rem;
}
.action-btn {
min-height: 44px;
}
.prop-input {
min-height: 44px;
}
}
</style>

View file

@ -46,7 +46,7 @@
};
</script>
<div class="flex h-full flex-col gap-3 p-4">
<div class="flex h-full flex-col gap-3 p-3 sm:p-4">
<div class="flex gap-3 text-xs text-white/40">
<span>{memos.length} Memos</span>
<span>{pinned.length} angepinnt</span>
@ -61,7 +61,7 @@
_siblingIds: sorted.map((m) => m.id),
_siblingKey: 'memoId',
})}
class="mb-2 w-full rounded-md border border-white/10 px-3 py-2.5 text-left transition-colors hover:bg-white/5"
class="mb-2 w-full rounded-md border border-white/10 px-3 py-2.5 text-left transition-colors hover:bg-white/5 min-h-[44px]"
>
<div class="flex items-start justify-between gap-2">
<div class="min-w-0 flex-1">

View file

@ -402,4 +402,17 @@
background: rgba(255, 255, 255, 0.06);
color: #e5e7eb;
}
@media (max-width: 640px) {
.detail-view {
padding: 0.75rem;
}
.pin-btn,
.action-btn {
min-height: 44px;
}
.prop-input {
min-height: 44px;
}
}
</style>

View file

@ -76,7 +76,7 @@
);
</script>
<div class="flex h-full flex-col gap-4 p-4">
<div class="flex h-full flex-col gap-4 p-3 sm:p-4">
<!-- Active mood preview -->
{#if activeMood}
<div
@ -93,7 +93,7 @@
<!-- Mood grid -->
<div class="flex-1 overflow-auto">
<div class="grid grid-cols-3 gap-2">
<div class="grid grid-cols-2 sm:grid-cols-3 gap-2">
{#each moods as mood (mood.id)}
<button
onclick={() => (activeMoodId = activeMoodId === mood.id ? null : mood.id)}

View file

@ -54,7 +54,7 @@
}
</script>
<div class="flex h-full flex-col gap-3 p-4">
<div class="flex h-full flex-col gap-3 p-3 sm:p-4">
<div class="flex gap-3 text-xs text-white/40">
<span>{songs.length} Songs</span>
<span>{playlists.length} Playlists</span>
@ -71,7 +71,7 @@
_siblingIds: recentlyPlayed.map((s) => s.id),
_siblingKey: 'songId',
})}
class="flex w-full items-center gap-3 rounded-md px-2 py-1.5 transition-colors hover:bg-white/5 cursor-pointer text-left"
class="flex w-full min-h-[44px] items-center gap-3 rounded-md px-2 py-1.5 transition-colors hover:bg-white/5 cursor-pointer text-left"
>
<div
class="flex h-8 w-8 shrink-0 items-center justify-center rounded bg-white/10 text-xs text-white/30"

View file

@ -367,4 +367,17 @@
background: rgba(255, 255, 255, 0.06);
color: #e5e7eb;
}
@media (max-width: 640px) {
.detail-view {
padding: 0.75rem;
}
.fav-btn,
.action-btn {
min-height: 44px;
}
.prop-input {
min-height: 44px;
}
}
</style>

View file

@ -449,4 +449,14 @@
font-size: 0.8125rem;
color: #9ca3af;
}
@media (max-width: 640px) {
.app-view {
padding: 0.75rem;
}
.note-item {
padding: 0.625rem 0.375rem;
min-height: 44px;
}
}
</style>

View file

@ -58,7 +58,7 @@
};
</script>
<div class="flex h-full flex-col gap-3 p-4">
<div class="flex h-full flex-col gap-3 p-3 sm:p-4">
<!-- Calorie progress -->
<div class="text-center">
<p class="text-2xl font-light text-white/90">{Math.round(totalCalories)}</p>
@ -90,7 +90,7 @@
<!-- Today's meals -->
<div class="flex-1 overflow-auto">
{#each todayMeals as meal (meal.id)}
<div class="mb-1 rounded-md px-3 py-2 transition-colors hover:bg-white/5">
<div class="mb-1 min-h-[44px] rounded-md px-3 py-2 transition-colors hover:bg-white/5">
<div class="flex items-center justify-between">
<span class="text-xs text-white/50">{mealTypeLabels[meal.mealType] ?? meal.mealType}</span
>

View file

@ -440,4 +440,14 @@
transform: rotate(360deg);
}
}
@media (max-width: 640px) {
.photos-list-view {
padding: 0.5rem;
}
.album-row {
padding: 0.625rem;
min-height: 44px;
}
}
</style>

View file

@ -38,10 +38,12 @@
<!-- svelte-ignore a11y_click_events_have_key_events a11y_no_static_element_interactions -->
<div
class="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4"
class="fixed inset-0 z-50 flex items-end sm:items-center justify-center bg-black/50 p-0 sm:p-4"
onclick={handleBackdropClick}
>
<div class="w-full max-w-md rounded-xl border border-border bg-background-card p-6">
<div
class="w-full max-w-md rounded-t-xl sm:rounded-xl border border-border bg-background-card p-6 max-h-[95vh] sm:max-h-[90vh]"
>
<header class="mb-6 flex items-center justify-between">
<h2 class="text-lg font-semibold text-foreground">Album erstellen</h2>
<button

View file

@ -26,14 +26,14 @@
const favoriteCount = $derived(images.filter((i) => i.isFavorite).length);
</script>
<div class="flex h-full flex-col gap-3 p-4">
<div class="flex h-full flex-col gap-3 p-3 sm:p-4">
<div class="flex items-center justify-between">
<p class="text-xs text-white/40">{images.length} Bilder</p>
<p class="text-xs text-white/40">{favoriteCount} Favoriten</p>
</div>
<div class="flex-1 overflow-auto">
<div class="grid grid-cols-3 gap-1.5">
<div class="grid grid-cols-2 sm:grid-cols-3 gap-1.5">
{#each sorted as image (image.id)}
<div class="group relative aspect-square overflow-hidden rounded-md bg-white/5">
{#if image.publicUrl}

View file

@ -534,4 +534,14 @@
opacity: 0.3;
}
}
@media (max-width: 640px) {
.places-list-view {
padding: 0.5rem;
}
.place-item {
padding: 0.625rem;
min-height: 44px;
}
}
</style>

View file

@ -600,4 +600,20 @@
background: rgba(255, 255, 255, 0.06);
color: #e5e7eb;
}
@media (max-width: 640px) {
.detail-view {
padding: 0.75rem;
}
.fav-btn,
.action-btn,
.tag-pill {
min-height: 44px;
}
.field-input,
.field-textarea,
.field-select {
min-height: 44px;
}
}
</style>

View file

@ -58,7 +58,7 @@
};
</script>
<div class="flex h-full flex-col gap-3 p-4">
<div class="flex h-full flex-col gap-3 p-3 sm:p-4">
<div class="flex gap-3 text-xs text-white/40">
<span>{plants.length} Pflanzen</span>
{#if dueForWatering.length > 0}
@ -80,7 +80,7 @@
_siblingIds: plants.map((p) => p.id),
_siblingKey: 'plantId',
})}
class="mb-2 w-full rounded-md border border-white/10 px-3 py-2.5 text-left transition-colors hover:bg-white/5"
class="mb-2 w-full rounded-md border border-white/10 px-3 py-2.5 text-left transition-colors hover:bg-white/5 min-h-[44px]"
>
<div class="flex items-center gap-2">
<span class="text-sm"

View file

@ -408,4 +408,17 @@
background: rgba(255, 255, 255, 0.06);
color: #e5e7eb;
}
@media (max-width: 640px) {
.detail-view {
padding: 0.75rem;
}
.action-btn {
min-height: 44px;
}
.prop-select,
.prop-input {
min-height: 44px;
}
}
</style>

View file

@ -30,7 +30,7 @@
}
</script>
<div class="flex h-full flex-col gap-3 p-4">
<div class="flex h-full flex-col gap-3 p-3 sm:p-4">
<!-- Model selector -->
<select
bind:value={selectedModel}
@ -45,7 +45,9 @@
<div class="flex-1 overflow-auto">
{#each messages as msg, i}
<div
class="mb-2 rounded-md px-3 py-2 {msg.role === 'user' ? 'bg-white/5' : 'bg-blue-500/10'}"
class="mb-2 min-h-[44px] rounded-md px-3 py-2 {msg.role === 'user'
? 'bg-white/5'
: 'bg-blue-500/10'}"
>
<p class="text-[10px] text-white/30">{msg.role === 'user' ? 'Du' : modelLabel}</p>
<p class="text-sm text-white/70">{msg.content}</p>

View file

@ -42,7 +42,7 @@
}
</script>
<div class="flex h-full flex-col gap-3 p-4">
<div class="flex h-full flex-col gap-3 p-3 sm:p-4">
<p class="text-xs text-white/40">{decks.length} Präsentationen</p>
<div class="flex-1 overflow-auto">
@ -54,7 +54,7 @@
_siblingIds: decks.map((d) => d.id),
_siblingKey: 'deckId',
})}
class="mb-2 w-full rounded-md border border-white/10 px-3 py-2.5 text-left transition-colors hover:bg-white/5"
class="mb-2 w-full rounded-md border border-white/10 px-3 py-2.5 text-left transition-colors hover:bg-white/5 min-h-[44px]"
>
<p class="truncate text-sm font-medium text-white/80">{deck.title}</p>
<div class="mt-1 flex items-center gap-2 text-xs text-white/40">

View file

@ -341,4 +341,14 @@
background: rgba(255, 255, 255, 0.06);
color: #e5e7eb;
}
@media (max-width: 640px) {
.detail-view {
padding: 0.75rem;
}
.action-btn,
.toggle-btn {
min-height: 44px;
}
}
</style>

View file

@ -58,7 +58,7 @@
);
</script>
<div class="flex h-full flex-col gap-3 p-4">
<div class="flex h-full flex-col gap-3 p-3 sm:p-4">
<div class="flex gap-3 text-xs text-white/40">
<span>{questions.length} Fragen</span>
<span>{collections.length} Sammlungen</span>
@ -73,7 +73,7 @@
_siblingIds: sorted.map((q) => q.id),
_siblingKey: 'questionId',
})}
class="mb-2 w-full text-left rounded-md border border-white/10 px-3 py-2.5 transition-colors hover:bg-white/5 cursor-pointer"
class="mb-2 w-full text-left rounded-md border border-white/10 px-3 py-2.5 transition-colors hover:bg-white/5 cursor-pointer min-h-[44px]"
>
<div class="flex items-start justify-between gap-2">
<p class="text-sm font-medium text-white/80">{question.title}</p>

View file

@ -403,4 +403,16 @@
background: rgba(255, 255, 255, 0.06);
color: #e5e7eb;
}
@media (max-width: 640px) {
.detail-view {
padding: 0.75rem;
}
.action-btn {
min-height: 44px;
}
.prop-select {
min-height: 44px;
}
}
</style>

View file

@ -42,7 +42,7 @@
const highestLevel = $derived(Math.max(0, ...skills.map((s) => s.level)));
</script>
<div class="flex h-full flex-col gap-3 p-4">
<div class="flex h-full flex-col gap-3 p-3 sm:p-4">
<!-- Stats -->
<div class="flex gap-3 text-xs text-white/40">
<span>{totalXp} XP</span>
@ -62,7 +62,7 @@
_siblingIds: skills.map((s) => s.id),
_siblingKey: 'skillId',
})}
class="mb-2 w-full rounded-md border border-white/10 px-3 py-2.5 text-left transition-colors hover:bg-white/5"
class="mb-2 w-full rounded-md border border-white/10 px-3 py-2.5 text-left transition-colors hover:bg-white/5 min-h-[44px]"
>
<div class="flex items-center justify-between">
<div class="flex items-center gap-2">

View file

@ -40,12 +40,14 @@
</script>
<div
class="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm"
class="fixed inset-0 z-50 flex items-end sm:items-center justify-center bg-black/60 backdrop-blur-sm"
onclick={handleBackdropClick}
role="dialog"
aria-modal="true"
>
<div class="mx-4 w-full max-w-md rounded-2xl border border-gray-700 bg-gray-800 p-6 shadow-xl">
<div
class="w-full max-w-md rounded-t-2xl sm:rounded-2xl border border-gray-700 bg-gray-800 p-6 shadow-xl max-h-[95vh] sm:max-h-[90vh] sm:mx-4"
>
<!-- Header -->
<div class="mb-6 flex items-center justify-between">
<h2 class="text-xl font-bold text-white">Neuer Skill</h2>

View file

@ -53,12 +53,14 @@
</script>
<div
class="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm"
class="fixed inset-0 z-50 flex items-end sm:items-center justify-center bg-black/60 backdrop-blur-sm"
onclick={handleBackdropClick}
role="dialog"
aria-modal="true"
>
<div class="mx-4 w-full max-w-md rounded-2xl border border-gray-700 bg-gray-800 p-6 shadow-xl">
<div
class="w-full max-w-md rounded-t-2xl sm:rounded-2xl border border-gray-700 bg-gray-800 p-6 shadow-xl max-h-[95vh] sm:max-h-[90vh] sm:mx-4"
>
<!-- Header -->
<div class="mb-6 flex items-center justify-between">
<div>

View file

@ -49,12 +49,14 @@
</script>
<div
class="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm"
class="fixed inset-0 z-50 flex items-end sm:items-center justify-center bg-black/60 backdrop-blur-sm"
onclick={handleBackdropClick}
role="dialog"
aria-modal="true"
>
<div class="mx-4 w-full max-w-md rounded-2xl border border-gray-700 bg-gray-800 p-6 shadow-xl">
<div
class="w-full max-w-md rounded-t-2xl sm:rounded-2xl border border-gray-700 bg-gray-800 p-6 shadow-xl max-h-[95vh] sm:max-h-[90vh] sm:mx-4"
>
<!-- Header -->
<div class="mb-6 flex items-center justify-between">
<h2 class="text-xl font-bold text-white">Skill bearbeiten</h2>

View file

@ -510,4 +510,20 @@
background: rgba(255, 255, 255, 0.06);
color: #e5e7eb;
}
@media (max-width: 640px) {
.detail-view {
padding: 0.75rem;
}
.action-btn,
.xp-btn {
min-height: 44px;
}
.prop-select,
.prop-input,
.xp-input,
.xp-desc-input {
min-height: 44px;
}
}
</style>

View file

@ -56,7 +56,7 @@
}
</script>
<div class="flex h-full flex-col gap-3 p-4">
<div class="flex h-full flex-col gap-3 p-3 sm:p-4">
<div class="flex gap-3 text-xs text-white/40">
<span>{folders.length} Ordner</span>
<span>{files.length} Dateien</span>
@ -68,7 +68,7 @@
<h3 class="mb-2 text-xs font-medium text-white/50">Ordner</h3>
{#each folders.filter((f) => !f.parentFolderId) as folder (folder.id)}
<div
class="flex items-center gap-2 rounded-md px-2 py-1.5 transition-colors hover:bg-white/5"
class="flex min-h-[44px] items-center gap-2 rounded-md px-2 py-1.5 transition-colors hover:bg-white/5"
>
<span class="text-sm" style="color: {folder.color ?? '#6b7280'}">&#128193;</span>
<span class="truncate text-sm text-white/70">{folder.name}</span>
@ -86,7 +86,7 @@
_siblingIds: recentFiles.map((f) => f.id),
_siblingKey: 'fileId',
})}
class="flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left transition-colors hover:bg-white/5"
class="flex w-full min-h-[44px] items-center gap-2 rounded-md px-2 py-1.5 text-left transition-colors hover:bg-white/5"
>
<span class="text-sm">{@html fileIcon(file.mimeType)}</span>
<span class="min-w-0 flex-1 truncate text-sm text-white/70">{file.name}</span>

View file

@ -283,4 +283,14 @@
background: rgba(255, 255, 255, 0.06);
color: #e5e7eb;
}
@media (max-width: 640px) {
.detail-view {
padding: 0.75rem;
}
.fav-btn,
.action-btn {
min-height: 44px;
}
}
</style>

View file

@ -98,7 +98,7 @@
}
</script>
<div class="flex h-full flex-col gap-3 p-4">
<div class="flex h-full flex-col gap-3 p-3 sm:p-4">
<!-- Inline Timer -->
<div class="flex items-center gap-2">
<button
@ -141,7 +141,7 @@
{#each todayEntries as entry (entry.id)}
<button
onclick={() => navigate('detail', { entryId: entry.id })}
class="mb-1 w-full rounded-md px-3 py-2 text-left transition-colors hover:bg-white/5"
class="mb-1 w-full min-h-[44px] rounded-md px-3 py-2 text-left transition-colors hover:bg-white/5"
>
<div class="flex items-center justify-between">
<p class="truncate text-sm text-white/80">

View file

@ -521,4 +521,19 @@
background: rgba(255, 255, 255, 0.06);
color: #e5e7eb;
}
@media (max-width: 640px) {
.detail-view {
padding: 0.75rem;
}
.action-btn,
.billable-toggle {
min-height: 44px;
}
.prop-select,
.prop-input,
.dur-input {
min-height: 44px;
}
}
</style>

View file

@ -54,10 +54,12 @@
<!-- svelte-ignore a11y_click_events_have_key_events -->
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div
class="fixed inset-0 z-[9997] flex items-center justify-center bg-black/45 p-4 backdrop-blur-sm"
class="fixed inset-0 z-[9997] flex items-end sm:items-center justify-center bg-black/45 p-0 sm:p-4 backdrop-blur-sm"
onclick={(e) => e.target === e.currentTarget && finish()}
>
<div class="w-full max-w-sm rounded-2xl border border-border bg-card shadow-2xl">
<div
class="w-full max-w-sm rounded-t-2xl sm:rounded-2xl border border-border bg-card shadow-2xl max-h-[95vh] sm:max-h-[90vh]"
>
<div class="flex flex-col items-center p-8 text-center">
<div class="mb-4 flex h-16 w-16 items-center justify-center rounded-2xl bg-primary/10">
<svelte:component this={steps[step].icon} size={32} class="text-primary" />

View file

@ -91,11 +91,11 @@
<!-- svelte-ignore a11y_click_events_have_key_events -->
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div
class="fixed inset-0 z-[9995] flex items-center justify-center bg-black/45 p-4 backdrop-blur-sm sm:p-8"
class="fixed inset-0 z-[9995] flex items-end sm:items-center justify-center bg-black/45 p-0 sm:p-8 backdrop-blur-sm"
onclick={handleBackdropClick}
>
<div
class="flex max-h-[calc(100vh-4rem)] w-full max-w-[1040px] flex-col overflow-hidden rounded-2xl border border-border bg-card shadow-2xl max-sm:max-h-[calc(100vh-60px)] max-sm:rounded-b-none"
class="flex w-full max-w-[1040px] flex-col overflow-hidden rounded-t-2xl sm:rounded-2xl border border-border bg-card shadow-2xl max-h-[95vh] sm:max-h-[calc(100vh-4rem)]"
>
<!-- Top bar -->
<div

View file

@ -97,10 +97,12 @@
<!-- svelte-ignore a11y_click_events_have_key_events -->
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div
class="fixed inset-0 z-[9996] flex items-center justify-center bg-black/45 p-4 backdrop-blur-sm"
class="fixed inset-0 z-[9996] flex items-end sm:items-center justify-center bg-black/45 p-0 sm:p-4 backdrop-blur-sm"
onclick={(e) => e.target === e.currentTarget && onClose()}
>
<div class="w-full max-w-lg rounded-2xl border border-border bg-card shadow-2xl">
<div
class="w-full max-w-lg rounded-t-2xl sm:rounded-2xl border border-border bg-card shadow-2xl max-h-[95vh] sm:max-h-[90vh]"
>
<!-- Header -->
<div class="flex items-center justify-between border-b border-border px-5 py-3">
<h2 class="text-lg font-semibold text-foreground">

View file

@ -700,4 +700,22 @@
background: rgba(255, 255, 255, 0.06);
color: #e5e7eb;
}
@media (max-width: 640px) {
.detail-view {
padding: 0.75rem;
}
.complete-btn,
.action-btn,
.schedule-btn,
.unschedule-btn,
.subtask-item,
.tag-pill {
min-height: 44px;
}
.prop-select,
.prop-input {
min-height: 44px;
}
}
</style>

View file

@ -52,7 +52,7 @@
}
</script>
<div class="flex h-full flex-col gap-3 p-4">
<div class="flex h-full flex-col gap-3 p-3 sm:p-4">
<div class="flex gap-3 text-xs text-white/40">
<span>{links.length} Links</span>
<span>{totalClicks} Klicks</span>
@ -68,7 +68,7 @@
_siblingIds: sorted.map((l) => l.id),
_siblingKey: 'linkId',
})}
class="mb-1 w-full text-left rounded-md px-3 py-2 transition-colors hover:bg-white/5 cursor-pointer"
class="mb-1 w-full min-h-[44px] text-left rounded-md px-3 py-2 transition-colors hover:bg-white/5 cursor-pointer"
>
<div class="flex items-center justify-between">
<p class="truncate text-sm font-medium text-white/80">

View file

@ -399,4 +399,17 @@
background: rgba(255, 255, 255, 0.06);
color: #e5e7eb;
}
@media (max-width: 640px) {
.detail-view {
padding: 0.75rem;
}
.action-btn,
.toggle-label {
min-height: 44px;
}
.prop-input {
min-height: 44px;
}
}
</style>

View file

@ -85,7 +85,7 @@
<!-- svelte-ignore a11y_click_events_have_key_events -->
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div
class="flex h-full cursor-pointer flex-col items-center justify-center p-6"
class="flex h-full cursor-pointer flex-col items-center justify-center p-4 sm:p-6"
onclick={nextQuote}
use:dropTarget={{
accepts: ['tag'],
@ -116,7 +116,10 @@
</div>
{/if}
<button onclick={toggleFav} class="mt-3 rounded-full p-1.5 transition-colors hover:bg-white/5">
<button
onclick={toggleFav}
class="mt-3 min-h-[44px] rounded-full p-1.5 transition-colors hover:bg-white/5"
>
<Heart
size={16}
weight={isFav ? 'fill' : 'regular'}

View file

@ -247,4 +247,14 @@
color: #ef4444;
border-color: rgba(239, 68, 68, 0.2);
}
@media (max-width: 640px) {
.detail-view {
padding: 1rem;
}
.action-btn,
.bio-btn {
min-height: 44px;
}
}
</style>