ROSE helps sustainability managers collect data and comply with regulations.

ROSE helps sustainability managers collect data and comply with regulations.

but to understand the progress of a reporting project, users had to compare multiple tabs, causing confusion and fear.

but to understand the progress of a reporting project, users had to compare multiple tabs, causing confusion and fear.

The good ending

The good ending

100 % customer independence for key platform interaction.

100 % customer independence for key platform interaction.

Improved time to clarity: few clicks to identifying “what’s missing?” for a given timeframe.

Improved time to clarity: few clicks to identifying “what’s missing?” for a given timeframe.

Hours of customer support work per week reduced by automating progress status and communication.

Hours of customer support work per week reduced by automating progress status and communication.

"the coverage tool is really nice as a good overeview on whether data coverage is complete or not for different timeframes"

"the coverage tool is really nice as a good overeview on whether data coverage is complete or not for different timeframes"

Sid, key active customer

Sid, key active customer

The team

The team

Johannes (CTO)

Johannes (CTO)

Thais (CEO)

Thais (CEO)

Lorenzo (CS)

Lorenzo (CS)

Kseniia (Eng)

Kseniia (Eng)

Why this problem?

Why this problem?

At the time, we were laying the groundwork for a new product direction, moving ROSE from consulting-led to product-led. To navigate the ambiguity of this shift, I collaborated with the CTO and team to define key outcomes that would guide our first steps. One of the most important was increasing customer independence and reducing dependency on consulting support.

We prioritized solving this problem, since it was connected to the core jobs our users had: "what is missing?" and "where do I start?"

At the time, we were laying the groundwork for a new product direction, moving ROSE from consulting-led to product-led. To navigate the ambiguity of this shift, I collaborated with the CTO and team to define key outcomes that would guide our first steps. One of the most important was increasing customer independence and reducing dependency on consulting support.

We prioritized solving this problem, since it was connected to the core jobs our users had: "what is missing?" and "where do I start?"

The previous solution

The previous solution

Data collection progress was tracked outside the platform manually using a huge excel sheet, containing many datapoints and manually updated by Lorenzo and the customers.

We didn't have the appetite to build something this complex, so the challenge was how to arrive at a meaningful progress view without it containing this level of detail.

Data collection progress was tracked outside the platform manually using a huge excel sheet, containing many datapoints and manually updated by Lorenzo and the customers.

We didn't have the appetite to build something this complex, so the challenge was how to arrive at a meaningful progress view without it containing this level of detail.

Shaping for our appetite

Shaping for our appetite

I led a shaping session with Lorenzo and Kseniia, to sketch a minimal solution to bet on that would fit our two weeks appetite from a technical perspective.

We understood we could build a minimal yet impactful progress view with 3 ingredients: Operation ID, the relevant data categories for it, and the collectors that exist for them.

I led a shaping session with Lorenzo and Kseniia, to sketch a minimal solution to bet on that would fit our two weeks appetite from a technical perspective.

We understood we could build a minimal yet impactful progress view with 3 ingredients: Operation ID, the relevant data categories for it, and the collectors that exist for them.

Choosing who to optimize for

Choosing who to optimize for

Since we wanted to start with the minimal complexity, we had to optimizing one out for two different use cases:
One optimized for operation based progress, and the other for global resource based progress.

Since our target customers were managing their operation's data locally, we prioritized an operation based approach.

Since we wanted to start with the minimal complexity, we had to optimizing one out for two different use cases:
One optimized for operation based progress, and the other for global resource based progress.

Since our target customers were managing their operation's data locally, we prioritized an operation based approach.

A new icon set

A new icon set

Since this view was data rich, I wanted to improve readability by creating a new icon set for each energy data type, allowing users to scan the view easily.

Since this view was data rich, I wanted to improve readability by creating a new icon set for each energy data type, allowing users to scan the view easily.

Interaction explorations

Interaction explorations

Another exploration was about the progress bar's on-hover modals, starting with minimal ways of communicating what data is collected and what is missing.

Another exploration was about the progress bar's on-hover modals, starting with minimal ways of communicating what data is collected and what is missing.

I've decided to go with a component that would cover the whole timeframe, instead of a month based modal, to allow a full understanding of you progress in one interaction.

I've decided to go with a component that would cover the whole timeframe, instead of a month based modal, to allow a full understanding of you progress in one interaction.

The coverage view

The coverage view

Piecing everything together, I designed a progress view anchored by operations, communicating completeness and calling for action using our new design system's color logic.

Piecing everything together, I designed a progress view anchored by operations, communicating completeness and calling for action using our new design system's color logic.

Setting the little things right

Setting the little things right

At the time we shipped this feature, we we're also moving away from our old design system into the new one I was building, so when we implemented our previous "Show archived" toggle component, it looked broken and confusing.

I opened Cursor, updated the component, and shipped
it to production.

At the time we shipped this feature, we we're also moving away from our old design system into the new one I was building, so when we implemented our previous "Show archived" toggle component, it looked broken and confusing.

I opened Cursor, updated the component, and shipped
it to production.

<SwitchPrimitives.Root
  ref={ref}
  {...props}
  className={cn(
    "group relative inline-flex items-start",
    // Vars
    "[--thumb:14px] [--spacer:2px]",
    // Track height = thumb + 2*pad
    "h-[calc(var(--thumb)+var(--spacer)*2)]",
    // Track width = thumb*2 + gap + 2*pad
    "w-[calc(var(--thumb)*2+var(--spacer)*3)]",
    "rounded-full transition-colors",

    props.checked
    ? "bg-indigo-600"
    : "bg-stone-200",
    
    className
  )}
>
  <SwitchPrimitives.Thumb
    className={cn(
      "pointer-events-none absolute left-[var(--spacer)] top-1/2 bg-white",
      "h-[var(--thumb)] w-[var(--thumb)] -translate-y-1/2 rounded-full shadow",
      "transition-transform duration-150 ease-out will-change-transform",

      props.checked
      ? "translate-x-[calc(var(--spacer)+var(--thumb))]"
      : "translate-x-0"
    )}
  />
</SwitchPrimitives

<SwitchPrimitives.Root
  ref={ref}
  {...props}
  className={cn(
    "group relative inline-flex items-start",
    // Vars
    "[--thumb:14px] [--spacer:2px]",
    // Track height = thumb + 2*pad
    "h-[calc(var(--thumb)+var(--spacer)*2)]",
    // Track width = thumb*2 + gap + 2*pad
    "w-[calc(var(--thumb)*2+var(--spacer)*3)]",
    "rounded-full transition-colors",

    props.checked
    ? "bg-indigo-600"
    : "bg-stone-200",
    
    className
  )}
>
  <SwitchPrimitives.Thumb
    className={cn(
      "pointer-events-none absolute left-[var(--spacer)] top-1/2 bg-white",
      "h-[var(--thumb)] w-[var(--thumb)] -translate-y-1/2 rounded-full shadow",
      "transition-transform duration-150 ease-out will-change-transform",

      props.checked
      ? "translate-x-[calc(var(--spacer)+var(--thumb))]"
      : "translate-x-0"
    )}
  />
</SwitchPrimitives

Shipping and learnings

Shipping and learnings

After shipping, this coverage view became our go-to page for progress discussions, reducing hours of manual CS work each week.

The impact pushed us toward our current work: using AI to empower customers to build their own dashboards and process data. I designed and iterated the prompt engineering that guides our AI to generate dashboards consistent with our design system. This reduced setup effort for customers and moved us closer to our goal of full product-led independence.

After shipping, this coverage view became our go-to page for progress discussions, reducing hours of manual CS work each week.

The impact pushed us toward our current work: using AI to empower customers to build their own dashboards and process data. I designed and iterated the prompt engineering that guides our AI to generate dashboards consistent with our design system. This reduced setup effort for customers and moved us closer to our goal of full product-led independence.