# AGENTS.md — Mundi
<!-- Auto-generated by codebase-summary. See Custom Instructions section for manually maintained content. -->

## Project Overview
<!-- metadata: scope=orientation -->

Mundi is a geography learning application for GNOME. Users explore interactive SVG maps in discovery mode and take timed quizzes identifying regions, countries, capitals, and rivers. Built with Rust, GTK4 4.14+, and libadwaita 1.5+.

**Key entry points**: `src/main.rs` → `MundiApplication` → `MundiWindow` → `MapExerciseView`

## Directory Map
<!-- metadata: scope=navigation -->

```
src/                        # All Rust source
  main.rs                   # Entry point, i18n init, GResource registration
  application.rs            # App lifecycle, global actions (quit/preferences/about)
  window.rs                 # Main window, country list, AdwNavigationView root
  registry.rs               # Static country/exercise catalog — add new content here
  region_names.rs           # Translatable region name constants (N_() macro)
  map_widget.rs             # Custom GskPath SVG renderer + hit detection (no Cairo)
  map_exercise_view.rs      # Quiz/discovery controller, timer, sound integration
  quiz.rs                   # Quiz state machine (pure logic, no GTK)
  quiz_results_view.rs      # Score display + leaderboard UI
  leaderboard.rs            # JSON persistence for high scores (top 50)
  sound_player.rs           # GtkMediaFile wrapper (correct/wrong/music)
  preferences_dialog.rs     # Sound effects toggle (GSettings-bound)
resources/
  maps/{country}/*.svg      # SVG maps (18 files across 14 directories)
  ui/*.ui                   # GTK Builder XML templates (4 files)
  sounds/                   # correct.oga, wrong.oga, quiz-music.oga
  style.css                 # Named colors for map region states
  resources.gresource.xml   # GResource manifest
data/
  *.gschema.xml             # GSettings schema (settings + relocatable stats)
  *.metainfo.xml            # AppStream metadata with release history
  *.desktop.in              # Desktop entry template
  icons/                    # App icon (SVG, GNOME HIG palette)
po/                         # Translations: es, fr, gl, it, pl
build.rs                    # Config generation + GResource compilation
```

## Architecture Patterns
<!-- metadata: scope=patterns -->

**GObject subclass pattern**: Every UI component uses `mod imp` with `#[derive(gtk::CompositeTemplate)]`, `ObjectSubclass`, and `glib::wrapper!`. Templates are XML files in `resources/ui/`.

**Data-driven registry**: Countries and exercises are static data in `registry.rs`. Adding content requires no new types — only data entries, SVG maps, and region name constants.

**SVG rendering (no Cairo)**: `MapWidget` parses SVG with `quick-xml`, creates `GskPath` objects, renders via `snapshot.append_fill()`/`append_stroke()`. Hit detection uses `GskPath::in_fill()` and `closest_point()`.

**SVG ID conventions**:
- `id="Name"` — clickable region
- `id="_bg_Name"` — background outline (capitals exercises)
- `id="__anything"` — decorative (non-interactive)
- `id="_river_Name"` — river (stroke-rendered)
- Path data: absolute `M L Z` only (no curves, no transforms)

**Navigation**: `AdwNavigationView` with programmatic page pushing: Country list → Exercise list → `MapExerciseView`

## Key Interfaces
<!-- metadata: scope=signals-settings -->

**Signals**: `MapWidget::region-clicked(String)` — sole map→controller channel. `QuizResultsView::retry` — triggers new quiz.

**GSettings**: `io.github.nacho.mundi` (sound-effects), `.state.window` (size, maximized), `.stats` (relocatable: correct/total per exercise at path `/io/github/nacho/mundi/stats/{country}/{exercise}/`)

**CSS colors**: `map-region-color`, `map-region-highlight-color`, `map-region-correct-color`, `map-region-wrong-color`, `map-border-color` — all reference Adwaita named colors, auto-adapt to light/dark.

## Scoring
<!-- metadata: scope=quiz-logic -->

3 attempts per question. Points awarded = attempts remaining (3/2/1/0). Total possible = regions × 3. Leaderboard ranks by score desc, then time asc. Top 50 per exercise, stored as JSON in `$XDG_DATA_HOME/mundi/`.

## Adding Content
<!-- metadata: scope=extension -->

**New country/exercise**: (1) Create SVG in `resources/maps/{country}/`, (2) add region names in `region_names.rs`, (3) register in `registry.rs`, (4) add to `resources.gresource.xml`.

**Capitals exercise**: SVG uses `_bg_` prefix for outlines, 1×1 path squares for dots. Set `kind: ExerciseKind::Capitals`. Use `alternates` for dual capitals.

## CI & Config from Files
<!-- metadata: scope=ci-config -->

**CI** (`.github/workflows/ci.yml`): On push/PR to `main` — `cargo fmt --check` → `cargo clippy -D warnings` → `cargo build` → `cargo test` → `meson setup + compile`.

**Build-time config**: `build.rs` generates `config.rs` from `src/config.rs.in` via `@VAR@` substitution (env vars from Meson, or hardcoded defaults for Cargo dev builds).

## Detailed Documentation

For deeper information, see `.agents/summary/index.md` which indexes:
- `architecture.md` — type hierarchy, rendering pipeline, build system
- `components.md` — all GTK4 subclasses and logic components
- `interfaces.md` — signals, GSettings schema, GResource paths, public APIs
- `data_models.md` — structs, enums, persistence formats
- `workflows.md` — startup, quiz lifecycle, leaderboard, release process
- `dependencies.md` — all Cargo/system deps with purposes

## Custom Instructions
<!-- This section is for human and agent-maintained operational knowledge.
     Add repo-specific conventions, gotchas, and workflow rules here.
     This section is preserved exactly as-is when re-running codebase-summary. -->

### Development Workflow
- **ALWAYS run `cargo fmt` before committing**
- Run `cargo clippy` to check for warnings
- Development: `glib-compile-schemas data/ && GSETTINGS_SCHEMA_DIR=data cargo run`
- Production: `meson setup builddir && meson compile -C builddir`

### Release Process
1. Update version in `Cargo.toml`, `meson.build`, and `snap/snapcraft.yaml`
2. Add release entry in metainfo XML with version, date, and changelog
3. `cargo fmt && cargo update -p mundi`
4. `git commit -am "Release X.Y.Z" && git tag vX.Y.Z && git push && git push --tags`

### Code Conventions
- No Cairo — use GskPath for all map rendering and hit detection
- All user-visible strings must be translatable via gettext
- Region names use `N_()` for extraction, `gettext()` at runtime
- Separate UI templates (XML) from logic (Rust)
- Application icon MUST follow GNOME HIG palette
- Keep dependencies minimal and well-justified

### AI Assistant Guidelines
- Prioritize GTK4/Adwaita best practices
- Suggest modern Rust patterns appropriate for GUI applications
- Consider both development (Cargo) and production (Meson) build workflows
- Focus on GNOME HIG compliance for UI suggestions
- Keep code concise and maintainable
- Always remind about running `cargo fmt` before commits
