Skip to content

feat: profile images and accent colors from OEM defaults #329

@hessius

Description

@hessius

Summary

Integrate profile default images and accent colors from the MeticulousHome ProfileDefaultImages repository to enrich the profile browsing and creation experience.

Background

The OEM provides 25 curated profile thumbnail images (PNG, 106-254KB each) and an accent_colors.json that maps image MD5 hashes to hex accent colors. These are used on the machine dial UI to give each profile a distinct visual identity.

Behaviour

Profile Cards (Catalogue & History)

Current: Profile cards show the profile name on a plain background.
After: Profile cards display the profile's assigned thumbnail image as a background with the accent color as a subtle gradient overlay. Cards without an assigned image use the current plain style.

Visual example:

┌──────────────────────┐
│  [thumbnail image]    │  ← Profile image as card background
│                       │     (dimmed 40% in dark mode)
│  ══════════════════  │  ← Gradient fade to accent color
│  Slow-Mo Blossom     │  ← Profile name over accent color bar
│  ⏱ 4:30  ☕ 36g      │  ← Metadata
└──────────────────────┘

Profile Creation (AI-generated)

When Gemini creates a new profile:

  1. Backend picks the most appropriate default image based on profile characteristics:
    • Espresso-based → espresso thumbnail
    • Pour-over style → pour-over thumbnail
    • Filter/long brew → filter thumbnail
    • Fallback → generic coffee thumbnail
  2. The accent color from accent_colors.json is applied automatically
  3. User can change image/color in profile editor

Profile Editor

New "Appearance" section:

  • Image picker: Grid of available thumbnails (25 defaults + any user-uploaded)
  • Accent color: Color picker pre-populated from the image's mapped accent color
  • Preview: Live preview of how the card will look
  • Custom upload: Option to upload a custom image (cropped to standard dimensions)

Settings View

Profile list entries show a small circular thumbnail (24px) next to the profile name, using the accent color as a ring border.

How Accent Colors Work

The OEM maps images to colors via MD5 hash:

{
  "a1b2c3d4...": "#8B4513",
  "e5f6g7h8...": "#2E8B57"  
}

When a profile has an image URI reference matching a known image, we look up its MD5 → accent color. This color is used for:

  • Card gradient overlay
  • Profile name background tint
  • Settings list avatar ring
  • Brew screen accent highlight

Data Source

  • Images: Bundled at build time from ProfileDefaultImages repo (or fetched on first load in direct mode)
  • accent_colors.json: Bundled alongside images
  • Storage: public/images/profiles/ in web app, served statically

Implementation

Backend

  1. Clone ProfileDefaultImages at Docker build time (like we do for espresso-profile-schema)
  2. Serve images via static file route: GET /api/profile-images/{filename}
  3. Expose GET /api/profile-images/manifest returning image list + accent colors
  4. Add image and accentColor fields to profile metadata in AI generation

Frontend

  1. Bundle default images in public/images/profiles/
  2. New component: ProfileThumbnail — renders image with accent color overlay
  3. Update ProfileCard to use ProfileThumbnail background
  4. New component: ImagePicker — grid selector for profile editor
  5. Color utility: getAccentColor(imageHash) lookup
  6. Update profile creation flow to assign default image
  7. Lazy-load images (IntersectionObserver) for performance
  8. i18n keys for image picker labels (6 locales)

Profile Schema Extension

Add optional fields to profile metadata:

interface ProfileDisplay {
  image?: string        // URI reference to thumbnail
  accentColor?: string  // #RRGGBB hex color
  shortDescription?: string  // ≤100 chars (already in schema)
}

Acceptance Criteria

  • 25 default profile images bundled and served
  • Accent colors loaded from manifest
  • Profile cards show thumbnail + accent color when available
  • Profile editor has image picker
  • AI-generated profiles get a default image assigned
  • Images lazy-loaded for performance
  • Graceful fallback when no image assigned
  • Dark mode: images dimmed, accent colors adjusted
  • i18n for all 6 locales
  • Tests for accent color lookup and image manifest

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions