Skip to content

feat: Material You (Android) CSS theme for native feel on Android devices #291

@hessius

Description

@hessius

Problem

Companion to #288 (iOS theme) — Android users expect Material Design conventions. MeticAI should feel native on both platforms when running as a web app or future Capacitor app (#253).

Proposed Solution

Add an optional Material You–inspired CSS theme layer that activates on Android devices:

Platform Detection

  • Detect Android via navigator.userAgent
  • Apply .material-theme class to root element
  • Auto-detect by default; manual override in Settings (same toggle as iOS: Auto / iOS / Material / Off)

CSS Changes (layered on existing light/dark themes)

Property Current Material Theme
Font family System default Roboto, "Google Sans", system-ui, sans-serif
Border-radius --radius (8px) 12px cards, 20px FAB-style buttons (pill shape)
Elevation Flat borders box-shadow layers (Material elevation tokens)
Ripple effect None CSS ripple on tap (::after pseudo-element)
Toggle switches shadcn default Material 3 style (thumb + track, tonal colors)
Color system Custom gold/espresso Adapt to Material 3 tonal palette (keep gold as primary)
FAB hint None Primary action button gets FAB-like prominence
Motion Fade transitions Material motion (emphasized easing, shared axis)
Active states Opacity State layers (8% opacity overlay on hover, 12% on press)
Typography Default scale Material type scale (titleLarge, bodyMedium, etc.)

Implementation Approach

.material-theme {
  --font-family: "Roboto", "Google Sans", system-ui, sans-serif;
  --radius: 12px;
  --button-radius: 20px;
  --elevation-1: 0 1px 2px rgba(0,0,0,0.3), 0 1px 3px 1px rgba(0,0,0,0.15);
  --elevation-2: 0 1px 2px rgba(0,0,0,0.3), 0 2px 6px 2px rgba(0,0,0,0.15);
}

.material-theme button {
  position: relative;
  overflow: hidden;
}

/* Material ripple effect */
.material-theme button::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at var(--ripple-x, 50%) var(--ripple-y, 50%),
    currentColor 0%, transparent 60%);
  opacity: 0;
  transition: opacity 0.3s;
}

.material-theme button:active::after {
  opacity: 0.12;
}

/* Material 3 state layers */
.material-theme button:hover {
  background-image: linear-gradient(currentColor 8%, transparent 8%);
}

Shared Settings Toggle (with #288)

[Platform Theme]  [Auto-detect ▾]
                  [iOS]
                  [Material]
                  [None]

Key Files

  • apps/web/src/index.css — Main styles
  • apps/web/src/styles/theme.css — CSS variables
  • apps/web/src/hooks/use-mobile.ts — Extend with Android detection
  • apps/web/src/components/ui/ — shadcn/ui component overrides
  • apps/web/src/components/SettingsView.tsx — Shared platform theme toggle with feat: iOS-inspired CSS theme for native feel on Apple devices #288

Scope

Acceptance Criteria

  • Android devices automatically get the Material theme
  • Theme selectable via Settings (shared dropdown with iOS option from feat: iOS-inspired CSS theme for native feel on Apple devices #288)
  • Works with both light and dark modes
  • Does not affect non-Android devices (unless manually selected)
  • Ripple/state layer effects on interactive elements
  • Material 3 elevation shadows on cards
  • Material-style toggle switches
  • No layout shifts or visual regressions on desktop

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