mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 20:21:09 +02:00
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:
parent
a5f5c8b63f
commit
92d8275704
61 changed files with 499 additions and 81 deletions
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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] ?? '📄'}</span>
|
||||
<div class="min-w-0 flex-1">
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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)}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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'}">📁</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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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" />
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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'}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue