[{"data":1,"prerenderedAt":232},["ShallowReactive",2],{"i-lucide:chevron-down":3,"i-lucide:search":8,"i-lucide:sun":10,"i-lucide:moon":12,"i-lucide:arrow-right":14,"i-lucide:menu":16,"i-lucide:mail":18,"i-simple-icons:x":20,"i-simple-icons:linkedin":22,"i-simple-icons:dribbble":25,"i-simple-icons:github":27,"work-index":29,"i-lucide:chevron-right":228,"i-lucide:flask-conical":230},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":7},0,24,false,"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m6 9l6 6l6-6\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":9},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m21 21l-4.34-4.34\"\u002F>\u003Ccircle cx=\"11\" cy=\"11\" r=\"8\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":11},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"4\"\u002F>\u003Cpath d=\"M12 2v2m0 16v2M4.93 4.93l1.41 1.41m11.32 11.32l1.41 1.41M2 12h2m16 0h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":13},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":15},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 12h14m-7-7l7 7l-7 7\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":17},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 5h16M4 12h16M4 19h16\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":19},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m22 7l-8.991 5.727a2 2 0 0 1-2.009 0L2 7\"\u002F>\u003Crect width=\"20\" height=\"16\" x=\"2\" y=\"4\" rx=\"2\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":21},"\u003Cpath fill=\"currentColor\" d=\"M14.234 10.162L22.977 0h-2.072l-7.591 8.824L7.251 0H.258l9.168 13.343L.258 24H2.33l8.016-9.318L16.749 24h6.993zm-2.837 3.299l-.929-1.329L3.076 1.56h3.182l5.965 8.532l.929 1.329l7.754 11.09h-3.182z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":23,"hidden":24},"\u003Cpath fill=\"currentColor\" d=\"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037c-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85c3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.06 2.06 0 0 1-2.063-2.065a2.064 2.064 0 1 1 2.063 2.065m1.782 13.019H3.555V9h3.564zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0z\"\u002F>",true,{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":26},"\u003Cpath fill=\"currentColor\" d=\"M12 24C5.385 24 0 18.615 0 12S5.385 0 12 0s12 5.385 12 12s-5.385 12-12 12m10.12-10.358c-.35-.11-3.17-.953-6.384-.438c1.34 3.684 1.887 6.684 1.992 7.308a10.28 10.28 0 0 0 4.395-6.87zm-6.115 7.808c-.153-.9-.75-4.032-2.19-7.77l-.066.02c-5.79 2.015-7.86 6.025-8.04 6.4a10.16 10.16 0 0 0 6.29 2.166c1.42 0 2.77-.29 4-.814zm-11.62-2.58c.232-.4 3.045-5.055 8.332-6.765q.202-.067.405-.12q-.392-.879-.832-1.74C7.17 11.775 2.206 11.71 1.756 11.7l-.004.312c0 2.633.998 5.037 2.634 6.855zm-2.42-8.955c.46.008 4.683.026 9.477-1.248a66 66 0 0 0-3.8-5.928a10.28 10.28 0 0 0-5.676 7.17zM9.6 2.052c.282.38 2.145 2.914 3.822 6c3.645-1.365 5.19-3.44 5.373-3.702A10.2 10.2 0 0 0 12 1.764c-.825 0-1.63.1-2.4.285zm10.335 3.483c-.218.29-1.935 2.493-5.724 4.04c.24.49.47.985.68 1.486c.08.18.15.36.22.53c3.41-.43 6.8.26 7.14.33c-.02-2.42-.88-4.64-2.31-6.38z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":28},"\u003Cpath fill=\"currentColor\" d=\"M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"\u002F>",[30,70,105,138,170,199],{"path":31,"title":32,"client":33,"excerpt":34,"industry":35,"services":36,"year":40,"kind":41,"accent":42,"cover":43,"coverAlt":44,"featured":24,"outcomes":45},"\u002Fwork\u002Fnorthwind-design-system","One design system across four acquired products","Northwind Cloud",null,"SaaS",[37,38,39],"Design Systems","Product Design","Frontend Engineering","2026","concept","#00D4FF","\u002Fcase-studies\u002Fnorthwind\u002Fscreens\u002Ftoken-architecture.webp","Northwind design system — the three-layer token architecture screen",[46,50,54,58,62,66],{"value":47,"label":48,"description":49},"11 → 1","Button implementations","Eleven divergent buttons across four codebases, expressed as one component whose variant table is its contract.",{"value":51,"label":52,"description":53},"214","Tokens across three layers","Primitives, semantic roles and component tokens — replacing the 2,847 unrelated raw values the scenario audit assumes.",{"value":55,"label":56,"description":57},"48","Components specified","Each with its variants, states, keyboard behaviour and accessibility contract declared in a single table.",{"value":59,"label":60,"description":61},"1","Layer a rebrand touches","Products consume semantic roles only. Changing the brand is an edit to layer two, not a search across four repositories.",{"value":63,"label":64,"description":65},"3","Steps to use a system component","Down from nine in the modelled current-state flow — see the flow comparison below.",{"value":67,"label":68,"description":69},"4 → 1","Sources of truth","One published library, consumed identically by design tooling and every front-end.",{"path":71,"title":72,"client":73,"excerpt":34,"industry":74,"services":75,"year":40,"kind":41,"accent":78,"cover":79,"coverAlt":80,"featured":6,"outcomes":81},"\u002Fwork\u002Fmeridian-clinical-ai","Designing an AI that clinicians are allowed to disagree with","Meridian Health","Healthcare",[76,38,77],"AI Product Design","Product Strategy","#22C55E","\u002Fcase-studies\u002Fmeridian\u002Fscreens\u002Freview-surface.webp","Meridian clinical review surface with evidence above the recommendation",[82,85,89,93,97,101],{"value":67,"label":83,"description":84},"Interactions to record disagreement","A modal, a taxonomy select and a free-text justification collapsed into one inline control that captures the same audit data.",{"value":86,"label":87,"description":88},"100%","Recommendations carrying provenance","Every recommendation links the specific record fields that drove it. Previously none did.",{"value":90,"label":91,"description":92},"3 bands","Replacing a confidence percentage","A calibrated three-band scale, because \"87% confident\" was read as either meaningless or falsely precise.",{"value":94,"label":95,"description":96},"9 → 4","Screens in the review path","Reasoning, evidence and history moved into the review surface instead of sitting behind separate navigations.",{"value":98,"label":99,"description":100},"2","Actions with equal affordance","Accept and disagree are the same size, the same distance from the pointer, and neither is the default.",{"value":102,"label":103,"description":104},"0","Automatic actions","The model never writes to the record. It argues; a person decides.",{"path":106,"title":107,"client":108,"excerpt":34,"industry":109,"services":110,"year":112,"kind":41,"accent":113,"cover":114,"coverAlt":115,"featured":6,"outcomes":116},"\u002Fwork\u002Fledgerly-onboarding","Rebuilding onboarding around the first useful moment","Ledgerly","Fintech",[111,38,39],"SaaS Design","2025","#7C3AED","\u002Fcase-studies\u002Fledgerly\u002Fscreens\u002Ffirst-run.webp","Ledgerly first run — a sample ledger reconciling on load",[117,121,125,128,131,135],{"value":118,"label":119,"description":120},"9 → 3","Steps before the first reconciliation","Six administrative steps deferred until after the user has seen the product do its job once.",{"value":122,"label":123,"description":124},"6","Setup tasks moved after first value","Teammate invites, chart of accounts, reconciliation rules and three settings, each requested at the point it is first needed.",{"value":59,"label":126,"description":127},"Screens in the activation path","A single progressive surface replacing a five-screen wizard and a persistent checklist panel.",{"value":102,"label":129,"description":130},"Checklists","Removed entirely. It measured completion of a sequence that did not predict anything.",{"value":132,"label":133,"description":134},"47 → 6 min","Modelled time to first reconciliation","A walkthrough estimate of the redesigned path against the current one, counting only unavoidable waits.",{"value":63,"label":136,"description":137},"Fields required before signup completes","Email, password and country. Everything else is asked when the product needs it.",{"path":139,"title":140,"client":141,"excerpt":34,"industry":142,"services":143,"year":112,"kind":41,"accent":145,"cover":146,"coverAlt":147,"featured":6,"outcomes":148},"\u002Fwork\u002Ffleetwise-dashboard","A fleet dashboard people stop exporting to spreadsheets","Fleetwise","Logistics",[144,38,39],"Dashboard Design","#F59E0B","\u002Fcase-studies\u002Ffleetwise\u002Fscreens\u002Fcomposable-query.webp","Fleetwise composable query above a virtualised shipment table",[149,153,156,159,163,166],{"value":150,"label":151,"description":152},"1 → n","Simultaneous filter conditions","A single-select filter bar replaced by a stackable condition builder with and\u002For grouping.",{"value":98,"label":154,"description":155},"Filtered sets visible at once","A split view for the comparison operators previously did by opening two spreadsheet windows.",{"value":102,"label":157,"description":158},"Views lost on refresh","Saved views persist the full query, column set, sort and density, and are shareable by URL.",{"value":160,"label":161,"description":162},"40,000","Rows held at interactive latency","Virtualised body with client-side filtering, so exploration does not cost a server round-trip per keystroke.",{"value":67,"label":164,"description":165},"Screens to answer a recurring question","The daily questions operators asked became saved views on one surface instead of four navigations.",{"value":167,"label":168,"description":169},"12","Table states specified","Loading, empty, filtered-empty, error, partial, stale and six selection states — the ones dense tables usually omit.",{"path":171,"title":172,"client":173,"excerpt":34,"industry":174,"services":175,"year":40,"kind":41,"accent":176,"cover":177,"coverAlt":178,"featured":6,"outcomes":179},"\u002Fwork\u002Fverdigris-marketplace","An e-commerce system where every product is one of one","Verdigris","E-commerce",[38,37,39],"#E07A5F","\u002Fcase-studies\u002Fverdigris\u002Fscreens\u002Flisting.webp","Verdigris listing with condition and declared flaws above the description",[180,183,186,189,192,195],{"value":122,"label":181,"description":182},"Standardised condition grades","A fixed vocabulary with written definitions and worked examples, replacing free-text seller descriptions.",{"value":86,"label":184,"description":185},"Listings requiring photographed flaws","Publication is blocked until every declared flaw carries a close photograph at a stated distance.",{"value":67,"label":187,"description":188},"Screens to judge a piece","Condition, dimensions, provenance and flaw detail consolidated onto the listing itself.",{"value":102,"label":190,"description":191},"Countdown timers or scarcity pressure","One-of-one inventory is stated as a fact. Nothing in the interface manufactures urgency on top of it.",{"value":98,"label":193,"description":194},"Scale references per listing","A human figure and a standard doorway, generated from the measured dimensions rather than illustrated.",{"value":196,"label":197,"description":198},"9","Provenance fields captured at intake","Period, maker, materials, origin, prior restoration and four more — structured, so they are filterable rather than prose.",{"path":200,"title":201,"client":202,"excerpt":34,"industry":203,"services":204,"year":40,"kind":41,"accent":205,"cover":206,"coverAlt":207,"featured":6,"outcomes":208},"\u002Fwork\u002Fhalyard-progressive-delivery","A progressive delivery console that can answer \"who is seeing this?\"","Halyard","Developer Tools",[38,37,39],"#818CF8","\u002Fcase-studies\u002Fhalyard\u002Fscreens\u002Fflag-surface.webp","Halyard flag surface leading with the computed audience",[209,212,216,219,222,225],{"value":59,"label":210,"description":211},"Authoritative answer to \"who sees this\"","A computed audience, replacing four rule surfaces a reader had to combine mentally to reach an answer.",{"value":213,"label":214,"description":215},"5 → 1","Screens to diagnose a rollout","Flag state, environment, cohort membership, overrides and evaluation history consolidated onto one surface.",{"value":102,"label":217,"description":218},"Confirmation dialogs on the kill switch","One action, no modal. Safety comes from scope, reversibility and an audit entry, not from a dialog nobody reads at 3am.",{"value":86,"label":220,"description":221},"Flags carrying an expiry","Creation requires one. A flag without an expiry is permanent branching disguised as a temporary experiment.",{"value":122,"label":223,"description":224},"Lifecycle states specified","Draft, rolling, held, complete, expiring and archived — making flag debt visible as a state rather than a spreadsheet.",{"value":59,"label":226,"description":227},"Action to explain any evaluation","Paste an identifier, get the exact rule path that produced that user's variant, including which rule short-circuited.",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":229},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m9 18l6-6l-6-6\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":231},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14 2v6a2 2 0 0 0 .245.96l5.51 10.08A2 2 0 0 1 18 22H6a2 2 0 0 1-1.755-2.96l5.51-10.08A2 2 0 0 0 10 8V2M6.453 15h11.094M8.5 2h7\"\u002F>",1787594495072]