Why I don't Sleep

Why I don't Sleep
Photo by Steve Johnson / Unsplash

This morning, 4:30AM, I woke up thinking:

Wouldn't it be cool if to set the AI's personality, there was a color mixer controller, kind of like what Paper-app had (before Evernote ruined the app) and like a color grading control in film?

Then I couldn't get back to sleep. So, like any sane human, I got some coffee and went to my office and woke up my AI minions.

What follows below is the chat in Claude Code, just cleaned up (by Claude desktop!) for readability. First, this is the end result. This will be part of how users will set the tone/voice of any AI generated content in DormWay, as well as setting the mix between emphasis on academics/wellness/fitness/leisure, etc.

Start to finish, this took one hour. It is also now open source. Read on.

0:00
/0:24

Building a Personality Mixer Control for DormWay

The Initial Concept

Me: I want to experiment with making a SwiftUI component to use to set personality of an AI agent. The idea is its like a color mixer. A circle where top, left, right, bottom are "traits" represented by a color, and the user can slide a dot within the circle, "mixing" between these traits (and their colors) to make a unique personality.

Claude: I'll help you create a SwiftUI component for mixing AI personality traits using a color mixer interface. Let me build this as a reusable component.

[Claude created the initial PersonalityMixer.swift with 251 lines of code, implementing a circular interface with draggable selector and color blending logic]

The initial implementation included:

  • A circular interface with 4 traits at cardinal positions
  • A draggable selector dot
  • Real-time color blending based on position
  • Percentage display showing the weight of each trait

First Refinement: Visual Hierarchy

Me: OK, but the text needs to be outside the circle, and the color OF the circle needs to be based on the blend

Claude: I'll fix the component so the trait labels are outside the circle and the circle itself shows the blended color.

This update moved the trait labels outside the circle and made the entire circle fill with the blended color based on the selector position.

Color Blending Logic

Me: The gray circle should, for instance, if analytical is at 93% and empathetic at 35%, be 93% blue and 35% red. The little dot needs to be able to move the full radius of the big circle as well, since it'll be thumb controlled.

Claude: I'll fix the color blending to use the actual trait colors and allow the dot to move to the full edge of the circle.

Key improvements:

  • Proper color blending using actual trait colors with weights
  • Selector dot can now reach the circle's edge for easier thumb control
  • Additive color mixing (like mixing lights)

Inverting the Color Scheme

Me: lets invert so the middle is white?

Claude: I'll update the color blending so the center is white and colors get stronger as you move towards the edges.

The updated blending logic:

private var blendedColor: Color {
    // Start with white
    var red: Double = 1.0
    var green: Double = 1.0  
    var blue: Double = 1.0
    
    // Calculate total influence (distance from center)
    let totalInfluence = sqrt(localPosition.x * localPosition.x + localPosition.y * localPosition.y)
    
    // Blend between white (center) and the mixed color (edges)
    if totalInfluence > 0 {
        // ... color mixing logic
    }
    
    return Color(red: red, green: green, blue: blue)
}

Adding Visual Polish

Me: That's perfect. I wonder if there's some aesthetic punch ups, like some subtle vignetting on the edges of the big circle, drop shadow on the thumb/small circle? or even a subtle "liquid" effect like its blending paint?

Claude: I'll add some aesthetic enhancements to make the component more visually appealing with vignetting, shadows, and a liquid paint effect.

The visual enhancements included:

  • Angular gradient vignette around edges
  • Dual shadows (black for depth + colored shadow matching blend)
  • Animated ripple circles for liquid effect
  • Glossy highlight gradients

Typography Enhancement

Me: That looks fantastic, but now the text is really bland. What can we do with that

Claude: Let's enhance the trait labels to match the polished aesthetic of the mixer.

Added dynamic text effects:

  • Glow effect when traits are active
  • Dynamic scaling based on selection weight
  • Gradient fills using trait colors
  • Spring animations

Solving Layout Issues

Me: yeah, but the right and left ones are horizontal which puts them off screen

Claude: You're right! Let me fix the positioning of the left and right labels so they stay on screen.

Me: no, didn't work. Analytical needs to be rotated 45 right, Practical 45 left

The solution was to rotate the side labels:

private func labelRotation(for position: PersonalityTrait.Position) -> Angle {
    switch position {
    case .top, .bottom:
        return .zero
    case .right:
        return .degrees(-45)
    case .left:
        return .degrees(45)
    }
}

Moving to Icons

Me: OK.. that's kind of better, but still.... is there any more clever way of integrating the text?

Claude: [Implemented colored dots with abbreviated text]

Me: Lets actually use SF symbols! I love this, but don't love the three letter thing. Creative: paintpalette, analytical: function, empathetic: heart, practical: clock

The final trait structure:

let traits = [
    PersonalityTrait(name: "Creative", color: .purple, icon: "paintpalette", position: .top),
    PersonalityTrait(name: "Analytical", color: .blue, icon: "function", position: .right),
    PersonalityTrait(name: "Empathetic", color: .pink, icon: "heart", position: .bottom),
    PersonalityTrait(name: "Practical", color: .green, icon: "clock", position: .left)
]

Adding Data Visualization

Me: then maybe for the blend display on the bottom, we make really good use of SwiftCharts dynamically?

Claude: [Implemented a dynamic bar chart using SwiftCharts]

Me: there are better ways to show percentages though. Pie? And it'd be cool if the percentage view was a detail view that could "slide" from under the main control, not be visible the whole time?

The final implementation included:

  • A hidden-by-default pie chart
  • Smooth slide-out animation
  • Toggle button to show/hide details
  • Donut chart design with dominant trait highlight

Perfecting the Animation

Me: Love it, but the detail card is sliding from top of screen. It should slide down from, and scale out from the center of the control

Claude: You're right! Let me fix the animation so the detail card slides down and scales from the center of the mixer control.

PersonalityPieChart(traits: traits, weights: traitWeights)
    .scaleEffect(showDetails ? 1 : 0.3)
    .opacity(showDetails ? 1 : 0)
    .offset(y: showDetails ? 340 : 0)

Me: That is awesome. But its now covering the bottom half of the mixer

Claude: [Final adjustment to position the detail card below the mixer without overlap]

The Result

The final PersonalityMixer component features:

  • A visually stunning circular interface with liquid paint aesthetics
  • SF Symbol indicators for each trait
  • Smooth color blending from white center to trait colors at edges
  • Professional visual effects (vignetting, shadows, highlights)
  • An optional slide-out pie chart for detailed percentages
  • Fully gesture-driven interface optimized for thumb control

This component will be perfect for DormWay's AI assistant personality customization, allowing students to create their ideal AI companion through an intuitive, visually appealing interface.