Project Phoebe
Published in

Project Phoebe

Mutate More: Digging Deeper Into UI That Evolves With the User

Project Phoebe Phase 2

What it feels like to use a mutative app

One of the questions I got a lot after the introduction of Phoebe was about actually using a mutative interface. Several people noted — correctly — that having an interface change every time you use it would be stressful, annoying, or confusing for the user.

Hello Selene

One way to do this is demonstrated through the contrast mutation in Selene.

  1. We could stop the mutation from happening until the user turns their screen on and off or
  2. The changes could continue to happen on the fly, but the mutation would happen more slowly.

Changes between app use

The contrast mutation is ephemeral, meaning it isn’t permanent, and only happens in short durations (on the fly as the user uses the app). Many mutations could be ephemeral, adapting to temporary realities or extra-characteristic states.

Gaia: Mutation as a platform

For Selene, we intentionally chose two specific mutations to implement first, but ultimately if we’re consciously deciding as designers and developers that we know which mutations will be comfortable for every user, we have avoided the problem that mutative design looks to solve.

Gaia + Selene

But that vision of Gaia is far into the future. So what does Gaia look like in our sample app, Selene?

// makes sure it doesn't go too bright
public final static float HIGH_THRESHOLD = 0.8f;
// makes sure it doesn't go too dark
public final static float TOLERABLE_THRESHOLD = 0.2f;
public final static float LOW_THRESHOLD = 0.05f;
public final static float MIN = 0.0f;

* @param sensor object coming from our bus containing the Ambient Light sensor value
* @param mutativeObject the object that'll be mutated
* @param colorToScale the current color of the mutative object
* @return a new HSV value to be applied into the object
public static float[] computeHSV(AmbientLightSensorChange sensor, Object mutativeObject, int colorToScale) {
// we divide the color into red green and blue
int red =;
int green =;
int blue =;

final float hsv[] = new float[3];

Color.RGBToHSV(red, green, blue, hsv);

// 'magic' algorithm
float div = Float.valueOf(String.format(Locale.getDefault(), "%.2f",
sensor.getLight() / ((int) SensorManager.LIGHT_OVERCAST >> 1)));

if (div > HIGH_THRESHOLD) {
} else if (div < LOW_THRESHOLD) {
div = MIN;

// Text is, by rule, in a contrasted color to the background, so we have to apply the formula backwards to the
// rest of the views
if (mutativeObject instanceof TextView) {
hsv[2] += div;
} else {
hsv[2] -= div;

// making sure we don't have a weird negative value
hsv[2] = Math.max(hsv[2], TOLERABLE_THRESHOLD);

return hsv;

Designing for Gaia

Ephemeral mutations as onboarding

The best onboarding is no onboarding — introductions to an app can become lengthy, boring, and — for existing users — annoying. Ideally users learn about the interface organically, accomplishing their tasks with minimal effort.

Dark patterns

Of course there’s the potential for evil here too, or so-called “dark patterns” of UI — it’s easy to imagine for example that a custom mutation (so, if we’re living in the future where Gaia is implemented at the OS level, a mutation that lives outside Gaia) could destroy a user’s muscle memory by for instance switching two buttons with the goal being to increase engagement on one or the other.

Until then…

Until we reach consensus on initial patterns for designing and building mutative interfaces, more experimentation and research remain to be done.



Updates on Project Phoebe, a first exploration of mutative design

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store