Commit graph

93 commits

Author SHA1 Message Date
Bruno Deanoz
515a71efb5 feat: Inter Variable font, theme picker wired end-to-end, settings i18n
Inter Variable (v4.1, 859 KB): full type scale with 9 weight axes
(W100–W900), negative tracking at display sizes, positive at labels.

Theme picker: SettingsViewModel now uses KaizenThemeId from the design
system (AMBER/BLAU/MONO/AURORA). MainActivity wires selectedTheme +
appearanceMode to KaizenTheme composable — switching themes in Settings
instantly propagates to the entire app.

No server sync needed — web stores theme in localStorage, app stores
locally. Backend /api/v1/me has no uiTheme field in the DB.

Settings strings migrated to string resources (de + en).
SettingsViewModelTest updated for new enum values + System default.
2026-06-21 15:17:17 +02:00
Bruno Deanoz
f83d4b4e17 fix: Oklab round-trip precision — Double math + corrected LMS matrix
Root cause: Float32 accumulated ~0.017 error across 6 matrix multiplications
(RGB→LMS→Lab→Lab→LMS→RGB), producing negative linear-green values that got
clamped to 0 by toSRGB().

Fix: all matrix math now uses Double. Forward LMS matrix corrected to match
Björn Ottosson's reference implementation. Variable shadowing eliminated.

All 3 OklabTest cases now pass (were failing since initial commit).
2026-06-21 15:10:25 +02:00
Bruno Deanoz
e3d624c961 feat: orb uses rememberTiltState(), update CLAUDE.md with i18n + migration status
KaizenOrb now uses centralized rememberTiltState() (GAME_ROTATION_VECTOR,
lifecycle-aware, battery-saver-aware) instead of inline sensor code.
Breath animation uses Durations tokens from motion system.

CLAUDE.md: updated design system section with GlassSurface correction
(no backdrop-filter on Android), migration status (all components done),
i18n section documenting the de/en string resource architecture.
2026-06-21 15:04:31 +02:00
Bruno Deanoz
0237eae1e6 feat: i18n — extract all UI strings to resources (de + en)
German (default) in values/strings.xml, English in values-en/strings.xml.
Matches web app's next-intl de/en setup.

Migrated: greeting, hero headline, chat input, error messages, mode pills,
suggestion pills, sidebar (brand, search, dates, logout, settings),
model sheet, login screen (welcome, fields, errors, submit button),
conversation labels (locked, pinned).

ChatModels: Suggestion/ChatMode now use resource IDs instead of hardcoded strings.
greeting() is now @Composable (uses stringResource).
ModePillsRow: selected state uses resource ID (Int) instead of String.
Date labels (HEUTE/GESTERN/FRÜHER) localized via DateLabels data class.
2026-06-21 15:02:16 +02:00
Bruno Deanoz
94c0f85fb7 feat: migrate all UI components to design system v2
- Sidebar: GlassSurface + KaizenShapes (lg, sm, md, pill, circle)
- ChatInput: GlassSurface with input tier opacity
- ChatScreen: menu button uses GlassSurface, error banner uses KaizenShapes
- EmptyHero: suggestion chips removed on mobile (DESIGN.md §11.1)
- LoginScreen: GlassFields use KaizenShapes.lg
- ModelSheet: KaizenShapes (xl, md, xs, circle)
- SettingsCard: GlassSurface with card tier opacity
- SettingsScreen: back button uses GlassSurface
- SettingsComponents: all CircleShape/RoundedCornerShape → KaizenShapes
- Markdown: copy button uses KaizenShapes.circle
- GlassSurface: removed misleading Modifier.blur (Android has no backdrop-filter)
- TypingDots: uses motion duration tokens
- Fixed deprecated ArrowBack icon → AutoMirrored variant
2026-06-21 14:50:11 +02:00
Bruno Deanoz
4d71475995 fix: derive all theme colors from web CSS files (OKLCH → P3 RGB)
Amber blobs were cold (blue/indigo) but web uses warm (gold/coral/honey/teal).
Mono had slate chroma but web is pure achromatic (zero chroma).
Aurora dark primary was magenta but web swaps to gold in dark mode.
All four themes now pixel-match the web app's OKLCH values.
2026-06-21 14:41:23 +02:00
Bruno Deanoz
f1c6a88c4c docs: add CLAUDE.md as architecture map (renamed from NEXT.md)
Adds design system v2 section covering P3 colors, squircle shapes,
GlassSurface, multi-layer shadows, 4-theme system, sensor tilt state,
motion tokens, and new test inventory.
2026-06-21 14:35:45 +02:00
Bruno Deanoz
6465b47bbb feat: design system v2 — P3 colors, squircle shapes, glass surfaces, multi-theme, motion tokens
Foundation for the premium UI overhaul:
- P3 DisplayP3 color pipeline (all tokens in wide gamut)
- SquircleShape (iOS-style superellipse with G2 continuity)
- KaizenShapes token system (xs/sm/md/lg/xl/pill/circle)
- Multi-layer ShadowStack system (level 0–4)
- GlassSurface composable with RenderEffect blur + API fallback
- Motion tokens (easing curves, spring specs, durations)
- Tilt sensor state (GAME_ROTATION_VECTOR, lifecycle-aware)
- 4-theme system (Amber/Blau/Mono/Aurora) with AccentScheme
- ThemeRegistry + CompositionLocal for accent propagation
- Unit tests for colors, shapes, shadows, themes
2026-06-21 14:32:25 +02:00
Bruno Deanoz
203316b1c3 fix: enable encodeDefaults so message persistence actually works
kotlinx.serialization defaults to not encoding properties with default
values. SaveMessage.kind = "chat" was never sent, causing the backend's
sanitizeSaveableMessage() to reject every save with 400. This also
broke title generation since it was gated behind a successful save.
2026-06-21 13:43:24 +02:00
Bruno Deanoz
9759d478a7 feat: offline-first cache layer with Room
Room 2.8.4 as local SQLite read-cache for conversations and messages.
Sidebar and chat history load instantly from cache, background refresh
syncs with the server. Streaming stays in-memory, flushed to Room after
completion. Includes ChatViewModel, repositories, mappers, TypeConverters,
and unit tests.
2026-06-21 12:50:46 +02:00
Bruno Deanoz
d8dcb25e3d feat: attachment support — display, upload, and send files in chat
- Parse and render message attachments from loaded conversations (images
  inline via OkHttp + in-memory cache, other kinds as icon chips)
