[{"_1":2},"routes/case-study",{"_3":4},"data",{"_5":6,"_7":8,"_9":10,"_11":12},"unlocked",false,"pub",{"_16":420,"_18":107,"_20":421,"_22":170,"_24":422,"_26":529,"_28":424,"_36":426,"_38":427,"_428":429,"_40":177,"_42":430,"_530":531,"_532":533,"_534":535,"_536":537,"_538":539,"_540":541,"_542":-7,"_543":544,"_545":546,"_547":548,"_549":550},"meta",{"_16":420,"_18":107,"_20":421,"_22":170,"_24":422,"_26":423,"_28":424,"_322":420,"_34":425,"_36":426,"_38":427,"_428":429,"_40":177,"_42":430,"_179":327,"_431":432,"_44":433},"more",[13,14,15],{"_16":316,"_18":99,"_20":317,"_22":318,"_24":319,"_26":320,"_28":321,"_322":316,"_34":323,"_36":324,"_38":325,"_40":177,"_42":326,"_179":327,"_44":328},{"_16":168,"_18":92,"_20":169,"_22":170,"_24":171,"_26":172,"_28":29,"_30":173,"_34":174,"_36":175,"_38":176,"_40":177,"_42":178,"_179":180,"_44":181},{"_16":17,"_18":19,"_20":21,"_22":23,"_24":25,"_26":27,"_28":29,"_30":31,"_32":33,"_34":35,"_36":37,"_38":39,"_40":41,"_42":43,"_44":45},"slug","oroom","order","04","title","From browsing to booking","client","OROOM","discipline","Web design · hospitality","tags",[165,166,167],"cover","stack","loop",{"_77":153,"_154":150,"_155":156,"_81":157,"_83":158,"_159":160},"shot",{"_77":150,"_81":151,"_83":152},"logo",{"_77":145,"_79":23,"_81":146,"_83":147,"_148":149},"accent","#c2186f","accentBright","#f279b4","accentInk","#fdf4f8","cardSummary","A hotel website rebuilt around the decision a guest is actually making — sell the stay, not the room inventory.","head",{"_46":47,"_48":49,"_50":51,"_20":52,"_53":54,"_55":56,"_57":58,"_59":60},"carriesEvidence",true,"context","Hotel website · OROOM · Responsive web","eyebrow","Conversion up 6.4× after the redesign.","From browsing\nto booking","lede","The website wasn’t failing aesthetically — it was failing strategically. Visitors kept asking the one question the site never answered: what am I actually paying for?","proof",[128,129,130,131],"facts",[114,115,116,117],"process",{"_20":61,"_62":63},"One website. Researched, argued for, redesigned, tested.","stages",[64,65,66,67,68],{"_69":107,"_71":108,"_73":109,"_75":110},{"_69":99,"_71":100,"_73":101,"_75":102},{"_69":92,"_71":93,"_73":94,"_75":95},{"_69":19,"_71":85,"_73":86,"_75":87},{"_69":70,"_71":72,"_73":74,"_75":76},"n","05","name","Ship","sub","Responsive, in both languages","art",{"_77":78,"_79":80,"_81":82,"_83":84},"src","/work-assets/oroom/home-after-desktop.webp","alt","The redesigned homepage","width",1814,"height",3083,"Test","Same task, before vs after",{"_77":88,"_79":89,"_81":90,"_83":91},"/work-assets/oroom/calendar-desktop.webp","The master calendar",2000,2192,"03","Design","Wireframes → three moves",{"_77":96,"_79":97,"_81":90,"_83":98},"/work-assets/oroom/wireframes.webp","Wireframes of the redesigned site",998,"02","Define","Three pain points → how might we",{"_77":103,"_79":104,"_81":105,"_83":106},"/work-assets/oroom/google-score.webp","The Google review summary",1630,446,"01","Research","Hotjar recordings + review mining",{"_77":111,"_79":112,"_81":90,"_83":113},"/work-assets/oroom/hotjar-calendar.webp","A Hotjar recording of the old calendar",937,{"_118":126,"_120":127},{"_118":124,"_120":125},{"_118":122,"_120":123},{"_118":119,"_120":121},"label","Scope","value","Research →\nUX → UI →\ndesktop + mobile layouts","Team","CEO\nDevelopers\nMarketing team","Timeline","4 months","Role","Product designer\n& research lead",{"_120":142,"_133":143,"_118":144},{"_120":139,"_133":140,"_118":141},{"_120":136,"_133":137,"_118":138},{"_120":132,"_133":134,"_118":135},"3","unit","more locations","opened since,\non the same design","4.5 → 8.8","average usability score","same task, before vs. after","+44%","engaged sessions","after the redesign","6.4×","conversion rate","from 0.25% to 1.85%","/logos/oroom.png",893,160,"scale",0.85,"/tiles/oroom-rooms-poster.webp",1200,546,"/tiles/oroom-loop.webp","poster","video",{"_161":162,"_163":164},1000,455,"matte","#150515","mp4","/tiles/oroom-loop.mp4","webm","/tiles/oroom-loop.webm","Freelance","End-to-end","Conversion","timesheet","The timesheet kept getting more complicated. The interface didn't have to.","Toggl 2.0","Product design · continuous ownership",[313,314,315],{"_77":298,"_203":299,"_154":300,"_301":302,"_155":303,"_81":304,"_83":304,"_305":306},{"_77":294,"_203":295,"_79":170,"_81":296,"_83":297},"#4A5578","#8B96C4","#FFFFFF","Five months on one surface. As the Timesheet grew from a flat entry grid to four levels of grouping and richer summaries, the work was deciding what people needed to see, and when.","lockNote","Shipped client work. The write-up quotes production internals, so it's shared on request rather than published.",{"_46":47,"_48":182,"_50":183,"_20":184,"_53":185,"_55":186,"_57":187,"_59":188},"Timesheet · Toggl 2.0 · Web app","Five months on one surface.","The timesheet kept getting more complicated.\nThe interface didn’t have to.","From an MVP time-entry surface to grouped rows, deeper hierarchy and richer summaries, I kept evolving the Timesheet as its complexity grew — using research, product critique and production prototypes to decide what users needed to see, and when.",[278,279,280,281],[270,271,272,273],{"_20":189,"_62":190},"One surface. Researched, grouped, tested in the product, shipped.",[191,192,193,194,195,196],{"_69":107,"_71":108,"_73":259,"_199":260,"_261":262},{"_69":99,"_71":246,"_73":247,"_199":248,"_75":249},{"_69":92,"_71":234,"_73":235,"_199":236,"_75":237},{"_69":19,"_71":221,"_73":222,"_199":223,"_75":224},{"_69":70,"_71":213,"_73":214,"_199":215},{"_69":197,"_71":72,"_73":198,"_199":200,"_75":201},"06","Four grouping modes · 31 files · PM + engineering review","item",{"_77":208,"_203":209,"_79":210,"_81":211,"_83":212},{"_77":202,"_203":204,"_79":205,"_81":206,"_83":207},"/tiles/timesheet-story/05-ship.webp","srcDark","/tiles/timesheet-story/05-ship-dark.webp","The merged grouping on realistic data: Apollo Inc. and Northwind Trading with their projects, tasks and first day cells",620,465,"/tiles/timesheet-story/items/tiers.webp","/tiles/timesheet-story/items/tiers-dark.webp","The shipped grouping: Group by Client & project, and the four levels on neutral tiers with compact, quieter logs",572,230,"Extend","Roll-ups, responsive behaviour, more capability",{"_77":216,"_203":217,"_79":218,"_81":219,"_83":220},"/tiles/timesheet-story/05-carry.webp","/tiles/timesheet-story/05-carry-dark.webp","The squeezed sheet: the day columns clipped at Wednesday with the totals column pinned",360,270,"Resolve","Experimental PR → production PR → engineering review",{"_77":229,"_203":230,"_79":231,"_81":232,"_83":233},{"_77":225,"_203":226,"_79":227,"_81":90,"_83":228},"/tiles/timesheet-story/shipped-check-light.png","/tiles/timesheet-story/shipped-check.png","The visual check before merge: the grouped view on realistic data",994,"/tiles/timesheet-story/items/ship.webp","/tiles/timesheet-story/items/ship-dark.webp","Three merged pull requests",187,99,"Explore","Visual hypotheses as live toggles in the product",{"_77":242,"_203":243,"_79":244,"_81":245,"_83":245},{"_77":238,"_203":239,"_79":240,"_81":90,"_83":241},"/tiles/timesheet-story/density-console-light.png","/tiles/timesheet-story/density-console.png","The density console: the visual hypotheses as toggles over the real grouped timesheet",1020,"/tiles/timesheet-story/items/console.webp","/tiles/timesheet-story/items/console-dark.webp","The density console: neutral tiers, compact logs, tree guides and quieter log text as live switches",284,"Diagnose","Four levels, one visual treatment",{"_77":255,"_203":256,"_79":257,"_81":211,"_83":258},{"_77":250,"_203":251,"_79":252,"_81":253,"_83":254},"/tiles/timesheet-story/02-diagnose.webp","/tiles/timesheet-story/02-diagnose-dark.webp","The first grouped timesheet: the Slack group, its tasks and their logs sharing one visual treatment",507,380,"/tiles/timesheet-story/items/levels.webp","/tiles/timesheet-story/items/levels-dark.webp","Four levels of one grouped week — client, project, task, time log — every row in the same treatment",190,"Screener + moderated testing set the entry rules",{"_265":47,"_77":266,"_203":267,"_79":268,"_81":269,"_83":151},"gatedArt",{"_77":263,"_203":264},"/tiles/timesheet-story/01-research-locked.webp","/tiles/timesheet-story/01-research-dark-locked.webp","fill","/tiles/timesheet-story/01-research.webp","/tiles/timesheet-story/01-research-dark.webp","Tasks logged per day across 801 screener responses: 29% log one or two, 46% three to five, 17% six to ten, 8% more than ten",1600,{"_118":126,"_120":277},{"_118":124,"_120":276},{"_118":122,"_120":275},{"_118":119,"_120":274},"Research →\nUX → UI →\nmerged PR","Product manager\nFront-end engineer","Mar–Aug 2026","Sole product designer",{"_120":291,"_133":292,"_118":293},{"_120":288,"_133":289,"_118":290},{"_120":285,"_133":286,"_118":287},{"_120":282,"_133":283,"_118":284},"31","files touched","in the shipped implementation","+2,405","lines added","across my merged PR","801","research responses","that set the entry rules","5","months","one surface, from a flat grid to grouped hierarchy","/logos/toggl-2-dark.svg","/logos/toggl-2-0-on-dark.svg",249,60,"/tiles/timesheet.webp","/tiles/timesheet-dark.webp","/tiles/timesheet-poster.webp","posterDark","/tiles/timesheet-dark-poster.webp",{"_161":307,"_163":308,"_309":310,"_311":312},800,"fit","contain","/tiles/timesheet.mp4","/tiles/timesheet.webm","mp4Dark","/tiles/timesheet-dark.mp4","webmDark","/tiles/timesheet-dark.webm","Research-grounded","Product critique","Shipped","navigator","The pattern that outlived my involvement","Toggl","Product design · originator, then advisor",[417,418,419],"grid","story",{"_77":412,"_79":413,"_81":414,"_83":415,"_148":416},"#3F6B5C","#6FA893","Asked to redesign an onboarding screen, I argued the screen wasn't the problem. The feature navigator that came out of it ran for ten months — and a year later I went back and broke the number that had justified it.","Shipped client work. The write-up quotes production outcomes, so it's shared on request rather than published.",{"_46":47,"_48":329,"_50":330,"_20":331,"_53":332,"_55":333,"_57":334,"_59":335},"Navigator · Toggl Track · Windows desktop","Asked to redesign onboarding, I argued it wasn’t the problem.","Sometimes the right move\nis to change the question.","I turned an onboarding redesign\ninto a persistent feature navigator —\na pattern that shipped and was\nlater rebuilt for Toggl 2.0.",[389,390,391,392],[381,382,383,384],{"_20":336,"_62":337},"One pattern. Argued for, shipped, re-examined, rebuilt.",[338,339,340,341,342],{"_69":107,"_71":108,"_73":374,"_199":375},{"_69":99,"_71":366,"_73":367,"_199":368},{"_69":92,"_71":72,"_73":359,"_199":360},{"_69":19,"_71":351,"_73":352,"_199":353},{"_69":70,"_71":343,"_73":344,"_199":345},"V2","Rebuilt for Toggl 2.0 by another team",{"_77":346,"_203":347,"_79":348,"_81":349,"_83":350},"/tiles/navigator-items/v2.webp","/tiles/navigator-items/v2-dark.webp","The Toggl 2.0 desktop navigator, built by another team: Make tracking automatic, a 1 of 4 progress bar, one feature marked Done and the next with its Turn on button",432,322,"Readout","Ten months of telemetry, then the number I broke",{"_77":354,"_203":355,"_79":356,"_81":357,"_83":358},"/tiles/navigator-items/media.webp","/tiles/navigator-items/media-dark.webp","The calendar clip from the feature page: a week of events, one converted into a running Client sync entry",374,205,"V1 on Windows, four or five items, personalised",{"_77":361,"_203":362,"_79":363,"_81":364,"_83":365},"/tiles/navigator-items/panel.webp","/tiles/navigator-items/panel-dark.webp","The navigator panel: Track Navigator, its line, and the first two rows — Projects and Calendar integration",391,234,"Refuse","Not a better screen: a navigator",{"_77":369,"_203":370,"_79":371,"_81":372,"_83":373},"/tiles/navigator-items/pillHover.webp","/tiles/navigator-items/pillHover-dark.webp","The Navigator button with the pointer resting on it",152,61,"Users skip onboarding, and the tooltips too",{"_77":376,"_203":377,"_79":378,"_81":379,"_83":380},"/tiles/navigator-items/empty.webp","/tiles/navigator-items/empty-dark.webp","The Windows timer’s empty state: the laptop illustration and Let’s get tracking!",207,247,{"_118":126,"_120":388},{"_118":124,"_120":387},{"_118":122,"_120":386},{"_118":119,"_120":385},"Strategy → research →\nUX → UI → specification","Cross-product —\nWindows desktop → Toggl 2.0","V1: Aug 2025 → ~Oct 2025\nV2: Jun–Jul 2026","V1 — originator & sole designer\nV2 — advisor",{"_120":408,"_133":409,"_118":410,"_396":411,"_403":47,"_398":47},{"_120":404,"_133":405,"_118":406,"_396":407,"_403":47,"_398":47},{"_120":399,"_133":400,"_118":401,"_396":402,"_403":47,"_398":47},{"_120":393,"_133":394,"_118":395,"_396":397,"_398":47},"4","personalized features","before selection dropped away","info","Beyond the first four, selection fell to around 5%.","gatedInfo","40,647","Navigator selections","actual interaction with the system, not just exposure","Alongside 25,788 Navigator completions — feature pages read to the end. Two lifetime totals, not a funnel.","gatedValue","29%","of new Windows users","engaged with the Navigator","Started at 20.3% and reached 29%, then held around 28% for six months.","1 in 4","new users","opened the Navigator","~13.4k of ~54k onboardings over ten months.","/logos/toggl-track.svg","Toggl Track",568,367,1.5,"Scope refusal","Instrumentation","V1 → V2","goals","Goals: designing a state system, not a feature","Product design · 0→1, sole designer",[527,528,315],"orbits",{"_77":294,"_203":295,"_79":170,"_81":296,"_83":297},"#936900","#E4AC21","accentLarge","#B88400","A goal-tracking feature for Toggl 2.0, where the real design problem wasn’t the layout — it was what a goal’s state means when users can still edit the past.","pill",{"_20":525,"_73":526},{"_46":47,"_48":434,"_50":435,"_20":436,"_53":437,"_55":438,"_57":439,"_59":440},"Goals · Toggl 2.0 · Web app","From design handoff to staging in 2 working days.","I didn’t prototype the screens.\nI prototyped the product.","I took Goals from research to a complete, working experience in code — exploring behaviour, states and edge cases before development. The prototype became the team’s reference for how the feature should work.",[509,510,511,512],[502,503,504,505],{"_20":441,"_62":442},"One feature. Designed, built and tested before production.",[443,444,445,446,447],{"_69":107,"_71":108,"_73":489,"_199":490,"_75":491},{"_69":99,"_71":234,"_73":482,"_75":483},{"_69":92,"_71":468,"_73":469,"_199":470,"_75":471},{"_69":19,"_71":221,"_73":458,"_199":459,"_75":-7,"_261":460},{"_69":70,"_71":72,"_73":448,"_199":449,"_75":450},"PRs → staging → beta → QA → GA",{"_77":456,"_203":457,"_79":231,"_81":232,"_83":233},{"_77":451,"_203":452,"_79":453,"_81":454,"_83":455},"/tiles/goals-process/05-ship.webp","/tiles/goals-process/05-ship-dark.webp","The create-a-goal modal from the final handoff prototype, previewing the time already logged toward the new goal",1024,768,"/tiles/goals-process/items/ship.webp","/tiles/goals-process/items/ship-dark.webp","Edge cases + badge backend alignment",{"_77":463,"_203":464,"_79":465,"_81":466,"_83":467},{"_77":461,"_203":462},"/tiles/goals-process/04-resolve-locked.webp","/tiles/goals-process/04-resolve-locked-dark.webp","/tiles/goals-process/items/resolve.webp","/tiles/goals-process/items/resolve-dark.webp","One column of the state matrix: Reached tinted while the period runs, Reached solid or Missed once it banks",250,145,"Build","Storybook variants + full coded prototype",{"_77":477,"_203":478,"_79":479,"_81":480,"_83":481},{"_77":472,"_203":473,"_79":474,"_81":475,"_83":476},"/tiles/goals-process/03-build.webp","/tiles/goals-process/03-build-dark.webp","Every display treatment for a goal rendered side by side in Storybook: chip strips, panel rows, ring cards and tile cards",1057,1457,"/tiles/goals-process/items/build.webp","/tiles/goals-process/items/build-dark.webp","Two goal chips with a percentage ring, one of the treatments weighed in Storybook",262,104,"Competitor research + visual state exploration",{"_77":484,"_203":485,"_79":486,"_81":487,"_83":488},"/tiles/goals-process/02-explore.webp","/tiles/goals-process/02-explore-dark.webp","The Figma exploration board: an early goals strip, the create-a-goal modal and its pickers, beside screens from competitor goal apps",1258,848,"Old Goals + user testing",{"_77":497,"_203":498,"_79":499,"_81":500,"_83":501},{"_77":492,"_203":493,"_79":494,"_81":495,"_83":496},"/tiles/goals-process/01-research.webp","/tiles/goals-process/01-research-dark.webp","The old Goals panel: four goals, each a progress ring with the hours logged against its target",1022,766,"/tiles/goals-process/items/research.webp","/tiles/goals-process/items/research-dark.webp","Three rows of the old Goals panel: a ring and a fraction each",428,328,{"_118":126,"_120":277},{"_118":124,"_120":508},{"_118":122,"_120":507},{"_118":119,"_120":506},"Research →\nUX → UI →\ncoded prototype","Product manager\nFront-end engineer\nBack-end engineer\nTech lead","5 weeks\nReleased 24 Jul 2026",{"_120":522,"_133":523,"_118":524,"_396":513,"_398":47},{"_120":519,"_133":520,"_118":521,"_396":-7},{"_120":516,"_133":517,"_118":518,"_396":-7},{"_120":513,"_133":514,"_118":515,"_403":47,"_396":-7},"","goals created","in the first 7 weeks","47","commits to prototype","working reference the team built from","6,266","lines in prototype","whole experience, not a sketch","2","working days","from handoff to the first build on staging","I prototyped the product, not just the screens.","I took Goals from research to a working experience in code.","Research-led","Prototyped in code",[527,528,315],"hook","A goal has more states than it looks like: on pace, behind, at risk, reached, missed — each of them either provisional or final. Getting that vocabulary right was the work.","year","2026","role","Senior product designer — sole designer, end to end","timeline","~1 week research · ~4 weeks design · handoff 8 Jul → merged 10 Jul → GA 24 Jul 2026","team","1 PM · 1 frontend · 1 backend engineer","platform","Web · Toggl 2.0","prerelease","publicSummary",{"_813":814,"_815":816,"_817":818,"_819":820},"inShort",[801,802,803,804],"publicTldr",[772,552,553,554,773,774,557,558,775,776,561,562,563,777,567,568,778,570],"publicFull",[551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570],{"_571":600,"_118":762,"_75":763,"_603":108,"_605":107,"_577":47,"_606":764,"_608":765,"_610":47},{"_571":593,"_593":108,"_26":758},{"_571":572,"_118":513,"_573":756},{"_571":719,"_720":721,"_722":723,"_724":725},{"_571":576,"_577":47,"_118":711,"_578":712},{"_571":600,"_118":698,"_699":47,"_75":700,"_603":701,"_605":99,"_577":47,"_606":702,"_608":703,"_610":47},{"_571":593,"_593":93,"_26":693},{"_571":572,"_118":513,"_573":690},{"_571":666,"_577":47,"_667":668},{"_571":600,"_118":656,"_75":657,"_603":528,"_605":92,"_577":47,"_606":658,"_608":659,"_610":47},{"_571":593,"_593":468,"_26":651},{"_571":572,"_118":513,"_573":649},{"_571":641,"_77":642,"_79":643,"_81":644,"_83":645,"_646":647},{"_571":600,"_118":630,"_75":631,"_603":632,"_605":99,"_577":47,"_606":632,"_608":633,"_623":47},{"_571":600,"_118":618,"_75":619,"_603":620,"_577":47,"_605":92,"_606":621,"_608":622,"_623":47},{"_571":600,"_118":601,"_75":602,"_603":604,"_605":19,"_577":47,"_606":607,"_608":609,"_610":47},{"_571":593,"_593":594,"_26":595},{"_571":572,"_118":513,"_573":591},{"_571":576,"_577":47,"_578":579},{"_571":572,"_118":513,"_573":574},"kind","prose","paragraphs",[575],"The figures behind this — adoption, retention against the in-house benchmark, and the two things I would change — are in the full study.","stats","gated","items",[580,581,582,583],{"_120":513,"_133":514,"_118":590},{"_120":513,"_133":588,"_118":589},{"_120":513,"_133":586,"_118":587},{"_120":513,"_133":584,"_118":585},"weekly reach","even as the active base tripled","as likely to still be active","three weeks on, for new users who set a goal in week one","of creators were brand-new","at seven weeks","in the first 7 weeks, weekly creation still climbing",[592],"Goals reached staging in **two working days** and GA on 24 July. Post-launch usage showed that **new users were creating goals surprisingly early** — reframing Goals as part of **activation**, not only a mechanism for long-term retention.","stage","Ship + learn",[596,597,598,599],"staging","beta","GA","post-launch data","chapter","We built for retention. Users showed us activation.",{"_77":613,"_203":614,"_79":615,"_81":616,"_83":617},"subtitle","What it moved","tldr","summary","Goals became an early activation signal — and the data showed us where discoverability still fell short.","image",{"_77":611,"_79":612},"hasMore","/tiles/goals-full/prod-widget-in-context.webp","The shipped Goals widget in the Toggl 2.0 timer panel","/tiles/goals-items/menu.webp","/tiles/goals-items/menu-dark.webp","A goal’s actions menu: Edit goal, Duplicate, Archive, Delete",184,172,"Sixteen days from handoff to everyone.",{"_77":625,"_203":626,"_79":627,"_81":628,"_83":629},"From prototype to production.","Handoff on a Wednesday, the first slice on staging by Friday, feature-complete a week later, released to everyone on 24 July.",{"_77":451,"_79":624},"locked","The shipped creator, previewing the time already logged toward a new goal","/tiles/goals-items/reached.webp","/tiles/goals-items/reached-dark.webp","The goal-reached moment: the ring with its tick, and the line You did it!",123,156,"The hard part wasn’t designing the badge. It was defining when it was true.",{"_77":636,"_203":637,"_79":638,"_81":639,"_83":640},"That exploration exposed a deeper problem: the product needed a state model.",{"_77":634,"_79":635},"/tiles/goals-full/state-matrix.webp","The unified state matrix: every situation for an at-least goal and a cap goal, with its badge","/tiles/goals-items/badges.webp","/tiles/goals-items/badges-dark.webp","The state badges: On pace, Behind pace, At risk, Reached, Not started",240,56,"artifact","/tiles/goals-process/storybook.webp","Three chip-strip treatments for a goal rendered side by side in Storybook, every state in each",1100,500,"stat",{"_120":648,"_118":524},"2 working days",[650],"I moved the design discussion into the product itself: I built the **complete experience in the real codebase**, using prompt-driven coding to explore interactions, states and edge cases before production. Instead of a file that says “here is what I mean”, **engineering got something they could click**. What started as a prototype became the team’s **behavioural reference for implementation**.",[652,653,654,655],"Storybook","prompt coding","edge cases","PR","The prototype became the handoff.",{"_77":661,"_203":662,"_79":663,"_81":664,"_83":665},"Use code to reduce ambiguity between design and engineering.",{"_77":472,"_79":660},"Every display treatment for a goal rendered side by side in Storybook","/tiles/goals-items/rings.webp","/tiles/goals-items/rings-dark.webp","Three progress rings at three fills, the unit explored in code",192,64,"flow","steps",[669,670,671,672,673],{"_118":689,"_73":513,"_675":-7},{"_118":688,"_73":513,"_675":-7},{"_118":687,"_73":513,"_675":-7},{"_118":686,"_73":513,"_675":-7},{"_118":674,"_73":-7,"_675":676},"State","badges",[677,678,679],{"_118":684,"_681":685},{"_118":683,"_681":682},{"_118":680,"_681":682},"At risk","tone","amber","Behind","On pace","green","Pace","Logged","Elapsed","Target",[691,692],"The existing feature told users their target. I wanted it to **show them how they were doing** — without making them work it out from a target, the time logged and how much of the period had passed.","So progress became **a state you can read at a glance**: on pace, behind, at risk, reached. That shaped the **visual state system**, the goal setup, the timer widget and the more expressive Goals page.",[694,695,696,697],"goal setup","state system","timer","Goals page","Make progress obvious and Goals worth returning to.","artWide",{"_77":706,"_203":707,"_79":708,"_81":709,"_83":710},"What should Goals actually communicate?","Turn tracked time into visible progress.",{"_77":704,"_79":705},"/tiles/goals-process/pace-line.webp","Two goal tracks with the state badges placed where each verdict begins","/tiles/goals-items/row.webp","/tiles/goals-items/row-dark.webp","One goal row from 2.0: Study 8 hours a week, 0.8/8 hours · 10%, reading Behind",332,66,"What the numbers said",[713,714],{"_120":513,"_133":717,"_118":718},{"_120":513,"_133":715,"_118":716},"asking for longer periods","20 of them for monthly, which didn’t exist","of solo workspaces","had ever created a goal","converge","columns",[746,747,748],"outcome","What to rebuild","had",{"_118":726,"_727":728,"_729":730},"What we had","body","Track Goals across surfaces: creation modal, goals by the calendar, goals page itself.","arts",[731,732,733],{"_77":742,"_79":743,"_81":744,"_83":745,"_737":-7},{"_77":738,"_79":739,"_81":740,"_83":741,"_737":-7},{"_77":734,"_79":735,"_81":644,"_83":736,"_737":-7},"/tiles/goals-compare/page-before.webp","Track’s goals page: a table of name, member, target, progress, streak and end date, with the active-goals filter above it",621,"caption","/tiles/goals-compare/panel-before.webp","Track’s Goals panel: four goals as rings, each with a fraction",700,610,"/tiles/goals-compare/creator-before.webp","Track’s create-a-goal dialog with the recurrence menu open: every day, every week, weekdays",470,665,{"_118":754,"_727":755,"_751":-7},{"_118":752,"_727":753,"_751":-7},{"_118":749,"_727":750,"_751":-7},"Team alignment","What the system allowed","detail","User research","What users said","Product data","What users did",[757],"Goals already existed in Track. Before bringing them into 2.0, I wanted to understand **what was actually working**, what wasn’t, what was missing, and **which inherited decisions still deserved to survive**.",[759,760,761],"user research","usage data","product archaeology","Don’t copy the feature. Understand it first.",{"_77":767,"_203":768,"_79":769,"_81":770,"_83":771},"Research before rebuilding.",{"_77":734,"_79":766},"Track’s goals page: the table of name, member, target, progress, streak and end date","/tiles/goals-items/track-row.webp","/tiles/goals-items/track-row-dark.webp","One goal from Track’s panel: a ring, Study 8 hours a week, 0.8/8 hours",403,93,{"_571":600,"_118":762,"_75":799,"_606":764,"_608":800},{"_571":576,"_577":47,"_118":711,"_578":796},{"_571":600,"_118":698,"_699":47,"_75":794,"_606":702,"_608":795},{"_571":666,"_577":47,"_667":788},{"_571":600,"_118":656,"_75":786,"_606":658,"_608":787},{"_571":600,"_118":601,"_75":784,"_606":607,"_608":785},{"_571":576,"_577":47,"_578":779},[780,781,782,783],{"_120":513,"_133":514,"_118":590},{"_120":513,"_133":588,"_118":589},{"_120":513,"_133":586,"_118":587},{"_120":513,"_133":584,"_118":585},{"_77":613,"_203":614,"_79":615,"_81":616,"_83":617},{"_77":611,"_79":612},{"_77":661,"_203":662,"_79":663,"_81":664,"_83":665},{"_77":472,"_79":660},[789,790,791,792,793],{"_118":689,"_73":513,"_675":-7},{"_118":688,"_73":513,"_675":-7},{"_118":687,"_73":513,"_675":-7},{"_118":686,"_73":513,"_675":-7},{"_118":674,"_73":-7,"_675":676},{"_77":706,"_203":707,"_79":708,"_81":709,"_83":710},{"_77":704,"_79":705},[797,798],{"_120":513,"_133":717,"_118":718},{"_120":513,"_133":715,"_118":716},{"_77":767,"_203":768,"_79":769,"_81":770,"_83":771},{"_77":734,"_79":766},{"_118":811,"_727":812},{"_118":809,"_727":810},{"_118":807,"_727":808},{"_118":805,"_727":806},"What changed","Goals shipped **16 days after handoff** and reached general availability in July 2026. The post-launch data reframed Goals as an **early activation signal**.","The approach","I explored the experience **in the real codebase**, using Storybook and prompt coding to test **behaviour and edge cases before production**.","What I designed","A new **goal creation flow**, **progress and pace indicators**, **state badges**, a **Goals page** with statistics, and a clearer **empty state**.","The brief","Bring Goals to Toggl 2.0 for **solo users** — a parity feature for Track users and a way to keep **intended time front-of-mind** while tracking.","problem","Toggl 2.0 needed goals — a way to set a time target and track progress against it. The previous generation had shipped something similar and capped users at four active goals, so this was not a blank page: it was a feature with inherited decisions attached, and a limit nobody could account for.","users","Solo users. The spec framed them as freelancers protecting billable hours — research contradicted that. The real drivers were personal accountability, manager visibility, and employer budget tracking; all three participants read “billable” as oversight, not invoicing.","approach","A goal **state system** rather than a screen: trajectory carried by hue, finality by fill weight, and the same word across both. Archiving instead of a bigger number. A timer-page widget for the goals you are working against, and a full page behind it. The whole thing built as a clickable prototype in the team’s real design system and handed over as a behaviour reference.","shipped","Shipped to general availability in Toggl 2.0 on 24 July 2026. Sole designer, end to end."]
