fix(tasks): full-size fields in the task details on phones

Task list, people search, hashtag and subtask fields were 24-32 px with
12 px text on phones; they now match the other fields (44 px, 16 px text,
no zoom on iOS). The note button says just "Notiz" there, so the header
stays on one line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
sandrodachandClaude Opus 5.5 committed 2026-11-02 12:59:16 +01:00
1 parent 92993c2dd2
commit b04991ee23
3 files changed
+14 -10

No files matched your search

+3 -1
View File
@@ -14,6 +14,7 @@ Eingesetzt beim Teilen (`UnifiedShareModal`), beim Hinzufügen zu Gruppen (`Grou
- Bereits gewählte oder freigegebene Personen werden über `excludeUserIds` ausgeblendet. - Bereits gewählte oder freigegebene Personen werden über `excludeUserIds` ausgeblendet.
- **Einzelauswahl** (Teilen, Gruppen): `selectedUser` setzen; das Feld zeigt dann die gewählte Person mit ×. - **Einzelauswahl** (Teilen, Gruppen): `selectedUser` setzen; das Feld zeigt dann die gewählte Person mit ×.
- **Mehrfachauswahl** (Aufgaben zuweisen): `selectedUser={null}` lassen und in `onSelectUser` zur Liste hinzufügen. Die Gewählten stehen als Chips (Avatar, Name, ×) über dem Feld, das Feld bleibt für die nächste Suche frei. - **Mehrfachauswahl** (Aufgaben zuweisen): `selectedUser={null}` lassen und in `onSelectUser` zur Liste hinzufügen. Die Gewählten stehen als Chips (Avatar, Name, ×) über dem Feld, das Feld bleibt für die nächste Suche frei.
- Am Handy sind Feld, gewählte Person und Trefferzeilen 44 px hoch (Schrift 16 px, kein Zoom unter iOS), ab `sm` wie bisher 32 px.
## Profilbilder als Stapel ## Profilbilder als Stapel
@@ -64,7 +65,8 @@ Komponente: [CountBadge.tsx](../frontend/src/components/CountBadge.tsx), CSS-Kla
- `muted` (Standard): reine Anzahl. Tabs der Aufgabenlisten und Listen, Organisationen, mobiles Menü. - `muted` (Standard): reine Anzahl. Tabs der Aufgabenlisten und Listen, Organisationen, mobiles Menü.
- Beide kommen aus den Theme-Variablen (`--accent-primary`/`--text-on-accent` bzw. `--text-muted`/`--bg-panel`) und passen sich damit jedem Theme an. - Beide kommen aus den Theme-Variablen (`--accent-primary`/`--text-on-accent` bzw. `--text-muted`/`--bg-panel`) und passen sich damit jedem Theme an.
- **Position (`position`):** - **Position (`position`):**
- `corner`: Benachrichtigungs-Badge oben rechts am nächsten `relative` Elternelement, mit Ring in der Seitenfarbe. In der Navigation und an den Tabs sitzt er **auf dem Text**: der Text steht in einem `relative inline-flex`-Span (mit `pr-3`, solange ein Zähler da ist), der Kreis bekommt `-top-0.5 -right-2`, damit er die obere Tab-Linie nicht anschneidet und nicht am Text klebt. In der mobilen Leiste sitzt er am Icon (`-top-1.5 -right-2.5`). - `text`: an Beschriftungen (Navigation, Reiter der Aufgabenlisten und Listen, Workspace-Kopf). Der Zähler steht im Textfluss direkt hinter dem Wort, leicht angehoben, und schließt direkt an; nur sein Ring in Seitenfarbe hängt 2 px über den letzten Buchstaben, egal wie viele Stellen die Zahl hat; breitere Zahlen machen den Reiter breiter. Der Text steht dafür in einem `inline-flex items-center`-Span.
- `corner`: Benachrichtigungs-Badge oben rechts am nächsten `relative` Elternelement, mit Ring in der Seitenfarbe; für Icons, z. B. in der mobilen Leiste (`-top-1.5 -right-2.5`).
- `inline`: im Textfluss. - `inline`: im Textfluss.
- Zahlen im mobilen Menü (`MobileActionContext`, `badge: number`) werden automatisch als `CountBadge` gezeigt; Text-Badges wie „2 aktiv“ bleiben Textmarken. - Zahlen im mobilen Menü (`MobileActionContext`, `badge: number`) werden automatisch als `CountBadge` gezeigt; Text-Badges wie „2 aktiv“ bleiben Textmarken.
- **Wichtig für neue Klassen:** Tailwind entfernt Klassen aus `@layer components`, die nicht wörtlich im Code stehen. Klassennamen deshalb nie zusammensetzen (`count-badge-${variant}`), sondern ausschreiben. - **Wichtig für neue Klassen:** Tailwind entfernt Klassen aus `@layer components`, die nicht wörtlich im Code stehen. Klassennamen deshalb nie zusammensetzen (`count-badge-${variant}`), sondern ausschreiben.
+3 -3
View File
@@ -103,7 +103,7 @@ export const UserAutocomplete: React.FC<UserAutocompleteProps> = ({
return ( return (
<div ref={containerRef} className={`relative ${className}`}> <div ref={containerRef} className={`relative ${className}`}>
{selectedUser ? ( {selectedUser ? (
<div className="h-8 px-2.5 bg-panel-elevated border border-accent/40 rounded-btn flex items-center justify-between gap-2 text-xs"> <div className="h-11 sm:h-8 px-2.5 bg-panel-elevated border border-accent/40 rounded-btn flex items-center justify-between gap-2 text-xs">
<div className="flex items-center gap-2 min-w-0"> <div className="flex items-center gap-2 min-w-0">
<UserAvatar user={selectedUser} size="xs" /> <UserAvatar user={selectedUser} size="xs" />
<span className="font-semibold text-main truncate"> <span className="font-semibold text-main truncate">
@@ -148,7 +148,7 @@ export const UserAutocomplete: React.FC<UserAutocompleteProps> = ({
onFocus={() => setIsOpen(true)} onFocus={() => setIsOpen(true)}
onKeyDown={handleKeyDown} onKeyDown={handleKeyDown}
placeholder={placeholder} placeholder={placeholder}
className="w-full h-8 pl-8 pr-2.5 bg-input text-main border border-border rounded-btn focus:outline-none focus:border-accent text-xs placeholder:text-muted transition-colors disabled:opacity-50" className="w-full h-11 sm:h-8 pl-8 pr-2.5 bg-input text-main border border-border rounded-btn focus:outline-none focus:border-accent text-base sm:text-xs placeholder:text-muted transition-colors disabled:opacity-50"
/> />
{showResults && ( {showResults && (
@@ -166,7 +166,7 @@ export const UserAutocomplete: React.FC<UserAutocompleteProps> = ({
type="button" type="button"
onClick={() => handleSelect(u)} onClick={() => handleSelect(u)}
onMouseEnter={() => setHighlightedIndex(idx)} onMouseEnter={() => setHighlightedIndex(idx)}
className={`w-full px-2.5 py-1.5 flex items-center justify-between gap-2 text-left text-xs transition-colors cursor-pointer ${ className={`w-full min-h-11 sm:min-h-0 px-2.5 py-1.5 flex items-center justify-between gap-2 text-left text-xs transition-colors cursor-pointer ${
isHighlighted isHighlighted
? 'bg-accent/15 text-main font-medium' ? 'bg-accent/15 text-main font-medium'
: 'hover:bg-panel-elevated text-main' : 'hover:bg-panel-elevated text-main'
@@ -287,7 +287,9 @@ const TaskDetailModalContent: React.FC<TaskDetailModalProps & { task: Thought }>
className="btn-primary min-h-[38px] sm:min-h-0 h-9 sm:h-7 px-2.5 sm:px-2 text-xs flex items-center gap-1.5 font-semibold" className="btn-primary min-h-[38px] sm:min-h-0 h-9 sm:h-7 px-2.5 sm:px-2 text-xs flex items-center gap-1.5 font-semibold"
> >
<FileText className="w-4 h-4 sm:w-3.5 sm:h-3.5" /> <FileText className="w-4 h-4 sm:w-3.5 sm:h-3.5" />
<span>In Notiz öffnen</span> {/* Short on phones, so the header buttons stay on one line */}
<span className="sm:hidden">Notiz</span>
<span className="hidden sm:inline">In Notiz öffnen</span>
</button> </button>
) : !readOnly && ( ) : !readOnly && (
<button <button
@@ -611,7 +613,7 @@ const TaskDetailModalContent: React.FC<TaskDetailModalProps & { task: Thought }>
<select <select
value={task.taskListId || ''} value={task.taskListId || ''}
onChange={(e) => onUpdateTaskList(task, e.target.value)} onChange={(e) => onUpdateTaskList(task, e.target.value)}
className="w-full h-8 input-field px-2.5 text-xs bg-panel" className="w-full h-11 sm:h-8 input-field px-2.5 text-base sm:text-xs bg-panel"
> >
<option value="">-- Keine Liste (Allgemein) --</option> <option value="">-- Keine Liste (Allgemein) --</option>
{taskLists.map((tl) => ( {taskLists.map((tl) => (
@@ -714,7 +716,7 @@ const TaskDetailModalContent: React.FC<TaskDetailModalProps & { task: Thought }>
value={newTagDraft} value={newTagDraft}
onChange={(e) => setNewTagDraft(e.target.value)} onChange={(e) => setNewTagDraft(e.target.value)}
placeholder="+ #hashtag" placeholder="+ #hashtag"
className="h-6 w-24 px-1.5 text-xs input-field" className="h-11 sm:h-6 w-32 sm:w-24 px-2 sm:px-1.5 text-base sm:text-xs input-field"
/> />
</form> </form>
)} )}
@@ -802,13 +804,13 @@ const TaskDetailModalContent: React.FC<TaskDetailModalProps & { task: Thought }>
type="text" type="text"
value={newSubtaskTitle} value={newSubtaskTitle}
onChange={(e) => setNewSubtaskTitle(e.target.value)} onChange={(e) => setNewSubtaskTitle(e.target.value)}
placeholder="Neue Unteraufgabe hinzufügen…" placeholder="Neue Unteraufgabe…"
className="flex-1 h-7 px-2 text-xs input-field" className="flex-1 min-w-0 h-11 sm:h-7 px-2 text-base sm:text-xs input-field"
/> />
<button <button
type="submit" type="submit"
disabled={!newSubtaskTitle.trim()} disabled={!newSubtaskTitle.trim()}
className="btn-action h-7 px-2.5 text-xs disabled:opacity-40" className="btn-action h-11 sm:h-7 px-2.5 text-xs disabled:opacity-40"
> >
<Plus className="w-3 h-3" /> <Plus className="w-3 h-3" />
<span>Hinzufügen</span> <span>Hinzufügen</span>