- Wire up the + button with Android file picker (ActivityResultContracts)
- Upload files to /api/v1/upload with progress tracking and preview chips
- Send attachments with chat requests and persist them in saved messages
- Markdown: horizontal rules, blockquotes, links, code block copy button
2026-06-20 00:36:07 +02:00
Bruno Deanoz
4616ef2ba1 feat: Markdown rendering with syntax-highlighted code blocks
Native Compose Markdown renderer replaces raw Text() for assistant
messages. Supports headings, bold/italic, inline code, fenced code
blocks with keyword highlighting (15+ languages), ordered/unordered
lists. Streaming cursor integrates seamlessly into the last block.
2026-06-19 17:21:01 +02:00
Bruno Deanoz
423abc03af fix: show specific error diagnostics instead of generic connection failure
Replace null-returning fetchModels/fetchConversations with FetchResult<T>
sealed interface. Error banner now shows the exact cause (HTTP status,
DNS, SSL, timeout, JSON parsing) instead of "Verbindung zum Server
fehlgeschlagen".
2026-06-19 17:10:05 +02:00
Bruno Deanoz
827a2f307c fix: streaming performance, error handling, and API diagnostics
- Eliminate recomposition hell: isolate auto-scroll via derivedStateOf + snapshotFlow
- Preserve partial response on connection drop instead of replacing with error
- O(1) incremental stream parser (StreamConsumer.Incremental) replacing O(N²) re-scan
- Parallel conversation creation via async/await to reduce TTFT
- TCP/TLS prewarm on app resume via LifecycleResumeEffect
- Surface API failures with Log.w and UI error banner instead of silent emptyList()
- Fix nullable KaizenModel.name crash in ModelSheet
2026-06-19 15:34:59 +02:00
Bruno Deanoz
d81c6ffda7 fix: make KaizenApi exceptionally robust against malformed JSON or parsing failures 2026-06-19 09:06:55 +02:00
Bruno Deanoz
7399c73e6a feat: Redesign model selection sheet with OpenRouter/Vertex badging & offline-first caching 2026-06-19 09:00:58 +02:00
Bruno Deanoz
ea5e625f0f feat(chat): wire sidebar to real conversations + persist history
Sidebar now lists the user's conversations from GET /api/v1/conversations
(date-grouped, pinned first, active highlighted) instead of mock data. Sending
creates a server conversation on the first message, persists each exchange via
POST .../messages, and auto-titles new conversations. Tapping a chat loads its
stored messages; new-chat/logout reset the active conversation. Linear model
(no branching); locked chats are skipped (no in-app unlock yet).
2026-06-19 07:58:07 +02:00
Bruno Deanoz
d2f269f33a feat(chat): model + speed picker (top pill + bottom sheet)
Top pill shows the active model; tapping opens a bottom sheet with a
response-speed segment (Instant/Normal/Max -> reasoningEffort + throughput),
model search, favorites, provider grouping and a Vertex hoster badge.
Model/speed/favorites persisted in the encrypted store; chat now sends the
additive reasoningEffort/preferThroughput v1 fields.
2026-06-19 07:43:59 +02:00
Bruno Deanoz
aa0a97b959 fix(ui): dither gradients to kill 8-bit sRGB banding on orb + mesh 2026-06-19 07:27:33 +02:00
Bruno Deanoz
44c17b6f9f feat: wire chat to the real Kaizen backend (in-app login + streaming)
Replaces the Phase-0 fakeReply mock with the real v1 API. Deployment-agnostic:
one binary, one Authorization: Bearer contract, server-URL field switches between
the official instance and any self-host.

