diff --git a/.claude/skills/check-api/SKILL.md b/.claude/skills/check-api/SKILL.md
new file mode 100644
index 0000000..58c9760
--- /dev/null
+++ b/.claude/skills/check-api/SKILL.md
@@ -0,0 +1,41 @@
+---
+name: check-api
+description: Check Teslamate API response format for a given endpoint. Use when you need to understand the JSON structure returned by the API.
+allowed-tools: Read, WebFetch
+---
+
+# Check Teslamate API
+
+Query the Teslamate API to inspect JSON response format for endpoints.
+
+## Configuration
+
+The API URL should be set in a `.env` file at the project root (gitignored):
+
+```
+TESLAMATE_API_URL=https://your-teslamate-api.example.com
+```
+
+If no `.env` file exists, ask the user for their Teslamate API URL.
+
+## Common Endpoints
+
+- `/api/v1/cars` - List all cars
+- `/api/v1/cars/{id}` - Car details with current state (battery, location, climate, etc.)
+- `/api/v1/cars/{id}/drives` - Drive history (supports `?start_date=` and `?end_date=`)
+- `/api/v1/cars/{id}/charges` - Charge history (supports `?start_date=` and `?end_date=`)
+- `/api/v1/cars/{id}/drives/{drive_id}` - Single drive details with positions
+- `/api/v1/cars/{id}/charges/{charge_id}` - Single charge details with charging curve
+
+## Instructions
+
+1. Read the `.env` file to get `TESLAMATE_API_URL`
+2. If not found, ask the user for the URL
+3. Use WebFetch to query the requested endpoint
+4. Present the JSON structure clearly, highlighting relevant fields
+
+## Date Format
+
+The API's parseDateParam function only accepts:
+- RFC3339 format: `2024-12-07T00:00:00Z`
+- DateTime format: `2024-12-07 00:00:00`
diff --git a/.claude/skills/new-screen/SKILL.md b/.claude/skills/new-screen/SKILL.md
new file mode 100644
index 0000000..afecaf5
--- /dev/null
+++ b/.claude/skills/new-screen/SKILL.md
@@ -0,0 +1,131 @@
+---
+name: new-screen
+description: Scaffold a new Jetpack Compose screen following project patterns. Use when creating a new screen or view in the app.
+allowed-tools: Read, Write, Edit, Glob
+---
+
+# New Screen Skill
+
+Create a new Jetpack Compose screen following MateDroid's patterns.
+
+## Project Structure
+
+Screens are located in `app/src/main/java/com/matedroid/ui/screens/`:
+```
+screens/
+├── dashboard/
+│ └── DashboardScreen.kt
+├── drives/
+│ ├── DrivesScreen.kt
+│ └── DriveDetailScreen.kt
+├── charges/
+│ ├── ChargesScreen.kt
+│ └── ChargeDetailScreen.kt
+├── settings/
+│ └── SettingsScreen.kt
+└── {feature}/
+ └── {Feature}Screen.kt
+```
+
+## Process
+
+1. Ask the user for:
+ - Screen name (e.g., "Battery Health")
+ - Brief description of what it displays
+ - Whether it needs navigation parameters
+
+2. Read an existing screen as reference (e.g., `DashboardScreen.kt`)
+
+3. Create the new screen file following the pattern
+
+## Screen Template
+
+```kotlin
+package com.matedroid.ui.screens.{feature}
+
+import androidx.compose.foundation.layout.*
+import androidx.compose.material3.*
+import androidx.compose.runtime.*
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import com.matedroid.R
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+fun {Feature}Screen(
+ onNavigateBack: () -> Unit,
+ modifier: Modifier = Modifier
+) {
+ Scaffold(
+ topBar = {
+ TopAppBar(
+ title = { Text(stringResource(R.string.{feature}_title)) },
+ navigationIcon = {
+ IconButton(onClick = onNavigateBack) {
+ Icon(
+ imageVector = Icons.AutoMirrored.Filled.ArrowBack,
+ contentDescription = stringResource(R.string.back)
+ )
+ }
+ }
+ )
+ }
+ ) { paddingValues ->
+ Column(
+ modifier = modifier
+ .fillMaxSize()
+ .padding(paddingValues)
+ .padding(16.dp)
+ ) {
+ // Screen content here
+ }
+ }
+}
+```
+
+## After Creating the Screen
+
+1. Add string resources for the screen title using the translate skill
+2. Add navigation route to the app's navigation graph
+3. Remind the user to wire up the navigation
+
+## Common Patterns
+
+### Loading State
+```kotlin
+var isLoading by remember { mutableStateOf(true) }
+
+if (isLoading) {
+ CircularProgressIndicator()
+} else {
+ // Content
+}
+```
+
+### API Data Fetching
+```kotlin
+LaunchedEffect(Unit) {
+ // Fetch data from TeslamateApiService
+}
+```
+
+### Pull to Refresh
+```kotlin
+val pullRefreshState = rememberPullToRefreshState()
+PullToRefreshBox(state = pullRefreshState, isRefreshing = isRefreshing) {
+ // Content
+}
+```
+
+### Cards
+```kotlin
+Card(
+ modifier = Modifier.fillMaxWidth(),
+ colors = CardDefaults.cardColors(
+ containerColor = MaterialTheme.colorScheme.surfaceVariant
+ )
+) {
+ // Card content
+}
+```
diff --git a/.claude/skills/release/SKILL.md b/.claude/skills/release/SKILL.md
new file mode 100644
index 0000000..136c0ad
--- /dev/null
+++ b/.claude/skills/release/SKILL.md
@@ -0,0 +1,82 @@
+---
+name: release
+description: Create a new release. Bumps version, updates changelog, creates fastlane changelog, commits, tags, and pushes.
+allowed-tools: Read, Edit, Write, Bash, Glob
+---
+
+# Release Skill
+
+Create a new release for MateDroid.
+
+## Pre-flight Checks
+
+1. Ensure you're on the `main` branch with no uncommitted changes
+2. Verify the `[Unreleased]` section in `CHANGELOG.md` has content to release
+
+## Release Process
+
+### 1. Determine Version
+
+Ask the user what type of release:
+- **patch** (0.10.0 → 0.10.1): Bug fixes only
+- **minor** (0.10.0 → 0.11.0): New features, backwards compatible
+- **major** (0.10.0 → 1.0.0): Breaking changes (requires explicit user confirmation)
+
+### 2. Update Version in build.gradle.kts
+
+Edit `app/build.gradle.kts`:
+- Increment `versionCode` by 1
+- Update `versionName` to the new version
+
+### 3. Update CHANGELOG.md
+
+1. Change `## [Unreleased]` to `## [X.Y.Z] - YYYY-MM-DD` (today's date)
+2. Add a new empty `## [Unreleased]` section above it
+3. Add the new version link at the bottom:
+ ```
+ [X.Y.Z]: https://github.com/vide/matedroid/compare/vPREVIOUS...vX.Y.Z
+ ```
+4. Update the `[Unreleased]` link to compare from the new version
+
+### 4. Create Fastlane Changelog
+
+Create `fastlane/metadata/android/en-US/changelogs/{versionCode}.txt` with the release notes.
+
+Format (max 500 chars for Play Store):
+```
+Added:
+- Feature 1
+- Feature 2
+
+Changed:
+- Change 1
+
+Fixed:
+- Fix 1
+```
+
+Keep it concise - this appears in Play Store and F-Droid.
+
+### 5. Commit and Tag
+
+```bash
+git add -A
+git commit -m "chore: release vX.Y.Z"
+git tag -a vX.Y.Z -m "Release X.Y.Z"
+```
+
+### 6. Push
+
+```bash
+git push origin main
+git push origin vX.Y.Z
+```
+
+### 7. Create GitHub Release
+
+Use `gh release create vX.Y.Z --title "vX.Y.Z" --notes-file -` with the changelog content.
+
+The GitHub Actions workflow will automatically:
+- Build APK and AAB
+- Upload to GitHub release
+- Deploy to Google Play (alpha track)
diff --git a/.claude/skills/translate/SKILL.md b/.claude/skills/translate/SKILL.md
new file mode 100644
index 0000000..e1171e7
--- /dev/null
+++ b/.claude/skills/translate/SKILL.md
@@ -0,0 +1,70 @@
+---
+name: translate
+description: Add a new translatable string to all locale files (English, Italian, Spanish, Catalan). Use when adding user-visible text to the app.
+allowed-tools: Read, Edit
+---
+
+# Translate Skill
+
+Add a new string resource to all 4 locale files.
+
+## String Resource Files
+
+| Locale | File |
+|---------|-----------------------------------------------|
+| English | `app/src/main/res/values/strings.xml` |
+| Italian | `app/src/main/res/values-it/strings.xml` |
+| Spanish | `app/src/main/res/values-es/strings.xml` |
+| Catalan | `app/src/main/res/values-ca/strings.xml` |
+
+## Process
+
+1. Ask the user for:
+ - The string name (use `snake_case`, e.g., `drive_details_title`)
+ - The English text
+ - Context for translators (optional but recommended)
+
+2. Generate translations for Italian, Spanish, and Catalan
+
+3. Add to all 4 files with an XML comment for context:
+ ```xml
+
+ Drive Details
+ ```
+
+## Guidelines
+
+- Use `snake_case` for string names (e.g., `settings_title`, `drive_history`)
+- Add XML comments above strings to provide context for translators
+- Technical terms like AC, DC, kW, kWh should NOT be translated
+- Format specifiers (`%s`, `%d`, `%1$s`) must be preserved in translations
+- Keep translations natural - don't be overly literal
+
+## String with Parameters
+
+For strings with parameters, use positional format specifiers:
+```xml
+%1$d km away
+```
+
+In Kotlin:
+```kotlin
+stringResource(R.string.distance_km, distance)
+```
+
+## Plurals
+
+For quantity strings, use plurals:
+```xml
+
+ - %d day
+ - %d days
+
+```
+
+## After Adding Strings
+
+Remind the user to use `stringResource(R.string.xxx)` in Compose code:
+```kotlin
+Text(stringResource(R.string.drive_details_title))
+```
diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..dc92f8c
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,5 @@
+# Copy this file to .env and fill in your values
+# Used by Claude Code skills (check-api)
+
+# Your Teslamate API URL (e.g., https://teslamate-api.example.com)
+TESLAMATE_API_URL=
diff --git a/.gitignore b/.gitignore
index 529eb04..4fbefd3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,7 +17,7 @@
bin/
gen/
out/
-release/
+/release/
# Gradle files
.gradle/
@@ -95,3 +95,6 @@ mockups/
# Logo source files (generated icons are in res/mipmap-*)
matedroid-logo*.png
+
+# Local environment configuration
+.env