[{"_1":2},"routes/case-study",{"_3":4},"data",{"_5":6,"_7":8,"_9":10,"_11":12},"unlocked",false,"pub",{"_16":405,"_18":95,"_20":536,"_22":170,"_24":407,"_26":537,"_28":303,"_33":411,"_35":412,"_177":-7,"_37":38,"_39":413,"_538":419,"_539":540,"_541":271,"_542":543,"_544":545,"_546":547,"_548":-7,"_549":-7,"_550":551,"_552":553,"_554":555},"meta",{"_16":405,"_18":95,"_20":406,"_22":170,"_24":407,"_26":408,"_28":303,"_304":409,"_31":410,"_33":411,"_35":412,"_37":38,"_39":413,"_41":414,"_43":415},"more",[13,14,15],{"_16":298,"_18":86,"_20":299,"_22":300,"_24":301,"_26":302,"_28":303,"_304":305,"_306":307,"_31":308,"_33":309,"_35":310,"_37":311,"_39":312,"_43":313},{"_16":168,"_18":112,"_20":169,"_22":170,"_24":171,"_26":172,"_28":173,"_30":168,"_31":174,"_33":175,"_35":176,"_177":178,"_37":38,"_39":179,"_41":42,"_180":181,"_43":182},{"_16":17,"_18":19,"_20":21,"_22":23,"_24":25,"_26":27,"_28":29,"_30":17,"_31":32,"_33":34,"_35":36,"_37":38,"_39":40,"_41":42,"_43":44},"slug","navigator","order","02","title","The pattern that outlived my involvement","client","Toggl","discipline","Product design · originator, then advisor","tags",[165,166,167],"cover","grid","story","logo",{"_76":159,"_80":160,"_82":161,"_84":162,"_163":164},"accent","#3F6B5C","accentBright","#6FA893","accentInk","#FFFFFF","cardSummary","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.","lockNote","Shipped client work. The write-up quotes production outcomes, so it's shared on request rather than published.","head",{"_45":46,"_47":48,"_49":50,"_20":51,"_52":53,"_54":55,"_56":57,"_58":59},"carriesEvidence",true,"context","Navigator · Toggl Track · Windows desktop","eyebrow","Asked to redesign onboarding, I argued it wasn’t the problem.","Sometimes the right move\nis to change the question.","lede","I turned an onboarding redesign\ninto a persistent feature navigator —\na pattern that shipped and was\nlater rebuilt for Toggl 2.0.","proof",[135,136,137,138],"facts",[121,122,123,124],"process",{"_20":60,"_61":62},"One pattern. Argued for, shipped, re-examined, rebuilt.","stages",[63,64,65,66,67],{"_68":112,"_70":113,"_72":114,"_74":115},{"_68":19,"_70":104,"_72":105,"_74":106},{"_68":95,"_70":96,"_72":97,"_74":98},{"_68":86,"_70":87,"_72":88,"_74":89},{"_68":69,"_70":71,"_72":73,"_74":75},"n","05","name","V2","sub","Rebuilt for Toggl 2.0 by another team","item",{"_76":77,"_78":79,"_80":81,"_82":83,"_84":85},"src","/tiles/navigator-items/v2.webp","srcDark","/tiles/navigator-items/v2-dark.webp","alt","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","width",432,"height",322,"04","Readout","Ten months of telemetry, then the number I broke",{"_76":90,"_78":91,"_80":92,"_82":93,"_84":94},"/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,"03","Ship","V1 on Windows, four or five items, personalised",{"_76":99,"_78":100,"_80":101,"_82":102,"_84":103},"/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",{"_76":107,"_78":108,"_80":109,"_82":110,"_84":111},"/tiles/navigator-items/pillHover.webp","/tiles/navigator-items/pillHover-dark.webp","The Navigator button with the pointer resting on it",152,61,"01","Research","Users skip onboarding, and the tooltips too",{"_76":116,"_78":117,"_80":118,"_82":119,"_84":120},"/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,{"_125":133,"_127":134},{"_125":131,"_127":132},{"_125":129,"_127":130},{"_125":126,"_127":128},"label","Scope","value","Strategy → research →\nUX → UI → specification","Team","Cross-product —\nWindows desktop → Toggl 2.0","Timeline","V1: Aug 2025 → ~Oct 2025\nV2: Jun–Jul 2026","Role","V1 — originator & sole designer\nV2 — advisor",{"_127":155,"_140":156,"_125":157,"_143":158,"_150":46,"_145":46},{"_127":151,"_140":152,"_125":153,"_143":154,"_150":46,"_145":46},{"_127":146,"_140":147,"_125":148,"_143":149,"_150":46,"_145":46},{"_127":139,"_140":141,"_125":142,"_143":144,"_145":46},"4","unit","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,"scale",1.5,"Scope refusal","Instrumentation","V1 → V2","goals","Goals: designing a state system, not a feature","Toggl 2.0","Product design · 0→1, sole designer",[295,296,297],"orbits",{"_76":291,"_78":292,"_80":170,"_82":293,"_84":294},"#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":289,"_72":290},{"_45":46,"_47":183,"_49":184,"_20":185,"_52":186,"_54":187,"_56":188,"_58":189},"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.",[272,273,274,275],[264,265,266,267],{"_20":190,"_61":191},"One feature. Designed, built and tested before production.",[192,193,194,195,196],{"_68":112,"_70":113,"_72":251,"_74":252,"_199":253},{"_68":19,"_70":243,"_72":244,"_199":245},{"_68":95,"_70":229,"_72":230,"_74":231,"_199":232},{"_68":86,"_70":211,"_72":212,"_74":213,"_199":214,"_215":216},{"_68":69,"_70":96,"_72":197,"_74":198,"_199":200},"PRs → staging → beta → QA → GA",{"_76":206,"_78":207,"_80":208,"_82":209,"_84":210},"art",{"_76":201,"_78":202,"_80":203,"_82":204,"_84":205},"/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","Three merged pull requests",187,99,"Resolve","Edge cases + badge backend alignment",{"_76":224,"_78":225,"_80":226,"_82":227,"_84":228},{"_76":219,"_78":220,"_80":221,"_82":222,"_84":223},"gatedArt",{"_76":217,"_78":218},"/tiles/goals-process/04-resolve-locked.webp","/tiles/goals-process/04-resolve-locked-dark.webp","/tiles/goals-process/04-resolve.webp","/tiles/goals-process/04-resolve-dark.webp","The unified state matrix agreed with the backend lead: every situation for an at-least goal and a cap goal, its current badge against the proposed one",865,649,"/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",{"_76":238,"_78":239,"_80":240,"_82":241,"_84":242},{"_76":233,"_78":234,"_80":235,"_82":236,"_84":237},"/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,"Explore","Competitor research + visual state exploration",{"_76":246,"_78":247,"_80":248,"_82":249,"_84":250},"/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",{"_76":259,"_78":260,"_80":261,"_82":262,"_84":263},{"_76":254,"_78":255,"_80":256,"_82":257,"_84":258},"/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,{"_125":133,"_127":271},{"_125":131,"_127":270},{"_125":129,"_127":269},{"_125":126,"_127":268},"Research →\nUX → UI →\ncoded prototype","Product manager\nFront-end engineer\nBack-end engineer\nTech lead","5 weeks\nReleased 24 Jul 2026","Sole product designer",{"_127":285,"_140":286,"_125":287,"_143":288,"_145":46},{"_127":282,"_140":283,"_125":284},{"_127":279,"_140":280,"_125":281},{"_127":276,"_140":277,"_125":278,"_150":46},"2,224","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","Feature-complete in one more week → one week in beta → released to all users on 24 Jul 2026.","I prototyped the product, not just the screens.","I took Goals from research to a working experience in code.","/logos/toggl-2-dark.svg","/logos/toggl-2-0-on-dark.svg",249,60,"Research-led","Prototyped in code","Shipped","oroom","From browsing to booking","OROOM","Web design · hospitality",[402,403,404],"stack","loop",{"_76":390,"_391":387,"_392":393,"_82":394,"_84":395,"_396":397},"shot",{"_76":387,"_82":388,"_84":389},{"_76":383,"_80":300,"_82":384,"_84":385,"_163":386},"#c2186f","#f279b4","#fdf4f8","A hotel website rebuilt around the decision a guest is actually making — sell the stay, not the room inventory.",{"_45":46,"_47":314,"_49":315,"_20":316,"_52":317,"_54":318,"_56":319,"_58":320},"Hotel website · OROOM · Responsive web","Conversion up 6.4× after the redesign.","From browsing\nto booking","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?",[367,368,369,370],[359,360,361,362],{"_20":321,"_61":322},"One website. Researched, argued for, redesigned, tested.",[323,324,325,326,327],{"_68":112,"_70":113,"_72":354,"_199":355},{"_68":19,"_70":347,"_72":348,"_199":349},{"_68":95,"_70":341,"_72":342,"_199":343},{"_68":86,"_70":334,"_72":335,"_199":336},{"_68":69,"_70":96,"_72":328,"_199":329},"Responsive, in both languages",{"_76":330,"_80":331,"_82":332,"_84":333},"/work-assets/oroom/home-after-desktop.webp","The redesigned homepage",1814,3083,"Test","Same task, before vs after",{"_76":337,"_80":338,"_82":339,"_84":340},"/work-assets/oroom/calendar-desktop.webp","The master calendar",2000,2192,"Design","Wireframes → three moves",{"_76":344,"_80":345,"_82":339,"_84":346},"/work-assets/oroom/wireframes.webp","Wireframes of the redesigned site",998,"Define","Three pain points → how might we",{"_76":350,"_80":351,"_82":352,"_84":353},"/work-assets/oroom/google-score.webp","The Google review summary",1630,446,"Hotjar recordings + review mining",{"_76":356,"_80":357,"_82":339,"_84":358},"/work-assets/oroom/hotjar-calendar.webp","A Hotjar recording of the old calendar",937,{"_125":133,"_127":366},{"_125":131,"_127":365},{"_125":129,"_127":364},{"_125":126,"_127":363},"Research →\nUX → UI →\ndesktop + mobile layouts","CEO\nDevelopers\nMarketing team","4 months","Product designer\n& research lead",{"_127":380,"_140":381,"_125":382},{"_127":377,"_140":378,"_125":379},{"_127":374,"_140":375,"_125":376},{"_127":371,"_140":372,"_125":373},"3","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,0.85,"/tiles/oroom-rooms-poster.webp",1200,546,"/tiles/oroom-loop.webp","poster","video",{"_398":399,"_400":401},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.","Product design · continuous ownership",[534,535,297],{"_76":519,"_78":520,"_391":521,"_522":523,"_392":524,"_82":525,"_84":525,"_526":527},{"_76":291,"_78":292,"_80":170,"_82":293,"_84":294},"#4A5578","#8B96C4","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.","Shipped client work. The write-up quotes production internals, so it's shared on request rather than published.",{"_45":46,"_47":416,"_49":417,"_20":418,"_52":419,"_54":420,"_56":421,"_58":422},"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.",[503,504,505,506],[496,497,498,499],{"_20":423,"_61":424},"One surface. Researched, grouped, tested in the product, shipped.",[425,426,427,428,429,430],{"_68":112,"_70":113,"_72":486,"_74":487,"_215":488,"_199":-7},{"_68":19,"_70":473,"_72":474,"_74":475,"_199":476},{"_68":95,"_70":243,"_72":462,"_74":463,"_199":464},{"_68":86,"_70":211,"_72":453,"_74":454,"_199":455},{"_68":69,"_70":445,"_72":446,"_74":447},{"_68":431,"_70":96,"_72":432,"_74":433,"_199":434},"06","Four grouping modes · 31 files · PM + engineering review",{"_76":440,"_78":441,"_80":442,"_82":443,"_84":444},{"_76":435,"_78":436,"_80":437,"_82":438,"_84":439},"/tiles/timesheet-story/05-ship.webp","/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",{"_76":448,"_78":449,"_80":450,"_82":451,"_84":452},"/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,"Experimental PR → production PR → engineering review",{"_76":460,"_78":461,"_80":208,"_82":209,"_84":210},{"_76":456,"_78":457,"_80":458,"_82":339,"_84":459},"/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","Visual hypotheses as live toggles in the product",{"_76":469,"_78":470,"_80":471,"_82":472,"_84":472},{"_76":465,"_78":466,"_80":467,"_82":339,"_84":468},"/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",{"_76":482,"_78":483,"_80":484,"_82":443,"_84":485},{"_76":477,"_78":478,"_80":479,"_82":480,"_84":481},"/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",{"_491":46,"_76":492,"_78":493,"_80":494,"_82":495,"_84":388},{"_76":489,"_78":490},"/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,{"_125":133,"_127":271},{"_125":131,"_127":502},{"_125":129,"_127":501},{"_125":126,"_127":500},"Research →\nUX → UI →\nmerged PR","Product manager\nFront-end engineer","Mar–Aug 2026",{"_127":516,"_140":517,"_125":518,"_143":-7},{"_127":513,"_140":514,"_125":515,"_143":-7},{"_127":510,"_140":511,"_125":512,"_143":-7},{"_127":507,"_140":508,"_125":509,"_143":-7},"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","/tiles/timesheet.webp","/tiles/timesheet-dark.webp","/tiles/timesheet-poster.webp","posterDark","/tiles/timesheet-dark-poster.webp",{"_398":528,"_400":529,"_530":531,"_532":533},800,"fit","contain","/tiles/timesheet.mp4","/tiles/timesheet.webm","mp4Dark","/tiles/timesheet-dark.mp4","webmDark","/tiles/timesheet-dark.webm","Research-grounded","Product critique","The timesheet kept getting more complicated. The interface didn’t have to.",[534,535,297],"hook","year","2026","role","timeline","Mar–Aug 2026 · research Apr · grouping merged 12 Aug","team","1 PM · 1 frontend engineer","platform","Web · Toggl 2.0","prerelease","publicSummary","inShort",[869,870,871,872],"publicTldr",[831,557,558,559,560,832,562,833,834,835,836,837,838,839,840,841,842,843,844,845],"publicFull",[556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587],{"_588":589,"_125":823,"_591":824,"_593":112,"_594":46,"_595":825,"_686":46,"_199":826,"_215":-7,"_779":46},{"_588":679,"_679":113,"_26":819},{"_588":604,"_125":606,"_607":817},{"_588":695,"_76":811,"_78":812,"_80":813,"_697":814,"_699":46,"_82":815,"_84":816},{"_588":604,"_125":606,"_607":809},{"_588":702,"_594":46,"_727":46,"_647":797},{"_588":782,"_783":784,"_785":786},{"_588":589,"_125":775,"_591":776,"_593":19,"_595":777,"_686":46,"_199":778,"_779":46},{"_588":679,"_679":473,"_26":771},{"_588":604,"_125":757,"_758":759,"_607":760},{"_588":604,"_125":606,"_607":754},{"_588":589,"_125":746,"_591":747,"_593":19,"_594":46,"_595":748,"_199":749,"_598":46},{"_588":589,"_125":738,"_591":739,"_593":95,"_595":740,"_199":741},{"_588":679,"_679":211,"_26":734},{"_588":604,"_125":730,"_607":731},{"_588":695,"_727":46,"_76":465,"_78":466,"_80":728,"_697":729,"_699":46},{"_588":623,"_125":712,"_624":713,"_626":714},{"_588":604,"_125":606,"_607":710},{"_588":702,"_647":703},{"_588":604,"_125":606,"_607":700},{"_588":695,"_76":456,"_78":457,"_80":696,"_697":698,"_699":46},{"_588":604,"_605":46,"_125":606,"_607":692},{"_588":589,"_125":684,"_591":676,"_593":86,"_595":685,"_686":46,"_199":687},{"_588":679,"_679":445,"_26":680},{"_588":604,"_125":676,"_607":677},{"_588":646,"_125":606,"_647":648},{"_588":604,"_125":643,"_607":644},{"_588":623,"_624":625,"_626":627},{"_588":604,"_125":606,"_607":620},{"_588":392,"_76":611,"_78":612,"_532":613,"_522":614,"_400":615,"_391":616,"_617":618,"_80":619},{"_588":604,"_605":46,"_125":606,"_607":608},{"_588":589,"_125":590,"_591":592,"_593":86,"_594":46,"_595":596,"_199":597,"_598":46},"kind","chapter","Shipped as a system, not a screen.","subtitle","More capability, without more complexity by default.","tldr","gated","summary","What shipped — and how the system carried beyond the original scope.",{"_76":599,"_78":600,"_80":601,"_82":602,"_84":603},"locked","/tiles/timesheet-items/shipped.webp","/tiles/timesheet-items/shipped-dark.webp","Apollo Inc., Apollo launch, Inbox triage and Kickoff prep — the shipped grouping on realistic data",172,175,"prose","claim","","paragraphs",[609,610],"**More capability, nothing more visible by default.**","For hierarchy, that meant revealing depth only when asked. For responsive behaviour, it meant reclaiming space from the chrome before asking the content to give anything up.","/tiles/timesheet-story/timesheet-squeeze.mp4","/tiles/timesheet-story/timesheet-squeeze-dark.mp4","/tiles/timesheet-story/timesheet-squeeze-dark.webm","/tiles/timesheet-story/timesheet-squeeze-dark-poster.png","/tiles/timesheet-story/timesheet-squeeze.webm","/tiles/timesheet-story/timesheet-squeeze-poster.png","gif","/tiles/timesheet-story/timesheet-squeeze.gif","Screen recording of the Toggl 2.0 timesheet: the week grouped by project, then by client and project, opened one level at a time; then the window narrows until the day columns scroll while the name and total columns stay pinned.",[621,622],"The Timesheet had a hard minimum width, and the task/project name column was silently absorbing the squeeze. Rather than start shrinking the content, I **measured what the layout could give up first**: oversized gutters, slack inside day cells and space in the totals column.","I prototyped the responsive behaviour directly in the product and brought the working version to the engineer to merge.","flow","highlight",4,"steps",[628,629,630,631,632],{"_125":641,"_72":642},{"_125":639,"_72":640},{"_125":637,"_72":638},{"_125":635,"_72":636},{"_125":633,"_72":634},"Responsive","space on request","Roll-ups","billable · subtasks","Hierarchy","depth on request","Grouping","four modes","MVP","time entry","Responsive, by initiative",[645],"Responsive behaviour wasn’t part of the original brief. **I decided to prototype it anyway.**","highlights","items",[649,650,651,652],{"_20":641,"_653":671,"_199":672},{"_20":639,"_653":666,"_199":667},{"_20":637,"_653":661,"_199":662},{"_20":635,"_653":654,"_199":655},"body","Billable and non-billable breakdowns, and subtask totals rolled into their parents — **more information without another layer of visible rows** by default.",{"_76":656,"_78":657,"_80":658,"_82":659,"_84":660},"/tiles/timesheet-items/cue-totals.webp","/tiles/timesheet-items/cue-totals-dark.webp","Thursday, Friday and the total for a client, its project, a task and its logs — the sums rolling up",400,182,"Depth remained progressive: **each level had to be requested** rather than exposed all at once, with neutral visual tiers carrying the structure as it became deeper.",{"_76":663,"_78":664,"_80":665,"_82":659,"_84":660},"/tiles/timesheet-items/cue-tiers.webp","/tiles/timesheet-items/cue-tiers-dark.webp","ACME client, Orange, Passion fruit is the best fruit, Some — each level a shade deeper","Task, Project, Client and Client & Project became **four ways to organise the same underlying entries**, with groups opening collapsed and the selected grouping remembered per workspace.",{"_76":668,"_78":669,"_80":670,"_82":659,"_84":660},"/tiles/timesheet-items/cue-groupby.webp","/tiles/timesheet-items/cue-groupby-dark.webp","The labelled Group by: Client & project control above the grouped rows","Time entry stayed immediate: a row per task, a cell per day, with **always-visible inputs** — the rule the research set, and the part of the surface that never changed.",{"_76":673,"_78":674,"_80":675,"_82":659,"_84":660},"/tiles/timesheet-items/cue-cells.webp","/tiles/timesheet-items/cue-cells-dark.webp","A task’s day cells with its logs’ beneath: inputs always in view","One surface, more layers",[678],"The grouping problem didn’t end when the first version worked. The Timesheet kept gaining capability, so the real test was whether **the same rules could survive what came next**.","stage",[681,682,683],"billable roll-ups","subtask roll-ups","responsive squeeze","The same system kept absorbing new capability","The original problem shipped, and the design principles continued to guide subsequent work.","artWide",{"_76":688,"_78":689,"_80":690,"_82":691,"_84":242},"/tiles/timesheet-items/squeeze.webp","/tiles/timesheet-items/squeeze-dark.webp","The sheet squeezed: the day columns clipped at Wednesday, the totals column pinned, a client’s and a project’s totals still in view",224,[693,694],"**The code wasn’t the deliverable. The merged product was.**","The prototype gave me a way to resolve the design in the environment where it would actually live. The final PR gave engineering something concrete to review, challenge and ship.","figure","The final visual check before merge: grouped by client and project, tiers, task rows with tags and billable marks, and time logs","caption","The visual check before merge.","wide",[701],"He reviewed the implementation beyond the automated checks, **pushed three fixes they had missed**, and asked for a final visual pass.","stats",[704,705],{"_127":510,"_140":511,"_125":709},{"_127":706,"_140":707,"_125":708},"−149","lines removed","the exploratory controls and what they had touched","in the production PR, across 31 files",[711],"Once the direction settled, I cleaned the experiment into a **production PR**: removed the exploratory controls, fixed the UI issues I found along the way, and ran another round of automated checks before handing it to the engineer who owned the surface.","From exploration to merge",1,[715,716,717,718],{"_125":725,"_72":726},{"_125":723,"_72":724},{"_125":721,"_72":722},{"_125":719,"_72":720},"Merged","checked against the agreed design","Engineering review","three fixes, a final visual pass","Production-ready PR","exploratory controls out, UI fixes in","Experimental PR","a previewable PR, toggles on his own data","tight","The experimental PR in the browser: the grouped timesheet with the density console open over it","The experimental PR: every treatment a toggle on the live grid.","From a live experiment to a production PR",[732,733],"Nothing here was handed over as static frames. The exploration lived in the product as an **experimental PR with a preview URL**, and every treatment was exposed as a toggle the PM could flip on his own data.","That changed the conversation. Instead of discussing whether a screenshot looked better, we could **test the hierarchy on realistic data** and compare different treatments in the environment where the Timesheet would actually live.",[735,736,737],"experimental PR","clean PR","engineer review","I explored the problem in the product, not around it","From prototype to product","The design stayed close to the thing being built.",{"_76":742,"_78":743,"_80":744,"_82":385,"_84":745},"/tiles/timesheet-items/menu.webp","/tiles/timesheet-items/menu-dark.webp","The Group by menu: Task, Project, Client, Client & project",169,"“Dense” wasn’t the diagnosis. Depth was.","When feedback is vague, make the problem specific.","The PM felt it, two stakeholders didn’t; live prototypes made the disagreement testable.",{"_76":750,"_78":751,"_80":752,"_82":227,"_84":753},"/tiles/timesheet-items/console.webp","/tiles/timesheet-items/console-dark.webp","The density console: neutral tiers, compact time logs, tree guide lines, quieter log text and smaller log text as toggles",310,[755,756],"Each level could carry its own rows, indentation and totals. What looked like a simple grouped table at two levels became **a much deeper structure at four**.","The challenge wasn’t fitting more rows on the screen. It was making the hierarchy **readable without making the Timesheet feel like a different product**.","The cost of a deeper hierarchy","aside",{"_76":766,"_78":767,"_80":768,"_82":769,"_84":770},[761,762,763,764,765],"Each grouping adds a level to the sheet:","- **2 levels** — the task and its logs","- **3 levels** — project or client","- **4 levels** — client and project (client, project, task, log)","**That difference mattered.**","/tiles/timesheet-story/four-levels.webp","/tiles/timesheet-story/four-levels-dark.webp","ACME client, Orange, Passion fruit is the best fruit, Some, Time log — four levels on their tiers",484,221,[772,773,774],"4 groupings","PM review","mid-July","Four levels changed what “simple” meant","The hierarchy","Not density — how much hierarchy appears at once.",{"_76":780,"_78":781,"_80":768,"_82":769,"_84":770},"hasMore","/tiles/timesheet-items/tiers.webp","/tiles/timesheet-items/tiers-dark.webp","converge","columns",[787,788,789],"outcome","What grouping had to respect",{"_125":795,"_653":796,"_792":-7},{"_125":793,"_653":794,"_792":-7},{"_125":790,"_653":791,"_792":-7},"Complexity on demand","More capability, less visible by default","detail","Organise without gating","Grouping should organise, not gate","Keep entry immediate","Filled in far more often than it is read",[798,799,800,801],{"_127":513,"_140":514,"_125":515,"_808":46},{"_127":606,"_140":806,"_125":807},{"_127":606,"_140":804,"_125":805,"_143":-7},{"_127":606,"_140":802,"_125":803},"tasks a day","where grid preference peaked; above ten, the list won outright","preferred the weekly grid","the strongest single preference in this group","were the ideal user","people tracking their own hours for an employer","open",[810],"In April 2026 I ran a **screener that doubled as a market scan**:","/tiles/timesheet-story/track-timesheet.png","/tiles/timesheet-story/track-timesheet-dark.png","Toggl Track’s Timesheet: a week of project rows with a cell per day and a total per row and per day","Track’s Timesheet, the view being brought to Toggl 2.0: one row per project, a cell per day, and the week’s total.",1420,664,[818],"The grid I inherited was the obvious one: a row per task, a cell per day. But before changing it, I wanted to understand what the Timesheet was actually for — did people come here to **review their week**, or to **enter it**? The two needs imply very different surfaces.",[820,821,822],"801-response screener","moderated sessions","April 2026","Research set the rules before the UI did","The foundation","Before adding complexity, understand what the surface is for.",{"_76":827,"_78":828,"_80":606,"_82":829,"_84":830},"/tiles/timesheet-items/chart-locked.webp","/tiles/timesheet-items/chart-locked-dark.webp",300,148,{"_588":589,"_125":823,"_595":825,"_686":46,"_199":868,"_215":-7},{"_588":702,"_594":46,"_727":46,"_647":864},{"_588":589,"_125":775,"_595":777,"_686":46,"_199":863},{"_588":679,"_679":473,"_26":862},{"_588":604,"_125":606,"_607":860},{"_588":695,"_727":46,"_76":766,"_78":767,"_80":768,"_82":769,"_84":770},{"_588":589,"_125":738,"_595":740,"_199":859},{"_588":679,"_679":211,"_26":858},{"_588":604,"_125":606,"_607":856},{"_588":695,"_727":46,"_76":465,"_78":466,"_80":728,"_699":46},{"_588":623,"_624":713,"_626":851},{"_588":589,"_125":684,"_595":685,"_686":46,"_199":850},{"_588":679,"_679":445,"_26":849},{"_588":604,"_125":606,"_607":846},{"_588":392,"_76":611,"_78":612,"_532":613,"_522":614,"_400":615,"_391":616,"_617":618,"_80":619},[847,848],"Grouping became the foundation for **roll-ups and responsive behaviour** — each one adding capability without making more visible by default.","Responsive wasn’t part of the brief. **I prototyped it anyway** — measuring what the layout could give up first, so the task and project names never had to shrink.",[681,682,683],{"_76":688,"_78":689,"_80":690,"_82":691,"_84":242},[852,853,854,855],{"_125":725,"_72":726},{"_125":723,"_72":724},{"_125":721,"_72":722},{"_125":719,"_72":720},[857],"Nothing was handed over as static frames. The exploration lived in the product as an **experimental PR with a preview URL**, every treatment a toggle the PM could flip on his own data — so we compared hierarchies **on realistic data**, not screenshots.",[735,736,737],{"_76":742,"_78":743,"_80":744,"_82":385,"_84":745},[861,756],"Grouping by client **and** project is four levels — client, project, task, log — and each one could carry its own rows, indentation and totals. What read as a simple grouped table at two levels became **a much deeper structure at four**.",[772,773,774],{"_76":780,"_78":781,"_80":768,"_82":769,"_84":770},[798,865,866,867],{"_127":606,"_140":806,"_125":807},{"_127":606,"_140":804,"_125":805,"_143":-7},{"_127":606,"_140":802,"_125":803},{"_76":827,"_78":828,"_80":606,"_82":829,"_84":830},{"_125":879,"_653":880},{"_125":877,"_653":878},{"_125":875,"_653":876},{"_125":873,"_653":874},"What changed","**Four levels of hierarchy** shipped to **web and desktop in August 2026** — **31 files, +2,405 / −149 lines** — and the same rule carried into **roll-ups and responsive behaviour**.","The approach","An **801-response screener** and moderated sessions first, then **live prototypes in the product** on realistic data, worked through with the PM and engineer into my **final PR** that got merged.","What I designed","A **hierarchy system**, not a redesign: grouped views **open collapsed**, expand **one level at a time**, and read through **neutral tiers, tree guides and quieter log text**.","The brief","Bring **Timesheet view** from Track to Toggl 2.0 — an existing capability on a **new surface and data structure** — without making the Timesheet **harder to scan or enter time into**."]