- auth/LoginScreen: server-URL + email + password -> POST /api/v1/auth/token
- net/SecureStore: kzn_ token in EncryptedSharedPreferences (KeyStore AES-256-GCM)
- net/SessionViewModel: snapshot-state login/logout routing, restores on launch
- net/KaizenApi: POST /api/v1/chat streaming + GET /api/v1/me for the default model
- net/StreamConsumer: Kotlin port of lib/chat/stream-consumer.ts (JVM-unit-tested)
- deps: okhttp, kotlinx-serialization, security-crypto; INTERNET permission

Code-complete; not yet built/run on device (no Android SDK on the dev Mac).
2026-06-19 01:04:55 +02:00
Bruno Deanoz
8a527451d7 fix(ui): resolve ColumnScope, Oklab.Lab, and missing layout imports in SettingsComponents.kt 2026-06-18 17:46:05 +02:00
Bruno Deanoz
779796f825 feat(ui): connect modular SettingsScreen, complete SettingsComponents, and wire up dynamic sidebar avatar 2026-06-18 17:44:01 +02:00
Bruno Deanoz
d0cb89cf6e feat(ui): add clean SettingsViewModel and comprehensive ViewModel JVM unit tests 2026-06-18 17:42:00 +02:00
Bruno Deanoz
dfdd9e761f docs(roadmap): create LATER.md architectural blueprint for future security, KeyStore, and backend sync 2026-06-18 17:40:58 +02:00
Bruno Deanoz
0999e154cd test(ui): add comprehensive Oklab color-space unit test suite 2026-06-18 17:36:30 +02:00
Bruno Deanoz
57fa02bd6f feat(ui): implement Display P3, Ultra HDR support, and perzeptive Oklab color interpolation 2026-06-18 17:25:12 +02:00
Bruno Deanoz
41a21c30c8 fix(ui): import background and border Modifiers in ChatScreen.kt 2026-06-18 17:18:21 +02:00
Bruno Deanoz
7235cd7bc1 fix(ui): import isSystemInDarkTheme in ChatScreen and correct padding signature in Sidebar 2026-06-18 17:16:10 +02:00
Bruno Deanoz
37e424df3e feat(ui): implement gorgeous floating glassmorphic sidebar and rich 3D ambient shadows for suggestions, pills, and input 2026-06-18 17:13:13 +02:00
Bruno Deanoz
2c3d057641 fix(ui): dynamically shrink EmptyHero bottom spacer on keyboard open to keep greeting visible 2026-06-18 17:03:55 +02:00
Bruno Deanoz
7b012d1041 fix(ui): remove incorrect blur from sphere Canvas to restore razor-sharp edges and solid crystal glass definition 2026-06-18 17:01:28 +02:00
Bruno Deanoz
b03f1773fe fix(ui): add missing ExperimentalLayoutApi import to ChatComponents.kt 2026-06-18 16:59:43 +02:00
Bruno Deanoz
c3fb668ea1 feat(ui): sculpt KaizenOrb into a highly realistic 3D sphere with heavy volume shadows, and remove the redundant top header bar 2026-06-18 16:55:49 +02:00
Bruno Deanoz
7a95f7735c feat(ui): implement masterclass KaizenOrb with native 3D gyroscope parallax refraction and double conic caustics 2026-06-18 16:52:41 +02:00
Bruno Deanoz
f8498adc27 fix(ui): add @OptIn(ExperimentalLayoutApi) for FlowRow layout compiler error 2026-06-18 16:43:52 +02:00
Bruno Deanoz
e3ea6d241f feat(ui): implement tablet optimizations and gemini-style dynamic keyboard suggestion-hiding 2026-06-18 16:40:18 +02:00
Bruno Deanoz
e13f6798db fix(ui): remove redundant bottom dock imePadding and restore constant bottom clear margins 2026-06-18 16:35:42 +02:00
Bruno Deanoz
cbcbd4f76b fix(ui): resolve double-resizing overlap bug with dynamic keyboard insets padding 2026-06-18 16:33:21 +02:00
Bruno Deanoz
43ca73c04a feat(ui): implement liquid glass styling, floating panels, and perfect soft-keyboard inset handling 2026-06-18 16:29:15 +02:00
Bruno Deanoz
4cd117e703 Redesign hero to match web (suggestion pills, date/time, mode pill row, +/call/send input); add thinking phase with phase-aware haptics; glassier orb 2026-06-18 15:49:47 +02:00
Bruno Deanoz
d46949878d Fix send crash (VIBRATE permission), add light/dark theme, redesign send button, group hero to fix keyboard reflow 2026-06-18 15:39:27 +02:00
Bruno Deanoz
66f83b97a7 Add Phase 0 feel-prototype: chat screen, mesh/orb design, mock streaming, haptics 2026-06-18 15:26:32 +02:00
a5a6dbff61 Initial commit - Kaizen App 2026-06-18 15:08:09 +02:00