<?xml version="1.0" encoding="UTF-8" standalone="no"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:gd="http://schemas.google.com/g/2005" xmlns:georss="http://www.georss.org/georss" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-9165069509664255576</atom:id><lastBuildDate>Sun, 03 May 2026 23:04:38 +0000</lastBuildDate><category>Business SEO</category><category>Design</category><category>CSS</category><category>SEO</category><category>UI</category><category>PHP</category><category>Tools</category><category>Magento</category><category>javascript</category><category>Techniques</category><category>UX</category><category>Web Design</category><category>Inspiration</category><category>Workflow</category><category>Business</category><category>AI</category><category>Accessibility</category><category>Usability</category><category>User experience</category><category>GEO</category><category>Responsive Web design</category><category>Coding</category><category>asp.net</category><category>shopify</category><category>liquid</category><category>Apps</category><category>Tips</category><category>tutorial</category><category>Wordpress</category><category>c-sharp</category><category>CSS3</category><category>API</category><category>HTML</category><category>Amazon</category><category>Performance</category><category>.NET</category><category>Security</category><category>Resources</category><category>Typography</category><category>guides</category><category>html5</category><category>Communication</category><category>Web Designers</category><category>Mobile</category><category>WebDevelopment</category><category>social media</category><category>webdev</category><category>jQuery</category><category>LINUX</category><category>Tutorials</category><category>E-Commerce</category><category>React</category><category>design patterns</category><category>Frameworks</category><category>MySQL</category><category>optimization</category><category>Designers</category><category>How to</category><category>ML</category><category>content</category><category>Animation</category><category>CMS</category><category>Design Systems</category><category>Testing</category><category>C#</category><category>Freelancing</category><category>Android</category><category>Essentials</category><category>User Research</category><category>Blogging</category><category>Clients</category><category>Java</category><category>mobile technology</category><category>Marketing</category><category>Modern business</category><category>Browsers</category><category>Process</category><category>Security in MVC</category><category>WordPress Themes</category><category>development</category><category>Career</category><category>Case Studies</category><category>Creativity</category><category>Figma</category><category>LLM</category><category>MVC5</category><category>Plugins</category><category>Web Development</category><category>mvc</category><category>Banking</category><category>Code</category><category>Magento Tips &amp; Tricks</category><category>Productivity</category><category>best practices</category><category>cloud</category><category>Headless</category><category>Navigation</category><category>Next.js</category><category>Opinion</category><category>Research</category><category>azure</category><category>cPanel</category><category>google</category><category>web</category><category>website</category><category>windows</category><category>windows azure</category><category>AI marketing</category><category>Ajax</category><category>Apple</category><category>ECommerce</category><category>Interaction</category><category>Networking</category><category>Photoshop</category><category>Product Strategy</category><category>SVG</category><category>how-to</category><category>ipad</category><category>responsive design</category><category>smpf</category><category>Core Web vitals</category><category>Facebook</category><category>News</category><category>Search Engine Optimization</category><category>Teams</category><category>User Interface</category><category>Web Developers</category><category>Websites</category><category>c</category><category>trends</category><category>updates</category><category>Graphic Design</category><category>HTML 5</category><category>IPhone</category><category>Layouts</category><category>Psychology</category><category>Serverless</category><category>Website performance</category><category>algorithm</category><category>cloud computing</category><category>ocr</category><category>traffic</category><category>ASP.NET5</category><category>Active Directory</category><category>Browser</category><category>CSS Basics</category><category>Data Science</category><category>Email</category><category>Encryption</category><category>FOG</category><category>Fonts</category><category>Illustration</category><category>Node.js</category><category>Round-Ups</category><category>WHM</category><category>Web Designs</category><category>best of lists</category><category>cool apps</category><category>free tools</category><category>front-end</category><category>laravel</category><category>linkedin</category><category>python</category><category>strategy</category><category>technology</category><category>tips and tricks</category><category>user interaction</category><category>Branding</category><category>Centos</category><category>Flash</category><category>Freelancers</category><category>General</category><category>Global Web Design</category><category>HR</category><category>JSP</category><category>Logo</category><category>MVP</category><category>Machine learning</category><category>SystemDesign</category><category>Technology trends</category><category>UX design</category><category>app</category><category>cross-browser</category><category>free</category><category>mobiles</category><category>salesforce</category><category>sap</category><category>share</category><category>twitter</category><category>web 2.0</category><category>web designer</category><category>webdesign tips</category><category>Animations basics</category><category>Artificial Intelligence</category><category>Bootstrap</category><category>Community</category><category>DevTools</category><category>Drupal</category><category>EWM</category><category>Execution</category><category>Firewalls</category><category>Founders</category><category>IE CSS</category><category>IIS 7.0</category><category>Icons</category><category>Information</category><category>Internal communications</category><category>Internet Explorer</category><category>Jamstack</category><category>Joomla</category><category>Opinion Column</category><category>Oracle</category><category>ProductManagement</category><category>Programming</category><category>RWD</category><category>Responsive Websites</category><category>Review</category><category>Startups</category><category>UBUNTU</category><category>Visual Design</category><category>Website Design</category><category>XSS</category><category>coding tips</category><category>communities</category><category>database</category><category>layout</category><category>memory</category><category>mobile ready website</category><category>samba</category><category>windows 7</category><category>3D</category><category>AI Tools</category><category>Advertising</category><category>Android apps</category><category>Best of Web</category><category>Business Apps</category><category>CSS frameworks</category><category>Classification Model</category><category>Color</category><category>Colors</category><category>Compilation</category><category>Configure WordPress</category><category>Conversions</category><category>Corporate</category><category>Cross Site Scripting Attack</category><category>Cross Site scripting</category><category>Data Visualization</category><category>Design System</category><category>Design Trends</category><category>DevOps</category><category>Digital Marketing</category><category>Education</category><category>Effects</category><category>Errors</category><category>Ethan Marcotte</category><category>Examples and Practices</category><category>Forms</category><category>Framework</category><category>GraphQL</category><category>Great Business Resources</category><category>Humor</category><category>JSF</category><category>MVC6</category><category>Magento Bug Fixes</category><category>Media Queries</category><category>New Technologies</category><category>New Technology</category><category>On Page SEO</category><category>PPC</category><category>Personalization</category><category>Photography</category><category>Project Management</category><category>ProjectManagement</category><category>Redesign</category><category>SOLID</category><category>Showcase</category><category>Skills</category><category>Solid principles</category><category>Start-Ups</category><category>Windows 2008</category><category>Wireless Techchnology</category><category>access denied</category><category>analytics</category><category>backup</category><category>best windows mobile apps</category><category>business goals</category><category>css3 transition</category><category>debugging</category><category>devices</category><category>freelance</category><category>generator</category><category>http</category><category>imaging</category><category>js</category><category>mac</category><category>mobile application</category><category>models</category><category>productivity Apps</category><category>pytorch</category><category>semantics</category><category>seo friendly</category><category>sharepoint 2010</category><category>sharer</category><category>snapins</category><category>solid principles in .NET</category><category>storage</category><category>themeforest</category><category>vue</category><category>xml</category><category>32 bit drivers</category><category>404</category><category>Active Directory 2008</category><category>Active Injection</category><category>Administration</category><category>Adobe</category><category>Amazon workspaces</category><category>Art</category><category>Articles</category><category>Authentication Provider</category><category>Autonomous AI Agents</category><category>BeyondTheBrowser</category><category>Branding Advertisement</category><category>Business Tools</category><category>CSRF</category><category>Calendar</category><category>Captcha</category><category>Chrome</category><category>ChromeDev</category><category>ChromeDeveloper</category><category>Codes and Scripts</category><category>Computational Thinking</category><category>Conferences</category><category>Cookie Stealing</category><category>Credit cards</category><category>Cross Site Request Forgery</category><category>Customer Experience</category><category>DDOS Attack</category><category>Design patters</category><category>DigitalTransformation</category><category>Docs</category><category>EO</category><category>Eclipse</category><category>Ethics</category><category>Events</category><category>Exim</category><category>Expression Engine</category><category>External Authentication Provider</category><category>Feature Engineering Feature</category><category>Finding Work</category><category>Fireworks</category><category>Front</category><category>FrontEndDevelopment</category><category>Functions</category><category>Gatsby</category><category>Get Started</category><category>Google SGE</category><category>Guidelines</category><category>HTACCESS</category><category>IE bugs</category><category>Images</category><category>Innovation</category><category>Instagram</category><category>Installation</category><category>Interactivity</category><category>Internet</category><category>Java basics</category><category>Javascript Libraries</category><category>Laboratory</category><category>Language and Communication</category><category>Leadership</category><category>Learning</category><category>LocalStorage</category><category>MSSQL</category><category>Magento 1.7</category><category>Magento Core Hacks</category><category>Mail Manage</category><category>Mail Queues</category><category>Mental Health</category><category>NET</category><category>PPC Beginner</category><category>Passive Injection</category><category>Plesk</category><category>Preprocessors for CSS</category><category>ProductDesign</category><category>Query</category><category>Query-Intent Targeting</category><category>REST</category><category>Roundup</category><category>Ruby on Rails</category><category>SCM</category><category>SMTP</category><category>SQL</category><category>Sass</category><category>Search Engine Optimisation</category><category>Selling Web Design</category><category>Shortcodes</category><category>Social Networking</category><category>Software</category><category>SoftwareDevelopment</category><category>Storytelling</category><category>TV</category><category>Techiques</category><category>Templates</category><category>URL REWRITE</category><category>Virtual Workers</category><category>Visual Studio 2015</category><category>Voice</category><category>Web Components</category><category>Web Design Inspiration</category><category>Web Pro Business</category><category>Web Security</category><category>Web.config</category><category>WebDev2026</category><category>Webmasters</category><category>Website Builder</category><category>Wi-Fi</category><category>Windows Form</category><category>Wolfram|Alpha</category><category>Workshops</category><category>XSS Attack</category><category>apache</category><category>asp</category><category>best iPhone 4S games</category><category>blogs</category><category>clean code</category><category>client</category><category>configuration</category><category>contact form</category><category>conv-neural-network</category><category>crm</category><category>css framework</category><category>deal</category><category>dll</category><category>erp</category><category>exception</category><category>explicit</category><category>exploit</category><category>facebook apps</category><category>fiction</category><category>flipkart</category><category>form</category><category>games</category><category>genetic algorithm</category><category>gif</category><category>github</category><category>gmail</category><category>google+</category><category>handling errors</category><category>headers</category><category>help and support</category><category>html5 browser</category><category>inspiration design</category><category>jailbreak</category><category>jobmarket</category><category>magento 1.5.1</category><category>magentoui</category><category>malloc</category><category>manufacturing</category><category>masterdata</category><category>mobile apps</category><category>mobile development</category><category>mobile first</category><category>mobile payments</category><category>mozilla addons</category><category>offshore outsourcing</category><category>online networking</category><category>outsourcing</category><category>perl script</category><category>png</category><category>pointers</category><category>reactjs</category><category>responsive designs</category><category>responsive website</category><category>revenue</category><category>search engine</category><category>search index</category><category>sharepoint 2010 error</category><category>social media for business</category><category>social media management</category><category>social media strategy</category><category>software delivery strategy</category><category>speed</category><category>supervised learning</category><category>tesseract</category><category>textbox</category><category>tool</category><category>travel</category><category>user centered design</category><category>vision</category><category>vlan</category><category>web applications</category><category>web design tips</category><category>whatsapp</category><category>widgets</category><category>wordpress multisite network</category><category>+1</category><category>2008 AD</category><category>2011 trends</category><category>2026 AI Marketing Tools</category><category>A11y</category><category>AES</category><category>AI Answers</category><category>AI Marketing Tools</category><category>AI&lt;ML</category><category>AIO Guide</category><category>AIReadiness</category><category>AIinHealthcare</category><category>APF</category><category>ARIMA</category><category>ActionResult</category><category>ActiveDirectory</category><category>Add Terms and Conditions</category><category>Adobe Catalyrst</category><category>Advertisement</category><category>Agile</category><category>Amaon</category><category>Android App Development</category><category>Angular</category><category>Angular JS</category><category>Anti-Spam</category><category>Apache lucene</category><category>Apache lucene indexing</category><category>AppsBusinessContent Strategy</category><category>Array</category><category>Automation #Leadership</category><category>B2B</category><category>BI</category><category>Backgrounds</category><category>Barcode</category><category>BbPress</category><category>Benefits of Blog</category><category>Best Facebook Apps for iPad</category><category>Best Of</category><category>Big Picture</category><category>BiotechIndustry</category><category>BlackBerry Apps</category><category>Blockchain Uses</category><category>Blockchain in Payment System</category><category>Blogging Benefits</category><category>Blogging Tips</category><category>Blue Color Websites</category><category>Bootable</category><category>Brands as Entities</category><category>BuildInPublic</category><category>Buttons</category><category>By Noupe     Posted in AJAX</category><category>C# 6</category><category>C# 6.0</category><category>C#.Angular</category><category>CAPM</category><category>CIO</category><category>CQS</category><category>CSF</category><category>CSS Grid</category><category>CTO</category><category>Canvas</category><category>Capacity Planning</category><category>Case Studty</category><category>Cell Phones</category><category>Cheat Sheets</category><category>ChromeDeveloperTool</category><category>Clamav</category><category>ClickJacking</category><category>ClickJacking Attack</category><category>ClinicalResearch</category><category>CloudComputing</category><category>CloudCostOptimization</category><category>CloudMigration</category><category>CloudOptimization</category><category>Clubhouse</category><category>Code Review</category><category>Collection</category><category>Command Query Separation</category><category>ConfigServer</category><category>Configure WordPress Multisite</category><category>Console</category><category>ConsoleTab</category><category>Content Strategy</category><category>Copywriting</category><category>CostOptimization</category><category>Creative Ads</category><category>Custom Error</category><category>Custom Menu</category><category>Custom Tag Helper</category><category>DCPROMO</category><category>Daring Fireball</category><category>DataDrivenHealthcare</category><category>DataManagement</category><category>DataMigration</category><category>Databases</category><category>Debugging Features</category><category>Decision Tree</category><category>Dell N5010</category><category>Design Principles</category><category>Developer Tools</category><category>DigitalHealth</category><category>Dimensionality reduction</category><category>Discord</category><category>Discussions</category><category>E-Commerce Themes</category><category>E-E-A-T</category><category>EWMjobs</category><category>Ecommerce-Website-Security</category><category>EdgeComputing</category><category>Elmah</category><category>Elmah Session Hijack</category><category>Elmah Session Hijakcking</category><category>Emotional Design</category><category>Enable Terms and Conditions</category><category>Encapsulation</category><category>EnterpriseIT</category><category>Error</category><category>Error Messages WP</category><category>Evaluation</category><category>Evaluation Confusion Matrix</category><category>Evaluation Methods</category><category>Evergreen</category><category>Excel</category><category>Experience Design</category><category>FBA</category><category>FORECASTING ANALYTICS</category><category>Facebook Authentication Provider</category><category>Facebook Designs</category><category>Facebook apps for students</category><category>Feature scaling in machine learning</category><category>Features C# 6</category><category>FinanceTransformation</category><category>Find Clients</category><category>Firefox extension</category><category>Fixes</category><category>Flash Drive</category><category>Flash Mobile</category><category>Fluid Layouts</category><category>Forum</category><category>Foundation5</category><category>Framework Information</category><category>Free Wordpress Plugins</category><category>Free Wordpress Portfolio themes</category><category>Freebies</category><category>Future</category><category>Future Perspectives</category><category>GEEO</category><category>GLFW</category><category>GPS</category><category>GenerativeAI</category><category>GeoLocation</category><category>Gini</category><category>Git</category><category>Glossaries</category><category>Google Treats Brands as Entities</category><category>GoogleChrome</category><category>Graphics</category><category>Green Business</category><category>Green Color Websites</category><category>HT</category><category>HTTP requests</category><category>Hamstack</category><category>Hardware problem</category><category>HealthcareAnalytics</category><category>HealthcareData</category><category>Hide Price</category><category>How to Make a Website</category><category>HttpOnly</category><category>HttpOnly Login</category><category>Hugo</category><category>Hybrid</category><category>I</category><category>IE</category><category>IOS App Development</category><category>IT strategy</category><category>ITConsulting</category><category>Ideation</category><category>Illustrator</category><category>Image optimization</category><category>ImageMagick</category><category>Importance of Blog</category><category>Index</category><category>Infographics</category><category>Infrastructure</category><category>InfrastructureManagement</category><category>Insecure Direct Object Reference</category><category>Insecure Object Reference</category><category>Interface Design</category><category>Internationalization</category><category>Interview</category><category>Interviews</category><category>JSON</category><category>Java FAQ</category><category>Javascript basics</category><category>John Gruber</category><category>Keyword Research</category><category>Kids</category><category>LMD</category><category>LSI keywords</category><category>LSP</category><category>Lambda Expression Visual Studio</category><category>Laptop</category><category>Less</category><category>LifeScienceAnalytics</category><category>LifeSciences</category><category>Linkedin groups</category><category>Linux Malware Detect</category><category>Liskov</category><category>Liskov Substitution Principle</category><category>Liskov Substitution Principle in .NET</category><category>Localization</category><category>Localizations</category><category>Login Http</category><category>Logo Design</category><category>MAgent</category><category>MDG</category><category>MDX</category><category>MVC4</category><category>Machine learning Model</category><category>Magento 1.4</category><category>Magento 1.7.0</category><category>Magento 1.7.0.2</category><category>Magento 1.7.x</category><category>Magento Checkout</category><category>Magento Extensions</category><category>Magento Products</category><category>Magento Templates</category><category>Magento Tutorials</category><category>Magento zip plus 4</category><category>Magento zip plus four</category><category>Management Tips</category><category>MarketResearch</category><category>Master Semantic SEO</category><category>Mathematica</category><category>Membership Premium</category><category>Memberships</category><category>Menus/Navigation</category><category>Microsoft</category><category>Middleware</category><category>MiniTab Screen</category><category>ModSecurity</category><category>Model</category><category>Mootools</category><category>Multisite</category><category>MySQ</category><category>Nagento</category><category>Netstat</category><category>Network</category><category>Newsletters</category><category>NextJs</category><category>OCP</category><category>OCP in .NET</category><category>Object Oriented Principles</category><category>Object Reference</category><category>Online Storage</category><category>Only machine administrators are allowed</category><category>Open Closed Principle</category><category>Open Redirection</category><category>Open Redirection Attack</category><category>OpenGL</category><category>Opera</category><category>Over Posting</category><category>Over Posting Attack</category><category>Over Posting Attack MVC</category><category>Overflow</category><category>PANDAS</category><category>PBI</category><category>PHPMyAmin</category><category>PMP</category><category>PMbestpractice</category><category>POS</category><category>POST</category><category>PWA</category><category>Page SEO</category><category>Paypal API</category><category>PerfTip</category><category>Performa</category><category>PharmaAnalytics</category><category>Philosophy</category><category>PhpMyAdmin</category><category>Pine Script</category><category>Pinterest</category><category>Portfolio design</category><category>Power BI</category><category>Print</category><category>Printing</category><category>Privacy</category><category>Product Page</category><category>ProductThinking</category><category>Profiling</category><category>ProgramManagement</category><category>ProjectManager</category><category>Publishing</category><category>Python Programming</category><category>Quora</category><category>Quote and Comment</category><category>RIM</category><category>RSA</category><category>RSS</category><category>React native</category><category>React native createClass</category><category>React native undefined</category><category>Recruitment</category><category>Redux</category><category>Regression Model</category><category>Remote Access</category><category>Remove Price</category><category>Resource</category><category>Response Header</category><category>Restaurant POS</category><category>Resumes</category><category>Round Tips</category><category>Routing</category><category>Routing Constraints</category><category>SAPSCM</category><category>SAPTransformation</category><category>SAPopportunities</category><category>SCMoppportunities</category><category>SCSS</category><category>SEO Friendly themes</category><category>SEO agency</category><category>SEOBusibness</category><category>SMS Authentication in MVC</category><category>SRP</category><category>SRP in .NET</category><category>Sahrepoint</category><category>Salesforce package install failed</category><category>Schema Markup</category><category>Search</category><category>Search engines</category><category>Secret Manager</category><category>SecretManager</category><category>Secure Object Reference</category><category>Selection Methods</category><category>Sell Your Services</category><category>Sell online</category><category>Selling Web Design Services</category><category>Semantic SEO</category><category>Session Hijack</category><category>Session Hijack Elmah</category><category>Session Hijacking</category><category>Session Hijacking using Elmah</category><category>Share Chat</category><category>SharePoint 2010 Search</category><category>SharePoint search results</category><category>Simple Script Makes Powerfull Count</category><category>Smashing Books</category><category>SoftwareArchitecture .ProjectManagement</category><category>Sprites</category><category>Stack trace</category><category>StartupGrowth</category><category>Static Generators</category><category>Steal Credentials</category><category>Stories</category><category>StringBuffer Class</category><category>Studies</category><category>Surf  with different proxy</category><category>TIME SERIES FORECASTING</category><category>TIME SERIES TIME SERIES ANALYSIS</category><category>Tablets</category><category>Tabs</category><category>Tag Helper</category><category>Tag helper Advantage</category><category>Tax+4</category><category>Teamwork</category><category>TechLeadership</category><category>Technique</category><category>Techniques
Typography</category><category>TempData</category><category>Terms and Conditions</category><category>Texture Based Website</category><category>Themes</category><category>Time savers</category><category>Timeseries</category><category>Timten-AgentParser</category><category>Top Facebook Apps for iPad</category><category>Transitions</category><category>Travel Templates</category><category>Trend</category><category>Tumblr</category><category>Tutoril</category><category>TypeScript</category><category>UX Research</category><category>Unblock</category><category>Unblock Facebook</category><category>Undefined is not an object(evaluating'_react2.default.PropType.bool') react native update react update</category><category>Uploaders</category><category>User Exp</category><category>User Reasearch</category><category>VB.NET Quiz</category><category>VNACloud</category><category>Varien</category><category>Version Information</category><category>Video</category><category>Video Converters</category><category>View</category><category>ViewBag</category><category>ViewData</category><category>ViewModel</category><category>VirtuMart</category><category>Virtual Box</category><category>Virtual Office</category><category>Visual Studio</category><category>Visualization</category><category>Vuew</category><category>WP errors</category><category>Wasm</category><category>Web Designing</category><category>Web Hosting</category><category>Web technologies</category><category>WebAccessibility</category><category>WebAssembly</category><category>WebGL</category><category>Website Designing</category><category>White screen WordPress</category><category>Window XP</category><category>Windows Apps</category><category>Windows Server</category><category>Windows server 2008</category><category>Wireless</category><category>Wolfram Language</category><category>WordPress Ad Plugins</category><category>WordPress Catfish Ads</category><category>WordPress Flyout Ads</category><category>WordPress Membership website</category><category>WordPress network with multiple domains</category><category>WordPress network without subdomains</category><category>Wordpress Amazon S3</category><category>Wordpress Migration to Catalyst</category><category>Wordpress blogs</category><category>Writing</category><category>XSRF</category><category>Xhtml</category><category>YQL</category><category>ZURB Foundation</category><category>Zip+4</category><category>add fields</category><category>adversal machine learning</category><category>adverserial machine learning</category><category>advertise</category><category>amazon client</category><category>android gps apps</category><category>android vs ios</category><category>antivirus</category><category>application architecture architecture GraphQL gRPC REST</category><category>applications</category><category>appsettings</category><category>arp</category><category>ascii-art</category><category>aslr</category><category>asp dot net</category><category>asp.net development</category><category>asug</category><category>attributes</category><category>auto discounts</category><category>back-end</category><category>bad comment</category><category>barcod</category><category>base64</category><category>bbuffer-overflow</category><category>beautifulsoup</category><category>best iPhone</category><category>bigcommerce</category><category>blockquote</category><category>blogging tools</category><category>books</category><category>browser hacks</category><category>bsod</category><category>buddypress spam</category><category>buddypress spam activity</category><category>buddypress spam plugin</category><category>budget</category><category>buffer</category><category>buffer-overflow</category><category>bufferedwritter</category><category>burgerAPI</category><category>burning</category><category>business applications</category><category>business logic</category><category>business networking site</category><category>business value</category><category>cache</category><category>cdp</category><category>change port mstsc</category><category>change port remote desktop</category><category>change rdc port</category><category>change rdp port</category><category>checklists</category><category>choices</category><category>cloud based app</category><category>cloud workspaces</category><category>code faster</category><category>collaboration</category><category>combine multiple javascripts</category><category>command prompt</category><category>comment</category><category>comment in code</category><category>comments</category><category>compile</category><category>compress</category><category>conda</category><category>conference</category><category>configuration in laravel</category><category>connection strings</category><category>consultants</category><category>contact forms</category><category>conv-neural network</category><category>cookie secure</category><category>cookie security</category><category>cookies</category><category>core dumps</category><category>count line</category><category>cpp</category><category>crash</category><category>crawl using python</category><category>crawl using selenium and python</category><category>ctc</category><category>custom error in web config</category><category>custom fields</category><category>customer value</category><category>cyber law</category><category>d3</category><category>data URIs</category><category>data protection</category><category>debian</category><category>decompilation</category><category>decompilaton</category><category>decryption</category><category>dep</category><category>digg</category><category>digital</category><category>directory traversal</category><category>django</category><category>dnsmasq</category><category>domain</category><category>dot net development</category><category>dutch company logo</category><category>dynamic</category><category>dynamic dacebook</category><category>e-commerce development</category><category>e-commerce web development</category><category>e-commerce webstore</category><category>embed</category><category>empathy</category><category>emulators</category><category>encoding</category><category>encrypted code</category><category>error correction</category><category>esx</category><category>ethernet</category><category>example in python</category><category>exploit scanner</category><category>extensions</category><category>facebook app</category><category>facebook connect</category><category>faceboook</category><category>failed missing organization</category><category>fcgi</category><category>feature</category><category>feature scaling</category><category>feedburner share</category><category>file</category><category>filenotfoundexception</category><category>filewritter</category><category>find fonts used online</category><category>find line count</category><category>flash player</category><category>flowplayer</category><category>form validation post and retain form data laravel</category><category>forms in laravel</category><category>foundation</category><category>free Android gps apps</category><category>free iPhone 4S games</category><category>free windows mobile apps</category><category>free wordpress themes</category><category>from validation laravel</category><category>ftp</category><category>giyhub</category><category>gmail extention</category><category>godaddy</category><category>good</category><category>google xml</category><category>graceful degradation</category><category>gradient-descent</category><category>grid Systems</category><category>group policies</category><category>grow</category><category>hana</category><category>headless chrome</category><category>healthcare</category><category>healthcare apps</category><category>hide stack trace</category><category>hosting</category><category>hot-patch</category><category>how to make website</category><category>hp</category><category>htc</category><category>htc explorer</category><category>html5 video plugin</category><category>https</category><category>human resource</category><category>iPhone 4S</category><category>image creator</category><category>image processing</category><category>image slideshow</category><category>install amazon workspaces</category><category>intel-pin</category><category>inter-process-communication</category><category>interfaces</category><category>intimacy</category><category>ios</category><category>ip</category><category>ipad 2 apps</category><category>ipad apps</category><category>ipad.ipad2</category><category>issue in ubuntu</category><category>java collection</category><category>java collection framework</category><category>java collection tutorial</category><category>java collections</category><category>java collections example</category><category>java collections framework</category><category>java example</category><category>java tutorial</category><category>javascript date</category><category>javascript remoting</category><category>javascripts</category><category>job-sites</category><category>jpg</category><category>kernel</category><category>labels</category><category>large file processor</category><category>lazyloading</category><category>learn</category><category>licensing</category><category>lifetime value</category><category>lighning app installation</category><category>linux ubuntu</category><category>linux.</category><category>list</category><category>lldp</category><category>log</category><category>log file parcer</category><category>login</category><category>mac os x</category><category>magento 1.3</category><category>magento 1.8</category><category>magento checkout zip</category><category>magento zip</category><category>magento.ui</category><category>magnto</category><category>make money online</category><category>malicious code</category><category>mangeot</category><category>map</category><category>maps</category><category>material</category><category>matlab</category><category>mean</category><category>menu images</category><category>message</category><category>messenger</category><category>metric</category><category>min-max normalization</category><category>minecraft</category><category>mission</category><category>mobile application tips</category><category>mobile business intelligence</category><category>mobile security</category><category>mobile smart website</category><category>mobile trends</category><category>money</category><category>motog</category><category>msi</category><category>nameserver</category><category>nearest neighbour</category><category>nero</category><category>netbios</category><category>neural network</category><category>neural-network</category><category>neurology</category><category>nodejs</category><category>normalization</category><category>normalization in pandas</category><category>northwest wordpress sites</category><category>nusiness</category><category>oauth2</category><category>ob</category><category>octave</category><category>ogg</category><category>online editors</category><category>online invoice</category><category>online marketing</category><category>online tools</category><category>open source</category><category>optimize</category><category>outsourcing to India</category><category>pacific northwest wordpress</category><category>pagination</category><category>panel</category><category>passing parameter from javascript to controller</category><category>password security</category><category>patch</category><category>payroll management system</category><category>pbis</category><category>performance fix</category><category>performance in java</category><category>performance issue in java</category><category>perl</category><category>perl file parcer</category><category>perl script for count line</category><category>permissions</category><category>phone</category><category>phonegap</category><category>photo gallery</category><category>php.magento</category><category>php8</category><category>phpmagento</category><category>picam</category><category>pinescript</category><category>pixel-art</category><category>popup</category><category>portfolios</category><category>post formats</category><category>prng</category><category>professionalism</category><category>project</category><category>protocol</category><category>proxy</category><category>proxy website</category><category>pscyholopgy</category><category>pwntools</category><category>quotes</category><category>reason for performance</category><category>recaptcha</category><category>reflector</category><category>regex</category><category>registry</category><category>regularexpression</category><category>reinforcement-learning</category><category>remote desktop port  How to change the listening port for RDC/RDP</category><category>remoting</category><category>remoting crud</category><category>rendering</category><category>responsive web designs</category><category>robert martin</category><category>robots.txt</category><category>rpi</category><category>rsync</category><category>ruby</category><category>salesforce issue</category><category>sapcloud</category><category>sapconsultants</category><category>satellite internet</category><category>scraping</category><category>scraping using chrome and selenium</category><category>scraping using python and beautifulsoup</category><category>screenshot</category><category>search engine marketing</category><category>selectors</category><category>server</category><category>services</category><category>servlet</category><category>servlet class</category><category>servlet deploy in tomcat</category><category>servlet example</category><category>servlet tutorial</category><category>set</category><category>set custom error</category><category>set custom error in .net</category><category>setup</category><category>sex</category><category>sharepoint</category><category>shell</category><category>sidebar</category><category>silverlight</category><category>single responsibility principle</category><category>sitemap</category><category>skeleton</category><category>sklearn</category><category>skype</category><category>small business</category><category>smartphones</category><category>smp</category><category>social media automation</category><category>social networking tools</category><category>sockets</category><category>source</category><category>spam</category><category>sql azure</category><category>sql injection</category><category>ssl</category><category>static-analysis</category><category>subscriptions</category><category>supply chain</category><category>svn</category><category>sync</category><category>syntax highlighting</category><category>sysprep</category><category>tac</category><category>tasseract</category><category>tax calculation</category><category>tax not calculated</category><category>tcp</category><category>tech blogging</category><category>tech news</category><category>telegram</category><category>texture pack</category><category>theme authenticity checker</category><category>theme checker</category><category>theora</category><category>thumbnails</category><category>time management</category><category>times ten</category><category>tips to use cloud accounting software</category><category>top performance issue in java</category><category>transactionaldata</category><category>tweaks</category><category>ubunt</category><category>ubuntu login bug</category><category>ubuntu login loop bug</category><category>ultrasurf</category><category>unblock youtube</category><category>unicode</category><category>unix</category><category>unsupervised learning</category><category>unsupervised-learning</category><category>upcoming e-commerce trends</category><category>upgrade</category><category>url</category><category>use LSI keywords</category><category>user interface improvement microsoft</category><category>utf8</category><category>util</category><category>utility</category><category>version control</category><category>vertical align center</category><category>video playlist</category><category>videos</category><category>visualforce page access static resource</category><category>visualforce script remoting</category><category>voip</category><category>volusion</category><category>w3c</category><category>web fonts</category><category>web history</category><category>web marketing</category><category>web standards</category><category>web2 roundups</category><category>webhost security</category><category>website designs</category><category>website headers</category><category>website tools</category><category>websockets</category><category>white blank screen</category><category>why comments bad</category><category>wi-vi technology</category><category>wifi</category><category>windows message</category><category>windows mobile</category><category>windows phone</category><category>wine installation</category><category>wireframing</category><category>wms</category><category>wordpress audio player</category><category>wordpress design</category><category>wordpress help</category><category>wordpress images</category><category>wordpress membership plugin</category><category>wordpress menu</category><category>wordpress multisite registration</category><category>wordpress multisite users</category><category>wordpress plugin</category><category>wordpress plugins</category><category>wordpress showcase</category><category>wordpress video player</category><category>workaholic</category><category>wp to buffer</category><category>yahoo</category><category>yii framework</category><category>youtube to mp3</category><category>youtube videos to mp3</category><category>zip code Magento</category><category>{ine Script</category><category>| search results</category><title>Honey Vig Web Developer Ajax,Jquery, ASP, PHP, dotNET</title><description>Advice, Opinions and Views</description><link>http://honeyvig.blogspot.com/</link><managingEditor>noreply@blogger.com (H)</managingEditor><generator>Blogger</generator><openSearch:totalResults>3399</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><language>en-us</language><itunes:explicit>no</itunes:explicit><itunes:subtitle>Advice, Opinions and Views</itunes:subtitle><itunes:category text="Technology"><itunes:category text="Software How-To"/></itunes:category><itunes:owner><itunes:email>noreply@blogger.com</itunes:email></itunes:owner><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9165069509664255576.post-7229268987186895344</guid><pubDate>Fri, 01 May 2026 08:45:00 +0000</pubDate><atom:updated>2026-05-01T01:45:00.117-07:00</atom:updated><title>Identifying Necessary Transparency Moments In Agentic AI (Part 1)</title><description>&lt;p&gt;&amp;nbsp;Designing for agentic AI requires attention to both the system’s 
behavior and the transparency of its actions. Between the black box and 
the data dump lies a more thoughtful approach.&lt;/p&gt;&lt;div class="c-garfield-summary"&gt;&lt;section aria-label="Quick summary" class="article__summary"&gt;explores how to map decision points and reveal the right moments to build trust through clarity, not noise.&lt;/section&gt;&lt;/div&gt;&lt;p&gt;Designing
 for autonomous agents presents a unique frustration. We hand a complex 
task to an AI, it vanishes for 30 seconds (or 30 minutes), and then it 
returns with a result. We stare at the screen. Did it work? Did it 
hallucinate? Did it check the compliance database or skip that step?&lt;/p&gt;&lt;p&gt;We typically respond to this anxiety with one of two extremes. We either keep the system a &lt;strong&gt;Black Box&lt;/strong&gt;, hiding everything to maintain simplicity, or we panic and provide a &lt;strong&gt;Data Dump&lt;/strong&gt;, streaming every log line and API call to the user.&lt;/p&gt;&lt;p&gt;Neither approach directly addresses the nuance needed to provide users with the ideal level of transparency.&lt;/p&gt;&lt;p&gt;The &lt;em&gt;Black Box&lt;/em&gt; leaves users feeling powerless. The &lt;em&gt;Data Dump&lt;/em&gt;
 creates notification blindness, destroying the efficiency the agent 
promised to provide. Users ignore the constant stream of information 
until something breaks, at which point they lack the context to fix it.&lt;/p&gt;&lt;p&gt;We need an organized way to find the balance. In my previous article, “&lt;a href="https://www.smashingmagazine.com/2026/02/designing-agentic-ai-practical-ux-patterns/"&gt;Designing For Agentic AI&lt;/a&gt;”,
 we looked at interface elements that build trust, like showing the AI’s
 intended action beforehand (Intent Previews) and giving users control 
over how much the AI does on its own (Autonomy Dials). But knowing which
 elements to use is only part of the challenge. The harder question for 
designers is knowing when to use them.&lt;/p&gt;&lt;p&gt;How do you know which 
specific moment in a 30-second workflow requires an Intent Preview and 
which can be handled with a simple log entry?&lt;/p&gt;&lt;p&gt;This article provides a method to answer that question. We will walk through the &lt;strong&gt;Decision Node Audit&lt;/strong&gt;.
 This process gets designers and engineers in the same room to map 
backend logic to the user interface. You will learn how to pinpoint the 
exact moments a user needs an update on what the AI is doing. We will 
also cover an &lt;strong&gt;Impact/Risk matrix&lt;/strong&gt; that will help to prioritize which decision nodes to display and any associated design pattern to pair with that decision.&lt;/p&gt;&lt;h2 id="transparency-moments-a-case-study-example"&gt;Transparency Moments: A Case Study Example&amp;nbsp;&lt;/h2&gt;&lt;p&gt;Consider
 Meridian (not real name), an insurance company that uses an agentic AI 
to process initial accident claims. The user uploads photos of vehicle 
damage and the police report. The agent then disappears for a minute 
before returning with a risk assessment and a proposed payout range.&lt;/p&gt;&lt;p&gt;Initially,
 Meridian’s interface simply showed Calculating Claim Status. Users grew
 frustrated. They had submitted several detailed documents and felt 
uncertain about whether the AI had even reviewed the police report, 
which contained mitigating circumstances. The Black Box created 
distrust.&lt;/p&gt;&lt;p&gt;To fix this, the design team conducted a Decision Node 
Audit. They found that the AI performed three distinct, 
probability-based steps, with numerous smaller steps embedded:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Image Analysis&lt;/strong&gt;&lt;br /&gt;The
 agent compared the damage photos against a database of typical car 
crash scenarios to estimate the repair cost. This involved a confidence 
score.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Textual Review&lt;/strong&gt;&lt;br /&gt;It scanned the police 
report for keywords that affect liability (e.g., fault, weather 
conditions, sobriety). This involved a probability assessment of legal 
standing.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Policy Cross Reference&lt;/strong&gt;&lt;br /&gt;It matched 
the claim details against the user’s specific policy terms, searching 
for exceptions or coverage limits. This also involved probabilistic 
matching.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The team turned these steps into transparency moments. The interface sequence was updated to:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Assessing Damage Photos&lt;/strong&gt;: Comparing against 500 vehicle impact profiles.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Reviewing Police Report&lt;/strong&gt;: Analyzing liability keywords and legal precedent.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Verifying Policy Coverage&lt;/strong&gt;: Checking for specific exclusions in your plan.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The
 system still took the same amount of time, but the explicit 
communication about the agent’s internal workings restored user 
confidence. Users understood that the AI was performing the complex task
 it was designed for, and they knew exactly where to focus their 
attention if the final assessment seemed inaccurate. This design choice 
transformed a moment of anxiety into a moment of connection with the 
user.&lt;/p&gt;&lt;h3 id="applying-the-impact-risk-matrix-what-we-chose-to-hide"&gt;Applying the Impact/Risk Matrix: What We Chose to Hide&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/04/identifying-necessary-transparency-moments-agentic-ai-part1/#applying-the-impact-risk-matrix-what-we-chose-to-hide"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Most
 AI experiences have no shortage of events and decision nodes that could
 potentially be displayed during processing. One of the most critical 
outcomes of the audit was to decide what to keep invisible. In the 
Meridian example, the backend logs generated 50+ events per claim. We 
could have defaulted to displaying each event as they were processed as 
part of the UI. Instead, we applied the risk matrix to prune them:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;em&gt;Log Event:&lt;/em&gt; Pinging Server West-2 for redundancy check.&lt;ul&gt;&lt;li&gt;&lt;em&gt;Filter Verdict:&lt;/em&gt; &lt;strong&gt;Hide.&lt;/strong&gt; (Low Stakes, High Technicality).&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;Log Event:&lt;/em&gt; Comparing repair estimate to BlueBook value.&lt;ul&gt;&lt;li&gt;&lt;em&gt;Filter Verdict:&lt;/em&gt; &lt;strong&gt;Show.&lt;/strong&gt; (High Stakes, impacts user’s payout).&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;By
 cutting out the unnecessary details, the important information — like 
the coverage verification — was more impactful. We created an open 
interface and designed an open &lt;em&gt;experience&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;This approach 
uses the idea that people feel better about a service when they can see 
the work being done. By showing the specific steps (Assessing, 
Reviewing, Verifying), we changed a 30-second wait from a time of worry (&lt;em&gt;“Is it broken?”&lt;/em&gt;) to a time of feeling like something valuable is being created (&lt;em&gt;“It’s thinking”&lt;/em&gt;).&lt;/p&gt;&lt;p&gt;Let’s
 now take a closer look at how we can review the decision-making process
 in our products to identify key moments that require clear information.&lt;/p&gt;&lt;div aria-hidden="true" class="c-friskies-box partners partners__lead partners__lead-place partners__external" data-amount="1" data-audience="non-subscriber" data-remove="true" data-rendered="true"&gt;&lt;ul&gt;&lt;a class="partners__native--smashing" href="https://www.smashingmagazine.com/contact/"&gt;
        &lt;picture&gt;
          &lt;source media="(max-width: 600px)"&gt;&lt;/source&gt;
          &lt;img alt="Advertise with Smashing Magazine" width="325" /&gt;
        &lt;/picture&gt;
      &lt;/a&gt;&lt;/ul&gt;&lt;/div&gt;&lt;h2 id="the-decision-node-audit"&gt;The Decision Node Audit&lt;/h2&gt;&lt;p&gt;Transparency fails when we treat it as a style choice rather than a functional requirement. We have a tendency to ask, &lt;em&gt;“What should the UI look like?”&lt;/em&gt; before we ask, &lt;em&gt;“What is the agent actually deciding?”&lt;/em&gt;&lt;/p&gt;&lt;p&gt;The
 Decision Node Audit is a straightforward way to make AI systems easier 
to understand. It works by carefully mapping out the system’s internal 
process. The main goal is to find and clearly define the exact moments 
where the system stops following its set rules and instead makes a 
choice based on chance or estimation. By mapping this structure, 
creators can show these points of uncertainty directly to the people 
using the system. This changes system updates from being vague 
statements to specific, reliable reports about how the AI reached its 
conclusion.&lt;/p&gt;&lt;p&gt;In addition to the insurance case study above, I 
recently worked with a team building a procurement agent. The system 
reviewed vendor contracts and flagged risks. Originally, the screen 
displayed a simple progress bar: &lt;em&gt;“Reviewing contracts.”&lt;/em&gt; Users hated it. Our research indicated they felt anxious about the legal implications of a missing clause.&lt;/p&gt;&lt;p&gt;We
 fixed this by conducting a Decision Node Audit. I’ve included a 
step-by-step checklist for conducting this audit at the conclusion of 
this article.&lt;/p&gt;&lt;p&gt;We ran a session with the engineers and outlined how
 the system works. We identified “Decision Points” — moments where the 
AI had to choose between two good options.&lt;/p&gt;&lt;p&gt;In standard computer 
programs, the process is clear: if A happens, then B will always happen.
 In AI systems, the process is often based on chance. The AI thinks A is
 probably the best choice, but it might only be 65% certain.&lt;/p&gt;&lt;p&gt;In 
the contract system, we found a moment when the AI checked the liability
 terms against our company rules. It was rarely a perfect match. The AI 
had to decide if a 90% match was good enough. This was a key decision 
point.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/identifying-necessary-transparency-moments-agentic-ai-part1/1-decision-node-structure.png"&gt;&lt;img alt="The diagram shows how to connect a hidden system decision based on probability (an Ambiguity Point) to a visible moment of explanation for the user (a Transparency Moment)." height="437" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/identifying-necessary-transparency-moments-agentic-ai-part1/1-decision-node-structure.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;&lt;strong&gt;Figure 1:&lt;/strong&gt;
 This diagram shows how to connect a hidden system decision based on 
probability (an Ambiguity Point) to a visible moment of explanation for 
the user (a Transparency Moment).&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Once we identified this node, we exposed it to the user. Instead of &lt;em&gt;“Reviewing contracts,”&lt;/em&gt; the interface updated to say: &lt;em&gt;“Liability clause varies from standard template. Analyzing risk level.”&lt;/em&gt;&lt;/p&gt;&lt;p&gt;This
 specific update gave users confidence. They knew the agent checked the 
liability clause. They understood the reason for the delay and gained 
trust that the desired action was occurring on the back end. They also 
knew where to dig in deeper once the agent generated the contract.&lt;/p&gt;&lt;p&gt;To
 check how the AI makes decisions, you need to work closely with your 
engineers, product managers, business analysts, and key people who are 
making the choices (often hidden) that affect how the AI tool functions.
 Draw out the steps the tool takes. Mark every spot where the process 
changes direction because a probability is met. These are the places 
where you should focus on being more transparent.&lt;/p&gt;&lt;p&gt;As shown in Figure 2 below, the Decision Node Audit involves these steps:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Get the team together:&lt;/strong&gt;
 Bring in the product owners, business analysts, designers, key 
decision-makers, and the engineers who built the AI. For example,&lt;/p&gt;&lt;p&gt;Think
 about a product team building an AI tool designed to review messy legal
 contracts. The team includes the UX designer, the product manager, the 
UX researcher, a practicing lawyer who acts as the subject-matter 
expert, and the backend engineer who wrote the text-analysis code.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Draw the whole process:&lt;/strong&gt; Document every step the AI takes, from the user’s first action to the final result.&lt;/p&gt;&lt;p&gt;The
 team stands at a whiteboard and sketches the entire sequence for a key 
workflow that involves the AI searching for a liability clause in a 
complex contract. The lawyer uploads a fifty-page PDF&amp;nbsp;→ The system 
converts the document into readable text.&amp;nbsp;→ The AI scans the pages for 
liability clauses.&amp;nbsp;→ The user waits.&amp;nbsp;→ Moments or minutes later, the 
tool highlights the found paragraphs in yellow on the user interface. 
They do this for many other workflows that the tool accommodates as 
well.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Find where things are unclear:&lt;/strong&gt; Look at the process map for any spot where the AI compares options or inputs that don’t have one perfect match.&lt;/p&gt;&lt;p&gt;The
 team looks at the whiteboard to spot the ambiguous steps. Converting an
 image to text follows strict rules. Finding a specific liability clause
 involves guesswork. Every firm writes these clauses differently, so the
 AI has to weigh multiple options and make a prediction instead of 
finding an exact word match.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Identify the ‘best guess’ steps:&lt;/strong&gt;
 For each unclear spot, check if the system uses a confidence score (for
 example, is it 85% sure?). These are the points where the AI makes a 
final choice.&lt;/p&gt;&lt;p&gt;The system has to guess (give a probability) which 
paragraph(s) closely resemble a standard liability clause. It assigns a 
confidence score to its best guess. That guess is a decision node. The 
interface needs to tell the lawyer it is highlighting a potential match,
 rather than stating it found the definitive clause.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Examine the choice:&lt;/strong&gt;
 For each choice point, figure out the specific internal math or 
comparison being done (e.g., matching a part of a contract to a policy 
or comparing a picture of a broken car to a library of damaged car 
photos).&lt;/p&gt;&lt;p&gt;The engineer explains that the system compares the 
various paragraphs against a database of standard liability clauses from
 past firm cases. It calculates a text similarity score to decide on a 
match based on probabilities.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Write clear explanations:&lt;/strong&gt; Create messages for the user that clearly describe the specific internal action happening when the AI makes a choice.&lt;/p&gt;&lt;p&gt;The content designer writes a specific message for this exact moment. The text reads: &lt;em&gt;Comparing document text to standard firm clauses to identify potential liability risks.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Update the screen:&lt;/strong&gt; Put these new, clear explanations into the user interface, replacing vague messages like &lt;em&gt;“Reviewing contracts.”&lt;/em&gt;&lt;/p&gt;&lt;p&gt;The
 design team removes the generic Processing PDF loading spinner. They 
insert the new explanation into a status bar located right above the 
document viewer while the AI thinks.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Check for Trust:&lt;/strong&gt;
 Make sure the new screen messages give users a simple reason for any 
wait time or result, which should make them feel more confident and 
trusting.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/identifying-necessary-transparency-moments-agentic-ai-part1/2-decision-nodes-ai-legal-tool.png"&gt;&lt;img alt="Comic where a product team maps the decision nodes of an AI legal tool to design transparent interface messages." height="437" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/identifying-necessary-transparency-moments-agentic-ai-part1/2-decision-nodes-ai-legal-tool.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;&lt;strong&gt;Figure 2:&lt;/strong&gt;
 A product team maps the decision nodes of an AI legal tool to design 
transparent interface messages. (Comic generated using Google 
Gemini/Nano Banana)&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="the-impact-risk-matrix"&gt;The Impact/Risk Matrix&lt;/h3&gt;&lt;p&gt;Once
 you look closely at the AI’s process, you’ll likely find many points 
where it makes a choice. An AI might make dozens of small choices for a 
single complex task. Showing them all creates too much unnecessary 
information. You need to group these choices.&lt;/p&gt;&lt;p&gt;You can use an &lt;strong&gt;Impact/Risk Matrix&lt;/strong&gt; to sort these choices based on the types of action(s) the AI is taking. Here are examples of impact/risk matrices:&lt;/p&gt;&lt;p&gt;First, look for low-stakes and low-impact decisions.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Low Stakes / Low Impact&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;em&gt;Example:&lt;/em&gt; Organizing a file structure or renaming a document.&lt;/li&gt;&lt;li&gt;&lt;em&gt;Transparency Need:&lt;/em&gt; Minimal. A subtle toast notification or a log entry suffices. Users can undo these actions easily.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Then identify the high-stakes and high-impact decisions.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;High Stakes / High Impact&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;em&gt;Example:&lt;/em&gt; Rejecting a loan application or executing a stock trade.&lt;/li&gt;&lt;li&gt;&lt;em&gt;Transparency Need:&lt;/em&gt; High. These actions require Proof of Work. The system must demonstrate the rationale before or immediately as it acts.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Consider
 a financial trading bot that treats all buy/sell orders the same. It 
executes a $5 trade with the same opacity as a $50,000 trade. Users 
might question whether the tool recognizes the potential impact of 
transparency on trading on a large dollar amount. They need the system 
to pause and show its work for the high-stakes trades. The solution is 
to introduce a Reviewing Logic state for any transaction exceeding a 
specific dollar amount, allowing the user to see the factors driving the
 decision before execution.&lt;/p&gt;&lt;h3 id="mapping-nodes-to-patterns-a-design-pattern-selection-rubric"&gt;Mapping Nodes to Patterns: A Design Pattern Selection Rubric&lt;/h3&gt;&lt;p&gt;Once
 you have identified your experience’s key decision nodes, you must 
decide which UI pattern applies to each one you’ll display. In Designing
 For Agentic AI, we introduced patterns like the Intent Preview (for 
high-stakes control) and the Action Audit (for retrospective safety). 
The decisive factor in choosing between them is reversibility.&lt;/p&gt;&lt;p&gt;We filter every decision node through the impact matrix in order to assign the correct pattern:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;High Stakes &amp;amp; Irreversible:&lt;/strong&gt;
 These nodes require an Intent Preview. Because the user cannot easily 
undo the action (e.g., permanently deleting a database), the 
transparency moment must happen before execution. The system must pause,
 explain its intent, and require confirmation.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;High Stakes &amp;amp; Reversible:&lt;/strong&gt;
 These nodes can rely on the Action Audit &amp;amp; Undo pattern. If the 
AI-powered sales agent moves a lead to a different pipeline, it can do 
so autonomously as long as it notifies the user and offers an immediate 
Undo button.&lt;/p&gt;&lt;p&gt;By strictly categorizing nodes this way, we avoid 
“alert fatigue.” We reserve the high-friction Intent Preview only for 
the truly irreversible moments, while relying on the Action Audit to 
maintain speed for everything else.&lt;/p&gt;&lt;table class="tablesaw break-out"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;br /&gt;&lt;/th&gt;&lt;th&gt;Reversible&lt;/th&gt;&lt;th&gt;Irreversible&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td data-label=""&gt;&lt;strong&gt;Low Impact&lt;/strong&gt;&lt;/td&gt;&lt;td data-label="Reversible"&gt;&lt;strong&gt;Type&lt;/strong&gt;: Auto-Execute&lt;br /&gt;&lt;strong&gt;UI&lt;/strong&gt;: Passive Toast / Log&lt;br /&gt;&lt;em&gt;Ex: Renaming a file&lt;/em&gt;&lt;/td&gt;&lt;td data-label="Irreversible"&gt;&lt;strong&gt;Type&lt;/strong&gt;: Confirm&lt;br /&gt;&lt;strong&gt;UI&lt;/strong&gt;: Simple Undo option&lt;br /&gt;&lt;em&gt;Ex: Archiving an email&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td data-label=""&gt;&lt;strong&gt;High Impact&lt;/strong&gt;&lt;/td&gt;&lt;td data-label="Reversible"&gt;&lt;strong&gt;Type&lt;/strong&gt;: Review&lt;br /&gt;&lt;strong&gt;UI&lt;/strong&gt;: Notification + Review Trail&lt;br /&gt;&lt;em&gt;Ex: Sending a draft to a client&lt;/em&gt;&lt;/td&gt;&lt;td data-label="Irreversible"&gt;&lt;strong&gt;Type&lt;/strong&gt;: Intent preview&lt;br /&gt;&lt;strong&gt;UI&lt;/strong&gt;: Modal / Explicit Permission&lt;br /&gt;&lt;em&gt;Ex: Deleting a server&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Table 1:&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;The impact and reversibility matrix can then be used to map your moments of transparency to design patterns.&lt;/em&gt;&lt;/p&gt;&lt;h3 id="qualitative-validation-the-wait-why-test"&gt;Qualitative Validation: “The Wait, Why?” Test&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/04/identifying-necessary-transparency-moments-agentic-ai-part1/#qualitative-validation-the-wait-why-test"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;You
 can identify potential nodes on a whiteboard, but you must validate 
them with human behavior. You need to verify whether your map matches 
the user’s mental model. I use a protocol called the &lt;strong&gt;“Wait, Why?” Test&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;Ask a user to watch the agent complete a task. Instruct them to speak aloud. Whenever they ask a question, &lt;em&gt;“Wait, why did it do that?”&lt;/em&gt; or &lt;em&gt;“Is it stuck?”&lt;/em&gt; or &lt;em&gt;“Did it hear me?”&lt;/em&gt; — you mark a timestamp.&lt;/p&gt;&lt;p&gt;These
 questions signal user confusion. The user feels their control slipping 
away. For example, in a study for a healthcare scheduling assistant, 
users watched the agent book an appointment. The screen sat static for 
four seconds. Participants consistently asked, &lt;em&gt;“Is it checking my calendar or the doctor’s?”&lt;/em&gt;&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/identifying-necessary-transparency-moments-agentic-ai-part1/3-wait-why-protocol.png"&gt;&lt;img alt="The Wait, Why? Protocol. A timeline illustrating how silence creates anxiety. By mapping the specific moment users ask ‘Is it stuck?’, designers can insert transparency exactly when it is needed." height="437" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/identifying-necessary-transparency-moments-agentic-ai-part1/3-wait-why-protocol.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;&lt;strong&gt;Figure 3:&lt;/strong&gt;
 The Wait, Why? Protocol. A timeline illustrating how silence creates 
anxiety. By mapping the specific moment users ask ‘Is it stuck?’, 
designers can insert transparency exactly when it is needed.&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;That question revealed a missing &lt;strong&gt;Transparency Moment&lt;/strong&gt;. The system needed to split that four-second wait into two distinct steps: &lt;em&gt;“Checking your availability”&lt;/em&gt; followed by &lt;em&gt;“Syncing with provider schedule.”&lt;/em&gt;&lt;/p&gt;&lt;p&gt;This small change reduced users’ expressed levels of anxiety.&lt;/p&gt;&lt;p&gt;Transparency
 fails when it only describes a system action. The interface must 
connect the technical process to the user’s specific goal. A screen 
displaying &lt;em&gt;“Checking your availability”&lt;/em&gt; falls flat because it lacks context. The user understands that the AI is looking at a calendar, but they do not know why.&lt;/p&gt;&lt;p&gt;We
 must pair the action with the outcome. The system needs to split that 
four-second wait into two distinct steps. First, the interface displays &lt;em&gt;“Checking your calendar to find open times.”&lt;/em&gt; Then it updates to &lt;em&gt;“Syncing with the provider’s schedule to secure your appointment.”&lt;/em&gt; This grounds the technical process in the user’s actual life.&lt;/p&gt;&lt;p&gt;Consider
 an AI managing inventory for a local cafe. The system encounters a 
supply shortage. An interface reading “contacting vendor” or “reviewing 
options” creates anxiety. The manager wonders if the system is canceling
 the order or buying an expensive alternative. A better approach is to 
explain the intended result: &lt;em&gt;“Evaluating alternative suppliers to maintain your Friday delivery schedule.”&lt;/em&gt; This tells the user exactly what the AI is trying to achieve.&lt;/p&gt;&lt;div aria-hidden="true" class="c-friskies-box partners partners__lead partners__lead-place partners__external" data-amount="1" data-audience="non-subscriber" data-remove="true"&gt;&lt;/div&gt;&lt;h2 id="operationalizing-the-audit"&gt;Operationalizing the Audit&amp;nbsp;&lt;/h2&gt;&lt;p&gt;You
 have completed the Decision Node Audit and filtered your list through 
the Impact and Risk Matrix. You now have a list of essential moments for
 being transparent. Next, you need to create them in the UI. This step 
requires teamwork across different departments. You can’t design 
transparency by yourself using a design tool. You need to understand how
 the system works behind the scenes.&lt;/p&gt;&lt;p&gt;Start with a &lt;strong&gt;Logic Review&lt;/strong&gt;.
 Meet with your lead system designer. Bring your map of decision nodes. 
You need to confirm that the system can actually share these states. I 
often find that the technical system doesn’t reveal the exact state I 
want to show. The engineer might say the system just returns a general 
“working” status. You must push for a detailed update. You need the 
system to send a specific notice when it switches from reading text to 
checking rules. Without that technical connection, your design is 
impossible to build.&lt;/p&gt;&lt;p&gt;Next, involve the Content Design team. You 
have the technical reason for the AI’s action, but you need a clear, 
human-friendly explanation. Engineers provide the underlying process, 
but content designers provide the way it’s communicated. Do not write 
these messages alone. A developer might write &lt;em&gt;“Executing function 402,”&lt;/em&gt; which is technically correct but meaningless to the user. A designer might write &lt;em&gt;“Thinking,”&lt;/em&gt; which is friendly but too vague. A content strategist finds the right middle ground. They create specific phrases, such as &lt;em&gt;“Scanning for liability risks”&lt;/em&gt;, that show the AI is working without confusing the user.&lt;/p&gt;&lt;p&gt;Finally,
 test the transparency of your messages. Don’t wait until the final 
product is built to see if the text works. I conduct comparison tests on
 simple prototypes where the only thing that changes is the status 
message. For example, I show one group (Group A) a message that says &lt;em&gt;“Verifying identity”&lt;/em&gt; and another group (Group B) a message that says &lt;em&gt;“Checking government databases”&lt;/em&gt;
 (these are made-up examples, but you understand the point). Then I ask 
them which AI feels safer. You’ll often discover that certain words 
cause worry, while others build trust. You must treat the wording as 
something you need to test and prove effective.&lt;/p&gt;&lt;h3 id="how-this-changes-the-design-process"&gt;How This Changes the Design Process&lt;/h3&gt;&lt;p&gt;Conducting
 these audits has the potential to strengthen how a team works together.
 We stop handing off polished design files. We start using messy 
prototypes and shared spreadsheets. The core tool becomes a &lt;strong&gt;transparency matrix&lt;/strong&gt;.
 Engineers and the content designers edit this spreadsheet together. 
They map the exact technical codes to the words the user will read.&lt;/p&gt;&lt;p&gt;Teams
 will experience friction during the logic review. Imagine a designer 
asking the engineer how the AI decides to decline a transaction 
submitted on an expense report. The engineer might say the backend only 
outputs a generic status code like &lt;em&gt;“Error: Missing Data”.&lt;/em&gt; The 
designer states that this isn’t actionable information on the screen. 
The designer negotiates with the engineer to create a specific technical
 hook. The engineer writes a new rule so the system reports exactly what
 is missing, such as a missing receipt image.&lt;/p&gt;&lt;p&gt;Content designers act as translators during this phase. A developer might write a technically accurate string like &lt;em&gt;“Calculating confidence threshold for vendor matching.”&lt;/em&gt;
 A content designer translates that string into a phrase that builds 
trust for a specific outcome. The strategist rewrites it as &lt;em&gt;“Comparing local vendor prices to secure your Friday delivery.”&lt;/em&gt; The user understands the action and the result.&lt;/p&gt;&lt;p&gt;The
 entire cross-functional team sits in on user testing sessions. They 
watch a real person react to different status messages. Seeing a user 
panic because the screen says &lt;em&gt;“Executing trade”&lt;/em&gt; forces the team to rethink their approach. The engineers and designers align on better wording. They change the text to &lt;em&gt;“Verifying sufficient funds”&lt;/em&gt; before buying stock. Testing together guarantees the final interface serves both the system logic and the user’s peace of mind.&lt;/p&gt;&lt;p&gt;It
 does require time to incorporate these additional activities into the 
team’s calendar. However, the end result should be a team that 
communicates more openly, and users who have a better understanding of 
what their AI-powered tools are doing on their behalf (and why). This &lt;strong&gt;integrated approach&lt;/strong&gt; is a cornerstone of designing truly trustworthy AI experiences.&lt;/p&gt;&lt;h2 id="trust-is-a-design-choice"&gt;Trust Is A Design Choice&lt;/h2&gt;&lt;p&gt;We
 often view trust as an emotional byproduct of a good user experience. 
It is easier to view trust as a mechanical result of predictable 
communication.&lt;/p&gt;&lt;p&gt;We build trust by showing the right information at 
the right time. We destroy it by overwhelming the user or hiding the 
machinery completely.&lt;/p&gt;&lt;p&gt;Start with the Decision Node Audit, 
particularly for agentic AI tools and products. Find the moments where 
the system makes a judgment call. Map those moments to the Risk Matrix. 
If the stakes are high, open the box. Show the work.&lt;/p&gt;&lt;p&gt;In the next 
article, we will look at how to design these moments: how to write the 
copy, structure the UI, and handle the inevitable errors when the agent 
gets it wrong.&lt;/p&gt;&lt;h2 id="appendix-the-decision-node-audit-checklist"&gt;Appendix: The Decision Node Audit Checklist&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Phase 1: Setup and Mapping&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;✅ Get the team together:&lt;/strong&gt; Bring in the product owners, business analysts, designers, key decision-makers, and the engineers who built the AI.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Hint:&lt;/em&gt; You need the engineers to explain the actual backend logic. Do not attempt this step alone.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;✅ Draw the whole process:&lt;/strong&gt; Document every step the AI takes, from the user’s first action to the final result.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Hint:&lt;/em&gt; A physical whiteboard session often works best for drawing out these initial steps.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Phase 2: Locating the Hidden Logic&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;✅ Find where things are unclear:&lt;/strong&gt; Look at the process map for any spot where the AI compares options or inputs that do not have one perfect match.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;✅ Identify the best guess steps:&lt;/strong&gt;
 For each unclear spot, check if the system uses a confidence score. For
 example, ask if the system is 85 percent sure. These are the points 
where the AI makes a final choice.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;✅ Examine the choice:&lt;/strong&gt;
 For each choice point, figure out the specific internal math or 
comparison being done. An example is matching a part of a contract to a 
policy. Another example involves comparing a picture of a broken car to a
 library of damaged car photos.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Phase 3: Creating the User Experience&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;✅ Write clear explanations:&lt;/strong&gt; Create messages for the user that clearly describe the specific internal action happening when the AI makes a choice.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Hint:&lt;/em&gt;
 Ground your messages in concrete reality. If an AI books a meeting with
 a client at a local cafe, tell the user the system is checking the cafe
 reservation system.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;✅ Update the screen:&lt;/strong&gt; Put 
these new, clear explanations into the user interface. Replace vague 
messages like Reviewing contracts with your specific explanations.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;✅ Check for Trust:&lt;/strong&gt;
 Make sure the new screen messages give users a simple reason for any 
wait time or result. This should make them feel confident and trusting.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Hint:&lt;/em&gt; Test these messages with actual users to verify they understand the specific outcome being achieved.&lt;/p&gt;</description><link>http://honeyvig.blogspot.com/2026/05/identifying-necessary-transparency.html</link><author>noreply@blogger.com (H)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9165069509664255576.post-4424176700041561457</guid><pubDate>Thu, 30 Apr 2026 06:56:00 +0000</pubDate><atom:updated>2026-04-29T23:56:00.117-07:00</atom:updated><title>The UX Designer’s Nightmare: When “Production-Ready” Becomes A Design Deliverable</title><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="c-garfield-summary"&gt;&lt;section aria-label="Quick summary" class="article__summary"&gt;In
 a rush to embrace AI, the industry is redefining what it means to be a 
UX designer, blurring the line between design and engineering. Carrie 
Webster explores what’s gained, what’s lost, and why designers need to 
remain the guardians of the user experience.&lt;/section&gt;&lt;/div&gt;&lt;p&gt;In early 2026, I noticed that the UX designer’s toolkit seemed to shift overnight. The industry standard &lt;em&gt;“Should designers code?”&lt;/em&gt;
 debate was abruptly settled by the market, not through a consensus of 
our craft, but through the brute force of job requirements. If you 
browse LinkedIn today, you’ll notice a stark change: UX roles 
increasingly demand &lt;strong&gt;&lt;a href="https://www.refontelearning.com/blog/ui-ux-designer-engineering-in-2026-crafting-future-ready-user-experiences"&gt;AI-augmented development&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;technical orchestration,&lt;/strong&gt; and &lt;strong&gt;production-ready prototyping.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;For
 many, including myself, this is the ultimate design job nightmare. We 
are being asked to deliver both the “vibe” and the “code” 
simultaneously, using AI agents to bridge a technical gap that 
previously took years of computer science knowledge and coding 
experience to cross. But as the industry rushes to meet these new 
expectations, they are discovering that AI-generated functional code is 
not always &lt;em&gt;good&lt;/em&gt; code.&lt;/p&gt;&lt;h2 id="the-linkedin-pressure-cooker-role-creep-in-2026"&gt;The LinkedIn Pressure Cooker: Role Creep In 2026&lt;/h2&gt;&lt;p&gt;The job market is sending a clear signal. While traditional graphic design roles are expected to grow by only &lt;strong&gt;3%&lt;/strong&gt; through 2034, UX, UI, and &lt;a href="https://www.nobledesktop.com/careers/designer/job-outlook#:~:text=The%20projected%20future%20growth%20figures%20for%20Digital,job%20growth%20(which%20lies%20somewhere%20around%205%25)."&gt;Product Design roles&lt;/a&gt; are projected to grow by &lt;strong&gt;16%&lt;/strong&gt; over the same period.&lt;/p&gt;&lt;p&gt;However, this growth is increasingly tied to the rise of &lt;strong&gt;AI product development&lt;/strong&gt;,
 where “design skills” have recently become the #1 most in-demand 
capability, even ahead of coding and cloud infrastructure. Companies 
building these platforms are no longer just looking for visual 
designers; they need professionals who can “&lt;a href="https://humbldesign.io/blog-posts/will-ai-replace-designers-2026"&gt;translate technical capability into human-centered experiences&lt;/a&gt;.”&lt;/p&gt;&lt;p&gt;This
 creates a high-stakes environment for the UX designer. We are no longer
 just responsible for the interface; we are expected to understand the 
technical logic well enough to ensure that complex AI capabilities feel 
intuitive, safe, and useful for the human on the other side of the 
screen. Designers are being pushed toward a &lt;strong&gt;“design engineer” model&lt;/strong&gt;, where we must bridge the gap between abstract &lt;a href="https://www.refontelearning.com/blog/ui-ux-designer-engineering-in-2026-crafting-future-ready-user-experiences#skills-and-competencies-for-the-2026-uiux-designer-3"&gt;AI logic and user-facing code&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;A &lt;a href="https://www.lyssna.com/blog/ux-design-trends/"&gt;recent survey&lt;/a&gt; found that &lt;strong&gt;73% of designers&lt;/strong&gt;
 now view AI as a primary collaborator rather than just a tool. However,
 this “collaboration” often looks like “role creep.” Recruiters are 
often not just looking for someone who understands user empathy and 
information architecture — they want someone who can also prompt a React
 component into existence and push it to a repository!&lt;/p&gt;&lt;p&gt;This shift has created a &lt;strong&gt;competency gap&lt;/strong&gt;.&lt;/p&gt;&lt;blockquote&gt;As
 an experienced senior designer who has spent decades mastering the 
nuances of cognitive load, accessibility standards, and ethnographic 
research, I am suddenly finding myself being judged on my ability to 
debug a CSS Flexbox issue or manage a Git branch.&lt;/blockquote&gt;&lt;p&gt;The nightmare isn’t the technology itself. It’s the &lt;strong&gt;reallocation of value&lt;/strong&gt;.&lt;/p&gt;&lt;blockquote class="pull-quote"&gt;&lt;p&gt;&lt;a aria-label="Share on Twitter" class="pull-quote__link" href="https://twitter.com/share?text=%0aBusinesses%20are%20beginning%20to%20value%20the%20speed%20of%20output%20over%20the%20quality%20of%20the%20experience,%20fundamentally%20changing%20what%20it%20means%20to%20be%20a%20%e2%80%9csuccessful%e2%80%9d%20designer%20in%202026.%0a&amp;amp;url=https://smashingmagazine.com%2f2026%2f04%2fproduction-ready-becomes-design-deliverable-ux%2f"&gt;Businesses
 are beginning to value the speed of output over the quality of the 
experience, fundamentally changing what it means to be a “successful” 
designer in 2026.&lt;/a&gt;&lt;/p&gt;&lt;div class="pull-quote__quotation"&gt;&lt;div class="pull-quote__bg"&gt;&lt;span class="pull-quote__symbol"&gt;“&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/ux-designer-nightmare-production-ready-becomes-design-deliverable/1-figma.jpg"&gt;&lt;img alt="Figma to AI code ad" height="450" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/ux-designer-nightmare-production-ready-becomes-design-deliverable/1-figma.jpg" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Tools that allow designers to switch from design to code. (Image source: &lt;a href="https://www.figma.com/community/plugin/1443774571835235184/figma-to-ai-code-by-designcode"&gt;Figma&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="the-competence-trap-two-job-skill-sets-one-average-result"&gt;The Competence Trap: Two Job Skill Sets, One Average Result&lt;/h3&gt;&lt;p&gt;There
 is potentially a very dangerous myth circulating in boardrooms that AI 
makes a designer “equal” to an engineer. This narrative suggests that 
because an LLM can generate a functional JavaScript event handler, the 
person prompting it doesn’t need to understand the underlying logic. In 
reality, attempting to master two disparate, deep fields simultaneously 
will most likely lead to being &lt;strong&gt;averagely competent&lt;/strong&gt; at both.&lt;/p&gt;&lt;h3 id="the-averagely-competent-dilemma"&gt;The “Averagely Competent” Dilemma&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/04/production-ready-becomes-design-deliverable-ux/#the-averagely-competent-dilemma"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;For
 a senior UX designer to become a senior-level coder is like asking a 
master chef to also be a master plumber because “they both work in the 
kitchen.” You might get the water running, but you won’t know why the 
pipes are rattling.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;The “cognitive offloading” risk.&lt;/strong&gt;&lt;br /&gt;Research
 shows that while AI can speed up task completion, it often leads to a 
significant decrease in conceptual mastery. In a controlled study, 
participants using AI assistance scored &lt;a href="https://www.psychologytoday.com/au/blog/the-asymmetric-brain/202602/cognitive-offloading-using-ai-reduces-new-skill-formation"&gt;17% lower&lt;/a&gt; on comprehension tests than those who coded by hand.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The debugging gap.&lt;/strong&gt;&lt;br /&gt;The largest performance gap between AI-reliant users and hand-coders is in &lt;a href="https://www.anthropic.com/research/AI-assistance-coding-skills"&gt;debugging&lt;/a&gt;. When a designer uses AI to write code they don’t fully understand, they don’t have the ability to identify &lt;em&gt;when&lt;/em&gt; and &lt;em&gt;why&lt;/em&gt; it fails.&lt;/li&gt;&lt;/ul&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/ux-designer-nightmare-production-ready-becomes-design-deliverable/2-ai-assistance-coding-skills-speed.png"&gt;&lt;img alt="A chart showing how AI assistance impacts coding speed and skill formation " height="451" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/ux-designer-nightmare-production-ready-becomes-design-deliverable/2-ai-assistance-coding-skills-speed.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Using AI tools impedes coding skill formation. (Image source: &lt;a href="https://www.anthropic.com/research/AI-assistance-coding-skills"&gt;Anthropic&lt;/a&gt;)&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;So,
 if a designer ships an AI-generated component that breaks during a 
high-traffic event and cannot manually trace the logic, they are no 
longer an expert. They are now a liability.&lt;/p&gt;&lt;h3 id="the-high-cost-of-unoptimised-code"&gt;The High Cost Of Unoptimised Code&amp;nbsp;&lt;/h3&gt;&lt;p&gt;Any
 experienced code engineer will tell you that creating code with AI 
without the right prompt leads to a lot of rework. Because most 
designers lack the technical foundation to audit the code the AI gives 
them, they are inadvertently shipping massive amounts of &lt;a href="https://gocrossbridge.com/blog/ai-generated-code/"&gt;“Quality Debt”&lt;/a&gt;.&lt;/p&gt;&lt;h2 id="common-issues-in-designer-generated-ai-code"&gt;Common Issues In Designer-Generated AI Code&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;The security flaw&lt;/strong&gt;&lt;br /&gt;Recent reports indicate that up to &lt;a href="https://www.sherlockforensics.com/pages/ai-code-security-report-2026.html"&gt;92% of AI-generated codebases&lt;/a&gt;
 contain at least one critical vulnerability. A designer might see a 
functioning login form, unaware that it has an 86% failure rate in XSS 
defense, which are the security measures aimed at preventing attackers 
from injecting malicious scripts into trusted websites.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The accessibility illusion&lt;/strong&gt;&lt;br /&gt;AI
 often generates “functional” applications that lack semantic integrity.
 A designer might prompt a “beautiful and functional toggle switch,” but
 the AI may provide a non-semantic &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; that lacks keyboard focus and screen-reader compatibility, creating &lt;a href="https://www.levelaccess.com/blog/accessibility-debt-in-software-development-and-how-to-engineer-it-out/"&gt;Accessibility Debt&lt;/a&gt; that is expensive to fix later.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The performance penalty&lt;/strong&gt;&lt;br /&gt;AI-generated code tends to be verbose. AI is linked to &lt;a href="https://www.netcorpsoftwaredevelopment.com/blog/ai-generated-code-statistics"&gt;4x more code duplication&lt;/a&gt;
 than human-written code. This verbosity slows down page loads, creates 
massive CSS files, and negatively impacts SEO. To a business, the task 
looks “done.” To a user with a slow connection or a screen reader, the 
site is a nightmare.&lt;/li&gt;&lt;/ul&gt;&lt;h2 id="creating-more-work-not-less"&gt;Creating More Work, Not Less&lt;/h2&gt;&lt;p&gt;The promise of AI was that designers could ship features without bothering the engineers. The reality has been the birth of a &lt;strong&gt;“Rework Tax”&lt;/strong&gt; that is draining engineering resources across the industry.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Cleaning up&lt;/strong&gt;&lt;br /&gt;Organisations are finding that while velocity increases, incidents per Pull Request are also rising by &lt;a href="https://blog.exceeds.ai/ai-code-analysis-benchmark-reports/"&gt;23.5%&lt;/a&gt;.
 Some engineering teams now spend a significant portion of their week 
cleaning up “AI slop” delivered by design teams who skipped a rigorous 
review process.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The communication gap&lt;/strong&gt;&lt;br /&gt;Only &lt;a href="https://www.lyssna.com/blog/ux-design-trends/"&gt;69% of designers&lt;/a&gt; feel AI improves the quality of their work, compared to &lt;strong&gt;82% of developers&lt;/strong&gt;. This gap exists because “code that compiles” is not the same as “code that is maintainable.”&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;When
 a designer hands off AI-generated code that ignores a company’s 
internal naming conventions or management patterns, they aren’t helping 
the engineer; they are creating a puzzle that someone else has to solve 
later.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/ux-designer-nightmare-production-ready-becomes-design-deliverable/3-issues-developers-face-ai-generated-code.jpg"&gt;&lt;img alt="Typical issues that developers face with AI-generated code" height="600" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/ux-designer-nightmare-production-ready-becomes-design-deliverable/3-issues-developers-face-ai-generated-code.jpg" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Typical issues that developers face with AI-generated code. (Image source: &lt;a href="https://www.netcorpsoftwaredevelopment.com/blog/ai-generated-code-statistics"&gt;Netcorp&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="the-solution"&gt;The Solution&amp;nbsp;&lt;/h3&gt;&lt;p&gt;We need to move away from the nightmare of the “&lt;strong&gt;Solo Full-Stack Designer&lt;/strong&gt;” and toward a model of &lt;strong&gt;designer/coder collaboration&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The ideal reality:&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;The Partnership&lt;/strong&gt;&lt;br /&gt;Instead of designers trying to be mediocre coders, they should work in a &lt;strong&gt;human-AI-human loop&lt;/strong&gt;. A senior UX designer should work &lt;em&gt;with&lt;/em&gt; an engineer to use AI; the designer creates prompts for &lt;strong&gt;intent, accessibility, and user flow&lt;/strong&gt;, while the engineer creates prompts for &lt;strong&gt;architecture and performance&lt;/strong&gt;.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Design systems as guardrails&lt;/strong&gt;&lt;br /&gt;To prevent accessibility debt from spreading at scale, &lt;a href="https://webaim.org/projects/million/"&gt;accessible components must be the default&lt;/a&gt;
 in your design system. AI should be used to feed these tokens into your
 UI, ensuring that even generated code stays within the “source of 
truth.”&lt;/li&gt;&lt;/ul&gt;&lt;h2 id="beyond-the-prompt"&gt;Beyond The Prompt&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/04/production-ready-becomes-design-deliverable-ux/#beyond-the-prompt"&gt;#&lt;/a&gt;&lt;/h2&gt;&lt;div aria-hidden="true" class="c-friskies-box partners partners__lead partners__lead-place partners__external" data-amount="1" data-audience="non-subscriber" data-remove="true" data-rendered="true"&gt;&lt;ul&gt;&lt;a class="partners__native--smashing" href="https://www.smashingmagazine.com/contact/"&gt;
        &lt;picture&gt;
          &lt;source media="(max-width: 600px)"&gt;&lt;/source&gt;
          &lt;img alt="Advertise with Smashing Magazine" width="325" /&gt;
        &lt;/picture&gt;
      &lt;/a&gt;&lt;/ul&gt;&lt;/div&gt;&lt;p&gt;The industry is currently in a state of “AI Infatuation,” but the pendulum will eventually swing back toward quality.&lt;/p&gt;&lt;blockquote class="pull-quote"&gt;&lt;p&gt;&lt;a aria-label="Share on Twitter" class="pull-quote__link" href="https://twitter.com/share?text=%0aThe%20UX%20designer%e2%80%99s%20nightmare%20ends%20when%20we%20stop%20trying%20to%20compete%20with%20AI%20tools%20at%20what%20they%20do%20best%20%28generating%20syntax%29%20and%20keep%20our%20focus%20on%20what%20they%20cannot%20do%20%28understanding%20human%20complexity%29.%0a&amp;amp;url=https://smashingmagazine.com%2f2026%2f04%2fproduction-ready-becomes-design-deliverable-ux%2f"&gt;The
 UX designer’s nightmare ends when we stop trying to compete with AI 
tools at what they do best (generating syntax) and keep our focus on 
what they cannot do (understanding human complexity).&lt;/a&gt;&lt;/p&gt;&lt;div class="pull-quote__quotation"&gt;&lt;div class="pull-quote__bg"&gt;&lt;span class="pull-quote__symbol"&gt;“&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;p&gt;Businesses
 that prioritise “designer-shipped code” without engineering oversight 
will eventually face a reckoning of technical debt, security breaches, 
and accessibility lawsuits. The designers who thrive in 2026 and beyond 
will be those who refuse to be “prompt operators” and instead position 
themselves as the &lt;strong&gt;guardians of the user experience&lt;/strong&gt;. This is the perfect outcome for experienced designers and for the industry.&lt;/p&gt;&lt;p&gt;Our
 value has always been our ability to advocate for the human on the 
other side of the screen. We must use AI to augment our design thinking,
 allowing us to test more ideas and iterate faster, but we must never 
let it replace the specialised engineering expertise that ensures our 
designs technically &lt;em&gt;work&lt;/em&gt; for everyone.&lt;/p&gt;&lt;h3 id="summary-checklist-for-ux-designers"&gt;Summary Checklist for UX Designers&amp;nbsp;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Work Together.&lt;/strong&gt;&lt;br /&gt;Use
 AI-made code as a starting point to talk with your developers. Don’t 
use it as a shortcut to avoid working with them. Ask them to help you 
with prompts for code creation for the best outcomes.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Understand the “Why”.&lt;/strong&gt;&lt;br /&gt;Never submit code you don’t understand. If you can’t explain how the AI-generated logic works, don’t include it in your work.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Build for Everyone.&lt;/strong&gt;&lt;br /&gt;Good
 design is more than just looks. Use AI to check if your code works for 
people using screen readers or keyboards, not just to make things look 
pretty.&lt;/li&gt;&lt;/ul&gt;</description><link>http://honeyvig.blogspot.com/2026/04/the-ux-designers-nightmare-when_01127696254.html</link><author>noreply@blogger.com (H)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9165069509664255576.post-4339684066322337230</guid><pubDate>Wed, 29 Apr 2026 07:02:00 +0000</pubDate><atom:updated>2026-04-29T00:02:00.115-07:00</atom:updated><title>The Site-Search Paradox: Why The Big Box Always Wins</title><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="c-garfield-summary"&gt;&lt;section aria-label="Quick summary" class="article__summary"&gt;Success
 in modern UX isn’t about having the most content. It’s about having the
 most findable content. Yet even with more data and better tools than 
ever, internal search often fails, leaving users to rely on global 
search engines to find a single page on a local site. Why does the “Big 
Box” still win, and how can we bring users back?&lt;/section&gt;&lt;/div&gt;&lt;p&gt;In 
the early days of the web, the search bar was a luxury, added to a site 
once it became “too big” to navigate by clicking. We treated it like an 
index at the back of a book: a literal, alphabetical list of words that 
pointed to specific pages. If you typed the exact word the author used, 
you found what you needed. If you didn’t, you were met with a “0 Results
 Found” screen that felt like a digital dead end.&lt;/p&gt;&lt;p&gt;Twenty-five 
years later, we are still building search bars that act like 1990s index
 cards, even though the humans using them have been fundamentally 
rewired. Today, when a user lands on your site and can’t find what they 
need in the global navigation within seconds, they don’t try to learn 
your taxonomy. They head for the search box. But if that box fails them,
 and demands they use &lt;em&gt;your&lt;/em&gt; specific brand vocabulary, or 
punishes them for a typo, they do something that should keep every UX 
designer awake at night. They leave your site, go to Google, and type &lt;strong&gt;site:yourwebsite.com [query]&lt;/strong&gt;.
 Or, worse still, they just type in their query and end up on a 
competitor’s website. I personally use Google over a site’s search 
nearly every time.&lt;/p&gt;&lt;p&gt;This is the &lt;strong&gt;Site-Search Paradox&lt;/strong&gt;.
 In an era where we have more data and better tools than ever, our 
internal search experiences are often so poor that users prefer to use a
 trillion-dollar global search engine to find a single page on a local 
site. As Information Architects and UX designers, we have to ask, why 
does the “Big Box” win, and how can we take our users back?&lt;/p&gt;&lt;h2 id="the-syntax-tax-and-the-death-of-exact-match"&gt;The “Syntax Tax” And The Death Of Exact Match&lt;/h2&gt;&lt;p&gt;The primary reason site search fails is what I call the &lt;strong&gt;Syntax Tax&lt;/strong&gt;.
 This is the cognitive load we place on users when we require them to 
guess the exact string of characters we’ve used in our database.&lt;/p&gt;&lt;p&gt;Research by &lt;strong&gt;Origin Growth&lt;/strong&gt; on &lt;a href="https://www.origingrowth.co.uk/blog/search-vs-navigate-how-people-behave-on-websites-do-they-search-or-do-they-navigate/"&gt;&lt;strong&gt;Search vs Navigate&lt;/strong&gt;&lt;/a&gt; shows that roughly &lt;strong&gt;50% of users&lt;/strong&gt;
 go straight to the search bar upon landing on a site. For example, when
 a user types “sofa” into a furniture site that has categorised 
everything under “couches,” and the site returns nothing, the user 
doesn’t think, &lt;em&gt;“Ah, I should try a synonym.”&lt;/em&gt; They think, &lt;em&gt;“This site doesn’t have what I want.”&lt;/em&gt;&lt;/p&gt;&lt;p&gt;This is a failure of &lt;strong&gt;Information Architecture (IA)&lt;/strong&gt;. We’ve built our systems to match &lt;em&gt;strings&lt;/em&gt; (literal sequences of letters) rather than &lt;em&gt;things&lt;/em&gt; (the concepts behind the words). When we force users to match our internal vocabulary, we are taxing their brainpower.&lt;/p&gt;&lt;figure&gt;&lt;a href="https://files.smashing.media/articles/site-search-paradox-why-big-box-always-wins/1-keyword-semantic-search.jpg"&gt;&lt;img alt="Keyword Search vs Semantic Search" height="1000" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/site-search-paradox-why-big-box-always-wins/1-keyword-semantic-search.jpg" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Keyword Search vs. Semantic Search. (Image source: &lt;a href="https://www.linkedin.com/posts/gerrid-smith_seo-digitalmarketing-marketing-activity-7349860105007341568-ipM_/"&gt;Gerrid Smith&lt;/a&gt;)&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;h2 id="why-google-wins-it-s-not-power-it-s-context"&gt;Why Google Wins: It’s Not Power, It’s Context&amp;nbsp;&lt;/h2&gt;&lt;p&gt;It
 is easy to throw our hands up and say, “We can’t compete with Google’s 
engineering.” But Google’s success isn’t just about raw power; it’s 
about &lt;strong&gt;contextual understanding&lt;/strong&gt;. While we often treat search as a technical utility, Google treats it as an IA challenge.&lt;/p&gt;&lt;p&gt;Data from the &lt;strong&gt;Baymard Institute&lt;/strong&gt; reveals that &lt;a href="https://baymard.com/blog/ecommerce-search-query-types"&gt;&lt;strong&gt;41% of e-commerce sites&lt;/strong&gt;&lt;/a&gt; fail to support even basic symbols or abbreviations, and this often leads to &lt;strong&gt;users&lt;/strong&gt; abandoning a site after a single failed search attempt. Google wins because it uses &lt;a href="https://www.ibm.com/think/topics/stemming-lemmatization#:~:text=How%20lemmatization%20works,syntactic%20function%20in%20the%20sentence."&gt;&lt;strong&gt;stemming and lemmatization&lt;/strong&gt;&lt;/a&gt;
 — IA techniques that recognize “running” and “ran” are the same intent.
 Most internal searches are “blind” to this context, treating “Running 
Shoe” and “Running Shoes” as entirely different entities.&lt;/p&gt;&lt;blockquote class="pull-quote"&gt;&lt;p&gt;&lt;a aria-label="Share on Twitter" class="pull-quote__link" href="https://twitter.com/share?text=%0aIf%20your%20site%20search%20can%e2%80%99t%20handle%20a%20simple%20plural%20or%20a%20common%20misspelling,%20you%20are%20effectively%20charging%20your%20users%20a%20tax%20for%20being%20human.%0a&amp;amp;url=https://smashingmagazine.com%2f2026%2f03%2fsite-search-paradox-why-big-box-always-wins%2f"&gt;If
 your site search can’t handle a simple plural or a common misspelling, 
you are effectively charging your users a tax for being human.&lt;/a&gt;&lt;/p&gt;&lt;div class="pull-quote__quotation"&gt;&lt;div class="pull-quote__bg"&gt;&lt;span class="pull-quote__symbol"&gt;“&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;figure&gt;&lt;a href="https://files.smashing.media/articles/site-search-paradox-why-big-box-always-wins/2-user-query-friction-user-flow.jpg"&gt;&lt;img alt="User Query Friction vs User Flow" height="800" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/site-search-paradox-why-big-box-always-wins/2-user-query-friction-user-flow.jpg" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;User Query Friction vs. User Flow. (Image source: Created with Gemini)&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;h2 id="the-ux-of-maybe-designing-for-probabilistic-results"&gt;The UX Of “Maybe”: Designing For Probabilistic Results&lt;/h2&gt;&lt;p&gt;In
 traditional IA, we think in binaries: A page is either in a category, 
or it isn’t. A search result is either a match or it isn’t. Modern 
search, which users now expect, is &lt;strong&gt;probabilistic&lt;/strong&gt;. It deals in “confidence levels.”&lt;/p&gt;&lt;p&gt;According to &lt;strong&gt;Forresters&lt;/strong&gt;, users who use search are &lt;a href="https://www.nosto.com/blog/ecommerce-site-search-statistics/#:~:text=Everyone’s%20searching%20for%20something%2C%20but,to%20convert%20and%20come%20back"&gt;&lt;strong&gt;2–3 times more likely to convert&lt;/strong&gt;&lt;/a&gt; than those who don’t, &lt;em&gt;if&lt;/em&gt; the search works. And &lt;a href="https://www.nosto.com/blog/ecommerce-site-search-statistics/#:~:text=Everyone’s%20searching%20for%20something%2C%20but,to%20convert%20and%20come%20back"&gt;&lt;strong&gt;80% of users&lt;/strong&gt;&lt;/a&gt; on e-commerce sites exit a site due to poor search results.&lt;/p&gt;&lt;p&gt;As designers, we rarely design for the middle ground. We design a “&lt;strong&gt;Results Found&lt;/strong&gt;” page and a “&lt;strong&gt;No Results&lt;/strong&gt;” page. We miss the most important state: &lt;strong&gt;The “Did You Mean?” State.&lt;/strong&gt;
 A well-designed search interface should provide “Fuzzy” matches. 
Instead of a cold “0 Results Found” screen, we should be using our 
metadata to say, &lt;em&gt;“We didn’t find that in ‘Electronics,’ but we found 3 matches in ‘Accessories’.”&lt;/em&gt; By designing for “Maybe,” we can keep the user in the flow.&lt;/p&gt;&lt;h2 id="case-study-the-cost-of-invisible-content"&gt;Case Study: The Cost Of “Invisible” Content&amp;nbsp;&lt;/h2&gt;&lt;p&gt;To
 understand why IA is the fuel for the search engine, we must look at 
how data is structured behind the scenes. In my 25 years of practice, 
I’ve seen that the “findability” of a page is directly tied to its 
structured metadata.&lt;/p&gt;&lt;p&gt;Consider a large-scale enterprise I worked 
with that had over 5,000 technical documents. Their internal search was 
returning irrelevant results because the “Title” tag of every document 
was the internal SKU number (e.g., “DOC-9928-X”) rather than the 
human-readable name.&lt;/p&gt;&lt;p&gt;By reviewing the search logs, we discovered 
that users were searching for “installation guide.” Because that phrase 
didn’t appear in the SKU-based title, the engine ignored the most 
relevant files. We implemented a &lt;strong&gt;Controlled Vocabulary&lt;/strong&gt;,
 which was a set of standardised terms that mapped SKUs to human 
language. Within three months, the “Exit Rate” from the search page 
dropped by 40%. This wasn’t an algorithmic fix; it was an IA fix. It 
proves that a search engine is only as good as the map we give it.&lt;/p&gt;&lt;div aria-hidden="true" class="c-friskies-box partners partners__lead partners__lead-place partners__external" data-amount="1" data-audience="non-subscriber" data-remove="true" data-rendered="true"&gt;&lt;ul&gt;&lt;a class="partners__native--smashing" href="https://www.smashingmagazine.com/contact/"&gt;
        &lt;picture&gt;
          &lt;source media="(max-width: 600px)"&gt;&lt;/source&gt;
          &lt;img alt="Advertise with Smashing Magazine" width="325" /&gt;
        &lt;/picture&gt;
      &lt;/a&gt;&lt;/ul&gt;&lt;/div&gt;&lt;h2 id="the-internal-language-gap"&gt;The Internal Language Gap&amp;nbsp;&lt;/h2&gt;&lt;p&gt;Throughout
 my two decades in UX, I’ve noticed a recurring theme: internal teams 
often suffer from “The curse of knowledge.” We become so immersed in our
 own corporate vocabulary, or sometimes referred to as business jargon, 
that we forget the user doesn’t speak our language.&lt;/p&gt;&lt;p&gt;I once worked 
with a financial institution that was frustrated by high call volumes to
 their support centre. Users were complaining they couldn’t find “loan 
payoff” information on the site. When we looked at the search logs, 
“loan payoff” was the #1 searched term that resulted in zero hits.&lt;/p&gt;&lt;p&gt;Why?
 Because the institution’s IA team had labelled every relevant page 
under the formal term “Loan Release.” To the bank, a “payoff” was a 
process, but a “Loan Release” was the legal document that was the 
“thing” in the database. Because the search engine was looking for 
literal character strings, it refused to connect the user’s desperate 
need with the company’s official solution.&lt;/p&gt;&lt;p&gt;This is where the IA 
professional must act as a translator. By simply adding “loan payoff” as
 a hidden metadata keyword to the Loan Release pages, we solved a 
multi-million dollar support problem. We didn’t need a faster server; we
 needed &lt;strong&gt;a more empathetic taxonomy&lt;/strong&gt;.&lt;/p&gt;&lt;h2 id="the-4-step-site-search-audit-framework"&gt;The 4-step Site-search Audit Framework&lt;/h2&gt;&lt;p&gt;If
 you want to reclaim your search box from Google, you cannot simply “set
 it and forget it.” You must treat search as a living product. Here is 
the framework I use to audit and optimise search experiences:&lt;/p&gt;&lt;h3 id="phase-1-the-zero-result-audit"&gt;Phase 1: The “Zero-result” Audit&lt;/h3&gt;&lt;p&gt;Pull your search logs from the last 90 days. Filter for all queries that returned zero results. Group these into three buckets:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;True gaps&lt;/strong&gt;&lt;br /&gt;Content the user wants that you simply don’t have (a signal for your content strategy team).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Synonym gaps&lt;/strong&gt;&lt;br /&gt;Content you have, but described in words the user doesn’t use (e.g., “Sofa” vs “Couch”).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Format gaps&lt;/strong&gt;&lt;br /&gt;The user is looking for a “video” or “PDF,” but your search only indexes HTML text.&lt;/li&gt;&lt;/ul&gt;&lt;h3 id="phase-2-query-intent-mapping"&gt;Phase 2: Query Intent Mapping&lt;/h3&gt;&lt;p&gt;Analyse the &lt;em&gt;top 50&lt;/em&gt; most common queries. Are they &lt;strong&gt;Navigational&lt;/strong&gt; (looking for a specific page), &lt;strong&gt;Informational&lt;/strong&gt; (looking for “how to”), or &lt;strong&gt;Transactional&lt;/strong&gt;
 (looking for a specific product)? Your search UI should look different 
for each. A navigational search should “Quick-Link” the user directly to
 the destination, bypassing the results page entirely.&lt;/p&gt;&lt;h3 id="phase-3-the-fuzzy-matching-test"&gt;Phase 3: The “Fuzzy” Matching Test&lt;/h3&gt;&lt;p&gt;Intentionally
 mistype your top 10 products. Use plurals, common typos, and American 
vs. British English spellings (e.g., “Color” vs. “Colour”). If your 
search fails these tests, your engine lacks “stemming” support. This is a
 technical requirement you must advocate for to your engineering team.&lt;/p&gt;&lt;h3 id="phase-4-scoping-and-filtering-ux"&gt;Phase 4: Scoping And Filtering UX&lt;/h3&gt;&lt;p&gt;Look
 at your results page. Does it offer filters that actually make sense? 
If a user searches for “shoes,” they should see filters for &lt;em&gt;Size&lt;/em&gt; and &lt;em&gt;Colour&lt;/em&gt;. Generic filters can be as bad as no filters.&lt;/p&gt;&lt;h2 id="reclaiming-the-search-box-a-strategy-for-ia-professionals"&gt;Reclaiming The Search Box: A Strategy For IA Professionals&amp;nbsp;&lt;/h2&gt;&lt;p&gt;To stop the exodus to Google, we must move beyond the “Box” and look at the &lt;strong&gt;scaffolding&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Step A: Implement semantic scaffolding.&lt;/strong&gt;&lt;br /&gt;Don’t
 just return a list of links. Use your IA to provide context. If a user 
searches for a product, show them the product, but also show them the &lt;em&gt;manual&lt;/em&gt;, the &lt;em&gt;FAQs&lt;/em&gt;, and the &lt;em&gt;related parts&lt;/em&gt;. This “associative” search mimics how the human brain works and how Google operates.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Step B: Stop being a librarian, start being a concierge.&lt;/strong&gt;&lt;br /&gt;A
 librarian tells you exactly where the book is on the shelf. A concierge
 listens to what you want to achieve and gives you a recommendation. 
Your search bar should use predictive text not just to complete words, 
but to &lt;strong&gt;suggest intentions&lt;/strong&gt;.&lt;/p&gt;&lt;h2 id="using-a-google-powered-search-bar"&gt;Using A Google-powered Search Bar&lt;/h2&gt;&lt;p&gt;Using a “Google-powered” search bar, as seen on the &lt;strong&gt;University of Chicago&lt;/strong&gt;
 website, is essentially an admission that a site’s internal 
organisation has become too complex for its own navigation to handle. 
While it is a quick “fix” for massive institutions to ensure users find &lt;em&gt;something&lt;/em&gt;, it is generally a poor choice for businesses with deep content.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/site-search-paradox-why-big-box-always-wins/3-university-chicago-website.png"&gt;&lt;img alt="Example of a university website using Google-powered search." height="508" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/site-search-paradox-why-big-box-always-wins/3-university-chicago-website.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Example of a university website using Google-powered search. (Source: &lt;a href="https://www.uchicago.edu/en"&gt;University of Chicago&lt;/a&gt;)&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;By
 delegating the search to Google, you surrender the user experience to 
an outside algorithm. You lose the ability to promote specific products,
 you expose your users to third-party ads, and you train your customers 
to leave your ecosystem the moment they need help. For a business, 
search should be a curated conversation that guides a customer toward a 
goal, not a generic list of links that pushes them back to the open web.&lt;/p&gt;&lt;figure&gt;&lt;a href="https://files.smashing.media/articles/site-search-paradox-why-big-box-always-wins/4-search-results.jpg"&gt;&lt;img alt="Shows search results with useful options when there are no exact matches. Additional suggestions are provided, including a “Did you mean” feature to help connect users with similar items." height="817" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/site-search-paradox-why-big-box-always-wins/4-search-results.jpg" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Shows
 search results with useful options when there are no exact matches. 
Additional suggestions are provided, including a “Did you mean” feature 
to help connect users with similar items. (Image source: &lt;a href="https://www.crateandbarrel.com/"&gt;Crate &amp;amp; Barrel&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;div aria-hidden="true" class="c-friskies-box partners partners__lead partners__lead-place partners__external" data-amount="1" data-audience="non-subscriber" data-remove="true"&gt;&lt;/div&gt;&lt;h2 id="the-simple-search-ux-checklist"&gt;The Simple Search UX Checklist&lt;/h2&gt;&lt;p&gt;Here
 is a final checklist for reference when you are building the search 
experience for your users. Work with your product team to ensure you are
 engaging with the right team members.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Kill the dead-end.&lt;/strong&gt;&lt;br /&gt;Never just say “&lt;strong&gt;No results found&lt;/strong&gt;.” If an exact match isn’t there, suggest a similar category, a popular product, or a way to contact support.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Fix “almost” matches.&lt;/strong&gt;&lt;br /&gt;Make
 sure the search can handle plurals (like “plant” vs. “plants”) and 
common typos. Users shouldn’t be punished for a slip of the thumb.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Predict the user’s goal.&lt;/strong&gt;&lt;br /&gt;Use an “auto-suggest” menu to show helpful actions (like “Track my order”) or categories, not just a list of words.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Talk like a human.&lt;/strong&gt;&lt;br /&gt;Look
 at your search logs to see the words people actually use. If they type 
“couch” and you call it “sofa,” create a bridge in the background so 
they find what they need anyway.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Smart filtering.&lt;/strong&gt;&lt;br /&gt;Only
 show filters that matter. If someone searches for “shoes,” show them 
size and color filters, not a generic list that applies to the whole 
site.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Show, don’t just list.&lt;/strong&gt;&lt;br /&gt;Use small 
thumbnails and clear labels in the search results so users can see the 
difference between a product, a blog post, and a help article at a 
glance.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Speed is trust.&lt;/strong&gt;&lt;br /&gt;If the search takes more than a second, use a loading animation. If it’s too slow, people will immediately go back to Google.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Check the “failure” logs.&lt;/strong&gt;&lt;br /&gt;Once
 a month, look at what people searched for that returned zero results. 
This is your “to-do list” for fixing your site’s navigation.&lt;/li&gt;&lt;/ul&gt;&lt;h2 id="conclusion-the-search-bar-is-a-conversation"&gt;Conclusion: The Search Bar Is A Conversation&lt;/h2&gt;&lt;p&gt;The
 search box is the only place on your site where the user tells us 
exactly, in their own words, what they want. When we fail to understand 
those words, when we let the “Big Box” of Google do the work for us, we 
aren’t just losing a page view. We are losing the opportunity to prove 
that we &lt;strong&gt;understand&lt;/strong&gt; our customers.&lt;/p&gt;&lt;blockquote class="pull-quote"&gt;&lt;p&gt;&lt;a aria-label="Share on Twitter" class="pull-quote__link" href="https://twitter.com/share?text=%0aSuccess%20in%20modern%20UX%20isn%e2%80%99t%20about%20having%20the%20most%20content;%20it%e2%80%99s%20about%20having%20the%20most%20findable%20content.%20It%e2%80%99s%20time%20to%20stop%20taxing%20users%20for%20their%20syntax%20and%20start%20designing%20for%20their%20intent.%0a&amp;amp;url=https://smashingmagazine.com%2f2026%2f03%2fsite-search-paradox-why-big-box-always-wins%2f"&gt;Success
 in modern UX isn’t about having the most content; it’s about having the
 most findable content. It’s time to stop taxing users for their syntax 
and start designing for their intent.&lt;/a&gt;&lt;/p&gt;&lt;div class="pull-quote__quotation"&gt;&lt;div class="pull-quote__bg"&gt;&lt;span class="pull-quote__symbol"&gt;“&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;p&gt;By
 moving from literal string matching to semantic understanding, and by 
supporting our search engines with robust, human-centered Information 
Architecture, we can finally close the gap.&lt;/p&gt;</description><link>http://honeyvig.blogspot.com/2026/04/the-site-search-paradox-why-big-box.html</link><author>noreply@blogger.com (H)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9165069509664255576.post-6938033417554899952</guid><pubDate>Tue, 28 Apr 2026 06:52:00 +0000</pubDate><atom:updated>2026-04-27T23:52:00.118-07:00</atom:updated><title>A Practical Guide To Design Principles</title><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="c-garfield-summary"&gt;&lt;section aria-label="Quick summary" class="article__summary"&gt;by Vitaly.&lt;/section&gt;&lt;/div&gt;&lt;p&gt;We often see design principles as rigid guidelines that dictate design decisions. But actually, they are an incredible tool to &lt;strong&gt;rally the team around a shared purpose&lt;/strong&gt; and document the values and beliefs that an organization embodies.&lt;/p&gt;&lt;p&gt;They
 align teams and inform decision-making. They also keep us afloat amidst
 all the hype, big assumptions, desire for faster delivery, and AI 
workslop. But how do we choose the right ones, and how do we get 
started? Let’s find out.&lt;/p&gt;&lt;h2 id="real-world-design-principles"&gt;Real-World Design Principles&lt;/h2&gt;&lt;p&gt;In times when we can generate any passable design and code within minutes, we need to decide better &lt;strong&gt;what’s worth designing and building&lt;/strong&gt; — and what values we want our products to embody.&lt;/p&gt;&lt;p&gt;It’s
 similar to voice and tone. You might not design it intentionally, but 
then end users will define it for you. And so, without principles, many 
company initiatives are &lt;strong&gt;random, sporadic, ad-hoc&lt;/strong&gt; — and feel vague, inconsistent, or simply dull to the outside world.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Design principles&lt;/strong&gt; are guidelines and design considerations that &lt;a href="https://ixdf.org/literature/topics/design-principles"&gt;designers apply with discretion&lt;/a&gt; — by default, without debating or discussing what has already been agreed upon.&lt;/p&gt;&lt;p&gt;One fantastic resource that I keep coming back to after all these years is Ben Brignell’s &lt;a href="https://principles.design"&gt;Principles.design&lt;/a&gt;. It has &lt;strong&gt;230 pointers for design principles and methods&lt;/strong&gt;, searchable and tagged, covering everything from language and infrastructure to hardware and organizations.&lt;/p&gt;&lt;h2 id="10-principles-of-good-design"&gt;10 Principles Of Good Design&amp;nbsp;&lt;/h2&gt;&lt;p&gt;There is no shortage of principles out there. But the good ones are more than just being &lt;em&gt;visionary&lt;/em&gt; — they &lt;strong&gt;have a point of view&lt;/strong&gt;, and they explain what we &lt;em&gt;don’t do&lt;/em&gt; as much as what we do. They also explain what &lt;strong&gt;we stand for&lt;/strong&gt; in the world — beyond profits, stock prices, and all the hype and noise around us.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://www.vitsoe.com/gb/about/good-design#good-design-is-innovative"&gt;&lt;img alt="10 legendary principles for good design" height="559" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/stop-endless-debates-design-principles/1-principles-good-design.jpg" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;10 legendary principles for good design, by &lt;a href="https://www.vitsoe.com/gb/about/good-design#good-design-is-innovative"&gt;Dieter Rams&lt;/a&gt;. Still relevant, after all these years.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Many years ago, I encountered &lt;a href="https://www.vitsoe.com/gb/about/good-design#good-design-is-innovative"&gt;Dieter Rams’ 10 principles of good design&lt;/a&gt; (see above), a very &lt;strong&gt;humble, practical and tangible&lt;/strong&gt; overview of principles that were informing, shaping, and guarding his design work at Braun.&lt;/p&gt;&lt;p&gt;There are &lt;strong&gt;no visionary claims&lt;/strong&gt;,
 and no big bold statements: just a clear overview of what we do, and 
where our ambition and care lie for the products we are designing. It’s 
honest, sincere, and in many ways beautifully &lt;strong&gt;humane&lt;/strong&gt;.&lt;/p&gt;&lt;h3 id="examples-of-design-principles"&gt;Examples Of Design Principles&amp;nbsp;&lt;/h3&gt;&lt;p&gt;There are plenty of &lt;strong&gt;wonderful examples&lt;/strong&gt; that I keep close:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://www.anthropic.com/constitution"&gt;Anthropic’s Constitution&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://principles.design/examples/principles-of-product-design"&gt;Principles of Product Design&lt;/a&gt;, by Joshua Porter&lt;/li&gt;&lt;li&gt;&lt;a href="https://principles.design/examples/20-guiding-principles-for-experience-design"&gt;Guiding Principles for Experience Design&lt;/a&gt;, by Whitney Hess, PCC&lt;/li&gt;&lt;li&gt;&lt;a href="https://github.com/Heydon/principles-of-web-accessibility"&gt;Principles of Web Accessibility&lt;/a&gt;, by Heydon Pickering&lt;/li&gt;&lt;li&gt;&lt;a href="https://humanebydesign.com"&gt;Humane by Design&lt;/a&gt;, by Jon Yablonski&lt;/li&gt;&lt;li&gt;&lt;a href="https://principles.design/examples/designing-for-voice-interfaces"&gt;Designing Voice UX Principles&lt;/a&gt;, by Brian Colcord&lt;/li&gt;&lt;li&gt;&lt;a href="https://linear.app/developers/aig"&gt;Agentic Design Principles&lt;/a&gt;, by Linear&lt;/li&gt;&lt;li&gt;&lt;a href="https://www.intercom.com/blog/principles-bot-design/"&gt;AI Chatbot Design Principles&lt;/a&gt;, by Emmet Connolly&lt;/li&gt;&lt;li&gt;&lt;a href="https://voiceprinciples.com"&gt;Voice UX Principles&lt;/a&gt;, by Ben Sauer&lt;/li&gt;&lt;/ul&gt;&lt;h3 id="design-principles-in-design-systems"&gt;Design Principles In Design Systems&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://guides.18f.org/"&gt;18F&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://styleguide.audi.com/document/2440#/-/experience-principles"&gt;Audi&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://www.ibm.com/design/language/philosophy/principles/"&gt;Carbon (IBM)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://acorn.firefox.com/latest/get-started/firefox-design-principles-5ezPvNdo"&gt;Firefox&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://www.gov.uk/guidance/government-design-principles"&gt;Gov.uk&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://contentdesign.intuit.com/style-and-usage/our-principles/"&gt;Intuit&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://service-manual.nhs.uk/design-system/design-principles"&gt;NHS&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://nordhealth.design/principles/"&gt;Nordhealth&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://base.uber.com/6d2425e9f/p/434f39-principles"&gt;Uber&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 id="how-to-establish-design-principles"&gt;How To Establish Design Principles&lt;/h2&gt;&lt;p&gt;Design principles can be personal, but usually they are committed to and shaped by the &lt;strong&gt;entire product team&lt;/strong&gt;. Design principles &lt;strong&gt;aren’t just for designers&lt;/strong&gt;. User’s experience is &lt;em&gt;everything&lt;/em&gt; from performance to support to customer service, and ideally, participants would cover these areas as well.&lt;/p&gt;&lt;p&gt;In
 practice, though, establishing principles might feel incredibly 
challenging. They are abstract and fluffy and often ambiguous, and often
 very difficult to agree upon.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://www.figma.com/community/file/1051212964426062558"&gt;&lt;img alt="Workshop kit for a design principles workshop" height="461" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/stop-endless-debates-design-principles/2-design-principles-workshop.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;&lt;a href="https://www.figma.com/community/file/1051212964426062558"&gt;One of many workshop kits&lt;/a&gt; for a design principles workshop.&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;You can get started with a &lt;strong&gt;simple 8-step workshop&lt;/strong&gt; (inspired by &lt;a href="https://medium.com/@marcintreder/design-system-sprint-4-design-principles-8efb22d8a208"&gt;Marcin Treder&lt;/a&gt;, &lt;a href="https://medium.com/design-bootcamp/design-principles-workshop-a-template-15c7c90458f2"&gt;Maria Meireles&lt;/a&gt; and &lt;a href="https://www.better.care/blog-en/establishing-design-principles-for-a-design-system-and-what-it-taught-us/"&gt;Better&lt;/a&gt;):&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Pre-session Research&lt;/strong&gt;&lt;br /&gt;Study how users speak about the products, what they appreciate, and the words they use.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Get Into Principles Mode&lt;/strong&gt;&lt;br /&gt;Invite 6–8 participants, ask them to choose their favorite object, and describe it in 3 words.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Product Analogies&lt;/strong&gt;&lt;br /&gt;Compare product to tangible items (e.g., ‘A Porsche 911’ or ‘a Braun audio system’).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Extract Attributes&lt;/strong&gt;&lt;br /&gt;Individually, in silence, everyone writes 3–5 initial principles, which are then grouped by theme for review.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Link Attributes To Research&lt;/strong&gt;&lt;br /&gt;Link attributes to actual user pain points or desires, to make sure they are grounded in reality.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Value Statements&lt;/strong&gt;&lt;br /&gt;We write &lt;em&gt;‘We want X because of Y’&lt;/em&gt; sentences that express the rationale behind our thinking.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Move to Principles&lt;/strong&gt;&lt;br /&gt;Remove analogies to create enduring rules that will guide our design process.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Reality Check&lt;/strong&gt;&lt;br /&gt;Search for both positive and negative examples in our products to see where principles are being met or ignored.&lt;/li&gt;&lt;/ol&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://www.better.care/blog-en/establishing-design-principles-for-a-design-system-and-what-it-taught-us/"&gt;&lt;img alt="Variants of sentences for establishing design principles" height="492" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/stop-endless-debates-design-principles/3-design-principles.jpg" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Voting for the most relevant sentences in keyword groups. From &lt;a href="https://www.better.care/blog-en/establishing-design-principles-for-a-design-system-and-what-it-taught-us/"&gt;Better&lt;/a&gt;. (&lt;a href="https://files.smashing.media/articles/stop-endless-debates-design-principles/3-design-principles.jpg"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="useful-starter-kits-for-principles-workshops"&gt;Useful Starter Kits For Principles Workshops&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/04/practical-guide-design-principles/#useful-starter-kits-for-principles-workshops"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://medium.com/design-bootcamp/design-principles-workshop-a-template-15c7c90458f2"&gt;Design Principles Workshop (Figma Template)&lt;/a&gt;, by Maria Meireles&lt;/li&gt;&lt;li&gt;&lt;a href="https://www.figma.com/community/file/1051212964426062558"&gt;Design Principles Workshop (FigJam Template)&lt;/a&gt;, by Richard Picot&lt;/li&gt;&lt;li&gt;&lt;a href="https://miro.com/templates/design-principles-workshop/"&gt;How to Create Design Principles (Miro Workshop Template)&lt;/a&gt;, by NanoGiants&lt;/li&gt;&lt;/ul&gt;&lt;h2 id="wrapping-up"&gt;Wrapping Up&amp;nbsp;&lt;/h2&gt;&lt;p&gt;Creating principles is only a small portion of the work; most work is about &lt;strong&gt;effectively sharing and embedding them&lt;/strong&gt;. It’s difficult to get anywhere without finding ways to &lt;strong&gt;make design principles a default&lt;/strong&gt; — by revisiting settings, templates, naming conventions, and output.&lt;/p&gt;&lt;p&gt;Principles help &lt;strong&gt;avoid endless discussions&lt;/strong&gt;
 that often stem from personal preferences or taste. But design should 
not be a matter of taste; it must be guided by our goals and values. 
Design principles can help with just that.&lt;/p&gt;&lt;h2 id="useful-resources"&gt;Useful Resources&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://principles.design"&gt;Design Principles Collection&lt;/a&gt;, by Ben Brignell&lt;/li&gt;&lt;li&gt;“&lt;a href="https://medium.com/@marcintreder/design-system-sprint-4-design-principles-8efb22d8a208"&gt;How To Establish Design Principles&lt;/a&gt;”, by Marcin Treder&lt;/li&gt;&lt;li&gt;“&lt;a href="https://www.better.care/blog-en/establishing-design-principles-for-a-design-system-and-what-it-taught-us/"&gt;Establishing Design Principles for a Design System and What It Taught Us&lt;/a&gt;”, by Better Design Team&lt;/li&gt;&lt;li&gt;&lt;a href="https://principles.adactio.com"&gt;Design Principles&lt;/a&gt;, by Jeremy Keith&lt;/li&gt;&lt;li&gt;&lt;a href="https://www.designprinciplesftw.com"&gt;Design Principles Collection&lt;/a&gt;, by Gabriel Svennerberg&lt;/li&gt;&lt;li&gt;&lt;a href="https://medium.com/design-bootcamp/design-principles-workshop-a-template-15c7c90458f2"&gt;Design Principles Workshop (Figma Template)&lt;/a&gt;, by Maria Meireles&lt;/li&gt;&lt;li&gt;&lt;a href="https://www.figma.com/community/file/1051212964426062558"&gt;Design Principles Workshop (FigJam Template)&lt;/a&gt;, by Richard Picot&lt;/li&gt;&lt;li&gt;&lt;a href="https://miro.com/templates/design-principles-workshop/"&gt;How to Create Design Principles (Miro Workshop Template)&lt;/a&gt;, by NanoGiants&lt;/li&gt;&lt;li&gt;&lt;a href="https://designsystems.surf/components/modal"&gt;Modals in Design Systems&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</description><link>http://honeyvig.blogspot.com/2026/04/a-practical-guide-to-design-principles.html</link><author>noreply@blogger.com (H)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9165069509664255576.post-7433714191173803800</guid><pubDate>Mon, 27 Apr 2026 08:53:00 +0000</pubDate><atom:updated>2026-04-27T01:53:02.232-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Feature Engineering Feature</category><title>Why Senior Engineers Go Quiet — The Hidden 3-Week Warning Before Failure</title><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="ember-view reader-text-block__paragraph" id="ember62"&gt;
      &lt;em&gt;Delivery intelligence for technology leaders&lt;/em&gt;&lt;span class="white-space-pre"&gt; &lt;/span&gt;· &amp;nbsp; Issue #40 &amp;nbsp; · &amp;nbsp; Every Wednesday
    &lt;/p&gt;

  






            
        
    &lt;h2 class="ember-view reader-text-block__heading-2" id="ember63"&gt;
      Not 3 months. Not 3 weeks of runway. 3 weeks until something breaks.
    &lt;/h2&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember64"&gt;
      &lt;em&gt;Disclaimer: Details in this issue have been changed to protect client confidentiality. The situation and the lesson are real&lt;/em&gt;
    &lt;/p&gt;

  










            
  &lt;hr class="reader-divider-block__horizontal-rule" /&gt;



            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember65"&gt;
      &lt;strong&gt;She had been the most engaged person in every stand-up for 7 months.&lt;/strong&gt;
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember66"&gt;
      The lead engineer on our most complex workstream. Sharp, direct, 
the kind of person who would call out a bad architectural decision in 
front of the client without hesitation. She had identified three 
significant technical risks in the first quarter, all of which were 
caught before they reached the backlog. The team trusted her completely.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember67"&gt;
      In week 29, I noticed she had not challenged anything in stand-up 
for 6 days. She was answering her 3 questions. She was present. She was 
doing her work. She had just stopped.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember68"&gt;
      &lt;em&gt;"Yesterday I finished the integration layer. Today I'm continuing the same. No blockers."&lt;/em&gt;
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember69"&gt;
      Eleven days later, the integration layer failed under load. It was
 not a simple bug. It was a structural decision that had been made in 
week 26 - one she had known was wrong, had decided not to raise, and had
 spent the following three weeks building around.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember70"&gt;
      When I asked her why she had not flagged it, her answer was more honest than I had expected:&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;strong&gt;&lt;em&gt;"I
 raised two things in month 5 and both times I felt like I was being 
managed rather than heard. I decided it wasn't worth the energy."&lt;/em&gt;&lt;/strong&gt;
    &lt;/p&gt;

  










            
  &lt;hr class="reader-divider-block__horizontal-rule" /&gt;



            
        &lt;pre class="reader-text-block__code-block"&gt;&lt;code&gt;Today's menu:

&#128680;  The problem: The specific silence pattern that precedes every major technical failure I have seen in 14 years and why it is always the most capable person who goes quiet first

&#128184;  What it costs: Why the silence of senior engineers is the most accurate leading indicator of delivery risk available and why it never appears on a RAID log

✅  The fix: The 3-week intervention that catches the pattern before it becomes a crisis&lt;/code&gt;&lt;/pre&gt;
  










            
  &lt;hr class="reader-divider-block__horizontal-rule" /&gt;



            
        
    &lt;h3 class="ember-view reader-text-block__heading-3" id="ember71"&gt;
      ⚠️&amp;nbsp; The silence pattern — what it is and why the best person goes first
    &lt;/h3&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember72"&gt;
      Senior engineers go quiet in stand-ups for a specific, 
identifiable reason that is almost never the one delivery leaders 
assume. It is not burnout — burnout produces agitation before silence. 
It is not disengagement — disengagement produces lower quality work, not
 lower verbal frequency. And it is almost never satisfaction.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember73"&gt;
      The most common cause of senior-engineer silence in a 
well-functioning team is a specific, rational cost-benefit calculation: 
the engineer has assessed that the cost of raising a concern — the 
social friction, the pushback, the feeling of being managed — is greater
 than the benefit of having the concern heard. And they have made this 
calculation based on evidence from the programme.
    &lt;/p&gt;

  






            
        
    &lt;blockquote class="ember-view reader-text-block__blockquote" id="ember74"&gt;
      &lt;em&gt;Senior engineers do not go quiet because they have nothing to 
say. They go quiet because they have learned that saying it is not worth
 it.&lt;/em&gt;
    &lt;/blockquote&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember75"&gt;
      The reason the best engineer goes first is exactly their 
seniority. A junior developer raises concerns because they are still 
learning the social norms of the team. A senior engineer has already 
made the social calculation with much more precision — and has enough 
other things to focus on that withdrawing from verbal risk-raising is a 
rational conservation of energy.
    &lt;/p&gt;

  







              
    &lt;div class="reader-image-block reader-image-block--full-width"&gt;
      &lt;figure class="reader-image-block__figure"&gt;
          
    &lt;div class="ivm-image-view-model    reader-image-block__img-container"&gt;
        
    &lt;div class="ivm-view-attr__img-wrapper
        
        "&gt;

          &lt;img alt="Article content" class="ivm-view-attr__img--centered  reader-image-block__img evi-image lazy-image ember-view" id="ember76" src="https://media.licdn.com/dms/image/v2/D4D12AQFJgP8BKfUhDw/article-inline_image-shrink_1500_2232/B4DZ2NPq0XIoAc-/0/1776191189007?e=1778716800&amp;amp;v=beta&amp;amp;t=C_UYyJZ2ldBE-8vTQ2lKZPjpt2h5QhBWGJGmbPt1-yg" /&gt;
    &lt;/div&gt;
  
          &lt;/div&gt;
  

          &lt;figcaption class="reader-image-block__figure-image-caption display-block full-width text-body-small-open t-sans text-align-center t-black--light"&gt;
            
          &lt;/figcaption&gt;
      &lt;/figure&gt;
    &lt;/div&gt;
  









            
  &lt;hr class="reader-divider-block__horizontal-rule" /&gt;



            
        
    &lt;h3 class="ember-view reader-text-block__heading-3" id="ember77"&gt;
      &#129300;&amp;nbsp; Quiz
    &lt;/h3&gt;

  






            
        &lt;pre class="reader-text-block__code-block"&gt;&lt;code&gt;You lead a 12-person engineering team. Your most senior developer historically engaged, opinionated, and reliable has given a variation of "all good, no blockers" in stand-up for 8 consecutive days. Delivery metrics are normal. What is the right first action?

A)  Nothing — consistent delivery metrics are the signal that matters, not verbal frequency

B)  Ask them directly in the stand-up: "Are you sure there are no blockers? You've been very quiet this week."

C)  Have a private 15-minute conversation outside the stand-up: "I've noticed you have been less vocal recently, is there anything you're sitting on that you haven't raised?"

D)  Send a team-wide message encouraging everyone to raise concerns more actively

&#128073;  Answer at the end of this issue&lt;/code&gt;&lt;/pre&gt;
  










            
  &lt;hr class="reader-divider-block__horizontal-rule" /&gt;



            
        
    &lt;h3 class="ember-view reader-text-block__heading-3" id="ember78"&gt;
      &#128161;&amp;nbsp; The fix
    &lt;/h3&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember79"&gt;
      Three interventions timed specifically to the 3-week window before the silence becomes a structural problem.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember80"&gt;
      &lt;strong&gt;✅&amp;nbsp; Fix 1: Week 1 — The private, direct conversation&lt;/strong&gt;
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember81"&gt;
      Within 5 days of noticing the silence, a 15-minute private 
conversation. Not a performance conversation. Not a welfare check. A 
specific, respectful inquiry:
    &lt;/p&gt;

  






            
        
    &lt;blockquote class="ember-view reader-text-block__blockquote" id="ember82"&gt;
      &lt;em&gt;"I've noticed you've been less vocal in stand-ups recently. I 
want to make sure I'm not missing something important. Is there anything
 you are sitting on technically or otherwise that you haven't raised?"&lt;/em&gt;
    &lt;/blockquote&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember83"&gt;
      The silence after this question is important. Do not fill it. The 
engineer is doing a rapid cost-benefit recalculation. Is this person 
going to hear what I say or manage it? Your job in the first 90 seconds 
after they speak is to demonstrate, specifically and behaviourally, that
 you are doing the former.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember84"&gt;
      If they say "nothing, all fine": thank them and leave the door 
open. Watch for a second week of silence. If that occurs, the 
calculation has been made and you need the next intervention.
    &lt;/p&gt;

  







              
    &lt;div class="reader-image-block reader-image-block--full-width"&gt;
      &lt;figure class="reader-image-block__figure"&gt;
          
    &lt;div class="ivm-image-view-model    reader-image-block__img-container"&gt;
        
    &lt;div class="ivm-view-attr__img-wrapper
        
        "&gt;

          &lt;img alt="Article content" class="ivm-view-attr__img--centered  reader-image-block__img evi-image lazy-image ember-view" id="ember85" src="https://media.licdn.com/dms/image/v2/D4D12AQH07i6UrxSi4g/article-inline_image-shrink_1500_2232/B4DZ2NQeiLJ0Ac-/0/1776191400643?e=1778716800&amp;amp;v=beta&amp;amp;t=Uqsut-Zb6No338Xl8Moe_j4pDCWGIJTKy7NzMVNQJkA" /&gt;
    &lt;/div&gt;
  
          &lt;/div&gt;
  

          &lt;figcaption class="reader-image-block__figure-image-caption display-block full-width text-body-small-open t-sans text-align-center t-black--light"&gt;
            
          &lt;/figcaption&gt;
      &lt;/figure&gt;
    &lt;/div&gt;
  





            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember86"&gt;
      &lt;strong&gt;✅&amp;nbsp; Fix 2: Week 2 — The concern-cost audit&lt;/strong&gt;
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember87"&gt;
      If the private conversation has not produced the information, the 
issue is structural: the cost of raising concerns in this team is too 
high. A 45-minute session with the senior engineers only, no junior team
 members, with one question:
    &lt;/p&gt;

  






            
        
    &lt;blockquote class="ember-view reader-text-block__blockquote" id="ember88"&gt;
      &lt;em&gt;"Think of the last time you identified a concern on this 
programme and decided not to raise it. What made you decide not to raise
 it?"&lt;/em&gt;
    &lt;/blockquote&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember89"&gt;
      Write every answer on a whiteboard. Do not defend against any of 
them. Do not explain or contextualise. Just write them down and read 
them back. The act of making the concern-cost visible, in a room, 
without defensiveness, is often enough to change the dynamic because it 
signals that this is now a problem you are taking seriously rather than 
managing.
    &lt;/p&gt;

  







              
    &lt;div class="reader-image-block reader-image-block--full-width"&gt;
      &lt;figure class="reader-image-block__figure"&gt;
          
    &lt;div class="ivm-image-view-model    reader-image-block__img-container"&gt;
        
    &lt;div class="ivm-view-attr__img-wrapper
        
        "&gt;

          &lt;img alt="Article content" class="ivm-view-attr__img--centered  reader-image-block__img evi-image lazy-image ember-view" id="ember90" src="https://media.licdn.com/dms/image/v2/D4D12AQFEm7oCExGt6A/article-inline_image-shrink_1000_1488/B4DZ2NQx9.J0AQ-/0/1776191480675?e=1778716800&amp;amp;v=beta&amp;amp;t=DDXn1E__0nYmpjqSjXPy5n8yTvxqHvbZARz0W2NiAyo" /&gt;
    &lt;/div&gt;
  
          &lt;/div&gt;
  

          &lt;figcaption class="reader-image-block__figure-image-caption display-block full-width text-body-small-open t-sans text-align-center t-black--light"&gt;
            
          &lt;/figcaption&gt;
      &lt;/figure&gt;
    &lt;/div&gt;
  





            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember91"&gt;
      &lt;strong&gt;✅&amp;nbsp; Fix 3: Week 3 — The structural fix builds concern-raising into the process, not the person&lt;/strong&gt;
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember92"&gt;
      If the silence persists into week 3, the issue is not about the 
individual engineer. It is about the environment. Three structural 
changes that reduce the cost of raising concerns at the team level:
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember93"&gt;
            &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;The end-of-day risk log.&lt;/strong&gt;&lt;span class="white-space-pre"&gt; &lt;/span&gt;A
 standing Slack channel or equivalent where the only acceptable input is
 "I noticed X today and I am not sure whether it is a risk." No 
resolution required. No follow-up demanded. Just observation. The 
programme lead acknowledges every entry within 24 hours.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The pre-commitment check.&lt;/strong&gt;&lt;span class="white-space-pre"&gt; &lt;/span&gt;Before
 any architectural or technical decision is finalised, one question is 
asked of the most senior person who disagreed with it: "What would need 
to happen for you to be proven right?" This gives dissent a legitimate 
structural role instead of requiring it to be raised as a confrontation.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The monthly technical retrospective.&lt;/strong&gt;&lt;span class="white-space-pre"&gt; &lt;/span&gt;Separate
 from the delivery retrospective. Focused entirely on technical 
decisions: what are we building that we are not comfortable with? This 
is where the concerns that are too technical to raise in a delivery 
forum find a legitimate place.&lt;/li&gt;&lt;/ul&gt;

    &lt;p&gt;&lt;/p&gt;

  







              
    &lt;div class="reader-image-block reader-image-block--full-width"&gt;
      &lt;figure class="reader-image-block__figure"&gt;
          
    &lt;div class="ivm-image-view-model    reader-image-block__img-container"&gt;
        
    &lt;div class="ivm-view-attr__img-wrapper
        
        "&gt;

          &lt;img alt="Article content" class="ivm-view-attr__img--centered  reader-image-block__img evi-image lazy-image ember-view" id="ember94" src="https://media.licdn.com/dms/image/v2/D4D12AQG9SNJ78kHNMg/article-inline_image-shrink_1500_2232/B4DZ2NRDVEG0AU-/0/1776191551367?e=1778716800&amp;amp;v=beta&amp;amp;t=mwbh-yxgC90C7TutpNXImwmWj7dN-gc5ydgLMHjDKwg" /&gt;
    &lt;/div&gt;
  
          &lt;/div&gt;
  

          &lt;figcaption class="reader-image-block__figure-image-caption display-block full-width text-body-small-open t-sans text-align-center t-black--light"&gt;
            
          &lt;/figcaption&gt;
      &lt;/figure&gt;
    &lt;/div&gt;
  









            
  &lt;hr class="reader-divider-block__horizontal-rule" /&gt;



            
        
    &lt;h3 class="ember-view reader-text-block__heading-3" id="ember95"&gt;
      &#127919;&amp;nbsp; What to do this week
    &lt;/h3&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember96"&gt;
      This week, track one metric you have probably never tracked before:
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember97"&gt;
            &lt;/p&gt;&lt;ul&gt;&lt;li&gt;For the three most senior engineers on your team: 
how many substantive observations (concerns, challenges, technical 
flags) have they made in stand-ups and ceremonies in the last 10 working
 days?&lt;/li&gt;&lt;li&gt;Not "did they attend." Not "are they performing." How many times did they say something that was not a status update?&lt;/li&gt;&lt;/ul&gt;

    &lt;p&gt;&lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember98"&gt;
      If the answer is fewer than two per person per week: you may have a silence pattern forming.&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;strong&gt;You now have 3 weeks before it becomes a structural problem.&lt;/strong&gt;
    &lt;/p&gt;

  










            
  &lt;hr class="reader-divider-block__horizontal-rule" /&gt;



            
        &lt;pre class="reader-text-block__code-block"&gt;&lt;code&gt;Want the concern-cost audit questions — the exact 45-minute format?

Reply "silence" to this email and I'll send it directly to you.&lt;/code&gt;&lt;/pre&gt;
  










            
  &lt;hr class="reader-divider-block__horizontal-rule" /&gt;



            
        
    &lt;h3 class="ember-view reader-text-block__heading-3" id="ember99"&gt;
      &#127760;&amp;nbsp; Around the web this week
    &lt;/h3&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember100"&gt;
      &lt;strong&gt;⚡&amp;nbsp; 1 tool:&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;/strong&gt;TeamRetro
 — asynchronous retrospective tool with anonymous input. The specific 
use case: a standing "what am I not saying" prompt that team members can
 contribute to before the synchronous session. The anonymity removes the
 social cost before the concern reaches the room.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember101"&gt;
      &lt;strong&gt;&#128202;&amp;nbsp; 1 number:&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;/strong&gt;Google's
 Project Aristotle research found that psychological safety, the belief 
that one will not be punished for raising concerns, is the single 
strongest predictor of team effectiveness across the 180 teams studied. 
It ranked above all technical, organisational, and individual competence
 factors. The silence pattern is what happens when psychological safety 
has already failed.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember102"&gt;
      &lt;strong&gt;&#128172;&amp;nbsp; 1 quote:&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;/strong&gt;&lt;em&gt;"What
 got you here won't get you there." - Marshall Goldsmith. For delivery 
leaders, what got you here: confidence, decisiveness, pattern-matching 
from experience, is precisely what creates the silence in your best 
people. Success and the conditions for future success are not the same 
thing.&lt;/em&gt;
    &lt;/p&gt;

  










            
  &lt;hr class="reader-divider-block__horizontal-rule" /&gt;



            
        
    &lt;h3 class="ember-view reader-text-block__heading-3" id="ember103"&gt;
      &#128073;&amp;nbsp; Quiz answer
    &lt;/h3&gt;

  






            
        
    &lt;blockquote class="ember-view reader-text-block__blockquote" id="ember104"&gt;
      &lt;strong&gt;C — private, direct, and non-accusatory.&lt;/strong&gt;
    &lt;/blockquote&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember105"&gt;
      Option A is the most common response and the most dangerous, it 
treats delivery metrics as the only signal that matters, which is the 
assumption that allows this pattern to reach crisis. Option B creates a 
public moment that compounds the social cost already causing the 
silence. Option D is too diffuse to address the specific pattern and may
 actually increase the cost of raising concerns by making it feel 
scrutinised.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember106"&gt;
      Option C works because it is private, it is observational rather 
than accusatory ("I've noticed" not "why aren't you"), and it 
specifically names the concern about unraised issues. It gives the 
engineer a low-cost way to surface what they are sitting on without 
requiring them to do it in front of the team. The phrase "is there 
anything you're sitting on" is important — it names the specific pattern
 you are looking for.
    &lt;/p&gt;

  










            
  &lt;hr class="reader-divider-block__horizontal-rule" /&gt;



            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember107"&gt;
      The lead engineer I described in the opening story is, as far as I
 know, thriving. She left the programme at the end of that engagement — 
not because of the incident, but because the engagement ended.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember108"&gt;
      What she taught me by going quiet, by deciding three weeks before 
the failure that raising concerns was not worth the energy, is something
 I now treat as the most important signal in any programme I lead. Not 
the RAG status. Not the velocity chart. The voice of the most capable 
person in the room.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember109"&gt;
      &lt;strong&gt;When that voice goes quiet, everything else is noise. The 3-week clock is already running.&lt;/strong&gt;
    &lt;/p&gt;

  






            
        
    &lt;blockquote class="ember-view reader-text-block__blockquote" id="ember110"&gt;
      Think of the most technically capable person on your current team.
 When did they last challenge something, a decision, an assumption, a 
plan in a group setting? If you cannot remember, the clock may already 
be running.
    &lt;/blockquote&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember111"&gt;
      &lt;em&gt;Hit reply. I read everything.&lt;/em&gt;
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember112"&gt;
      Until next Wednesday,
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember113"&gt;
      &lt;strong&gt;Aman&lt;/strong&gt;
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember114"&gt;
      &lt;a class="xwxVfcRwnBUeGipgoiZPeKPJMrvzgAVqE " data-test-app-aware-link="" href="http://www.amansingh.pro" tabindex="0" target="_self"&gt;&lt;em&gt;www.amansingh.pro&lt;/em&gt;&lt;/a&gt;
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember115"&gt;
      
        &lt;br /&gt;
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember116"&gt;
      &lt;em&gt;If this issue is named something you have been watching but could not describe, forward it to one person who needs to read it.&lt;/em&gt;
    &lt;/p&gt;</description><link>http://honeyvig.blogspot.com/2026/04/why-senior-engineers-go-quiet-hidden-3.html</link><author>noreply@blogger.com (H)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9165069509664255576.post-233338858945345680</guid><pubDate>Mon, 27 Apr 2026 06:50:00 +0000</pubDate><atom:updated>2026-04-26T23:50:42.834-07:00</atom:updated><title>How To Improve UX In Legacy Systems</title><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="c-garfield-summary"&gt;&lt;section aria-label="Quick summary" class="article__summary"&gt;Practical guidelines for driving UX impact in organizations with legacy systems and broken processes. Brought to you by &lt;a href="https://measure-ux.com/"&gt;Measuring UX Impact&lt;/a&gt;, &lt;strong&gt;friendly video course on UX&lt;/strong&gt; and design patterns by Vitaly.&lt;/section&gt;&lt;/div&gt;&lt;p&gt;Imagine that you need to improve the &lt;strong&gt;UX of a legacy system&lt;/strong&gt;.
 A system that has been silently working in the background for almost a 
decade. It’s slow, half-broken, unreliable, and severely outdated — a 
sort of “black box” that everyone relies upon, but nobody really knows 
what’s happening under the hood.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Where would you even start?&lt;/strong&gt;
 Legacy stories are often daunting, adventurous, and utterly confusing. 
They represent a mixture of fast-paced decisions, quick fixes, and 
accumulating UX debt.&lt;/p&gt;&lt;p&gt;There is no one-fits-all solution to tackle them, but there are ways to make progress, albeit slowly, while respecting the &lt;strong&gt;needs and concerns&lt;/strong&gt; of users and stakeholders. Now, let’s see how we can do just that.&lt;/p&gt;&lt;h2 id="the-actual-challenges-of-legacy-ux"&gt;The Actual Challenges Of Legacy UX&lt;/h2&gt;&lt;p&gt;It might feel that legacy products are waiting to be deprecated at any moment. But in reality, they are often &lt;strong&gt;critical for daily operations&lt;/strong&gt;.
 Many legacy systems are heavily customized for the needs of the 
organization, often built externally by a supplier and often without 
rigorous usability testing.&lt;/p&gt;&lt;p&gt;It’s common for enterprises to spend &lt;strong&gt;40–60% of their time&lt;/strong&gt; managing, maintaining, and fine-tuning legacy systems. They are essential, critical — but also very expensive to keep alive.&lt;/p&gt;&lt;figure&gt;&lt;a href="https://files.smashing.media/articles/how-improve-ux-legacy-systems/1-cash-register.jpg"&gt;&lt;img alt="A detailed electronic medical record (EMR) screen for an ophthalmology patient, displaying their visit summary including chief complaint, past medical history, medications, and optical test results." height="500" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/how-improve-ux-legacy-systems/1-cash-register.jpg" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Cash
 registers are frequently designed once and rarely touched again. 
Replacing them across 1000s of stores is remarkably expensive.&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="1-legacy-must-co-exist-with-products-built-around-them"&gt;1. Legacy Must Co-Exist With Products Built Around Them&lt;/h3&gt;&lt;p&gt;Running in a &lt;strong&gt;broken, decade-old ecosystem&lt;/strong&gt;,
 legacy still works, yet nobody knows exactly how and why it still does.
 People who have set it up originally probably have left the company 
years ago, leaving a lot of unknowns and poorly documented work behind.&lt;/p&gt;&lt;p&gt;With them come &lt;strong&gt;fragmented and inconsistent design choices&lt;/strong&gt;, stuck in old versions of old design tools that have long been discontinued.&lt;/p&gt;&lt;figure&gt;&lt;a href="https://files.smashing.media/articles/how-improve-ux-legacy-systems/2-legacy-system-healthcare.jpg"&gt;&lt;img alt="A detailed electronic medical record (EMR) screen for an ophthalmology patient, displaying their visit summary including chief complaint, past medical history, medications, and optical test results." src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/how-improve-ux-legacy-systems/2-legacy-system-healthcare.jpg" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;One of many: a legacy system used by EMR systems in healthcare.&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Still, legacy systems must neatly &lt;strong&gt;co-exist within modern digital products&lt;/strong&gt;
 built around them. In many ways, the end result resembles a 
Frankenstein — many bits and pieces glued together, often a mixture of 
modern UIs and painfully slow and barely usable fragments here and there
 — especially when it comes to validation, error messages, or processing
 data.&lt;/p&gt;&lt;h3 id="2-legacy-systems-make-or-break-ux"&gt;2. Legacy Systems Make or Break UX&lt;/h3&gt;&lt;p&gt;Once you sprinkle a little bit of quick bugfixing, unresolved business logic issues, and unresponsive layouts, you have a &lt;strong&gt;truly frustrating experience&lt;/strong&gt;, despite the enormous effort put into the rest of the application.&lt;/p&gt;&lt;p&gt;If one single step in a complex user flow feels &lt;strong&gt;utterly broken and confusing&lt;/strong&gt;,
 then the entire product appears to be broken as well, despite the 
incredible efforts the design teams have put together in the rest of the
 product.&lt;/p&gt;&lt;p&gt;Well, eventually, you’ll have to tackle legacy. And that’s where we need to consider available options for your &lt;strong&gt;UX roadmap&lt;/strong&gt;.&lt;/p&gt;&lt;h2 id="ux-roadmap-for-tackling-legacy-projects"&gt;UX Roadmap For Tackling Legacy Projects&amp;nbsp;&lt;/h2&gt;&lt;h3 id="don-t-dismiss-legacy-build-on-existing-knowledge"&gt;Don’t Dismiss Legacy: Build on Existing Knowledge&lt;/h3&gt;&lt;p&gt;Because
 legacy systems are often big unknowns that cause a lot of frustration 
to everyone, from stakeholders to designers to engineers to users. The 
initial thought might be to remove it entirely and &lt;strong&gt;redesign it from scratch&lt;/strong&gt;, but in practice, that’s not always feasible. Big-bang-redesign is a &lt;strong&gt;remarkably expensive&lt;/strong&gt; and very time-consuming endeavor.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/how-improve-ux-legacy-systems/3-questions-ask-legacy-system.png"&gt;&lt;img alt="An overview of questions to ask key stakeholders to understand the legacy system, its key features, workflows, and priorities." height="467" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/how-improve-ux-legacy-systems/3-questions-ask-legacy-system.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;First things first: map legacy features, workflows, and priorities as a part of discovery.&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Legacy systems &lt;strong&gt;hold valuable knowledge&lt;/strong&gt;
 about the business practice, and they do work — and a new system must 
perfectly match years of knowledge and customization done behind the 
scenes. That’s why stakeholders and users (in B2B) are typically &lt;strong&gt;heavily attached to legacy systems&lt;/strong&gt;, despite all their well-known drawbacks and pains.&lt;/p&gt;&lt;p&gt;To
 most people, because such systems are at the very heart of the 
business, operating on them seems to be extremely risky and will require
 a significant amount of &lt;strong&gt;caution and preparation&lt;/strong&gt;. 
Corporate users don’t want big risks. So instead of dismissing legacy 
entirely, we might start by gathering existing knowledge first.&lt;/p&gt;&lt;h3 id="map-existing-workflows-and-dependencies"&gt;Map Existing Workflows and Dependencies&lt;/h3&gt;&lt;p&gt;The
 best place to start is to understand how and where exactly legacy 
systems are in use. You might discover that some bits of the legacy 
systems are used all over the place — not only in your product, but also
 in business dashboards, by external agencies, and by other companies 
that integrate your product into their services.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://creative.navy/case-studies/ux-ui-design-technical-software-users"&gt;&lt;img alt="An overview of users’ behavior, frequency of use for features, and the complexity of the flow." height="464" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/how-improve-ux-legacy-systems/4-testing-session.jpg" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Testing
 sessions to understand where users struggle, and how difficult tasks 
are to complete for them. From a fantastic case study by &lt;a href="https://creative.navy/case-studies/ux-ui-design-technical-software-users"&gt;CreativeNavy&lt;/a&gt;.&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Very
 often, legacy systems have dependencies on their own, integrating other
 legacy systems that might be much older and in a much worse state. 
Chances are high that you might not even consider them in the big-bang 
redesign — mostly because you don’t know just &lt;strong&gt;how many black boxes&lt;/strong&gt; are in there.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://creative.navy/case-studies/ux-ui-design-technical-software-users"&gt;&lt;img alt="An overview of users’ behavior, frequency of use for features, and the complexity of the flow." src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/how-improve-ux-legacy-systems/5-map-workflows-user-behavior.jpg" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Map
 existing workflows by tracking user behavior, frequency, desired 
outcome, complexity, patterns, and user needs. From a fantastic case 
study by &lt;a href="https://creative.navy/case-studies/ux-ui-design-technical-software-users"&gt;CreativeNavy&lt;/a&gt;. (&lt;a href="https://files.smashing.media/articles/how-improve-ux-legacy-systems/5-map-workflows-user-behavior.jpg"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Set up a board to &lt;a href="https://www.linkedin.com/pulse/breaking-down-complexity-task-analysis-ux-vitaly-friedman-sjt4f/"&gt;document current workflows and dependencies&lt;/a&gt; to get a better idea of how everything works together. Include stakeholders, and &lt;strong&gt;involve heavy users in the conversation&lt;/strong&gt;.
 You won’t be able to open the black box, but you can still shed some 
light on it from the perspectives of different people who may be relying
 on legacy for their work.&lt;/p&gt;&lt;figure&gt;&lt;a href="https://files.smashing.media/articles/how-improve-ux-legacy-systems/6-prioritizing-migrated-features.png"&gt;&lt;img alt="Prioritizing migrated features and features by impact and urgency." height="375" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/how-improve-ux-legacy-systems/6-prioritizing-migrated-features.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Priorities matter. You won’t need to migrate everything, but you need to discover critical parts that must be migrated.&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Once you’ve done that, set up a meeting to &lt;strong&gt;reflect to users and stakeholders&lt;/strong&gt;
 what you have discovered. You will need to build confidence and trust 
that you aren’t missing anything important, and you need to visualize 
the dependencies that a legacy tool has to everyone involved.&lt;/p&gt;&lt;p&gt;Replacing a legacy system is &lt;strong&gt;never about legacy alone&lt;/strong&gt;. It’s about the dependencies and workflows that rely on it, too.&lt;/p&gt;&lt;h3 id="choose-your-ux-migration-strategy"&gt;Choose Your UX Migration Strategy&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/04/legacy-systems/#choose-your-ux-migration-strategy"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Once you have a &lt;strong&gt;big picture&lt;/strong&gt;
 in front of you, you need to decide on what to do next. Big-bang 
relaunch or a small upgrade? Which approach would work best? You might &lt;strong&gt;consider the following options&lt;/strong&gt; before you decide on how to proceed:&lt;/p&gt;&lt;figure&gt;&lt;a href="https://files.smashing.media/articles/how-improve-ux-legacy-systems/7-legacy-migration-strategies.jpg"&gt;&lt;img alt="A diagram titled ‘Legacy Migration Strategies’, showing five different approaches to migrating from an old system to a new system using arrows and descriptions." height="804" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/how-improve-ux-legacy-systems/7-legacy-migration-strategies.jpg" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;The
 different legacy migration strategies. You never migrate just a system —
 you also migrate workflows, habits, processes, and ways of working.&lt;/figcaption&gt;&lt;/figure&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Big-bang relaunch&lt;/strong&gt;.&lt;br /&gt;Sometimes
 the only available option, but it’s very risky, expensive, and can take
 years, without any improvements to the existing setup in the meantime.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Incremental migration&lt;/strong&gt;.&lt;br /&gt;Slowly retire pieces of legacy by replacing small bits with new designs. This offers quicker wins in a &lt;code&gt;Frankenstein&lt;/code&gt; style but can make the system unstable.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Parallel migration&lt;/strong&gt;.&lt;br /&gt;Run
 a public beta of the replacement alongside the legacy system to involve
 users in shaping the new design. Retire the old system when the new one
 is stable, but be prepared for the cost of maintaining both.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Incremental parallel migration&lt;/strong&gt;.&lt;br /&gt;List
 all business requirements the legacy system fulfills, then build a new 
product to meet them reliably, matching the old system from day one. 
Test early with power users, possibly offering an option to switch 
systems until the old one is fully retired.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Legacy UI upgrade + public beta&lt;/strong&gt;.&lt;br /&gt;Perform
 low-risk fine-tuning on the legacy system to align UX, while 
incrementally building a new system with a public beta. This yields 
quicker and long-term wins, ideal for fast results.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Replacing
 a system that has been carefully refined and heavily customized for a 
decade is a monolithic task. You can’t just rebuild something from 
scratch within a few weeks that others have been working on for years.&lt;/p&gt;&lt;p&gt;So whenever possible, try to &lt;strong&gt;increment gradually&lt;/strong&gt;, involving users and stakeholders and engineers along the way — and with enough &lt;strong&gt;buffer time&lt;/strong&gt; and &lt;strong&gt;continuous feedback loops&lt;/strong&gt;.&lt;/p&gt;&lt;h2 id="wrapping-up"&gt;Wrapping Up&lt;/h2&gt;&lt;p&gt;With legacy projects, failure is often not an option. You’re migrating not just components, but &lt;strong&gt;users and workflows&lt;/strong&gt;. Because you operate on the &lt;strong&gt;very heart of the business&lt;/strong&gt;, expect a lot of attention, skepticism, doubts, fears, and concerns. So build &lt;strong&gt;strong relationships&lt;/strong&gt;
 with key stakeholders and key users and share ownership with them. You 
will need their support and their buy-in to bring your UX work in 
action.&lt;/p&gt;&lt;p&gt;Stakeholders will request old and new features. They will focus on &lt;strong&gt;edge cases, exceptions, and tiny tasks&lt;/strong&gt;.
 They will question your decisions. They will send mixed signals and 
change their opinions. And they will expect the new system to run 
flawlessly from day one.&lt;/p&gt;&lt;p&gt;And the best thing you can do is to work 
with them throughout the entire design process, right from the very 
beginning. Run a successful pilot project to &lt;strong&gt;build trust&lt;/strong&gt;. Report your progress repeatedly. And account for &lt;strong&gt;intense phases of rigorous testing&lt;/strong&gt; with legacy users.&lt;/p&gt;&lt;p&gt;Revamping
 a legacy system is a tough challenge. But there is rarely any project 
that can have so much impact on such a scale. Roll up your sleeves and 
get through it successfully, and your team will be &lt;strong&gt;remembered, respected, and rewarded&lt;/strong&gt; for years to come.&lt;/p&gt;&lt;div class="book-cta__inverted"&gt;&lt;div class="book-cta" data-handler="ContentTabs" data-mq="(max-width: 480px)"&gt;&lt;div class="book-cta__col book-cta__hardcover content-tab--content"&gt;&lt;h3 class="book-cta__title"&gt;&lt;span&gt;Video + UX Training&lt;/span&gt;&lt;/h3&gt;&lt;span class="book-cta__price"&gt;&lt;span&gt;&lt;span&gt;&lt;span class="currency-sign"&gt;$&lt;/span&gt;&amp;nbsp;&lt;span&gt;495&lt;sup class="sup"&gt;.00&lt;/sup&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class="book-cta__price--old"&gt;&lt;span class="currency-sign"&gt;$&lt;/span&gt;&amp;nbsp;&lt;span&gt;799&lt;sup class="sup"&gt;.00&lt;/sup&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;a class="btn btn--full btn--medium btn--text-shadow" href="https://smart-interface-design-patterns.thinkific.com/enroll/3081832?price_id=3951439"&gt;Get Video + UX Training&lt;div&gt;&lt;/div&gt;&lt;/a&gt;&lt;p class="book-cta__desc"&gt;25 video lessons (8h) + &lt;a href="https://smashingconf.com/online-workshops/workshops/vitaly-friedman-impact-design/"&gt;Live UX Training&lt;/a&gt;.&lt;br /&gt;100 days money-back-guarantee.&lt;/p&gt;&lt;/div&gt;&lt;div class="book-cta__col book-cta__ebook content-tab--content"&gt;&lt;h3 class="book-cta__title"&gt;&lt;span&gt;Video only&lt;/span&gt;&lt;/h3&gt;&lt;div data-audience="anonymous free supporter" data-remove="true"&gt;&lt;span class="book-cta__price" data-handler="PriceTag"&gt;&lt;span&gt;&lt;span&gt;&lt;span class="currency-sign"&gt;$&lt;/span&gt;&amp;nbsp;&lt;span&gt;250&lt;sup class="sup"&gt;.00&lt;/sup&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="book-cta__price--old"&gt;&lt;span class="currency-sign"&gt;$&lt;/span&gt;&amp;nbsp;&lt;span&gt;350&lt;sup class="sup"&gt;.00&lt;/sup&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;a class="btn btn--full btn--medium btn--text-shadow" href="https://smart-interface-design-patterns.thinkific.com/enroll/3081832?price_id=3950630"&gt;Get the video course&lt;div&gt;&lt;/div&gt;&lt;/a&gt;&lt;p class="book-cta__desc" data-audience="anonymous free supporter" data-remove="true"&gt;25 video lessons (8h). Updated yearly.&lt;br /&gt;Also available as a &lt;a href="https://smart-interface-design-patterns.thinkific.com/enroll/3570306?price_id=4503439"&gt;UX Bundle with 3 video courses.&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="useful-resources"&gt;Useful Resources&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://blog.scottlogic.com/2021/07/16/UX-Migration-Strategy.html"&gt;UX Migration Strategy For Legacy Apps&lt;/a&gt;, by Tamara Chehayeb Makarem&lt;/li&gt;&lt;li&gt;&lt;a href="https://uxdesign.cc/to-improve-legacy-systems-sometimes-you-need-to-take-a-restoration-mindset-d72f7b69442f?sk=v2%2F524df15a-3aca-48f6-adff-98588a64bda0"&gt;How To Improve Legacy Systems&lt;/a&gt;, by Christopher Wong&lt;/li&gt;&lt;li&gt;&lt;a href="https://medium.com/enterprise-ux/designing-with-legacy-d0e4bef0d9ea"&gt;Designing With Legacy&lt;/a&gt;, by Peter Zalman&lt;/li&gt;&lt;li&gt;&lt;a href="https://medium.com/design-bootcamp/redesigning-a-legacy-system-for-a-large-organisation-5089429f7e2e"&gt;Redesigning A Large Legacy System&lt;/a&gt;, by Pawel Halicki&lt;/li&gt;&lt;li&gt;&lt;a href="https://understandlegacycode.com"&gt;How To Manage Legacy Code&lt;/a&gt;, by Nicolas Carlo&lt;/li&gt;&lt;li&gt;&lt;a href="https://www.koruux.com/blog/transforming-legacy-system/"&gt;How To Transform Legacy&lt;/a&gt;, by Bansi Mehta&lt;/li&gt;&lt;li&gt;&lt;a href="https://www.debt.design/"&gt;Design Debt 101&lt;/a&gt;, by Alicja Suska&lt;/li&gt;&lt;li&gt;&lt;a href="https://www.linkedin.com/posts/vitalyfriedman_ux-enterprise-activity-7128696386841120769-VcPD"&gt;Practical Guide To Enterprise UX&lt;/a&gt;, by Yours Truly&lt;/li&gt;&lt;li&gt;&lt;a href="https://www.linkedin.com/posts/vitalyfriedman_ux-design-healthcare-activity-7124347175395815424-Q8Xn"&gt;Healthcare UX Design Playbook&lt;/a&gt;, by Yours Truly&lt;/li&gt;&lt;/ul&gt;</description><link>http://honeyvig.blogspot.com/2026/04/how-to-improve-ux-in-legacy-systems.html</link><author>noreply@blogger.com (H)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9165069509664255576.post-6078493634285266707</guid><pubDate>Mon, 27 Apr 2026 06:44:00 +0000</pubDate><atom:updated>2026-04-26T23:44:42.395-07:00</atom:updated><title>Session Timeouts: The Overlooked Accessibility Barrier In Authentication Design</title><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="c-garfield-summary"&gt;&lt;section aria-label="Quick summary" class="article__summary"&gt;Poorly
 handled session timeouts are more than a technical inconvenience. They 
can become serious accessibility barriers that interrupt essential 
online tasks, especially for people with disabilities. Here is how to 
implement thoughtful session management that improves usability, reduces
 frustration, and helps create a more accessible and respectful web.&lt;/section&gt;&lt;/div&gt;&lt;p&gt;For
 web professionals, session management is a balancing act between user 
experience, cybersecurity, and resource usage. For people with 
disabilities, it is more than that — it is a barrier to buying digital 
tickets, scrolling on social media, or applying for a loan online. &lt;strong&gt;Session timeout accessibility&lt;/strong&gt; can be the difference between a bad day and a good day for those with disabilities.&lt;/p&gt;&lt;p&gt;For
 many, getting halfway through an important form only to be 
unceremoniously kicked back to the login screen is a common experience. 
Such incidents can lead to exasperation and even abandonment of the 
website entirely. With some backend work, web professionals can ensure 
no one has to experience this frustration.&lt;/p&gt;&lt;h2 id="why-session-timeouts-disproportionately-affect-users-with-disabilities"&gt;Why Session Timeouts Disproportionately Affect Users With Disabilities&lt;/h2&gt;&lt;p&gt;A considerable portion of the global population has cognitive, motor, or vision impairments. Worldwide, &lt;a href="https://designerly.com/mobile-app-accessibility-checklist/"&gt;around 1.3 billion people&lt;/a&gt;
 have significant disabilities. Whether they possess motor, cognitive, 
or visual impairments, their disabilities affect their ability to 
interact with technology easily. They can all be disproportionately 
affected by session timeouts, making session timeout accessibility a 
critical issue.&lt;/p&gt;&lt;p&gt;Session timeouts are inaccessible for a large percentage of the population. An &lt;a href="https://www.hanoversearch.com/blog/inclusive-recruitment-a-focus-on-neurodiverse-talent/"&gt;estimated 20% of people are&lt;/a&gt; neurodivergent, meaning timeout barriers don’t just affect a small subset of users — they impact a &lt;strong&gt;substantial portion of any website’s audience&lt;/strong&gt;. As a result, some users may look inactive when they are not. &lt;strong&gt;Strict timeouts create undue pressure.&lt;/strong&gt;&lt;/p&gt;&lt;h3 id="motor-impairments-and-slower-input-speeds"&gt;Motor Impairments and Slower Input Speeds&lt;/h3&gt;&lt;p&gt;For
 instance, someone with cerebral palsy tries to purchase tickets online 
for an upcoming concert. Due to coordination difficulties and muscle 
stiffness, they may enter their information more slowly than a 
non-disabled person would. They select the date, choose their seats, and
 fill out personal information. Before they can enter their credit card 
details, a timeout pop-up appears. They have been logged out due to 
“inactivity” and must restart the entire process.&lt;/p&gt;&lt;p&gt;This situation 
is not entirely hypothetical. Matthew Kayne is a disability rights 
advocate, broadcaster, and contributor to The European magazine. He 
describes the effort required to navigate websites as someone with 
cerebral palsy. He explains how the user interface &lt;a href="https://the-european.eu/story-53902/this-one-digital-glitch-is-pushing-disabled-people-to-breaking-point.html"&gt;is often poorly designed&lt;/a&gt;
 for adaptive devices, and he worries his equipment won’t respond 
correctly. After carefully navigating each page, he is suddenly logged 
out. In a moment, one timed form can erase hours of work, and it’s not 
just a matter of inconvenience. A single failed attempt can delay 
support or cause him to miss appointments.&lt;/p&gt;&lt;p&gt;Motor impairments can &lt;strong&gt;slow input speed&lt;/strong&gt;,
 making it appear the user is not at their computer. As such, people who
 experience stiffness, hand tremors, coordination challenges, 
involuntary movements, or muscle weakness are disproportionately 
affected by session timeouts. According to the DWP Accessibility Manual,
 it &lt;a href="https://accessibility-manual.dwp.gov.uk/tools-and-resources/basic-accessibility-checks/10-session-timeouts-impact-on-users"&gt;can take multiple attempts&lt;/a&gt;
 for adaptive technology to register input, slowing users down 
considerably. Even if they receive a warning, they may not be able to 
act fast enough to prove they are still active.&lt;/p&gt;&lt;h3 id="cognitive-impairments-and-processing-time"&gt;Cognitive Impairments and Processing Time&lt;/h3&gt;&lt;p&gt;Session
 timeouts can also create accessibility barriers for those with various 
types of cognitive differences. Strict timeouts can create undue 
pressure that assumes everyone processes information at the same speed. 
Users may appear inactive when they are actually reading, thinking, or 
processing.&lt;/p&gt;&lt;p&gt;Cognitive differences encompass a wide range of 
experiences, including neurodivergences like autism and ADHD, 
developmental disabilities like Down syndrome, and learning disabilities
 like dyslexia. Many people are born with cognitive differences. In 
fact, an &lt;a href="https://www.hanoversearch.com/blog/inclusive-recruitment-a-focus-on-neurodiverse-talent/"&gt;estimated 20% of people are&lt;/a&gt;
 neurodivergent, making up a large portion of any website’s audience. 
Others acquire cognitive disabilities later in life through traumatic 
brain injury or conditions like dementia.&lt;/p&gt;&lt;p&gt;People with cognitive 
disabilities often need more time to complete online tasks — not because
 of any deficit, but because they process information differently. 
Design choices that work well for neurotypical users can create 
unnecessary obstacles for people with ADHD, dyslexia, autism, or 
memory-related conditions.&lt;/p&gt;&lt;p&gt;Invisible session timeouts are 
particularly problematic for people who experience memory loss, language
 processing differences, or &lt;strong&gt;time blindness&lt;/strong&gt;. For example, neurodivergent technology leader Kate Carruthers says ADHD &lt;a href="https://katecarruthers.com/life-with-adhd-time-blindness-or-why-i-lose-hours-not-just-my-keys/"&gt;has affected her perception&lt;/a&gt; of time. She has time blindness and can’t reliably track how much time has passed, making estimates unhelpful.&lt;/p&gt;&lt;blockquote class="pull-quote"&gt;&lt;p&gt;&lt;a aria-label="Share on Twitter" class="pull-quote__link" href="https://twitter.com/share?text=%0aWhen%20websites%20depend%20on%20users%20estimating%20remaining%20time%20before%20a%20session%20expires,%20they%20quietly%20exclude%20people%20%e2%80%94%20not%20just%20those%20with%20formal%20ADHD%20diagnoses,%20but%20anyone%20who%20experiences%20time%20differently%20or%20processes%20information%20at%20a%20different%20pace.%0a&amp;amp;url=https://smashingmagazine.com%2f2026%2f04%2fsession-timeouts-accessibility-barrier-authentication-design%2f"&gt;When
 websites depend on users estimating remaining time before a session 
expires, they quietly exclude people — not just those with formal ADHD 
diagnoses, but anyone who experiences time differently or processes 
information at a different pace.&lt;/a&gt;&lt;/p&gt;&lt;div class="pull-quote__quotation"&gt;&lt;div class="pull-quote__bg"&gt;&lt;span class="pull-quote__symbol"&gt;“&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;h3 id="vision-impairments-and-screen-reader-navigation-overhead"&gt;Vision Impairments and Screen Reader Navigation Overhead&lt;/h3&gt;&lt;p&gt;Since
 blind or low-vision users cannot visually scan a page to find what they
 need, they must listen to links, headings, and form fields, which is 
inherently &lt;strong&gt;more time-consuming&lt;/strong&gt;. More than &lt;a href="https://int.livhospital.com/complete-top-5-reasons-for-vision-loss-worldwide/"&gt;43 million people worldwide&lt;/a&gt;
 are affected by blindness, while 295 million have moderate to severe 
vision impairment, which makes this a significant accessibility concern 
for any global-facing website.&lt;/p&gt;&lt;p&gt;As a result, these users’ sessions may expire even if they are active. &lt;strong&gt;Live timers and 30-second warnings do little to help&lt;/strong&gt;, as they are not built with screen readers in mind.&lt;/p&gt;&lt;p&gt;Bogdan
 Cerovac, a web developer passionate about digital accessibility, 
experienced this firsthand. The countdown timer informed him how long he
 had left before being logged out due to inactivity. By all accounts, it
 worked fine. However, he describes the &lt;a href="https://cerovac.com/a11y/2025/07/countdowns-and-timers-forgotten-detail-that-can-make-your-users-really-hate-your-product/"&gt;screen reader experience as horrible&lt;/a&gt;,
 as it notified him of the remaining time every single second. He 
couldn’t navigate the page because he was spammed by constant status 
messages.&lt;/p&gt;&lt;h2 id="common-timeout-patterns-that-fail-accessibility-requirements"&gt;Common Timeout Patterns That Fail Accessibility Requirements&lt;/h2&gt;&lt;p&gt;According to the National Institute of Standards and Technology, &lt;a href="https://pages.nist.gov/800-63-4/sp800-63b/session/"&gt;session management is preferable&lt;/a&gt;
 to continually preserving credentials, which would incentivize users to
 create authentication workarounds that could threaten security. 
However, several common timeout patterns fail to meet modern standards 
for session timeout accessibility.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/session-timeouts-accessibility-barrier-authentication-design/1-timeout-pattern-fail-accessibility.png"&gt;&lt;img alt="A session expired window with a “Back to main page” button." height="480" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/session-timeouts-accessibility-barrier-authentication-design/1-timeout-pattern-fail-accessibility.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Image source: &lt;a href="https://github.com/alfio-event/alf.io/issues/903"&gt;princekwame&lt;/a&gt;.&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="silent-timeouts-and-insufficient-warnings"&gt;Silent Timeouts and Insufficient Warnings&lt;/h3&gt;&lt;p&gt;Many
 websites either provide no warning before logging users out, or they 
display a brief, seconds-long pop-up that appears too late to be 
actionable. For users who navigate via screen reader, these warnings may
 not be announced in time. For those with motor impairments, a 30-second
 countdown may not provide enough time to respond.&lt;/p&gt;&lt;p&gt;Let’s consider 
the Consular Electronic Application Center’s DS-260 page, which is used 
to apply for or renew U.S. nonimmigrant visas. If an application &lt;a href="https://travel.state.gov/content/travel/en/us-visas/visa-information-resources/forms/online-immigrant-visa-forms/ds-260-faqs.html"&gt;is idle for around 20 minutes&lt;/a&gt;,
 it will log the user off without warning. The FAQ page only provides an
 approximate time estimate. Someone’s work only saves when they complete
 the page, so they may lose significant progress.&lt;/p&gt;&lt;h3 id="nonextendable-sessions"&gt;Nonextendable Sessions&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/04/session-timeouts-accessibility-barrier-authentication-design/#nonextendable-sessions"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;An
 abrupt “session expired” message is frustrating even for individuals 
without disabilities. If there is no option to continue, users are 
forced to log back in and restart their work, wasting time and energy.&lt;/p&gt;&lt;h3 id="form-data-loss-on-expiration"&gt;Form Data Loss on Expiration&amp;nbsp;&lt;/h3&gt;&lt;p&gt;Unless
 the website automatically saves progress, visitors will lose everything
 when the session expires. For someone with disabilities, this does not 
simply waste time. It can make their day immeasurably harder. Imagine 
spending an hour on a service request, job application, or purchase 
order only for all progress to be completely erased with little to no 
warning.&lt;/p&gt;&lt;h2 id="design-patterns-that-balance-security-and-accessibility"&gt;Design Patterns That Balance Security and Accessibility&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/04/session-timeouts-accessibility-barrier-authentication-design/#design-patterns-that-balance-security-and-accessibility"&gt;#&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Inconsistent
 timeout periods and a lack of warnings lead to the sudden, unexpected 
loss of all unsaved work. For long, complex forms, like the DS-260, a 
poor user experience is extremely frustrating. In comparison, the United
 Kingdom’s application for pension credit is highly accessible. It warns
 users &lt;a href="https://design-system.dwp.gov.uk/patterns/manage-a-session-timeout"&gt;at least two minutes&lt;/a&gt;
 in advance and allows them to extend the session. It meets level AA of 
the WCAG 2.2 success criteria, indicating its accessibility.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/session-timeouts-accessibility-barrier-authentication-design/2-timeout-pattern-accessibility.png"&gt;&lt;img alt="A tab session expired window with a refresh button." height="450" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/session-timeouts-accessibility-barrier-authentication-design/2-timeout-pattern-accessibility.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Image source: &lt;a href="https://experienceleaguecommunities.adobe.com/adobe-workfront-23/pop-up-message-saying-session-has-expired-129862"&gt;Experience League&lt;/a&gt;.&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;People
 with disabilities are disproportionately affected by the unintended 
consequences of poor session management. Thankfully, session timeouts’ 
inaccessibility is not a matter of fact. With a few small changes, web 
professionals can significantly improve their website’s accessibility.&lt;/p&gt;&lt;h3 id="advance-warning-systems-and-extend-functionality"&gt;Advance Warning Systems and Extend Functionality&lt;/h3&gt;&lt;p&gt;Websites
 should clearly state the time limit’s existence and duration before the
 session starts. For instance, if someone is filling out a bank form, 
the first page should exist solely to inform them that it has a 
60-minute time limit. A live counter that updates regularly can help 
them track how much time remains. Also, users should be told whether 
they can adjust the session timeout length.&lt;/p&gt;&lt;h3 id="activity-based-vs-absolute-timeouts"&gt;Activity-Based vs. Absolute Timeouts&lt;/h3&gt;&lt;p&gt;An
 activity-based timeout logs users out due to inactivity, while an 
absolute timeout logs them out regardless of activity. For an office, a 
24-hour absolute timer might make sense, since workers only need to log 
in when they get to work. As long as users know when their session will 
expire, the latter is more accessible than the former.&lt;/p&gt;&lt;h3 id="auto-save-and-progress-preservation"&gt;Auto-Save and Progress Preservation&lt;/h3&gt;&lt;p&gt;Cookies,
 localStorage, and sessionStorage are temporary, client-side storage 
mechanisms that allow web applications to store data for the duration of
 a single browser session. They are powerful, lightweight tools. Web 
developers can use them to automatically save users’ progress at 
frequent intervals, ensuring data is restored upon reauthentication.&lt;/p&gt;&lt;p&gt;This
 way, even if someone’s session expires by accident, they are not 
penalized. Once they log back in, they can finish filling out their 
credit card details or pick up where they left off with an online form.&lt;/p&gt;&lt;h2 id="testing-and-wcag-compliance-considerations"&gt;Testing and WCAG Compliance Considerations&lt;/h2&gt;&lt;p&gt;The
 Web Content Accessibility Guidelines (WCAG) is a collection of 
internationally accepted internet accessibility standards published by 
the W3C. It acts as the arbiter of session timeout accessibility. Web 
developers should pay special attention to &lt;strong&gt;Guideline 2.9.2&lt;/strong&gt;, &lt;a href="https://www.w3.org/TR/wcag-3.0/#adequate-time"&gt;which outlines best practices for adequate&lt;/a&gt; time.&lt;/p&gt;&lt;p&gt;The &lt;strong&gt;timeout adjustable mechanism&lt;/strong&gt;
 should extend the time limit before the session expires or allow it to 
be turned off completely. For the former option, a dialog box should 
appear asking users if they need more time, allowing them to continue 
with one click. The WC3 notes that exceptions exist.&lt;/p&gt;&lt;p&gt;For example, 
when a website conducts a live ticket sale, users can only hold tickets 
in their carts for 10 minutes to give others a chance to purchase 
limited inventory. Alternatively, session timeouts may be necessary on 
shared computers. If librarians allowed everyone to stay logged in 
instead of automatically signing them out overnight, they would risk 
security issues.&lt;/p&gt;&lt;p&gt;Some processes should not have time limits at 
all. When browsing social media, reading a news article, or searching 
for items on an e-commerce site, there is no reason a session should 
expire within an arbitrary time frame. Meanwhile, in a timed exam, it 
may be necessary. However, in this case, administrators can extend time 
limits for students with disabilities.&lt;/p&gt;&lt;p&gt;When web developers make session management accessible, they are not catering to a small group. Pew Research Center data shows &lt;a href="https://www.pewresearch.org/short-reads/2021/09/10/americans-with-disabilities-less-likely-than-those-without-to-own-some-digital-devices/"&gt;62% of adults with disabilities&lt;/a&gt;
 own a computer. 72% have high-speed home internet. These figures do not
 differ statistically from the percentage of non-disabled adults who say
 the same.&lt;/p&gt;&lt;h2 id="overcoming-the-session-timeout-accessibility-barrier"&gt;Overcoming the Session Timeout Accessibility Barrier&lt;/h2&gt;&lt;p&gt;The WCAG provides additional resources that web developers can review to understand session management accessibility better:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://www.w3.org/TR/UNDERSTANDING-WCAG20/time-limits-required-behaviors.html"&gt;WCAG SC 2.2.1 Timing Adjustable&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://www.w3.org/TR/UNDERSTANDING-WCAG20/time-limits-server-timeout.html"&gt;WCAG SC 2.2.5 Re-authenticating&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://www.w3.org/WAI/WCAG22/Understanding/timeouts.html"&gt;WCAG SC 2.2.6 Timeouts&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;In
 addition to following these guidelines, there is a wealth of 
information from leading educational institutions, authorities on open 
web technologies, and government agencies. They provide a great starting
 place for those with intermediate web development knowledge.&lt;/p&gt;&lt;p&gt;Web 
professionals should consider the following resources to learn more 
about tools and techniques they can use to make session management more 
accessible:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://accessibility.huit.harvard.edu/technique-session-extension"&gt;Harvard University’s Session Extension Technique&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://accessibility-manual.dwp.gov.uk/tools-and-resources/basic-accessibility-checks/10-session-timeouts-how-to-test"&gt;DWP Accessibility Manual: How to test session timeouts&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage"&gt;Window: sessionStorage property&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;blockquote class="pull-quote"&gt;&lt;p&gt;&lt;a aria-label="Share on Twitter" class="pull-quote__link" href="https://twitter.com/share?text=%0aSession%20timeout%20accessibility%20is%20not%20only%20an%20industry%20best%20practice%20but%20an%20ethical%20web%20development%20standard.%0a&amp;amp;url=https://smashingmagazine.com%2f2026%2f04%2fsession-timeouts-accessibility-barrier-authentication-design%2f"&gt;Session timeout accessibility is not only an industry best practice but an ethical web development standard.&lt;/a&gt;&lt;/p&gt;&lt;div class="pull-quote__quotation"&gt;&lt;div class="pull-quote__bg"&gt;&lt;span class="pull-quote__symbol"&gt;“&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;p&gt;Those who prioritize it will appeal to a wider audience, &lt;strong&gt;improve usability&lt;/strong&gt;, and attract more website visitors and longer sessions.&lt;/p&gt;&lt;p&gt;The
 main takeaway is that a website with inaccessible session timeouts 
sends a clear message that it doesn’t value the user’s time or effort, a
 problem that creates significant barriers for people with disabilities.
 However, this is a solvable issue. With a few simple changes, such as 
providing session extension warnings and auto-saving progress, web 
developers can build a more considerate, accessible, and respectful 
internet for everyone.&lt;/p&gt;</description><link>http://honeyvig.blogspot.com/2026/04/session-timeouts-overlooked.html</link><author>noreply@blogger.com (H)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9165069509664255576.post-5801852115429374999</guid><pubDate>Sat, 25 Apr 2026 06:10:00 +0000</pubDate><atom:updated>2026-04-24T23:14:25.511-07:00</atom:updated><title>The UX Designer’s Nightmare: When “Production-Ready” Becomes A Design Deliverable</title><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="c-garfield-summary"&gt;&lt;section aria-label="Quick summary" class="article__summary"&gt;In
 a rush to embrace AI, the industry is redefining what it means to be a 
UX designer, blurring the line between design and engineering. Carrie 
Webster explores what’s gained, what’s lost, and why designers need to 
remain the guardians of the user experience.&lt;/section&gt;&lt;/div&gt;&lt;p&gt;In early 2026, I noticed that the UX designer’s toolkit seemed to shift overnight. The industry standard &lt;i&gt;“Should designers code?”&lt;/i&gt;
 debate was abruptly settled by the market, not through a consensus of 
our craft, but through the brute force of job requirements. If you 
browse LinkedIn today, you’ll notice a stark change: UX roles 
increasingly demand &lt;b&gt;&lt;a href="https://www.refontelearning.com/blog/ui-ux-designer-engineering-in-2026-crafting-future-ready-user-experiences"&gt;AI-augmented development&lt;/a&gt;&lt;/b&gt;, &lt;b&gt;technical orchestration,&lt;/b&gt; and &lt;b&gt;production-ready prototyping.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;For
 many, including myself, this is the ultimate design job nightmare. We 
are being asked to deliver both the “vibe” and the “code” 
simultaneously, using AI agents to bridge a technical gap that 
previously took years of computer science knowledge and coding 
experience to cross. But as the industry rushes to meet these new 
expectations, they are discovering that AI-generated functional code is 
not always &lt;i&gt;good&lt;/i&gt; code.&lt;/p&gt;&lt;h2 id="the-linkedin-pressure-cooker-role-creep-in-2026"&gt;The LinkedIn Pressure Cooker: Role Creep In 2026&lt;/h2&gt;&lt;p&gt;The job market is sending a clear signal. While traditional graphic design roles are expected to grow by only &lt;b&gt;3%&lt;/b&gt; through 2034, UX, UI, and &lt;a href="https://www.nobledesktop.com/careers/designer/job-outlook#:~:text=The%20projected%20future%20growth%20figures%20for%20Digital,job%20growth%20(which%20lies%20somewhere%20around%205%25)."&gt;Product Design roles&lt;/a&gt; are projected to grow by &lt;b&gt;16%&lt;/b&gt; over the same period.&lt;/p&gt;&lt;p&gt;However, this growth is increasingly tied to the rise of &lt;b&gt;AI product development&lt;/b&gt;,
 where “design skills” have recently become the #1 most in-demand 
capability, even ahead of coding and cloud infrastructure. Companies 
building these platforms are no longer just looking for visual 
designers; they need professionals who can “&lt;a href="https://humbldesign.io/blog-posts/will-ai-replace-designers-2026"&gt;translate technical capability into human-centered experiences&lt;/a&gt;.”&lt;/p&gt;&lt;p&gt;This
 creates a high-stakes environment for the UX designer. We are no longer
 just responsible for the interface; we are expected to understand the 
technical logic well enough to ensure that complex AI capabilities feel 
intuitive, safe, and useful for the human on the other side of the 
screen. Designers are being pushed toward a &lt;b&gt;“design engineer” model&lt;/b&gt;, where we must bridge the gap between abstract &lt;a href="https://www.refontelearning.com/blog/ui-ux-designer-engineering-in-2026-crafting-future-ready-user-experiences#skills-and-competencies-for-the-2026-uiux-designer-3"&gt;AI logic and user-facing code&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;A &lt;a href="https://www.lyssna.com/blog/ux-design-trends/"&gt;recent survey&lt;/a&gt; found that &lt;b&gt;73% of designers&lt;/b&gt;
 now view AI as a primary collaborator rather than just a tool. However,
 this “collaboration” often looks like “role creep.” Recruiters are 
often not just looking for someone who understands user empathy and 
information architecture — they want someone who can also prompt a React
 component into existence and push it to a repository!&lt;/p&gt;&lt;p&gt;This shift has created a &lt;b&gt;competency gap&lt;/b&gt;.&lt;/p&gt;&lt;blockquote&gt;As
 an experienced senior designer who has spent decades mastering the 
nuances of cognitive load, accessibility standards, and ethnographic 
research, I am suddenly finding myself being judged on my ability to 
debug a CSS Flexbox issue or manage a Git branch.&lt;/blockquote&gt;&lt;p&gt;The nightmare isn’t the technology itself. It’s the &lt;b&gt;reallocation of value&lt;/b&gt;.&lt;/p&gt;&lt;blockquote class="pull-quote"&gt;&lt;p&gt;&lt;a aria-label="Share on Twitter" class="pull-quote__link" href="https://twitter.com/share?text=%0aBusinesses%20are%20beginning%20to%20value%20the%20speed%20of%20output%20over%20the%20quality%20of%20the%20experience,%20fundamentally%20changing%20what%20it%20means%20to%20be%20a%20%e2%80%9csuccessful%e2%80%9d%20designer%20in%202026.%0a&amp;amp;url=https://smashingmagazine.com%2f2026%2f04%2fproduction-ready-becomes-design-deliverable-ux%2f"&gt;Businesses
 are beginning to value the speed of output over the quality of the 
experience, fundamentally changing what it means to be a “successful” 
designer in 2026.&lt;/a&gt;&lt;/p&gt;&lt;div class="pull-quote__quotation"&gt;&lt;div class="pull-quote__bg"&gt;&lt;span class="pull-quote__symbol"&gt;“&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/ux-designer-nightmare-production-ready-becomes-design-deliverable/1-figma.jpg"&gt;&lt;img alt="Figma to AI code ad" height="450" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/ux-designer-nightmare-production-ready-becomes-design-deliverable/1-figma.jpg" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Tools that allow designers to switch from design to code. (Image source: &lt;a href="https://www.figma.com/community/plugin/1443774571835235184/figma-to-ai-code-by-designcode"&gt;Figma&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="the-competence-trap-two-job-skill-sets-one-average-result"&gt;The Competence Trap: Two Job Skill Sets, One Average Result&lt;/h3&gt;&lt;p&gt;There
 is potentially a very dangerous myth circulating in boardrooms that AI 
makes a designer “equal” to an engineer. This narrative suggests that 
because an LLM can generate a functional JavaScript event handler, the 
person prompting it doesn’t need to understand the underlying logic. In 
reality, attempting to master two disparate, deep fields simultaneously 
will most likely lead to being &lt;b&gt;averagely competent&lt;/b&gt; at both.&lt;/p&gt;&lt;h3 id="the-averagely-competent-dilemma"&gt;The “Averagely Competent” Dilemma&lt;/h3&gt;&lt;p&gt;For
 a senior UX designer to become a senior-level coder is like asking a 
master chef to also be a master plumber because “they both work in the 
kitchen.” You might get the water running, but you won’t know why the 
pipes are rattling.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;The “cognitive offloading” risk.&lt;/b&gt;&lt;br /&gt;Research
 shows that while AI can speed up task completion, it often leads to a 
significant decrease in conceptual mastery. In a controlled study, 
participants using AI assistance scored &lt;a href="https://www.psychologytoday.com/au/blog/the-asymmetric-brain/202602/cognitive-offloading-using-ai-reduces-new-skill-formation"&gt;17% lower&lt;/a&gt; on comprehension tests than those who coded by hand.&lt;/li&gt;&lt;li&gt;&lt;b&gt;The debugging gap.&lt;/b&gt;&lt;br /&gt;The largest performance gap between AI-reliant users and hand-coders is in &lt;a href="https://www.anthropic.com/research/AI-assistance-coding-skills"&gt;debugging&lt;/a&gt;. When a designer uses AI to write code they don’t fully understand, they don’t have the ability to identify &lt;i&gt;when&lt;/i&gt; and &lt;i&gt;why&lt;/i&gt; it fails.&lt;/li&gt;&lt;/ul&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/ux-designer-nightmare-production-ready-becomes-design-deliverable/2-ai-assistance-coding-skills-speed.png"&gt;&lt;img alt="A chart showing how AI assistance impacts coding speed and skill formation" height="451" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/ux-designer-nightmare-production-ready-becomes-design-deliverable/2-ai-assistance-coding-skills-speed.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Using AI tools impedes coding skill formation. (Image source: &lt;a href="https://www.anthropic.com/research/AI-assistance-coding-skills"&gt;Anthropic&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;So,
 if a designer ships an AI-generated component that breaks during a 
high-traffic event and cannot manually trace the logic, they are no 
longer an expert. They are now a liability.&lt;/p&gt;&lt;h3 id="the-high-cost-of-unoptimised-code"&gt;The High Cost Of Unoptimised Code&lt;/h3&gt;&lt;p&gt;Any
 experienced code engineer will tell you that creating code with AI 
without the right prompt leads to a lot of rework. Because most 
designers lack the technical foundation to audit the code the AI gives 
them, they are inadvertently shipping massive amounts of &lt;a href="https://gocrossbridge.com/blog/ai-generated-code/"&gt;“Quality Debt”&lt;/a&gt;.&lt;/p&gt;&lt;h2 id="common-issues-in-designer-generated-ai-code"&gt;Common Issues In Designer-Generated AI Code&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;The security flaw&lt;/b&gt;&lt;br /&gt;Recent reports indicate that up to &lt;a href="https://www.sherlockforensics.com/pages/ai-code-security-report-2026.html"&gt;92% of AI-generated codebases&lt;/a&gt;
 contain at least one critical vulnerability. A designer might see a 
functioning login form, unaware that it has an 86% failure rate in XSS 
defense, which are the security measures aimed at preventing attackers 
from injecting malicious scripts into trusted websites.&lt;/li&gt;&lt;li&gt;&lt;b&gt;The accessibility illusion&lt;/b&gt;&lt;br /&gt;AI
 often generates “functional” applications that lack semantic integrity.
 A designer might prompt a “beautiful and functional toggle switch,” but
 the AI may provide a non-semantic &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; that lacks keyboard focus and screen-reader compatibility, creating &lt;a href="https://www.levelaccess.com/blog/accessibility-debt-in-software-development-and-how-to-engineer-it-out/"&gt;Accessibility Debt&lt;/a&gt; that is expensive to fix later.&lt;/li&gt;&lt;li&gt;&lt;b&gt;The performance penalty&lt;/b&gt;&lt;br /&gt;AI-generated code tends to be verbose. AI is linked to &lt;a href="https://www.netcorpsoftwaredevelopment.com/blog/ai-generated-code-statistics"&gt;4x more code duplication&lt;/a&gt;
 than human-written code. This verbosity slows down page loads, creates 
massive CSS files, and negatively impacts SEO. To a business, the task 
looks “done.” To a user with a slow connection or a screen reader, the 
site is a nightmare.&lt;/li&gt;&lt;/ul&gt;&lt;h2 id="creating-more-work-not-less"&gt;Creating More Work, Not Less&lt;/h2&gt;&lt;p&gt;The promise of AI was that designers could ship features without bothering the engineers. The reality has been the birth of a &lt;b&gt;“Rework Tax”&lt;/b&gt; that is draining engineering resources across the industry.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Cleaning up&lt;/b&gt;&lt;br /&gt;Organisations are finding that while velocity increases, incidents per Pull Request are also rising by &lt;a href="https://blog.exceeds.ai/ai-code-analysis-benchmark-reports/"&gt;23.5%&lt;/a&gt;.
 Some engineering teams now spend a significant portion of their week 
cleaning up “AI slop” delivered by design teams who skipped a rigorous 
review process.&lt;/li&gt;&lt;li&gt;&lt;b&gt;The communication gap&lt;/b&gt;&lt;br /&gt;Only &lt;a href="https://www.lyssna.com/blog/ux-design-trends/"&gt;69% of designers&lt;/a&gt; feel AI improves the quality of their work, compared to &lt;b&gt;82% of developers&lt;/b&gt;. This gap exists because “code that compiles” is not the same as “code that is maintainable.”&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;When
 a designer hands off AI-generated code that ignores a company’s 
internal naming conventions or management patterns, they aren’t helping 
the engineer; they are creating a puzzle that someone else has to solve 
later.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/ux-designer-nightmare-production-ready-becomes-design-deliverable/3-issues-developers-face-ai-generated-code.jpg"&gt;&lt;img alt="Typical issues that developers face with AI-generated code" height="600" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/ux-designer-nightmare-production-ready-becomes-design-deliverable/3-issues-developers-face-ai-generated-code.jpg" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Typical issues that developers face with AI-generated code. (Image source: &lt;a href="https://www.netcorpsoftwaredevelopment.com/blog/ai-generated-code-statistics"&gt;Netcorp&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="the-solution"&gt;The Solution&lt;/h3&gt;&lt;p&gt;We need to move away from the nightmare of the “&lt;b&gt;Solo Full-Stack Designer&lt;/b&gt;” and toward a model of &lt;b&gt;designer/coder collaboration&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;&lt;b&gt;The ideal reality:&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;The Partnership&lt;/b&gt;&lt;br /&gt;Instead of designers trying to be mediocre coders, they should work in a &lt;b&gt;human-AI-human loop&lt;/b&gt;. A senior UX designer should work &lt;i&gt;with&lt;/i&gt; an engineer to use AI; the designer creates prompts for &lt;b&gt;intent, accessibility, and user flow&lt;/b&gt;, while the engineer creates prompts for &lt;b&gt;architecture and performance&lt;/b&gt;.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Design systems as guardrails&lt;/b&gt;&lt;br /&gt;To prevent accessibility debt from spreading at scale, &lt;a href="https://webaim.org/projects/million/"&gt;accessible components must be the default&lt;/a&gt;
 in your design system. AI should be used to feed these tokens into your
 UI, ensuring that even generated code stays within the “source of 
truth.”&lt;/li&gt;&lt;/ul&gt;&lt;h2 id="beyond-the-prompt"&gt;Beyond The Prompt&lt;/h2&gt;&lt;div aria-hidden="true" class="c-friskies-box partners partners__lead partners__lead-place partners__external" data-amount="1" data-audience="non-subscriber" data-remove="true" data-rendered="true"&gt;&lt;ul&gt;&lt;a class="partners__native--smashing" href="https://www.smashingmagazine.com/contact/"&gt;
        &lt;picture&gt;
          &lt;source media="(max-width: 600px)"&gt;&lt;/source&gt;
          &lt;img alt="Advertise with Smashing Magazine" width="325" /&gt;
        &lt;/picture&gt;
      &lt;/a&gt;&lt;/ul&gt;&lt;/div&gt;&lt;p&gt;The industry is currently in a state of “AI Infatuation,” but the pendulum will eventually swing back toward quality.&lt;/p&gt;&lt;blockquote class="pull-quote"&gt;&lt;p&gt;&lt;a aria-label="Share on Twitter" class="pull-quote__link" href="https://twitter.com/share?text=%0aThe%20UX%20designer%e2%80%99s%20nightmare%20ends%20when%20we%20stop%20trying%20to%20compete%20with%20AI%20tools%20at%20what%20they%20do%20best%20%28generating%20syntax%29%20and%20keep%20our%20focus%20on%20what%20they%20cannot%20do%20%28understanding%20human%20complexity%29.%0a&amp;amp;url=https://smashingmagazine.com%2f2026%2f04%2fproduction-ready-becomes-design-deliverable-ux%2f"&gt;The
 UX designer’s nightmare ends when we stop trying to compete with AI 
tools at what they do best (generating syntax) and keep our focus on 
what they cannot do (understanding human complexity).&lt;/a&gt;&lt;/p&gt;&lt;div class="pull-quote__quotation"&gt;&lt;div class="pull-quote__bg"&gt;&lt;span class="pull-quote__symbol"&gt;“&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;p&gt;Businesses
 that prioritise “designer-shipped code” without engineering oversight 
will eventually face a reckoning of technical debt, security breaches, 
and accessibility lawsuits. The designers who thrive in 2026 and beyond 
will be those who refuse to be “prompt operators” and instead position 
themselves as the &lt;b&gt;guardians of the user experience&lt;/b&gt;. This is the perfect outcome for experienced designers and for the industry.&lt;/p&gt;&lt;p&gt;Our
 value has always been our ability to advocate for the human on the 
other side of the screen. We must use AI to augment our design thinking,
 allowing us to test more ideas and iterate faster, but we must never 
let it replace the specialised engineering expertise that ensures our 
designs technically &lt;i&gt;work&lt;/i&gt; for everyone.&lt;/p&gt;&lt;h3 id="summary-checklist-for-ux-designers"&gt;Summary Checklist for UX Designers&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Work Together.&lt;/b&gt;&lt;br /&gt;Use
 AI-made code as a starting point to talk with your developers. Don’t 
use it as a shortcut to avoid working with them. Ask them to help you 
with prompts for code creation for the best outcomes.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Understand the “Why”.&lt;/b&gt;&lt;br /&gt;Never submit code you don’t understand. If you can’t explain how the AI-generated logic works, don’t include it in your work.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Build for Everyone.&lt;/b&gt;&lt;br /&gt;Good
 design is more than just looks. Use AI to check if your code works for 
people using screen readers or keyboards, not just to make things look 
pretty.&lt;/li&gt;&lt;/ul&gt;</description><link>http://honeyvig.blogspot.com/2026/04/the-ux-designers-nightmare-when.html</link><author>noreply@blogger.com (H)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9165069509664255576.post-2450539452636518949</guid><pubDate>Mon, 13 Apr 2026 12:48:00 +0000</pubDate><atom:updated>2026-04-13T05:48:33.349-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Career</category><category domain="http://www.blogger.com/atom/ns#">mission</category><category domain="http://www.blogger.com/atom/ns#">UI</category><category domain="http://www.blogger.com/atom/ns#">UX</category><category domain="http://www.blogger.com/atom/ns#">vision</category><title> What Will Engineers Actually Do in 2030? </title><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 class="ember-view reader-text-block__heading-2" id="ember61"&gt;
      &#128293; Big Story of the Week
    &lt;/h2&gt;

  






            
        
    &lt;h3 class="ember-view reader-text-block__heading-3" id="ember62"&gt;
      &#129489;&#128187; The Engineer of 2030: Builder, Reviewer, or AI Trainer?
    &lt;/h3&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember63"&gt;
      If you look at how you work today… and compare it to even a year ago, something feels different.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember64"&gt;
      You’re still coding. But not in the same way.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember65"&gt;
      Sometimes, it feels like:
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember66"&gt;
            &lt;/p&gt;&lt;ul&gt;&lt;li&gt;You’re reviewing more than writing&lt;/li&gt;&lt;li&gt;Thinking more than typing&lt;/li&gt;&lt;li&gt;Guiding more than building&lt;/li&gt;&lt;/ul&gt;

    &lt;p&gt;&lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember67"&gt;
      And that raises an uncomfortable but important question:
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember68"&gt;
      &#128073;&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;em&gt;What does it actually mean to be an engineer in the future?&lt;/em&gt;
    &lt;/p&gt;

  










            
  &lt;hr class="reader-divider-block__horizontal-rule" /&gt;



            
        
    &lt;h3 class="ember-view reader-text-block__heading-3" id="ember69"&gt;
      &#129504; The Shift Has Already Started
    &lt;/h3&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember70"&gt;
      Let’s be real.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember71"&gt;
      AI can now:
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember72"&gt;
            &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Generate full functions in seconds&lt;/li&gt;&lt;li&gt;Suggest optimizations&lt;/li&gt;&lt;li&gt;Write tests you might skip&lt;/li&gt;&lt;li&gt;Even explain your own code back to you&lt;/li&gt;&lt;/ul&gt;

    &lt;p&gt;&lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember73"&gt;
      So naturally, your role starts to shift.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember74"&gt;
      Not overnight. But quietly, consistently.
    &lt;/p&gt;

  










            
  &lt;hr class="reader-divider-block__horizontal-rule" /&gt;



            
        
    &lt;h3 class="ember-view reader-text-block__heading-3" id="ember75"&gt;
      ⚙️ So… What Are We Becoming?
    &lt;/h3&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember76"&gt;
      The future engineer isn’t just one thing anymore.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember77"&gt;
      It’s a mix of roles.
    &lt;/p&gt;

  










            
  &lt;hr class="reader-divider-block__horizontal-rule" /&gt;



            
        
    &lt;h3 class="ember-view reader-text-block__heading-3" id="ember78"&gt;
      &#128313; 1. The Builder (Still Important)
    &lt;/h3&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember79"&gt;
      Yes — coding isn’t going away.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember80"&gt;
      You still need to:
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember81"&gt;
            &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Understand systems&lt;/li&gt;&lt;li&gt;Write critical logic&lt;/li&gt;&lt;li&gt;Handle edge cases&lt;/li&gt;&lt;/ul&gt;

    &lt;p&gt;&lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember82"&gt;
      Because AI is fast… but it doesn’t&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;em&gt;understand context like you do.&lt;/em&gt;
    &lt;/p&gt;

  










            
  &lt;hr class="reader-divider-block__horizontal-rule" /&gt;



            
        
    &lt;h3 class="ember-view reader-text-block__heading-3" id="ember83"&gt;
      &#128313; 2. The Reviewer (More Important Than Ever)
    &lt;/h3&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember84"&gt;
      AI can generate code.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember85"&gt;
      But can it guarantee:
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember86"&gt;
            &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Business correctness? ❌&lt;/li&gt;&lt;li&gt;Edge case handling? ❌&lt;/li&gt;&lt;li&gt;Long-term maintainability? ❌&lt;/li&gt;&lt;/ul&gt;

    &lt;p&gt;&lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember87"&gt;
      That’s where you come in.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember88"&gt;
      You’re no longer just writing code — &#128073; you’re&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;strong&gt;validating intelligence&lt;/strong&gt;.
    &lt;/p&gt;

  










            
  &lt;hr class="reader-divider-block__horizontal-rule" /&gt;



            
        
    &lt;h3 class="ember-view reader-text-block__heading-3" id="ember89"&gt;
      &#128313; 3. The AI Trainer (The New Role)
    &lt;/h3&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember90"&gt;
      This is where things get interesting.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember91"&gt;
      You’re now:
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember92"&gt;
            &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Writing better prompts&lt;/li&gt;&lt;li&gt;Refining outputs&lt;/li&gt;&lt;li&gt;Teaching AI what “good” looks like&lt;/li&gt;&lt;/ul&gt;

    &lt;p&gt;&lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember93"&gt;
      In a way… &#128073; you’re training a junior developer that learns instantly.
    &lt;/p&gt;

  










            
  &lt;hr class="reader-divider-block__horizontal-rule" /&gt;



            
        
    &lt;h3 class="ember-view reader-text-block__heading-3" id="ember94"&gt;
      ⚠️ The Risk Nobody Talks About
    &lt;/h3&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember95"&gt;
      There’s a hidden danger in all this.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember96"&gt;
      If we rely too much on AI:
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember97"&gt;
            &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Our fundamentals may weaken&lt;/li&gt;&lt;li&gt;Our debugging instincts may slow down&lt;/li&gt;&lt;li&gt;Our deep understanding may fade&lt;/li&gt;&lt;/ul&gt;

    &lt;p&gt;&lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember98"&gt;
      And that’s risky.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember99"&gt;
      Because when AI fails — &#128073;&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;em&gt;you’re still the final line of defense.&lt;/em&gt;
    &lt;/p&gt;

  










            
  &lt;hr class="reader-divider-block__horizontal-rule" /&gt;



            
        
    &lt;h3 class="ember-view reader-text-block__heading-3" id="ember100"&gt;
      &#127757; The Bigger Reality
    &lt;/h3&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember101"&gt;
      The barrier to building software is dropping fast.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember102"&gt;
      Which means:
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember103"&gt;
            &lt;/p&gt;&lt;ul&gt;&lt;li&gt;More builders are entering the space&lt;/li&gt;&lt;li&gt;More products are being created&lt;/li&gt;&lt;li&gt;More competition is coming&lt;/li&gt;&lt;/ul&gt;

    &lt;p&gt;&lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember104"&gt;
      So the real differentiator won’t be: ❌ Who can code ✅ But who can&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;strong&gt;think, design, and adapt&lt;/strong&gt;
    &lt;/p&gt;

  










            
  &lt;hr class="reader-divider-block__horizontal-rule" /&gt;



            
        
    &lt;h3 class="ember-view reader-text-block__heading-3" id="ember105"&gt;
      &#128302; What the Best Engineers Will Do
    &lt;/h3&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember106"&gt;
      The engineers who thrive won’t fight AI.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember107"&gt;
      They’ll:
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember108"&gt;
            &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Use it to move faster&lt;/li&gt;&lt;li&gt;Focus on deeper problems&lt;/li&gt;&lt;li&gt;Build better systems, not just more code&lt;/li&gt;&lt;/ul&gt;

    &lt;p&gt;&lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember109"&gt;
      Because the game is changing from: &#128073;&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;em&gt;“Write more code”&lt;/em&gt;&lt;span class="white-space-pre"&gt; &lt;/span&gt;to &#128073;&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;em&gt;“Create more impact”&lt;/em&gt;
    &lt;/p&gt;

  










            
  &lt;hr class="reader-divider-block__horizontal-rule" /&gt;



            
        
    &lt;h3 class="ember-view reader-text-block__heading-3" id="ember110"&gt;
      &#128161; Engineer’s Takeaway
    &lt;/h3&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember111"&gt;
      The future engineer is not just a builder.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember112"&gt;
      They are: &#129504; A thinker &#128269; A reviewer &#129302; A guide to AI
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember113"&gt;
      And maybe that’s the real evolution.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember114"&gt;
      Because in the end, &#128073;&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;strong&gt;tools will change — but great thinking never goes out of style.&lt;/strong&gt;
    &lt;/p&gt;

  










            
  &lt;hr class="reader-divider-block__horizontal-rule" /&gt;



            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember115"&gt;
      ✍️&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;em&gt;EngiSphere Insight:&lt;/em&gt;&lt;span class="white-space-pre"&gt; &lt;/span&gt;“The engineers who win in the AI era won’t be the fastest coders — they’ll be the smartest decision-makers.”
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember116"&gt;
      #SoftwareEngineering #AI #FutureOfWork #Developers #TechTrends #EngiSphere
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember117"&gt;
      #ArtificialIntelligence #Programming #CareerGrowth #TechLeadership #Innovation
    &lt;/p&gt;</description><link>http://honeyvig.blogspot.com/2026/04/what-will-engineers-actually-do-in-2030.html</link><author>noreply@blogger.com (H)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9165069509664255576.post-8223300613439298879</guid><pubDate>Mon, 06 Apr 2026 13:55:00 +0000</pubDate><atom:updated>2026-04-06T06:55:37.874-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Accessibility</category><category domain="http://www.blogger.com/atom/ns#">Figma</category><category domain="http://www.blogger.com/atom/ns#">Tools</category><title>Testing Font Scaling For Accessibility With Figma Variables</title><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="c-garfield-summary"&gt;&lt;section aria-label="Quick summary" class="article__summary"&gt;Accessibility
 works best when it blends into everyday design workflows. The goal 
isn’t a big transformation, but simple work processes that fit naturally
 into a team’s routine. With Figma variables, testing font size 
increases becomes part of the design flow itself, making accessibility 
feel almost inevitable rather than optional.&lt;/section&gt;&lt;/div&gt;&lt;p&gt;Building a
 true culture of digital accessibility in a company is a mission of 
resilience and perseverance. It’s not difficult for the discourse on 
accessibility to fall into the usual clichés. Accessibility is very 
important for people. The accessibility of digital products and services
 promotes inclusion. Or even, all professionals on the teams should be 
involved in accessibility work. Of course. No one in their right mind 
will dispute any of these statements (I hope).&lt;/p&gt;&lt;p&gt;However, the second part of this conversation, which very few companies reach, is &lt;em&gt;“how?”&lt;/em&gt;
 How do we make this happen in the midst of the day-to-day work of 
digital transformation teams, which, as we all know, are immersed in 
demanding scripts, often with a very limited number of people available?
 Most of the time, the choice ends up being between &lt;em&gt;“we do this”&lt;/em&gt; and &lt;em&gt;“that.”&lt;/em&gt; And it shouldn’t, because, in these cases, I never saw accessibility winning in this equation.&lt;/p&gt;&lt;p&gt;It
 shouldn’t be this way. You don’t need to be this way. First of all, 
because choosing between accessibility and anything else isn’t the right
 choice. Accessibility is no longer just another feature to be added to 
the others. It’s an added value for the business and, currently, a legal
 obligation that can have serious consequences for companies. On the 
other hand, there are intelligent, optimized, and impactful ways to 
incorporate accessibility principles into the natural dynamics of teams.
 It’s possible to work on accessibility without turning team operations 
upside down. In essence, that’s what AccessibilityOps does. &lt;strong&gt;Empowering people&lt;/strong&gt; and &lt;strong&gt;providing teams with simple processes&lt;/strong&gt; so they can &lt;strong&gt;integrate accessibility work into their daily routines&lt;/strong&gt; without disproportionate effort.&lt;/p&gt;&lt;h2 id="accessibility-and-design"&gt;Accessibility And Design&lt;/h2&gt;&lt;p&gt;Working
 on digital accessibility in design can involve several actions. It’s 
clear that we need to pay particular attention to color and how it’s 
used to convey meaning. Of course, the interaction sizes of elements 
must be comfortable. But, most importantly, we must &lt;strong&gt;think about design from a versatile perspective&lt;/strong&gt;.
 An interface isn’t a poster. We can control many aspects of that 
design, but how users interact with the interface is subject to an 
endless number of variables. The type of device, context, purpose, 
network quality, etc. All of this greatly affects each person’s 
experience and interaction. Along with all this, when digital 
accessibility concerns are brought into the design process, it adds even
 more variables.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/01-assistive-technologies.png"&gt;&lt;img alt="Assistive technologies" height="533" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/01-assistive-technologies.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;(&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/01-assistive-technologies.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;People often use what are called &lt;strong&gt;assistive technologies and strategies&lt;/strong&gt;.
 Basically, these are technological tools or, at the very least, 
“tricks” that people resort to in order to find more comfortable usage 
models. The famous screen readers, commonly associated with the use of 
blind people (but which are not only useful to them), for example, are 
an assistive technology. Changing colors or color contrasts between 
different elements is also an assistive technology. Increasing the font 
size (which we discussed in this text) is another example. There are 
countless assistive technologies and strategies. Almost as many as the 
different contexts of use for each person.\&lt;/p&gt;&lt;div class="feature-panel-container" data-audience="non-subscriber" data-remove="true"&gt;&lt;aside class="feature-panel"&gt;&lt;div class="feature-panel-right-col"&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;&lt;/aside&gt;&lt;/div&gt;&lt;h2 id="we-don-t-control-everything"&gt;We Don’t Control Everything&amp;nbsp;&lt;/h2&gt;&lt;p&gt;In
 other words (and this is the “bad news” for us designers), “our design”
 is subject, from the users’ perspective, to transformations that we 
don’t control. It will be “transformed” by the user, ensuring that they 
can interact with the application and everything it offers in the most 
comfortable way possible. And that’s a good thing. If this happens and 
everything goes well, we will have surely done our accessibility work 
very well, and we all deserve congratulations. If the user applies any 
of these support technologies and strategies and still cannot use the 
digital application, it’s a sign that something is not working as it 
should.&lt;/p&gt;&lt;p&gt;Oh, and speaking of which. Don’t even think about blocking
 the use of these technologies or support strategies. They may be 
“destroying” your beautiful design, but they are allowing more and more 
people to actually use the app. In the end, wasn’t that exactly what we 
promised we wanted to do? Design for (all) people. Without exception?&lt;/p&gt;&lt;h2 id="increase-font-size"&gt;Increase Font Size&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/03/testing-font-scaling-accessibility-figma-variables/#increase-font-size"&gt;#&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;How
 many times have we heard someone — friends, family, or even colleagues —
 complaining that this or that text is too small? Text plays a very 
important role in the digital experience. Much information is conveyed 
through text: instructions for use, button captions, or interactive 
elements. All of this uses text as a communication tool. If reading all 
these elements is difficult, naturally, the experience is severely 
impaired.&lt;/p&gt;&lt;p&gt;Comfortable text reading, regardless of its function, is
 a non-negotiable principle. This reading can be facilitated by using 
comfortable sizes in the design. However, supporting technologies and 
strategies, through the functionality of increasing font size, can also 
help improve readability. According to &lt;a href="https://appt.org/en/stats/font-size"&gt;APPT&lt;/a&gt; data, &lt;strong&gt;26% of Android and iOS mobile device users&lt;/strong&gt;
 increase the default font size (data from February 2026). One in four 
users increases the font size on their smartphone. This is a very 
significant sample of people, making this functionality unavoidable in 
design processes.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/02-chart.png"&gt;&lt;img alt="Chart with font sizes where 26% of users use large font-size." height="533" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/02-chart.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;(&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/02-chart.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;h2 id="compliance-with-guidelines"&gt;Compliance With Guidelines&lt;/h2&gt;&lt;p&gt;Increasing
 font size in interfaces can represent a huge design challenge. It’s 
important to understand that, suddenly, some text elements, due to user 
actions, can double in size from their initial size.&lt;/p&gt;&lt;blockquote&gt;“With
 the exception of captions and text images, text can be resized without 
assistive technology up to 200% without loss of content or 
functionality.”&lt;br /&gt;&lt;br /&gt;— &lt;a href="https://acessibilidade.gov.pt/wcag/#resize-text"&gt;Success criterion 1.4.4, “Resizing Text”&lt;/a&gt; of the Web Content Accessibility Guidelines (WCAG), version 2.2&lt;/blockquote&gt;&lt;p&gt;This
 success criterion is at the AA compliance level, meaning this is an 
absolutely mandatory feature according to any legal framework.&lt;/p&gt;&lt;p&gt;It’s
 easy to understand the 200% in this success criterion. If we assume we 
design the interfaces at a 100% scale, meaning the element size is the 
initial size, then increasing the text by up to 200% will correspond to 
doubling the initial size. Other enlargement scales can also be used, 
such as 120%, 140%, and so on. In other words, we have to ensure that 
users can increase the text to double its initial size through 
supporting technologies or strategies (and this is not a minor detail).&lt;/p&gt;&lt;p&gt;To
 comply with this standard, we don’t need to provide text size increase 
tools in the interfaces. In practice, these features are nothing more 
than redundancy. Devices already allow this to be done in a standardized
 way. Users who really need this setting know it (because, without it, 
their lives would be much more difficult). Well, they already have this 
setting applied across their device. And that means we can eliminate 
these additional interface elements, simplifying the experience.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/03-feature.png"&gt;&lt;img alt="Text size increase tool in the interface" height="533" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/03-feature.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;(&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/03-feature.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;h2 id="standardized-access"&gt;Standardized Access&lt;/h2&gt;&lt;p&gt;An
 important concept to remember about assistive technologies, 
particularly in this case regarding increasing font size, is that most 
devices already have many of these tools installed by default. In other 
words, in many cases, users don’t need to purchase their own software or
 buy a specific type of device just to have this functionality.&lt;/p&gt;&lt;p&gt;Whether
 on mobile devices or even in web browsers, in the vast majority of 
cases, it’s easy to find installed features that allow you to increase 
the default font size we’re using throughout the interface. This 
principle of increasing font size can be applied to digital products, 
such as apps, or even to any type of website running on the standard web
 browsers used today.&lt;/p&gt;&lt;h3 id="iphones"&gt;iPhones&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/03/testing-font-scaling-accessibility-figma-variables/#iphones"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;On
 iPhone devices, the font size increase feature is integrated by 
default. To use this feature, simply access the “Settings” panel, select
 “Accessibility,” and within the “Vision” options group, access the 
“Text Size and Display” feature and configure the desired font size 
increase on that screen.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/04-iphones.png"&gt;&lt;img alt="iPhone screens with settings on accessibility" height="533" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/04-iphones.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;(&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/04-iphones.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="google-chrome"&gt;Google Chrome&lt;/h3&gt;&lt;p&gt;Web
 browsers also offer, by default, the functionality to increase font 
size. For example, in Google Chrome, this feature is available in the 
“Options” panel, specifically in the “Appearance” area. In the list of 
options that appear in this group, simply select the “Font size” option.
 Normally, the “Medium — Recommended” option will be selected. You can 
change this setting to any other available font size. Try, for example, 
the “Very large” option.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/05-google-chrome.png"&gt;&lt;img alt="Google Chrome settings on accessibility" height="533" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/05-google-chrome.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;(&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/05-google-chrome.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;h2 id="test-in-figma"&gt;Test In Figma&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/03/testing-font-scaling-accessibility-figma-variables/#test-in-figma"&gt;#&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;To ensure that digital accessibility work becomes effective in the daily lives of teams, it is essential to find &lt;strong&gt;simple work processes&lt;/strong&gt;.
 Actions or initiatives that can be integrated into the team’s routine, 
that address accessibility in an integrated way, and do not require a 
dramatic transformation of the current reality. If that were necessary, 
he believes, it wouldn’t happen most of the time. Therefore, designing 
simple work processes is half the battle for accessibility to truly 
happen, in this case, also within a design team.&lt;/p&gt;&lt;p&gt;Regarding testing
 font size increases in design, we have extraordinary tools at our 
disposal today. Those who remember the days of designing complex 
interfaces in &lt;a href="https://www.adobe.com/pt/products/photoshop.html"&gt;Adobe Photoshop&lt;/a&gt; will recognize the differences in the tools we have today (and thankfully so). It’s now possible, through tools like &lt;a href="https://www.figma.com/design/"&gt;Figma&lt;/a&gt;, to create such dynamism in design that testing font size increases for accessibility becomes almost unavoidable for the team.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/06-hands-on.png"&gt;&lt;img alt="Visualization on font sizes" height="533" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/06-hands-on.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;(&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/06-hands-on.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: To take this test, you need to have a strong grasp of Figma’s &lt;a href="https://help.figma.com/hc/en-us/articles/360039957034-Create-and-apply-text-styles"&gt;text styles&lt;/a&gt;, &lt;a href="https://help.figma.com/hc/en-us/articles/360040451373-Guide-to-auto-layout"&gt;auto layouts&lt;/a&gt;, and &lt;a href="https://help.figma.com/hc/en-us/articles/15339657135383-Guide-to-variables-in-Figma"&gt;variables&lt;/a&gt;.
 These three are fundamental tools for success without much extra 
effort. If you haven’t yet mastered these features, it’s highly 
recommended that you start there. Don’t skip steps. Learning is a 
gradual process that must be followed in a structured, step-by-step 
manner.&lt;/p&gt;&lt;h3 id="where-do-we-want-to-go"&gt;Where Do We Want To Go?&lt;/h3&gt;&lt;p&gt;The
 font size increase test in Figma that we want to perform is simple. We 
want to have a set of variables available for all the text styles we use
 in the interface, allowing us to choose whether we want to see the 
interface with the text at a scale of 100%, 120%, 140%, 160%, 180%, or 
200%. As we apply this set of variables (much like applying variables 
for light and dark mode), we observe the transformations of the text in 
the interface and understand to what extent adaptations are needed in 
each version of the interface with different typographic scales.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/07-font-scaling.png"&gt;&lt;img alt="Font scaling" height="533" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/07-font-scaling.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;(&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/07-font-scaling.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="how-do-we-make-this-happen"&gt;How Do We Make This Happen?&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/03/testing-font-scaling-accessibility-figma-variables/#how-do-we-make-this-happen"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;For this test to go so smoothly, you need to do some groundwork. &lt;a href="https://dxd.pt/design-systems/"&gt;Design systems&lt;/a&gt;
 can greatly help optimize much of this initial work. But I won’t lie to
 you. For the test to work well, your design needs to have a very 
serious level of organization and systematization.&lt;/p&gt;&lt;p&gt;This isn’t 
really a guide, because each team will have its own work model, and 
these recommendations can be applied in different ways (and that’s 
okay). However, for this test to work, it’s important to ensure certain 
assumptions in the design. To help you phase the implementation of this 
test model, here are some steps to follow. Step-by-step instructions to 
guide you in organizing your files and ensuring you can fully execute 
this test in the simplest and most practical way possible.&lt;/p&gt;&lt;h3 id="1-designing-the-interfaces"&gt;1. Designing The Interfaces&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/03/testing-font-scaling-accessibility-figma-variables/#1-designing-the-interfaces"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;It
 all starts with the design. Before any testing, the focus should, as it
 should, be on the design of each interface that we will want to test 
later. At this stage, there is still no specific concern with the font 
size increase test that we will perform later. Naturally, all interface 
design should, from the outset, follow the most basic &lt;a href="https://www.a11yproject.com/checklist/"&gt;accessibility recommendations&lt;/a&gt; applied to design.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/08-design-screens.png"&gt;&lt;img alt="Design screens" height="533" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/08-design-screens.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;(&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/08-design-screens.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="2-apply-auto-layouts-to-all-elements"&gt;2. Apply Auto Layouts To All Elements&amp;nbsp;&lt;/h3&gt;&lt;p&gt;In
 every screen design you create, you’ll need to ensure you apply auto 
layouts perfectly. This is a very important step. It’s this consistent 
application of auto layouts to the entire structure and design elements 
that will later guarantee the scalability of the interface when we start
 testing font size increases. You really can’t underestimate this step. 
If you don’t pay it the attention it deserves, you’ll see when we test 
typographic scaling in the interfaces, everything breaking down like an 
elephant in a china shop.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/09-auto-layout.png"&gt;&lt;img alt="Auto layout" height="534" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/09-auto-layout.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;(&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/09-auto-layout.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="3-structuring-and-applying-text-styles"&gt;3. Structuring And Applying Text Styles&lt;/h3&gt;&lt;p&gt;To
 perform our font size increase test, we’ll also need you to have 
applied text styles to each interface design. You probably even started 
creating them as you were drawing. Great. If you haven’t done so, it’s 
important that you do it now. For the test to work perfectly, we really 
need this. Don’t leave any text element in the design without a text 
style applied.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/10-text-styles.png"&gt;&lt;img alt="Text styles" height="533" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/10-text-styles.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;(&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/10-text-styles.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="4-define-the-set-of-variables-100"&gt;4. Define The Set Of Variables 100%&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/03/testing-font-scaling-accessibility-figma-variables/#4-define-the-set-of-variables-100"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;This
 test forces a fairly high degree of optimization. In practice, this 
means we will have to use Figma variables for all the characteristics of
 the text styles we have in the interface. At this stage, you must 
define Figma “number” variables for at least the font-size and 
line-height of the text styles you applied to the drawing. With this 
step, you are defining the font size increase scale values for a 100% 
visualization model, that is, the initial and reference version of the 
drawing. It is important that you structure these variables for each 
text style in the drawing because, subsequently, we will have to 
consider the enlargement scale of each of these text elements.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/11-variables-100-percent.png"&gt;&lt;img alt="Defining the set of variables 100%" height="533" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/11-variables-100-percent.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;(&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/11-variables-100-percent.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="5-apply-the-variables-to-the-text-styles"&gt;5. Apply The Variables To The Text Styles&amp;nbsp;&lt;/h3&gt;&lt;p&gt;Having
 defined the variables for the 100% scale text styles, you must now 
apply them to the elements of the text styles already created. Don’t 
forget to apply variables at least to the font-size and line-height 
characteristics. If you have more typographical variables, that’s fine. 
But you should at least have variables applied to font-size and 
line-height. This is really very important.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/12-text-styles-variables.png"&gt;&lt;img alt="Applying variables to the text styles" height="533" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/12-text-styles-variables.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;(&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/12-text-styles-variables.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="6-define-the-variables-for-increasing-the-text-size"&gt;6. Define The Variables For Increasing The Text Size&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/03/testing-font-scaling-accessibility-figma-variables/#6-define-the-variables-for-increasing-the-text-size"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Now
 that you have the variables applied to the 100% scale text styles, the 
next step is to create the variables for the other font size increase 
scales. In practice, you have to create the variables that will tell the
 system what font size each text style will grow to when the increase 
scale is 120%, 140%, 160%, etc.&lt;/p&gt;&lt;p&gt;To define the font-size and 
line-height values, simply multiply the initial value by the scale 
percentage. For example, if a text style has a font-size of 16px, the 
size for the 120% scale will be 16 multiplied by 1.2, which gives a 
result of 19.2. Repeat this calculation for all font-size and 
line-height values of the font size increase scale percentages you 
choose.&lt;/p&gt;&lt;p&gt;You can also choose whether or not to apply rounding to 
the final values. This is an approximate test, and therefore any 
differences that may arise from rounding will not affect the final 
perception of the test result.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/13-font-scaling-variables.png"&gt;&lt;img alt="Font scalling variables" height="533" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/13-font-scaling-variables.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;(&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/13-font-scaling-variables.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="7-apply-variables-to-different-scale-versions"&gt;7. Apply Variables To Different Scale Versions&lt;/h3&gt;&lt;p&gt;The
 moment of truth has arrived. The next step is to understand if we have 
everything working so that the test runs perfectly. Therefore, you 
should copy the original interface and apply the set of variables for 
each of the font size increase rates that make sense to you. Repeat this
 process for all the font size increase percentages you have defined.&lt;/p&gt;&lt;p&gt;As
 a suggestion, you can use the 120%, 140%, 160%, 180%, and 200% increase
 percentages as a reference. If you want to simplify, you can reduce the
 number of scaling percentages you are working with. Regardless of the 
number of percentages you are working with, you should always work with 
the minimum of 100% and 200% scales.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/14-apply-different-scales.png"&gt;&lt;img alt="Applied variables to different scale versions" height="533" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/14-apply-different-scales.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;(&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/14-apply-different-scales.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="8-identify-areas-for-improvement"&gt;8. Identify Areas For Improvement&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/03/testing-font-scaling-accessibility-figma-variables/#8-identify-areas-for-improvement"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;By
 applying different font size increase scales to the same screen, it’s 
easy to understand where improvements might be needed. This is where the
 real test of increasing font size in interface design and the most 
interesting accessibility work begins.&lt;/p&gt;&lt;p&gt;In your analysis of the various screens, keep some important aspects in mind:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The
 fact that the text appears gigantic isn’t a problem and doesn’t “ruin” 
the design. Remember that this can mean the difference between someone 
being able to use a particular product or service or not.&lt;/li&gt;&lt;li&gt;An 
accessibility problem exists when increasing the font size makes it 
impossible for the user to read certain texts or to activate certain 
controls.&lt;/li&gt;&lt;li&gt;For text elements that are already very large, 
increasing the font size might not make sense. Doing so could make those
 elements disproportionate, which wouldn’t improve readability (since 
they are already a good size) and would occupy completely unnecessary 
space.&lt;/li&gt;&lt;li&gt;If there are elements that appear to be popping out of the screen, the first step is to confirm how you are applying &lt;strong&gt;auto layout&lt;/strong&gt;. Many design aspects can be easily resolved with the proper use of auto layout.&lt;/li&gt;&lt;li&gt;Regardless of the scale of font size increase, it is essential to maintain the &lt;strong&gt;visual hierarchy of the typography&lt;/strong&gt;, as this readability is important for perceiving the different levels of information present on the screen.&lt;/li&gt;&lt;li&gt;This
 test can help identify elements that may need adjustments directly in 
the code to function well at a given scale of increase. Not everything 
can be solved through design alone, and that’s perfectly fine. 
Accessibility is essentially a team effort.&lt;/li&gt;&lt;/ul&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/15-critical-points.png"&gt;&lt;img alt="Critical points for improvement" height="533" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/15-critical-points.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;(&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/15-critical-points.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="9-make-corrections-and-adjustments-to-the-design"&gt;9. Make Corrections And Adjustments To The Design&lt;/h3&gt;&lt;p&gt;Finally,
 based on the various screens with different text enlargement scales 
applied, you can make the design changes that make sense. Some of these 
adjustments may only be necessary in code. In these cases, you document 
all these suggestions and pass them on to the development team. It is 
also crucial to reinforce (again) that some of the problems you may 
encounter in the design can be quickly resolved in the design process, 
with the simple and correct application of auto-layout properties.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/16-make-changes.png"&gt;&lt;img alt="Design changes to those critical points" height="533" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/16-make-changes.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;(&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/16-make-changes.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="10-go-back-to-the-beginning-and-repeat-the-process"&gt;10. Go Back To The Beginning And Repeat The Process&lt;/h3&gt;&lt;p&gt;This
 is a cyclical approach. This means you should repeat these steps, or 
variations thereof, as many times as necessary throughout the project. 
It’s natural that, over time and with process optimization, some of 
these steps will cease to make sense. That’s absolutely not a problem. 
But the most important thing to realize here is that accessibility and 
this process of testing font size increases shouldn’t be done just once,
 and that’s it. It’s a test to be done many, many times throughout the 
day-to-day work of each project and team.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/17-staring-point.png"&gt;&lt;img alt="Starting point" height="533" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/17-staring-point.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;(&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/17-staring-point.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;h2 id="the-role-of-design-systems"&gt;The Role Of Design Systems&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/03/testing-font-scaling-accessibility-figma-variables/#the-role-of-design-systems"&gt;#&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;At
 first glance, this list of steps might seem like a complex exercise. 
But it’s not. This is because the vast majority, if not all, of these 
steps are easy to execute in any context where a design system exists. 
In fact, design systems have become an &lt;strong&gt;unavoidable standard&lt;/strong&gt;
 in the Product Design industry. We can discuss what each team calls a 
design system, but the truth is that it’s very difficult today to find a
 Product Design team that doesn’t have, at the very least, a minimally 
structured library of components and styles.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/18-design-systems.png"&gt;&lt;img alt="Visualization on design systems" height="533" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/18-design-systems.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;&lt;br /&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;With
 this foundation, whether more or less documented, it’s very easy to 
apply this type of font size increase test using Figma variables. 
Furthermore, if your design system already has, for example, structured 
variables for light and dark mode, it means you’re already applying the 
exact same principles we used to perform this test. So, nothing new.&lt;/p&gt;&lt;p&gt;Working with design systems involves a level of &lt;strong&gt;structuring and organization&lt;/strong&gt;
 that is also very useful for creating this type of test. There’s a myth
 that design systems limit creativity. This is not true. Design systems 
help solve the “bureaucratic” part of design, so we can actually have 
more time for what matters: in this case, testing accessibility and 
building more and more products and services that are truly accessible 
to the greatest number of people.&lt;/p&gt;&lt;h2 id="example-file"&gt;Example File&lt;/h2&gt;&lt;p&gt;It’s
 always easier to see an example than just read a description of a 
process. If this is true in many disciplines of knowledge, in design, 
this premise makes even more sense. Therefore, in this &lt;a href="https://www.figma.com/community/file/1600134823556764105"&gt;Figma file&lt;/a&gt;, freely published and openly available to the community, you’ll find a &lt;strong&gt;practical example of the entire testing process&lt;/strong&gt;
 described here. Remember that this is just an example. There may be 
countless ways to perform this type of test within the context of a 
Figma file.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/19-community.png"&gt;&lt;img alt="Visualization for the Figma file on testing font scaling" height="533" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/19-community.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;(&lt;a href="https://files.smashing.media/articles/testing-font-scaling-accessibility-figma-variables/19-community.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Be
 sure to look at this approach with a critical eye. It’s a suggestion 
for testing font size increases that follows a specific process. Despite
 this, the approach should be adapted to your team’s specific reality, 
processes, and level of maturity. Simply copying formulas from other 
teams without understanding if they make sense in our own context is a 
sure way to make accessibility efforts disproportionate. Every situation
 is unique. This approach attempts to simplify accessibility work as 
much as possible in this specific context. And remember: if something 
happens, however small, it’s a step forward, not a step backward. And 
that should be celebrated by everyone on the team.&lt;/p&gt;</description><link>http://honeyvig.blogspot.com/2026/04/testing-font-scaling-for-accessibility.html</link><author>noreply@blogger.com (H)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9165069509664255576.post-2598603610714520335</guid><pubDate>Sat, 04 Apr 2026 10:45:00 +0000</pubDate><atom:updated>2026-04-04T03:45:54.568-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">CSS</category><category domain="http://www.blogger.com/atom/ns#">javascript</category><category domain="http://www.blogger.com/atom/ns#">Techniques</category><category domain="http://www.blogger.com/atom/ns#">Tools</category><title>Dropdowns Inside Scrollable Containers: Why They Break And How To Fix Them Properly</title><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="c-garfield-summary"&gt;&lt;section aria-label="Quick summary" class="article__summary"&gt;Dropdowns
 often work perfectly until they’re placed inside a scrollable panel, 
where they can get clipped, and half the menu disappears behind the 
container’s edge. Godstime Aburu explains why this happens and offers 
practical solutions to fix it.&lt;/section&gt;&lt;/div&gt;&lt;p&gt;The scenario is almost 
always the same, which is a data table inside a scrollable container. 
Every row has an action menu, a small dropdown with some options, like &lt;strong&gt;Edit&lt;/strong&gt;, &lt;strong&gt;Duplicate&lt;/strong&gt;, and &lt;strong&gt;Delete&lt;/strong&gt;. You build it, it seems to work perfectly in isolation, and then someone puts it inside that scrollable &lt;code&gt;div&lt;/code&gt;
 and things fall apart. I’ve seen this exact bug in three different 
codebases: the container, the stack, and the framework, all different. 
The bug, though, is totally identical.&lt;/p&gt;&lt;p&gt;The dropdown gets clipped 
at the container’s edge. Or it shows up behind content that should 
logically be below it. Or it works fine until the user scrolls, and then
 it drifts.
You reach for &lt;code&gt;z-index: 9999&lt;/code&gt;. Sometimes it helps, but other 
times it does absolutely nothing. That inconsistency is the first clue 
that something deeper is happening.&lt;/p&gt;&lt;p&gt;The reason it keeps coming 
back is that three separate browser systems are involved, and most 
developers understand each one on its own but never think about what 
happens when all three collide: &lt;strong&gt;overflow&lt;/strong&gt;, &lt;strong&gt;stacking contexts&lt;/strong&gt;, and &lt;strong&gt;containing blocks&lt;/strong&gt;.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/dropdowns-scrollable-containers-why-break-how-fix/1-three-browser-systems-large.png"&gt;&lt;img alt="Three browser systems: overflow clipping, stacking contexts, and containing blocks." height="410" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/dropdowns-scrollable-containers-why-break-how-fix/1-three-browser-systems-large.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Three browser systems: overflow clipping, stacking contexts, and containing blocks. (&lt;a href="https://files.smashing.media/articles/dropdowns-scrollable-containers-why-break-how-fix/1-three-browser-systems-large.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Once you understand how all three interact, the failure modes stop feeling random. In fact, they become predictable.&lt;/p&gt;&lt;h2 id="the-three-things-actually-causing-this"&gt;The Three Things Actually Causing This&lt;/h2&gt;&lt;p&gt;Let’s look at each of those items in detail.&lt;/p&gt;&lt;h3 id="the-overflow-problem"&gt;The Overflow Problem&lt;/h3&gt;&lt;p&gt;When you set &lt;code&gt;overflow: hidden&lt;/code&gt;, &lt;code&gt;overflow: scroll&lt;/code&gt;, or &lt;code&gt;overflow: auto&lt;/code&gt; on an element, the browser will clip anything that extends beyond its bounds, including absolutely positioned descendants.&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-css"&gt;&lt;code class=" language-css"&gt;&lt;span class="token selector"&gt;.scroll-container&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
  &lt;span class="token property"&gt;overflow&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; auto&lt;span class="token punctuation"&gt;;&lt;/span&gt;
  &lt;span class="token property"&gt;height&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; 300px&lt;span class="token punctuation"&gt;;&lt;/span&gt;
  &lt;span class="token comment"&gt;/* This will clip the dropdown, full stop */&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;

&lt;span class="token selector"&gt;.dropdown&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
  &lt;span class="token property"&gt;position&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; absolute&lt;span class="token punctuation"&gt;;&lt;/span&gt;
  &lt;span class="token comment"&gt;/* Doesn't matter -- still clipped by .scroll-container */&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;That surprised me the first time I ran into it. I’d assumed &lt;code&gt;position: absolute&lt;/code&gt; would let an element escape a container’s clipping. It doesn’t.&lt;/p&gt;&lt;p&gt;In
 practice, that means an absolutely positioned menu can be cut off by 
any ancestor that has a non-visible overflow value, even if that 
ancestor isn’t the menu’s containing block. Clipping and positioning are
 separate systems. They just happen to collide in ways that look 
completely random until you understand both.&lt;/p&gt;&lt;figure class="break-out"&gt;&lt;div&gt;&lt;/div&gt;&lt;figcaption&gt;See the Pen &lt;a href="https://codepen.io/smashingmag/pen/RNGZNPw"&gt;Overflow &amp;amp; Clipping [forked]&lt;/a&gt; by &lt;a href="https://codepen.io/BboyGT"&gt;BboyGT&lt;/a&gt;.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;This
 is also an accessibility problem, not just a visual one. When a 
dropdown is clipped, it’s still in the DOM. A keyboard user can still 
focus on it. They just can’t see what they’re focusing on. In my 
testing, I saw screen readers announce menu items that were invisible to
 sighted users. That disconnect is a real problem. It’s also the kind of
 thing that passes a visual review completely fine.&lt;/p&gt;&lt;h3 id="the-stacking-context-trap"&gt;The Stacking Context Trap&lt;/h3&gt;&lt;p&gt;Think
 of a stacking context as a sealed layer. Whatever is inside it is 
painted together, as one block. Nothing inside it can escape above 
something outside it, no matter what &lt;code&gt;z-index&lt;/code&gt; you use.&lt;/p&gt;&lt;p&gt;The
 thing is, a lot of CSS properties create a new stacking context. I 
didn’t know half of these triggered a new context until I started 
debugging &lt;code&gt;z-index&lt;/code&gt; issues and had to look them up.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;position&lt;/code&gt; with a &lt;code&gt;z-index&lt;/code&gt; value other than &lt;code&gt;auto&lt;/code&gt;;&lt;/li&gt;&lt;li&gt;&lt;code&gt;opacity&lt;/code&gt; less than &lt;code&gt;1&lt;/code&gt;;&lt;/li&gt;&lt;li&gt;&lt;code&gt;transform&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;, &lt;code&gt;perspective&lt;/code&gt;, &lt;code&gt;clip-path&lt;/code&gt;, or &lt;code&gt;mask&lt;/code&gt;;&lt;/li&gt;&lt;li&gt;&lt;code&gt;will-change&lt;/code&gt; referencing any of the above;&lt;/li&gt;&lt;li&gt;&lt;code&gt;isolation: isolate&lt;/code&gt;;&lt;/li&gt;&lt;li&gt;&lt;code&gt;contain: layout&lt;/code&gt; or &lt;code&gt;paint&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This is exactly why &lt;code&gt;z-index: 9999&lt;/code&gt; sometimes does nothing. If your dropdown is trapped inside a stacking context that paints below another stacking context, its &lt;code&gt;z-index&lt;/code&gt; value doesn’t matter at all. &lt;code&gt;z-index&lt;/code&gt; is only compared between siblings in the same stacking context. That’s how a modal with &lt;code&gt;z-index: 1&lt;/code&gt; can sit on top of your dropdown with &lt;code&gt;z-index: 9999&lt;/code&gt;. They are not in the same context. The comparison never happens.&lt;/p&gt;&lt;p&gt;That kind of &lt;code&gt;z-index&lt;/code&gt; war is never going to be won. You’re fighting in the wrong arena.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/dropdowns-scrollable-containers-why-break-how-fix/2-why-z-index-fails-large.png"&gt;&lt;img alt="The dropdown’s z-index: 9999 only competes inside the card’s stacking context. The card paints below the modal, so the fight never happens." height="405" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/dropdowns-scrollable-containers-why-break-how-fix/2-why-z-index-fails-large.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;The dropdown’s &lt;code&gt;z-index: 9999&lt;/code&gt; only competes inside the card’s stacking context. The card paints below the modal, so the fight never happens. (&lt;a href="https://files.smashing.media/articles/dropdowns-scrollable-containers-why-break-how-fix/2-why-z-index-fails-large.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure class="break-out"&gt;&lt;div&gt;&lt;/div&gt;&lt;figcaption&gt;See the Pen &lt;a href="https://codepen.io/smashingmag/pen/zxKdxGL"&gt;Stacking Contexts [forked]&lt;/a&gt; by &lt;a href="https://codepen.io/BboyGT"&gt;BboyGT&lt;/a&gt;.&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="the-containing-block-surprise"&gt;The Containing Block Surprise&lt;/h3&gt;&lt;p&gt;I learned something uncomfortable about containing blocks early on: &lt;strong&gt;Absolute positioning does not mean “position anywhere.”&lt;/strong&gt;
 The browser finds the nearest positioned ancestor and treats it as the 
reference frame for that element’s coordinates and dimensions.&lt;/p&gt;&lt;p&gt;If 
that ancestor is deep inside a scroll container, the dropdown’s 
coordinates are calculated relative to it. When the container scrolls, 
those coordinates don’t update. The trigger moves. The dropdown stays 
put.&lt;/p&gt;&lt;h2 id="why-absolute-positioning-fails-alone"&gt;Why Absolute Positioning Fails Alone&lt;/h2&gt;&lt;p&gt;For a long time, &lt;code&gt;position: absolute&lt;/code&gt;
 was my default answer for dropdowns. It works in isolation. The moment 
you put it inside a real application, though, things start breaking in 
ways that don’t feel connected to anything you changed.&lt;/p&gt;&lt;p&gt;In a clean DOM, &lt;code&gt;position: absolute&lt;/code&gt;
 works fine. Real applications are just messier. There’s almost always 
something up the ancestor tree that creates an unexpected stacking 
context or clips descendants.&lt;/p&gt;&lt;p&gt;I ran into this with a dropdown inside a table, which lived inside a scrollable &lt;code&gt;div&lt;/code&gt;, where a card component somewhere up the tree had &lt;code&gt;transform: translateZ(0)&lt;/code&gt;
 applied as a GPU compositing hint. That transform created a new 
stacking context. The dropdown was trapped below everything outside the 
card that had a non-auto &lt;code&gt;z-index&lt;/code&gt;. And the scroll container was clipping it regardless.&lt;/p&gt;&lt;p&gt;Debugging
 this felt like following a trail of ghosts with three different 
ancestors, three different failure modes, and one invisible dropdown. 
Once I stopped trying to patch the symptom and started tracing which 
ancestor was responsible, the root cause became obvious.&lt;/p&gt;&lt;h2 id="the-fixes-that-actually-work"&gt;The Fixes That Actually Work&lt;/h2&gt;&lt;p&gt;Here’s what does work.&lt;/p&gt;&lt;h3 id="portals-the-fix-that-ultimately-worked-for-me"&gt;Portals: The Fix That Ultimately Worked For Me&lt;/h3&gt;&lt;p&gt;What
 finally worked for me was getting the dropdown out of the problematic 
part of the DOM entirely, rendering it directly as a child of &lt;code&gt;document.body&lt;/code&gt; instead. In React and Vue, this is called a &lt;strong&gt;portal&lt;/strong&gt;. In vanilla JavaScript, it’s just &lt;code&gt;document.body.appendChild()&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Once
 it’s at the body level, none of the ancestor clipping or stacking 
context problems apply. The dropdown is outside all of it. &lt;code&gt;z-index&lt;/code&gt; works the way you expect it to.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/dropdowns-scrollable-containers-why-break-how-fix/3-portal-pattern-dropdown-large.png"&gt;&lt;img alt="Portal Pattern: DOM structure before vs. after" height="400" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/dropdowns-scrollable-containers-why-break-how-fix/3-portal-pattern-dropdown-large.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Portalling
 moves the dropdown out of the ancestor tree entirely. The overflow and 
stacking context problems don’t follow it because it’s no longer a 
descendant of either ancestor. (&lt;a href="https://files.smashing.media/articles/dropdowns-scrollable-containers-why-break-how-fix/3-portal-pattern-dropdown-large.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Here’s a React example using &lt;code&gt;createPortal&lt;/code&gt;:&lt;/p&gt;&lt;div class="break-out"&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token keyword"&gt;import&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt; createPortal &lt;span class="token punctuation"&gt;}&lt;/span&gt; &lt;span class="token keyword"&gt;from&lt;/span&gt; &lt;span class="token string"&gt;'react-dom'&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token keyword"&gt;import&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt; useState&lt;span class="token punctuation"&gt;,&lt;/span&gt; useEffect&lt;span class="token punctuation"&gt;,&lt;/span&gt; useRef &lt;span class="token punctuation"&gt;}&lt;/span&gt; &lt;span class="token keyword"&gt;from&lt;/span&gt; &lt;span class="token string"&gt;'react'&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

&lt;span class="token keyword"&gt;function&lt;/span&gt; &lt;span class="token function"&gt;Dropdown&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token parameter"&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt; anchorRef&lt;span class="token punctuation"&gt;,&lt;/span&gt; isOpen&lt;span class="token punctuation"&gt;,&lt;/span&gt; children &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
  &lt;span class="token keyword"&gt;const&lt;/span&gt; &lt;span class="token punctuation"&gt;[&lt;/span&gt;position&lt;span class="token punctuation"&gt;,&lt;/span&gt; setPosition&lt;span class="token punctuation"&gt;]&lt;/span&gt; &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;useState&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt; top&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;0&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; left&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;0&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

  &lt;span class="token function"&gt;useEffect&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token operator"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
    &lt;span class="token keyword"&gt;if&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;isOpen &lt;span class="token operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; anchorRef&lt;span class="token punctuation"&gt;.&lt;/span&gt;current&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
      &lt;span class="token keyword"&gt;const&lt;/span&gt; rect &lt;span class="token operator"&gt;=&lt;/span&gt; anchorRef&lt;span class="token punctuation"&gt;.&lt;/span&gt;current&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;getBoundingClientRect&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token function"&gt;setPosition&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt;
        top&lt;span class="token operator"&gt;:&lt;/span&gt; rect&lt;span class="token punctuation"&gt;.&lt;/span&gt;bottom &lt;span class="token operator"&gt;+&lt;/span&gt; window&lt;span class="token punctuation"&gt;.&lt;/span&gt;scrollY&lt;span class="token punctuation"&gt;,&lt;/span&gt;
        left&lt;span class="token operator"&gt;:&lt;/span&gt; rect&lt;span class="token punctuation"&gt;.&lt;/span&gt;left &lt;span class="token operator"&gt;+&lt;/span&gt; window&lt;span class="token punctuation"&gt;.&lt;/span&gt;scrollX&lt;span class="token punctuation"&gt;,&lt;/span&gt;
      &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;
  &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token punctuation"&gt;[&lt;/span&gt;isOpen&lt;span class="token punctuation"&gt;,&lt;/span&gt; anchorRef&lt;span class="token punctuation"&gt;]&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

  &lt;span class="token keyword"&gt;if&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token operator"&gt;!&lt;/span&gt;isOpen&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token keyword"&gt;return&lt;/span&gt; &lt;span class="token keyword"&gt;null&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

  &lt;span class="token keyword"&gt;return&lt;/span&gt; &lt;span class="token function"&gt;createPortal&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;
    &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;div
      id&lt;span class="token operator"&gt;=&lt;/span&gt;&lt;span class="token string"&gt;"dropdown-demo"&lt;/span&gt;
      role&lt;span class="token operator"&gt;=&lt;/span&gt;&lt;span class="token string"&gt;"menu"&lt;/span&gt;
      className&lt;span class="token operator"&gt;=&lt;/span&gt;&lt;span class="token string"&gt;"dropdown-menu"&lt;/span&gt;
      style&lt;span class="token operator"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt; position&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'absolute'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; top&lt;span class="token operator"&gt;:&lt;/span&gt; position&lt;span class="token punctuation"&gt;.&lt;/span&gt;top&lt;span class="token punctuation"&gt;,&lt;/span&gt; left&lt;span class="token operator"&gt;:&lt;/span&gt; position&lt;span class="token punctuation"&gt;.&lt;/span&gt;left &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt;
    &lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="token punctuation"&gt;{&lt;/span&gt;children&lt;span class="token punctuation"&gt;}&lt;/span&gt;
    &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;/&lt;/span&gt;div&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
    document&lt;span class="token punctuation"&gt;.&lt;/span&gt;body
  &lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;figure class="break-out"&gt;&lt;div&gt;&lt;/div&gt;&lt;figcaption&gt;See the Pen &lt;a href="https://codepen.io/smashingmag/pen/Kwgvwdv"&gt;Portal Fix [forked]&lt;/a&gt; by &lt;a href="https://codepen.io/BboyGT"&gt;BboyGT&lt;/a&gt;.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;In my case, the fix required explicit accessibility work. When I &lt;code&gt;portal&lt;/code&gt;-led
 the menu out of the DOM to escape clipping, I also had to restore the 
logical relationship for keyboard and screen reader users, move focus 
into the menu when it opens, and reliably return focus to the trigger on
 close. That extra bit of JavaScript fixes the accessibility gap the 
portal creates.&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-html"&gt;&lt;code class=" language-html"&gt;&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt;
  &lt;span class="token attr-name"&gt;id&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;dropdown-toggle&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt;
  &lt;span class="token attr-name"&gt;aria-haspopup&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;menu&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt;
  &lt;span class="token attr-name"&gt;aria-expanded&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;false&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt;
  &lt;span class="token attr-name"&gt;aria-controls&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;dropdown-demo&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt;
&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  Actions
&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;&lt;/span&gt;ul&lt;/span&gt; &lt;span class="token attr-name"&gt;id&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;dropdown-demo&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="token attr-name"&gt;role&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;menu&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="token attr-name"&gt;hidden&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt; &lt;span class="token attr-name"&gt;role&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;menuitem&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Edit&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt; &lt;span class="token attr-name"&gt;role&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;menuitem&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Duplicate&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt; &lt;span class="token attr-name"&gt;role&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;menuitem&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Delete&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;/&lt;/span&gt;ul&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Portals
 fixed the clipping quickly, but they came with trade-offs, and I 
learned the hard way. In one repo, the dropdown lost theme context 
because it rendered outside the provider. In another repo, the close 
animation felt detached because events were routed differently. Each 
required a small targeted fix, context forwarding, explicit focus 
restoration, or moving the animation into the portal, but together they 
show portals are a surgical tool, not a one-click replacement.&lt;/p&gt;&lt;h3 id="fixed-positioning-and-why-it-s-trickier-than-it-looks"&gt;Fixed Positioning (And Why It’s Trickier Than It Looks)&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/03/dropdowns-scrollable-containers-why-break-how-fix/#fixed-positioning-and-why-it-s-trickier-than-it-looks"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Fixed
 positioning can feel like a simple solution. Instead of being 
positioned relative to an ancestor, the element is positioned relative 
to the viewport itself. But transforms, and other properties as we saw 
earlier, create containing blocks that can prevent a &lt;code&gt;position: fixed&lt;/code&gt; element from escaping a container.&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token punctuation"&gt;.&lt;/span&gt;dropdown&lt;span class="token operator"&gt;-&lt;/span&gt;menu &lt;span class="token punctuation"&gt;{&lt;/span&gt;
  position&lt;span class="token operator"&gt;:&lt;/span&gt; fixed&lt;span class="token punctuation"&gt;;&lt;/span&gt;
  &lt;span class="token comment"&gt;/* Coordinates set via JavaScript */&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;


&lt;span class="token keyword"&gt;function&lt;/span&gt; &lt;span class="token function"&gt;positionDropdown&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token parameter"&gt;trigger&lt;span class="token punctuation"&gt;,&lt;/span&gt; dropdown&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
  &lt;span class="token keyword"&gt;const&lt;/span&gt; rect &lt;span class="token operator"&gt;=&lt;/span&gt; trigger&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;getBoundingClientRect&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
  dropdown&lt;span class="token punctuation"&gt;.&lt;/span&gt;style&lt;span class="token punctuation"&gt;.&lt;/span&gt;top &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token template-string"&gt;&lt;span class="token template-punctuation string"&gt;`&lt;/span&gt;&lt;span class="token interpolation"&gt;&lt;span class="token interpolation-punctuation punctuation"&gt;${&lt;/span&gt;rect&lt;span class="token punctuation"&gt;.&lt;/span&gt;bottom&lt;span class="token interpolation-punctuation punctuation"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="token string"&gt;px&lt;/span&gt;&lt;span class="token template-punctuation string"&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
  dropdown&lt;span class="token punctuation"&gt;.&lt;/span&gt;style&lt;span class="token punctuation"&gt;.&lt;/span&gt;left &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token template-string"&gt;&lt;span class="token template-punctuation string"&gt;`&lt;/span&gt;&lt;span class="token interpolation"&gt;&lt;span class="token interpolation-punctuation punctuation"&gt;${&lt;/span&gt;rect&lt;span class="token punctuation"&gt;.&lt;/span&gt;left&lt;span class="token interpolation-punctuation punctuation"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="token string"&gt;px&lt;/span&gt;&lt;span class="token template-punctuation string"&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;While
 debugging, I found a transform on an ancestor that stole the containing
 block, which explained why the menu behaved as if it were stuck even 
though it was supposedly fixed.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/dropdowns-scrollable-containers-why-break-how-fix/4-fixed-positioning-large.png"&gt;&lt;img alt="Fixed Positioning" height="385" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/dropdowns-scrollable-containers-why-break-how-fix/4-fixed-positioning-large.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;&lt;code&gt;position: fixed&lt;/code&gt; uses the viewport as its containing block — until an ancestor has &lt;code&gt;transform&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;, or &lt;code&gt;will-change&lt;/code&gt;.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;And,
 of course, we can’t ignore accessibility. Fixed elements that appear 
over content must still be keyboard-reachable. If the focus order 
doesn’t naturally move into the fixed dropdown, you’ll need to manage it
 using code. It’s also worth checking that it doesn’t sit over other 
interactive content with no way to dismiss it. That one bites you in 
keyboard testing.&lt;/p&gt;&lt;h3 id="css-anchor-positioning-where-i-think-this-is-heading"&gt;CSS Anchor Positioning: Where I Think This Is Heading&lt;/h3&gt;&lt;p&gt;&lt;a href="https://css-tricks.com/css-anchor-positioning-guide/"&gt;CSS Anchor Positioning&lt;/a&gt;
 is the direction I’m most interested in right now. I wasn’t sure how 
much of the spec was actually usable when I first looked at it. It lets 
you declare the relationship between a dropdown and its trigger directly
 in CSS, and the browser handles the coordinates.&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-css"&gt;&lt;code class=" language-css"&gt;&lt;span class="token selector"&gt;.trigger&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
  &lt;span class="token property"&gt;anchor-name&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; --my-trigger&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;

&lt;span class="token selector"&gt;.dropdown-menu&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
  &lt;span class="token property"&gt;position&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; absolute&lt;span class="token punctuation"&gt;;&lt;/span&gt;
  &lt;span class="token property"&gt;position-anchor&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; --my-trigger&lt;span class="token punctuation"&gt;;&lt;/span&gt;
  &lt;span class="token property"&gt;top&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; &lt;span class="token function"&gt;anchor&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;bottom&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
  &lt;span class="token property"&gt;left&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; &lt;span class="token function"&gt;anchor&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;left&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
  &lt;span class="token property"&gt;position-try-fallbacks&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; flip-block&lt;span class="token punctuation"&gt;,&lt;/span&gt; flip-inline&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;position-try-fallbacks&lt;/code&gt;
 property is what makes this worth using over a manual calculation. The 
browser tries alternative placements before giving up, so a dropdown at 
the bottom of the viewport automatically flips upward instead of getting
 cut off.&lt;/p&gt;&lt;p&gt;Browser support is solid in Chromium-based browsers and growing in Safari. Firefox needs a &lt;code&gt;polyfill&lt;/code&gt;. The &lt;a href="https://github.com/oddbird/css-anchor-positioning"&gt;&lt;code&gt;@oddbird/css-anchor-positioning&lt;/code&gt;&lt;/a&gt;
 package covers the core spec. I’ve hit layout edge cases with it that 
required fallbacks I didn’t anticipate, so treat it as a progressive 
enhancement or pair it with a JavaScript fallback for Firefox.&lt;/p&gt;&lt;p&gt;In short, promising but not universal yet. Test in your target browsers.&lt;/p&gt;&lt;p&gt;And as far as accessibility is concerned, declaring a visual relationship in CSS doesn’t tell the accessibility tree anything. &lt;code&gt;aria-controls&lt;/code&gt;, &lt;code&gt;aria-expanded&lt;/code&gt;, &lt;code&gt;aria-haspopup&lt;/code&gt; — that part is still on you.&lt;/p&gt;&lt;h3 id="sometimes-the-fix-is-just-moving-the-element"&gt;Sometimes The Fix Is Just Moving The Element&lt;/h3&gt;&lt;p&gt;Before
 reaching for a portal or making coordinate calculations, I always ask 
one question first: Does this dropdown actually need to live inside the 
scroll container?&lt;/p&gt;&lt;p&gt;If it doesn’t, moving the markup to a 
higher-level wrapper eliminates the problem entirely, with no JavaScript
 and no coordinate calculations.&lt;/p&gt;&lt;p&gt;This isn’t always possible. If 
the button and dropdown are encapsulated in the same component, moving 
one without the other means rethinking the whole API. But when you can 
do it, there’s nothing to debug. The problem just doesn’t exist.&lt;/p&gt;&lt;h2 id="what-modern-css-still-doesn-t-solve"&gt;What Modern CSS Still Doesn’t Solve&lt;/h2&gt;&lt;p&gt;CSS has come a long way here, but there are still places it lets you down.&lt;/p&gt;&lt;p&gt;The &lt;code&gt;position: fixed&lt;/code&gt; and &lt;code&gt;transform&lt;/code&gt;
 issues are still there. It’s in the spec intentionally, which means no 
CSS workaround exists. If you’re using an animation library that wraps 
your layout in a transformed element, you’re back to needing portals or 
anchor positioning.&lt;/p&gt;&lt;p&gt;CSS Anchor Positioning is promising, but new. As mentioned earlier, Firefox still needs a &lt;code&gt;polyfill&lt;/code&gt;
 at the time I’m writing this. I’ve hit layout edge cases with it that 
required fallbacks I didn’t anticipate. If you need consistent behavior 
across all browsers today, you’re still reaching for JavaScript for the 
tricky parts.&lt;/p&gt;&lt;p&gt;The addition I’ve actually changed my workflow for is the &lt;a href="https://www.smashingmagazine.com/2026/03/getting-started-popover-api/"&gt;HTML Popover API&lt;/a&gt;,
 now available in all modern browsers. Elements with the popover 
attribute render in the browser’s top layer, above everything, with no 
JavaScript positioning needed.&lt;/p&gt;&lt;div class="break-out"&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-html"&gt;&lt;code class=" language-html"&gt;&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class="token attr-name"&gt;popovertarget&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;dropdown-demo&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Open&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class="token attr-name"&gt;id&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;dropdown-demo&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="token attr-name"&gt;popover&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;manual&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="token attr-name"&gt;role&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;menu&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Popover content&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Escape
 handling, dismiss-on-click-outside, and solid accessibility semantics 
come free for things like tooltips, disclosure widgets, and simple 
overlays. It’s the first tool I reach for now.&lt;/p&gt;&lt;p&gt;That said, it 
doesn’t solve positioning. It solves layering. You still need anchor 
positioning or JavaScript to align a popover to its trigger. The Popover
 API handles the layering. Anchor positioning handles the placement. 
Used together, they cover most of what you’d previously reach for a 
library to do.&lt;/p&gt;&lt;h2 id="a-decision-guide-for-your-situation"&gt;A Decision Guide For Your Situation&lt;/h2&gt;&lt;p&gt;After going through all of this the hard way, here’s how I actually think about the choice now.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/dropdowns-scrollable-containers-why-break-how-fix/5-dropdown-decision-guide-large.png"&gt;&lt;img alt="A decision guide for broken dropdown." src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/dropdowns-scrollable-containers-why-break-how-fix/5-dropdown-decision-guide-large.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Four questions that cover most real-world dropdown bugs. Accessibility applies regardless of which path you take. (&lt;a href="https://files.smashing.media/articles/dropdowns-scrollable-containers-why-break-how-fix/5-dropdown-decision-guide-large.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Use a portal.&lt;/strong&gt;&lt;br /&gt;I’d
 use this when the trigger lives deep in nested scroll containers. I 
used this pattern for table action menus and paired it with focus 
restoration and accessibility checks. It’s the most reliable option, but
 budget time for the extra wiring.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Use fixed positioning.&lt;/strong&gt;&lt;br /&gt;This
 is for when you’re in vanilla JavaScript or a lightweight framework and
 can verify no ancestor applies transforms or filters. It’s simple to 
set up and simple to debug, as long as that one constraint holds.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Use CSS Anchor Positioning.&lt;/strong&gt;&lt;br /&gt;Reach for this when your browser support allows it. If Firefox support is required, pair it with the &lt;code&gt;@oddbird&lt;/code&gt; polyfill. This is where the platform is ultimately heading and will eventually become your go-to approach.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Restructure the DOM.&lt;/strong&gt;&lt;br /&gt;Use
 this when the architecture permits it, and you want zero runtime 
complexity. I believe it’s likely the most underrated option.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Combine patterns.&lt;/strong&gt;&lt;br /&gt;Do
 this when you want anchor positioning as your primary approach, paired 
with a JavaScript fallback for unsupported browsers. Or a portal for DOM
 placement paired with &lt;code&gt;getBoundingClientRect()&lt;/code&gt; for coordinate accuracy.&lt;/li&gt;&lt;/ul&gt;&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;&lt;p&gt;I
 used to treat this bug as a one-off issue — something to patch and move
 on from. But once I sat with it long enough to understand all three 
systems involved — &lt;strong&gt;overflow clipping&lt;/strong&gt;, &lt;strong&gt;stacking contexts&lt;/strong&gt;, and &lt;strong&gt;containing blocks&lt;/strong&gt;
 — it stopped feeling random. I could look at a broken dropdown and 
immediately trace which ancestor was responsible. That shift in how I 
read the DOM was the real takeaway.&lt;/p&gt;&lt;p&gt;There’s no single right 
answer. What I reached for depended on what I could control in the 
codebase: portals when the ancestor tree was unpredictable; fixed 
positioning when it was clean and simple; moving the element when 
nothing was stopping me; and anchor positioning now, where I can.&lt;/p&gt;&lt;p&gt;Whatever you end up choosing, &lt;strong&gt;don’t treat accessibility as the last step&lt;/strong&gt;.
 In my experience, that’s exactly when it gets skipped. The ARIA 
relationships, the focus management, the keyboard behavior — those 
aren’t polish. They’re part of what makes the thing actually work.&lt;/p&gt;&lt;p&gt;Check out the full source code in &lt;a href="https://github.com/BboyGT/DropDowns"&gt;my GitHub repo&lt;/a&gt;.&lt;/p&gt;&lt;h3 id="further-reading"&gt;Further Reading&lt;/h3&gt;&lt;p&gt;These are the references I kept coming back to while working through this:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Positioned_layout/Stacking_context"&gt;The Stacking Context&lt;/a&gt; (MDN)&lt;/li&gt;&lt;li&gt;“&lt;a href="https://css-tricks.com/css-anchor-positioning-guide/"&gt;CSS Anchor Positioning Guide&lt;/a&gt;”, Juan Diego Rodriguez&lt;/li&gt;&lt;li&gt;“&lt;a href="https://www.smashingmagazine.com/2026/03/getting-started-popover-api/"&gt;Getting Started With The Popover API&lt;/a&gt;”, Godstime Aburu&lt;/li&gt;&lt;li&gt;&lt;a href="https://floating-ui.com/"&gt;Floating UI&lt;/a&gt; (floating-ui.com)&lt;/li&gt;&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/overflow"&gt;CSS Overflow&lt;/a&gt; (MDN)&lt;/li&gt;&lt;/ul&gt;</description><link>http://honeyvig.blogspot.com/2026/04/dropdowns-inside-scrollable-containers.html</link><author>noreply@blogger.com (H)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9165069509664255576.post-7568299416267101744</guid><pubDate>Sat, 04 Apr 2026 10:31:00 +0000</pubDate><atom:updated>2026-04-04T03:31:45.372-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">CSS3</category><category domain="http://www.blogger.com/atom/ns#">UI</category><category domain="http://www.blogger.com/atom/ns#">UX</category><title>Modal vs. Separate Page: UX Decision Tree</title><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;You probably have been there before. How do we choose between &lt;strong&gt;showing a modal&lt;/strong&gt; to users, and when do we navigate them to a separate, new page? And does it matter at all?&lt;/p&gt;&lt;p&gt;Actually, it does. The decision influences users’ flow, their context, their ability to look up details, and with it &lt;strong&gt;error frequency and task completion&lt;/strong&gt;. Both options can be disruptive and frustrating — at the wrong time, and at the wrong place.&lt;/p&gt;&lt;p&gt;So we’d better get it right. Well, let’s see how to do just that.&lt;/p&gt;&lt;h2 id="modals-vs-dialogs-vs-overlays-vs-lightboxes"&gt;Modals vs. Dialogs vs. Overlays vs. Lightboxes&lt;/h2&gt;&lt;p&gt;While
 we often speak about a single modal UI component, we often ignore fine,
 intricate nuances between all the different types of modals. In fact, &lt;strong&gt;not every modal is the same&lt;/strong&gt;. Modals, dialogs, overlays, and lightboxes — all sound similar, but they are actually quite different:&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://www.nngroup.com/articles/popups/"&gt;&lt;img alt="A 2x2 grid illustrating four types of dialog boxes: nonlightbox modal, nonlightbox nonmodal, lightbox modal, and lightbox nonmodal. Each shows a modal window on a browser interface." height="573" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/modal-separate-page-ux-decision-tree/2-modal-nonmodal-lightbox-nonlightbox-dialog-boxes.jpg" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Understanding modal vs. nonmodal and lightbox vs. nonlightbox dialog boxes for good UX. (Image source: &lt;a href="https://www.nngroup.com/articles/popups/"&gt;Popups by NN/g&lt;/a&gt;)&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Dialog&lt;/strong&gt;&lt;br /&gt;A generic term for “conversation” (user ↔ system).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Overlay&lt;/strong&gt;&lt;br /&gt;A small content panel displayed on top of a page.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Modal&lt;/strong&gt;&lt;br /&gt;User must interact with overlay + background &lt;strong&gt;disabled&lt;/strong&gt;.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Nonmodal&lt;/strong&gt;&lt;br /&gt;User must interact with overlay + background &lt;strong&gt;enabled&lt;/strong&gt;.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Lightbox&lt;/strong&gt;&lt;br /&gt;Dimmed background to focus attention on the modal.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;As Anna Kaley &lt;a href="https://www.nngroup.com/articles/popups/"&gt;highlights&lt;/a&gt;,
 most overlays appear at the wrong time, interrupt users during critical
 tasks, use poor language, and break users’ flow. They are &lt;strong&gt;interruptive by nature&lt;/strong&gt;, and typically with a high level of severity without a strong need for that.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://miro.medium.com/v2/1*wUxWMpp5GXXvg2fHhQWoWQ.jpeg"&gt;&lt;img alt="A diagram categorizing overlay types into modal and non-modal components, with examples like dialogs, navigation drawers, snackbars, and tooltips." height="385" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/modal-separate-page-ux-decision-tree/3-overlay-types-modal-non-modal-components.jpg" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;The many sides of modals and overlays. A little tree to understand the differences for UI components. (Image source: &lt;a href="https://uxplanet.org/modal-vs-page-a-decision-making-framework-34453e911129"&gt;Ryan Neufeld&lt;/a&gt;) (&lt;a href="https://files.smashing.media/articles/modal-separate-page-ux-decision-tree/3-overlay-types-modal-non-modal-components.jpg"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Surely users &lt;em&gt;must&lt;/em&gt; be slowed down and interrupted if the consequences of their action have a high impact, but for most scenarios &lt;strong&gt;non-modals are much more subtle&lt;/strong&gt; and a more friendly option to bring something to the user’s attention. If anything, I always suggest it to be a &lt;strong&gt;default&lt;/strong&gt;.&lt;/p&gt;&lt;h2 id="modals-for-single-self-contained-tasks"&gt;Modals → For Single, Self-Contained Tasks&lt;/h2&gt;&lt;p&gt;As designers, we often dismiss modals as irrelevant and annoying — &lt;em&gt;and often they are!&lt;/em&gt; — yet they have their value as well. They can be very helpful to &lt;strong&gt;warn users about potential mistakes&lt;/strong&gt;
 or help them avoid data loss. They can also help perform related 
actions or drill down into details without interrupting the current 
state of the page.&lt;/p&gt;&lt;p&gt;But the biggest advantage of modals is that they help users &lt;strong&gt;keep the context&lt;/strong&gt;
 of the current screen. It doesn’t mean just the UI, but also edited 
input, scrolling position, state of accordions, selection of filters, 
sorting, and so on.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/modal-separate-page-ux-decision-tree/4-nonmodal.png"&gt;&lt;img alt="Equity filters panel showing categories and a modal interface to set intraday price change conditions." height="526" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/modal-separate-page-ux-decision-tree/4-nonmodal.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Nonmodal in action: large and small overlays for filters and a modal for customization work well on &lt;a href="https://finance.yahoo.com/markets/stocks/most-active/"&gt;Yahoo! Finance&lt;/a&gt;. (&lt;a href="https://files.smashing.media/articles/modal-separate-page-ux-decision-tree/4-nonmodal.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;At times, users need to &lt;strong&gt;confirm a selection quickly&lt;/strong&gt;
 (e.g., filters as shown above) and then proceed immediately from there.
 Auto-save can achieve the same, of course, but it’s not always needed 
or desired. And blocking the UI is often not a good idea.&lt;/p&gt;&lt;p&gt;However, modals aren’t used for any tasks. Typically, we use them for &lt;strong&gt;single, self-contained tasks&lt;/strong&gt;
 where users should jump in, complete a task, and then return to where 
they were. Unsurprisingly, they do work well for high-priority, short 
interactions (e.g., alerts, destructive actions, quick confirmations).&lt;/p&gt;&lt;p&gt;&lt;strong&gt;When modals help&lt;/strong&gt;:&lt;/p&gt;&lt;p&gt;&#128683; Modals are often disruptive, invasive, and confusing.&lt;br /&gt;&#128683; They make it difficult to compare and copy-paste.&lt;br /&gt;✅ Yet modals allow users to maintain multiple contexts.&lt;br /&gt;✅ Useful to prevent irreversible errors and data loss.&lt;br /&gt;✅ Useful if sending users to a new page would be disruptive.&lt;/p&gt;&lt;p&gt;✅ Show a modal only if users will value the disruption.&lt;br /&gt;✅ By default, prefer non-blocking dialogs (“nonmodals”).&lt;br /&gt;✅ Allow users to minimize, hide, or restore the dialog later.&lt;br /&gt;✅ Use a modal to slow users down, e.g., verify complex input.&lt;br /&gt;✅ Give a way out with “Close”, ESC key, or click outside the box.&lt;/p&gt;&lt;h2 id="pages-for-complex-multi-step-workflows"&gt;Pages → For Complex, Multi-Step Workflows&lt;/h2&gt;&lt;p&gt;Wizards or &lt;strong&gt;tabbed navigation within modals&lt;/strong&gt;
 doesn’t work too well, even in complex enterprise products — there, 
side panels or drawers typically work better. Troubles start when users 
need to compare or reference data points — yet modals block this 
behavior, so they re-open the same page in multiple tabs instead.&lt;/p&gt;&lt;figure&gt;&lt;a href="https://files.smashing.media/articles/modal-separate-page-ux-decision-tree/5-modal.jpg"&gt;&lt;img alt="A modal with the text saying ‘We use too many damn modals. Let us just not’." height="735" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/modal-separate-page-ux-decision-tree/5-modal.jpg" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Perhaps, we use &lt;a href="https://modalzmodalzmodalz.com"&gt;Too Many Modals&lt;/a&gt;. A not-very-modal-friendly project by Adrian Egger.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;For more complex flows and multi-step processes, &lt;strong&gt;standalone pages work best&lt;/strong&gt;.
 Pages also work better when they demand the user’s full attention, and 
reference to the previous screen isn’t very helpful. And drawers work 
for sub-tasks that are too complex for a simple modal, but don’t need a 
full page navigation.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;When to avoid modals&lt;/strong&gt;:&lt;/p&gt;&lt;p&gt;&#128683; Avoid modals for &lt;strong&gt;error messages&lt;/strong&gt;.&lt;br /&gt;&#128683; Avoid modals for &lt;strong&gt;feature notifications&lt;/strong&gt;.&lt;br /&gt;&#128683; Avoid modals for &lt;strong&gt;onboarding experience&lt;/strong&gt;.&lt;br /&gt;&#128683; Avoid modals for complex, &lt;strong&gt;lengthy multi-step-tasks&lt;/strong&gt;.&lt;br /&gt;&#128683; Avoid &lt;strong&gt;multiple nested modals&lt;/strong&gt; and use prev/next instead.&lt;br /&gt;&#128683; Avoid &lt;strong&gt;auto-triggered modals&lt;/strong&gt; unless absolutely necessary.&lt;/p&gt;&lt;h2 id="avoid-both-for-repeated-tasks"&gt;Avoid Both For Repeated Tasks&lt;/h2&gt;&lt;p&gt;In
 many complex, task-heavy products, users will find themselves 
performing the same tasks repeatedly, over and over again. There, &lt;strong&gt;both modals and new page navigations add friction&lt;/strong&gt; because they interrupt the flow or force users to gather missing data between all the different tabs or views.&lt;/p&gt;&lt;p&gt;Too
 often, users end up with a broken experience, full of never-ending 
confirmations, exaggerated warnings, verbose instructions, or just 
missing reference points. As &lt;a href="https://www.linkedin.com/feed/update/urn:li:activity:7417845782365560832/?dashCommentUrn=urn%3Ali%3Afsd_comment%3A%287417848602338902016%2Curn%3Ali%3Aactivity%3A7417845782365560832%29"&gt;Saulius Stebulis mentioned&lt;/a&gt;, in these scenarios, &lt;strong&gt;expandable sections&lt;/strong&gt; or &lt;strong&gt;in-place editing&lt;/strong&gt; often work better — they keep the task anchored to the current screen.&lt;/p&gt;&lt;p&gt;In
 practice, in many scenarios, users don’t complete their tasks in 
isolation. They need to look up data, copy-paste values, refine entries 
in different places, or just review similar records as they work through
 their tasks.&lt;/p&gt;&lt;p&gt;Overlays and drawers are more helpful in maintaining
 access to background data during the task. As a result, the context 
always stays in its place, available for reference or copy-paste. Save 
modals and page navigation for moments where the interruption genuinely 
adds value — especially to prevent critical mistakes.&lt;/p&gt;&lt;h2 id="modals-vs-pages-a-decision-tree"&gt;Modals vs. Pages: A Decision Tree&lt;/h2&gt;&lt;p&gt;A while back, Ryan Neufeld put together a &lt;a href="https://uxplanet.org/modal-vs-page-a-decision-making-framework-34453e911129"&gt;very helpful guide&lt;/a&gt; to help designers &lt;strong&gt;choose between modals and pages&lt;/strong&gt;. It comes with a handy &lt;a href="https://miro.medium.com/v2/1*JQSGKbw1_iv5b85xYyNL-Q.png"&gt;PNG cheatsheet&lt;/a&gt; and a &lt;a href="https://docs.google.com/spreadsheets/d/1fZhXsV-IFWM0ZuMLLc8gG1BXqeQxFkCoYvSJt0gl2II/edit?gid=150659778#gid=150659778"&gt;Google Doc template&lt;/a&gt; with questions broken down across 7 sections.&lt;/p&gt;&lt;p&gt;It’s lengthy, extremely thorough, but very easy to follow:&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/modal-separate-page-ux-decision-tree/6-decision-tree-diagram-ui-design.png"&gt;&lt;img alt="A decision tree diagram for UI design, asking questions to determine whether to use a Page, Non-Modal Component, Dialog, or Sheet Nav Drawer." height="2402" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/modal-separate-page-ux-decision-tree/6-decision-tree-diagram-ui-design.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;A
 flowchart to choose between page vs. modal, with the page being the 
default, and modals reserved for interruption and focus. Put together by
 wonderful &lt;a href="https://uxplanet.org/modal-vs-page-a-decision-making-framework-34453e911129"&gt;Ryan Neufeld&lt;/a&gt;.&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;It might look daunting, but it’s a quite simple &lt;strong&gt;4-step process&lt;/strong&gt;:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Context of the screen&lt;/strong&gt;.&lt;br /&gt;First, we check if users need to maintain the context of the underlying screen.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Task complexity and duration&lt;/strong&gt;.&lt;br /&gt;Simpler, focused, non-distracting tasks could use a modal, but long, complex flows need a page.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Reference to underlying page&lt;/strong&gt;.&lt;br /&gt;Then, we check if users often need to refer to data in the background or if the task is a simple confirmation or selection.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Choosing the right overlay&lt;/strong&gt;.&lt;br /&gt;Finally, if an overlay is indeed a good option, it guides us to choose between modal or nonmodal (leaning towards a nonmodal).&lt;/li&gt;&lt;/ol&gt;&lt;h2 id="wrapping-up"&gt;Wrapping Up&lt;/h2&gt;&lt;p&gt;Whenever
 possible, avoid blocking the entire UI. Have a dialog floating, 
partially covering the UI, but allowing navigation, scrolling, and 
copy-pasting. Or show the contents of the modal as a side drawer. Or use
 a vertical accordion instead. Or bring users to a separate page if you 
need to show a lot of detail.&lt;/p&gt;&lt;p&gt;But if you want to boost users’ efficiency and speed, &lt;strong&gt;avoid modals at all costs&lt;/strong&gt;. Use them to slow users down, to bundle their attention, to prevent mistakes. As &lt;a href="https://www.nngroup.com/articles/modal-nonmodal-dialog/"&gt;Therese Fessenden noted&lt;/a&gt;, no one likes to be interrupted, but if you must, make sure it’s absolutely worth the cost.&lt;/p&gt;&lt;h2 id="meet-smart-interface-design-patterns"&gt;Meet “Smart Interface Design Patterns”&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/03/modal-separate-page-ux-decision-tree/#meet-smart-interface-design-patterns"&gt;#&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;You can find a &lt;strong&gt;whole section about modals&lt;/strong&gt; and alternatives in &lt;a href="https://smart-interface-design-patterns.com/"&gt;&lt;strong&gt;Smart Interface Design Patterns&lt;/strong&gt;&lt;/a&gt;, our &lt;strong&gt;15h-video course&lt;/strong&gt;
 with 100s of practical examples from real-life projects — with a live 
UX training later this year. Everything from mega-dropdowns to complex 
enterprise tables — with 5 new segments added every year. &lt;a href="https://www.youtube.com/watch?v=jhZ3el3n-u0"&gt;Jump to a free preview&lt;/a&gt;. Use code &lt;a href="https://smart-interface-design-patterns.com"&gt;&lt;strong&gt;BIRDIE&lt;/strong&gt;&lt;/a&gt; to &lt;strong&gt;save 15%&lt;/strong&gt; off.&lt;/p&gt;&lt;figure style="margin-bottom: 0;"&gt;&lt;br /&gt;&lt;/figure&gt;&lt;div class="book-cta__inverted"&gt;&lt;div class="book-cta" data-handler="ContentTabs" data-mq="(max-width: 480px)"&gt;&lt;div class="book-cta__col book-cta__hardcover content-tab--content"&gt;&lt;h3 class="book-cta__title"&gt;&lt;span&gt;Video + UX Training&lt;/span&gt;&lt;/h3&gt;&lt;span class="book-cta__price"&gt;&lt;span&gt;&lt;span&gt;&lt;span class="currency-sign"&gt;$&lt;/span&gt;&amp;nbsp;&lt;span&gt;579&lt;sup class="sup"&gt;.00&lt;/sup&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class="book-cta__price--old"&gt;&lt;span class="currency-sign"&gt;$&lt;/span&gt;&amp;nbsp;&lt;span&gt;699&lt;sup class="sup"&gt;.00&lt;/sup&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;a class="btn btn--full btn--medium btn--text-shadow" href="https://smart-interface-design-patterns.thinkific.com/enroll/1645405?price_id=2163032"&gt;Get Video + UX Training&lt;div&gt;&lt;/div&gt;&lt;/a&gt;&lt;p class="book-cta__desc"&gt;25 video lessons (15h) + &lt;a href="https://smashingconf.com/online-workshops/workshops/vitaly-friedman-impact-design/"&gt;Live UX Training&lt;/a&gt;.&lt;br /&gt;100 days money-back-guarantee.&lt;/p&gt;&lt;/div&gt;&lt;div class="book-cta__col book-cta__ebook content-tab--content"&gt;&lt;h3 class="book-cta__title"&gt;&lt;span&gt;Video only&lt;/span&gt;&lt;/h3&gt;&lt;div data-audience="anonymous free supporter" data-remove="true"&gt;&lt;span class="book-cta__price" data-handler="PriceTag"&gt;&lt;span&gt;&lt;span&gt;&lt;span class="currency-sign"&gt;$&lt;/span&gt;&amp;nbsp;&lt;span&gt;275&lt;sup class="sup"&gt;.00&lt;/sup&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="book-cta__price--old"&gt;&lt;span class="currency-sign"&gt;$&lt;/span&gt;&amp;nbsp;&lt;span&gt;350&lt;sup class="sup"&gt;.00&lt;/sup&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;a class="btn btn--full btn--medium btn--text-shadow" href="https://smart-interface-design-patterns.thinkific.com/enroll/1645405?et=paid"&gt;Get the video course&lt;div&gt;&lt;/div&gt;&lt;/a&gt;&lt;p class="book-cta__desc" data-audience="anonymous free supporter" data-remove="true"&gt;40 video lessons (15h). Updated yearly.&lt;br /&gt;Also available as a &lt;a href="https://smart-interface-design-patterns.thinkific.com/enroll/3082557?price_id=3951421"&gt;UX Bundle with 2 video courses.&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="useful-resources"&gt;Useful Resources&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://www.nngroup.com/articles/popups/"&gt;Different Types of Popups&lt;/a&gt;, by Anna Kaley&lt;/li&gt;&lt;li&gt;&lt;a href="https://app.uxcel.com/courses/ui-components-n-patterns/modals--dialogs-best-practices-166"&gt;Best Practices for Designing UI Modals&lt;/a&gt;, by Uxcel&lt;/li&gt;&lt;li&gt;&lt;a href="https://modalzmodalzmodalz.com/"&gt;We Use Too Many Damn Modals: UX Guidelines&lt;/a&gt;, by Adrian Egger&lt;/li&gt;&lt;li&gt;&lt;a href="https://www.nngroup.com/articles/modal-nonmodal-dialog/"&gt;Modal &amp;amp; Nonmodal Dialogs&lt;/a&gt;, by Therese Fessenden&lt;/li&gt;&lt;li&gt;&lt;a href="https://medium.com/pulsar/modern-enterprise-ui-design-part-2-modal-dialogs-2ccd3cc33c92"&gt;Modern Enterprise UI Design: Modal Dialogs&lt;/a&gt;, by James Jacobs&lt;/li&gt;&lt;li&gt;&lt;a href="https://designsystems.surf/components/modal"&gt;Modals in Design Systems&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</description><link>http://honeyvig.blogspot.com/2026/04/modal-vs-separate-page-ux-decision-tree.html</link><author>noreply@blogger.com (H)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9165069509664255576.post-5790225869387696179</guid><pubDate>Fri, 03 Apr 2026 09:38:00 +0000</pubDate><atom:updated>2026-04-03T05:18:05.920-07:00</atom:updated><title>Anime vs. Marvel/DC: Designing Digital Products With Emotion In Flow</title><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="c-garfield-summary"&gt;&lt;section aria-label="Quick summary" class="article__summary"&gt;Design
 is about pacing and feelings as much as pixels and patterns. Alan Cohen
 explores Emotion in Flow and Emotion in Conflict, showing how anime 
like Dan Da Dan and superhero films like James Gunn’s Superman manage 
emotional shifts and translating those ideas into practical patterns for
 product design.&lt;/section&gt;&lt;/div&gt;&lt;p&gt;Design isn’t only pixels and 
patterns. It’s pacing and feelings, too. Some products feel cinematic as
 they guide us through uncertainty, relief, confidence, and calm without
 yanking us around. That’s &lt;b&gt;Emotion in Flow&lt;/b&gt;. Others undercut their own moments with a joke in the wrong place, a surprise pop-up, or a jumpy transition. That’s &lt;b&gt;Emotion in Conflict&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;These
 aren’t UX-only ideas. You can see them everywhere in entertainment. And
 the clearest way to feel the difference is to compare how &lt;b&gt;anime&lt;/b&gt; handles emotional shifts versus how &lt;b&gt;Marvel and DC films&lt;/b&gt; stumble. We’ll use two specific examples, one from &lt;i&gt;Dan da Dan&lt;/i&gt; (anime series on Netflix) and one from James Gunn’s &lt;i&gt;Superman&lt;/i&gt; movie, to define the two concepts, and then translate them into practical product design patterns you can apply right away.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Note&lt;/b&gt;: &lt;i&gt;We’ll focus on&lt;/i&gt; &lt;b&gt;&lt;i&gt;digital products&lt;/i&gt;&lt;/b&gt;, &lt;i&gt;including apps, SaaS, and web.&lt;/i&gt;&lt;/p&gt;&lt;h2 id="emotion-in-flow-anime-dan-da-dan"&gt;Emotion In Flow (Anime: Dan da Dan)&lt;/h2&gt;&lt;p&gt;In &lt;i&gt;Dan da Dan&lt;/i&gt;, the tonal range is wild, horror, comedy, tenderness, yet it &lt;b&gt;flows&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;Example:
 In one arc, the protagonists are on a bizarre, comedic quest involving 
the “golden genitals” of one of the main characters (yes, really), and 
in another, we’re drawn into a heartbreaking story of a mother whose 
child is kidnapped. On paper, that shift should be a car crash. On 
screen, it’s coherent and emotionally legible.&lt;/p&gt;&lt;p&gt;Why does this work on screen?&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Continuity of stakes.&lt;/b&gt;&lt;br /&gt;Even
 when a gag lands, the characters’ goals and danger stay intact. Humor 
releases tension after a mini‑resolution; it doesn’t deny the threat.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Clear mood cues.&lt;/b&gt;&lt;br /&gt;Music,
 framing, pacing, and character reactions telegraph the next feeling. 
You’re primed for the shift, so you ride it rather than getting yanked.&lt;/li&gt;&lt;li&gt;&lt;b&gt;One emotional anchor.&lt;/b&gt;&lt;br /&gt;Relationships remain the North Star, so the scene’s heart doesn’t get lost when the tone moves.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;b&gt;How does this translate to UX?&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Good products do the same:&amp;nbsp;&lt;b&gt;prepare&lt;/b&gt;, &lt;b&gt;transition&lt;/b&gt;, &lt;b&gt;resolve&lt;/b&gt;,&amp;nbsp;so users stay immersed as the emotional tone shifts.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/anime-marvel-dc-designing-digital-products-emotion-flow/1-dan-da-dan.jpg"&gt;&lt;img alt="Dan da Dan from humor to empathy flawlessly." height="483" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/anime-marvel-dc-designing-digital-products-emotion-flow/1-dan-da-dan.jpg" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Dan da Dan: from humor to empathy, flawlessly.&lt;/figcaption&gt;&lt;/figure&gt;&lt;h2 id="emotion-in-conflict-marvel-dc-james-gunn-s-superman"&gt;Emotion In Conflict (Marvel/DC: James Gunn’s Superman)&amp;nbsp;&lt;/h2&gt;&lt;p&gt;Lois
 &amp;amp; Clark are having a heartfelt, intimate conversation, a slow, 
human moment, while in the background a running gag plays out (a monster
 getting clobbered with a giant baseball bat). The gag steals the focus 
right when the scene asks you to feel something real. The result is a 
tonal clash that punctures the emotion instead of releasing it.&lt;/p&gt;&lt;p&gt;Why does this fail on screen?&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Increased cognitive load.&lt;/b&gt;&lt;br /&gt;What’s
 happening here maps directly to cognitive load theory. When a scene (or
 interface) asks users to process two competing emotional signals at 
once, it introduces &lt;i&gt;extraneous cognitive load&lt;/i&gt;, mental effort 
that has nothing to do with the task or moment itself. Instead of 
focusing on the emotional beat, attention is split between signals that 
don’t resolve each other. In products, this is what happens when humor, 
promotions, or unexpected UI changes intrude on high-stakes moments: 
users are forced to interpret tone and intent at the same time they’re 
trying to act, which slows comprehension and increases stress.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Competing beats at the same time.&lt;/b&gt;&lt;br /&gt;The joke overlaps the climax of a serious beat; the audience pays attention to the switch rather than the feeling.&lt;/li&gt;&lt;li&gt;&lt;b&gt;No tonal handoff.&lt;/b&gt;&lt;br /&gt;There’s no transition that lands the intimacy before humor arrives, so the moment feels undercut rather than resolved.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;b&gt;How does this translate to UX?&lt;/b&gt;&lt;/p&gt;&lt;p&gt;In
 products, this is the confetti-before-confirmation problem, the cheeky 
error in a money flow, or the promo modal that appears right in the 
middle of a critical task. This also spikes cognitive load: users must 
process the humor while trying to fix a problem, which slows them down 
and increases stress.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/anime-marvel-dc-designing-digital-products-emotion-flow/2-superman.jpg"&gt;&lt;img alt="Heartfelt conversation disrupted by background gag in James Gunn’s Superman." height="409" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/anime-marvel-dc-designing-digital-products-emotion-flow/2-superman.jpg" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Heartfelt conversation disrupted by background gag in James Gunn’s Superman.&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;h2 id="quick-definitions"&gt;Quick Definitions&amp;nbsp;&lt;/h2&gt;&lt;blockquote&gt;&lt;b&gt;Emotion in Flow&lt;/b&gt;&lt;br /&gt;Emotional shifts feel earned, telegraphed, and timed so they resolve prior beats. Immersion holds.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Emotion in Conflict&lt;/b&gt;&lt;br /&gt;A jarring switch (or hard cut) that punctures a live emotional beat. Immersion breaks.&lt;/blockquote&gt;&lt;p&gt;Now that we’ve named it: how does this connect to UX?&lt;/p&gt;&lt;h2 id="how-emotions-shape-product-memorability"&gt;How Emotions Shape Product Memorability&amp;nbsp;&lt;/h2&gt;&lt;p&gt;People
 don’t remember the average of an experience; they remember peaks and 
the ending. If your flow’s peak is frustration, or your ending is messy,
 that’s what sticks. So design the emotional curve on purpose.&lt;/p&gt;&lt;p&gt;Emotions live across three layers (from &lt;a href="https://www.academia.edu/27771503/Emotional_Design_Donald_Norman"&gt;Don Norman’s Emotional Design&lt;/a&gt;), and your product needs to line them up:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Visceral (gut):&lt;/b&gt; First-impression signals: visuals, motion, haptics, sound.&lt;br /&gt;&lt;i&gt;Examples:&lt;/i&gt;
 A steady skeleton loader calms more than a jittery spinner; a gentle 
success chime/haptic tap lets the win land without shouting; consistent 
easing/direction tells the eye what changed.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Behavioral (doing):&lt;/b&gt; Can I complete my task smoothly? Friction here means stress.&lt;br /&gt;&lt;i&gt;Examples:&lt;/i&gt;
 Three clear payment steps with predictable progress; error states that 
explain what happened and how to recover; inline validation instead of 
end-of-form explosions.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Reflective (meaning):&lt;/b&gt; The story I tell myself after, &lt;i&gt;“Was that worth it? Do I trust this?”&lt;/i&gt;&lt;br /&gt;&lt;i&gt;Examples:&lt;/i&gt;
 A tidy wrap-up screen (“Done. You’ll get X by Friday.”) gives closure; a
 small recap (“You saved €18 this year”) creates pride without 
fireworks.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;a href="https://www.nngroup.com/articles/microinteractions/#toc-what-are-microinteractions-1"&gt;Microinteractions&lt;/a&gt;
 are the emotional glue. Each one has a trigger (I tap Pay), rules (what
 the system does), feedback (progress and a clear result), and loops or 
modes (what happens if the user tries again). Get these right, and your 
transitions bridge feelings. Get them wrong, and they break the flow.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/anime-marvel-dc-designing-digital-products-emotion-flow/3-emotional-beat-curve.jpg"&gt;&lt;img alt="The beat sheet: uncertainty → clarity → anticipation → achievement → calm." height="441" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/anime-marvel-dc-designing-digital-products-emotion-flow/3-emotional-beat-curve.jpg" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;The beat sheet: uncertainty → clarity → anticipation → achievement → calm.&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;The emotional beat sheet maps cleanly onto Norman’s layers of experience:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Uncertainty&lt;/b&gt; lives in the &lt;b&gt;visceral&lt;/b&gt; and early &lt;b&gt;behavioral&lt;/b&gt; layers, where users rely on sensory cues (motion, clarity, feedback) to understand what’s happening.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Clarity&lt;/b&gt; is firmly in the &lt;b&gt;behavioral&lt;/b&gt; layer, the moment when the system’s intent and the user’s next action lock into place.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Anticipation&lt;/b&gt; is a blend of &lt;b&gt;behavioral&lt;/b&gt; (the user is doing something with purpose) and &lt;b&gt;reflective&lt;/b&gt; (the user is already predicting the outcome and imagining what comes next).&lt;/li&gt;&lt;li&gt;&lt;b&gt;Achievement&lt;/b&gt; is a &lt;b&gt;reflective peak&lt;/b&gt;, where the user evaluates success, trust, and whether the experience “felt right.”&lt;/li&gt;&lt;li&gt;&lt;b&gt;Calm/Closure&lt;/b&gt; is primarily &lt;b&gt;reflective&lt;/b&gt;, helping users wrap up the meaning of the interaction and decide if the product is trustworthy and worth returning to.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;In
 real products, this sequence doesn’t disappear when things go wrong. 
Errors, latency, and degraded states are not exceptions to the emotional
 arc — they are part of it. Seen through a narrative lens, these moments
 are the obstacles in the hero’s journey. A well-designed recovery state
 acknowledges the setback, clarifies what happened, and guides the next 
step without introducing new emotional noise. When failure is treated as
 a beat instead of a rupture, emotional flow can be preserved even under
 stress.&lt;/p&gt;&lt;h2 id="ux-examples-emotion-in-flow-vs-emotion-in-conflict"&gt;UX Examples: Emotion In Flow vs. Emotion In Conflict&lt;/h2&gt;&lt;h3 id="emotion-in-flow"&gt;Emotion In Flow&lt;/h3&gt;&lt;p&gt;Checkout
 done right (Stripe/Apple Pay style): short steps, clear progress, and a
 crisp success state (a checkmark with an optional soft haptic). The 
peak (success) lands, and the end gives closure (receipt or next step).&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/anime-marvel-dc-designing-digital-products-emotion-flow/4-emotion-in-flow.jpg"&gt;&lt;img alt="Two screens: Review &amp;amp; Pay → Payment Successful." height="483" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/anime-marvel-dc-designing-digital-products-emotion-flow/4-emotion-in-flow.jpg" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Two screens: Review &amp;amp; Pay → Payment Successful.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Pickup
 status (ride‑hailing apps, e.g., Uber, Free Now, or Bolt): progressive 
updates maintain orientation and reduce anxiety (“Driver arriving”, “2 
min away”, “Arrived”). Uncertainty turns into clarity, with gentle 
motion preparing each transition.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/anime-marvel-dc-designing-digital-products-emotion-flow/5-emotion-in-flow-uber.jpg"&gt;&lt;img alt="Pickup status from the Uber app" height="450" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/anime-marvel-dc-designing-digital-products-emotion-flow/5-emotion-in-flow-uber.jpg" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Pickup status from the Uber app.&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="emotion-in-conflict"&gt;Emotion In Conflict&amp;nbsp;&lt;/h3&gt;&lt;p&gt;&lt;b&gt;Note&lt;/b&gt;: &lt;i&gt;We’re
 not naming specific products here — we respect the work behind them. 
Instead, we’re showing the patterns that cause emotional conflict and 
exactly how to fix them.&lt;/i&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Jokes in serious moments.&lt;/b&gt;&lt;br /&gt;Cheeky copy-in-error states for money/health/security. Users are stressed; humor amplifies irritation.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Celebration before resolution.&lt;/b&gt;&lt;br /&gt;Confetti, fireworks, or loud sounds before confirmation. The party interrupts the climax.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Hard state jumps.&lt;/b&gt;&lt;br /&gt;Surprise modals/promos mid‑task, full‑screen takeovers without preparation. Feels like an abrupt cut during an emotional beat.&lt;/li&gt;&lt;/ul&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/anime-marvel-dc-designing-digital-products-emotion-flow/6-emotion-in-conflict.jpg"&gt;&lt;img alt="Examples of Emotion in Conflict in product design" height="483" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/anime-marvel-dc-designing-digital-products-emotion-flow/6-emotion-in-conflict.jpg" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Examples
 of Emotion in Conflict in product design: joking tone in a high-stakes 
error, premature celebration before confirmation, surprise promo 
takeover mid-checkout. All three break the emotional arc and disrupt 
user trust.&lt;/figcaption&gt;&lt;/figure&gt;&lt;h2 id="what-you-can-do-to-ensure-emotion-in-flow"&gt;What You Can Do To Ensure Emotion in Flow&lt;/h2&gt;&lt;p&gt;Here’s a Notion page with the full template you can duplicate:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://ludicrous-maraca-88d.notion.site/Emotional-Beat-Sheet-Template-2b9b9dbc8bf080dc8c63c77c42c66242?source=copy_link"&gt;Emotional beat sheet template&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;h3 id="1-write-the-emotional-beat-sheet-first"&gt;1. Write The Emotional Beat Sheet First&lt;/h3&gt;&lt;p&gt;For
 each core flow (onboarding, payment, recovery), map the feelings per 
step: uncertainty → clarity → anticipation → achievement → calm. Attach 
copy, motion, and microinteractions to each beat. (Who carries the 
emotion where?)&lt;/p&gt;&lt;h3 id="2-align-tone-with-task-risk"&gt;2. Align Tone With Task Risk&lt;/h3&gt;&lt;p&gt;Create
 a tone matrix (risk level × state). In high‑risk errors, be calm, 
plain, and solution‑oriented. Save playfulness for low‑risk contexts.&lt;/p&gt;&lt;p&gt;Template snippets:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;High‑risk error&lt;/b&gt;: “We couldn’t verify your ID. Try again or contact support.”&lt;/li&gt;&lt;li&gt;&lt;b&gt;Low‑risk empty state&lt;/b&gt;: “Nothing here yet. Want to start with a sample?”&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This
 is where many mature products quietly drift into emotional conflict. 
Over time, teams add delight by habit rather than intent.&lt;/p&gt;&lt;p&gt;A useful
 self-check is to ask: If we removed every playful or celebratory 
element from this step, would the flow still feel humane — or were those
 elements masking friction?&lt;/p&gt;&lt;blockquote class="pull-quote"&gt;&lt;p&gt;&lt;a aria-label="Share on Twitter" class="pull-quote__link" href="https://twitter.com/share?text=%0aGood%20emotional%20design%20clarifies%20experience;%20great%20emotional%20design%20doesn%e2%80%99t%20need%20decoration%20to%20compensate%20for%20confusion.%0a&amp;amp;url=https://smashingmagazine.com%2f2026%2f03%2fanime-marvel-dc-designing-digital-products-emotion-flow%2f"&gt;Good emotional design clarifies experience; great emotional design doesn’t need decoration to compensate for confusion.&lt;/a&gt;&lt;/p&gt;&lt;div class="pull-quote__quotation"&gt;&lt;div class="pull-quote__bg"&gt;&lt;span class="pull-quote__symbol"&gt;“&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;h3 id="3-design-peak-and-end-on-purpose"&gt;3. Design Peak And End On Purpose&lt;/h3&gt;&lt;p&gt;Engineer
 one clear peak (the moment of success) and one clean end (confirmation 
and what happens next). Measure recall and satisfaction at both points.&lt;/p&gt;&lt;h3 id="4-use-microinteractions-as-bridges-not-spotlights"&gt;4. Use Microinteractions As Bridges, Not Spotlights&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Prepare: Small, consistent motion hints before a big state change.&lt;/li&gt;&lt;li&gt;Confirm: Success gets a subtle settle, with a slightly slower ease-out and an optional light haptic.&lt;/li&gt;&lt;li&gt;Recover: Repeated failure gracefully shifts tone from upbeat to supportive and guides the next step.&lt;/li&gt;&lt;/ul&gt;&lt;h3 id="5-test-for-emotional-continuity"&gt;5. Test For Emotional Continuity&lt;/h3&gt;&lt;p&gt;In usability sessions, don’t just ask &lt;i&gt;“Was that easy?”&lt;/i&gt; Instead, you can ask &lt;i&gt;“What feeling changed here?”&lt;/i&gt; If you hear “confused → amused → confused,” you’ve got conflict, not flow. Iterate transitions, not just screens.&lt;/p&gt;&lt;h2 id="how-to-avoid-emotion-in-conflict-fast-checklist"&gt;How To Avoid Emotion in Conflict: Fast Checklist&lt;/h2&gt;&lt;p&gt;Red flags → fixes:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Jokes in serious moments → swap for calm, direct language, and a clear recovery path.&lt;/li&gt;&lt;li&gt;Celebration before resolution → move celebration to after confirmation; tone it down for high‑risk tasks.&lt;/li&gt;&lt;li&gt;Hard state jumps → pre‑announce transitions; keep framing consistent; use meaningful motion to preserve continuity.&lt;/li&gt;&lt;li&gt;Cross‑team tone drift → centralize voice &amp;amp; tone guidelines with examples per risk level and state.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;There
 are moments when breaking emotional flow is intentional and necessary. 
Security warnings, legal confirmations, and safety-critical alerts often
 benefit from abrupt tonal shifts. In these cases, disruption signals 
importance and demands attention. The problem isn’t emotional conflict 
itself; it’s &lt;b&gt;accidental conflict&lt;/b&gt;. When designers choose disruption deliberately, users understand the stakes instead of feeling whiplash.&lt;/p&gt;&lt;h2 id="conclusion"&gt;Conclusion&amp;nbsp;&lt;/h2&gt;&lt;p&gt;&lt;b&gt;Great experiences are directed experiences.&lt;/b&gt;
 Dan da Dan shows how to move through feelings without losing us: it 
prepares, transitions, and resolves. The Superman scene shows the 
opposite: a gag colliding with a heartfelt beat.&lt;/p&gt;&lt;p&gt;Do the former. 
Map your emotional beats, align tone to task risk, and let 
microinteractions bridge feelings so users remember the right peak and 
the right end, not the whiplash in the middle.&lt;/p&gt;</description><link>http://honeyvig.blogspot.com/2026/04/anime-vs-marveldc-designing-digital.html</link><author>noreply@blogger.com (H)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9165069509664255576.post-4093200822973202532</guid><pubDate>Fri, 03 Apr 2026 09:34:36 +0000</pubDate><atom:updated>2026-04-03T02:34:36.891-07:00</atom:updated><title>20 AI Concepts Everyone Should Understand — Let's Start With 5</title><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p class="ember-view reader-text-block__paragraph" id="ember62"&gt;
      I will be honest with you. A few months ago, I kept hearing words like&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;i&gt;tokens&lt;/i&gt;,&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;i&gt;embeddings&lt;/i&gt;,&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;i&gt;attention mechanisms&lt;/i&gt;&lt;span class="white-space-pre"&gt; &lt;/span&gt;and nodding along like I fully got it. I didn't.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember63"&gt;
      So I did what any curious person does. I went deep. I started 
studying AI architecture, how these systems actually work from the 
backend, and how all these buzzwords connect.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember64"&gt;
      What I found was actually fascinating and way more approachable than I expected. So I am turning it into a series. "&lt;b&gt;20 AI concepts", explained simply.&lt;/b&gt;&lt;span class="white-space-pre"&gt; &lt;/span&gt;
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember65"&gt;
      Here are the first five.
    &lt;/p&gt;

  






            
        
    &lt;h3 class="ember-view reader-text-block__heading-3" id="ember66"&gt;
      1. Large Language Models (LLMs)
    &lt;/h3&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember67"&gt;
      Think of an LLM as a system that has read an almost 
incomprehensible amount of text: books, articles, code, conversations 
and learned the patterns of how language works.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember68"&gt;
      It doesn't store facts like a database. It learns&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;i&gt;how language flows&lt;/i&gt;&lt;span class="white-space-pre"&gt; &lt;/span&gt;and
 uses that to predict what comes next. That's why it can answer 
questions, summarise documents, write code, and hold a conversation. 
It's not retrieving answers. It's constructing them, word by word, based
 on patterns it's internalised. Wild when you think about it.
    &lt;/p&gt;

  






            
        
    &lt;h3 class="ember-view reader-text-block__heading-3" id="ember69"&gt;
      2. Tokenisation
    &lt;/h3&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember70"&gt;
      Before any of that can happen, the model needs to convert your 
words into something a computer can actually work with. That's 
tokenisation: breaking text into smaller chunks called tokens.&lt;span class="white-space-pre"&gt; &lt;/span&gt;
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember71"&gt;
      &lt;i&gt;"AI is transforming industries"&lt;/i&gt;&lt;span class="white-space-pre"&gt; &lt;/span&gt;might become:
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember72"&gt;
      &lt;b&gt;AI | is | transform | ing | industries&lt;/b&gt;
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember73"&gt;
      Sometimes it breaks at word boundaries. Sometimes mid-word. Each 
token then gets converted into a number, because at the end of the day, 
models are doing math, not reading.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember74"&gt;
      This is why token limits matter when you are working with AI 
tools. The model isn't reading your whole document the way you do. It's 
processing a sequence of numbered chunks.
    &lt;/p&gt;

  






            
        
    &lt;h3 class="ember-view reader-text-block__heading-3" id="ember75"&gt;
      3. Vectors (Embeddings)
    &lt;/h3&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember76"&gt;
      Here's where it gets interesting. Once you have tokens, the model 
converts them into vectors - lists of numbers that represent meaning, 
not just the word itself.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember77"&gt;
      The cool part? Words with similar meanings end up mathematically close to each other in this numerical space.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember78"&gt;
      &lt;i&gt;Dog&lt;/i&gt;&lt;span class="white-space-pre"&gt; &lt;/span&gt;is close to&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;i&gt;cat&lt;/i&gt;.&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;i&gt;Doctor&lt;/i&gt;&lt;span class="white-space-pre"&gt; &lt;/span&gt;is close to&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;i&gt;nurse&lt;/i&gt;.&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;i&gt;Car&lt;/i&gt;&lt;span class="white-space-pre"&gt; &lt;/span&gt;is close to&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;i&gt;vehicle&lt;/i&gt;.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember79"&gt;
      This is how AI can do semantic search - finding things that&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;i&gt;mean&lt;/i&gt;&lt;span class="white-space-pre"&gt; &lt;/span&gt;the
 same thing, even if the exact words don't match. It's also the 
foundation of tools like vector databases and RAG systems, which we will
 get to later in this series.
    &lt;/p&gt;

  






            
        
    &lt;h3 class="ember-view reader-text-block__heading-3" id="ember80"&gt;
      4. The Attention Mechanism
    &lt;/h3&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember81"&gt;
      This one is one of my favourite concepts. Take this sentence:&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;i&gt;"The dog chased the ball because it was fast."&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;/i&gt;What does&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;i&gt;"it"&lt;/i&gt;&lt;span class="white-space-pre"&gt; &lt;/span&gt;refer to? The dog or the ball?
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember82"&gt;
      You figured it out instantly. But for a model processing 
individual tokens, that's actually a hard problem. The attention 
mechanism solves this. It allows the model to look across the entire 
sentence (or paragraph, or document) and figure out which words are most
 relevant to understanding each other.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember83"&gt;
      It's why modern AI doesn't just process text left-to-right like older systems did. It understands&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;i&gt;relationships&lt;/i&gt;&lt;span class="white-space-pre"&gt; &lt;/span&gt;between words, even across long distances in a passage.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember84"&gt;
      The 2017 paper&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;i&gt;"Attention is All You Need"&lt;/i&gt;&lt;span class="white-space-pre"&gt; &lt;/span&gt;(link:&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;a class="xNiwzWHrbebvVdTPhrqFFMLPZAeEoaSrfNgM" data-test-app-aware-link="" href="https://en.wikipedia.org/wiki/Attention_Is_All_You_Need" tabindex="0" target="_self"&gt;https://en.wikipedia.org/wiki/Attention_Is_All_You_Need&lt;/a&gt;&lt;span class="white-space-pre"&gt; &lt;/span&gt;) introduced this as part of the Transformer architecture. Pretty much every major AI model today is built on that foundation.
    &lt;/p&gt;

  






            
        
    &lt;h3 class="ember-view reader-text-block__heading-3" id="ember85"&gt;
      5. Self-Supervised Learning
    &lt;/h3&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember86"&gt;
      Here's something that always blew my mind a little. Training a 
model used to require humans to label massive amounts of data manually.&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;i&gt;This image is a cat. This email is spam. This review is positive.&lt;/i&gt;
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember87"&gt;
      Self-supervised learning flips that. The model trains itself by predicting missing or upcoming words in text.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember88"&gt;
      Fill in the blank:&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;i&gt;"The capital of France is ____."&lt;/i&gt;
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember89"&gt;
      Do that billions of times across billions of sentences, and the 
model starts to pick up grammar, facts, reasoning, even nuance - without
 anyone manually labelling anything. It's a beautifully simple idea that
 unlocks an almost unlimited amount of training data.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember90"&gt;
      All of these concepts are the foundation of everything - 
conversational AI, enterprise copilots, semantic search, AI agents, and 
autonomous workflows.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember91"&gt;
      When you understand how the building blocks work, the more complex stuff starts to make a lot more sense.
    &lt;/p&gt;

  






            
        
    &lt;h3 class="ember-view reader-text-block__heading-3" id="ember92"&gt;
      What's Coming Next?
    &lt;/h3&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember93"&gt;
      This is Part 1 of a 20-concept AI series. My goal is simple - to 
make this stuff genuinely understandable for anyone working in or around
 technology today.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember94"&gt;
      If you're on this learning journey too, follow along. Part 2 is coming soon.
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember95"&gt;
      &lt;i&gt;What AI concept has confused you the most? Drop it in the 
comments — I might just cover it in the series. Let's exchange concepts 
and ideas.&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;/i&gt;
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember96"&gt;
      &lt;i&gt;#AIconcepts #LLM #vectordatabase #tokenisation #attention 
#supervisedlearning #machinelearning #poc #aiprojects 
#commercialprojects&lt;/i&gt;&lt;/p&gt;</description><link>http://honeyvig.blogspot.com/2026/04/20-ai-concepts-everyone-should.html</link><author>noreply@blogger.com (H)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9165069509664255576.post-7920144991931519400</guid><pubDate>Fri, 03 Apr 2026 09:34:35 +0000</pubDate><atom:updated>2026-04-03T02:34:35.427-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">AI&lt;ML</category><category domain="http://www.blogger.com/atom/ns#">Data Science</category><category domain="http://www.blogger.com/atom/ns#">human resource</category><title>Using AI to Predict Intrinsic Motivation to Excel</title><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="reader-article-content reader-article-content--content-blocks" dir="ltr"&gt;
          

      &lt;div class="reader-content-blocks-container"&gt;

            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember60"&gt;We're looking for some of Simon Sinek's early adopters (these are 
the people on the left side of the curve above) to determine if our new 
customized ChatGPT -&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;a class="saMVTQfWvPIcSlFvHFFmSeylOlrDMFEgYhDQqc" data-test-app-aware-link="" href="https://hiring.tips/PbHGPT_Survey" tabindex="0" target="_self"&gt;PbHGPT&lt;/a&gt;&lt;span class="white-space-pre"&gt; &lt;/span&gt;- can solve these pervasive hiring problems:&lt;span class="white-space-pre"&gt; &lt;/span&gt;
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember61"&gt;
            &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Using the interview to predict "n" and why it's 
the make or break predictor of on-the-job success (FYI, n = level of 
intrinsic motivation to do the actual work in the actual environment. 
This is almost impossible to do without AI.)&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Dealing 
with hiring managers who focus too much on skills and experience, rather
 than a person's ability, performance, ''n" and potential.&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Bias of all sorts whether it's before, during or after the interview.&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Helping job seekers prepare for an interview and prove they possess enough "n" to do the job.&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Convincing a strong candidate that your offer represents the best career move even without the biggest compensation package.&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;

    &lt;p&gt;&lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember62"&gt;
      It turns out, at least according to Sinek, that if PbHGPT solves 
most of these problems, the late adopters on the right side of the 
adoption curve will agree to follow the process. That's why early 
adopters and "&lt;a class="saMVTQfWvPIcSlFvHFFmSeylOlrDMFEgYhDQqc" data-test-app-aware-link="" href="https://hiring.tips/Moneyball_signup" tabindex="0" target="_self"&gt;Moneyball for HR!&lt;/a&gt;"
 are needed to prove it works with data analytics. Predicting "n" is the
 most important part of this, since it's often overlooked in the 
interview or assessed incorrectly.&lt;span class="white-space-pre"&gt; &lt;/span&gt;
    &lt;/p&gt;

  






            
        
    &lt;h3 class="ember-view reader-text-block__heading-3" id="ember63"&gt;
      PbHGPT Provides Real Time Advice to Prevent Problems
    &lt;/h3&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember64"&gt;
      Another critical aspect of this&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;a class="saMVTQfWvPIcSlFvHFFmSeylOlrDMFEgYhDQqc" data-test-app-aware-link="" href="https://hiring.tips/PbHGPT_Survey" tabindex="0" target="_self"&gt;Performance-based Hiring GPT&lt;/a&gt;&lt;span class="white-space-pre"&gt; &lt;/span&gt;is
 that it's been designed to offer instant advice on how to achieve all 
of the above exactly when you need it. This is how you prevent problems 
before they occur.&lt;span class="white-space-pre"&gt; &lt;/span&gt;
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember65"&gt;
      For example, imagine you're interviewing a candidate and ask for 
advice on how to measure "n" or if the candidate can handle a tough 
technical or business problem and you get an immediate answer. Or, you 
could upload the candidate's resume and ask PbHGPT to create a custom 
interview guide and talent scorecard the moment before the candidate 
joins your Zoom call. You could even upload a transcript of the 
interview to determine if the candidate is a good fit for the role or if
 you conducted an accurate and bias-free interview.&lt;span class="white-space-pre"&gt; &lt;/span&gt;
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember66"&gt;
      &lt;b&gt;You can even measure Quality of Hire.&lt;/b&gt;
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember67"&gt;
      Wow!&lt;span class="white-space-pre"&gt; &lt;/span&gt;
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember68"&gt;
      To determine if Performance-based Hiring GPT successfully solves 
these types of problems we'd like you to try it out and give us your 
feedback.&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;a class="saMVTQfWvPIcSlFvHFFmSeylOlrDMFEgYhDQqc" data-test-app-aware-link="" href="https://hiring.tips/PbHGPT_Survey" tabindex="0" target="_self"&gt;The link to the GPT is in this survey&lt;/a&gt;. Since the link changes every 72 hours, or so, you might need to&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;a class="saMVTQfWvPIcSlFvHFFmSeylOlrDMFEgYhDQqc" data-test-app-aware-link="" href="https://hiring.tips/PbHGPT_demo" tabindex="0" target="_self"&gt;request the latest link&lt;/a&gt;&lt;span class="white-space-pre"&gt; &lt;/span&gt;if you get an error message.&lt;span class="white-space-pre"&gt; &lt;/span&gt;
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember69"&gt;
      To get started be sure to use the prompts shown here starting with, "&lt;a class="saMVTQfWvPIcSlFvHFFmSeylOlrDMFEgYhDQqc" data-test-app-aware-link="" href="https://hiring.tips/PbHGPT_n" tabindex="0" target="_self"&gt;&lt;i&gt;What's "n," why is it so important and how can it be assessed during the interview?&lt;/i&gt;&lt;/a&gt;&lt;b&gt;&lt;i&gt;"&lt;/i&gt;&lt;/b&gt;
    &lt;/p&gt;

  






            
        
    &lt;h3 class="ember-view reader-text-block__heading-3" id="ember70"&gt;
      Put PbHGPT Through the Wringer with These Prompts
    &lt;/h3&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember71"&gt;
            &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Please describe the Hiring Formula for Success 
and the importance of "n" in the formula. Is this formula really 
groundbreaking or is it just basic interview ideas repackaged with a 
fancy name?&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;How could this GPT address hiring manager 
concerns when interviewing a candidate who can do the work but who has a
 different mix of skills and experiences than on the job description?&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Sometimes
 the best people aren't the best interviewers, and they get excluded 
from consideration for these reasons. How can this GPT help address this
 issue?&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;List the top 10 ways this GPT eliminates bias.&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;I’m
 a candidate for a job and want to be sure I’m assessed properly. How 
can this GPT help me get ready. More important, what do I need to do 
prove that I possess "n" in great measure?&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;

    &lt;p&gt;&lt;/p&gt;

  






            
        
    &lt;h3 class="ember-view reader-text-block__heading-3" id="ember72"&gt;
      Early Adopters Are the Real Agents of Change
    &lt;/h3&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember73"&gt;
      Last year I worked with LinkedIn Learning to publish a new course -&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;a class="saMVTQfWvPIcSlFvHFFmSeylOlrDMFEgYhDQqc" data-test-app-aware-link="" href="https://hiring.tips/LIL_HRChange" tabindex="0" target="_self"&gt;&lt;i&gt;Change Management for HR&lt;/i&gt;&lt;/a&gt;&lt;span class="white-space-pre"&gt; &lt;/span&gt;- which describes Simon Sinek's&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;i&gt;Theory of Diffusion&lt;/i&gt;&lt;span class="white-space-pre"&gt; &lt;/span&gt;as
 model for implementing change. I asked PbHGPT how this process could be
 used for validating its effectiveness and why Early Adopters are always
 the drivers of major change. Here's what it said.&lt;span class="white-space-pre"&gt; &lt;/span&gt;
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember74"&gt;
      &lt;i&gt;According to Simon Sinek’s application of&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;/i&gt;&lt;b&gt;&lt;i&gt;Diffusion of Innovation&lt;/i&gt;&lt;/b&gt;&lt;i&gt;,
 "Early Adopters" are individuals or groups that are the first to adopt 
new ideas, products, or innovations. They are typically risk-tolerant 
and enthusiastic about experimenting with new approaches before the 
majority. They provide valuable feedback and validation, influencing 
later adopters by demonstrating the benefits of innovation.&lt;/i&gt;
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember75"&gt;
      &lt;b&gt;&lt;i&gt;Early adopters are critical&lt;/i&gt;&lt;/b&gt;&lt;i&gt;&lt;span class="white-space-pre"&gt; &lt;/span&gt;for validating that this GPT improves hiring results because they help&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;/i&gt;&lt;b&gt;&lt;i&gt;demonstrate the tool's effectiveness in real-world applications&lt;/i&gt;&lt;/b&gt;&lt;i&gt;.
 Their feedback helps refine the system, identifying strengths and 
weaknesses early. They also influence the broader organization, making 
it easier to scale the GPT's adoption to more traditional users, who 
might be more cautious about adopting new technology. By showing 
measurable improvements in key hiring metrics such as&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;/i&gt;&lt;b&gt;&lt;i&gt;quality of hire, time-to-fill&lt;/i&gt;&lt;/b&gt;&lt;i&gt;, or&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;/i&gt;&lt;b&gt;&lt;i&gt;candidate experience&lt;/i&gt;&lt;/b&gt;&lt;i&gt;, early adopters create credibility for the tool's impact.&lt;/i&gt;
    &lt;/p&gt;

  






            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember76"&gt;
      &lt;a class="saMVTQfWvPIcSlFvHFFmSeylOlrDMFEgYhDQqc" data-test-app-aware-link="" href="https://hiring.tips/PbHGPT_Survey" tabindex="0" target="_self"&gt;If this describes you, let's begin proving it starting with calculating your own "n."&lt;/a&gt;
    &lt;/p&gt;

  










            
  &lt;hr class="reader-divider-block__horizontal-rule" /&gt;



            
        
    &lt;p class="ember-view reader-text-block__paragraph" id="ember77"&gt;
      We recognize that some Performance-based Hiring training is required to get the most value from PbHGPT.&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;a class="saMVTQfWvPIcSlFvHFFmSeylOlrDMFEgYhDQqc" data-test-app-aware-link="" href="https://hiring.tips/HMT_Immersion" tabindex="0" target="_self"&gt;Our two-part full immersion program&lt;/a&gt;&lt;span class="white-space-pre"&gt; &lt;/span&gt;is a good way to get started. For those who want to become expert users, coaches or trainers we suggest&lt;span class="white-space-pre"&gt; &lt;/span&gt;&lt;a class="saMVTQfWvPIcSlFvHFFmSeylOlrDMFEgYhDQqc" data-test-app-aware-link="" href="https://hiring.tips/PBHR_new3" tabindex="0" target="_self"&gt;our complete Performance-based Hiring workshop&lt;/a&gt;.&lt;span class="white-space-pre"&gt; &lt;/span&gt;
    &lt;/p&gt;

  






      &lt;/div&gt;
  
      &lt;/div&gt;</description><link>http://honeyvig.blogspot.com/2026/04/using-ai-to-predict-intrinsic.html</link><author>noreply@blogger.com (H)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9165069509664255576.post-4827023658047559401</guid><pubDate>Thu, 02 Apr 2026 14:30:00 +0000</pubDate><atom:updated>2026-04-02T07:30:00.119-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Coding</category><category domain="http://www.blogger.com/atom/ns#">javascript</category><category domain="http://www.blogger.com/atom/ns#">React</category><title>Building Dynamic Forms In React And Next.js</title><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="c-garfield-summary"&gt;&lt;section aria-label="Quick summary" class="article__summary"&gt;Some
 forms stay UI, while others quietly become rule engines. Here’s why 
these two different approaches exist and how to choose between them.&lt;/section&gt;&lt;/div&gt;&lt;div class="sponsor-panel c-felix-the-cat"&gt;&lt;p class="sponsor-panel-content"&gt;This article has been kindly supported by our dear friends at &lt;a href="https://surveyjs.io/"&gt;SurveyJS&lt;/a&gt;,
 JavaScript UI libraries for custom web forms. Keep full ownership of 
your data. Build JSON-driven forms in your app (React/Angular/Vue) 
without SaaS limitations. &lt;em&gt;Thank you!&lt;/em&gt;&lt;/p&gt;&lt;a class="sponsor-panel-image" href="https://surveyjs.io/"&gt;&lt;img alt="SurveyJS" src="https://files.smashing.media/articles/building-dynamic-forms-react-next-js/surveyjs-logo.svg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;There’s a mental model most React developers share without ever discussing it out loud. That forms are &lt;em&gt;always&lt;/em&gt; supposed to be components. This means a stack like:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;React Hook Form&lt;/strong&gt; for local state (minimal re-renders, ergonomic field registration, imperative interaction).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Zod&lt;/strong&gt; for validation (input correctness, boundary validation, type-safe parsing).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;React Query&lt;/strong&gt; for backend: submission, retries, caching, server sync, and so on.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;And
 for the vast majority of forms — your login screens, your settings 
pages, your CRUD modals — this works really well. Each piece does its 
job, they compose cleanly, and you can move on to the parts of your 
application that actually differentiate your product.&lt;/p&gt;&lt;p&gt;But every 
once in a while, a form starts accumulating things like visibility rules
 that depend on earlier answers, or derived values that cascade through 
three fields. Maybe even entire pages that should be skipped or shown 
based on a running total.&lt;/p&gt;&lt;p&gt;You handle the first conditional with a &lt;code&gt;useWatch&lt;/code&gt; and an inline branch, which is fine. Then another. &lt;a href="https://zod.dev/api#superrefine"&gt;Then you’re reaching for &lt;code&gt;superRefine&lt;/code&gt;&lt;/a&gt;
 to encode cross-field rules that your Zod schema can’t express in the 
normal way. Then, step navigation starts leaking business logic. At some
 point, you look at what you’ve built and realize that the form isn’t 
really UI anymore. It’s more of a decision process, and the component 
tree is just where you happened to store it.&lt;/p&gt;&lt;p&gt;This is where I think
 the mental model for forms in React breaks down, and it’s really 
nobody’s fault. The RHF + Zod stack is excellent at what it was designed
 for. &lt;strong&gt;The issue is that we tend to keep using it past the point where its abstractions match the problem&lt;/strong&gt; because the alternative requires a different way of thinking about forms entirely.&lt;/p&gt;&lt;p&gt;This article is about that alternative. To show this, we’ll build the exact same multi-step form twice:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;With React Hook Form + Zod wired to React Query for submission,&lt;/li&gt;&lt;li&gt;With SurveyJS, which treats a form as data — a simple JSON schema — rather than a component tree.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Same
 requirements, same conditional logic, same API call at the end. Then 
we’ll map exactly what moved and what stayed, and lay out a practical 
way to decide which model you should use, and when.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The form we’re building:&lt;/strong&gt;&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/building-dynamic-forms-react-next-js/1-dynamic-form.png"&gt;&lt;img alt="Multi-step dynamic form" height="798" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/building-dynamic-forms-react-next-js/1-dynamic-form.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;&lt;br /&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;This form will use a 4-step flow:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Step 1: Details&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;First name (required),&lt;/li&gt;&lt;li&gt;Email (required, valid format).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Step 2: Order&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Unit price,&lt;/li&gt;&lt;li&gt;Quantity,&lt;/li&gt;&lt;li&gt;Tax rate,&lt;/li&gt;&lt;li&gt;Derived:&lt;ul&gt;&lt;li&gt;Subtotal,&lt;/li&gt;&lt;li&gt;Tax,&lt;/li&gt;&lt;li&gt;Total.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Step 3: Account &amp;amp; Feedback&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Do you have an account? (Yes/No)&lt;ul&gt;&lt;li&gt;If Yes → username + password, both required.&lt;/li&gt;&lt;li&gt;If No → email already collected in step 1.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Satisfaction rating (1–5)&lt;ul&gt;&lt;li&gt;If ≥ 4 → ask “What did you like?”&lt;/li&gt;&lt;li&gt;If ≤ 2 → ask “What can we improve?”&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Step 4: Review&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Only appears if &lt;code&gt;total &amp;gt;= 100&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Final submission.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This is not extreme. But it’s enough to expose architectural differences.&lt;/p&gt;&lt;h2 id="part-1-component-driven-react-hook-form-zod"&gt;Part 1: Component-Driven (React Hook Form + Zod)&lt;/h2&gt;&lt;h3 id="installation"&gt;Installation&lt;/h3&gt;&lt;div class="code-toolbar"&gt;&lt;pre class="  language-bash"&gt;&lt;code class="  language-bash"&gt;&lt;span class="token function"&gt;npm&lt;/span&gt; &lt;span class="token function"&gt;install&lt;/span&gt; react-hook-form zod @hookform/resolvers @tanstack/react-query
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id="zod-schema"&gt;Zod Schema&lt;/h3&gt;&lt;p&gt;Let’s
 start with the Zod schema, because that’s usually where the shape of 
the form gets established. For the first two steps — personal details 
and order inputs — everything is straightforward: required strings, 
numbers with minimums, and an enum. The interesting part starts when you
 try to express the conditional rules.&lt;/p&gt;&lt;div class="break-out"&gt;&lt;div class="code-toolbar"&gt;&lt;pre class="  language-typescript"&gt;&lt;code class="  language-typescript"&gt;&lt;span class="token keyword"&gt;import&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt; z &lt;span class="token punctuation"&gt;}&lt;/span&gt; &lt;span class="token keyword"&gt;from&lt;/span&gt; &lt;span class="token string"&gt;"zod"&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

&lt;span class="token keyword"&gt;export&lt;/span&gt; &lt;span class="token keyword"&gt;const&lt;/span&gt; formSchema &lt;span class="token operator"&gt;=&lt;/span&gt; z&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;object&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt;  
  firstName&lt;span class="token operator"&gt;:&lt;/span&gt; z&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;string&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;min&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token number"&gt;1&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token string"&gt;"Required"&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
  email&lt;span class="token operator"&gt;:&lt;/span&gt; z&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;string&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;email&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;"Invalid email"&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
  price&lt;span class="token operator"&gt;:&lt;/span&gt; z&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;number&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;min&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token number"&gt;0&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
  quantity&lt;span class="token operator"&gt;:&lt;/span&gt; z&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;number&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;min&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token number"&gt;1&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
  taxRate&lt;span class="token operator"&gt;:&lt;/span&gt; z&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;number&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
  hasAccount&lt;span class="token operator"&gt;:&lt;/span&gt; z&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token keyword"&gt;enum&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;[&lt;/span&gt;&lt;span class="token string"&gt;"Yes"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token string"&gt;"No"&lt;/span&gt;&lt;span class="token punctuation"&gt;]&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
  username&lt;span class="token operator"&gt;:&lt;/span&gt; z&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;string&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;optional&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
  password&lt;span class="token operator"&gt;:&lt;/span&gt; z&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;string&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;optional&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
  satisfaction&lt;span class="token operator"&gt;:&lt;/span&gt; z&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;number&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;min&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token number"&gt;1&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;max&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token number"&gt;5&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
  positiveFeedback&lt;span class="token operator"&gt;:&lt;/span&gt; z&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;string&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;optional&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
  improvementFeedback&lt;span class="token operator"&gt;:&lt;/span&gt; z&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;string&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;optional&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
&lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;superRefine&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;data&lt;span class="token punctuation"&gt;,&lt;/span&gt; ctx&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token operator"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
  &lt;span class="token keyword"&gt;if&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;data&lt;span class="token punctuation"&gt;.&lt;/span&gt;hasAccount &lt;span class="token operator"&gt;===&lt;/span&gt; &lt;span class="token string"&gt;"Yes"&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
    &lt;span class="token keyword"&gt;if&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token operator"&gt;!&lt;/span&gt;data&lt;span class="token punctuation"&gt;.&lt;/span&gt;username&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
      ctx&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;addIssue&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt; code&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"custom"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; path&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token punctuation"&gt;[&lt;/span&gt;&lt;span class="token string"&gt;"username"&lt;/span&gt;&lt;span class="token punctuation"&gt;]&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; message&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"Required"&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;  
    &lt;span class="token keyword"&gt;if&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token operator"&gt;!&lt;/span&gt;data&lt;span class="token punctuation"&gt;.&lt;/span&gt;password &lt;span class="token operator"&gt;||&lt;/span&gt; data&lt;span class="token punctuation"&gt;.&lt;/span&gt;password&lt;span class="token punctuation"&gt;.&lt;/span&gt;length &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt; &lt;span class="token number"&gt;6&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
      ctx&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;addIssue&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt; code&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"custom"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; path&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token punctuation"&gt;[&lt;/span&gt;&lt;span class="token string"&gt;"password"&lt;/span&gt;&lt;span class="token punctuation"&gt;]&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; message&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"Min 6 characters"&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;  
  &lt;span class="token punctuation"&gt;}&lt;/span&gt;

  &lt;span class="token keyword"&gt;if&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;data&lt;span class="token punctuation"&gt;.&lt;/span&gt;satisfaction &lt;span class="token operator"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="token number"&gt;4&lt;/span&gt; &lt;span class="token operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="token operator"&gt;!&lt;/span&gt;data&lt;span class="token punctuation"&gt;.&lt;/span&gt;positiveFeedback&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
    ctx&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;addIssue&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt; code&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"custom"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; path&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token punctuation"&gt;[&lt;/span&gt;&lt;span class="token string"&gt;"positiveFeedback"&lt;/span&gt;&lt;span class="token punctuation"&gt;]&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; message&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"Please share what you liked"&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  
  &lt;span class="token punctuation"&gt;}&lt;/span&gt;

  &lt;span class="token keyword"&gt;if&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;data&lt;span class="token punctuation"&gt;.&lt;/span&gt;satisfaction &lt;span class="token operator"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="token number"&gt;2&lt;/span&gt; &lt;span class="token operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="token operator"&gt;!&lt;/span&gt;data&lt;span class="token punctuation"&gt;.&lt;/span&gt;improvementFeedback&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
    ctx&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;addIssue&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt; code&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"custom"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; path&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token punctuation"&gt;[&lt;/span&gt;&lt;span class="token string"&gt;"improvementFeedback"&lt;/span&gt;&lt;span class="token punctuation"&gt;]&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; message&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"Please tell us what to improve"&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  
  &lt;span class="token punctuation"&gt;}&lt;/span&gt;  
&lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

&lt;span class="token keyword"&gt;export&lt;/span&gt; &lt;span class="token keyword"&gt;type&lt;/span&gt; &lt;span class="token class-name"&gt;FormData&lt;/span&gt; &lt;span class="token operator"&gt;=&lt;/span&gt; z&lt;span class="token punctuation"&gt;.&lt;/span&gt;infer&lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token keyword"&gt;typeof&lt;/span&gt; formSchema&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Notice that &lt;code&gt;username&lt;/code&gt; and &lt;code&gt;password&lt;/code&gt; are typed as &lt;code&gt;optional()&lt;/code&gt; even though they’re conditionally required because Zod’s type-level schema describes the &lt;em&gt;shape&lt;/em&gt; of the object, not the rules governing when fields matter.&lt;/p&gt;&lt;p&gt;The conditional requirement has to live inside &lt;code&gt;superRefine&lt;/code&gt;,
 which runs after the shape is validated and has access to the full 
object. That separation is not a flaw; it’s just what the tool is 
designed for: &lt;code&gt;superRefine&lt;/code&gt; is where cross-field logic goes when it can’t be expressed in the schema structure itself.&lt;/p&gt;&lt;p&gt;What’s also notable here is what this schema &lt;em&gt;doesn’t&lt;/em&gt;
 express. It has no concept of pages, no concept of which fields are 
visible at which point, and no concept of navigation. All of that will 
live somewhere else.&lt;/p&gt;&lt;h3 id="form-component"&gt;Form Component&lt;/h3&gt;&lt;div class="break-out"&gt;&lt;div class="code-toolbar"&gt;&lt;pre class="  language-typescript"&gt;&lt;code class="  language-typescript"&gt;&lt;span class="token keyword"&gt;import&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt; useForm&lt;span class="token punctuation"&gt;,&lt;/span&gt; useWatch &lt;span class="token punctuation"&gt;}&lt;/span&gt; &lt;span class="token keyword"&gt;from&lt;/span&gt; &lt;span class="token string"&gt;"react-hook-form"&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  
&lt;span class="token keyword"&gt;import&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt; zodResolver &lt;span class="token punctuation"&gt;}&lt;/span&gt; &lt;span class="token keyword"&gt;from&lt;/span&gt; &lt;span class="token string"&gt;"@hookform/resolvers/zod"&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  
&lt;span class="token keyword"&gt;import&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt; useMutation &lt;span class="token punctuation"&gt;}&lt;/span&gt; &lt;span class="token keyword"&gt;from&lt;/span&gt; &lt;span class="token string"&gt;"@tanstack/react-query"&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  
&lt;span class="token keyword"&gt;import&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt; useState&lt;span class="token punctuation"&gt;,&lt;/span&gt; useMemo &lt;span class="token punctuation"&gt;}&lt;/span&gt; &lt;span class="token keyword"&gt;from&lt;/span&gt; &lt;span class="token string"&gt;"react"&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  
&lt;span class="token keyword"&gt;import&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt; formSchema&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token keyword"&gt;type&lt;/span&gt; &lt;span class="token class-name"&gt;FormData&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt; &lt;span class="token keyword"&gt;from&lt;/span&gt; &lt;span class="token string"&gt;"./schema"&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

&lt;span class="token keyword"&gt;const&lt;/span&gt; &lt;span class="token constant"&gt;STEPS&lt;/span&gt; &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token punctuation"&gt;[&lt;/span&gt;&lt;span class="token string"&gt;"details"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token string"&gt;"order"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token string"&gt;"account"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token string"&gt;"review"&lt;/span&gt;&lt;span class="token punctuation"&gt;]&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

&lt;span class="token keyword"&gt;type&lt;/span&gt; &lt;span class="token class-name"&gt;OrderPayload&lt;/span&gt; &lt;span class="token operator"&gt;=&lt;/span&gt; FormData &lt;span class="token operator"&gt;&amp;amp;&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt; subtotal&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token builtin"&gt;number&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt; tax&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token builtin"&gt;number&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt; total&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token builtin"&gt;number&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

&lt;span class="token keyword"&gt;export&lt;/span&gt; &lt;span class="token keyword"&gt;function&lt;/span&gt; &lt;span class="token function"&gt;RHFMultiStepForm&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
  &lt;span class="token keyword"&gt;const&lt;/span&gt; &lt;span class="token punctuation"&gt;[&lt;/span&gt;step&lt;span class="token punctuation"&gt;,&lt;/span&gt; setStep&lt;span class="token punctuation"&gt;]&lt;/span&gt; &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;useState&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token number"&gt;0&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

  &lt;span class="token keyword"&gt;const&lt;/span&gt; mutation &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;useMutation&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt;
    &lt;span class="token function-variable function"&gt;mutationFn&lt;/span&gt;&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token keyword"&gt;async&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;payload&lt;span class="token operator"&gt;:&lt;/span&gt; OrderPayload&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token operator"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
      &lt;span class="token keyword"&gt;const&lt;/span&gt; res &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token keyword"&gt;await&lt;/span&gt; &lt;span class="token function"&gt;fetch&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;"/api/orders"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
        method&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"POST"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
        headers&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt; &lt;span class="token string"&gt;"Content-Type"&lt;/span&gt;&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"application/json"&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
        body&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token constant"&gt;JSON&lt;/span&gt;&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;stringify&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;payload&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
      &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token keyword"&gt;if&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token operator"&gt;!&lt;/span&gt;res&lt;span class="token punctuation"&gt;.&lt;/span&gt;ok&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token keyword"&gt;throw&lt;/span&gt; &lt;span class="token keyword"&gt;new&lt;/span&gt; &lt;span class="token class-name"&gt;Error&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;"Failed to submit"&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token keyword"&gt;return&lt;/span&gt; res&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;json&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

  &lt;span class="token keyword"&gt;const&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
    register&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
    control&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
    handleSubmit&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
    formState&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt; errors &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
  &lt;span class="token punctuation"&gt;}&lt;/span&gt; &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token generic-function"&gt;&lt;span class="token function"&gt;useForm&lt;/span&gt;&lt;span class="token generic class-name"&gt;&lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;FormData&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt;  
    resolver&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token function"&gt;zodResolver&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;formSchema&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
    defaultValues&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
      price&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;0&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
      quantity&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;1&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
      taxRate&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;0.1&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
      satisfaction&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;3&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
      hasAccount&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"No"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
  &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  

  &lt;span class="token keyword"&gt;const&lt;/span&gt; price &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;useWatch&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt; control&lt;span class="token punctuation"&gt;,&lt;/span&gt; name&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"price"&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  
  &lt;span class="token keyword"&gt;const&lt;/span&gt; quantity &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;useWatch&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt; control&lt;span class="token punctuation"&gt;,&lt;/span&gt; name&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"quantity"&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  
  &lt;span class="token keyword"&gt;const&lt;/span&gt; taxRate &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;useWatch&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt; control&lt;span class="token punctuation"&gt;,&lt;/span&gt; name&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"taxRate"&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  
  &lt;span class="token keyword"&gt;const&lt;/span&gt; hasAccount &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;useWatch&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt; control&lt;span class="token punctuation"&gt;,&lt;/span&gt; name&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"hasAccount"&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  
  &lt;span class="token keyword"&gt;const&lt;/span&gt; satisfaction &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;useWatch&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt; control&lt;span class="token punctuation"&gt;,&lt;/span&gt; name&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"satisfaction"&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  

  &lt;span class="token keyword"&gt;const&lt;/span&gt; subtotal &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;useMemo&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token operator"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;price &lt;span class="token operator"&gt;??&lt;/span&gt; &lt;span class="token number"&gt;0&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token operator"&gt;*&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;quantity &lt;span class="token operator"&gt;??&lt;/span&gt; &lt;span class="token number"&gt;1&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token punctuation"&gt;[&lt;/span&gt;price&lt;span class="token punctuation"&gt;,&lt;/span&gt; quantity&lt;span class="token punctuation"&gt;]&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  
  &lt;span class="token keyword"&gt;const&lt;/span&gt; tax &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;useMemo&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token operator"&gt;=&amp;gt;&lt;/span&gt; subtotal &lt;span class="token operator"&gt;*&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;taxRate &lt;span class="token operator"&gt;??&lt;/span&gt; &lt;span class="token number"&gt;0&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token punctuation"&gt;[&lt;/span&gt;subtotal&lt;span class="token punctuation"&gt;,&lt;/span&gt; taxRate&lt;span class="token punctuation"&gt;]&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  
  &lt;span class="token keyword"&gt;const&lt;/span&gt; total &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;useMemo&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token operator"&gt;=&amp;gt;&lt;/span&gt; subtotal &lt;span class="token operator"&gt;+&lt;/span&gt; tax&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token punctuation"&gt;[&lt;/span&gt;subtotal&lt;span class="token punctuation"&gt;,&lt;/span&gt; tax&lt;span class="token punctuation"&gt;]&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  

  &lt;span class="token keyword"&gt;const&lt;/span&gt; &lt;span class="token function-variable function"&gt;onSubmit&lt;/span&gt; &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;data&lt;span class="token operator"&gt;:&lt;/span&gt; FormData&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token operator"&gt;=&amp;gt;&lt;/span&gt; mutation&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;mutate&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt; &lt;span class="token operator"&gt;...&lt;/span&gt;data&lt;span class="token punctuation"&gt;,&lt;/span&gt; subtotal&lt;span class="token punctuation"&gt;,&lt;/span&gt; tax&lt;span class="token punctuation"&gt;,&lt;/span&gt; total &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  

  &lt;span class="token keyword"&gt;const&lt;/span&gt; showSubmit &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;step &lt;span class="token operator"&gt;===&lt;/span&gt; &lt;span class="token number"&gt;2&lt;/span&gt; &lt;span class="token operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; total &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt; &lt;span class="token number"&gt;100&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token operator"&gt;||&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;step &lt;span class="token operator"&gt;===&lt;/span&gt; &lt;span class="token number"&gt;3&lt;/span&gt; &lt;span class="token operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; total &lt;span class="token operator"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="token number"&gt;100&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;

  &lt;span class="token keyword"&gt;return&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;  
    &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;form onSubmit&lt;span class="token operator"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt;&lt;span class="token function"&gt;handleSubmit&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;onSubmit&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
      &lt;span class="token punctuation"&gt;{&lt;/span&gt;step &lt;span class="token operator"&gt;===&lt;/span&gt; &lt;span class="token number"&gt;0&lt;/span&gt; &lt;span class="token operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;  
        &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
          &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;input &lt;span class="token punctuation"&gt;{&lt;/span&gt;&lt;span class="token operator"&gt;...&lt;/span&gt;&lt;span class="token function"&gt;register&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;"firstName"&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt; placeholder&lt;span class="token operator"&gt;=&lt;/span&gt;&lt;span class="token string"&gt;"First Name"&lt;/span&gt; &lt;span class="token operator"&gt;/&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
          &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;input &lt;span class="token punctuation"&gt;{&lt;/span&gt;&lt;span class="token operator"&gt;...&lt;/span&gt;&lt;span class="token function"&gt;register&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;"email"&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt; placeholder&lt;span class="token operator"&gt;=&lt;/span&gt;&lt;span class="token string"&gt;"Email"&lt;/span&gt; &lt;span class="token operator"&gt;/&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
        &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;/&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
      &lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt;

      &lt;span class="token punctuation"&gt;{&lt;/span&gt;step &lt;span class="token operator"&gt;===&lt;/span&gt; &lt;span class="token number"&gt;1&lt;/span&gt; &lt;span class="token operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;  
        &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
          &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;input &lt;span class="token keyword"&gt;type&lt;/span&gt;&lt;span class="token operator"&gt;=&lt;/span&gt;&lt;span class="token string"&gt;"number"&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;&lt;span class="token operator"&gt;...&lt;/span&gt;&lt;span class="token function"&gt;register&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;"price"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt; valueAsNumber&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token boolean"&gt;true&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt; &lt;span class="token operator"&gt;/&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
          &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;input &lt;span class="token keyword"&gt;type&lt;/span&gt;&lt;span class="token operator"&gt;=&lt;/span&gt;&lt;span class="token string"&gt;"number"&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;&lt;span class="token operator"&gt;...&lt;/span&gt;&lt;span class="token function"&gt;register&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;"quantity"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt; valueAsNumber&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token boolean"&gt;true&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt; &lt;span class="token operator"&gt;/&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
          &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;select &lt;span class="token punctuation"&gt;{&lt;/span&gt;&lt;span class="token operator"&gt;...&lt;/span&gt;&lt;span class="token function"&gt;register&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;"taxRate"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt; valueAsNumber&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token boolean"&gt;true&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
            &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;option value&lt;span class="token operator"&gt;=&lt;/span&gt;&lt;span class="token string"&gt;"0.05"&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="token number"&gt;5&lt;/span&gt;&lt;span class="token operator"&gt;%&lt;/span&gt;&lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;/&lt;/span&gt;option&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
            &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;option value&lt;span class="token operator"&gt;=&lt;/span&gt;&lt;span class="token string"&gt;"0.1"&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="token number"&gt;10&lt;/span&gt;&lt;span class="token operator"&gt;%&lt;/span&gt;&lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;/&lt;/span&gt;option&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
            &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;option value&lt;span class="token operator"&gt;=&lt;/span&gt;&lt;span class="token string"&gt;"0.15"&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="token number"&gt;15&lt;/span&gt;&lt;span class="token operator"&gt;%&lt;/span&gt;&lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;/&lt;/span&gt;option&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
          &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;/&lt;/span&gt;select&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;

          &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;div&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;Subtotal&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;subtotal&lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;/&lt;/span&gt;div&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
          &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;div&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;Tax&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;tax&lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;/&lt;/span&gt;div&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
          &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;div&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;Total&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;total&lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;/&lt;/span&gt;div&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
        &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;/&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
      &lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt;

      &lt;span class="token punctuation"&gt;{&lt;/span&gt;step &lt;span class="token operator"&gt;===&lt;/span&gt; &lt;span class="token number"&gt;2&lt;/span&gt; &lt;span class="token operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;  
        &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
          &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;select &lt;span class="token punctuation"&gt;{&lt;/span&gt;&lt;span class="token operator"&gt;...&lt;/span&gt;&lt;span class="token function"&gt;register&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;"hasAccount"&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
            &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;option value&lt;span class="token operator"&gt;=&lt;/span&gt;&lt;span class="token string"&gt;"Yes"&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;Yes&lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;/&lt;/span&gt;option&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
            &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;option value&lt;span class="token operator"&gt;=&lt;/span&gt;&lt;span class="token string"&gt;"No"&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;No&lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;/&lt;/span&gt;option&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
          &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;/&lt;/span&gt;select&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;

          &lt;span class="token punctuation"&gt;{&lt;/span&gt;hasAccount &lt;span class="token operator"&gt;===&lt;/span&gt; &lt;span class="token string"&gt;"Yes"&lt;/span&gt; &lt;span class="token operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;  
            &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
              &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;input &lt;span class="token punctuation"&gt;{&lt;/span&gt;&lt;span class="token operator"&gt;...&lt;/span&gt;&lt;span class="token function"&gt;register&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;"username"&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt; placeholder&lt;span class="token operator"&gt;=&lt;/span&gt;&lt;span class="token string"&gt;"Username"&lt;/span&gt; &lt;span class="token operator"&gt;/&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
              &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;input &lt;span class="token punctuation"&gt;{&lt;/span&gt;&lt;span class="token operator"&gt;...&lt;/span&gt;&lt;span class="token function"&gt;register&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;"password"&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt; placeholder&lt;span class="token operator"&gt;=&lt;/span&gt;&lt;span class="token string"&gt;"Password"&lt;/span&gt; &lt;span class="token operator"&gt;/&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
            &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;/&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
          &lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt;

          &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;input &lt;span class="token keyword"&gt;type&lt;/span&gt;&lt;span class="token operator"&gt;=&lt;/span&gt;&lt;span class="token string"&gt;"number"&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;&lt;span class="token operator"&gt;...&lt;/span&gt;&lt;span class="token function"&gt;register&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;"satisfaction"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt; valueAsNumber&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token boolean"&gt;true&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt; &lt;span class="token operator"&gt;/&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;

          &lt;span class="token punctuation"&gt;{&lt;/span&gt;satisfaction &lt;span class="token operator"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="token number"&gt;4&lt;/span&gt; &lt;span class="token operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;  
            &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;textarea &lt;span class="token punctuation"&gt;{&lt;/span&gt;&lt;span class="token operator"&gt;...&lt;/span&gt;&lt;span class="token function"&gt;register&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;"positiveFeedback"&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt; &lt;span class="token operator"&gt;/&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
          &lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt;

          &lt;span class="token punctuation"&gt;{&lt;/span&gt;satisfaction &lt;span class="token operator"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="token number"&gt;2&lt;/span&gt; &lt;span class="token operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;  
            &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;textarea &lt;span class="token punctuation"&gt;{&lt;/span&gt;&lt;span class="token operator"&gt;...&lt;/span&gt;&lt;span class="token function"&gt;register&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;"improvementFeedback"&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt; &lt;span class="token operator"&gt;/&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
          &lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt;  
        &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;/&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
      &lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt;

      &lt;span class="token punctuation"&gt;{&lt;/span&gt;step &lt;span class="token operator"&gt;===&lt;/span&gt; &lt;span class="token number"&gt;3&lt;/span&gt; &lt;span class="token operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; total &lt;span class="token operator"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="token number"&gt;100&lt;/span&gt; &lt;span class="token operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;div&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;Review and submit&lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;/&lt;/span&gt;div&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt;

      &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;div&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;{&lt;/span&gt;step &lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt; &lt;span class="token number"&gt;0&lt;/span&gt; &lt;span class="token operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;button &lt;span class="token keyword"&gt;type&lt;/span&gt;&lt;span class="token operator"&gt;=&lt;/span&gt;&lt;span class="token string"&gt;"button"&lt;/span&gt; onClick&lt;span class="token operator"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token operator"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="token function"&gt;setStep&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;step &lt;span class="token operator"&gt;-&lt;/span&gt; &lt;span class="token number"&gt;1&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;Back&lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;/&lt;/span&gt;button&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;{&lt;/span&gt;showSubmit &lt;span class="token operator"&gt;?&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;  
          &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;button &lt;span class="token keyword"&gt;type&lt;/span&gt;&lt;span class="token operator"&gt;=&lt;/span&gt;&lt;span class="token string"&gt;"submit"&lt;/span&gt; disabled&lt;span class="token operator"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt;mutation&lt;span class="token punctuation"&gt;.&lt;/span&gt;isPending&lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
            &lt;span class="token punctuation"&gt;{&lt;/span&gt;mutation&lt;span class="token punctuation"&gt;.&lt;/span&gt;isPending &lt;span class="token operator"&gt;?&lt;/span&gt; &lt;span class="token string"&gt;"Submitting…"&lt;/span&gt; &lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"Submit"&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt;  
          &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;/&lt;/span&gt;button&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token operator"&gt;:&lt;/span&gt; step &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt; &lt;span class="token constant"&gt;STEPS&lt;/span&gt;&lt;span class="token punctuation"&gt;.&lt;/span&gt;length &lt;span class="token operator"&gt;-&lt;/span&gt; &lt;span class="token number"&gt;1&lt;/span&gt; &lt;span class="token operator"&gt;?&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;  
          &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;button &lt;span class="token keyword"&gt;type&lt;/span&gt;&lt;span class="token operator"&gt;=&lt;/span&gt;&lt;span class="token string"&gt;"button"&lt;/span&gt; onClick&lt;span class="token operator"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token operator"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="token function"&gt;setStep&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;step &lt;span class="token operator"&gt;+&lt;/span&gt; &lt;span class="token number"&gt;1&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;Next&lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;/&lt;/span&gt;button&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token keyword"&gt;null&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt;  
      &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;/&lt;/span&gt;div&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
      &lt;span class="token punctuation"&gt;{&lt;/span&gt;mutation&lt;span class="token punctuation"&gt;.&lt;/span&gt;isError &lt;span class="token operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;div&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;Error&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;mutation&lt;span class="token punctuation"&gt;.&lt;/span&gt;error&lt;span class="token punctuation"&gt;.&lt;/span&gt;message&lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;/&lt;/span&gt;div&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt;  
    &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;/&lt;/span&gt;form&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
  &lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  
&lt;span class="token punctuation"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;figure class="break-out"&gt;&lt;div&gt;&lt;/div&gt;&lt;figcaption&gt;See the Pen &lt;a href="https://codepen.io/smashingmag/pen/gbwwmNO"&gt;SurveyJS-03-RHF [forked]&lt;/a&gt; by &lt;a href="https://codepen.io/sixthextinction"&gt;sixthextinction&lt;/a&gt;.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;There’s quite a lot happening here, and it’s worth slowing down to notice where things ended up.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The derived values — &lt;code&gt;subtotal&lt;/code&gt;, &lt;code&gt;tax&lt;/code&gt;, &lt;code&gt;total&lt;/code&gt; — are computed in the component via &lt;code&gt;useWatch&lt;/code&gt; and &lt;code&gt;useMemo&lt;/code&gt; because they depend on live field values and there’s no other natural place for them.&lt;/li&gt;&lt;li&gt;The visibility rules for &lt;code&gt;username&lt;/code&gt;, &lt;code&gt;password&lt;/code&gt;, &lt;code&gt;positiveFeedback&lt;/code&gt;, and &lt;code&gt;improvementFeedback&lt;/code&gt; live in JSX as inline conditionals.&lt;/li&gt;&lt;li&gt;The step-skipping logic — the review page only appearing when &lt;code&gt;total &amp;gt;= 100&lt;/code&gt; — is embedded into the &lt;code&gt;showSubmit&lt;/code&gt; variable and the render condition on step 3.&lt;/li&gt;&lt;li&gt;Navigation itself is just a &lt;code&gt;useState&lt;/code&gt; counter that we’re manually incrementing.&lt;/li&gt;&lt;li&gt;React Query handles retries, caching, and invalidation. The form just calls &lt;code&gt;mutation.mutate&lt;/code&gt; with validated data.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;None of this is &lt;em&gt;wrong,&lt;/em&gt; per se. This is still idiomatic React, and the component is quite performant thanks to how RHF isolates re-renders.&lt;/p&gt;&lt;p&gt;But if you were to hand this to someone who hadn’t written it and ask them to explain &lt;em&gt;under what conditions the review page appears&lt;/em&gt;, they’d have to trace through &lt;code&gt;showSubmit&lt;/code&gt;,
 the step 3 render condition, and the nav button logic — three separate 
places — to reconstruct a rule that could have been stated in one line.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The form works, yes, but the behavior isn’t really inspectable as a system.&lt;/strong&gt; It has to be executed mentally.&lt;/p&gt;&lt;p&gt;More
 importantly, changing it requires engineering involvement. Even a small
 tweak, like adjusting when the review step shows up, means editing the 
component, updating validation, opening a pull request, waiting for 
review, and deploying again.&lt;/p&gt;&lt;h2 id="part-2-schema-driven-surveyjs"&gt;Part 2: Schema-Driven (SurveyJS)&lt;/h2&gt;&lt;p&gt;Now let’s build the same flow using a schema.&lt;/p&gt;&lt;h3 id="installation-1"&gt;Installation&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/03/building-dynamic-forms-react-next-js/#installation-1"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;div class="code-toolbar"&gt;&lt;pre class="  language-bash"&gt;&lt;code class="  language-bash"&gt;&lt;span class="token function"&gt;npm&lt;/span&gt; &lt;span class="token function"&gt;install&lt;/span&gt; survey-core survey-react-ui @tanstack/react-query
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;survey-core&lt;/code&gt;&lt;br /&gt;The
 MIT-licensed platform-independent runtime engine that powers SurveyJS’s
 form rendering — the part we care about here. It takes a JSON schema, 
builds an internal model from it, and handles everything that would 
otherwise live in your React component: evaluating visibility 
expressions, computing derived values, managing page state, tracking 
validation, and deciding what “complete” means given which pages were 
actually shown.&lt;/li&gt;&lt;li&gt;&lt;code&gt;survey-react-ui&lt;/code&gt;&lt;br /&gt;The UI / rendering layer that connects that model to React. It’s essentially a &lt;code&gt;&amp;lt;Survey model={model} /&amp;gt;&lt;/code&gt; component that re-renders whenever the engine’s state changes. SurveyJS UI libraries are also available for &lt;a href="https://www.npmjs.com/package/survey-angular"&gt;Angular&lt;/a&gt;, &lt;a href="https://www.npmjs.com/package/survey-vue3-ui"&gt;Vue3&lt;/a&gt;, and many other frameworks.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Together, they give you a fully functional, multi-page form runtime without writing a single line of control flow.&lt;/p&gt;&lt;p&gt;The
 schema format itself is, as said before, just a JSON — no DSL or 
anything proprietary. You can inline it, import it from a file, fetch it
 from an API, or store it in a database column and hydrate it at 
runtime.&lt;/p&gt;&lt;h3 id="the-same-form-as-data"&gt;The Same Form, As Data&lt;/h3&gt;&lt;p&gt;Here’s
 the same form, this time expressed as a JSON object. The schema defines
 everything: structure, validation, visibility rules, derived 
calculations, page navigation — and hands it to a &lt;code&gt;Model&lt;/code&gt; that evaluates it at runtime. Here’s what that looks like in full:&lt;/p&gt;&lt;div class="break-out"&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token keyword"&gt;export&lt;/span&gt; &lt;span class="token keyword"&gt;const&lt;/span&gt; surveySchema &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
  title&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"Order Flow"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
  showProgressBar&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"top"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
  pages&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token punctuation"&gt;[&lt;/span&gt;  
    &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
      name&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"details"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
      elements&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token punctuation"&gt;[&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;{&lt;/span&gt; type&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"text"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; name&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"firstName"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; isRequired&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token boolean"&gt;true&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;{&lt;/span&gt; type&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"text"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; name&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"email"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; inputType&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"email"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; isRequired&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token boolean"&gt;true&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; validators&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token punctuation"&gt;[&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt; type&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"email"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; text&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"Invalid email"&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;]&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;  
      &lt;span class="token punctuation"&gt;]&lt;/span&gt;  
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
    &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
      name&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"order"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
      elements&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token punctuation"&gt;[&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;{&lt;/span&gt; type&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"text"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; name&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"price"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; inputType&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"number"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; defaultValue&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;0&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;{&lt;/span&gt; type&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"text"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; name&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"quantity"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; inputType&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"number"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; defaultValue&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;1&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
          type&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"dropdown"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          name&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"taxRate"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          defaultValue&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;0.1&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          choices&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token punctuation"&gt;[&lt;/span&gt;  
            &lt;span class="token punctuation"&gt;{&lt;/span&gt; value&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;0.05&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; text&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"5%"&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
            &lt;span class="token punctuation"&gt;{&lt;/span&gt; value&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;0.1&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; text&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"10%"&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
            &lt;span class="token punctuation"&gt;{&lt;/span&gt; value&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;0.15&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; text&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"15%"&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;  
          &lt;span class="token punctuation"&gt;]&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
          type&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"expression"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          name&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"subtotal"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          expression&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"{price} * {quantity}"&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
          type&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"expression"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          name&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"tax"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          expression&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"{subtotal} * {taxRate}"&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
          type&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"expression"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          name&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"total"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          expression&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"{subtotal} + {tax}"&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;}&lt;/span&gt;  
      &lt;span class="token punctuation"&gt;]&lt;/span&gt;  
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
    &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
      name&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"account"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
      elements&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token punctuation"&gt;[&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
          type&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"radiogroup"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          name&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"hasAccount"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          choices&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token punctuation"&gt;[&lt;/span&gt;&lt;span class="token string"&gt;"Yes"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token string"&gt;"No"&lt;/span&gt;&lt;span class="token punctuation"&gt;]&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
          type&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"text"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          name&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"username"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          visibleIf&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"{hasAccount} = 'Yes'"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          isRequired&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token boolean"&gt;true&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
          type&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"text"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          name&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"password"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          inputType&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"password"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          visibleIf&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"{hasAccount} = 'Yes'"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          isRequired&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token boolean"&gt;true&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          validators&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token punctuation"&gt;[&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt; type&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"text"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; minLength&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;6&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; text&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"Min 6 characters"&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;]&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
          type&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"rating"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          name&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"satisfaction"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          rateMin&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;1&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          rateMax&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;5&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
          type&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"comment"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          name&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"positiveFeedback"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          visibleIf&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"{satisfaction} &amp;gt;= 4"&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
          type&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"comment"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          name&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"improvementFeedback"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
          visibleIf&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"{satisfaction} &amp;lt;= 2"&lt;/span&gt;  
        &lt;span class="token punctuation"&gt;}&lt;/span&gt;  
      &lt;span class="token punctuation"&gt;]&lt;/span&gt;  
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
    &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
      name&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"review"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
      visibleIf&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"{total} &amp;gt;= 100"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;  
      elements&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token punctuation"&gt;[&lt;/span&gt;&lt;span class="token punctuation"&gt;]&lt;/span&gt;  
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;  
  &lt;span class="token punctuation"&gt;]&lt;/span&gt;  
&lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Compare this to the RHF version for a moment.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The &lt;code&gt;superRefine&lt;/code&gt; block that conditionally required &lt;code&gt;username&lt;/code&gt; and &lt;code&gt;password&lt;/code&gt; is gone. &lt;code&gt;visibleIf: "{hasAccount} = 'Yes'"&lt;/code&gt; combined with &lt;code&gt;isRequired: true&lt;/code&gt; handles both concerns together, on the field itself, where you’d expect to find them.&lt;/li&gt;&lt;li&gt;The &lt;code&gt;useWatch&lt;/code&gt; + &lt;code&gt;useMemo&lt;/code&gt; chain that computed &lt;code&gt;subtotal&lt;/code&gt;, &lt;code&gt;tax&lt;/code&gt;, and &lt;code&gt;total&lt;/code&gt; is replaced by three &lt;code&gt;expression&lt;/code&gt; fields that reference each other by name.&lt;/li&gt;&lt;li&gt;The review page condition, which in the RHF version was reconstructable only by tracing through &lt;code&gt;showSubmit&lt;/code&gt;, the step 3 render branch.&lt;/li&gt;&lt;li&gt;And finally, the nav button logic is a single &lt;code&gt;visibleIf&lt;/code&gt; property on the page object.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The
 same logic is there. It’s just that the schema gives it a place to live
 where it’s visible in isolation, rather than spread across the 
component.&lt;/p&gt;&lt;p&gt;Also, note that the schema uses &lt;code&gt;type: 'expression'&lt;/code&gt; for subtotal, tax, and total. &lt;a href="https://surveyjs.io/form-library/documentation/api-reference/expression-model"&gt;Expression&lt;/a&gt; is read-only and used mainly to display calculated values. SurveyJS also supports &lt;code&gt;type: 'html'&lt;/code&gt; for static content, but for calculated values, &lt;code&gt;expression&lt;/code&gt; is the right choice.&lt;/p&gt;&lt;p&gt;Now for the React side.&lt;/p&gt;&lt;h3 id="rendering-and-submission"&gt;Rendering And Submission&lt;/h3&gt;&lt;p&gt;Very simple. Wire &lt;code&gt;onComplete&lt;/code&gt; to your API the same way — via &lt;code&gt;useMutation&lt;/code&gt; or plain &lt;code&gt;fetch&lt;/code&gt;:&lt;/p&gt;&lt;div class="break-out"&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token keyword"&gt;import&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt; useState&lt;span class="token punctuation"&gt;,&lt;/span&gt; useEffect&lt;span class="token punctuation"&gt;,&lt;/span&gt; useRef &lt;span class="token punctuation"&gt;}&lt;/span&gt; &lt;span class="token keyword"&gt;from&lt;/span&gt; &lt;span class="token string"&gt;"react"&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  
&lt;span class="token keyword"&gt;import&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt; useMutation &lt;span class="token punctuation"&gt;}&lt;/span&gt; &lt;span class="token keyword"&gt;from&lt;/span&gt; &lt;span class="token string"&gt;"@tanstack/react-query"&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  
&lt;span class="token keyword"&gt;import&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt; Model &lt;span class="token punctuation"&gt;}&lt;/span&gt; &lt;span class="token keyword"&gt;from&lt;/span&gt; &lt;span class="token string"&gt;"survey-core"&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  
&lt;span class="token keyword"&gt;import&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt; Survey &lt;span class="token punctuation"&gt;}&lt;/span&gt; &lt;span class="token keyword"&gt;from&lt;/span&gt; &lt;span class="token string"&gt;"survey-react-ui"&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  
&lt;span class="token keyword"&gt;import&lt;/span&gt; &lt;span class="token string"&gt;"survey-core/survey-core.css"&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

&lt;span class="token keyword"&gt;export&lt;/span&gt; &lt;span class="token keyword"&gt;function&lt;/span&gt; &lt;span class="token function"&gt;SurveyForm&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
  &lt;span class="token keyword"&gt;const&lt;/span&gt; &lt;span class="token punctuation"&gt;[&lt;/span&gt;model&lt;span class="token punctuation"&gt;]&lt;/span&gt; &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;useState&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token operator"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="token keyword"&gt;new&lt;/span&gt; &lt;span class="token class-name"&gt;Model&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;surveySchema&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

  &lt;span class="token keyword"&gt;const&lt;/span&gt; mutation &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;useMutation&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt;
    &lt;span class="token function-variable function"&gt;mutationFn&lt;/span&gt;&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token keyword"&gt;async&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token parameter"&gt;data&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token operator"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
      &lt;span class="token keyword"&gt;const&lt;/span&gt; res &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token keyword"&gt;await&lt;/span&gt; &lt;span class="token function"&gt;fetch&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;"/api/orders"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
        method&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"POST"&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
        headers&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt; &lt;span class="token string"&gt;"Content-Type"&lt;/span&gt;&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;"application/json"&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
        body&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token constant"&gt;JSON&lt;/span&gt;&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;stringify&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;data&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
      &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token keyword"&gt;if&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token operator"&gt;!&lt;/span&gt;res&lt;span class="token punctuation"&gt;.&lt;/span&gt;ok&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token keyword"&gt;throw&lt;/span&gt; &lt;span class="token keyword"&gt;new&lt;/span&gt; &lt;span class="token class-name"&gt;Error&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;"Failed to submit"&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token keyword"&gt;return&lt;/span&gt; res&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;json&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

  &lt;span class="token keyword"&gt;const&lt;/span&gt; mutationRef &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;useRef&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;mutation&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
  mutationRef&lt;span class="token punctuation"&gt;.&lt;/span&gt;current &lt;span class="token operator"&gt;=&lt;/span&gt; mutation&lt;span class="token punctuation"&gt;;&lt;/span&gt;
  &lt;span class="token function"&gt;useEffect&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token operator"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;  
    &lt;span class="token keyword"&gt;const&lt;/span&gt; &lt;span class="token function-variable function"&gt;handler&lt;/span&gt; &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token parameter"&gt;sender&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token operator"&gt;=&amp;gt;&lt;/span&gt; mutationRef&lt;span class="token punctuation"&gt;.&lt;/span&gt;current&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;mutate&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;sender&lt;span class="token punctuation"&gt;.&lt;/span&gt;data&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  
    model&lt;span class="token punctuation"&gt;.&lt;/span&gt;onComplete&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;add&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;handler&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  
    &lt;span class="token keyword"&gt;return&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token operator"&gt;=&amp;gt;&lt;/span&gt; model&lt;span class="token punctuation"&gt;.&lt;/span&gt;onComplete&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;remove&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;handler&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;  
  &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token punctuation"&gt;[&lt;/span&gt;model&lt;span class="token punctuation"&gt;]&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt; &lt;span class="token comment"&gt;// ref avoids re-registering handler every render (mutation object identity changes)&lt;/span&gt;

  &lt;span class="token keyword"&gt;return&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;
    &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;Survey model&lt;span class="token operator"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt;model&lt;span class="token punctuation"&gt;}&lt;/span&gt; &lt;span class="token operator"&gt;/&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;  
      &lt;span class="token punctuation"&gt;{&lt;/span&gt;mutation&lt;span class="token punctuation"&gt;.&lt;/span&gt;isError &lt;span class="token operator"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;div&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;Error&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;mutation&lt;span class="token punctuation"&gt;.&lt;/span&gt;error&lt;span class="token punctuation"&gt;.&lt;/span&gt;message&lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;/&lt;/span&gt;div&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;}&lt;/span&gt;
    &lt;span class="token operator"&gt;&amp;lt;&lt;/span&gt;&lt;span class="token operator"&gt;/&lt;/span&gt;&lt;span class="token operator"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;figure class="break-out"&gt;&lt;div&gt;&lt;/div&gt;&lt;figcaption&gt;See the Pen &lt;a href="https://codepen.io/smashingmag/pen/emddWNV"&gt;SurveyJS-03-SurveyJS [forked]&lt;/a&gt; by &lt;a href="https://codepen.io/sixthextinction"&gt;sixthextinction&lt;/a&gt;.&lt;/figcaption&gt;&lt;/figure&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;onComplete&lt;/code&gt; fires when the user reaches the end of the last &lt;em&gt;visible&lt;/em&gt; page. So if &lt;code&gt;total&lt;/code&gt;
 never crosses 100 and the review page is skipped, it still fires 
correctly because SurveyJS evaluates visibility before deciding what 
“last page” means.&lt;/li&gt;&lt;li&gt;Then, &lt;code&gt;sender.data&lt;/code&gt; contains all answers along with the calculated values (&lt;code&gt;subtotal&lt;/code&gt;, &lt;code&gt;tax&lt;/code&gt;, &lt;code&gt;total&lt;/code&gt;) as first-class fields, so the API payload is identical to what the RHF version assembled manually in &lt;code&gt;onSubmit&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;The &lt;code&gt;mutationRef&lt;/code&gt;
 pattern is the same one you’d reach for anywhere you need a stable 
event handler over a value that changes on every render — nothing 
SurveyJS-specific about it.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The React component no longer contains any business logic at all. There’s no &lt;code&gt;useWatch&lt;/code&gt;, no conditional JSX, no step counter, no &lt;code&gt;useMemo&lt;/code&gt; chain, no &lt;code&gt;superRefine&lt;/code&gt;. React is doing what it’s actually good at: rendering a component and wiring it to an API call.&lt;/p&gt;&lt;h2 id="what-moved-out-of-react"&gt;What Moved Out Of React?&lt;/h2&gt;&lt;table class="tablesaw break-out"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Concern&lt;/th&gt;&lt;th&gt;RHF Stack&lt;/th&gt;&lt;th&gt;SurveyJS&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td data-label="Concern"&gt;Visibility&lt;/td&gt;&lt;td data-label="RHF Stack"&gt;JSX branches&lt;/td&gt;&lt;td data-label="SurveyJS"&gt;&lt;code&gt;visibleIf&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td data-label="Concern"&gt;Derived values&lt;/td&gt;&lt;td data-label="RHF Stack"&gt;&lt;code&gt;useWatch&lt;/code&gt; / &lt;code&gt;useMemo&lt;/code&gt;&lt;/td&gt;&lt;td data-label="SurveyJS"&gt;&lt;code&gt;expression&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td data-label="Concern"&gt;Cross-field rules&lt;/td&gt;&lt;td data-label="RHF Stack"&gt;&lt;code&gt;superRefine&lt;/code&gt;&lt;/td&gt;&lt;td data-label="SurveyJS"&gt;Schema conditions&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td data-label="Concern"&gt;Navigation&lt;/td&gt;&lt;td data-label="RHF Stack"&gt;&lt;code&gt;step&lt;/code&gt; state&lt;/td&gt;&lt;td data-label="SurveyJS"&gt;Page &lt;code&gt;visibleIf&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td data-label="Concern"&gt;Rule location&lt;/td&gt;&lt;td data-label="RHF Stack"&gt;Distributed across files&lt;/td&gt;&lt;td data-label="SurveyJS"&gt;Centralized in the schema&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;What stays in React is layout, styling, submission wiring, and app integration, which is to say, &lt;strong&gt;the things React is actually designed for&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;Everything
 else moved into the schema, and because the schema is just a JSON 
object, it can be stored in a database, versioned independently of your 
application code, or edited through internal tooling without requiring a
 deploy.&lt;/p&gt;&lt;p&gt;A product manager who needs to change the threshold that 
triggers the review page can do that without touching the component. 
That’s a meaningful operational difference for teams where form behavior
 evolves frequently and isn’t always driven by engineers.&lt;/p&gt;&lt;h2 id="when-to-use-each-approach"&gt;When To Use Each Approach?&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/03/building-dynamic-forms-react-next-js/#when-to-use-each-approach"&gt;#&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Here’s a good rule of thumb that works for me: &lt;strong&gt;imagine deleting the form entirely&lt;/strong&gt;. What would you lose?&lt;/p&gt;&lt;ul&gt;&lt;li&gt;If it’s screens, you want component-driven forms.&lt;/li&gt;&lt;li&gt;If
 it’s business logic, like thresholds, branching rules, and conditional 
requirements that encode real decisions, you want a schema engine.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Similarly,
 if the changes coming your way are mostly about labels, fields, and 
layout, RHF will serve you fine. If they’re about conditions, outcomes, 
and rules that your ops or legal team might need to adjust on a Tuesday 
afternoon without filing a ticket, the schema model with SurveyJS is the
 more honest fit.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;These two approaches are not really in competition with each other.&lt;/strong&gt;
 They address different classes of problems, and the mistake worth 
avoiding is mismatching the abstraction to the weight of the logic — 
treating a rule system like a component because that’s the familiar 
tool, or reaching for a policy engine because a form grew to three steps
 and acquired a conditional field.&lt;/p&gt;&lt;p&gt;The form we built here sits 
near the boundary deliberately, complex enough to expose the difference 
but not so extreme that the comparison feels rigged. Most real forms 
that have gotten unwieldy in your codebase probably sit near that same 
boundary, and the question is usually just whether anyone has named what
 they actually are.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Use React Hook Form + Zod when:&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Forms are CRUD-oriented;&lt;/li&gt;&lt;li&gt;Logic is shallow and UI-driven;&lt;/li&gt;&lt;li&gt;Engineers own all behavior;&lt;/li&gt;&lt;li&gt;Backend remains the source of truth.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Use SurveyJS when:&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Forms encode business decisions;&lt;/li&gt;&lt;li&gt;Rules evolve independently of UI;&lt;/li&gt;&lt;li&gt;Logic must be visible, auditable, or versioned;&lt;/li&gt;&lt;li&gt;Non-engineers influence behavior;&lt;/li&gt;&lt;li&gt;The same form must run across multiple frontends.&lt;/li&gt;&lt;/ul&gt;</description><link>http://honeyvig.blogspot.com/2026/04/building-dynamic-forms-in-react-and.html</link><author>noreply@blogger.com (H)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9165069509664255576.post-1067697036801088982</guid><pubDate>Thu, 02 Apr 2026 07:33:00 +0000</pubDate><atom:updated>2026-04-02T00:33:28.468-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">CIO</category><category domain="http://www.blogger.com/atom/ns#">CloudOptimization</category><category domain="http://www.blogger.com/atom/ns#">CostOptimization</category><category domain="http://www.blogger.com/atom/ns#">CTO</category><category domain="http://www.blogger.com/atom/ns#">DigitalTransformation</category><category domain="http://www.blogger.com/atom/ns#">InfrastructureManagement</category><category domain="http://www.blogger.com/atom/ns#">ITConsulting</category><title>Moving From Moment.js To The JS Temporal API</title><description>&lt;div class="c-garfield-summary"&gt;&lt;section aria-label="Quick summary" class="article__summary"&gt;The way JavaScript handles time has evolved significantly, from the built-in &lt;code&gt;Date&lt;/code&gt; API to Moment.js and now Temporal. The new standard fills gaps in the original &lt;code&gt;Date&lt;/code&gt;
 API while addressing limitations found in Moment and other libraries. 
Joe Attardi shares practical “recipes” for migrating Moment-based code 
to the new Temporal API.&lt;/section&gt;&lt;/div&gt;&lt;p&gt;Almost any kind of 
application written in JavaScript works with times or dates in some 
capacity. In the beginning, this was limited to the built-in &lt;code&gt;Date&lt;/code&gt; API. This API includes basic functionality, but is quite limited in what it can do.&lt;/p&gt;&lt;p&gt;Third-party libraries like Moment.js, and later built-in APIs such as the &lt;code&gt;Intl&lt;/code&gt; APIs and the new &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal"&gt;Temporal API&lt;/a&gt;, add much greater flexibility to working with times and dates.&lt;/p&gt;&lt;h2 id="the-rise-and-fall-of-moment-js"&gt;The Rise And Fall Of Moment.js&lt;/h2&gt;&lt;p&gt;&lt;a href="https://momentjs.com"&gt;Moment.js&lt;/a&gt; is a JavaScript library with powerful utilities for working with times and dates. It includes missing features from the basic &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date"&gt;Date API&lt;/a&gt;,
 such as time zone manipulation, and makes many common operations 
simpler. Moment also includes functions for formatting dates and times. 
It became a widely used library in many different applications.&lt;/p&gt;&lt;p&gt;However,
 Moment also had its share of issues. It’s a large library, and can add 
significantly to an application’s bundle size. Because the library 
doesn’t support tree shaking (a feature of modern bundlers that can 
remove unused parts of libraries), the entire Moment library is included
 even if you only use one or two of its functions.&lt;/p&gt;&lt;p&gt;Another issue with Moment is the fact that the objects it creates are &lt;em&gt;mutable&lt;/em&gt;.
 Calling certain functions on a Moment object has side effects and 
mutates the value of that object. This can lead to unexpected behavior 
or bugs.&lt;/p&gt;&lt;p&gt;In 2020, the maintainers of Moment decided to put the 
library into maintenance mode. No new feature development is being done,
 and the maintainers recommend against using it for new projects.&lt;/p&gt;&lt;p&gt;There are other JavaScript date libraries, such as &lt;code&gt;date-fns&lt;/code&gt;, but there’s a new player in town, an API built directly into JavaScript: &lt;strong&gt;Temporal&lt;/strong&gt;. It’s a new standard that fills in the holes of the original &lt;code&gt;Date&lt;/code&gt; API as well as solves some of the limitations found in Moment and other libraries.&lt;/p&gt;&lt;div class="feature-panel-container" data-audience="non-subscriber" data-remove="true"&gt;&lt;aside class="feature-panel"&gt;&lt;div class="feature-panel-left-col"&gt;&lt;div class="feature-panel-description"&gt;&lt;div&gt;&lt;section class="nlbf"&gt;&lt;form action="//smashingmagazine.us1.list-manage.com/subscribe/post?u=16b832d9ad4b28edf261f34df&amp;amp;id=a1666656e0" method="post"&gt;&lt;div class="nlbwrapper"&gt;&lt;div class="nlbgroup"&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/form&gt;&lt;/section&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/aside&gt;&lt;/div&gt;&lt;h2 id="what-is-temporal"&gt;What Is Temporal?&lt;/h2&gt;&lt;p&gt;Temporal
 is a new time and date API being added to the ECMAScript standard, 
which defines modern JavaScript. As of March 2026, it has reached Stage 4
 of the TC39 process (the committee that oversees proposals and 
additions to the JavaScript language), and will be included in the next 
version of the ECMAScript specification. It has already been implemented
 in several browsers: &lt;a href="https://developer.chrome.com/release-notes/144"&gt;Chrome&lt;/a&gt; &lt;a href="https://developer.chrome.com/release-notes/144"&gt;144+&lt;/a&gt; and &lt;a href="https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/139#javascript"&gt;Firefox&lt;/a&gt; &lt;a href="https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/139#javascript"&gt;139+&lt;/a&gt;, with &lt;a href="https://bugs.webkit.org/show_bug.cgi?id=223166"&gt;Safari expected to follow soon&lt;/a&gt;. A &lt;a href="https://github.com/js-temporal/temporal-polyfill"&gt;polyfill is also available&lt;/a&gt; for unsupported browsers and Node.js.&lt;/p&gt;&lt;p&gt;The
 Temporal API creates objects that, generally, represent moments in 
time. These can be full-time and date stamps in a given time zone, or 
they can be a generic instance of “wall clock” time without any time 
zone or date information. Some of the main features of Temporal include:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Times with or without dates.&lt;/strong&gt;&lt;br /&gt;A
 Temporal object can represent a specific time on a specific date, or a 
time without any date information. A specific date, without a time, can 
also be represented.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Time zone support.&lt;/strong&gt;&lt;br /&gt;Temporal
 objects are fully time zone aware and can be converted across different
 time zones. Moment supports time zones, too, but it requires the 
additional &lt;code&gt;moment-timezone&lt;/code&gt; library.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Immutability.&lt;/strong&gt;&lt;br /&gt;Once
 a Temporal object is created, it cannot be changed. Time arithmetic or 
time zone conversions do not modify the underlying object. Instead, they
 generate a new Temporal object.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;1-based indexing.&lt;/strong&gt;&lt;br /&gt;A
 common source of bugs with the Date API (as well as with Moment) is 
that months are zero-indexed. This means that January is month &lt;code&gt;0&lt;/code&gt;, rather than month &lt;code&gt;1&lt;/code&gt; as we all understand in real life. Temporal fixes this by using 1-based indexing — January is month &lt;code&gt;1&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;It’s built into the browser.&lt;/strong&gt;&lt;br /&gt;Since Temporal is an API in the browser itself, it adds nothing to your application’s bundle size.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;It’s
 also important to note that the Date API isn’t going away. While 
Temporal supersedes this API, it is not being removed or deprecated. 
Many applications would break if browsers suddenly removed the Date API.
 However, also keep in mind that Moment is now considered a legacy 
project in maintenance mode.&lt;/p&gt;&lt;p&gt;In the rest of the article, we’ll 
look at some “recipes” for migrating Moment-based code to the new 
Temporal API. Let’s start refactoring!&lt;/p&gt;&lt;h2 id="creating-date-and-time-objects"&gt;Creating Date And Time Objects&lt;/h2&gt;&lt;p&gt;Before
 we can manipulate dates and times, we have to create objects 
representing them. To create a Moment object representing the current 
date and time, use the &lt;code&gt;moment&lt;/code&gt; function.&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token keyword"&gt;const&lt;/span&gt; now &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;moment&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;now&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt; 
&lt;span class="token comment"&gt;// Moment&amp;lt;2026-02-18T21:26:29-05:00&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This object can now be formatted or manipulated as needed.&lt;/p&gt;&lt;div class="break-out"&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token comment"&gt;// convert to UTC&lt;/span&gt;
&lt;span class="token comment"&gt;// warning: This mutates the Moment object and puts it in UTC mode!&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;now&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;utc&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt; 
&lt;span class="token comment"&gt;// Moment&amp;lt;2026-02-19T02:26:29Z&amp;gt;&lt;/span&gt;

&lt;span class="token comment"&gt;// print a formatted string - note that it's using the UTC time now&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;now&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;format&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'MM/DD/YYYY hh:mm:ss a'&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt; 
&lt;span class="token comment"&gt;// 02/19/2026 02:27:07 am&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The key thing to remember about Moment is that a Moment object always includes information about the time &lt;em&gt;and&lt;/em&gt;
 the date. If you only need to work with time information, this is 
usually fine, but it can cause unexpected behavior in situations like 
Daylight Saving Time or leap years, where the date can have an effect on
 time calculations.&lt;/p&gt;&lt;p&gt;Temporal is more flexible. You can create an object representing the current date and time by creating a &lt;code&gt;Temporal.Instant&lt;/code&gt;
 object. This represents a point in time defined by the time since “the 
epoch” (midnight UTC on January 1, 1970). Temporal can reference this 
instant in time with nanosecond-level precision.&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token keyword"&gt;const&lt;/span&gt; now &lt;span class="token operator"&gt;=&lt;/span&gt; Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;Now&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;instant&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

&lt;span class="token comment"&gt;// see raw nanoseconds since the epoch&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;now&lt;span class="token punctuation"&gt;.&lt;/span&gt;epochNanoseconds&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 1771466342612000000n&lt;/span&gt;

&lt;span class="token comment"&gt;// format for UTC&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;now&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;toString&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 2026-02-19T01:55:27.844Z&lt;/span&gt;

&lt;span class="token comment"&gt;// format for a particular time zone&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;now&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;toString&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt; timeZone&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'America/New_York'&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 2026-02-18T20:56:57.905-05:00&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;Temporal.Instant&lt;/code&gt; objects can also be created for a specific time and date by using the &lt;code&gt;from&lt;/code&gt; static method.&lt;/p&gt;&lt;div class="break-out"&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token keyword"&gt;const&lt;/span&gt; myInstant &lt;span class="token operator"&gt;=&lt;/span&gt; Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;Instant&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;from&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'2026-02-18T21:10:00-05:00'&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

&lt;span class="token comment"&gt;// Format the instant in the local time zone. Note that this only controls&lt;/span&gt;
&lt;span class="token comment"&gt;// the formatting - it does not mutate the object like `moment.utc` does.&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;myInstant&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;toString&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt; timeZone&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'America/New_York'&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 2026-02-18T21:10:00-05:00&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;You can also create other types of Temporal objects, including:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;&lt;code&gt;Temporal.PlainDate&lt;/code&gt;&lt;/strong&gt;: A date with no time information.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;code&gt;Temporal.PlainTime&lt;/code&gt;&lt;/strong&gt;: A time with no date information.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;code&gt;Temporal.ZonedDateTime&lt;/code&gt;&lt;/strong&gt;: A date and time in a specific time zone.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Each of these has a &lt;code&gt;from&lt;/code&gt; method that can be called with an object specifying the date and/or time, or a date string to parse.&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token comment"&gt;// Just a date&lt;/span&gt;
&lt;span class="token keyword"&gt;const&lt;/span&gt; today &lt;span class="token operator"&gt;=&lt;/span&gt; Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;PlainDate&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;from&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt;
  year&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;2026&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  month&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;2&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token comment"&gt;// note we're using 2 for February&lt;/span&gt;
  day&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;18&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;today&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;toString&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 2026-02-18&lt;/span&gt;

&lt;span class="token comment"&gt;// Just a time&lt;/span&gt;
&lt;span class="token keyword"&gt;const&lt;/span&gt; lunchTime &lt;span class="token operator"&gt;=&lt;/span&gt; Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;PlainTime&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;from&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt;
  hour&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;12&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;lunchTime&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;toString&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 12:00:00 &lt;/span&gt;

&lt;span class="token comment"&gt;// A date and time in the US Eastern time zone&lt;/span&gt;
&lt;span class="token keyword"&gt;const&lt;/span&gt; dueAt &lt;span class="token operator"&gt;=&lt;/span&gt; Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;ZonedDateTime&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;from&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt;
  timeZone&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'America/New_York'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  year&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;2026&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  month&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;3&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  day&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;1&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  hour&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;12&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  minute&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;0&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  second&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;0&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;dueAt&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;toString&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 2026-03-01T12:00:00-05:00[America/New_York]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="parsing"&gt;Parsing&lt;/h2&gt;&lt;p&gt;We’ve
 covered programmatic creation of date and time information. Now let’s 
look at parsing. Parsing is one area where Moment is more flexible than 
the built-in Temporal API.&lt;/p&gt;&lt;p&gt;You can parse a date string by passing it to the &lt;code&gt;moment&lt;/code&gt;
 function. With a single argument, Moment expects an ISO date string, 
but you can use alternative formats if you provide a second argument 
specifying the date format being used.&lt;/p&gt;&lt;div class="break-out"&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token keyword"&gt;const&lt;/span&gt; isoDate &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;moment&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'2026-02-21T09:00:00'&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token keyword"&gt;const&lt;/span&gt; formattedDate &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;moment&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'2/21/26 9:00:00'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token string"&gt;'M/D/YY h:mm:ss'&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;isoDate&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// Moment&amp;lt;2026-02-21T09:00:00-05:00&amp;gt;&lt;/span&gt;

console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;formattedDate&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// Moment&amp;lt;2026-02-21T09:00:00-05:00&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;In
 older versions, Moment would make a best guess to parse any arbitrarily
 formatted date string. This could lead to unpredictable results. For 
example, is &lt;code&gt;02-03-2026&lt;/code&gt; February 2 or March 3? For this 
reason, newer versions of Moment display a prominent deprecation warning
 if it’s called without an ISO formatted date string (unless the second 
argument with the desired format is also given).&lt;/p&gt;&lt;p&gt;Temporal will 
only parse a specifically formatted date string. The string must be 
compliant with the ISO 8601 format or its extension, RFC 9557. If a 
non-compliant date string is passed to a &lt;code&gt;from&lt;/code&gt; method, Temporal will throw a &lt;code&gt;RangeError&lt;/code&gt;.&lt;/p&gt;&lt;div class="break-out"&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token comment"&gt;// Using an RFC 9557 date string&lt;/span&gt;
&lt;span class="token keyword"&gt;const&lt;/span&gt; myDate &lt;span class="token operator"&gt;=&lt;/span&gt; Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;Instant&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;from&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'2026-02-21T09:00:00-05:00[America/New_York]'&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;myDate&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;toString&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt; timeZone&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'America/New_York'&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 2026-02-21T09:00:00-05:00&lt;/span&gt;

&lt;span class="token comment"&gt;// Using an unknown date string&lt;/span&gt;
&lt;span class="token keyword"&gt;const&lt;/span&gt; otherDate &lt;span class="token operator"&gt;=&lt;/span&gt; Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;Instant&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;from&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'2/21/26 9:00:00'&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// RangeError: Temporal error: Invalid character while parsing year value.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The exact requirements of the date string depend on which kind of Temporal object you’re creating. In the above example, &lt;code&gt;Temporal.Instant&lt;/code&gt; requires a full ISO 8601 or RFC 9557 date string specifying the date and time with a time zone offset, but you can also create &lt;code&gt;PlainDate&lt;/code&gt; or &lt;code&gt;PlainTime&lt;/code&gt; objects using just a subset of the date format.&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token keyword"&gt;const&lt;/span&gt; myDate &lt;span class="token operator"&gt;=&lt;/span&gt; Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;PlainDate&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;from&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'2026-02-21'&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;myDate&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;toString&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 2026-02-21&lt;/span&gt;

&lt;span class="token keyword"&gt;const&lt;/span&gt; myTime &lt;span class="token operator"&gt;=&lt;/span&gt; Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;PlainTime&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;from&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'09:00:00'&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;myTime&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;toString&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 09:00:00&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Note that these strings must still comply with the expected format, or an error will be thrown.&lt;/p&gt;&lt;div class="break-out"&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token comment"&gt;// Using a non-compliant time strings. These will all throw a RangeError.&lt;/span&gt;
Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;PlainTime&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;from&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'9:00'&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;PlainTime&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;from&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'9:00:00 AM'&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;strong&gt;Pro tip: Handling non-ISO strings&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Because Temporal prioritizes reliability, it won’t try to guess the format of a string like &lt;code&gt;02-01-2026&lt;/code&gt;.
 If your data source uses such strings, you will need to do some string 
manipulation to rearrange the values into an ISO string like &lt;code&gt;2026-02-01&lt;/code&gt; before attempting to use it with Temporal.&lt;/blockquote&gt;&lt;h2 id="formatting"&gt;Formatting&lt;/h2&gt;&lt;p&gt;Once you have a Moment or Temporal object, you’ll probably want to convert it to a formatted string at some point.&lt;/p&gt;&lt;p&gt;This is an instance where Moment is a bit more terse. You call the object’s &lt;code&gt;format&lt;/code&gt; method with a string of tokens that describe the desired date format.&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token keyword"&gt;const&lt;/span&gt; date &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;moment&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;date&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;format&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'MM/DD/YYYY'&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 02/22/2026&lt;/span&gt;

console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;date&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;format&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'MMMM Do YYYY, h:mm:ss a'&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// February 22nd 2026, 8:18:30 pm&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;On the other hand, Temporal requires you to be a bit more verbose. Temporal objects, such as &lt;code&gt;Instant&lt;/code&gt;, have a &lt;code&gt;toLocaleString&lt;/code&gt; method that accepts various formatting options specified as properties of an object.&lt;/p&gt;&lt;div class="break-out"&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token keyword"&gt;const&lt;/span&gt; date &lt;span class="token operator"&gt;=&lt;/span&gt; Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;Now&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;instant&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

&lt;span class="token comment"&gt;// with no arguments, we'll get the default format for the current locale&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;date&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;toLocaleString&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 2/22/2026, 8:23:36 PM (assuming a locale of en-US)&lt;/span&gt;

&lt;span class="token comment"&gt;// pass formatting options to generate a custom format string&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;date&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;toLocaleString&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'en-US'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
  month&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'long'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  day&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'numeric'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  year&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'numeric'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  hour&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'2-digit'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  minute&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'2-digit'&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// February 22, 2026 at 8:23 PM&lt;/span&gt;

&lt;span class="token comment"&gt;// only pass the fields you want in the format string&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;date&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;toLocaleString&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'en-US'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
  month&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'short'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  day&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'numeric'&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// Feb 22&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Temporal date formatting actually uses the &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt; API&lt;/strong&gt; (which is already readily available in modern browsers) under the hood. That means you can create a reusable &lt;code&gt;DateTimeFormat&lt;/code&gt; object with your custom formatting options, then pass Temporal objects to its &lt;code&gt;format&lt;/code&gt; method. Because of this, it doesn’t support custom date formats like Moment does. If you need something like &lt;code&gt;'Q1 2026'&lt;/code&gt; or other specialized formatting, you may need some custom date formatting code or reach for a third-party library.&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token keyword"&gt;const&lt;/span&gt; formatter &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token keyword"&gt;new&lt;/span&gt; &lt;span class="token class-name"&gt;Intl&lt;span class="token punctuation"&gt;.&lt;/span&gt;DateTimeFormat&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'en-US'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
  month&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'2-digit'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  day&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'2-digit'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  year&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'numeric'&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

&lt;span class="token keyword"&gt;const&lt;/span&gt; date &lt;span class="token operator"&gt;=&lt;/span&gt; Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;Now&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;instant&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;formatter&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;format&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;date&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 02/22/2026&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Moment’s
 formatting tokens are simpler to write, but they aren’t 
locale-friendly. The format strings “hard code” things like month/day 
order. The advantage of using a configuration object, as Temporal does, 
is that it will automatically adapt to any given locale and use the 
correct format.&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token keyword"&gt;const&lt;/span&gt; date &lt;span class="token operator"&gt;=&lt;/span&gt; Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;Now&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;instant&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

&lt;span class="token keyword"&gt;const&lt;/span&gt; formatOptions &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
  month&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'numeric'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  day&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'numeric'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  year&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'numeric'&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;


console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;date&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;toLocaleString&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'en-US'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; formatOptions&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 2/22/2026&lt;/span&gt;

console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;date&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;toLocaleString&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'en-GB'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; formatOptions&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 22/02/2026&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="date-calculations"&gt;Date calculations&lt;/h2&gt;&lt;p&gt;In
 many applications, you’ll need to end up performing some calculations 
on a date. You may want to add or subtract units of time (days, hours, 
seconds, etc.). For example, if you have the current date, you may want 
to show the user the date 1 week from now.&lt;/p&gt;&lt;p&gt;Moment objects have methods such as &lt;code&gt;add&lt;/code&gt; and &lt;code&gt;subtract&lt;/code&gt; that perform these operations. These functions take a value and a unit, for example: &lt;code&gt;add(7, 'days')&lt;/code&gt;.
 One very important difference between Moment and Temporal, however, is 
that when performing these date calculations, the underlying object is 
modified and its original value is lost.&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token keyword"&gt;const&lt;/span&gt; now &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;moment&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;now&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// Moment&amp;lt;2026-02-24T20:08:36-05:00&amp;gt;&lt;/span&gt;

&lt;span class="token keyword"&gt;const&lt;/span&gt; nextWeek &lt;span class="token operator"&gt;=&lt;/span&gt; now&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;add&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token number"&gt;7&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token string"&gt;'days'&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;nextWeek&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// Moment&amp;lt;2026-03-03T20:08:36-05:00&amp;gt;&lt;/span&gt;

&lt;span class="token comment"&gt;// Gotcha - the original object was mutated&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;now&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// Moment&amp;lt;2026-03-03T20:08:36-05:00&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;To avoid losing the original date, you can call &lt;code&gt;clone&lt;/code&gt; on the Moment object to create a copy.&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token keyword"&gt;const&lt;/span&gt; now &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;moment&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token keyword"&gt;const&lt;/span&gt; nextWeek &lt;span class="token operator"&gt;=&lt;/span&gt; now&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;clone&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;add&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token number"&gt;7&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token string"&gt;'days'&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;now&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// Moment&amp;lt;2026-02-24T20:12:55-05:00&amp;gt;&lt;/span&gt;

console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;nextWeek&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// Moment&amp;lt;2026-03-03T20:12:55-05:00&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;On the other hand, Temporal objects are &lt;em&gt;immutable&lt;/em&gt;. Once you’ve created an object like an &lt;code&gt;Instant&lt;/code&gt;, &lt;code&gt;PlainDate&lt;/code&gt;, and so on, the value of that object will never change. Temporal objects also have &lt;code&gt;add&lt;/code&gt; and &lt;code&gt;subtract&lt;/code&gt; methods.&lt;/p&gt;&lt;p&gt;Temporal is a little picky about which time units can be added to which object types. For example, you can’t add days to an &lt;code&gt;Instant&lt;/code&gt;:&lt;/p&gt;&lt;div class="break-out"&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token keyword"&gt;const&lt;/span&gt; now &lt;span class="token operator"&gt;=&lt;/span&gt; Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;Now&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;instant&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token keyword"&gt;const&lt;/span&gt; nextWeek &lt;span class="token operator"&gt;=&lt;/span&gt; now&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;add&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt; days&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;7&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// RangeError: Temporal error: Largest unit cannot be a date unit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This is because &lt;code&gt;Instant&lt;/code&gt;
 objects represent a specific point in time in UTC and are 
calendar-agnostic. Because the length of a day can change based on time 
zone rules such as Daylight Saving Time, this calculation isn’t 
available on an &lt;code&gt;Instant&lt;/code&gt;. You &lt;em&gt;can&lt;/em&gt;, however, perform this operation on other types of objects, such as a &lt;code&gt;PlainDateTime&lt;/code&gt;:&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token keyword"&gt;const&lt;/span&gt; now &lt;span class="token operator"&gt;=&lt;/span&gt; Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;Now&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;plainDateTimeISO&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;now&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;toLocaleString&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 2/24/2026, 8:23:59 PM&lt;/span&gt;

&lt;span class="token keyword"&gt;const&lt;/span&gt; nextWeek &lt;span class="token operator"&gt;=&lt;/span&gt; now&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;add&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt; days&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;7&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

&lt;span class="token comment"&gt;// Note that the original PlainDateTime remains unchanged&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;now&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;toLocaleString&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 2/24/2026, 8:23:59 PM&lt;/span&gt;

console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;nextWeek&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;toLocaleString&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 3/3/2026, 8:23:59 PM&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;You can also calculate how much time is between two Moment or Temporal objects.&lt;/p&gt;&lt;p&gt;With Moment’s &lt;code&gt;diff&lt;/code&gt; function, you need to provide a unit for granularity, otherwise it will return the difference in milliseconds.&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token keyword"&gt;const&lt;/span&gt; date1 &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;moment&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'2026-02-21T09:00:00'&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token keyword"&gt;const&lt;/span&gt; date2 &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;moment&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'2026-02-22T10:30:00'&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;date2&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;diff&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;date1&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 91800000&lt;/span&gt;

console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;date2&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;diff&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;date1&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token string"&gt;'days'&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;To do this with a Temporal object, you can pass another Temporal object to its &lt;code&gt;until&lt;/code&gt; or &lt;code&gt;since&lt;/code&gt; methods. This returns a &lt;code&gt;Temporal.Duration&lt;/code&gt; object containing information about the time difference. The &lt;code&gt;Duration&lt;/code&gt; object has properties for each component of the difference, and also can generate an &lt;a href="https://en.wikipedia.org/wiki/ISO_8601#Durations"&gt;ISO 8601&lt;/a&gt; duration string representing the time difference.&lt;/p&gt;&lt;div class="break-out"&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token keyword"&gt;const&lt;/span&gt; date1 &lt;span class="token operator"&gt;=&lt;/span&gt; Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;PlainDateTime&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;from&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'2026-02-21T09:00:00'&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token keyword"&gt;const&lt;/span&gt; date2 &lt;span class="token operator"&gt;=&lt;/span&gt; Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;PlainDateTime&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;from&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'2026-02-22T10:30:00'&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

&lt;span class="token comment"&gt;// largestUnit specifies the largest unit of time to represent&lt;/span&gt;
&lt;span class="token comment"&gt;// in the duration calculation&lt;/span&gt;
&lt;span class="token keyword"&gt;const&lt;/span&gt; diff &lt;span class="token operator"&gt;=&lt;/span&gt; date2&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;since&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;date1&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt; largestUnit&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'day'&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;diff&lt;span class="token punctuation"&gt;.&lt;/span&gt;days&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 1&lt;/span&gt;

console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;diff&lt;span class="token punctuation"&gt;.&lt;/span&gt;hours&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 1&lt;/span&gt;

console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;diff&lt;span class="token punctuation"&gt;.&lt;/span&gt;minutes&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 30&lt;/span&gt;

console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;diff&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;toString&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// P1DT1H30M&lt;/span&gt;
&lt;span class="token comment"&gt;// (ISO 8601 duration string: 1 day, 1 hour, 30 minutes)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="comparing-dates-and-times"&gt;Comparing Dates And Times&lt;/h2&gt;&lt;p&gt;Moment
 and Temporal both let you compare dates and times to determine which 
comes before the other, but take different approaches with the API.&lt;/p&gt;&lt;p&gt;Moment provides methods such as &lt;code&gt;isBefore&lt;/code&gt;, &lt;code&gt;isAfter&lt;/code&gt;, and &lt;code&gt;isSame&lt;/code&gt; to compare two Moment objects.&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token keyword"&gt;const&lt;/span&gt; date1 &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;moment&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'2026-02-21T09:00:00'&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token keyword"&gt;const&lt;/span&gt; date2 &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;moment&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'2026-02-22T10:30:00'&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;date1&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;isBefore&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;date2&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Temporal uses a static &lt;code&gt;compare&lt;/code&gt; method to perform a comparison between two objects of the same type. It returns &lt;code&gt;-1&lt;/code&gt; if the first date comes before the second, &lt;code&gt;0&lt;/code&gt; if they are equal, or &lt;code&gt;1&lt;/code&gt; if the first date comes after the second. The following example shows how to compare two &lt;code&gt;PlainDate&lt;/code&gt; objects. Both arguments to &lt;code&gt;Temporal.PlainDate.compare&lt;/code&gt; must be &lt;code&gt;PlainDate&lt;/code&gt; objects.&lt;/p&gt;&lt;div class="break-out"&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token keyword"&gt;const&lt;/span&gt; date1 &lt;span class="token operator"&gt;=&lt;/span&gt; Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;PlainDate&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;from&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt; year&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;2026&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; month&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;2&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; day&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;24&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token keyword"&gt;const&lt;/span&gt; date2 &lt;span class="token operator"&gt;=&lt;/span&gt; Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;PlainDate&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;from&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt; year&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;2026&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; month&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;3&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; day&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;24&lt;/span&gt; &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

&lt;span class="token comment"&gt;// date1 comes before date2, so -1&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;PlainDate&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;compare&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;date1&lt;span class="token punctuation"&gt;,&lt;/span&gt; date2&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

&lt;span class="token comment"&gt;// Error if we try to compare two objects of different types&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;PlainDate&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;compare&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;date1&lt;span class="token punctuation"&gt;,&lt;/span&gt; Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;Now&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;instant&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// TypeError: Temporal error: Invalid PlainDate fields provided.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;In particular, this makes it easy to sort an array of Temporal objects chronologically.&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token comment"&gt;// An array of Temporal.PlainDate objects&lt;/span&gt;
&lt;span class="token keyword"&gt;const&lt;/span&gt; dates &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token punctuation"&gt;[&lt;/span&gt; &lt;span class="token operator"&gt;...&lt;/span&gt; &lt;span class="token punctuation"&gt;]&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

&lt;span class="token comment"&gt;// use Temporal.PlainDate.compare as the comparator function&lt;/span&gt;
dates&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;sort&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;PlainDate&lt;span class="token punctuation"&gt;.&lt;/span&gt;compare&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id="time-zone-conversions"&gt;Time Zone Conversions&lt;/h2&gt;&lt;p&gt;The core Moment library doesn’t support time zone conversions. If you need this functionality, you also need to install the &lt;code&gt;moment-timezone&lt;/code&gt; package. This package is not tree-shakable, and therefore can add significantly to your bundle size. Once you’ve installed &lt;code&gt;moment-timezone&lt;/code&gt;, you can convert Moment objects to different time zones with the &lt;code&gt;tz&lt;/code&gt; method. As with other Moment operations, this mutates the underlying object.&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token comment"&gt;// Assuming US Eastern time&lt;/span&gt;
&lt;span class="token keyword"&gt;const&lt;/span&gt; now &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;moment&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;now&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// Moment&amp;lt;2026-02-28T20:08:20-05:00&amp;gt;&lt;/span&gt;

&lt;span class="token comment"&gt;// Convert to Pacific time.&lt;/span&gt;
&lt;span class="token comment"&gt;// The original Eastern time is lost.&lt;/span&gt;
now&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;tz&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'America/Los_Angeles'&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;now&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// Moment&amp;lt;2026-02-28T17:08:20-08:00&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Time zone functionality is built into the Temporal API when using a &lt;code&gt;Temporal.ZonedDateTime&lt;/code&gt; object. These objects include a &lt;code&gt;withTimeZone&lt;/code&gt; method that returns a new &lt;code&gt;ZonedDateTime&lt;/code&gt; representing the same moment in time, but in the specified time zone.&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token comment"&gt;// Again, assuming US Eastern time&lt;/span&gt;
&lt;span class="token keyword"&gt;const&lt;/span&gt; now &lt;span class="token operator"&gt;=&lt;/span&gt; Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;Now&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;zonedDateTimeISO&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;now&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;toLocaleString&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 2/28/2026, 8:12:02 PM EST&lt;/span&gt;

&lt;span class="token comment"&gt;// Convert to Pacific time&lt;/span&gt;
&lt;span class="token keyword"&gt;const&lt;/span&gt; nowPacific &lt;span class="token operator"&gt;=&lt;/span&gt; now&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;withTimeZone&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'America/Los_Angeles'&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;nowPacific&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;toLocaleString&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 2/28/2026, 5:12:02 PM PST&lt;/span&gt;

&lt;span class="token comment"&gt;// Original object remains unchanged&lt;/span&gt;
console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;now&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;toLocaleString&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// 2/28/2026, 8:12:02 PM EST&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;em&gt;The formatted values returned by &lt;code&gt;toLocaleString&lt;/code&gt; are, as the name implies, locale-dependent. The sample code was developed in the &lt;code&gt;en-US&lt;/code&gt; locale, so the format is like this: &lt;code&gt;2/28/2026, 5:12:02 PM PST&lt;/code&gt;. In another locale, this may be different. For example, in the &lt;code&gt;en-GB&lt;/code&gt; locale, you would get something like &lt;code&gt;28/2/2026, 17:12:02 GMT-8&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;&lt;h2 id="a-real-world-refactoring"&gt;A Real-world Refactoring&lt;/h2&gt;&lt;p&gt;Suppose we’re building an app for scheduling events across time zones. Part of this app is a function, &lt;code&gt;getEventTimes&lt;/code&gt;,
 which takes an ISO 8601 string representing the time and date of the 
event, a local time zone, and a target time zone. The function creates 
formatted time and date strings for the event in both time zones.&lt;/p&gt;&lt;p&gt;If the function is given an input string that’s not a valid time/date string, it will throw an error.&lt;/p&gt;&lt;p&gt;Here’s the original implementation, using Moment (also requiring use of the &lt;code&gt;moment-timezone&lt;/code&gt; package).&lt;/p&gt;&lt;div class="break-out"&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token keyword"&gt;import&lt;/span&gt; moment &lt;span class="token keyword"&gt;from&lt;/span&gt; &lt;span class="token string"&gt;'moment-timezone'&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

&lt;span class="token keyword"&gt;function&lt;/span&gt; &lt;span class="token function"&gt;getEventTimes&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token parameter"&gt;inputString&lt;span class="token punctuation"&gt;,&lt;/span&gt; userTimeZone&lt;span class="token punctuation"&gt;,&lt;/span&gt; targetTimeZone&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
  &lt;span class="token keyword"&gt;const&lt;/span&gt; timeFormat &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token string"&gt;'MMM D, YYYY, h:mm:ss a z'&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

  &lt;span class="token comment"&gt;// 1. Create the initial moment in the user's time zone&lt;/span&gt;
  &lt;span class="token keyword"&gt;const&lt;/span&gt; eventTime &lt;span class="token operator"&gt;=&lt;/span&gt; moment&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;tz&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;
    inputString&lt;span class="token punctuation"&gt;,&lt;/span&gt;
    moment&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token constant"&gt;ISO_8601&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token comment"&gt;// Expect an ISO 8601 string&lt;/span&gt;
    &lt;span class="token boolean"&gt;true&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token comment"&gt;// Strict parsing&lt;/span&gt;
    userTimeZone
  &lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
  
  &lt;span class="token comment"&gt;// Throw an error if the inputString did not represent a valid date&lt;/span&gt;
  &lt;span class="token keyword"&gt;if&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token operator"&gt;!&lt;/span&gt;eventTime&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;isValid&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
    &lt;span class="token keyword"&gt;throw&lt;/span&gt; &lt;span class="token keyword"&gt;new&lt;/span&gt; &lt;span class="token class-name"&gt;Error&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token string"&gt;'Invalid date/time input'&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
  &lt;span class="token punctuation"&gt;}&lt;/span&gt;

  &lt;span class="token comment"&gt;// 2. Calculate the target time&lt;/span&gt;
  &lt;span class="token comment"&gt;// CRITICAL: We must clone, or 'eventTime' changes forever!&lt;/span&gt;
  &lt;span class="token keyword"&gt;const&lt;/span&gt; targetTime &lt;span class="token operator"&gt;=&lt;/span&gt; eventTime&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;clone&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;tz&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;targetTimeZone&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

  &lt;span class="token keyword"&gt;return&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
    local&lt;span class="token operator"&gt;:&lt;/span&gt; eventTime&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;format&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;timeFormat&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
    target&lt;span class="token operator"&gt;:&lt;/span&gt; targetTime&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;format&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;timeFormat&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;

&lt;span class="token keyword"&gt;const&lt;/span&gt; schedule &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;getEventTimes&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;
  &lt;span class="token string"&gt;'2026-03-05T15:00-05:00'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  &lt;span class="token string"&gt;'America/New_York'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  &lt;span class="token string"&gt;'Europe/London'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;schedule&lt;span class="token punctuation"&gt;.&lt;/span&gt;local&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// Mar 5, 2026, 3:00:00 pm EST&lt;/span&gt;

console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;schedule&lt;span class="token punctuation"&gt;.&lt;/span&gt;target&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt; 
&lt;span class="token comment"&gt;// Mar 5, 2026, 8:00:00 pm GMT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;In
 this example, we’re using an expected date format of ISO 8601, which is
 helpfully built into Moment. We’re also using strict parsing, which 
means Moment won’t try to guess with a date string that doesn’t match 
the format. If a non-ISO date string is passed, it will result in an 
invalid date object, and we throw an error.&lt;/p&gt;&lt;p&gt;The Temporal implementation looks similar, but has a few key differences.&lt;/p&gt;&lt;div class="break-out"&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token keyword"&gt;function&lt;/span&gt; &lt;span class="token function"&gt;getEventTimes&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token parameter"&gt;inputString&lt;span class="token punctuation"&gt;,&lt;/span&gt; userTimeZone&lt;span class="token punctuation"&gt;,&lt;/span&gt; targetTimeZone&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
  &lt;span class="token comment"&gt;// 1. Parse the input directly into an Instant, then create&lt;/span&gt;
  &lt;span class="token comment"&gt;// a ZonedDateTime in the user's zone.&lt;/span&gt;
  &lt;span class="token keyword"&gt;const&lt;/span&gt; instant &lt;span class="token operator"&gt;=&lt;/span&gt; Temporal&lt;span class="token punctuation"&gt;.&lt;/span&gt;Instant&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;from&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;inputString&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
  &lt;span class="token keyword"&gt;const&lt;/span&gt; eventTime &lt;span class="token operator"&gt;=&lt;/span&gt; instant&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;toZonedDateTimeISO&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;userTimeZone&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

  &lt;span class="token comment"&gt;// 2. Convert to the target zone&lt;/span&gt;
  &lt;span class="token comment"&gt;// This automatically returns a NEW object; 'eventTime' is safe.&lt;/span&gt;
  &lt;span class="token keyword"&gt;const&lt;/span&gt; targetTime &lt;span class="token operator"&gt;=&lt;/span&gt; eventTime&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;withTimeZone&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;targetTimeZone&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

  &lt;span class="token comment"&gt;// 3. Format using Intl (built-in)&lt;/span&gt;
  &lt;span class="token keyword"&gt;const&lt;/span&gt; options &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
    year&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'numeric'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
    month&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'short'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
    day&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'numeric'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
    hour&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'numeric'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
    minute&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'2-digit'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
    second&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'2-digit'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
    timeZoneName&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token string"&gt;'short'&lt;/span&gt;
  &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

  &lt;span class="token keyword"&gt;return&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
    local&lt;span class="token operator"&gt;:&lt;/span&gt; eventTime&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;toLocaleString&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;navigator&lt;span class="token punctuation"&gt;.&lt;/span&gt;language&lt;span class="token punctuation"&gt;,&lt;/span&gt; options&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
    target&lt;span class="token operator"&gt;:&lt;/span&gt; targetTime&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;toLocaleString&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;navigator&lt;span class="token punctuation"&gt;.&lt;/span&gt;language&lt;span class="token punctuation"&gt;,&lt;/span&gt; options&lt;span class="token punctuation"&gt;)&lt;/span&gt;
  &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;

&lt;span class="token keyword"&gt;const&lt;/span&gt; schedule &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;getEventTimes&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;
  &lt;span class="token string"&gt;'2026-03-05T15:00-05:00'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  &lt;span class="token string"&gt;'America/New_York'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  &lt;span class="token string"&gt;'Europe/London'&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;schedule&lt;span class="token punctuation"&gt;.&lt;/span&gt;local&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// Mar 5, 2026, 3:00:00 PM EST&lt;/span&gt;

console&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;log&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;schedule&lt;span class="token punctuation"&gt;.&lt;/span&gt;target&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;// Mar 5, 2026, 8:00:00 PM GMT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;With
 Moment, we have to explicitly specify a format string for the resulting
 date strings. Regardless of the user’s location or locale, the event 
times will always be formatted as &lt;code&gt;Mar 5, 2026, 3:00:00 pm EST&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Also, we don’t have to explicitly throw an exception. If an invalid string is passed to &lt;code&gt;Temporal.Instant.from&lt;/code&gt;,
 Temporal will throw the exception for us. One thing to note is that 
even with strict parsing, the Moment version is still more lenient. 
Temporal requires the time zone offset at the end of the string.&lt;/p&gt;&lt;p&gt;You should also note that since we’re using &lt;code&gt;navigator.language&lt;/code&gt;, this code will only run in a browser environment, as &lt;code&gt;navigator&lt;/code&gt; is not defined in a Node.js environment.&lt;/p&gt;&lt;p&gt;The Temporal implementation uses the browser’s current locale (&lt;code&gt;navigator.language&lt;/code&gt;), so the user will automatically get event times formatted in their local time format. In the &lt;code&gt;en-US&lt;/code&gt; locale, this is &lt;code&gt;Mar 5, 2026, 3:00:00 pm EST&lt;/code&gt;. However, if the user is in London, for example, the event times will be formatted as &lt;code&gt;5 Mar 2026, 15:00:00 GMT-5&lt;/code&gt;.&lt;/p&gt;&lt;h2 id="summary"&gt;Summary&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/03/moving-from-moment-to-temporal-api/#summary"&gt;#&lt;/a&gt;&lt;/h2&gt;&lt;table class="tablesaw break-out"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Action&lt;/th&gt;&lt;th&gt;Moment.js&lt;/th&gt;&lt;th&gt;Temporal&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td data-label="Action"&gt;Current time&lt;/td&gt;&lt;td data-label="Moment.js"&gt;&lt;code&gt;moment()&lt;/code&gt;&lt;/td&gt;&lt;td data-label="Temporal"&gt;&lt;code&gt;Temporal.Now.zonedDateTimeISO()&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td data-label="Action"&gt;Parsing ISO&lt;/td&gt;&lt;td data-label="Moment.js"&gt;&lt;code&gt;moment(str)&lt;/code&gt;&lt;/td&gt;&lt;td data-label="Temporal"&gt;&lt;code&gt;Temporal.Instant.from(str)&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td data-label="Action"&gt;Add time&lt;/td&gt;&lt;td data-label="Moment.js"&gt;&lt;code&gt;.add(7, 'days')&lt;/code&gt; (mutates)&lt;/td&gt;&lt;td data-label="Temporal"&gt;&lt;code&gt;.add({ days: 7 })&lt;/code&gt; (new object)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td data-label="Action"&gt;Difference&lt;/td&gt;&lt;td data-label="Moment.js"&gt;&lt;code&gt;.diff(other, 'hours')&lt;/code&gt;&lt;/td&gt;&lt;td data-label="Temporal"&gt;&lt;code&gt;.since(other).hours&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td data-label="Action"&gt;Time zone&lt;/td&gt;&lt;td data-label="Moment.js"&gt;&lt;code&gt;.tz('Zone/Name')&lt;/code&gt;&lt;/td&gt;&lt;td data-label="Temporal"&gt;&lt;code&gt;.withTimeZone('Zone/Name')&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;At
 first glance, the difference may be slightly different (and in the case
 of Temporal, sometimes more verbose and more strict) syntax, but there 
are several key advantages to using Temporal over Moment.js:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Being more explicit means &lt;strong&gt;fewer surprises and unintended bugs&lt;/strong&gt;.
 Moment may appear to be more lenient, but it involves “guesswork,” 
which can sometimes result in incorrect dates. If you give Temporal 
something invalid, it throws an error. If the code runs, you know you’ve
 got a valid date.&lt;/li&gt;&lt;li&gt;Moment can add significant size to the application’s bundle, particularly if you’re using the &lt;code&gt;moment-timezone&lt;/code&gt; package. Temporal adds nothing (once it’s shipped in your target browsers).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Immutability&lt;/strong&gt; gives you the confidence that you’ll never lose or overwrite data when performing date conversions and operations.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Different representations of time&lt;/strong&gt; (&lt;code&gt;Instant&lt;/code&gt;, &lt;code&gt;PlainDateTime&lt;/code&gt;, &lt;code&gt;ZonedDateTime&lt;/code&gt;) depending on your requirements, where Moment is always a wrapper around a UTC timestamp.&lt;/li&gt;&lt;li&gt;Temporal uses the &lt;strong&gt;&lt;code&gt;Intl&lt;/code&gt; APIs for date formatting&lt;/strong&gt;, which means you can have locale-aware formatting without having to explicitly specify tokens.&lt;/li&gt;&lt;/ul&gt;&lt;h2 id="notes-on-the-polyfill"&gt;Notes On The Polyfill&lt;/h2&gt;&lt;p&gt;As mentioned earlier, there is a Temporal polyfill available, distributed as an npm package named &lt;code&gt;@js-temporal/polyfill&lt;/code&gt;.
 If you want to use Temporal today, you’ll need this polyfill to support
 browsers like Safari that haven’t shipped the API yet. The bad news 
with this is that it will add to your bundle size. The good news is that
 it still adds significantly less than &lt;code&gt;moment&lt;/code&gt; or &lt;code&gt;moment-timezone&lt;/code&gt;.
 Here is a comparison of the bundle sizes as reported by 
Bundlephobia.com, a website that presents information on npm package 
sizes (click on each package name to see the Bundlephobia analysis):&lt;/p&gt;&lt;table class="tablesaw break-out"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Package&lt;/th&gt;&lt;th&gt;Minified&lt;/th&gt;&lt;th&gt;Minified &amp;amp; gzipped&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td data-label="Package"&gt;&lt;a href="https://bundlephobia.com/package/@js-temporal/polyfill"&gt;&lt;code&gt;@js-temporal/polyfill&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td data-label="Minified"&gt;154.1 kB&lt;/td&gt;&lt;td data-label="Minified &amp;amp;amp; gzipped"&gt;44.1 kB&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td data-label="Package"&gt;&lt;a href="https://bundlephobia.com/package/moment"&gt;&lt;code&gt;moment&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td data-label="Minified"&gt;294.4 kB&lt;/td&gt;&lt;td data-label="Minified &amp;amp;amp; gzipped"&gt;75.4 kB&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td data-label="Package"&gt;&lt;a href="https://bundlephobia.com/package/moment-timezone"&gt;&lt;code&gt;moment-timezone&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td data-label="Minified"&gt;1 MB&lt;/td&gt;&lt;td data-label="Minified &amp;amp;amp; gzipped"&gt;114.2 kB&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;The
 polyfill also has historically had some performance issues around 
memory usage, and at the time of writing, it’s considered to be in an 
alpha state. Because of this, you may not want to use it in production 
until it reaches a more mature state.&lt;/p&gt;&lt;p&gt;The other good news is that 
hopefully the polyfill won’t be needed much longer (unless you need to 
support older browsers, of course). At the time of writing, Temporal has
 shipped in Chrome, Edge, and Firefox. It’s not quite ready in Safari 
yet, though it appears to be available with a runtime flag on the latest
 Technology Preview&lt;/p&gt;</description><link>http://honeyvig.blogspot.com/2026/04/moving-from-momentjs-to-js-temporal-api.html</link><author>noreply@blogger.com (H)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9165069509664255576.post-7980042107518219286</guid><pubDate>Thu, 02 Apr 2026 07:04:00 +0000</pubDate><atom:updated>2026-04-03T05:21:35.162-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">CSS</category><category domain="http://www.blogger.com/atom/ns#">UI</category><category domain="http://www.blogger.com/atom/ns#">Web Design</category><title>Beyond border-radius: What The CSS corner-shape Property Unlocks For Everyday UI</title><description>&lt;div class="c-garfield-summary"&gt;&lt;section aria-label="Quick summary" class="article__summary"&gt;For years, developers have been hacking around the limitations of &lt;code&gt;border-radius&lt;/code&gt;, using clip-path, SVG masks, and fragile workarounds just to get anything other than round corners. The new &lt;code&gt;corner-shape&lt;/code&gt; property finally changes that, opening the door to beveled, scooped, and squircle corners.&lt;/section&gt;&lt;/div&gt;&lt;p&gt;When
 I first started building websites, rounded corners required five 
background images, one for each corner, one for the body, and a prayer 
that the client wouldn’t ask for a different radius. Then the &lt;code&gt;border-radius&lt;/code&gt;
 property landed, and the entire web collectively sighed with relief. 
That was over fifteen years ago, and honestly, we’ve been riding that 
same wave ever since. Just as then, I hope that we can look at this 
feature as a progressive enhancement slowly making its way to other 
browsers.&lt;/p&gt;&lt;p&gt;I like a good &lt;code&gt;border-radius&lt;/code&gt; like any other 
guy, but the fact is that it only gives us one shape. Round. That’s it. 
Want beveled corners? Clip-path. Scooped ticket edges? SVG mask. 
Squircle app icons? A carefully tuned SVG that you hope nobody asks you 
to animate. We’ve been hacking around the limitations of &lt;code&gt;border-radius&lt;/code&gt;
 for years, and those hacks come with real trade-offs: borders don’t 
follow clip-paths, shadows get cut off, and you end up with brittle code
 that breaks the moment someone changes a padding value.&lt;/p&gt;&lt;p&gt;Well, the new &lt;b&gt;&lt;code&gt;corner-shape&lt;/code&gt;&lt;/b&gt; changes all of that.&lt;/p&gt;&lt;h2 id="what-is-corner-shape"&gt;What Is &lt;code&gt;corner-shape&lt;/code&gt;?&lt;/h2&gt;&lt;p&gt;The &lt;a href="https://css-tricks.com/almanac/properties/c/corner-shape/"&gt;&lt;code&gt;corner-shape&lt;/code&gt;&lt;/a&gt; property is a companion to &lt;code&gt;border-radius&lt;/code&gt;. It doesn’t replace it; it modifies the &lt;i&gt;shape&lt;/i&gt; of the curve that &lt;code&gt;border-radius&lt;/code&gt; creates. Without &lt;code&gt;border-radius&lt;/code&gt;, &lt;code&gt;corner-shape&lt;/code&gt; does nothing. But together, they’re a powerful pair.&lt;/p&gt;&lt;p&gt;The property accepts these values:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;&lt;code&gt;round&lt;/code&gt;&lt;/b&gt;: the default, same as regular &lt;code&gt;border-radius&lt;/code&gt;,&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;code&gt;squircle&lt;/code&gt;&lt;/b&gt;: a superellipse, the smooth Apple-style rounded square,&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;code&gt;bevel&lt;/code&gt;&lt;/b&gt;: a straight line between the two radius endpoints (snipped corners),&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;code&gt;scoop&lt;/code&gt;&lt;/b&gt;: an inverted curve, creating concave corners,&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;code&gt;notch&lt;/code&gt;&lt;/b&gt;: sharp inward cuts,&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;code&gt;square&lt;/code&gt;&lt;/b&gt;: effectively removes the rounding, overriding &lt;code&gt;border-radius&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;And you can set different values per corner, just like &lt;code&gt;border-radius&lt;/code&gt;:&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class="language-css"&gt;&lt;code class="language-css"&gt;*&lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; bevel round scoop squircle&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token comment"&gt;/* top-left, top-right, bottom-right, bottom-left */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;You can also use the &lt;a href="https://css-tricks.com/almanac/functions/s/superellipse/"&gt;&lt;code&gt;superellipse()&lt;/code&gt;&lt;/a&gt; function with a numeric parameter for fine-grained control.&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class="language-css"&gt;&lt;code class="language-css"&gt;&lt;span class="token selector"&gt;.element&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt; 
  &lt;span class="token property"&gt;border-radius&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; 25px&lt;span class="token punctuation"&gt;;&lt;/span&gt;
  &lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; &lt;span class="token function"&gt;superellipse&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;0&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt; &lt;span class="token comment"&gt;/* equal to 'bevel' */&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;So the question here might be: why not call this property “&lt;code&gt;border-shape&lt;/code&gt;” instead? Well, first of all, that is &lt;a href="https://una.im/border-shape"&gt;something completely different that we’ll get to play around with soon&lt;/a&gt;. Second, it does apply to a bit more than borders, such as outlines, box shadows, and backgrounds. That’s the thing that the &lt;code&gt;clip-path&lt;/code&gt; property could never do.&lt;/p&gt;&lt;h2 id="why-progressive-enhancement-matters-here"&gt;Why Progressive Enhancement Matters Here&lt;/h2&gt;&lt;p&gt;At the time of writing (March 2026), &lt;code&gt;corner-shape&lt;/code&gt;
 is only supported in Chrome 139+ and other Chromium-based browsers. 
That’s a significant chunk of users, but certainly not everyone. The 
temptation is to either ignore the property until it’s everywhere or to 
build demos that fall apart without it.&lt;/p&gt;&lt;p&gt;I don’t think either approach is right. The way I see it, &lt;code&gt;corner-shape&lt;/code&gt; is the perfect candidate for progressive enhancement, just as &lt;code&gt;border-radius&lt;/code&gt; was in the age of Internet Explorer 6. The baseline should use the techniques we already know, such as &lt;code&gt;border-radius&lt;/code&gt;, &lt;code&gt;clip-path&lt;/code&gt;, &lt;code&gt;radial-gradient&lt;/code&gt; masks and look intentionally good. Then, for browsers that support &lt;code&gt;corner-shape&lt;/code&gt;,
 we upgrade the experience. Sometimes this can be as simple as just 
providing a more basic default; sometimes it might need to be a bit 
more.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Every demo in this article is created with that progressive enhancement idea.&lt;/b&gt; The structure for the demos looks like:&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class="language-css"&gt;&lt;code class="language-css"&gt;&lt;span class="token atrule"&gt;&lt;span class="token rule"&gt;@layer&lt;/span&gt; base&lt;span class="token punctuation"&gt;,&lt;/span&gt; presentation&lt;span class="token punctuation"&gt;,&lt;/span&gt; demo&lt;span class="token punctuation"&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;presentation&lt;/code&gt; layer contains the full polished UI using proven techniques. The &lt;code&gt;demo&lt;/code&gt; layer wraps everything in &lt;code&gt;@supports&lt;/code&gt;:&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class="language-css"&gt;&lt;code class="language-css"&gt;&lt;span class="token atrule"&gt;&lt;span class="token rule"&gt;@layer&lt;/span&gt; demo&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
  &lt;span class="token atrule"&gt;&lt;span class="token rule"&gt;@supports&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; bevel&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
    &lt;span class="token comment"&gt;/* upgrade styles here */&lt;/span&gt;
  &lt;span class="token punctuation"&gt;}&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;No
 fallback banners, no “your browser doesn’t support this” messages. Just
 two tiers of design: good and better. I thought it could be nice just 
to show some examples. There are a few out there already, but I hope I 
can add a bit of extra inspiration on top of those.&lt;/p&gt;&lt;h2 id="demo-1-product-cards-with-ribbon-badges"&gt;Demo 1: Product Cards With Ribbon Badges&lt;/h2&gt;&lt;p&gt;Every
 e-commerce site has them: those little “New” or “Sale” badges pinned to
 the corner of a product card. Traditionally, getting that ribbon shape 
means reaching for &lt;code&gt;clip-path: polygon()&lt;/code&gt; or a rotated 
pseudo-element, let’s call it “fiddly code” that has the chance to fall 
apart the moment someone changes a padding value.&lt;/p&gt;&lt;p&gt;But here’s the thing: we don’t &lt;i&gt;need&lt;/i&gt; the ribbon shape in the baseline. A simple badge with slightly rounded corners tells the same story and looks perfectly fine:&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class="language-css"&gt;&lt;code class="language-css"&gt;&lt;span class="token selector"&gt;.product__badge&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
  &lt;span class="token property"&gt;border-radius&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; 0 4px 4px 0&lt;span class="token punctuation"&gt;;&lt;/span&gt;
  &lt;span class="token property"&gt;background-color&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; &lt;span class="token function"&gt;var&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;--badge-bg&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;That’s
 it. A small, clean label sitting flush against the left edge of the 
card. Nothing fancy, nothing broken. It works in every browser.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/1-product-cards-corner-badges.png"&gt;&lt;img alt="Product cards with colored corner badges like “New,” “–30%,” and “Limited.”" height="450" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/1-product-cards-corner-badges.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;&lt;br /&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;For browsers that support &lt;code&gt;corner-shape&lt;/code&gt;, we enhance:&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class="language-css"&gt;&lt;code class="language-css"&gt;&lt;span class="token atrule"&gt;&lt;span class="token rule"&gt;@layer&lt;/span&gt; demo&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
  &lt;span class="token comment"&gt;/* If the browser supports `corner-shape` */&lt;/span&gt;
  &lt;span class="token atrule"&gt;&lt;span class="token rule"&gt;@supports&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; bevel&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
    &lt;span class="token selector"&gt;.product&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
      &lt;span class="token property"&gt;border-radius&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; 40px&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; squircle&lt;span class="token punctuation"&gt;;&lt;/span&gt;
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;

    &lt;span class="token selector"&gt;.product__badge&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
      &lt;span class="token property"&gt;padding&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; 0.35rem 1.4rem 0.35rem 1rem&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token property"&gt;border-radius&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; 0 16px 16px 0&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; round bevel bevel round&lt;span class="token punctuation"&gt;;&lt;/span&gt;
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;
  &lt;span class="token punctuation"&gt;}&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;round bevel bevel round&lt;/code&gt; combination creates a directional ribbon. Round where it meets the card edge, beveled to a point on the other side. No &lt;code&gt;clip-path&lt;/code&gt;, no pseudo-element tricks. Borders, shadows, and backgrounds all follow the declared shape because it &lt;i&gt;is&lt;/i&gt; the shape.&lt;/p&gt;&lt;p&gt;The cards themselves upgrade from &lt;code&gt;border-radius: 12px&lt;/code&gt; to a larger size and the &lt;code&gt;squircle&lt;/code&gt;
 corner-shape, that smooth superellipse curve that makes standard 
rounding look slightly off by comparison. Designers will notice 
immediately. Everyone else will just say it “feels more premium.”&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/2-product-cards-ribbon-badges.png"&gt;&lt;img alt="Product cards with arrow-shaped corner badges labeled “New,” “–30%,” and “Limited,” pointing inward." height="450" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/2-product-cards-ribbon-badges.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;&lt;br /&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;b&gt;Hot tip:&lt;/b&gt; Using the &lt;code&gt;squircle&lt;/code&gt;
 value on card components is one of those upgrades where the 
before-and-after difference can be subtle in isolation, but 
transformative across an entire page. It’s the iOS effect: once 
everything uses superellipse curves, plain circular arcs start looking 
out of place. In this demo, I did exaggerate a bit.&lt;/p&gt;&lt;figure class="break-out"&gt;&lt;div&gt;&lt;/div&gt;&lt;figcaption&gt;See the Pen &lt;a href="https://codepen.io/smashingmag/pen/GgjNwQE"&gt;Corner-shape: Labels [forked]&lt;/a&gt; by &lt;a href="https://codepen.io/utilitybend"&gt;utilitybend&lt;/a&gt;.&lt;/figcaption&gt;&lt;/figure&gt;&lt;h2 id="demo-2-buttons-tags-and-components"&gt;Demo 2: Buttons, Tags, And Components&lt;/h2&gt;&lt;p&gt;This is the “component library demo”, the one that shows &lt;code&gt;corner-shape&lt;/code&gt;
 isn’t just for hero sections. It’s practical, everyday UI: solid 
buttons, outlined buttons, status tags, directional arrows, notification
 badges.&lt;/p&gt;&lt;p&gt;The set-up is intentionally clean. Standard &lt;code&gt;border-radius: 10px&lt;/code&gt; buttons with a polished typeface. Everything works, everything looks professional. You could do this without hesitation.&lt;/p&gt;&lt;p&gt;The &lt;code&gt;corner-shape&lt;/code&gt; layer turns it into a showcase. Each button type gets its own shape to demonstrate the range of what’s possible:&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class="language-css"&gt;&lt;code class="language-css"&gt;&lt;span class="token atrule"&gt;&lt;span class="token rule"&gt;@layer&lt;/span&gt; demo&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
  &lt;span class="token atrule"&gt;&lt;span class="token rule"&gt;@supports&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; bevel&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
    &lt;span class="token selector"&gt;.btn--primary&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
      &lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; bevel&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token property"&gt;transition&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; corner-shape 0.3s ease&lt;span class="token selector"&gt;;

      &amp;amp;:hover&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
        &lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; squircle&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token punctuation"&gt;}&lt;/span&gt;
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;

    &lt;span class="token selector"&gt;.btn--secondary&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
      &lt;span class="token property"&gt;border-radius&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; 25px&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; &lt;span class="token function"&gt;superellipse&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;0.5&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;

    &lt;span class="token selector"&gt;.btn--danger&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
      &lt;span class="token property"&gt;border-radius&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; 16px&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; squircle&lt;span class="token punctuation"&gt;;&lt;/span&gt;
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;

    &lt;span class="token selector"&gt;.btn--notch&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
      &lt;span class="token property"&gt;border-radius&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; 12px&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; notch&lt;span class="token punctuation"&gt;;&lt;/span&gt;
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;

    &lt;span class="token selector"&gt;.btn--scoop&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
      &lt;span class="token property"&gt;border-radius&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; 14px&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; scoop&lt;span class="token punctuation"&gt;;&lt;/span&gt;
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;
  &lt;span class="token punctuation"&gt;}&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/3-buttons-before.png"&gt;&lt;img alt="Buttins and tags before" height="450" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/3-buttons-before.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Before.&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/4-buttons-after.png"&gt;&lt;img alt="Buttins and tags after" height="450" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/4-buttons-after.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;After.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;The primary button starts beveled, faceted, and gem-like, and softens to &lt;code&gt;squircle&lt;/code&gt; on hover. Because &lt;code&gt;corner-shape&lt;/code&gt; values animate via their &lt;code&gt;superellipse()&lt;/code&gt;
 equivalents, the transition is smooth. It’s a fun interaction that used
 to be hard to achieve but is now a single property (used alongside &lt;code&gt;border-radius&lt;/code&gt;, of course).&lt;/p&gt;&lt;p&gt;The secondary button uses &lt;code&gt;superellipse(0.5)&lt;/code&gt;, a value that is &lt;i&gt;between&lt;/i&gt; a standard circle and a squircle, combined with a larger &lt;code&gt;border-radius&lt;/code&gt; for a distinctive pill-like shape. The danger button gets a more prominent &lt;code&gt;squircle&lt;/code&gt; with a generous radius. And &lt;code&gt;notch&lt;/code&gt; and &lt;code&gt;scoop&lt;/code&gt; each bring their own sharp or concave personality.&lt;/p&gt;&lt;p&gt;Beyond buttons, the status tags get &lt;code&gt;corner-shape: notch&lt;/code&gt;, those sharp inward cuts that give them a machine-stamped look. The directional arrow tags use &lt;code&gt;round bevel bevel round&lt;/code&gt; (and its reverse for the back arrow), replacing what used to require &lt;code&gt;clip-path: polygon()&lt;/code&gt;. Now borders and shadows work correctly across all states.&lt;/p&gt;&lt;figure class="break-out"&gt;&lt;div&gt;&lt;/div&gt;&lt;figcaption&gt;See the Pen &lt;a href="https://codepen.io/smashingmag/pen/gbwLQdG"&gt;Corner-shape: Buttons &amp;amp; Tags [forked]&lt;/a&gt; by &lt;a href="https://codepen.io/utilitybend"&gt;utilitybend&lt;/a&gt;.&lt;/figcaption&gt;&lt;/figure&gt;&lt;h2 id="demo-3-testimonial-cards"&gt;Demo 3: Testimonial Cards&amp;nbsp;&lt;/h2&gt;&lt;p&gt;This
 demo is probably my favourite one. At its foundation, these are just 
testimonial cards with serif typography, a sandy palette, and scooped 
corners on the featured card. The design language is intentionally 
different from the clean geometric buttons demo, and that’s the point. &lt;code&gt;corner-shape&lt;/code&gt; merely adds that extra “edge”.&lt;/p&gt;&lt;p&gt;The basis is standard &lt;code&gt;border-radius: 16px&lt;/code&gt;
 cards. The featured testimonial spans full width with a subtle gradient
 and a decorative open quote mark. Normal cards alternate in a 
two-column grid. It already looks like something from a premium 
marketing site.&lt;/p&gt;&lt;p&gt;The &lt;code&gt;corner-shape&lt;/code&gt; layer adds character:&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class="language-css"&gt;&lt;code class="language-css"&gt;&lt;span class="token atrule"&gt;&lt;span class="token rule"&gt;@layer&lt;/span&gt; demo&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
  &lt;span class="token comment"&gt;/* Progressive enhancement */&lt;/span&gt;
  &lt;span class="token atrule"&gt;&lt;span class="token rule"&gt;@supports&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; scoop&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
    &lt;span class="token selector"&gt;.testimonial&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
      &lt;span class="token property"&gt;border-radius&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; 20px&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; squircle&lt;span class="token punctuation"&gt;;&lt;/span&gt;
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;

    &lt;span class="token selector"&gt;.testimonial--featured&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
      &lt;span class="token property"&gt;border-radius&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; 24px&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; scoop&lt;span class="token punctuation"&gt;;&lt;/span&gt;
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;

    &lt;span class="token selector"&gt;.testimonial:not(.testimonial--featured):nth-child(even)&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
      &lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; scoop round&lt;span class="token punctuation"&gt;;&lt;/span&gt;
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;

    &lt;span class="token selector"&gt;.testimonial__avatar&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
      &lt;span class="token property"&gt;border-radius&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; 28%&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; squircle&lt;span class="token punctuation"&gt;;&lt;/span&gt;
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;
  &lt;span class="token punctuation"&gt;}&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The featured card gets full &lt;code&gt;scoop&lt;/code&gt;
 corners, concave on all four sides, creating an organic, almost 
hand-crafted feel that matches the serif typography. Even-numbered cards
 mix &lt;code&gt;scoop round&lt;/code&gt;, giving each one a slightly different personality without any extra markup.&lt;/p&gt;&lt;p&gt;The author avatars switch from circles to &lt;code&gt;squircle&lt;/code&gt;. A small touch that makes it a bit more “different”.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/5-testimonials-before.png"&gt;&lt;img alt="Testimonials before" height="450" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/5-testimonials-before.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Fallback.&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/6-testimonials-after.png"&gt;&lt;img alt="Testimonials after" height="450" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/6-testimonials-after.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Supported.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;b&gt;Hot tip:&lt;/b&gt; &lt;code&gt;corner-shape: scoop&lt;/code&gt;
 pairs beautifully with serif fonts and warm color palettes. The concave
 curves echo the organic shapes found in editorial design, calligraphy, 
and print layouts. For geometric sans-serif designs, stick with &lt;code&gt;squircle&lt;/code&gt; or &lt;code&gt;bevel&lt;/code&gt;.&lt;/p&gt;&lt;figure class="break-out"&gt;&lt;div&gt;&lt;/div&gt;&lt;figcaption&gt;See the Pen &lt;a href="https://codepen.io/smashingmag/pen/RNGoqvZ"&gt;Corner-shape: Testimonials [forked]&lt;/a&gt; by &lt;a href="https://codepen.io/utilitybend"&gt;utilitybend&lt;/a&gt;.&lt;/figcaption&gt;&lt;/figure&gt;&lt;h2 id="demo-4-pricing-cards"&gt;Demo 4: Pricing Cards&lt;/h2&gt;&lt;p&gt;Every
 SaaS site needs a pricing page, and the visual hierarchy challenge is 
always the same: make one plan stand out without the others feeling 
neglected. This demo solves it with &lt;code&gt;corner-shape&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;This is quite similar to the last demo in that we once again have a nice baseline for browsers that don’t yet support &lt;code&gt;corner-shape&lt;/code&gt;.
 We have three cards in a row, where the featured plan is distinguished 
by a warm gradient background, a stronger border, and a “Most Popular” 
badge.&lt;/p&gt;&lt;p&gt;The enhancement takes it further:&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class="language-css"&gt;&lt;code class="language-css"&gt;&lt;span class="token atrule"&gt;&lt;span class="token rule"&gt;@layer&lt;/span&gt; demo&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
  &lt;span class="token atrule"&gt;&lt;span class="token rule"&gt;@supports&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; squircle&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
    &lt;span class="token selector"&gt;.plan&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
      &lt;span class="token property"&gt;border-radius&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; 20px&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; squircle&lt;span class="token punctuation"&gt;;&lt;/span&gt;
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;

    &lt;span class="token selector"&gt;.plan--featured&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
      &lt;span class="token property"&gt;border-radius&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; 24px&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; scoop&lt;span class="token punctuation"&gt;;&lt;/span&gt;
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;

    &lt;span class="token selector"&gt;.plan__badge&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
      &lt;span class="token property"&gt;inset-inline-start&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; 50%&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token property"&gt;translate&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; -50% 0&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token property"&gt;padding-inline&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; 1.2rem&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token property"&gt;border-radius&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; 10px&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; bevel&lt;span class="token punctuation"&gt;;&lt;/span&gt;
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;

    &lt;span class="token selector"&gt;.plan__cta&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
      &lt;span class="token property"&gt;border-radius&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; 12px&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; squircle&lt;span class="token punctuation"&gt;;&lt;/span&gt;
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;
  &lt;span class="token punctuation"&gt;}&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Regular plans get &lt;code&gt;squircle&lt;/code&gt; for that premium feel. The featured plan gets &lt;code&gt;scoop&lt;/code&gt;, concave corners that immediately set it apart from its neighbors. The “Most Popular” badge centers itself and takes on &lt;code&gt;corner-shape: bevel&lt;/code&gt;, creating a gem-like, faceted shape that feels like a jewel pinned to the card. The CTA buttons get &lt;code&gt;squircle&lt;/code&gt; to match the card language.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/7-pricing-before.png"&gt;&lt;img alt="Pricing cards: before" height="450" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/7-pricing-before.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Before. (&lt;a href="https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/7-pricing-before.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/8-pricing-after.png"&gt;&lt;img alt="Pricing cards: after" height="450" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/8-pricing-after.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;After.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;What
 I like about this demo is how the shape hierarchy mirrors the content 
hierarchy. The most important element (featured plan) gets the most 
distinctive shape (&lt;code&gt;scoop&lt;/code&gt;). The badge gets the sharpest shape (&lt;code&gt;bevel&lt;/code&gt;). Everything else gets a simpler upgrade (&lt;code&gt;squircle&lt;/code&gt;). Shape becomes a tool for visual emphasis, not just decoration.&lt;/p&gt;&lt;figure class="break-out"&gt;&lt;div&gt;&lt;/div&gt;&lt;figcaption&gt;See the Pen &lt;a href="https://codepen.io/smashingmag/pen/vEXyQMZ"&gt;Corner-shape: Pricing [forked]&lt;/a&gt; by &lt;a href="https://codepen.io/utilitybend"&gt;utilitybend&lt;/a&gt;.&lt;/figcaption&gt;&lt;/figure&gt;&lt;h2 id="demo-5-music-player"&gt;Demo 5: Music Player&lt;/h2&gt;&lt;p&gt;The
 final demo is a warm dark UI for a music player with album art, 
playback controls, genre tags, and a listening queue. It’s the most 
visually complex demo, and it shows how &lt;code&gt;corner-shape&lt;/code&gt; works across many different element types within a single cohesive design.&lt;/p&gt;&lt;p&gt;This time, I went for a dark warm palette built on &lt;code&gt;oklch(18% 0.015 40)&lt;/code&gt;, and standard rounded corners throughout. The album art gets &lt;code&gt;border-radius: 12px&lt;/code&gt;, queue items get &lt;code&gt;border-radius: 12px&lt;/code&gt;, genre tags get &lt;code&gt;border-radius: 5px&lt;/code&gt;. It looks good. It’s a complete, polished player.&lt;/p&gt;&lt;p&gt;And then once again, we add some enhancements:&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class="language-css"&gt;&lt;code class="language-css"&gt;&lt;span class="token atrule"&gt;&lt;span class="token rule"&gt;@layer&lt;/span&gt; demo&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
  &lt;span class="token atrule"&gt;&lt;span class="token rule"&gt;@supports&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; squircle&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
    &lt;span class="token selector"&gt;.now-playing&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
      &lt;span class="token property"&gt;border-radius&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; 20px&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; squircle&lt;span class="token punctuation"&gt;;&lt;/span&gt;
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;

    &lt;span class="token selector"&gt;.now-playing__art&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
      &lt;span class="token property"&gt;border-radius&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; 16px&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; squircle&lt;span class="token punctuation"&gt;;&lt;/span&gt;
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;

    &lt;span class="token selector"&gt;.now-playing__swatch&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
      &lt;span class="token property"&gt;border-radius&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; 26%&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; squircle&lt;span class="token punctuation"&gt;;&lt;/span&gt;
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;

    &lt;span class="token selector"&gt;.queue-item&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
      &lt;span class="token property"&gt;border-radius&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; 14px&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; scoop round&lt;span class="token punctuation"&gt;;&lt;/span&gt;
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;

    &lt;span class="token selector"&gt;.tag&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
      &lt;span class="token property"&gt;border-radius&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; 8px&lt;span class="token punctuation"&gt;;&lt;/span&gt;
      &lt;span class="token property"&gt;corner-shape&lt;/span&gt;&lt;span class="token punctuation"&gt;:&lt;/span&gt; bevel&lt;span class="token punctuation"&gt;;&lt;/span&gt;
    &lt;span class="token punctuation"&gt;}&lt;/span&gt;
  &lt;span class="token punctuation"&gt;}&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The player card and album art get &lt;code&gt;squircle&lt;/code&gt;, the same curves used for app icons and album thumbnails. Album art swatches go from &lt;code&gt;border-radius: 22%&lt;/code&gt; to a proper &lt;code&gt;squircle&lt;/code&gt; at &lt;code&gt;26%&lt;/code&gt;, which is a subtle but meaningful difference in the visual elements you stare at while listening.&lt;/p&gt;&lt;p&gt;Queue items get &lt;code&gt;scoop round&lt;/code&gt;,
 resulting in concave corners on the top-left and bottom-left, and round
 on the right. It gives each row a distinctive feel without overwhelming
 the layout. Genre tags get &lt;code&gt;bevel&lt;/code&gt; for that sharp feeling.&lt;/p&gt;&lt;p&gt;The Play button also gets &lt;code&gt;corner-shape: squircle&lt;/code&gt; on its existing &lt;code&gt;border-radius: 50%&lt;/code&gt;
 to fit the album covers. On the surface, the difference is barely 
noticeable, but it contributes to the overall feel of the player.&lt;/p&gt;&lt;figure class="break-out"&gt;&lt;div&gt;&lt;/div&gt;&lt;figcaption&gt;See the Pen &lt;a href="https://codepen.io/smashingmag/pen/ogzYQRB"&gt;Corner-shape: Music player [forked]&lt;/a&gt; by &lt;a href="https://codepen.io/utilitybend"&gt;utilitybend&lt;/a&gt;.&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/9-music-before.png"&gt;&lt;img alt="Music player: before" height="450" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/9-music-before.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Before. (&lt;a href="https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/9-music-before.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/10-music-after.png"&gt;&lt;img alt="Music player: after" height="450" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/beyond-border-radius-css-corner-shape-property-ui/10-music-after.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;After.&lt;/figcaption&gt;&lt;/figure&gt;&lt;h2 id="browser-support"&gt;Browser Support&lt;/h2&gt;&lt;p&gt;As of writing, &lt;code&gt;corner-shape&lt;/code&gt; is available in Chrome 139+ and Chromium-based browsers. Firefox and Safari don’t support it yet. The spec lives in &lt;a href="https://drafts.csswg.org/css-borders/#propdef-corner-shape"&gt;CSS Borders and Box Decorations Module Level 4&lt;/a&gt;, which is a W3C Working Draft as of this writing.&lt;/p&gt;&lt;p&gt;For practical use, that’s fine. That’s the whole point of how these demos are built. The &lt;code&gt;presentation&lt;/code&gt; layer delivers a polished, complete UI to every browser. The &lt;code&gt;demo&lt;/code&gt; layer is a bonus for supporting browsers, wrapped in &lt;code&gt;@supports (corner-shape: ...)&lt;/code&gt;. I lived through the time when &lt;code&gt;border-radius&lt;/code&gt;
 was only available in Firefox. Somewhere along the line, it seems like 
we have forgotten that not every website needs to look exactly the same 
in every browser. What we really want is: no “broken” layouts and no 
“your browser doesn’t support this” messages, but rather a beautiful 
experience that just works, and can progressively enhance a bit of extra
 joy. In other words, we’re working with two tiers of design: good and 
better.&lt;/p&gt;&lt;h2 id="wrapping-up"&gt;Wrapping Up&lt;/h2&gt;&lt;p&gt;The approach I keep coming back to is: don’t design for &lt;code&gt;corner-shape&lt;/code&gt;, and don’t design &lt;i&gt;around&lt;/i&gt; the lack of it. Design a solid baseline with &lt;code&gt;border-radius&lt;/code&gt;
 and then enhance it. The presentation layer in every demo looks 
intentionally good. It’s not a degraded version waiting for a better 
browser. It’s a &lt;b&gt;complete design&lt;/b&gt;. The &lt;code&gt;demo&lt;/code&gt; layer adds a dimension that &lt;code&gt;border-radius&lt;/code&gt; alone can’t express.&lt;/p&gt;&lt;p&gt;What surprises me most about &lt;code&gt;corner-shape&lt;/code&gt; is the &lt;i&gt;range&lt;/i&gt; it offers — the amazing powerhouse we have with this single property: &lt;code&gt;squircle&lt;/code&gt; for that premium, superellipse feel on cards and avatars; &lt;code&gt;bevel&lt;/code&gt; for directional elements and gem-like badges; &lt;code&gt;scoop&lt;/code&gt; for editorial warmth and visual hierarchy; &lt;code&gt;notch&lt;/code&gt; for mechanical precision on tags; and &lt;code&gt;superellipse()&lt;/code&gt; for fine control between &lt;code&gt;round&lt;/code&gt; and &lt;code&gt;squircle&lt;/code&gt;. And the ability to mix values per corner (&lt;code&gt;round bevel bevel round&lt;/code&gt;, &lt;code&gt;scoop round&lt;/code&gt;) opens up shapes that would have required SVG masks or &lt;code&gt;clip-path&lt;/code&gt; hacks.&lt;/p&gt;&lt;p&gt;We went from five background images to &lt;code&gt;border-radius&lt;/code&gt;, to &lt;code&gt;corner-shape&lt;/code&gt;. Each step removed a category of workarounds. I’m excited to see what designers do with this one.&lt;/p&gt;&lt;h3 id="further-reading"&gt;Further Reading&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/corner-shape"&gt;&lt;code&gt;corner-shape&lt;/code&gt;&lt;/a&gt; (MDN)&lt;/li&gt;&lt;li&gt;“&lt;a href="https://css-tricks.com/what-can-we-actually-do-with-corner-shape/"&gt;What Can We Actually Do With &lt;code&gt;corner-shape&lt;/code&gt;?&lt;/a&gt;”, Daniel Schwarz&lt;/li&gt;&lt;li&gt;&lt;a href="https://drafts.csswg.org/css-borders/#propdef-corner-shape"&gt;CSS Borders and Box Decorations Module Level 4&lt;/a&gt; (W3C specification)&lt;/li&gt;&lt;li&gt;&lt;a href="https://codepen.io/bySebastian/pen/VYjPzYo"&gt;A fun demo for “eco-labels”&lt;/a&gt;, Sebastian on CodePen&lt;/li&gt;&lt;/ul&gt;</description><link>http://honeyvig.blogspot.com/2026/04/beyond-border-radius-what-css-corner.html</link><author>noreply@blogger.com (H)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9165069509664255576.post-8810384284336347610</guid><pubDate>Wed, 01 Apr 2026 12:50:00 +0000</pubDate><atom:updated>2026-04-01T05:50:17.829-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Design</category><category domain="http://www.blogger.com/atom/ns#">Psychology</category><category domain="http://www.blogger.com/atom/ns#">Usability</category><category domain="http://www.blogger.com/atom/ns#">UX</category><title>Persuasive Design: Ten Years Later</title><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="c-garfield-summary"&gt;&lt;section aria-label="Quick summary" class="article__summary"&gt;Many
 product teams still lean on usability improvements and isolated 
behavioral tweaks to address weak activation, drop-offs, and low 
retention – only to see results plateau or slip into shallow 
gamification. Anders Toxboe updates persuasive design for today’s 
reality, clarifying what has actually held up over the last decade and 
how modern frameworks can guide both discovery and ideation.&lt;/section&gt;&lt;/div&gt;&lt;p&gt;Ten
 years ago, persuasive design was a relatively new frontier in the field
 of UX. In a 2015 Smashing article, I was among those who &lt;a href="https://www.smashingmagazine.com/2015/10/beyond-usability-designing-with-persuasive-patterns"&gt;showed a way&lt;/a&gt;
 for practitioners to move from being primarily focused on improving 
usability and removing friction to also guide users toward a desired 
outcome. The premise was simple: by leveraging &lt;strong&gt;psychology&lt;/strong&gt;,
 we could influence user behavior and drive outcomes like higher 
sign-ups, faster and richer onboarding, and stronger retention and 
engagement.&lt;/p&gt;&lt;p&gt;A decade later, that promise has proven true — but not
 in the same way many of us expected. Most product teams still face 
familiar problems: high bounce rates, weak activation, and users 
dropping off before experiencing core value. Usability improvements 
help, but they don’t always address the behavioral gap that sits 
underneath these patterns.&lt;/p&gt;&lt;p&gt;Persuasive design didn’t disappear — it matured.&lt;/p&gt;&lt;p&gt;Today, the more useful version of this work is often called &lt;strong&gt;behavioral design&lt;/strong&gt;:
 a way to align product experiences with the real drivers of human 
behavior, with an ethical mindset. Done well, it can improve conversion,
 onboarding completion, engagement, and long-term use without slipping 
into manipulation.&lt;/p&gt;&lt;p&gt;Here’s what I’ll cover:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;What has held up from the last decade of persuasive design;&lt;/li&gt;&lt;li&gt;What didn’t hold up, especially the limits of pattern-first gamification;&lt;/li&gt;&lt;li&gt;What changed in how we model behavior, from triggers to context and systems;&lt;/li&gt;&lt;li&gt;How to use &lt;strong&gt;modern behavioral frameworks&lt;/strong&gt; to improve both discovery and ideation;&lt;/li&gt;&lt;li&gt;A practical way to run this work as a team, using a &lt;strong&gt;five-exercise workshop sequence&lt;/strong&gt;, you can adapt to your product.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The
 goal is not to add more tactics to your toolkit. It’s to help you build
 a repeatable, shared approach to diagnosing behavioral barriers and 
designing solutions that support both users’ goals and business 
outcomes.&lt;/p&gt;&lt;h2 id="is-persuasion-the-same-as-deception"&gt;Is Persuasion The Same As Deception?&lt;/h2&gt;&lt;p&gt;Behavioral Design is not about slapping &lt;a href="https://www.deceptive.design/"&gt;deceptive patterns&lt;/a&gt;
 or superficial “growth hacks” onto your UI. It’s about understanding 
what truly enables or hinders your users on their way to achieving their
 goal and then designing experiences that guide them to success.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/persuasive-design-ten-years-later/1-behavioral-design.png"&gt;&lt;img alt="Persuasion vs manipulation" height="404" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/persuasive-design-ten-years-later/1-behavioral-design.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;(&lt;a href="https://files.smashing.media/articles/persuasive-design-ten-years-later/1-behavioral-design.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Behavioral design is more about bridging the gap between &lt;strong&gt;what users want&lt;/strong&gt; (achieving their goals, feeling value) and &lt;strong&gt;what businesses need&lt;/strong&gt; (activation, retention, revenue), creating win-win outcomes where good UX and good business results align.&lt;/p&gt;&lt;p&gt;But like with all powerful tools, they can be used both for good and bad. The difference lies in the &lt;strong&gt;intention of the designer&lt;/strong&gt;.
 Some designers argue for not promoting behavioral or persuasive design,
 while others argue that we need to understand the tools to learn how to
 use them well and how we can easily, and often mindlessly, fall into 
the trap of promoting an unethical lens.&lt;/p&gt;&lt;p&gt;If we are not 
enlightened, then how can we judge what represents good and bad 
practice? If we do not understand how psychology works, then we lack the
 awareness needed to spot our biases. If we don’t understand these 
tools, we can’t spot when they’re misused.&lt;/p&gt;&lt;p&gt;The difference between persuasion and deception is intention, plus accountability.&lt;/p&gt;&lt;h2 id="a-decade-later-what-have-we-learned"&gt;A Decade Later, What Have We learned?&lt;/h2&gt;&lt;p&gt;In
 the early 2010s, many teams treated persuasive design as almost 
synonymous with gamification. If you added points, badges, and 
leaderboards, you were doing psychology. And to be fair, those surface 
mechanics did work in some cases, at least in the short term. They could
 nudge people through onboarding flows or encourage a few extra logins. 
But over the decade, their limits became clear. Once the novelty wore 
off, many of these systems felt shallow. Users learned to ignore streaks
 that did not connect to anything meaningful or dropped out when they 
realized the game layer was not helping them reach a real goal.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/persuasive-design-ten-years-later/2-persuasive-design.png"&gt;&lt;img alt="Diagram contrasting extrinsic rewards (points, praise, prizes, money) with intrinsic rewards like mastery, meaningful work, helping others, well-being, and personal satisfaction." height="533" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/persuasive-design-ten-years-later/2-persuasive-design.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;(&lt;a href="https://files.smashing.media/articles/persuasive-design-ten-years-later/2-persuasive-design.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;This is where &lt;strong&gt;self-determination theory&lt;/strong&gt; has quietly reshaped how serious teams think about motivation. It distinguishes between &lt;strong&gt;extrinsic motivators&lt;/strong&gt;, such as rewards, points, and status, and &lt;strong&gt;intrinsic drivers&lt;/strong&gt;
 like autonomy, competence, and relatedness. Put simply, if your 
“gamification” fights against what people actually care about, it will 
eventually fail. The interventions that have survived are the ones that 
support intrinsic needs. A language learning streak that makes you feel 
more capable and shows progress can work because it makes the core 
activity feel more meaningful and manageable. A badge that only exists 
to move a dashboard number, on the other hand, quickly becomes noise.&lt;/p&gt;&lt;h2 id="lesson-1-from-quick-fixes-to-behavioral-strategy"&gt;Lesson 1: From Quick Fixes To Behavioral Strategy&lt;/h2&gt;&lt;p&gt;One
 key lesson from the past decade is that behavioral design creates the 
most value when it moves beyond isolated fixes and becomes a &lt;strong&gt;deliberate strategy&lt;/strong&gt;.
 Many product teams start with a narrow goal: improve a sign-up rate, 
reduce drop-off, or boost early retention. When standard UX 
optimizations plateau, they turn to psychology for a quick lift, often 
with success.&lt;/p&gt;&lt;p&gt;The biggest opportunity is not one more uplift on a 
stubborn metric, but having a systematic way to understand and shape 
behavior across the product.&lt;/p&gt;&lt;blockquote&gt;Behavioral design isn’t about hacks.&lt;br /&gt;It’s about helping people succeed.&lt;/blockquote&gt;&lt;p&gt;Common
 signals are easy to recognize: people sign up but never finish 
onboarding; they click around once and never return; key features sit 
unused. A behavioral strategy doesn’t just ask “&lt;em&gt;What can we change on this screen?”&lt;/em&gt; It asks what is happening in the user’s mind and context at those moments.&lt;/p&gt;&lt;p&gt;That might lead you to design an onboarding experience that uses &lt;a href="https://learningloop.io/plays/psychology/triggers"&gt;curiosity&lt;/a&gt; and the &lt;a href="https://learningloop.io/plays/psychology/goal-gradient-effect"&gt;goal-gradient effect&lt;/a&gt;
 to guide people to a clear first win, instead of hoping they read a 
help doc. Or it might lead you to design for exploration and commitment 
over time: &lt;a href="https://ui-patterns.com/patterns/Social-proof"&gt;social proof&lt;/a&gt; where it actually matters, &lt;a href="https://learningloop.io/plays/psychology/appropriate-challenges"&gt;appropriate challenges&lt;/a&gt; that stretch but don’t overwhelm, &lt;a href="https://ui-patterns.com/patterns/ProgressiveDisclosure"&gt;progressive disclosure&lt;/a&gt; so advanced features show up when people are ready, and the right &lt;a href="https://learningloop.io/plays/psychology/triggers"&gt;triggers&lt;/a&gt; at the most &lt;a href="https://ui-patterns.com/patterns/Kairos"&gt;opportune moment&lt;/a&gt; instead of random nags.&lt;/p&gt;&lt;blockquote&gt;Great products aren’t just easy to use.&lt;br /&gt;They’re easier to commit to.&lt;/blockquote&gt;&lt;p&gt;Product psychology has shifted from scattered hypotheses to a &lt;a href="https://learningloop.io/playbook-collections/persuasive-patterns/"&gt;growing library of repeatable patterns&lt;/a&gt;.
 Those patterns only shine when they sit inside a coherent behavioral 
model: what users are trying to achieve, what blocks them, and which 
levers the team will pull at each stage.&lt;/p&gt;&lt;p&gt;Simple nudges, inspired by &lt;a href="https://www.amazon.com/Nudge-Improving-Decisions-Health-Happiness/dp/014311526X"&gt;Thaler and Sunstein&lt;/a&gt;, have helped popularize behavioral thinking in design. But we’ve also learned that &lt;a href="https://betteregulation.lumsa.it/repost-rednmr-publication-book-%E2%80%9Cnudge-final-edition%E2%80%9D-juli-ponce-sol%C3%A9"&gt;nudges alone rarely solve deeper behavioral challenges&lt;/a&gt;.
 A behavioral strategy goes further: it blends tactics, grounds them in 
real motivations, and ties experiments to a clear theory of change. The 
goal is not a one-off win on today’s dashboard, but a way of working 
that compounds over time.&lt;/p&gt;&lt;h3 id="lesson-2-game-mechanics-alone-are-not-enough"&gt;Lesson 2: Game Mechanics Alone Are Not Enough&lt;/h3&gt;&lt;p&gt;Game
 mechanics alone are no longer a credible behavioral strategy. Ten years
 ago, adding points, badges, and leaderboards was almost shorthand for 
“we’re doing psychology.” Today, most teams have learned the hard way 
that this is decoration unless it serves a real need.&lt;/p&gt;&lt;p&gt;A behavioral
 approach starts with a blunt question: What is the game layer in 
service of, and for whom? Does it help people make progress that matters
 to them, or does it just keep a dashboard happy? If it ignores 
intrinsic motivation, it will look clever in a slide deck and brittle in
 production.&lt;/p&gt;&lt;p&gt;In practice, that means points and streaks are not 
treated as automatic upgrades anymore. Teams ask whether a mechanic 
helps users feel more competent, more in control, or more connected to 
others. A streak only makes sense if it reflects real progress in a 
skill the user cares about. A leaderboard only adds value if people 
actually want to compare themselves and if the ranking helps them decide
 what to do next. If it does not pass those tests, it is clutter, not a 
motivational engine.&lt;/p&gt;&lt;blockquote&gt;Streaks and badges only work when they support something users truly value.&lt;/blockquote&gt;&lt;p&gt;The
 most effective products now start with the intrinsic side. They are 
clear about what the product helps users become or achieve, and only 
then ask whether a game mechanic can amplify that journey. When game 
elements are added, they live in the core loop rather than on top of it.
 They show mastery, mark meaningful milestones, and reinforce 
self-driven goals. That is the difference between treating gamification 
as a paint job and using it to support users on a path they already care
 about.&lt;/p&gt;&lt;h3 id="lesson-3-from-cause-and-effect-to-holistic-systems-thinking"&gt;Lesson 3: From Cause And Effect To Holistic Systems Thinking&lt;/h3&gt;&lt;p&gt;Early
 persuasive design often assumed a simple logic: find the broken step, 
add the right lever, and users move forward. Nice on a slide, rarely 
true in reality.&lt;/p&gt;&lt;p&gt;People don’t act for a single reason. They have 
context, history, competing goals, mood, time pressure, trust issues, 
and different definitions of success. Two users can take the same step 
for completely different reasons. The same user can behave differently 
on a different day.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/persuasive-design-ten-years-later/3-holistic-systems-thinking-persuasive-design.png"&gt;&lt;img alt="Diagram comparing cause-and-effect thinking (linear, predictable outcomes) with systems thinking (feedback loops, delays, and unknown outcomes)." height="533" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/persuasive-design-ten-years-later/3-holistic-systems-thinking-persuasive-design.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;(&lt;a href="https://files.smashing.media/articles/persuasive-design-ten-years-later/3-holistic-systems-thinking-persuasive-design.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;That’s why &lt;a href="https://en.wikipedia.org/wiki/Systems_thinking"&gt;systems thinking&lt;/a&gt;
 matters. Behavior is shaped by feedback loops and delays, not just one 
trigger. Outcomes we care about, trust, competence, and habit, are built
 over time. A change that boosts this week’s conversion can still weaken
 next month’s retention.&lt;/p&gt;&lt;p&gt;If you have ever shipped a “conversion 
win” and then watched support tickets, refunds, or churn go up, you have
 felt this. The local metric improved. The system got worse.&lt;/p&gt;&lt;p&gt;Your 
design structures either enable people or box them in. Defaults, 
navigation, feedback, pacing, rewards — each of these decisions reshapes
 the system and therefore the journeys people take through it.&lt;/p&gt;&lt;p&gt;So 
the job is not to perfect a single funnel. It is to build an environment
 where multiple valid paths can succeed, and where the system supports 
long-term goals, not just short-term clicks.&lt;/p&gt;&lt;blockquote&gt;The job isn’t to perfect one funnel, but to support multiple valid paths.&lt;/blockquote&gt;&lt;p&gt;A
 mature behavioral strategy is explicit about that. It is designed for 
several paths instead of one “happy flow,” supports autonomy instead of 
forcing compliance, and looks at downstream effects instead of only 
first-step conversion.&lt;/p&gt;&lt;h3 id="lesson-4-from-triggers-to-context"&gt;Lesson 4: From Triggers To Context&lt;/h3&gt;&lt;p&gt;The same shift has happened in the frameworks we use. A decade ago, the &lt;a href="https://www.behaviormodel.org/"&gt;Fogg Behavior Model&lt;/a&gt;
 (FBM) was everywhere. It gave teams a simple trio: motivation, ability,
 trigger — and a clear message: shouting louder with prompts does not 
fix low motivation or poor ability. That alone was a useful upgrade.&lt;/p&gt;&lt;p&gt;Fogg’s
 own work has moved on, too. With Tiny Habits, the focus leans more on 
identity, emotion, and making behaviors feel easy and personally 
meaningful. That mirrors a broader shift in the field: away from “fire 
more prompts” and toward designing environments where the right behavior
 feels natural.&lt;/p&gt;&lt;p&gt;Teams eventually ran into the same wall: prompts 
do not fix low capability or missing opportunity. You cannot nag people 
into skills they do not have or into contexts that do not exist. That is
 where many teams that work deeply with behavior change have gravitated 
toward &lt;a href="https://thedecisionlab.com/reference-guide/organizational-behavior/the-com-b-model-for-behavior-change"&gt;COM-B&lt;/a&gt; as a more complete foundation.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/persuasive-design-ten-years-later/4-fogg-behavior-com-b.png"&gt;&lt;img alt="Diagram comparing Fogg Behavior Mode vs COM-B model" height="341" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/persuasive-design-ten-years-later/4-fogg-behavior-com-b.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;(&lt;a href="https://files.smashing.media/articles/persuasive-design-ten-years-later/4-fogg-behavior-com-b.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;COM-B breaks behavior into &lt;strong&gt;capability&lt;/strong&gt;, &lt;strong&gt;opportunity&lt;/strong&gt;, and &lt;strong&gt;motivation&lt;/strong&gt;.
 It starts with a blunt check: can people actually do this, and does 
their environment let them? That maps well to modern products, where 
behavior happens across devices, channels, and moments, not on a single 
screen. It also plugs into broader behavior change work in health and 
public policy, so we do not have to reinvent everything inside UX.&lt;/p&gt;&lt;p&gt;Thinking
 this way nudges teams away from simple cause-and-effect stories. A drop
 in completion rate is no longer “the button is bad” or “we need more 
reminders,” but a question about how skills, context, and motivation 
interact. A capability issue might need a better interface and better 
education. An opportunity issue might be about device access, timing, or
 social surroundings, not layout. Motivation might be shaped as much by 
pricing and brand trust as by any in-product message.&lt;/p&gt;&lt;blockquote&gt;Modern
 behavioral design is less about activating clicks and more about 
shaping conditions where action feels easy and meaningful.&lt;/blockquote&gt;&lt;p&gt;This
 broader lens also makes cross-functional work simpler. Product, design,
 marketing, and data can share one behavior model and still see their 
own responsibilities in it. Designers shape perceived capability and 
opportunity in the interface, marketing shapes motivational framing and 
triggers, and operations shape the structural opportunity in the 
service. Instead of everyone pushing their own levers in isolation, 
COM-B helps teams see that they are working on different parts of the 
same system.&lt;/p&gt;&lt;h3 id="lesson-5-psychology-can-also-be-used-to-design-and-decode-discovery"&gt;Lesson 5: Psychology Can Also Be Used To Design And Decode Discovery&lt;/h3&gt;&lt;p&gt;COM-B
 is often used as a bridge between discovery and ideation. On the 
discovery side, it gives structure to research. You can use it to design
 interview guides, read analytics, and make sense of observational 
studies. It was built to diagnose what needs to change for a behavior to
 shift, which maps neatly onto early product discovery.&lt;/p&gt;&lt;blockquote&gt;Good discovery doesn’t just ask what users say, but examines what their behavior reveals.&lt;/blockquote&gt;&lt;p&gt;Instead of asking &lt;em&gt;“Why did you stop using the product?”&lt;/em&gt; and writing down the first answer, you deliberately walk through capability, opportunity, and motivation. You ask things like:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Can users actually do this, given their skills and knowledge?&lt;/li&gt;&lt;li&gt;Does their context help or hinder them in practice?&lt;/li&gt;&lt;li&gt;How strong is their motivation compared with other demands on their time and money?&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;You
 walk through recent experiences in detail: which device they used, what
 time of day it was, who else was around, and what else they were 
juggling. You talk about how important this behavior is compared with 
everything else in their life and what trade-offs they make. To 
participants, these questions feel natural. Under the hood, you are 
systematically covering all three parts of COM-B, in line with how 
behavior change practitioners use the model in qualitative work.&lt;/p&gt;&lt;p&gt;You
 can look at behavioral data in the same way. Funnel drop-offs, time on 
task, and click patterns are clues: are people stuck because they cannot
 progress, because the environment gets in the way, or because they do 
not care enough to continue? Modern analytics tools make it easier to 
watch what people actually do rather than only what they report, and 
combining quantitative and qualitative data gives you a fuller picture 
than either alone.&lt;/p&gt;&lt;p&gt;When there is a gap between what people say and what they do, you treat it as a &lt;strong&gt;signal&lt;/strong&gt;
 rather than an irritation. Someone might say that saving for retirement
 is very important, but never set up a recurring transfer. A user might 
claim that onboarding was simple, while their session shows repeated 
back and forth between steps. Those mismatches are often where biases, 
habits, and emotional barriers live. By labelling them in terms of 
capability, opportunity, and motivation, and linking them to specific 
barriers like &lt;a href="https://learningloop.io/plays/psychology/risk-aversion"&gt;risk aversion&lt;/a&gt;, &lt;a href="https://learningloop.io/plays/psychology/analysis-paralysis"&gt;analysis paralysis&lt;/a&gt;, &lt;a href="https://learningloop.io/plays/psychology/status-quo-bias"&gt;status quo bias&lt;/a&gt; or &lt;a href="https://learningloop.io/plays/psychology/present-bias"&gt;present bias&lt;/a&gt;, you move from vague “insights” to a structured map of what is actually in the way.&lt;/p&gt;&lt;blockquote&gt;The gap between what people say and what they do is not noise — it’s the map.&lt;/blockquote&gt;&lt;p&gt;The
 output of this kind of discovery is not just personas and journeys. You
 also get a clear statement of the current behavior, the target 
behavior, and the behavioral barriers and enablers that sit between 
them.&lt;/p&gt;&lt;h3 id="lesson-6-use-behavioral-discovery-in-your-ideation"&gt;Lesson 6: Use Behavioral Discovery In Your Ideation&lt;/h3&gt;&lt;p&gt;The bridge from discovery to ideation can be a single sentence template:&lt;/p&gt;&lt;blockquote&gt;From &lt;strong&gt;current behavior&lt;/strong&gt; to &lt;strong&gt;target behavior&lt;/strong&gt;, by &lt;strong&gt;doing X&lt;/strong&gt;, because of &lt;strong&gt;barrier Y&lt;/strong&gt;.&lt;/blockquote&gt;&lt;p&gt;This
 “from–to–by–why” framing forces teams to say what they actually 
believe. You are not just saying “add a checklist.” You are saying: “We 
believe a checklist will help new users feel more capable, which will 
increase the chance they complete setup in their first session.” Now it 
is a &lt;strong&gt;behavioral hypothesis&lt;/strong&gt; you can test with &lt;a href="https://learningloop.io/playbook-collections/validation-patterns/"&gt;experiments&lt;/a&gt;, not just a design idea you hope for.&lt;/p&gt;&lt;p&gt;From
 there, you can generate several variants that express the same 
principle in different ways and design experiments around them. You 
might try a few messages that all lean on &lt;a href="https://learningloop.io/plays/psychology/loss-aversion"&gt;loss aversion&lt;/a&gt;, or several ways of simplifying a high-friction step, or different forms of &lt;a href="https://learningloop.io/plays/psychology/social-proof"&gt;social proof&lt;/a&gt; that vary in tone and proximity.&lt;/p&gt;&lt;p&gt;The
 important shift is that you are no longer throwing ideas at the wall. 
You are deliberately targeting the capability, opportunity, or 
motivation issues that discovery surfaced, and testing which levers 
actually work in your context.&lt;/p&gt;&lt;blockquote&gt;Every idea should answer one question: which barrier are we trying to change?&lt;/blockquote&gt;&lt;p&gt;Over
 time, this loop between behavioral discovery and ideation turns into a 
local playbook. You learn that in your product, some principles reliably
 help your users and others fall flat. You also learn that patterns from
 glowing case studies do not automatically transfer. Even gamification 
and behavior change research often emphasize &lt;strong&gt;context-specific&lt;/strong&gt;, &lt;strong&gt;user-centred&lt;/strong&gt; implementations rather than generic recipes.&lt;/p&gt;&lt;p&gt;This
 dual use of psychology in discovery and ideation is one of the bigger 
shifts of the past decade. A product trio can look at a stubborn 
drop-off point and ask, together, “Is this a capability, opportunity, or
 motivation issue?” Then they generate ideas that target that part of 
the system instead of guessing. That shared language makes behavioral 
design less of a specialist add-on and more of a normal way for 
cross-functional teams to reason about their work.&lt;/p&gt;&lt;h2 id="a-decade-later-what-has-proven-to-work-in-practice"&gt;A Decade Later: What Has Proven To Work In Practice&lt;/h2&gt;&lt;p&gt;If
 the first decade of persuasive design taught us anything, it is that 
behavioral insight is cheap until a team can act on it together.&lt;/p&gt;&lt;p&gt;Methods matter.&lt;/p&gt;&lt;p&gt;Over
 time, a small set of workshop formats has consistently helped product 
teams uncover behavioral barriers, align on opportunities, and generate 
solutions grounded in real psychology instead of surface patterns. As 
behavioral design has grown from tactical nudges into a strategic 
discipline, an obvious question keeps coming up: &lt;strong&gt;How do teams actually do this work together in practice?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;How
 do product managers, designers, researchers, and engineers move from 
scattered observations (“people seem confused here”) to a shared 
behavioral diagnosis, and then to targeted ideas that reflect the real 
drivers of capability, opportunity, and motivation?&lt;/p&gt;&lt;p&gt;One effective way to make this concrete is through a workshop format. The aim is to help teams:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Interpret research through a behavioral lens,&lt;/li&gt;&lt;li&gt;Surface capability, opportunity, and motivation gaps,&lt;/li&gt;&lt;li&gt;Prioritize high-potential opportunities, and&lt;/li&gt;&lt;li&gt;Generate ideas that are both psychologically sound and ethically considered.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Real
 product work is messy and full of feedback loops; nobody follows a 
perfect step-by-step checklist. But for learning, and especially for 
introducing behavioral design into a team for the first time, a 
structured sequence of exercises gives people a mental model. It shows 
the journey from early discovery to behavioral clarity, from 
opportunities to ideas, and finally to interventions that have been 
stress-tested through an ethical lens.&lt;/p&gt;&lt;p&gt;The exercises below are one
 such recipe. The order is intentional: each step builds on the previous
 one to move from empathy and insight to prioritized opportunities, 
concrete concepts, and responsible solutions. No team will follow it 
letter-perfect every time, but it reflects how behavioral design work 
tends to unfold when it goes well.&lt;/p&gt;&lt;p&gt;Before diving into the details,
 here is the full recipe and how each exercise contributes to the bigger
 behavioral design process:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Behavioral Empathy Mapping&lt;/strong&gt;&lt;br /&gt;Builds a shared understanding of the user’s psychological landscape: emotions, habits, misconceptions, and sources of friction.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Behavioral Journey Mapping&lt;/strong&gt;&lt;br /&gt;Maps the user’s flow over time, and overlays behavioral enablers and obstacles.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Behavior Scoring&lt;/strong&gt;&lt;br /&gt;Prioritizes which behavioral opportunities to tackle first based on impact, feasibility, and evidence.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Ideas First, Patterns Later&lt;/strong&gt;&lt;br /&gt;Encourages context-first ideation, then uses &lt;a href="https://learningloop.io/playbook-collections/persuasive-patterns/"&gt;persuasive patterns&lt;/a&gt; to refine and strengthen promising concepts.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Dark Reality&lt;/strong&gt;&lt;br /&gt;Evaluates ethical risks, unintended consequences, and potential misuse.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;A note on timing:&lt;/strong&gt;
 In practice, this sequence can be run in different formats depending on
 constraints. For a compact format, teams often run Exercises 1–3 in a 
half-day workshop, and Exercises 4–5 in a second half-day session. With 
more time, the work can be spread across a full week: discovery 
synthesis early in the week, prioritization mid-week, and ideation plus 
ethical review toward the end. The structure matters more than the 
schedule; the goal is to preserve the progression from understanding → 
prioritization → ideation → reflection.&lt;/p&gt;&lt;p&gt;Below is a brief walkthrough of each exercise as I typically facilitate them in workshops in tandem with a library of &lt;a href="https://learningloop.io/playbook-collections/persuasive-patterns/"&gt;persuasive patterns&lt;/a&gt;.&lt;/p&gt;&lt;h3 id="exercise-1-behavioral-empathy-mapping"&gt;Exercise 1: Behavioral Empathy Mapping&lt;/h3&gt;&lt;p&gt;The first step is building a shared, psychologically informed understanding of users. &lt;a href="https://learningloop.io/plays/workshop-exercise/behavioral-empathy-mapping"&gt;Behavioral Empathy Mapping&lt;/a&gt;
 extends traditional empathy mapping by paying attention to what users 
attempt, avoid, postpone, misunderstand, or feel uncertain about. These 
subtle behavioral signals often reveal more than stated needs or pain 
points.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; Understand what drives or blocks 
the target behavior by capturing what users think, feel, say, and do — 
and spotting behavioral barriers and enablers.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Steps:&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;On a whiteboard or large paper, draw an empathy map: &lt;em&gt;Thinking &amp;amp; Feeling, Seeing, Saying &amp;amp; Doing, and Hearing&lt;/em&gt;.&lt;/li&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/persuasive-design-ten-years-later/5-empathy-map.png"&gt;&lt;img alt="An empathy map: Thinking &amp;amp; Feeling, Seeing, Saying &amp;amp; Doing, and Hearing." height="515" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/persuasive-design-ten-years-later/5-empathy-map.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;(&lt;a href="https://files.smashing.media/articles/persuasive-design-ten-years-later/5-empathy-map.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;li&gt;Add
 research insights by letting everyone silently add sticky notes from 
interviews, data, support logs, or observations into the quadrants. One 
insight per note.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Identify barriers and enablers.&lt;/strong&gt;&lt;br /&gt;Cluster notes that make the behavior &lt;strong&gt;harder&lt;/strong&gt; (barriers) or &lt;strong&gt;easier&lt;/strong&gt; (enablers).&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;
 A focused map of the psychological and contextual forces shaping the 
target behavior, ready to feed into Behavioral Journey Mapping.&lt;/p&gt;&lt;h3 id="exercise-2-behavioral-journey-mapping"&gt;Exercise 2: Behavioral Journey Mapping&lt;/h3&gt;&lt;p&gt;Once you understand the user’s mindset and context, the next step is to map how those forces play out across time. &lt;a href="https://learningloop.io/plays/workshop-exercise/behavioral-journey-mapping"&gt;Behavioral Journey Mapping&lt;/a&gt;
 overlays the user’s goals, actions, emotions, and environment onto the 
product journey, highlighting the specific moments where behavior tends 
to stall or shift.&lt;/p&gt;&lt;p&gt;Unlike traditional journey maps, the behavioral
 version focuses on where capability breaks down, where the environment 
works against the user, and where motivation fades or conflicts arise. 
These become early signals of where change is both needed and possible.&lt;/p&gt;&lt;p&gt;The
 output shows the team precisely where the product is asking too much, 
where users lack support, or where additional motivation or clarity 
might be required.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; Map the steps from the user’s starting point to the target behavior, and capture the key enablers and barriers along the way.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Steps:&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Draw a horizontal line from A (starting point) to B (target behavior).&lt;/li&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/persuasive-design-ten-years-later/6-behavioral-journey-mapping.png"&gt;&lt;img alt="A horizontal line from A to B." height="97" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/persuasive-design-ten-years-later/6-behavioral-journey-mapping.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;(&lt;a href="https://files.smashing.media/articles/persuasive-design-ten-years-later/6-behavioral-journey-mapping.png"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;li&gt;Have
 everyone write the steps a user takes from A to B on sticky notes (one 
per note). Include actions inside and outside the product.&lt;/li&gt;&lt;li&gt;Place the notes in order along the line. Merge duplicates and align on a shared sequence.&lt;/li&gt;&lt;li&gt;Extend the vertical axis with two rows:&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Enablers&lt;/strong&gt; (what could help users move forward),&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Barriers&lt;/strong&gt; (what could slow or stop users).&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/persuasive-design-ten-years-later/7-behavioral-journey-mapping.png"&gt;&lt;img alt="The vertical axis with two rows: Enablers and Barriers." height="387" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/persuasive-design-ten-years-later/7-behavioral-journey-mapping.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;&lt;br /&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;li&gt;Look for steps with many barriers or few enablers. These are behavioral hot spots.&lt;/li&gt;&lt;li&gt;Highlight the steps where a good nudge could meaningfully help users complete the journey.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt; A clear, behavior-focused journey showing &lt;strong&gt;where users struggle, why, and which moments offer the most leverage for change&lt;/strong&gt;.&lt;/p&gt;&lt;h3 id="exercise-3-behavior-scoring"&gt;Exercise 3: Behavior Scoring&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/03/persuasive-design-ten-years-later/#exercise-3-behavior-scoring"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;With
 a clearer picture of the user journey and what moments could benefit 
from a behaviorally helpful hand, you are now ready to identify the 
behavior it makes most sense to focus on trying to influence.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; Decide which potential target behaviors &lt;a href="https://learningloop.io/plays/workshop-exercise/behavior-scoring"&gt;are worth focusing on first&lt;/a&gt;, based on impact, ease of change, and ease of measurement.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Steps:&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;List
 potential target behaviors. Based on the output of the Behavioral 
Journey Mapping, list behaviors that could potentially be targeted. One 
behavior per sticky note. Be as concrete as possible (what users do, 
where, and when).&lt;/li&gt;&lt;li&gt;Create a table with the following columns:&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Impact of behavior change&lt;/strong&gt; (how much it could move the goal),&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Ease of change&lt;/strong&gt; (how realistic it is to influence),&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Ease of measurement&lt;/strong&gt; (how straightforward it is to track).&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;table class="tablesaw break-out"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Potential target behaviors&lt;/th&gt;&lt;th&gt;Impact of behavior change&lt;/th&gt;&lt;th&gt;Ease of change&lt;/th&gt;&lt;th&gt;Ease of measurement&lt;/th&gt;&lt;th&gt;Total&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td data-label="Potential target behaviors"&gt;…&lt;/td&gt;&lt;td data-label="Impact of behavior change"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td data-label="Ease of change"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td data-label="Ease of measurement"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td data-label="Total"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td data-label="Potential target behaviors"&gt;…&lt;/td&gt;&lt;td data-label="Impact of behavior change"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td data-label="Ease of change"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td data-label="Ease of measurement"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td data-label="Total"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td data-label="Potential target behaviors"&gt;…&lt;/td&gt;&lt;td data-label="Impact of behavior change"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td data-label="Ease of change"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td data-label="Ease of measurement"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td data-label="Total"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;li&gt;Enter each listed behavior into the table and score them from 0 to 10 in each column.&lt;/li&gt;&lt;li&gt;Sort behaviors by total score and discuss the highest-scoring ones:&lt;ul&gt;&lt;li&gt;Do they make sense given what you know about users and constraints?&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Select the primary target behaviors you want to carry into the next exercises.&lt;br /&gt;Optionally, note “bonus behaviors” that might follow as a side effect.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;
 A small set of prioritized target behaviors with a clear rationale for 
why they matter now, and a list of lower-priority behaviors you may 
revisit later.&lt;/p&gt;&lt;p&gt;A filled-out Behavior Scoring table could look like this:&lt;/p&gt;&lt;table class="tablesaw break-out"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Potential target behaviors&lt;/th&gt;&lt;th&gt;Impact of behavior change&lt;/th&gt;&lt;th&gt;Ease of change&lt;/th&gt;&lt;th&gt;Ease of measurement&lt;/th&gt;&lt;th&gt;Total&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td data-label="Potential target behaviors"&gt;User completes onboarding checklist in first session.&lt;/td&gt;&lt;td data-label="Impact of behavior change"&gt;8&lt;/td&gt;&lt;td data-label="Ease of change"&gt;6&lt;/td&gt;&lt;td data-label="Ease of measurement"&gt;9&lt;/td&gt;&lt;td data-label="Total"&gt;23&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td data-label="Potential target behaviors"&gt;User invites at least one teammate within 7 days.&lt;/td&gt;&lt;td data-label="Impact of behavior change"&gt;9&lt;/td&gt;&lt;td data-label="Ease of change"&gt;4&lt;/td&gt;&lt;td data-label="Ease of measurement"&gt;8&lt;/td&gt;&lt;td data-label="Total"&gt;21&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td data-label="Potential target behaviors"&gt;User watches the full product tour video.&lt;/td&gt;&lt;td data-label="Impact of behavior change"&gt;4&lt;/td&gt;&lt;td data-label="Ease of change"&gt;7&lt;/td&gt;&lt;td data-label="Ease of measurement"&gt;6&lt;/td&gt;&lt;td data-label="Total"&gt;17&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td data-label="Potential target behaviors"&gt;User reads help documentation during onboarding.&lt;/td&gt;&lt;td data-label="Impact of behavior change"&gt;3&lt;/td&gt;&lt;td data-label="Ease of change"&gt;5&lt;/td&gt;&lt;td data-label="Ease of measurement"&gt;4&lt;/td&gt;&lt;td data-label="Total"&gt;12&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;In
 this case, the checklist completion emerges as the strongest initial 
focus: it has high impact, is realistically influenceable through design
 changes, and can be measured reliably. Inviting a teammate may be 
strategically important, but it may require broader changes beyond 
interface design, making it a secondary focus.&lt;/p&gt;&lt;h3 id="exercise-4-ideas-first-patterns-later"&gt;Exercise 4: Ideas First, Patterns Later&lt;/h3&gt;&lt;p&gt;Once
 the team has agreed on which behavior matters most, the next risk is 
jumping too quickly to familiar psychological tricks. One of the 
clearest lessons has been that starting with “the pattern” often leads 
to generic solutions that feel clever but fail in context.&lt;/p&gt;&lt;p&gt;This exercise deliberately &lt;a href="https://learningloop.io/plays/workshop-exercise/ideas-first-patterns-later"&gt;separates idea generation from psychological framing&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; Generate solutions grounded in user context first, then use &lt;a href="https://learningloop.io/playbook-collections/persuasive-patterns/"&gt;psychological principles&lt;/a&gt; to sharpen and strengthen them.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Steps:&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Start
 by restating the prioritized target behavior and the key barrier 
identified during journey mapping. Keep this visible throughout the 
exercise.&lt;/li&gt;&lt;li&gt;Then give the team a short, focused ideation window (10–15 minutes).&lt;br /&gt;The
 rule here is simple: no references to behavioral models, cognitive 
biases, or persuasive patterns yet. Ideas should come directly from the 
user context, constraints, and moments uncovered earlier.&lt;/li&gt;&lt;li&gt;Collect
 ideas on a shared surface and group similar concepts. Look for multiple
 ways of solving the same underlying problem (cluster them together).&lt;/li&gt;&lt;li&gt;&lt;p&gt;Only now do you introduce a library of psychological principles and techniques. I developed the &lt;a href="https://learningloop.io/playbook-collections/persuasive-patterns/"&gt;persuasive patterns&lt;/a&gt; for this exact purpose. The goal of this step is not to replace ideas, but to refine them:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Which ideas could be strengthened by reducing friction?&lt;/li&gt;&lt;li&gt;Which might benefit from clearer feedback, social signals, or better timing?&lt;/li&gt;&lt;li&gt;Are there alternative ways to achieve the same effect more respectfully or more clearly?&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Patterns
 are used as lenses, not prescriptions. If a pattern does not improve 
clarity, agency, or usefulness in this context, it is simply ignored.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;
 A refined set of solution concepts that are grounded in real user 
context and supported, where appropriate, by behavioral principles 
rather than driven by them.&lt;/p&gt;&lt;p&gt;This sequencing helps teams avoid 
“pattern-first design,” where ideas are reverse-engineered to fit a 
theory instead of addressing real human situations.&lt;/p&gt;&lt;h3 id="exercise-5-dark-reality"&gt;Exercise 5: Dark Reality&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/03/persuasive-design-ten-years-later/#exercise-5-dark-reality"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Before ideas turn into experiments or shipped features, they need one final test. Not for feasibility or metrics, but for &lt;a href="https://learningloop.io/plays/workshop-exercise/dark-reality"&gt;ethics&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Over
 the years, this step has proven critical. Many persuasive solutions 
only reveal their downside when you imagine them working too well, or 
being applied in the wrong hands, or used on the wrong day by the wrong 
person.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; Surface ethical risks, unintended consequences, and potential misuse before implementation.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Steps:&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Take one or two of the strongest ideas from the previous exercise.&lt;/li&gt;&lt;li&gt;Imagine worst-case scenarios by asking the team to deliberately shift perspective:&lt;ul&gt;&lt;li&gt;What if a competitor used this against us?&lt;/li&gt;&lt;li&gt;What if this nudges users when they’re stressed, tired, or vulnerable?&lt;/li&gt;&lt;li&gt;What happens if this works repeatedly over months, not once?&lt;/li&gt;&lt;li&gt;Could this create pressure, guilt, or dependence?&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Capture concerns around autonomy, trust, fairness, inclusivity, or long-term well-being.&lt;/li&gt;&lt;li&gt;For each risk, explore ways to soften or counterbalance the effect:&lt;ul&gt;&lt;li&gt;Clearer intent or transparency,&lt;/li&gt;&lt;li&gt;Lower frequency or gentler timing,&lt;/li&gt;&lt;li&gt;Explicit opt-outs,&lt;/li&gt;&lt;li&gt;Alternative paths forward.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Some ideas are reshaped. Some are paused.&lt;br /&gt;Some survive intact, but now with greater confidence.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt; Solutions that have been stress-tested ethically, with known risks acknowledged and mitigated rather than ignored.&lt;/p&gt;&lt;h2 id="building-a-shared-vocabulary-for-product-psychology"&gt;Building A Shared Vocabulary For Product Psychology&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/03/persuasive-design-ten-years-later/#building-a-shared-vocabulary-for-product-psychology"&gt;#&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The
 teams that get the most out of behavioral design rarely have a single 
“psychology expert.” Instead, their team shares a vocabulary around 
product psychology and knows how to communicate around customer problem 
behaviorally.&lt;/p&gt;&lt;blockquote&gt;A shared vocabulary turns psychology into cross-functional work.&lt;/blockquote&gt;&lt;p&gt;When patterns and principles are shared:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Product, design, engineering, and marketing can talk about behavior without talking past each other.&lt;/li&gt;&lt;li&gt;Discovery insights are easier to interpret because common barriers and drivers have names.&lt;/li&gt;&lt;li&gt;Ideas can be framed as &lt;strong&gt;behavioral hypotheses&lt;/strong&gt; (“we believe this will increase early competence…”) instead of vague guesses.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The &lt;a href="https://learningloop.io/playbook-collections/persuasive-patterns/"&gt;Persuasive Patterns&lt;/a&gt;
 collection grew from this need: giving teams a common language and a 
concrete set of examples to point at. Whether used as a printed deck in a
 workshop or as long-form references during everyday work, the goal is 
the same: make product psychology something the whole team can see and 
discuss.&lt;/p&gt;&lt;p&gt;Persuasive design was often framed as a bag of tricks. Today, the work looks different:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Game mechanics are used to support &lt;strong&gt;intrinsic motivation&lt;/strong&gt;, not drive vanity engagement.&lt;/li&gt;&lt;li&gt;Frameworks like COM-B and systems thinking help teams see &lt;strong&gt;behavior in context&lt;/strong&gt;, not as a single trigger.&lt;/li&gt;&lt;li&gt;Behavioral insight is used to shape &lt;strong&gt;discovery and ideation&lt;/strong&gt;, not just last-minute copy changes.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Ethics&lt;/strong&gt; is part of the design brief, not an afterthought.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The
 next step is not more sophisticated nudges. It is a more systematic 
practice: simple methods, shared language, and a habit of asking &lt;em&gt;“What is really going on in our users’ lives here?”&lt;/em&gt;&lt;/p&gt;&lt;p&gt;If
 you start by focusing on one behavioral problem, use a couple of the 
exercises in this article, and give your team a shared set of patterns 
to reference, you are already practicing persuasive design in the way it
 has evolved over the last ten years: grounded in evidence, respectful 
of users, and aimed at outcomes that matter on both sides of the screen.&lt;/p&gt;</description><link>http://honeyvig.blogspot.com/2026/04/persuasive-design-ten-years-later.html</link><author>noreply@blogger.com (H)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9165069509664255576.post-2067011368525948125</guid><pubDate>Wed, 01 Apr 2026 05:12:00 +0000</pubDate><atom:updated>2026-04-03T05:23:05.132-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">UI</category><category domain="http://www.blogger.com/atom/ns#">UX</category><category domain="http://www.blogger.com/atom/ns#">Workflow</category><title>Human Strategy In An AI-Accelerated Workflow</title><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="c-garfield-summary"&gt;&lt;section aria-label="Quick summary" class="article__summary"&gt;UX
 design is entering a new phase, with designers shifting from makers of 
outputs to directors of intent. AI can now generate wireframes, 
prototypes, and even design systems in minutes, but UX has never been 
only about creating interfaces. It’s about navigating ambiguity, 
advocating for humans in systems optimised for efficiency, and solving 
their problems through thoughtful design.&lt;/section&gt;&lt;/div&gt;&lt;p&gt;I’ve been 
working in User Experience design for more than twenty years. Long 
enough to have seen the many job titles, from when stakeholders asked us
 to “just make it pretty” to when wireframes were delivered as annotated
 PDFs. I’ve seen many tools come and go over the years, methodologies 
rise and fall, and entire platforms disappear.&lt;/p&gt;&lt;p&gt;Yet, nothing has unsettled designers quite like AI.&lt;/p&gt;&lt;p&gt;When generative AI tools first entered my workflow, my reaction wasn’t excitement — it was &lt;b&gt;unease&lt;/b&gt;, with a little bit of &lt;b&gt;curiosity&lt;/b&gt;.
 Watching an interface appear in seconds, complete with sensible 
spacing, readable typography, and halfway-decent copy, triggered a very 
real fear: &lt;i&gt;If a machine can do this, where does that leave me?&lt;/i&gt;&lt;/p&gt;&lt;p&gt;That fear is now widespread. Designers at every level ask the same question, often quietly, &lt;i&gt;“Will an AI agent replace me by next week/month/year?”&lt;/i&gt;
 While the difference between next week and next year seems a lot, it 
depends on where you are in your career and the speed at which your 
employer chooses to engage with AI tools. I have been lucky in several 
roles to be working with organisations that haven’t allowed the use of 
AI tools due to data security concerns. If you’re interested in any of 
these conversations, you can view the discussions happening on platforms
 like &lt;a href="https://www.reddit.com/r/UXDesign/comments/1oqs2k8/in_reality_how_bad_is_the_ai_replacement/"&gt;Reddit&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Fearing
 the takeover of AI in our roles is not irrational. We’re seeing AI 
generate wireframes, prototypes, personas, usability summaries, 
accessibility suggestions, and entire design systems. Tasks that once 
took days can now literally take minutes.&lt;/p&gt;&lt;p&gt;Here’s the uncomfortable
 truth: If your role is largely about producing artefacts, drawing 
buttons, aligning components, or translating instructions into screens, 
then parts of that work are already being automated.&lt;/p&gt;&lt;p&gt;Still, UX design has &lt;i&gt;never&lt;/i&gt; truly been about just creating a user interface.&lt;/p&gt;&lt;blockquote&gt;UX
 is about navigating ambiguity. It’s about advocating for humans in 
systems optimised for efficiency. It’s about translating messy human 
needs and equally messy business goals into experiences that feel 
coherent, fair, sensible, and usable. It’s about solving human problems 
by creating a useful and effective user experience.&lt;/blockquote&gt;&lt;p&gt;AI isn’t replacing that work. Rather, it’s amplifying everything &lt;i&gt;around&lt;/i&gt; it. The real shift happening is that designers are moving from being &lt;b&gt;makers of outputs&lt;/b&gt; to &lt;b&gt;directors of intent&lt;/b&gt;.
 From creators to curators. From hands-on executors to strategic 
decision-makers. That feels exciting to me. And the creativity and 
ingenuity this brings to the world of UX.&lt;/p&gt;&lt;p&gt;And that shift doesn’t reduce our value as UX designers, but it does redefine it.&lt;/p&gt;&lt;h2 id="what-ai-does-better-than-us-the-boring-stuff"&gt;What AI Does Better Than Us (The “Boring” Stuff)&amp;nbsp;&lt;/h2&gt;&lt;p&gt;Let’s be clear, AI &lt;i&gt;is&lt;/i&gt; better than humans at certain aspects of design work. Fighting that reality only keeps us stuck in fear.&lt;/p&gt;&lt;h3 id="speed-and-volume"&gt;Speed And Volume&lt;/h3&gt;&lt;p&gt;AI
 is exceptionally good at generating large volumes of ideas quickly. For
 example, layout variations, copy options, component structures, and 
onboarding flows can all be produced in seconds. In early-stage design, 
this changes everything. Instead of spending hours sketching three 
concepts, you can review thirty. That doesn’t eliminate creativity but 
does expand the playground.&lt;/p&gt;&lt;p&gt;&lt;a href="https://www.mckinsey.com/capabilities/tech-and-ai/our-insights/the-economic-potential-of-generative-ai-the-next-productivity-frontier"&gt;McKinsey estimates&lt;/a&gt; that generative AI can reduce the time spent on creative and design-related tasks by up to &lt;b&gt;70%&lt;/b&gt;, particularly during ideation and exploration phases.&lt;/p&gt;&lt;figure&gt;&lt;a href="https://www.mckinsey.com/capabilities/tech-and-ai/our-insights/the-economic-potential-of-generative-ai-the-next-productivity-frontier#/"&gt;&lt;img alt="McKinseys report on generative AI." height="670" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/human-strategy-ai-accelerated-workflow/1-mckinseys-report-generative-ai.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;McKinseys report on generative AI. (Image source: &lt;a href="https://www.mckinsey.com/capabilities/tech-and-ai/our-insights/the-economic-potential-of-generative-ai-the-next-productivity-frontier#/"&gt;McKinsey&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;AI can also help with the research side of UX, for example, exploring the habits of a certain demographic, and &lt;a href="https://persona.qcri.org/blog/what-is-an-ai-generated-persona/"&gt;&lt;b&gt;creating personas&lt;/b&gt;&lt;/a&gt;.
 While this can reduce research time required, the designer is still 
required to guardrail this by providing accurate prompts and &lt;a href="https://uxpsychology.substack.com/p/the-problem-with-ai-generated-personas"&gt;&lt;b&gt;reviewing generated responses&lt;/b&gt;&lt;/a&gt;.
 I have personally found that using AI to assist with the initial 
research for design projects is incredibly useful, specifically when 
there is limited time and access to users.&lt;/p&gt;&lt;h3 id="consistency-and-rule-adherence"&gt;Consistency And Rule Adherence&lt;/h3&gt;&lt;p&gt;Design
 systems live or die by consistency. AI excels at following rules 
relentlessly, colour tokens, spacing systems, typography scales, and 
accessibility standards. It doesn’t forget. It doesn’t get tired. It 
doesn’t “eyeball it.”&lt;/p&gt;&lt;p&gt;AI’s precision makes it incredibly valuable 
for maintaining large-scale design systems, especially in enterprise or 
government environments where consistency and compliance matter more 
than novelty. This is one component of my UX role that I am happy to 
hand over to AI to manage!&lt;/p&gt;&lt;h3 id="data-processing-at-scale"&gt;Data Processing At Scale&lt;/h3&gt;&lt;p&gt;AI
 can analyse behavioural data at volumes challenging, if not impossible,
 for a human team to reasonably process. User journey paths, scroll 
depth, heatmaps to identify mouse interactions, conversion funnels — AI 
can identify patterns and anomalies almost instantly.&lt;/p&gt;&lt;p&gt;Behavioural analytics platforms increasingly rely on AI to surface insights that designers might otherwise miss. &lt;a href="https://contentsquare.com/guides/behavior-analytics/"&gt;Contentsquare&lt;/a&gt;,
 an AI-powered analytics platform, talks about the impacts and benefits 
of utilising behavioural analytics data. I’ve always said that 
quantitative data tells us the “what”, and qualitative data tells us the
 “why”. This is the human component of research where we get to connect 
with the users to understand the reason driving the behaviour.&lt;/p&gt;&lt;figure&gt;&lt;a href="https://files.smashing.media/articles/human-strategy-ai-accelerated-workflow/2-session-replay-tool-display.png"&gt;&lt;img alt="An example of a session replay tool display" height="700" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/human-strategy-ai-accelerated-workflow/2-session-replay-tool-display.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;An example of a session replay tool display. (Image Source: &lt;a href="https://contentsquare.com/guides/behavior-analytics/"&gt;Contentsquare&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;The key insight here is simple: &lt;b&gt;Analysing large volumes of behavioural data was never where our highest value lay&lt;/b&gt;.&lt;/p&gt;&lt;p&gt;If
 AI can take on repetitive production, system enforcement, and raw data 
analysis, designers would be free to focus on interpretation, judgment, 
and human meaning, the hardest parts of the job.&lt;/p&gt;&lt;h2 id="what-humans-do-better-than-ai-the-heart-stuff"&gt;What Humans Do Better Than AI (The “Heart” Stuff)&lt;/h2&gt;&lt;p&gt;For all its power, AI has a fundamental limitation: it has never and will never be human.&lt;/p&gt;&lt;h3 id="empathy-is-lived-experience"&gt;Empathy Is Lived Experience&amp;nbsp;&lt;/h3&gt;&lt;p&gt;AI can describe frustration. It can summarise user feedback. It can mimic empathetic language. But it has never &lt;i&gt;felt&lt;/i&gt;
 the quiet rage of a broken form, the anxiety of submitting sensitive 
data, or the shame of not understanding an interface that assumes too 
much.&lt;/p&gt;&lt;p&gt;Empathy in UX isn’t a dataset. It’s a &lt;b&gt;lived, embodied understanding of human vulnerability&lt;/b&gt;.
 This is why user interviews still matter. Why contextual inquiry still 
matters. Why designers who deeply understand their users consistently 
make better decisions.&lt;/p&gt;&lt;p&gt;In a previous role where I was designing an
 incredibly complex fraud alert platform, the key to successful outcomes
 of that design was based on my understanding of the variety of issues 
faced by customers. I accessed this information directly from members of
 the customer-facing team. This information was stored in their brain 
and based on direct experience with customers. No AI could know or 
access these goldmines of human experiences.&lt;/p&gt;&lt;p&gt;As the &lt;a href="https://www.nngroup.com/articles/definition-user-experience/"&gt;Nielsen Norman Group&lt;/a&gt; reminds us, good UX design is not about interfaces. It’s about &lt;b&gt;communication&lt;/b&gt; and &lt;b&gt;understanding&lt;/b&gt;.&lt;/p&gt;&lt;h3 id="ethics-require-judgment"&gt;Ethics Require Judgment&lt;/h3&gt;&lt;p&gt;AI
 optimises for the objectives we give it. If the goal is engagement, it 
will try to maximise engagement — regardless of long-term harm.&lt;/p&gt;&lt;p&gt;It
 doesn’t inherently recognise dark patterns, manipulation, or emotional 
exploitation. Infinite scroll, variable rewards, and addictive loops are
 all patterns AI can enthusiastically optimise unless a human 
intervenes.&lt;/p&gt;&lt;p&gt;&lt;a href="https://www.humanetech.com/the-cht-perspective"&gt;The Center for Humane Technology&lt;/a&gt; has documented how algorithmic optimisation can unintentionally undermine wellbeing.&lt;/p&gt;&lt;p&gt;Ethical UX design requires designers who can say, &lt;i&gt;“We could do this, but we shouldn’t.”&lt;/i&gt;&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/human-strategy-ai-accelerated-workflow/3-ethical-design-choices.png"&gt;&lt;img alt="Ethical design pyramide" height="646" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/human-strategy-ai-accelerated-workflow/3-ethical-design-choices.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Ethical design choices require human review. (Image source: &lt;a href="https://uxdesign.cc/considerations-and-responsibilities-for-ethical-designers-829450fcb972"&gt;Medium&lt;/a&gt;)&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="strategy-lives-in-context"&gt;Strategy Lives In Context&lt;/h3&gt;&lt;p&gt;AI
 doesn’t sit in stakeholder meetings. It doesn’t hear what’s implied but
 not stated. It doesn’t understand organisational politics, regulatory 
nuance, or long-term positioning.&lt;/p&gt;&lt;blockquote class="pull-quote"&gt;&lt;p&gt;&lt;a aria-label="Share on Twitter" class="pull-quote__link" href="https://twitter.com/share?text=%0aDesigners%20act%20as%20translators%20between%20business%20intent%20and%20human%20impact.%20That%20translation%20relies%20on%20trust,%20relationships,%20and%20context,%20not%20pattern%20recognition.%0a&amp;amp;url=https://smashingmagazine.com%2f2026%2f03%2fhuman-strategy-ai-accelerated-workflow%2f"&gt;Designers
 act as translators between business intent and human impact. That 
translation relies on trust, relationships, and context, not pattern 
recognition.&lt;/a&gt;&lt;/p&gt;&lt;div class="pull-quote__quotation"&gt;&lt;div class="pull-quote__bg"&gt;&lt;span class="pull-quote__symbol"&gt;“&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;p&gt;This is why senior designers increasingly operate at the intersection of product, strategy, and culture.&lt;/p&gt;&lt;p&gt;&lt;b&gt;The lesson is clear:&lt;/b&gt; As AI takes over execution, human designers become the guardians of intent.&lt;/p&gt;&lt;h2 id="how-the-daily-work-of-a-designer-is-changing"&gt;How The Daily Work Of A Designer Is Changing&lt;/h2&gt;&lt;p&gt;This shift isn’t theoretical. It’s already reshaping daily design practice.&lt;/p&gt;&lt;h3 id="from-designing-to-prompting"&gt;From Designing To Prompting&lt;/h3&gt;&lt;p&gt;Designers are moving from manipulating pixels to articulating intent. Clear goals, constraints, and priorities become the input.&lt;/p&gt;&lt;p&gt;Instead of asking AI to “draw a dashboard,” the task becomes:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;“Create a dashboard that reduces cognitive load for first-time users.”&lt;/li&gt;&lt;li&gt;“Explore layouts optimised for accessibility and low vision.”&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Prompting isn’t about clever wording; it’s about clarity of thinking and &lt;b&gt;understanding the intent of the outcomes&lt;/b&gt;.
 You may need to tweak your prompts as you go, but this is all part of 
the learning process of directing AI to deliver the outcomes needed.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/human-strategy-ai-accelerated-workflow/4-design-screens.png"&gt;&lt;img alt="Four design screens complete with user flow mapping" height="420" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/human-strategy-ai-accelerated-workflow/4-design-screens.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Four design screens created by Uizard Autodesigner, complete with user flow mapping. (Image source: &lt;a href="https://uizard.io/blog/5-ai-generated-ui-designs/#5-ai-generated-ui-design-examples"&gt;Uizard.io&lt;/a&gt;)&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="from-making-to-choosing"&gt;From Making To Choosing&lt;/h3&gt;&lt;p&gt;AI produces options. Designers make decisions.&lt;/p&gt;&lt;p&gt;A
 significant portion of future design work will involve reviewing, 
critiquing, and refining AI-generated outputs, and then selecting what 
best serves the user and aligns with ethical, business, and 
accessibility goals.&lt;/p&gt;&lt;p&gt;This mirrors how experienced designers 
already work: mentoring juniors, reviewing their concepts, and guiding 
direction, but at a much greater scale, given the sheer number of design
 options AI tools can generate.&lt;/p&gt;&lt;h3 id="the-movie-director-metaphor"&gt;The Movie Director Metaphor&lt;/h3&gt;&lt;p&gt;I
 often describe the modern designer as a movie director. A director 
doesn’t operate the camera, build the set, or act every role, but they 
are responsible for the story, the emotional intent, and the audience 
experience.&lt;/p&gt;&lt;p&gt;AI tools are the crew. Designers are responsible for the meaning of the story.&lt;/p&gt;&lt;h2 id="a-real-world-shift-what-this-looks-like-in-practice"&gt;A Real-World Shift: What This Looks Like In Practice&lt;/h2&gt;&lt;p&gt;To make this less abstract, let’s ground it in a familiar scenario.&lt;/p&gt;&lt;p&gt;Ten
 years ago, a designer might spend days producing wireframes for a new 
feature, carefully crafting each screen, annotating every interaction, 
and defending each decision in reviews. Much of the designer’s perceived
 value lived in the artefacts themselves.&lt;/p&gt;&lt;p&gt;Today, that same feature
 can be scaffolded in an afternoon with AI support. But here’s what 
hasn’t changed — the hard conversations.&lt;/p&gt;&lt;p&gt;The UX designer still has to ask:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Who is this actually for?&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;What problem are we solving, and for whom?&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;What happens when this fails?&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Who might this unintentionally exclude or disadvantage?&lt;/i&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;In
 practice, I’ve seen senior designers spend less time inside design 
tools and more time facilitating workshops, synthesising messy inputs, 
mediating between stakeholders, and protecting user needs when 
trade-offs arise.&lt;/p&gt;&lt;blockquote class="pull-quote"&gt;&lt;p&gt;&lt;a aria-label="Share on Twitter" class="pull-quote__link" href="https://twitter.com/share?text=%0aAI%20accelerates%20production,%20but%20it%20does%20not%20remove%20the%20designer%e2%80%99s%20responsibility.%20In%20fact,%20it%20increases%20it.%20When%20options%20are%20cheap%20and%20plentiful,%20discernment%20becomes%20a%20scarce%20skill.%0a&amp;amp;url=https://smashingmagazine.com%2f2026%2f03%2fhuman-strategy-ai-accelerated-workflow%2f"&gt;AI
 accelerates production, but it does not remove the designer’s 
responsibility. In fact, it increases it. When options are cheap and 
plentiful, discernment becomes a scarce skill.&lt;/a&gt;&lt;/p&gt;&lt;div class="pull-quote__quotation"&gt;&lt;div class="pull-quote__bg"&gt;&lt;span class="pull-quote__symbol"&gt;“&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;h2 id="conclusion-how-to-prepare-right-now"&gt;Conclusion: How To Prepare Right Now&lt;/h2&gt;&lt;p&gt;&lt;b&gt;Don’t panic — practice.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Avoiding AI won’t preserve your relevance. Learning to use it thoughtfully will.&lt;/p&gt;&lt;p&gt;Start small:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Explore &lt;a href="https://www.figma.com/ai/"&gt;&lt;b&gt;Figma’s AI features&lt;/b&gt;&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Use AI for ideation, not final decisions.&lt;/li&gt;&lt;li&gt;Treat outputs as conversation starters, not answers.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Confidence comes from familiarity, not avoidance.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Invest In Human Skills.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;The most resilient designers will double down on:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Psychology and behavioural science;&lt;/li&gt;&lt;li&gt;Communication and facilitation;&lt;/li&gt;&lt;li&gt;Ethics, accessibility, and inclusion;&lt;/li&gt;&lt;li&gt;Strategic thinking and storytelling.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;These skills compound over time, and they can’t be automated.&lt;/p&gt;&lt;p&gt;&lt;b&gt;The designer’s responsibility in an AI-accelerated world:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;There’s an uncomfortable implication in all of this that we don’t talk about enough: when AI makes it easier to design &lt;i&gt;anything&lt;/i&gt;,
 designers become more accountable for what gets released into the 
world. Bad design used to be excused by constraints. Limited time, 
limited tools, limited data. Those excuses are disappearing. When AI 
removes friction from execution, the &lt;b&gt;ethical and strategic responsibility&lt;/b&gt; lands squarely on human shoulders.&lt;/p&gt;&lt;p&gt;This is where UX designers can, and must, step up as stewards of quality, accessibility, and humanity in digital systems.&lt;/p&gt;&lt;h3 id="final-thought"&gt;Final Thought&amp;nbsp;&lt;/h3&gt;&lt;p&gt;AI
 won’t take your job. But a designer who knows how to think critically, 
direct intelligently, and collaborate effectively with AI might take the
 job of a designer who doesn’t.&lt;/p&gt;&lt;p&gt;The future of UX is no less human. It’s more intentional than ever.&lt;/p&gt;</description><link>http://honeyvig.blogspot.com/2026/03/human-strategy-in-ai-accelerated_31.html</link><author>noreply@blogger.com (H)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9165069509664255576.post-2546294751163006570</guid><pubDate>Tue, 17 Mar 2026 10:15:00 +0000</pubDate><atom:updated>2026-03-17T03:15:33.132-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">AI</category><category domain="http://www.blogger.com/atom/ns#">ML</category><title> Anthropic Just Doubled Claude's Usage Limits for Everyone </title><description>&lt;p&gt;&amp;nbsp; Welcome back! Anthropic just doubled Claude's usage limits in a surprise weekend move, Elon Musk is admitting xAI needs to be rebuilt from scratch, Meta is reportedly preparing to cut 20% of its workforce to fund its AI bet, and a pet owner with no science background used four AI models to design a cancer vaccine that actually shrank his dog's tumor.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Anthropic Doubles Claude's Usage Limits Across Every Plan&lt;br /&gt;Article content&lt;br /&gt;&lt;br /&gt;Anthropic dropped a surprise weekend announcement: double usage limits across all Claude plans for the next two weeks. The boost applies automatically outside peak hours, with no action needed. The company also made its full 1M-token context window generally available for Opus 4.6 and Sonnet 4.6 at no additional cost.&lt;br /&gt;&lt;br /&gt;The details:&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; Double Usage: 2x limits on Free, Pro, Max and Team plans for two weeks, applied automatically outside peak hours (weekdays 5am to 11am PST).&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; 1M Context Window: Full 1M-token context now GA for Claude Opus 4.6 and Sonnet 4.6, enabling uploads of entire codebases and long-form documents.&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; No Price Increase: Both the usage expansion and the context window upgrade come at no extra cost.&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; All Tools Included: The promotion covers all Claude tools, not just the chat interface.&lt;br /&gt;&lt;br /&gt;The 1M-token context window is the bigger move here. For developers and researchers working with large codebases or dense documentation, this changes the scope of what a single conversation with Claude can handle.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Musk Admits xAI "Was Not Built Right" As Rebuild Begins&lt;br /&gt;Article content&lt;br /&gt;&lt;br /&gt;Elon Musk publicly stated that xAI "was not built right" and needs a ground-up rebuild. Nine of the original 11 co-founders have now departed, leaving only Manuel Kroiss and Ross Nordeen. The admission comes as SpaceX, which owns xAI, prepares for a public listing later this year.&lt;br /&gt;&lt;br /&gt;The rebuild:&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; Latest Departures: Zihang Dai and Guodong Zhang left the company, with Zhang reportedly blamed by Musk for Grok's coding shortfalls before exiting.&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; New Hires: xAI brought in senior Cursor engineers Andrew Milich and Jason Ginsberg, both reporting directly to Musk, to accelerate Grok's coding capabilities.&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; Coding Deficit: Musk has publicly acknowledged that Grok is "currently behind" on coding versus frontier competitors.&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; IPO Pressure: The full rebuild is happening while SpaceX prepares for one of the largest public listings in recent history.&lt;br /&gt;&lt;br /&gt;Rebuilding from scratch while preparing for an IPO is an extraordinary challenge. Musk is betting that new talent and a clean architecture can close the gap with OpenAI and Anthropic, but the timeline to prove that is tightening.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Meta Reportedly Weighing Layoffs Affecting 20% Of Its Workforce&lt;br /&gt;Article content&lt;br /&gt;&lt;br /&gt;Meta is reportedly considering layoffs that could cut 20% or more of its nearly 79,000 employees. The move would offset aggressive AI infrastructure spending, including $600 billion earmarked for data centres by 2028.&lt;br /&gt;&lt;br /&gt;The pressure points:&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; Potential Scale: A 20% cut would impact roughly 16,000 people across the company.&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; AI Investment: Meta has committed $600B to data centre buildout, one of the largest infrastructure bets in tech history.&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; Recent Acquisitions: The company's purchase of Manus adds to its AI portfolio and its cost base.&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; Official Position: A Meta spokesperson described the reporting as "speculative reporting about theoretical approaches."&lt;br /&gt;&lt;br /&gt;Meta is making one of the biggest infrastructure bets in corporate history while potentially cutting the workforce needed to operate it. A 20% reduction is not efficiency trimming. It is a structural bet that AI can absorb the work.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;AI-Designed Vaccine Shrinks Rescue Dog's Tumor&lt;br /&gt;Article content&lt;br /&gt;&lt;br /&gt;Sydney AI consultant Paul Conyngham built a custom mRNA cancer vaccine for his dog Rosie by chaining ChatGPT, Grok, DeepMind's AlphaFold and a university genomics lab. One tumor shrank by half after the first injection.&lt;br /&gt;&lt;br /&gt;How it worked:&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; Diagnosis: Rosie was diagnosed with mast cell cancer in 2024 and given months to live after chemo and surgery failed.&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; AI Pipeline: Conyngham used ChatGPT to map the research, paid $3,000 for genomic sequencing and ran the data through AlphaFold to model mutations.&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; Vaccine Design: The UNSW RNA Institute helped produce the vaccine, with the final construct designed using Grok.&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; Results: One tumor shrank 50% after a December injection. A second vaccine targeting non-responding tumors is now in development.&lt;br /&gt;&lt;br /&gt;Try this yourself:&lt;br /&gt;&lt;br /&gt;Conyngham's approach demonstrates what is possible when you chain multiple AI models together for a single complex problem. The tools he used (ChatGPT, Grok, AlphaFold) are all publicly accessible. The breakthrough was not any single model, but the pipeline connecting them.&amp;nbsp;&lt;/p&gt;</description><link>http://honeyvig.blogspot.com/2026/03/anthropic-just-doubled-claudes-usage.html</link><author>noreply@blogger.com (H)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9165069509664255576.post-4182323690917354232</guid><pubDate>Fri, 13 Mar 2026 10:34:00 +0000</pubDate><atom:updated>2026-03-13T03:34:00.126-07:00</atom:updated><title>A Designer’s Guide To Eco-Friendly Interfaces</title><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="c-garfield-summary"&gt;&lt;section aria-label="Quick summary" class="article__summary"&gt;Every
 high-resolution hero image, autoplay video, and complex JavaScript 
animation carries a cost. Sustainable UX challenges the era of 
“unlimited pixels” and reframes performance as responsibility. In 2026, 
truly sophisticated design is defined not by how much it adds, but by 
how thoughtfully it reduces its footprint.&lt;/section&gt;&lt;/div&gt;&lt;p&gt;I’ve spent 
over two decades in the trenches of user experience design. I remember 
the transition from table-based layouts to CSS, the pivot to responsive 
design when the iPhone launched, and the rise of the “attention 
economy.” But as we navigate 2026, the industry is facing its most 
significant shift yet. We are moving past the era of “design at any 
cost” into the era of &lt;strong&gt;Sustainable UX&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;It’s not 
something most designers think about, including myself, until I was 
prompted by hearing about this as a concept. For years, we have treated 
the internet as an ethereal, weightless cloud. We have assumed that 
digital products were “green” simply because they weren’t printed on 
paper. I used to think that too, and before the concept of climate 
change emerged, it was more about saving trees.&lt;/p&gt;&lt;p&gt;We were wrong. The
 cloud is a physical infrastructure, a sprawling network of data 
centres, undersea cables, and cooling systems that hum &lt;sup&gt;24&lt;/sup&gt;⁄&lt;sub&gt;7&lt;/sub&gt;. While AI-focused data centers match the power &lt;a href="https://www.iea.org/reports/energy-and-ai/executive-summary"&gt;consumption of massive aluminum smelters&lt;/a&gt;, their high geographic density creates an even more intense and localised environmental strain.&lt;/p&gt;&lt;p&gt;As
 UX designers, we are the architects of this energy consumption. Every 
high-resolution hero image, every auto-playing background video, and 
every complex JavaScript animation we approve is a direct instruction to
 a processor to consume power. If we want to build a future that lasts, 
we must stop designing for “wow” and start designing for &lt;strong&gt;efficiency.&lt;/strong&gt;&lt;/p&gt;&lt;h2 id="dark-mode"&gt;Dark Mode&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/02/designer-guide-eco-friendly-interfaces/#dark-mode"&gt;#&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;In
 the early 2000s, white backgrounds were the standard because they 
mimicked the familiarity of paper. However, the hardware has evolved, 
and our design philosophy must follow. The shift from LCD to OLED 
(Organic Light Emitting Diode) technology has fundamentally changed how 
colour impacts energy.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/designer-guide-eco-friendly-interfaces/1-dark-mode-light-mode.jpg"&gt;&lt;img alt="Dark mode vs. Light mode." height="533" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/designer-guide-eco-friendly-interfaces/1-dark-mode-light-mode.jpg" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Dark mode vs. Light mode. (Image source: &lt;a href="https://www.purdue.edu/newsroom/archive/releases/2021/Q3/dark-mode-may-not-save-your-phones-battery-life-as-much-as-you-think,-but-there-are-a-few-silver-linings.html"&gt;Purdue University&lt;/a&gt;) (&lt;a href="https://files.smashing.media/articles/designer-guide-eco-friendly-interfaces/1-dark-mode-light-mode.jpg"&gt;Large preview&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="the-logic"&gt;The Logic&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/02/designer-guide-eco-friendly-interfaces/#the-logic"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Unlike traditional LCD screens, which require a backlight that is always on (even when displaying black), &lt;strong&gt;&lt;a href="https://www.digikey.cz/en/maker/blogs/2024/oled-vs-led-screens-unveiling-the-illuminating-differences"&gt;OLED screens illuminate each pixel individually&lt;/a&gt;&lt;/strong&gt;. When a pixel is set to true black (&lt;code&gt;#000000&lt;/code&gt;), that specific diode is turned completely off. It draws zero power.&lt;/p&gt;&lt;blockquote class="pull-quote"&gt;&lt;p&gt;&lt;a aria-label="Share on Twitter" class="pull-quote__link" href="https://twitter.com/share?text=%0aBy%20designing%20interfaces%20that%20favour%20darker%20palettes,%20we%20aren%e2%80%99t%20just%20following%20a%20trend;%20we%20are%20physically%20reducing%20the%20energy%20requirement%20of%20the%20user%e2%80%99s%20device.%0a&amp;amp;url=https://smashingmagazine.com%2f2026%2f02%2fdesigner-guide-eco-friendly-interfaces%2f"&gt;By
 designing interfaces that favour darker palettes, we aren’t just 
following a trend; we are physically reducing the energy requirement of 
the user’s device.&lt;/a&gt;&lt;/p&gt;&lt;div class="pull-quote__quotation"&gt;&lt;div class="pull-quote__bg"&gt;&lt;span class="pull-quote__symbol"&gt;“&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;h3 id="the-data"&gt;The Data&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/02/designer-guide-eco-friendly-interfaces/#the-data"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The energy savings are far from negligible. A landmark study by &lt;strong&gt;&lt;a href="https://www.purdue.edu/newsroom/archive/releases/2021/Q3/dark-mode-may-not-save-your-phones-battery-life-as-much-as-you-think,-but-there-are-a-few-silver-linings.html"&gt;Purdue University&lt;/a&gt;&lt;/strong&gt;
 in 2021, which has become the gold standard for this discussion, 
revealed that at 100% brightness, switching from light mode to dark mode
 can save an average of &lt;strong&gt;39% to 47%&lt;/strong&gt; of battery power. On
 a global scale, if every major app defaulted to dark mode, the 
reduction in grid demand would be astronomical.&lt;/p&gt;&lt;h3 id="the-design-goal"&gt;The Design Goal&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/02/designer-guide-eco-friendly-interfaces/#the-design-goal"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In 2026, Dark Mode should no longer be a secondary “theme” tucked away in a settings menu. We should be designing with a &lt;strong&gt;“Dark-First”&lt;/strong&gt; mentality. This doesn’t mean every site must look like &lt;em&gt;The Matrix&lt;/em&gt;,
 but it does mean prioritising high-contrast dark themes as the default 
system-preferred state. This extends the hardware lifespan of the device
 and lowers the carbon footprint of every interaction.&lt;/p&gt;&lt;p&gt;I 
personally prefer Light-Mode for reading, so it makes sense to have both
 light and dark mode options available. There are also &lt;strong&gt;&lt;a href="https://www.cueforgood.com/blog/dark-mode-accessibility-sustainable-web-design/"&gt;accessibility considerations&lt;/a&gt;&lt;/strong&gt; with providing both options.&lt;/p&gt;&lt;h2 id="image-and-video-optimisation"&gt;Image And Video Optimisation&lt;/h2&gt;&lt;p&gt;We have become lazy designers. With high-speed 5G and fibre optics, we’ve stopped worrying about file sizes. The &lt;strong&gt;&lt;a href="https://almanac.httparchive.org/en/2022/page-weight#:~:text=by%20Barry%20Pollard-,Introduction,often%20expensive%20mobile%20network%20access."&gt;average mobile page weight has increased by over 500%&lt;/a&gt;&lt;/strong&gt; in the last decade, largely due to unoptimized visual assets.&lt;/p&gt;&lt;h3 id="the-logic-1"&gt;The Logic&lt;/h3&gt;&lt;p&gt;The
 “Digital Fat” of a website (those 4MB Unsplash photos and 15MB 
background videos) is the single largest contributor to page-load 
energy. Every megabyte transferred from a server to a client requires 
electricity for the transmission, the server’s processing, and the 
user’s rendering engine. When we use massive files, we are essentially 
“burning” energy to show a picture that could have been just as 
effective at a fraction of the size. Not to mention, you are also 
providing a better user experience with a page that loads much faster.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/designer-guide-eco-friendly-interfaces/2-median-page-weight.png"&gt;&lt;img alt="Median page weight by content type." height="495" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/designer-guide-eco-friendly-interfaces/2-median-page-weight.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Median page weight by content type. (Image source: &lt;a href="https://almanac.httparchive.org/en/2022/page-weight#content-type-and-file-formats"&gt;HTTP Archive&lt;/a&gt;)&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="the-data-1"&gt;The Data&lt;/h3&gt;&lt;p&gt;According to the &lt;strong&gt;&lt;a href="https://almanac.httparchive.org/en/2022/page-weight"&gt;HTTP Archive&lt;/a&gt;&lt;/strong&gt;,
 images and video consistently account for the lion’s share of a page’s 
total weight. However, the shift to modern formats like &lt;strong&gt;AVIF&lt;/strong&gt; and &lt;strong&gt;WebP&lt;/strong&gt; can &lt;strong&gt;&lt;a href="https://crystallize.com/blog/avif-vs-webp"&gt;reduce image weight by up to 50%&lt;/a&gt; compared to JPEG,&lt;/strong&gt; without any perceptible loss in quality.&lt;/p&gt;&lt;p&gt;Although
 these formats are not as familiar to me as JPG and PNG, I am definitely
 looking forward to using them to reduce page size.&lt;/p&gt;&lt;h3 id="the-design-goal-1"&gt;The Design Goal&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/02/designer-guide-eco-friendly-interfaces/#the-design-goal-1"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;I
 recently led a redesign for a cybersecurity platform. By implementing a
 “Before and After” audit, we discovered that their homepage was loading
 5.5MB of data. By replacing high-res photography with &lt;strong&gt;SVG (Scalable Vector Graphics)&lt;/strong&gt; art and using clever &lt;strong&gt;CSS gradients&lt;/strong&gt; instead of image assets, we dropped the load to 1.2MB. That is a &lt;strong&gt;78% reduction in energy load!&lt;/strong&gt; As a designer, your first question should always be:&lt;/p&gt;&lt;blockquote&gt;“Do I need a photo for this, or can I achieve the same emotional resonance with code?”&lt;/blockquote&gt;&lt;h2 id="intentional-motion-cutting-loud-animations"&gt;Intentional Motion: Cutting “Loud” Animations&lt;/h2&gt;&lt;p&gt;We live in an era of “&lt;strong&gt;&lt;a href="https://www.nngroup.com/articles/scrolljacking-101"&gt;scroll-jacking&lt;/a&gt;&lt;/strong&gt;” and complex 3D Parallax effects. While these might win awards on Awwwards.com, they are often ecological disasters.&lt;/p&gt;&lt;h3 id="the-logic-2"&gt;The Logic&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/02/designer-guide-eco-friendly-interfaces/#the-logic-2"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Animation is not free. To render a complex animation, the device’s GPU (Graphics Processing Unit) must work at high capacity. &lt;strong&gt;&lt;a href="https://www.lenovo.com/au/en/knowledgebase/graphics-processing-unit-gpu-a-comprehensive-guide/?org"&gt;This increases the CPU temperature&lt;/a&gt;&lt;/strong&gt;,
 triggers cooling fans (in laptops), and drains battery rapidly. “Loud” 
animations that run constantly in the background or trigger massive 
re-paints of the browser are the energy equivalent of leaving your car 
idling in the driveway.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/designer-guide-eco-friendly-interfaces/3-size-comparison-uncompressed-images.png"&gt;&lt;img alt="Size comparison of uncompressed JPEG, PNG, WebP, and AVIF photos and text images." height="479" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/designer-guide-eco-friendly-interfaces/3-size-comparison-uncompressed-images.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Size comparison of uncompressed JPEG, PNG, WebP, and AVIF photos and text images. (Image source: &lt;a href="https://photutorial.com/image-format-comparison-statistics/"&gt;Photutorial&lt;/a&gt;)&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="the-data-2"&gt;The Data&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://m3.material.io/styles/motion/overview"&gt;Google’s Material Design guidelines&lt;/a&gt;&lt;/strong&gt; emphasize “&lt;strong&gt;Meaningful Motion&lt;/strong&gt;.” They argue that animation should be used only to orient the user or provide feedback. And using &lt;strong&gt;&lt;a href="https://www.tumwebsme.com/en/customer/blog/green-web-design-sustainable-websites-carbon-footprint-guide"&gt;WebP instead of JPEG can save 25-50%&lt;/a&gt;&lt;/strong&gt; of data on a page.&lt;/p&gt;&lt;h3 id="the-design-goal-2"&gt;The Design Goal&lt;/h3&gt;&lt;p&gt;We must adopt &lt;strong&gt;Meaningful Motion.&lt;/strong&gt; If an animation doesn’t help a user complete a task or understand a hierarchy, it is a waste. We should favour &lt;strong&gt;CSS transitions&lt;/strong&gt; over heavy JavaScript libraries like GSAP or Lottie where possible, as &lt;strong&gt;&lt;a href="https://www.sitepoint.com/introduction-to-hardware-acceleration-css-animations/"&gt;CSS is hardware-accelerated&lt;/a&gt;&lt;/strong&gt; and far more efficient for the browser to calculate.&lt;/p&gt;&lt;p&gt;As a UX designer, I can’t argue this approach. This not only helps reduce data waste but also improves UX for our users.&lt;/p&gt;&lt;h2 id="setting-a-data-budget-for-every-project"&gt;Setting A “Data Budget” For Every Project&amp;nbsp;&lt;/h2&gt;&lt;p&gt;In my 20+ years of UX, the most successful projects have generally been the ones with the tightest constraints.&lt;/p&gt;&lt;blockquote class="pull-quote"&gt;&lt;p&gt;&lt;a aria-label="Share on Twitter" class="pull-quote__link" href="https://twitter.com/share?text=%0aJust%20as%20a%20project%20has%20a%20financial%20budget,%20it%20should%20also%20have%20a%20carbon%20and%20data%20budget.%0a&amp;amp;url=https://smashingmagazine.com%2f2026%2f02%2fdesigner-guide-eco-friendly-interfaces%2f"&gt;Just as a project has a financial budget, it should also have a carbon and data budget.&lt;/a&gt;&lt;/p&gt;&lt;div class="pull-quote__quotation"&gt;&lt;div class="pull-quote__bg"&gt;&lt;span class="pull-quote__symbol"&gt;“&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;h3 id="the-logic-3"&gt;The Logic&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/02/designer-guide-eco-friendly-interfaces/#the-logic-3"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;A
 Data Budget is a hard cap on the total size of a page (e.g., “This 
landing page cannot exceed 1MB”). This forces the design team to make 
difficult, intentional choices. If you want to add a new tracking script
 or a fancy font weight, you have to “pay” for it by optimising or 
removing something else. This prevents “feature creep” from turning into
 “carbon creep.”&lt;/p&gt;&lt;h3 id="the-data-3"&gt;The Data&lt;/h3&gt;&lt;p&gt;The &lt;strong&gt;&lt;a href="https://sustainablewebdesign.org/estimating-digital-emissions/"&gt;Sustainable Web Design model&lt;/a&gt;&lt;/strong&gt;, developed by pioneers like &lt;strong&gt;&lt;a href="https://www.wholegraindigital.com/blog/updating-website-carbon-to-v4-of-the-sustainable-web-design-model/"&gt;Wholegrain Digital&lt;/a&gt;&lt;/strong&gt;,
 provides a formula to calculate the CO2 per page view. The average 
website produces about 0.5 grams of CO2 per view. For a site with 1 
million monthly views, that’s 6 metric tons of CO2 a year, equivalent to
 driving a car 15,000 miles.&lt;/p&gt;&lt;h3 id="the-design-goal-3"&gt;The Design Goal&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://mangrove-web.com/blog/resources/the-green-ux-checklist/"&gt;The Sustainable UX Checklist&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Reduce Images&lt;/strong&gt;&lt;br /&gt;Question
 the necessity of every visual and use the smallest resolution and most 
efficient file formats (like AVIF) to minimize data transfer.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Optimise Video&lt;/strong&gt;&lt;br /&gt;Eliminate
 auto-playing media and prioritise highly compressed, short loops to 
ensure energy is only spent on content the user intends to view.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Limit Fonts&lt;/strong&gt;&lt;br /&gt;Use
 a maximum of two web font weights or stick to classic system fonts to 
remove unnecessary server requests and rendering bloat.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Recycle Assets&lt;/strong&gt;&lt;br /&gt;Repurpose
 a single image or video multiple times using CSS filters and overlays 
to create visual variety without increasing the total page weight.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Choose Green Hosting&lt;/strong&gt;&lt;br /&gt;Host your digital products on servers verified by &lt;strong&gt;&lt;a href="https://www.thegreenwebfoundation.org/"&gt;The Green Web Foundation&lt;/a&gt;&lt;/strong&gt; to ensure they are powered by renewable energy sources.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Minimize Data Distance&lt;/strong&gt;&lt;br /&gt;Select
 server locations geographically close to your primary audience to 
reduce the energy required for data to travel through physical 
infrastructure.&lt;/li&gt;&lt;/ul&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/designer-guide-eco-friendly-interfaces/4-green-ux-checklist.png"&gt;&lt;img alt="Printable Green UX checklist from Mangrove Web" height="450" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/designer-guide-eco-friendly-interfaces/4-green-ux-checklist.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Printable Green UX checklist from Mangrove Web. (Image source: &lt;a href="https://mangrove-web.com/blog/resources/the-green-ux-checklist/"&gt;Mangrove Web&lt;/a&gt;)&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;h2 id="the-business-case-for-eco-friendly-design"&gt;The Business Case For Eco-friendly Design&amp;nbsp;&lt;/h2&gt;&lt;p&gt;Some
 might argue that “Green UX” sounds like a compromise on quality. On the
 contrary, it is a competitive advantage. Sustainable design is &lt;strong&gt;performance design.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;When you reduce page weight, your site loads faster. When your site loads faster, your &lt;strong&gt;&lt;a href="https://developers.google.com/search/docs/appearance/core-web-vitals"&gt;Core Web Vitals&lt;/a&gt;&lt;/strong&gt; improve. When your &lt;strong&gt;Core Web Vitals&lt;/strong&gt; improve, your &lt;strong&gt;SEO ranking&lt;/strong&gt;
 goes up. Furthermore, users on older devices or slower data plans 
(especially in emerging markets) can actually access your product. This 
is the definition of “Inclusive Design.”&lt;/p&gt;&lt;p&gt;By cutting the “digital 
fat,” we create a leaner, faster, and more accessible web. We are moving
 away from the “disposable design” of the 2010s toward a more permanent,
 respectful digital architecture.&lt;/p&gt;&lt;h2 id="conclusion-the-future-of-clean-design"&gt;Conclusion: The Future Of “Clean” Design&lt;/h2&gt;&lt;p&gt;In
 my two decades of design, I’ve seen many trends come and go. 
Skeuomorphism, Flat Design, Neumorphism — they were all aesthetic 
choices. But sustainable UX isn’t a trend; it’s now a necessity. We are 
the first generation of designers who have to reckon with the physical 
consequences of our digital work.&lt;/p&gt;&lt;p&gt;Sustainable UX is a 
“win-win-win.” It’s better for the planet because it reduces energy 
consumption. It’s better for the user because it results in faster, more
 responsive interfaces. And it’s better for the business because it 
lowers hosting costs AND improves conversion rates.&lt;/p&gt;&lt;p&gt;The era of 
“unlimited pixels” is over. In 2026, the most sophisticated design is 
the one that leaves the smallest footprint. We are no longer just 
designers; we are the guardians of the user’s battery, their data plan, 
and ultimately, the environment.&lt;/p&gt;&lt;h2 id="the-call-to-action"&gt;The Call To Action&lt;/h2&gt;&lt;p&gt;I challenge you to audit just &lt;strong&gt;one page&lt;/strong&gt; of your current project today. Use a tool like the &lt;strong&gt;&lt;a href="https://www.websitecarbon.com/"&gt;Website Carbon Calculator&lt;/a&gt;&lt;/strong&gt;
 to see its impact. Then, look for the “invisible waste.” Can that image
 be an SVG? Can that video be a static hero? Can that “loud” animation 
be silenced?&lt;/p&gt;&lt;p&gt;Start small. The most elegant solution is often the one with the fewest bytes.&lt;/p&gt;</description><link>http://honeyvig.blogspot.com/2026/03/a-designers-guide-to-eco-friendly.html</link><author>noreply@blogger.com (H)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9165069509664255576.post-5504052992724501233</guid><pubDate>Wed, 11 Mar 2026 10:30:00 +0000</pubDate><atom:updated>2026-03-11T03:30:00.124-07:00</atom:updated><title>Designing A Streak System: The UX And Psychology Of Streaks</title><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="c-garfield-summary"&gt;&lt;section aria-label="Quick summary" class="article__summary"&gt;What
 makes streaks so powerful and addictive? To design them well, you need 
to understand how they align with human psychology. Victor Ayomipo 
breaks down the UX and design principles behind effective streak 
systems.&lt;/section&gt;&lt;/div&gt;&lt;p&gt;I’m sure you’ve heard of streaks or used an 
app with one. But ever wondered why streaks are so popular and powerful?
 Well, there is the obvious one that apps want as much of your attention
 as possible, but aside from that, did you know that when the popular 
learning app Duolingo introduced iOS widgets to display streaks, &lt;a href="https://www.orizon.co/blog/duolingos-gamification-secrets#:~:text=When%20Duolingo%20introduced%20an%20iOS%20widget%20displaying%20streaks%2C%20user%20commitment%20increased%20by%2060%25!"&gt;user commitment surged by 60%&lt;/a&gt;.
 Sixty percent is a massive shift in behaviour and demonstrates how 
“streak” patterns can be used to increase engagement and drive usage.&lt;/p&gt;&lt;p&gt;At its most basic, &lt;strong&gt;a streak is the number of consecutive days that a user completes a specific activity&lt;/strong&gt;. Some people also define it as a “gamified” habit or a metric designed to encourage consistent usage.&lt;/p&gt;&lt;p&gt;But
 streaks transcend beyond being a metric or a record in an app; it is 
more psychological than that. Human instincts are easy to influence with
 the right factors. Look at these three factors: &lt;strong&gt;progress&lt;/strong&gt;, &lt;strong&gt;pride&lt;/strong&gt;, and fear of missing out (commonly called &lt;a href="https://www.smashingmagazine.com/2019/11/fomo-increase-conversions/"&gt;FOMO&lt;/a&gt;). What do all these have in common? &lt;em&gt;Effort&lt;/em&gt;.
 The more effort you put into something, the more it shapes your 
identity, and that is how streaks crosses into the world of behavioural 
psychology.&lt;/p&gt;&lt;p&gt;Now, with great power comes great responsibility, and because of that, there’s a dark side to streaks.&lt;/p&gt;&lt;p&gt;In
 this article, we’ll be going into the psychology, UX, and design 
principles behind building an effective streak system. We’ll look at (1)
 why our brains almost instinctively respond to streak activity, (2) how
 to design streaks in ways that genuinely help users, and (3) the 
technical work involved in building a streak pattern.&lt;/p&gt;&lt;h2 id="the-psychology-behind-streaks"&gt;The Psychology Behind Streaks&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/02/designing-streak-system-ux-psychology/#the-psychology-behind-streaks"&gt;#&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;To
 design and build an effective streak system, we need to understand how 
it aligns with how our brains are wired. Like, what makes it so 
effective to the extent that we feel so much intense dedication to 
protect our streaks?&lt;/p&gt;&lt;p&gt;There are three interesting, well-documented psychology principles that support what makes streaks so powerful and addictive.&lt;/p&gt;&lt;h3 id="loss-aversion"&gt;Loss Aversion&amp;nbsp;&lt;/h3&gt;&lt;p&gt;This is probably the strongest force behind streaks. I say this because most times, you almost can’t avoid this in life.&lt;/p&gt;&lt;p&gt;Think
 of it this way: If a friend gives you $100, you’d be happy. But if you 
lost $100 from your wallet, that would hurt way more. The emotional 
weight of those situations isn’t equal. Loss hurts way more than gain 
feels good.&lt;/p&gt;&lt;p&gt;Let’s take it further and say that I give you $100 and
 ask you to play a gamble. There’s a 50% chance you win another $100 and
 a 50% chance you lose the original $100. Would you take it? I wouldn’t.
 Most people wouldn’t. That’s loss aversion.&lt;/p&gt;&lt;p&gt;If you think about it, it is logical, it is understandable, it is human.&lt;/p&gt;&lt;p&gt;The
 concept behind loss aversion is that we feel the pain of losing 
something twice as much as the pleasure of gaining something of equal 
value. In psychological terms, loss lingers more than gains do.&lt;/p&gt;&lt;p&gt;You
 probably see how this relates to streaks. To build a noticeable streak,
 it requires effort; as a streak grows, the motivation behind it begins 
to fade; or more accurately, it starts to become secondary.&lt;/p&gt;&lt;p&gt;Here’s an example: Say your friend has a three-day streak closing their &lt;a href="https://www.apple.com/watch/close-your-rings/"&gt;“Move Rings” on their Apple Watch&lt;/a&gt;.
 They have almost nothing to lose beyond wanting to achieve their goal 
and be consistent. At the same time, you have an impressive 219-day 
streak going. Chances are that you are trapped by the &lt;em&gt;fear of losing it&lt;/em&gt;.
 You most likely aren’t thinking about the achievement at this point; 
it’s more about protecting your invested effort, and that is loss 
aversion.&lt;/p&gt;&lt;p&gt;&lt;a href="https://blog.duolingo.com/how-duolingo-streak-builds-habit/#:~:text=This%20is%20when%20we%20tap%20into%20%22loss%20aversion%2C%22%20an%20internal%20bias%20in%20your%20brain%20that%20makes%20you%20particularly%20averse%20to%20losing%20something%2C%20like%20a%20learning%20streak."&gt;Duolingo explains how loss aversion contributes to a user’s reluctance to break a long streak&lt;/a&gt;, even on their laziest days. In a way, a streak can turn into a habit when loss aversion settles in.&lt;/p&gt;&lt;h3 id="the-fogg-behaviour-model-b-map"&gt;The Fogg Behaviour Model (B = MAP)&lt;/h3&gt;&lt;p&gt;Now that we understand the fear of losing the effort invested in longer streaks, another question is: &lt;em&gt;What makes us do the thing in the first place, day after day, even before the streak gets big?&lt;/em&gt;&lt;/p&gt;&lt;p&gt;That’s what the &lt;a href="https://www.behaviormodel.org"&gt;Fogg Behaviour Model&lt;/a&gt;
 is about. It is relatively simple. A behaviour (B) only occurs when 
three factors — Motivation (M), Ability (A), and Prompt (P) — align at 
the same moment. Thus, the equation B=MAP.&lt;/p&gt;&lt;p&gt;If any of these factors, even one, is missing at that moment, the behaviour won’t happen.&lt;/p&gt;&lt;p&gt;So, for a streak system to be efficient and recurring, all three factors must be present:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Motivation&lt;/strong&gt;&lt;br /&gt;This
 is fragile and not something that is consistently present. There are 
days when you’re pumped to learn Spanish, and days you don’t even feel 
an iota of willpower to learn the language. &lt;strong&gt;Motivation&lt;/strong&gt; by itself to build a habit is unreliable and a losing battle from day one.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Ability&lt;/strong&gt;&lt;br /&gt;To compensate for the limitations of motivation, &lt;strong&gt;ability&lt;/strong&gt;
 is critical. In this context, ability means the ease of action, i.e, 
the effort is so easy that it’s unrealistic to say it isn’t possible. 
Most apps intentionally use this. Apple Fitness just needs you to stand 
for one minute in an hour to earn a tick towards your Stand goal. 
Duolingo only needs one completed lesson. These tasks do not require all
 that much effort. The barrier is so low that even on your worst days, 
you can do it. But the combined effort of an ongoing streak is where the
 idea of losing that streak kicks in.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Prompt&lt;/strong&gt;&lt;br /&gt;This is what completes the equation. Humans are naturally forgetful, so yes, ability can get us 90% there. But a &lt;strong&gt;prompt&lt;/strong&gt;
 reminds us to act. Streaks are persistent by design, so users need to 
be constantly reminded to act. To see how powerful a prompt can be, &lt;a href="https://review.firstround.com/the-tenets-of-a-b-testing-from-duolingos-master-growth-hacker/#:~:text=Gina%20Gotthilf%2C%20VP,DAUs%2C%E2%80%9D%20she%20says."&gt;Duolingo did an A/B test&lt;/a&gt; to see if a little red badge on the app’s icon increased consistent usage. It produced a 6% increase in daily active users. &lt;em&gt;Just a red badge.&lt;/em&gt;&lt;/p&gt;&lt;h4 id="model-limitations"&gt;Model Limitation&lt;/h4&gt;&lt;p&gt;All
 this being said, there is a limitation to the Fogg model whereby 
critics and modern research have noticed that a design that relies too 
heavily on prompts, like aggressive notifications, risks creating mental
 fatigue. Constant notifications and overtime could cause users to 
churn. So, watch out for that.&lt;/p&gt;&lt;h3 id="the-zeigarnik-effect"&gt;The Zeigarnik Effect&amp;nbsp;&lt;/h3&gt;&lt;p&gt;How
 do you feel when you leave a task of project half-done? That irritates 
many people because unfinished tasks occupy more mental space than the 
things we complete. When something is done and gone, we tend to forget 
it. When something is left undone, it tends to weigh on our minds.&lt;/p&gt;&lt;p&gt;This
 is exactly why digital products use artificial progress indicators, 
like Upwork’s profile completion bar, to let a user know that their 
profile is only “60% complete”. It nudges the user to finish what they 
started.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/designing-streak-system-ux-psychology/1-upwork-profile-completion-progress-bar.png"&gt;&lt;img alt="Upwork’s profile completion progress bar" height="325" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/designing-streak-system-ux-psychology/1-upwork-profile-completion-progress-bar.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Upwork’s profile completion progress bar.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Let’s
 look at another example. You have five tasks in a to-do list app, and 
at the end of the day, you only check four of them as completed. Many of
 us will feel unaccomplished because of that one unfinished task. That, 
right there, is the &lt;strong&gt;Zeigarnik effect&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Zeigarnik_effect"&gt;The Zeigarnik effect&lt;/a&gt;&lt;a href="https://en.wikipedia.org/wiki/Zeigarnik_effect"&gt;he&lt;/a&gt;
 was demonstrated by psychologist Bluma Zeigarnik, who described that we
 tend to keep incomplete tasks active in our memory longer than 
completed tasks.&lt;/p&gt;&lt;p&gt;A streak pattern naturally taps into this in UX 
design. Let’s say you are on day 63 of a learning streak. At that point,
 you’re in an ongoing pattern of unfinished business. Your brain would 
rarely forget about it as it sits in the back of your mind. At this 
point, your brain becomes the one sending you notifications.&lt;/p&gt;&lt;p&gt;When 
you put these psychological forces together, you begin to truly 
understand why streaks aren’t just a regular app feature; they are 
capable of reshaping human behaviour.&lt;/p&gt;&lt;p&gt;But somewhere along the line
 — I can’t say exactly when, as it differs for everyone — things reach a
 point where a streak shifts from “fun” to something you feel you can’t 
afford to lose. You don’t want 58 days of effort to go to waste, do you?
 That is what makes a streak system effective. If done right, &lt;strong&gt;streaks help users build astounding habits that accomplish a goal&lt;/strong&gt;. It could be reading daily or hitting the gym consistently.&lt;/p&gt;&lt;p&gt;These
 repeated actions (sometimes small) compound over time and become 
evident in our daily lives. But there are two sides to every coin.&lt;/p&gt;&lt;h2 id="the-thin-line-between-habit-and-compulsion"&gt;The Thin Line Between Habit And Compulsion&lt;/h2&gt;&lt;p&gt;If
 you have been following along, you can already tell there’s a dark side
 to streak systems. Habit formation is about consistency with a repeated
 goal. Compulsion, however, is the consistency of working on a goal that
 is no longer needed but held onto out of fear or pressure. It is a 
razor-thin line.&lt;/p&gt;&lt;p&gt;You brush your teeth every morning without 
thinking; it is automatic and instinctive, with a clear goal of having 
good breath. That’s a streak that forms a good habit. An ethical streak 
system gives users space to breathe. If, for some reason, you don’t 
brush in the morning, you can brush at noon. Imperfection is allowed 
without fear of losing a long effort.&lt;/p&gt;&lt;p&gt;Compulsion takes the 
opposite route, whereby a streak makes you anxious, you feel guilty or 
even exhausted, and sometimes, it feels like you haven’t accomplished 
anything, despite all your work. You act not because you want to, but 
because you’re subconsciously terrified of seeing your progress reset to
 zero.&lt;/p&gt;&lt;p&gt;Someone even described this perfectly, “&lt;a href="https://www.thecut.com/2019/04/why-breaking-a-streak-feels-so-awful.html#:~:text=Callie%20Beusman%2C%20the,day%20151%20now.%E2%80%9D"&gt;&lt;em&gt;I felt that I was cheating, but simply did not care. I am nothing without my streak&lt;/em&gt;&lt;/a&gt;”.
 This shows the extreme hold streaks can have on an individual. To the 
extent that users begin to tie their self-worth to an arbitrary metric 
rather than the original goal or reason they started the streak in the 
first place. The streak becomes who they are, not just what they do.&lt;/p&gt;&lt;p&gt;A well-designed &lt;strong&gt;ethical&lt;/strong&gt; streak system should feel like &lt;strong&gt;encouragement&lt;/strong&gt;
 to the user, not pressure or obligation. This relates to the balance of
 intrinsic and extrinsic motivation. Extrinsic motivation (external 
rewards, avoiding punishment) might get users started, but intrinsic 
motivation (doing the task for a personal goal like learning Spanish 
because you genuinely want to communicate with a loved one) is stronger 
for long-term engagement.&lt;/p&gt;&lt;p&gt;A good system should gravitate towards 
intrinsic motivation with careful use of extrinsic elements, i.e., 
remind users of how far they have come, not threaten them with what they
 might lose. Again, it is a fine line.&lt;/p&gt;&lt;p&gt;A simple test when 
designing a streak system is to actually take some time and think 
whether your products make money by selling solutions to anxiety that 
your product created. If yes, there’s a high chance you are exploiting 
users.&lt;/p&gt;&lt;p&gt;So the next question becomes, &lt;em&gt;If I choose to use streak, how do I design it in a way that genuinely helps users achieve their goals?&lt;/em&gt;&lt;/p&gt;&lt;h3 id="the-ux-of-good-streak-system-design"&gt;The UX of Good Streak System Design&lt;/h3&gt;&lt;p&gt;I
 believe this is where most projects either nail an effective streak 
system or completely mess it up. Let’s go through some UX principles of a
 good streak design.&lt;/p&gt;&lt;h3 id="keep-it-effortless"&gt;Keep It Effortless&lt;/h3&gt;&lt;p&gt;You’ve probably heard this before, maybe from books like &lt;a href="https://jamesclear.com/atomic-habits"&gt;&lt;em&gt;Atomic Habits&lt;/em&gt;&lt;/a&gt;,
 but it’s worth mentioning that one of the easiest ways habits can be 
formed is by making the action tiny and easy. This is similar to the &lt;em&gt;ability&lt;/em&gt; factor we discussed from the Fogg Behaviour Model.&lt;/p&gt;&lt;blockquote class="pull-quote"&gt;&lt;p&gt;&lt;a aria-label="Share on Twitter" class="pull-quote__link" href="https://twitter.com/share?text=%0aThe%20first%20rule%20of%20any%20streak%20design%20should%20be%20making%20the%20required%20action%20as%20small%20as%20humanly%20possible%20while%20still%20achieving%20progress.%0a&amp;amp;url=https://smashingmagazine.com%2f2026%2f02%2fdesigning-streak-system-ux-psychology%2f"&gt;The
 first rule of any streak design should be making the required action as
 small as humanly possible while still achieving progress.&lt;/a&gt;&lt;/p&gt;&lt;div class="pull-quote__quotation"&gt;&lt;div class="pull-quote__bg"&gt;&lt;span class="pull-quote__symbol"&gt;“&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;p&gt;If
 a daily action requires willpower to complete, that action won’t make 
it past five days. Why? You can’t be motivated five days in a row.&lt;/p&gt;&lt;p&gt;Case
 in point: If you run a meditation app, you don’t need to make users go 
through a 20-minute session just to maintain the streak. Try a single 
minute, maybe even something as small as thirty seconds, instead.&lt;/p&gt;&lt;p&gt;As the saying goes, &lt;a href="https://en.wikipedia.org/wiki/Little_Things_(poem)"&gt;&lt;em&gt;little drops of water make the mighty ocean&lt;/em&gt;&lt;/a&gt;.
 Small efforts compile into big achievements with time. That should be 
the goal: remove friction, especially when the moment might be 
difficult. When users are stressed or overwhelmed, let them know that 
simply showing up, even for a few seconds, counts as effort.&lt;/p&gt;&lt;h3 id="provide-clear-visual-feedback"&gt;Provide Clear Visual Feedback&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/02/designing-streak-system-ux-psychology/#provide-clear-visual-feedback"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Humans
 are visual by nature. Most times, we need to see something to believe; 
there’s this need to visualize things to understand them better and put 
things into perspective.&lt;/p&gt;&lt;p&gt;This is why streak patterns often use 
visual elements, like graphs, checkmarks, progress rings, and grids, to 
visualize effort. Look at GitHub’s contribution graph. It is a simple 
visualization of consistency. Yet developers breathe it in like oxygen.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/designing-streak-system-ux-psychology/2-contributions-graph.png"&gt;&lt;img alt="The contributions graph displayed on a GitHub user profile" height="207" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/designing-streak-system-ux-psychology/2-contributions-graph.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;The contributions graph displayed on a GitHub user profile.&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;strong&gt;The key is not to make a streak system feel abstract.&lt;/strong&gt;
 It should feel real and earned. For instance, Duolingo and Apple’s 
Fitness activity rings use clean animation designs on completion of a 
streak, and GitHub shows historical data of a user’s consistency over 
time.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/designing-streak-system-ux-psychology/3-apple-watch-fitness.png"&gt;&lt;img alt="Apple Watch Fitness shows a limited animated badge on completion of all three Activity rings." height="610" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/designing-streak-system-ux-psychology/3-apple-watch-fitness.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Apple Watch Fitness shows a limited animated badge on completion of all three Activity rings. (Image source: &lt;a href="https://www.apple.com/"&gt;Apple&lt;/a&gt;)&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="use-good-timing"&gt;Use Good Timing&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/02/designing-streak-system-ux-psychology/#use-good-timing"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;I
 mentioned earlierthat humans are generally forgetful by nature, and 
that prompts can help maintain forward momentum. Without prompts, most &lt;em&gt;new&lt;/em&gt;
 users forget to keep going. Life can get busy, motivation disappears, 
and things happen. Even long-time users benefit from prompts, though 
most times, they are already locked inside the habit loop. Nevertheless,
 even the most committed person can accidentally miss a day.&lt;/p&gt;&lt;p&gt;Your streak system most definitely needs reminders. The most-used prompt reminders are &lt;a href="https://www.smashingmagazine.com/2022/04/guide-push-notifications-developers/"&gt;push notifications&lt;/a&gt;.
 Timing really matters when working with push notifications. The type of
 app matters, too. Sending a notification at 9 a.m. saying &lt;em&gt;“You haven’t practiced today”&lt;/em&gt;
 is just weird for a learning app because many have things to do in the 
day before they even think about completing a lesson. If we’re talking 
about a fitness app, though, it is reasonable and maybe even expected to
 be reminded earlier in the day.&lt;/p&gt;&lt;p&gt;&lt;a href="https://clevertap.com/blog/best-time-to-send-push-notifications/#:~:text=Need%20to%20Know!-,Industry%2DSpecific%20Timing%3A%20Tailor%20Your%20Approach,-Different%20industries%20have"&gt;Push notifications vary significantly by app category&lt;/a&gt;.
 Fitness apps, for instance, see higher engagement with early morning 
notifications (7–8 AM), while productivity apps might perform better in 
early noon. The key is to A/B test your app’s timing based on your 
users’ behaviours rather than assuming things are one-size-fits-all. 
What works for a meditation app might not work for a coding tracker.&lt;/p&gt;&lt;p&gt;Other prompt methods are red dots on the app icon and even app widgets. Studies vary, but &lt;a href="https://www.nber.org/system/files/working_papers/w28936/w28936.pdf?utm_campaign=PAN%5B…%5Dtm_medium=PANTHEON_STRIPPED&amp;amp;%3Butm_source=PANTHEON_STRIPPEDhttps://www.nber.org/system/files/working_papers/w28936/w28936.pdf?utm_campaign=PAN%5B…%5Dtm_medium=PANTHEON_STRIPPED&amp;amp;%3Butm_source=PANTHEON_STRIPPED"&gt;the average person unlocks their device between 50-150 times a day&lt;/a&gt;
 (PDF). If a user sees a red dot on an app or a widget that indicates a 
current streak every time they unlock their phone, it increases 
commitment.&lt;/p&gt;&lt;p&gt;Just don’t overdo it; the prompt should serve as a reminder, not a nag.&lt;/p&gt;&lt;h3 id="celebrate-milestones"&gt;Celebrate Milestones&lt;/h3&gt;&lt;p&gt;A streak system should try to celebrate milestones to reignite emotions, especially for users deep into a streak.&lt;/p&gt;&lt;p&gt;When
 a user hits Day 7, Day 30, Day 50, Day 100, Day 365, you should make a 
big deal out of it. Acknowledge achievements — especially for long-time 
users.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/designing-streak-system-ux-psychology/4-apple-animated-badges.jpg"&gt;&lt;img alt="Apple watch achievement badges awards" height="548" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/designing-streak-system-ux-psychology/4-apple-animated-badges.jpg" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Image source: &lt;a href="https://www.apple.com/"&gt;Apple&lt;/a&gt;.&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;As
 we saw earlier, Duolingo figured this out and implemented an animated 
graphic that celebrates milestones with confetti. Some platforms even 
give substantial bonus rewards that validate users’ efforts. And this 
can be beneficial to apps, such that users tend to share their 
milestones publicly on social media.&lt;/p&gt;&lt;p&gt;Another benefit is the 
anticipation that comes before reaching milestones. It isn’t just 
keeping the streak alive endlessly; users have something to look forward
 to.&lt;/p&gt;&lt;h3 id="use-grace-mechanisms"&gt;Use Grace Mechanisms&amp;nbsp;&lt;/h3&gt;&lt;p&gt;Life
 is unpredictable. People get distracted. Any good streak system should 
expect imperfection. One of the biggest psychological threats to a 
streak system is the hard reset to zero after just a single missed day.&lt;/p&gt;&lt;p&gt;An
 “ethical” streak system should provide the user with some slack. Let’s 
say you have a 90-day chess learning streak. You have been consistent 
for three good months, and one day, your phone dies while traveling, and
 just like that, 90 becomes 0 — everything, all that effort, is erased, 
and progress vanishes. The user might be completely devastated. The 
thought of rebuilding it from scratch is so demoralizing that the effort
 isn’t worth it. At worst, a user might abandon the app after feeling 
like a failure.&lt;/p&gt;&lt;p&gt;Consider adding a “grace” mechanism to your streak system:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Streak Freeze&lt;/strong&gt;&lt;br /&gt;Allow users to intentionally miss a day without penalties.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Extra Time&lt;/strong&gt;&lt;br /&gt;Allow a few hours (2–3) past the usual deadline before triggering a reset.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Decay Models&lt;/strong&gt;&lt;br /&gt;Instead of a hard reset, the streak decreases by a small amount, e.g., 10 days is deducted from the streak per missed day.&lt;/li&gt;&lt;/ul&gt;&lt;h3 id="use-an-encouraging-tone"&gt;Use An Encouraging Tone&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/02/designing-streak-system-ux-psychology/#use-an-encouraging-tone"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Let’s compare two messages shown to users when a streak breaks:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;“You lost your 42-day streak. Start over.”&lt;/li&gt;&lt;li&gt;“You showed up for 42 days straight. That’s incredible progress! Wanna give it another try?”&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Both
 convey the same information, but the emotional impact is different. The
 first message would most likely make a user feel demoralized and cause 
them to quit. The second message celebrates what has already been 
achieved and gently encourages the user to try again.&lt;/p&gt;&lt;h2 id="streak-systems-design-challenges"&gt;Streak Systems Design Challenges&amp;nbsp;&lt;/h2&gt;&lt;p&gt;Before
 we go into the technical specifics of building a streak system, you 
should be aware of the challenges that you might face. Things can get 
complicated, as you might expect.&lt;/p&gt;&lt;h3 id="handling-timezones"&gt;Handling Timezones&lt;/h3&gt;&lt;p&gt;There
 is a reason why handling time and date is among the most difficult 
concepts developers deal with. There’s formatting, internationalization,
 and much more to consider.&lt;/p&gt;&lt;p&gt;Let me ask you this: &lt;em&gt;What counts as a day?&lt;/em&gt;&lt;/p&gt;&lt;p&gt;We
 know the world runs on different time zones, and as if that is not 
enough, some regions have Daylight Saving Time (DST) that happens twice a
 year. Where do you even begin handling these edge cases? What counts as
 the “start” of tomorrow?&lt;/p&gt;&lt;p&gt;Some developers try to avoid this by 
using one central timezone, like UTC. For some users, this would yield 
correct results, but for some, it could be off by an hour, two hours, or
 more. This inconsistency ruins the user experience. Users care less how
 you handle the time behind the scenes; all they expect is that if they 
perform a streak action at 11:40 p.m., then it should register at that 
exact time, in their context. You should define “one day” based on the 
user’s local timezone, not the server time.&lt;/p&gt;&lt;p&gt;Sure, you can take the
 easy route and reset streaks globally for all users at midnight UTC, 
but you are very much creating unfairness. Someone in California always 
has eight extra hours to complete their task than someone living in 
London. That’s an unjust design flaw that punishes certain users because
 of their location. And what if that person in London is only visiting, 
completes a task, then returns to another timezone?&lt;/p&gt;&lt;p&gt;One effective 
solution to all these is to ask users to explicitly set their timezone 
during onboarding (preferably after first authentication). It’s a good 
idea to include a subtle note that providing timezone information is 
only used for the app to accurately track progress, rather than being 
used as personally identifiable data. And it’s another good idea to make
 that a changeable setting.&lt;/p&gt;&lt;p&gt;I suggest that anyone avoid directly handling timezone logic in an app. Use tried-and-true date libraries, like &lt;a href="https://momentjs.com"&gt;Moment.js&lt;/a&gt; or &lt;a href="https://pypi.org/project/pytz/"&gt;pytz&lt;/a&gt; (Python), etc. There’s no need to reinvent the wheel for something as complex as this.&lt;/p&gt;&lt;h3 id="missed-days-and-edge-cases"&gt;Missed Days And Edge Cases&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/02/designing-streak-system-ux-psychology/#missed-days-and-edge-cases"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Another
 challenge you should worry about is uncontrollable edge cases like 
users oversleeping, server downtime, lag, network failures, and so on. 
Using the idea of &lt;strong&gt;grace mechanisms&lt;/strong&gt;, like the ones we discussed earlier, can help.&lt;/p&gt;&lt;p&gt;A
 grace window of two hours might help both user and developer, in the 
sense that users are not rigidly punished for uncontrollable life 
circumstances. For developers, grace windows are helpful in those 
uncontrollable moments when the server goes down in the middle of the 
night.&lt;/p&gt;&lt;p&gt;Above all, never trust the client. Always validate on the server-side. The server should be the single source of truth.&lt;/p&gt;&lt;h3 id="cheating-prevention"&gt;Cheating Prevention&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/02/designing-streak-system-ux-psychology/#cheating-prevention"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Again, I cannot stress this enough: &lt;strong&gt;Make sure to validate everything server-side.&lt;/strong&gt; Users are humans, and humans might cheat if given the opportunity. It is unavoidable.&lt;/p&gt;&lt;p&gt;You might try:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Storing all actions with UTC timestamps.&lt;/strong&gt;&lt;br /&gt;The
 client can send their local time, but the server can immediately 
convert that to UTC and validate against the server time. That way, if 
the client’s timestamp is suspiciously far, the system can reject it as 
an error, and the UI can respond accordingly.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Using event-based tracking.&lt;/strong&gt;&lt;br /&gt;In
 other words, store a record of each action with metadata including 
information like the user’s ID, the type of action performed, and the 
timestamp and timezone. This helps with validation.&lt;/li&gt;&lt;/ul&gt;&lt;h2 id="building-a-streak-system-engine"&gt;Building A Streak System Engine&amp;nbsp;&lt;/h2&gt;&lt;p&gt;This
 isn’t a code tutorial, so I will avoid dumping a bunch of code on you. 
I’ll keep this practical and describe how things generally operate a 
streak system engine as far as architecture, flow, and reliability.&lt;/p&gt;&lt;h3 id="core-architecture"&gt;Core Architecture&lt;/h3&gt;&lt;p&gt;As
 I’ve said several times, make the serverthe single source of truth for 
streak data. The architecture can go something like this on the server:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Store each user’s data in a database.&lt;/li&gt;&lt;li&gt;Store the current streak store (default as 0) as an integer.&lt;/li&gt;&lt;li&gt;Store
 the timezone preference, i.e., IANA Timezone string (either implicitly 
from local timestamp or explicitly by asking user to select their 
timezone). For example, “America/New_York”.&lt;/li&gt;&lt;li&gt;Handle all logic to 
determine if the streak continues or breaks, with a timezone check that 
is relative to the user’s local timezone.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Meanwhile, on the client-side:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Display the current streak, normally fetched from the server.&lt;/li&gt;&lt;li&gt;Send
 action done in the form of metadata to the server to validate whether 
the user actually completed a qualifying streak action.&lt;/li&gt;&lt;li&gt;Provide visual feedback based on the server responses.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;So,
 in short, the brain is on the server, and the client is for display 
purposes and submitting events. This saves you a lot of failures and 
edge cases, plus makes updates and fixes easier.&lt;/p&gt;&lt;h3 id="the-logical-flow"&gt;The Logical Flow&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/02/designing-streak-system-ux-psychology/#the-logical-flow"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Let’s simulate a walkthrough of how a minimal efficient streak system engine would go when a user completes an action:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The user completes a qualifying streak action.&lt;/li&gt;&lt;li&gt;The client sends an event to the server as metadata. This could be “User X completed action Y at timestamp Z”.&lt;/li&gt;&lt;li&gt;The
 server receives this event and does basic validation. Is this a real 
user? Are they authenticated? Is the action valid? Is the timezone 
consistent?&lt;/li&gt;&lt;li&gt;If this passes, the server retrieves the user’s streak data from the database.&lt;/li&gt;&lt;li&gt;Then, convert the received action timestamp to the user’s local timezone.&lt;/li&gt;&lt;li&gt;Let the server compare the calendar dates (not timestamps) in the user’s local timezone:&lt;ul&gt;&lt;li&gt;If it is the same day, then the action is redundant and there is no change in the streak.&lt;/li&gt;&lt;li&gt;If it is the next day, then the streak extends and increments by 1.&lt;/li&gt;&lt;li&gt;If there is a gap of more than one day, the streak breaks. However, this is where you might apply grace mechanics.&lt;/li&gt;&lt;li&gt;If the grace mechanism is missed, then reset the streak to 1.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;If
 you choose to save historical data for milestone achievements, then 
update variables like “longest streak” or “total active days”.&lt;/li&gt;&lt;li&gt;The server then updates the database and responds to the client. Something like this:&lt;/li&gt;&lt;/ol&gt;&lt;div class="code-toolbar"&gt;&lt;pre class="  language-json"&gt;&lt;code class="  language-json"&gt;&lt;span class="token punctuation"&gt;{&lt;/span&gt;
  &lt;span class="token property"&gt;"current_streak"&lt;/span&gt;&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;48&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  &lt;span class="token property"&gt;"longest_streak"&lt;/span&gt;&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;50&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  &lt;span class="token property"&gt;"total_active_days"&lt;/span&gt;&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token number"&gt;120&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
  &lt;span class="token property"&gt;"streak_extended"&lt;/span&gt;&lt;span class="token operator"&gt;:&lt;/span&gt; &lt;span class="token boolean"&gt;true&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;As a further measure, the server should either retry or reject and notify the client when anything fails during the process.&lt;/p&gt;&lt;h3 id="building-for-resilience"&gt;Building For Resilience&lt;/h3&gt;&lt;p&gt;As
 mentioned before, users losing a streak due to bugs or server downtime 
is terrible UX, and users don’t expect to take the fall for it. Thus, 
your streak system should have safeguards for those scenarios.&lt;/p&gt;&lt;p&gt;If 
the server is down for maintenance (or whatever reason), consider 
allowing a temporary window of additional hours to get it fixed so 
actions can be submitted late and still count. You can also choose to 
notify users, especially if the situation is capable of affecting an 
ongoing streak.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Establish an admin backdoor
 where data can be manually restored. Bugs are inevitable, and some 
users would call your app out or reach out to support that their streak 
broke for a reason they could not control. You should be able to 
manually restore the streaks if, after investigation, the user is right.&lt;/p&gt;&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;&lt;p&gt;One thing remains clear: Streaks are really powerful because of how human psychology works on a fundamental level.&lt;/p&gt;&lt;p&gt;The
 best streak system out there is the one that users don’t think about 
consciously. It has become a routine of immediate results or visible 
progress, like brushing teeth, which becomes a regular habit.&lt;/p&gt;&lt;p&gt;And 
I’m just gonna say it: Not all products need a streak system. Should you
 really force consistency just because you want daily active users? The 
answer may very well be “no”.&lt;/p&gt;</description><link>http://honeyvig.blogspot.com/2026/03/designing-streak-system-ux-and.html</link><author>noreply@blogger.com (H)</author><thr:total>0</thr:total><enclosure length="579424" type="application/pdf" url="https://www.nber.org/system/files/working_papers/w28936/w28936.pdf?utm_campaign=PAN%5B…%5Dtm_medium=PANTHEON_STRIPPED&amp;amp;%3Butm_source=PANTHEON_STRIPPEDhttps://www.nber.org/system/files/working_papers/w28936/w28936.pdf?utm_campaign=PAN%5B…%5Dtm_medium=PANTHEON_STRIPPED&amp;amp;%3Butm_source=PANTHEON_STRIPPED"/><itunes:explicit>no</itunes:explicit><itunes:subtitle>&amp;nbsp;What makes streaks so powerful and addictive? To design them well, you need to understand how they align with human psychology. Victor Ayomipo breaks down the UX and design principles behind effective streak systems. I’m sure you’ve heard of streaks or used an app with one. But ever wondered why streaks are so popular and powerful? Well, there is the obvious one that apps want as much of your attention as possible, but aside from that, did you know that when the popular learning app Duolingo introduced iOS widgets to display streaks, user commitment surged by 60%. Sixty percent is a massive shift in behaviour and demonstrates how “streak” patterns can be used to increase engagement and drive usage. At its most basic, a streak is the number of consecutive days that a user completes a specific activity. Some people also define it as a “gamified” habit or a metric designed to encourage consistent usage. But streaks transcend beyond being a metric or a record in an app; it is more psychological than that. Human instincts are easy to influence with the right factors. Look at these three factors: progress, pride, and fear of missing out (commonly called FOMO). What do all these have in common? Effort. The more effort you put into something, the more it shapes your identity, and that is how streaks crosses into the world of behavioural psychology. Now, with great power comes great responsibility, and because of that, there’s a dark side to streaks. In this article, we’ll be going into the psychology, UX, and design principles behind building an effective streak system. We’ll look at (1) why our brains almost instinctively respond to streak activity, (2) how to design streaks in ways that genuinely help users, and (3) the technical work involved in building a streak pattern.The Psychology Behind Streaks&amp;nbsp;# To design and build an effective streak system, we need to understand how it aligns with how our brains are wired. Like, what makes it so effective to the extent that we feel so much intense dedication to protect our streaks? There are three interesting, well-documented psychology principles that support what makes streaks so powerful and addictive.Loss Aversion&amp;nbsp; This is probably the strongest force behind streaks. I say this because most times, you almost can’t avoid this in life. Think of it this way: If a friend gives you $100, you’d be happy. But if you lost $100 from your wallet, that would hurt way more. The emotional weight of those situations isn’t equal. Loss hurts way more than gain feels good. Let’s take it further and say that I give you $100 and ask you to play a gamble. There’s a 50% chance you win another $100 and a 50% chance you lose the original $100. Would you take it? I wouldn’t. Most people wouldn’t. That’s loss aversion. If you think about it, it is logical, it is understandable, it is human. The concept behind loss aversion is that we feel the pain of losing something twice as much as the pleasure of gaining something of equal value. In psychological terms, loss lingers more than gains do. You probably see how this relates to streaks. To build a noticeable streak, it requires effort; as a streak grows, the motivation behind it begins to fade; or more accurately, it starts to become secondary. Here’s an example: Say your friend has a three-day streak closing their “Move Rings” on their Apple Watch. They have almost nothing to lose beyond wanting to achieve their goal and be consistent. At the same time, you have an impressive 219-day streak going. Chances are that you are trapped by the fear of losing it. You most likely aren’t thinking about the achievement at this point; it’s more about protecting your invested effort, and that is loss aversion. Duolingo explains how loss aversion contributes to a user’s reluctance to break a long streak, even on their laziest days. In a way, a streak can turn into a habit when loss aversion settles in.The Fogg Behaviour Model (B = MAP) Now that we understand the fear of losing the effort invested in longer streaks, another question is: What makes us do the thing in the first place, day after day, even before the streak gets big? That’s what the Fogg Behaviour Model is about. It is relatively simple. A behaviour (B) only occurs when three factors — Motivation (M), Ability (A), and Prompt (P) — align at the same moment. Thus, the equation B=MAP. If any of these factors, even one, is missing at that moment, the behaviour won’t happen. So, for a streak system to be efficient and recurring, all three factors must be present: Motivation This is fragile and not something that is consistently present. There are days when you’re pumped to learn Spanish, and days you don’t even feel an iota of willpower to learn the language. Motivation by itself to build a habit is unreliable and a losing battle from day one. Ability To compensate for the limitations of motivation, ability is critical. In this context, ability means the ease of action, i.e, the effort is so easy that it’s unrealistic to say it isn’t possible. Most apps intentionally use this. Apple Fitness just needs you to stand for one minute in an hour to earn a tick towards your Stand goal. Duolingo only needs one completed lesson. These tasks do not require all that much effort. The barrier is so low that even on your worst days, you can do it. But the combined effort of an ongoing streak is where the idea of losing that streak kicks in. Prompt This is what completes the equation. Humans are naturally forgetful, so yes, ability can get us 90% there. But a prompt reminds us to act. Streaks are persistent by design, so users need to be constantly reminded to act. To see how powerful a prompt can be, Duolingo did an A/B test to see if a little red badge on the app’s icon increased consistent usage. It produced a 6% increase in daily active users. Just a red badge.Model Limitation All this being said, there is a limitation to the Fogg model whereby critics and modern research have noticed that a design that relies too heavily on prompts, like aggressive notifications, risks creating mental fatigue. Constant notifications and overtime could cause users to churn. So, watch out for that.The Zeigarnik Effect&amp;nbsp; How do you feel when you leave a task of project half-done? That irritates many people because unfinished tasks occupy more mental space than the things we complete. When something is done and gone, we tend to forget it. When something is left undone, it tends to weigh on our minds. This is exactly why digital products use artificial progress indicators, like Upwork’s profile completion bar, to let a user know that their profile is only “60% complete”. It nudges the user to finish what they started.Upwork’s profile completion progress bar. Let’s look at another example. You have five tasks in a to-do list app, and at the end of the day, you only check four of them as completed. Many of us will feel unaccomplished because of that one unfinished task. That, right there, is the Zeigarnik effect. The Zeigarnik effecthe was demonstrated by psychologist Bluma Zeigarnik, who described that we tend to keep incomplete tasks active in our memory longer than completed tasks. A streak pattern naturally taps into this in UX design. Let’s say you are on day 63 of a learning streak. At that point, you’re in an ongoing pattern of unfinished business. Your brain would rarely forget about it as it sits in the back of your mind. At this point, your brain becomes the one sending you notifications. When you put these psychological forces together, you begin to truly understand why streaks aren’t just a regular app feature; they are capable of reshaping human behaviour. But somewhere along the line — I can’t say exactly when, as it differs for everyone — things reach a point where a streak shifts from “fun” to something you feel you can’t afford to lose. You don’t want 58 days of effort to go to waste, do you? That is what makes a streak system effective. If done right, streaks help users build astounding habits that accomplish a goal. It could be reading daily or hitting the gym consistently. These repeated actions (sometimes small) compound over time and become evident in our daily lives. But there are two sides to every coin.The Thin Line Between Habit And Compulsion If you have been following along, you can already tell there’s a dark side to streak systems. Habit formation is about consistency with a repeated goal. Compulsion, however, is the consistency of working on a goal that is no longer needed but held onto out of fear or pressure. It is a razor-thin line. You brush your teeth every morning without thinking; it is automatic and instinctive, with a clear goal of having good breath. That’s a streak that forms a good habit. An ethical streak system gives users space to breathe. If, for some reason, you don’t brush in the morning, you can brush at noon. Imperfection is allowed without fear of losing a long effort. Compulsion takes the opposite route, whereby a streak makes you anxious, you feel guilty or even exhausted, and sometimes, it feels like you haven’t accomplished anything, despite all your work. You act not because you want to, but because you’re subconsciously terrified of seeing your progress reset to zero. Someone even described this perfectly, “I felt that I was cheating, but simply did not care. I am nothing without my streak”. This shows the extreme hold streaks can have on an individual. To the extent that users begin to tie their self-worth to an arbitrary metric rather than the original goal or reason they started the streak in the first place. The streak becomes who they are, not just what they do. A well-designed ethical streak system should feel like encouragement to the user, not pressure or obligation. This relates to the balance of intrinsic and extrinsic motivation. Extrinsic motivation (external rewards, avoiding punishment) might get users started, but intrinsic motivation (doing the task for a personal goal like learning Spanish because you genuinely want to communicate with a loved one) is stronger for long-term engagement. A good system should gravitate towards intrinsic motivation with careful use of extrinsic elements, i.e., remind users of how far they have come, not threaten them with what they might lose. Again, it is a fine line. A simple test when designing a streak system is to actually take some time and think whether your products make money by selling solutions to anxiety that your product created. If yes, there’s a high chance you are exploiting users. So the next question becomes, If I choose to use streak, how do I design it in a way that genuinely helps users achieve their goals?The UX of Good Streak System Design I believe this is where most projects either nail an effective streak system or completely mess it up. Let’s go through some UX principles of a good streak design.Keep It Effortless You’ve probably heard this before, maybe from books like Atomic Habits, but it’s worth mentioning that one of the easiest ways habits can be formed is by making the action tiny and easy. This is similar to the ability factor we discussed from the Fogg Behaviour Model. The first rule of any streak design should be making the required action as small as humanly possible while still achieving progress.“ If a daily action requires willpower to complete, that action won’t make it past five days. Why? You can’t be motivated five days in a row. Case in point: If you run a meditation app, you don’t need to make users go through a 20-minute session just to maintain the streak. Try a single minute, maybe even something as small as thirty seconds, instead. As the saying goes, little drops of water make the mighty ocean. Small efforts compile into big achievements with time. That should be the goal: remove friction, especially when the moment might be difficult. When users are stressed or overwhelmed, let them know that simply showing up, even for a few seconds, counts as effort.Provide Clear Visual Feedback&amp;nbsp;# Humans are visual by nature. Most times, we need to see something to believe; there’s this need to visualize things to understand them better and put things into perspective. This is why streak patterns often use visual elements, like graphs, checkmarks, progress rings, and grids, to visualize effort. Look at GitHub’s contribution graph. It is a simple visualization of consistency. Yet developers breathe it in like oxygen.The contributions graph displayed on a GitHub user profile.&amp;nbsp; The key is not to make a streak system feel abstract. It should feel real and earned. For instance, Duolingo and Apple’s Fitness activity rings use clean animation designs on completion of a streak, and GitHub shows historical data of a user’s consistency over time.Apple Watch Fitness shows a limited animated badge on completion of all three Activity rings. (Image source: Apple)&amp;nbsp;Use Good Timing&amp;nbsp;# I mentioned earlierthat humans are generally forgetful by nature, and that prompts can help maintain forward momentum. Without prompts, most new users forget to keep going. Life can get busy, motivation disappears, and things happen. Even long-time users benefit from prompts, though most times, they are already locked inside the habit loop. Nevertheless, even the most committed person can accidentally miss a day. Your streak system most definitely needs reminders. The most-used prompt reminders are push notifications. Timing really matters when working with push notifications. The type of app matters, too. Sending a notification at 9 a.m. saying “You haven’t practiced today” is just weird for a learning app because many have things to do in the day before they even think about completing a lesson. If we’re talking about a fitness app, though, it is reasonable and maybe even expected to be reminded earlier in the day. Push notifications vary significantly by app category. Fitness apps, for instance, see higher engagement with early morning notifications (7–8 AM), while productivity apps might perform better in early noon. The key is to A/B test your app’s timing based on your users’ behaviours rather than assuming things are one-size-fits-all. What works for a meditation app might not work for a coding tracker. Other prompt methods are red dots on the app icon and even app widgets. Studies vary, but the average person unlocks their device between 50-150 times a day (PDF). If a user sees a red dot on an app or a widget that indicates a current streak every time they unlock their phone, it increases commitment. Just don’t overdo it; the prompt should serve as a reminder, not a nag.Celebrate Milestones A streak system should try to celebrate milestones to reignite emotions, especially for users deep into a streak. When a user hits Day 7, Day 30, Day 50, Day 100, Day 365, you should make a big deal out of it. Acknowledge achievements — especially for long-time users.Image source: Apple.&amp;nbsp; As we saw earlier, Duolingo figured this out and implemented an animated graphic that celebrates milestones with confetti. Some platforms even give substantial bonus rewards that validate users’ efforts. And this can be beneficial to apps, such that users tend to share their milestones publicly on social media. Another benefit is the anticipation that comes before reaching milestones. It isn’t just keeping the streak alive endlessly; users have something to look forward to.Use Grace Mechanisms&amp;nbsp; Life is unpredictable. People get distracted. Any good streak system should expect imperfection. One of the biggest psychological threats to a streak system is the hard reset to zero after just a single missed day. An “ethical” streak system should provide the user with some slack. Let’s say you have a 90-day chess learning streak. You have been consistent for three good months, and one day, your phone dies while traveling, and just like that, 90 becomes 0 — everything, all that effort, is erased, and progress vanishes. The user might be completely devastated. The thought of rebuilding it from scratch is so demoralizing that the effort isn’t worth it. At worst, a user might abandon the app after feeling like a failure. Consider adding a “grace” mechanism to your streak system:Streak Freeze Allow users to intentionally miss a day without penalties.Extra Time Allow a few hours (2–3) past the usual deadline before triggering a reset.Decay Models Instead of a hard reset, the streak decreases by a small amount, e.g., 10 days is deducted from the streak per missed day.Use An Encouraging Tone&amp;nbsp;# Let’s compare two messages shown to users when a streak breaks:“You lost your 42-day streak. Start over.”“You showed up for 42 days straight. That’s incredible progress! Wanna give it another try?” Both convey the same information, but the emotional impact is different. The first message would most likely make a user feel demoralized and cause them to quit. The second message celebrates what has already been achieved and gently encourages the user to try again.Streak Systems Design Challenges&amp;nbsp; Before we go into the technical specifics of building a streak system, you should be aware of the challenges that you might face. Things can get complicated, as you might expect.Handling Timezones There is a reason why handling time and date is among the most difficult concepts developers deal with. There’s formatting, internationalization, and much more to consider. Let me ask you this: What counts as a day? We know the world runs on different time zones, and as if that is not enough, some regions have Daylight Saving Time (DST) that happens twice a year. Where do you even begin handling these edge cases? What counts as the “start” of tomorrow? Some developers try to avoid this by using one central timezone, like UTC. For some users, this would yield correct results, but for some, it could be off by an hour, two hours, or more. This inconsistency ruins the user experience. Users care less how you handle the time behind the scenes; all they expect is that if they perform a streak action at 11:40 p.m., then it should register at that exact time, in their context. You should define “one day” based on the user’s local timezone, not the server time. Sure, you can take the easy route and reset streaks globally for all users at midnight UTC, but you are very much creating unfairness. Someone in California always has eight extra hours to complete their task than someone living in London. That’s an unjust design flaw that punishes certain users because of their location. And what if that person in London is only visiting, completes a task, then returns to another timezone? One effective solution to all these is to ask users to explicitly set their timezone during onboarding (preferably after first authentication). It’s a good idea to include a subtle note that providing timezone information is only used for the app to accurately track progress, rather than being used as personally identifiable data. And it’s another good idea to make that a changeable setting. I suggest that anyone avoid directly handling timezone logic in an app. Use tried-and-true date libraries, like Moment.js or pytz (Python), etc. There’s no need to reinvent the wheel for something as complex as this.Missed Days And Edge Cases&amp;nbsp;# Another challenge you should worry about is uncontrollable edge cases like users oversleeping, server downtime, lag, network failures, and so on. Using the idea of grace mechanisms, like the ones we discussed earlier, can help. A grace window of two hours might help both user and developer, in the sense that users are not rigidly punished for uncontrollable life circumstances. For developers, grace windows are helpful in those uncontrollable moments when the server goes down in the middle of the night. Above all, never trust the client. Always validate on the server-side. The server should be the single source of truth.Cheating Prevention&amp;nbsp;# Again, I cannot stress this enough: Make sure to validate everything server-side. Users are humans, and humans might cheat if given the opportunity. It is unavoidable. You might try:Storing all actions with UTC timestamps. The client can send their local time, but the server can immediately convert that to UTC and validate against the server time. That way, if the client’s timestamp is suspiciously far, the system can reject it as an error, and the UI can respond accordingly.Using event-based tracking. In other words, store a record of each action with metadata including information like the user’s ID, the type of action performed, and the timestamp and timezone. This helps with validation.Building A Streak System Engine&amp;nbsp; This isn’t a code tutorial, so I will avoid dumping a bunch of code on you. I’ll keep this practical and describe how things generally operate a streak system engine as far as architecture, flow, and reliability.Core Architecture As I’ve said several times, make the serverthe single source of truth for streak data. The architecture can go something like this on the server:Store each user’s data in a database.Store the current streak store (default as 0) as an integer.Store the timezone preference, i.e., IANA Timezone string (either implicitly from local timestamp or explicitly by asking user to select their timezone). For example, “America/New_York”.Handle all logic to determine if the streak continues or breaks, with a timezone check that is relative to the user’s local timezone. Meanwhile, on the client-side:Display the current streak, normally fetched from the server.Send action done in the form of metadata to the server to validate whether the user actually completed a qualifying streak action.Provide visual feedback based on the server responses. So, in short, the brain is on the server, and the client is for display purposes and submitting events. This saves you a lot of failures and edge cases, plus makes updates and fixes easier.The Logical Flow&amp;nbsp;# Let’s simulate a walkthrough of how a minimal efficient streak system engine would go when a user completes an action:The user completes a qualifying streak action.The client sends an event to the server as metadata. This could be “User X completed action Y at timestamp Z”.The server receives this event and does basic validation. Is this a real user? Are they authenticated? Is the action valid? Is the timezone consistent?If this passes, the server retrieves the user’s streak data from the database.Then, convert the received action timestamp to the user’s local timezone.Let the server compare the calendar dates (not timestamps) in the user’s local timezone:If it is the same day, then the action is redundant and there is no change in the streak.If it is the next day, then the streak extends and increments by 1.If there is a gap of more than one day, the streak breaks. However, this is where you might apply grace mechanics.If the grace mechanism is missed, then reset the streak to 1.If you choose to save historical data for milestone achievements, then update variables like “longest streak” or “total active days”.The server then updates the database and responds to the client. Something like this:{ "current_streak": 48, "longest_streak": 50, "total_active_days": 120, "streak_extended": true, } As a further measure, the server should either retry or reject and notify the client when anything fails during the process.Building For Resilience As mentioned before, users losing a streak due to bugs or server downtime is terrible UX, and users don’t expect to take the fall for it. Thus, your streak system should have safeguards for those scenarios. If the server is down for maintenance (or whatever reason), consider allowing a temporary window of additional hours to get it fixed so actions can be submitted late and still count. You can also choose to notify users, especially if the situation is capable of affecting an ongoing streak. Note: Establish an admin backdoor where data can be manually restored. Bugs are inevitable, and some users would call your app out or reach out to support that their streak broke for a reason they could not control. You should be able to manually restore the streaks if, after investigation, the user is right.Conclusion One thing remains clear: Streaks are really powerful because of how human psychology works on a fundamental level. The best streak system out there is the one that users don’t think about consciously. It has become a routine of immediate results or visible progress, like brushing teeth, which becomes a regular habit. And I’m just gonna say it: Not all products need a streak system. Should you really force consistency just because you want daily active users? The answer may very well be “no”.</itunes:subtitle><itunes:author>noreply@blogger.com (H)</itunes:author><itunes:summary>&amp;nbsp;What makes streaks so powerful and addictive? To design them well, you need to understand how they align with human psychology. Victor Ayomipo breaks down the UX and design principles behind effective streak systems. I’m sure you’ve heard of streaks or used an app with one. But ever wondered why streaks are so popular and powerful? Well, there is the obvious one that apps want as much of your attention as possible, but aside from that, did you know that when the popular learning app Duolingo introduced iOS widgets to display streaks, user commitment surged by 60%. Sixty percent is a massive shift in behaviour and demonstrates how “streak” patterns can be used to increase engagement and drive usage. At its most basic, a streak is the number of consecutive days that a user completes a specific activity. Some people also define it as a “gamified” habit or a metric designed to encourage consistent usage. But streaks transcend beyond being a metric or a record in an app; it is more psychological than that. Human instincts are easy to influence with the right factors. Look at these three factors: progress, pride, and fear of missing out (commonly called FOMO). What do all these have in common? Effort. The more effort you put into something, the more it shapes your identity, and that is how streaks crosses into the world of behavioural psychology. Now, with great power comes great responsibility, and because of that, there’s a dark side to streaks. In this article, we’ll be going into the psychology, UX, and design principles behind building an effective streak system. We’ll look at (1) why our brains almost instinctively respond to streak activity, (2) how to design streaks in ways that genuinely help users, and (3) the technical work involved in building a streak pattern.The Psychology Behind Streaks&amp;nbsp;# To design and build an effective streak system, we need to understand how it aligns with how our brains are wired. Like, what makes it so effective to the extent that we feel so much intense dedication to protect our streaks? There are three interesting, well-documented psychology principles that support what makes streaks so powerful and addictive.Loss Aversion&amp;nbsp; This is probably the strongest force behind streaks. I say this because most times, you almost can’t avoid this in life. Think of it this way: If a friend gives you $100, you’d be happy. But if you lost $100 from your wallet, that would hurt way more. The emotional weight of those situations isn’t equal. Loss hurts way more than gain feels good. Let’s take it further and say that I give you $100 and ask you to play a gamble. There’s a 50% chance you win another $100 and a 50% chance you lose the original $100. Would you take it? I wouldn’t. Most people wouldn’t. That’s loss aversion. If you think about it, it is logical, it is understandable, it is human. The concept behind loss aversion is that we feel the pain of losing something twice as much as the pleasure of gaining something of equal value. In psychological terms, loss lingers more than gains do. You probably see how this relates to streaks. To build a noticeable streak, it requires effort; as a streak grows, the motivation behind it begins to fade; or more accurately, it starts to become secondary. Here’s an example: Say your friend has a three-day streak closing their “Move Rings” on their Apple Watch. They have almost nothing to lose beyond wanting to achieve their goal and be consistent. At the same time, you have an impressive 219-day streak going. Chances are that you are trapped by the fear of losing it. You most likely aren’t thinking about the achievement at this point; it’s more about protecting your invested effort, and that is loss aversion. Duolingo explains how loss aversion contributes to a user’s reluctance to break a long streak, even on their laziest days. In a way, a streak can turn into a habit when loss aversion settles in.The Fogg Behaviour Model (B = MAP) Now that we understand the fear of losing the effort invested in longer streaks, another question is: What makes us do the thing in the first place, day after day, even before the streak gets big? That’s what the Fogg Behaviour Model is about. It is relatively simple. A behaviour (B) only occurs when three factors — Motivation (M), Ability (A), and Prompt (P) — align at the same moment. Thus, the equation B=MAP. If any of these factors, even one, is missing at that moment, the behaviour won’t happen. So, for a streak system to be efficient and recurring, all three factors must be present: Motivation This is fragile and not something that is consistently present. There are days when you’re pumped to learn Spanish, and days you don’t even feel an iota of willpower to learn the language. Motivation by itself to build a habit is unreliable and a losing battle from day one. Ability To compensate for the limitations of motivation, ability is critical. In this context, ability means the ease of action, i.e, the effort is so easy that it’s unrealistic to say it isn’t possible. Most apps intentionally use this. Apple Fitness just needs you to stand for one minute in an hour to earn a tick towards your Stand goal. Duolingo only needs one completed lesson. These tasks do not require all that much effort. The barrier is so low that even on your worst days, you can do it. But the combined effort of an ongoing streak is where the idea of losing that streak kicks in. Prompt This is what completes the equation. Humans are naturally forgetful, so yes, ability can get us 90% there. But a prompt reminds us to act. Streaks are persistent by design, so users need to be constantly reminded to act. To see how powerful a prompt can be, Duolingo did an A/B test to see if a little red badge on the app’s icon increased consistent usage. It produced a 6% increase in daily active users. Just a red badge.Model Limitation All this being said, there is a limitation to the Fogg model whereby critics and modern research have noticed that a design that relies too heavily on prompts, like aggressive notifications, risks creating mental fatigue. Constant notifications and overtime could cause users to churn. So, watch out for that.The Zeigarnik Effect&amp;nbsp; How do you feel when you leave a task of project half-done? That irritates many people because unfinished tasks occupy more mental space than the things we complete. When something is done and gone, we tend to forget it. When something is left undone, it tends to weigh on our minds. This is exactly why digital products use artificial progress indicators, like Upwork’s profile completion bar, to let a user know that their profile is only “60% complete”. It nudges the user to finish what they started.Upwork’s profile completion progress bar. Let’s look at another example. You have five tasks in a to-do list app, and at the end of the day, you only check four of them as completed. Many of us will feel unaccomplished because of that one unfinished task. That, right there, is the Zeigarnik effect. The Zeigarnik effecthe was demonstrated by psychologist Bluma Zeigarnik, who described that we tend to keep incomplete tasks active in our memory longer than completed tasks. A streak pattern naturally taps into this in UX design. Let’s say you are on day 63 of a learning streak. At that point, you’re in an ongoing pattern of unfinished business. Your brain would rarely forget about it as it sits in the back of your mind. At this point, your brain becomes the one sending you notifications. When you put these psychological forces together, you begin to truly understand why streaks aren’t just a regular app feature; they are capable of reshaping human behaviour. But somewhere along the line — I can’t say exactly when, as it differs for everyone — things reach a point where a streak shifts from “fun” to something you feel you can’t afford to lose. You don’t want 58 days of effort to go to waste, do you? That is what makes a streak system effective. If done right, streaks help users build astounding habits that accomplish a goal. It could be reading daily or hitting the gym consistently. These repeated actions (sometimes small) compound over time and become evident in our daily lives. But there are two sides to every coin.The Thin Line Between Habit And Compulsion If you have been following along, you can already tell there’s a dark side to streak systems. Habit formation is about consistency with a repeated goal. Compulsion, however, is the consistency of working on a goal that is no longer needed but held onto out of fear or pressure. It is a razor-thin line. You brush your teeth every morning without thinking; it is automatic and instinctive, with a clear goal of having good breath. That’s a streak that forms a good habit. An ethical streak system gives users space to breathe. If, for some reason, you don’t brush in the morning, you can brush at noon. Imperfection is allowed without fear of losing a long effort. Compulsion takes the opposite route, whereby a streak makes you anxious, you feel guilty or even exhausted, and sometimes, it feels like you haven’t accomplished anything, despite all your work. You act not because you want to, but because you’re subconsciously terrified of seeing your progress reset to zero. Someone even described this perfectly, “I felt that I was cheating, but simply did not care. I am nothing without my streak”. This shows the extreme hold streaks can have on an individual. To the extent that users begin to tie their self-worth to an arbitrary metric rather than the original goal or reason they started the streak in the first place. The streak becomes who they are, not just what they do. A well-designed ethical streak system should feel like encouragement to the user, not pressure or obligation. This relates to the balance of intrinsic and extrinsic motivation. Extrinsic motivation (external rewards, avoiding punishment) might get users started, but intrinsic motivation (doing the task for a personal goal like learning Spanish because you genuinely want to communicate with a loved one) is stronger for long-term engagement. A good system should gravitate towards intrinsic motivation with careful use of extrinsic elements, i.e., remind users of how far they have come, not threaten them with what they might lose. Again, it is a fine line. A simple test when designing a streak system is to actually take some time and think whether your products make money by selling solutions to anxiety that your product created. If yes, there’s a high chance you are exploiting users. So the next question becomes, If I choose to use streak, how do I design it in a way that genuinely helps users achieve their goals?The UX of Good Streak System Design I believe this is where most projects either nail an effective streak system or completely mess it up. Let’s go through some UX principles of a good streak design.Keep It Effortless You’ve probably heard this before, maybe from books like Atomic Habits, but it’s worth mentioning that one of the easiest ways habits can be formed is by making the action tiny and easy. This is similar to the ability factor we discussed from the Fogg Behaviour Model. The first rule of any streak design should be making the required action as small as humanly possible while still achieving progress.“ If a daily action requires willpower to complete, that action won’t make it past five days. Why? You can’t be motivated five days in a row. Case in point: If you run a meditation app, you don’t need to make users go through a 20-minute session just to maintain the streak. Try a single minute, maybe even something as small as thirty seconds, instead. As the saying goes, little drops of water make the mighty ocean. Small efforts compile into big achievements with time. That should be the goal: remove friction, especially when the moment might be difficult. When users are stressed or overwhelmed, let them know that simply showing up, even for a few seconds, counts as effort.Provide Clear Visual Feedback&amp;nbsp;# Humans are visual by nature. Most times, we need to see something to believe; there’s this need to visualize things to understand them better and put things into perspective. This is why streak patterns often use visual elements, like graphs, checkmarks, progress rings, and grids, to visualize effort. Look at GitHub’s contribution graph. It is a simple visualization of consistency. Yet developers breathe it in like oxygen.The contributions graph displayed on a GitHub user profile.&amp;nbsp; The key is not to make a streak system feel abstract. It should feel real and earned. For instance, Duolingo and Apple’s Fitness activity rings use clean animation designs on completion of a streak, and GitHub shows historical data of a user’s consistency over time.Apple Watch Fitness shows a limited animated badge on completion of all three Activity rings. (Image source: Apple)&amp;nbsp;Use Good Timing&amp;nbsp;# I mentioned earlierthat humans are generally forgetful by nature, and that prompts can help maintain forward momentum. Without prompts, most new users forget to keep going. Life can get busy, motivation disappears, and things happen. Even long-time users benefit from prompts, though most times, they are already locked inside the habit loop. Nevertheless, even the most committed person can accidentally miss a day. Your streak system most definitely needs reminders. The most-used prompt reminders are push notifications. Timing really matters when working with push notifications. The type of app matters, too. Sending a notification at 9 a.m. saying “You haven’t practiced today” is just weird for a learning app because many have things to do in the day before they even think about completing a lesson. If we’re talking about a fitness app, though, it is reasonable and maybe even expected to be reminded earlier in the day. Push notifications vary significantly by app category. Fitness apps, for instance, see higher engagement with early morning notifications (7–8 AM), while productivity apps might perform better in early noon. The key is to A/B test your app’s timing based on your users’ behaviours rather than assuming things are one-size-fits-all. What works for a meditation app might not work for a coding tracker. Other prompt methods are red dots on the app icon and even app widgets. Studies vary, but the average person unlocks their device between 50-150 times a day (PDF). If a user sees a red dot on an app or a widget that indicates a current streak every time they unlock their phone, it increases commitment. Just don’t overdo it; the prompt should serve as a reminder, not a nag.Celebrate Milestones A streak system should try to celebrate milestones to reignite emotions, especially for users deep into a streak. When a user hits Day 7, Day 30, Day 50, Day 100, Day 365, you should make a big deal out of it. Acknowledge achievements — especially for long-time users.Image source: Apple.&amp;nbsp; As we saw earlier, Duolingo figured this out and implemented an animated graphic that celebrates milestones with confetti. Some platforms even give substantial bonus rewards that validate users’ efforts. And this can be beneficial to apps, such that users tend to share their milestones publicly on social media. Another benefit is the anticipation that comes before reaching milestones. It isn’t just keeping the streak alive endlessly; users have something to look forward to.Use Grace Mechanisms&amp;nbsp; Life is unpredictable. People get distracted. Any good streak system should expect imperfection. One of the biggest psychological threats to a streak system is the hard reset to zero after just a single missed day. An “ethical” streak system should provide the user with some slack. Let’s say you have a 90-day chess learning streak. You have been consistent for three good months, and one day, your phone dies while traveling, and just like that, 90 becomes 0 — everything, all that effort, is erased, and progress vanishes. The user might be completely devastated. The thought of rebuilding it from scratch is so demoralizing that the effort isn’t worth it. At worst, a user might abandon the app after feeling like a failure. Consider adding a “grace” mechanism to your streak system:Streak Freeze Allow users to intentionally miss a day without penalties.Extra Time Allow a few hours (2–3) past the usual deadline before triggering a reset.Decay Models Instead of a hard reset, the streak decreases by a small amount, e.g., 10 days is deducted from the streak per missed day.Use An Encouraging Tone&amp;nbsp;# Let’s compare two messages shown to users when a streak breaks:“You lost your 42-day streak. Start over.”“You showed up for 42 days straight. That’s incredible progress! Wanna give it another try?” Both convey the same information, but the emotional impact is different. The first message would most likely make a user feel demoralized and cause them to quit. The second message celebrates what has already been achieved and gently encourages the user to try again.Streak Systems Design Challenges&amp;nbsp; Before we go into the technical specifics of building a streak system, you should be aware of the challenges that you might face. Things can get complicated, as you might expect.Handling Timezones There is a reason why handling time and date is among the most difficult concepts developers deal with. There’s formatting, internationalization, and much more to consider. Let me ask you this: What counts as a day? We know the world runs on different time zones, and as if that is not enough, some regions have Daylight Saving Time (DST) that happens twice a year. Where do you even begin handling these edge cases? What counts as the “start” of tomorrow? Some developers try to avoid this by using one central timezone, like UTC. For some users, this would yield correct results, but for some, it could be off by an hour, two hours, or more. This inconsistency ruins the user experience. Users care less how you handle the time behind the scenes; all they expect is that if they perform a streak action at 11:40 p.m., then it should register at that exact time, in their context. You should define “one day” based on the user’s local timezone, not the server time. Sure, you can take the easy route and reset streaks globally for all users at midnight UTC, but you are very much creating unfairness. Someone in California always has eight extra hours to complete their task than someone living in London. That’s an unjust design flaw that punishes certain users because of their location. And what if that person in London is only visiting, completes a task, then returns to another timezone? One effective solution to all these is to ask users to explicitly set their timezone during onboarding (preferably after first authentication). It’s a good idea to include a subtle note that providing timezone information is only used for the app to accurately track progress, rather than being used as personally identifiable data. And it’s another good idea to make that a changeable setting. I suggest that anyone avoid directly handling timezone logic in an app. Use tried-and-true date libraries, like Moment.js or pytz (Python), etc. There’s no need to reinvent the wheel for something as complex as this.Missed Days And Edge Cases&amp;nbsp;# Another challenge you should worry about is uncontrollable edge cases like users oversleeping, server downtime, lag, network failures, and so on. Using the idea of grace mechanisms, like the ones we discussed earlier, can help. A grace window of two hours might help both user and developer, in the sense that users are not rigidly punished for uncontrollable life circumstances. For developers, grace windows are helpful in those uncontrollable moments when the server goes down in the middle of the night. Above all, never trust the client. Always validate on the server-side. The server should be the single source of truth.Cheating Prevention&amp;nbsp;# Again, I cannot stress this enough: Make sure to validate everything server-side. Users are humans, and humans might cheat if given the opportunity. It is unavoidable. You might try:Storing all actions with UTC timestamps. The client can send their local time, but the server can immediately convert that to UTC and validate against the server time. That way, if the client’s timestamp is suspiciously far, the system can reject it as an error, and the UI can respond accordingly.Using event-based tracking. In other words, store a record of each action with metadata including information like the user’s ID, the type of action performed, and the timestamp and timezone. This helps with validation.Building A Streak System Engine&amp;nbsp; This isn’t a code tutorial, so I will avoid dumping a bunch of code on you. I’ll keep this practical and describe how things generally operate a streak system engine as far as architecture, flow, and reliability.Core Architecture As I’ve said several times, make the serverthe single source of truth for streak data. The architecture can go something like this on the server:Store each user’s data in a database.Store the current streak store (default as 0) as an integer.Store the timezone preference, i.e., IANA Timezone string (either implicitly from local timestamp or explicitly by asking user to select their timezone). For example, “America/New_York”.Handle all logic to determine if the streak continues or breaks, with a timezone check that is relative to the user’s local timezone. Meanwhile, on the client-side:Display the current streak, normally fetched from the server.Send action done in the form of metadata to the server to validate whether the user actually completed a qualifying streak action.Provide visual feedback based on the server responses. So, in short, the brain is on the server, and the client is for display purposes and submitting events. This saves you a lot of failures and edge cases, plus makes updates and fixes easier.The Logical Flow&amp;nbsp;# Let’s simulate a walkthrough of how a minimal efficient streak system engine would go when a user completes an action:The user completes a qualifying streak action.The client sends an event to the server as metadata. This could be “User X completed action Y at timestamp Z”.The server receives this event and does basic validation. Is this a real user? Are they authenticated? Is the action valid? Is the timezone consistent?If this passes, the server retrieves the user’s streak data from the database.Then, convert the received action timestamp to the user’s local timezone.Let the server compare the calendar dates (not timestamps) in the user’s local timezone:If it is the same day, then the action is redundant and there is no change in the streak.If it is the next day, then the streak extends and increments by 1.If there is a gap of more than one day, the streak breaks. However, this is where you might apply grace mechanics.If the grace mechanism is missed, then reset the streak to 1.If you choose to save historical data for milestone achievements, then update variables like “longest streak” or “total active days”.The server then updates the database and responds to the client. Something like this:{ "current_streak": 48, "longest_streak": 50, "total_active_days": 120, "streak_extended": true, } As a further measure, the server should either retry or reject and notify the client when anything fails during the process.Building For Resilience As mentioned before, users losing a streak due to bugs or server downtime is terrible UX, and users don’t expect to take the fall for it. Thus, your streak system should have safeguards for those scenarios. If the server is down for maintenance (or whatever reason), consider allowing a temporary window of additional hours to get it fixed so actions can be submitted late and still count. You can also choose to notify users, especially if the situation is capable of affecting an ongoing streak. Note: Establish an admin backdoor where data can be manually restored. Bugs are inevitable, and some users would call your app out or reach out to support that their streak broke for a reason they could not control. You should be able to manually restore the streaks if, after investigation, the user is right.Conclusion One thing remains clear: Streaks are really powerful because of how human psychology works on a fundamental level. The best streak system out there is the one that users don’t think about consciously. It has become a routine of immediate results or visible progress, like brushing teeth, which becomes a regular habit. And I’m just gonna say it: Not all products need a streak system. Should you really force consistency just because you want daily active users? The answer may very well be “no”.</itunes:summary></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9165069509664255576.post-2845286163604628923</guid><pubDate>Wed, 11 Mar 2026 06:35:00 +0000</pubDate><atom:updated>2026-03-10T23:35:59.945-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">CSS</category><category domain="http://www.blogger.com/atom/ns#">HTML</category><category domain="http://www.blogger.com/atom/ns#">Tools</category><title>Getting Started With The Popover API</title><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="c-garfield-summary"&gt;&lt;section aria-label="Quick summary" class="article__summary"&gt;What
 happens if you rebuild a single tooltip using the browser’s native 
model without the aid of a library? The Popover API turns tooltips from 
something you simulate into something the browser actually understands. 
Opening and closing, keyboard interaction, Escape handling, and much of 
the accessibility now come from the platform itself, not from ad-hoc 
JavaScript.&lt;/section&gt;&lt;/div&gt;&lt;p&gt;Tooltips feel like the smallest UI problem
 you can have. They’re tiny and usually hidden. When someone asks how to
 build one, the traditional answer almost always comes back using some 
JavaScript library. And for a long time, that was the sensible advice.&lt;/p&gt;&lt;p&gt;I followed it, too.&lt;/p&gt;&lt;p&gt;On
 the surface, a tooltip is simple. Hover or focus on an element, show a 
little box with some text, then hide it when the user moves away. But 
once you ship one to real users, the edges start to show. Keyboard users
 &lt;code&gt;Tab&lt;/code&gt; into the trigger, but never see the tooltip. Screen 
readers announce it twice, or not at all. The tooltip flickers when you 
move the mouse too quickly. It overlaps content on smaller screens. 
Pressing &lt;code&gt;Esc&lt;/code&gt; does not close it. Focus gets lost.&lt;/p&gt;&lt;p&gt;Over
 time, my tooltip code grew into something I didn’t really want to own 
anymore. Event listeners piled up. Hover and focus had to be handled 
separately. Outside clicks needed special cases. ARIA attributes had to 
be kept in sync by hand. Every small fix added another layer of logic.&lt;/p&gt;&lt;p&gt;Libraries
 helped, but they were also more like black boxes I worked around 
instead of fully understanding what was happening behind the scenes.&lt;/p&gt;&lt;p&gt;That was what pushed me to look at the newer &lt;a href="https://html.spec.whatwg.org/multipage/popover.html#the-popover-attribute"&gt;Popover API&lt;/a&gt;. I wanted to see what would happen if I rebuilt a single tooltip using the browser’s native model without the aid of a library.&lt;/p&gt;&lt;p&gt;As
 we start, it’s worth noting that, as with any new feature, there are 
some things with it that are still being ironed out. That said, it 
currently enjoys great browser support, although there are several 
pieces to the overall API that are in flux. It’s worth keeping an eye on
 &lt;a href="https://caniuse.com/?search=popover+api"&gt;Caniuse&lt;/a&gt; in the meantime.&lt;/p&gt;&lt;h2 id="the-old-tooltip"&gt;The “Old” Tooltip&lt;/h2&gt;&lt;p&gt;Before
 the Popover API, using a tooltip library was not a shortcut. It was the
 default. Browsers didn’t have a native concept of a tooltip that worked
 across mouse, keyboard, and assistive technology. If you cared about 
correctness, your only option was to use a library, and that is exactly 
what I did.&lt;/p&gt;&lt;p&gt;At a high level, the pattern was always the same: a 
trigger element, a hidden tooltip element, and JavaScript to coordinate 
the two.&lt;/p&gt;&lt;div class="break-out"&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-html"&gt;&lt;code class=" language-html"&gt;&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class="token attr-name"&gt;class&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;info&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;?&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class="token attr-name"&gt;class&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;tooltip&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="token attr-name"&gt;role&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;tooltip&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Helpful text&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/getting-started-popover-api/1-popover-api.png"&gt;&lt;img alt="The old approach with ~60 lines of JavaScript with five event listeners vs the new approach is about 10 lines of declarative HTML with zero event listeners." height="257" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/getting-started-popover-api/1-popover-api.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;The
 old approach required ~60 lines of JavaScript with five event listeners
 and manual state management. The new approach is about 10 lines of 
declarative HTML with zero event listeners.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;The
 library handled the wiring that allowed the element to show on hover or
 focus, hide on blur or mouse leave, and reposition/resize on scroll.&lt;/p&gt;&lt;figure class="video-embed-container break-out"&gt;&lt;div class="video-embed-container--wrapper"&gt;&lt;/div&gt;&lt;/figure&gt;&lt;p&gt;None of it was accidental. It was merely compensating for gaps in web platform features.&lt;/p&gt;&lt;h2 id="why-i-used-a-library"&gt;Why I Used A Library&lt;/h2&gt;&lt;p&gt;The
 library was doing real work for me: positioning, flipping at viewport 
edges, event coordination across input types, and scroll awareness 
inside complex layouts. Positioning alone justified the dependency. 
Handling scroll containers, transforms, and responsive layouts correctly
 is not simple.&lt;/p&gt;&lt;p&gt;The real issues showed up in &lt;strong&gt;accessibility behavior&lt;/strong&gt;, not visuals. The tooltip worked, but not all the time. Here’s where things started to fray at the seams:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Tooltips sometimes appeared late or not at all.&lt;/li&gt;&lt;li&gt;Tabbing quickly could skip them entirely.&lt;/li&gt;&lt;li&gt;Escape dismissal was not reliable.&lt;/li&gt;&lt;/ul&gt;&lt;figure class="video-embed-container break-out"&gt;&lt;div class="video-embed-container--wrapper"&gt;&lt;/div&gt;&lt;figcaption&gt;Keyboard
 navigation with the old implementation: Tabbing quickly causes tooltips
 to be skipped entirely, and Escape dismissal is unreliable.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;I also ran into issues trying to sync hover and focus behavior:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Mouse users expect immediacy.&lt;/li&gt;&lt;li&gt;Keyboard users expect predictability.&lt;/li&gt;&lt;li&gt;Supporting both meant delays and edge cases.&lt;/li&gt;&lt;/ul&gt;&lt;figure class="video-embed-container break-out"&gt;&lt;div class="video-embed-container--wrapper"&gt;&lt;/div&gt;&lt;figcaption&gt;This timing mismatch creates an inconsistent experience across input methods.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Not to mention, there were issues with &lt;strong&gt;assistive technologies&lt;/strong&gt;, particularly screen readers: Sometimes the tooltip was announced, sometimes it wasn’t, and sometimes it was announced twice.&lt;/p&gt;&lt;figure class="video-embed-container break-out"&gt;&lt;div class="video-embed-container--wrapper"&gt;&lt;/div&gt;&lt;figcaption&gt;Screen reader behavior with custom tooltips.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Keeping
 ARIA attributes in sync required manual updates. Miss one state change,
 and the tooltip became confusing or invisible to the accessibility 
tree.&lt;/p&gt;&lt;h2 id="this-was-not-bad-code"&gt;This Was Not Bad Code&lt;/h2&gt;&lt;p&gt;The implementation was tested, the library was solid, and the behavior was reasonable given the tools available at the time.&lt;/p&gt;&lt;blockquote&gt;The core problem was not the code. It was that the web platform lacked proper affordances.&lt;/blockquote&gt;&lt;p&gt;For
 example, the browser has no real way of knowing that the element was a 
tooltip. Everything was built from conventions: generic elements, event 
listeners, manually-managed ARIA, and custom dismissal logic.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/getting-started-popover-api/2-before-after-popover-api.png"&gt;&lt;img alt="Event flow: before and after Popover API." height="436" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/getting-started-popover-api/2-before-after-popover-api.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Before:
 A tangled web of event listeners, state management, and manual ARIA 
updates. After: The browser understands the relationship declaratively.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Over
 time, the tooltip could become fragile. Small changes carried risk. 
Minor fixes caused regressions. Worse, adding new tooltips inherited the
 same complexity. Things technically worked, but never felt settled or 
complete.&lt;/p&gt;&lt;p&gt;That was the state of things when I decided to rebuild the tooltip using the browser’s native &lt;a href="https://html.spec.whatwg.org/multipage/popover.html#the-popover-attribute"&gt;Popover API&lt;/a&gt;.&lt;/p&gt;&lt;h2 id="the-moment-i-tried-the-popover-api"&gt;The Moment I Tried The Popover API&lt;/h2&gt;&lt;p&gt;I
 didn’t switch to using the Popover API because I wanted to experiment 
with something new. I switched because I was tired of maintaining 
tooltip behavior that I believed the browser should have already 
understood.&lt;/p&gt;&lt;p&gt;I was skeptical at first. Most new web APIs promise 
simplicity, but still require glue, edge-case handling, or fallback 
logic that quietly recreates the same complexity that you were trying to
 escape.&lt;/p&gt;&lt;p&gt;So, I tried the Popover API in the smallest way possible. Here’s what that looked like:&lt;/p&gt;&lt;div class="break-out"&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-html"&gt;&lt;code class=" language-html"&gt;&lt;span class="token comment"&gt;&amp;lt;!-- popovertarget creates the connection to id="tip-1" --&amp;gt;&lt;/span&gt;
&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class="token attr-name"&gt;popovertarget&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;tip-1&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;?&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class="token comment"&gt;&amp;lt;!-- popover="manual": browser manages this as a popover --&amp;gt;&lt;/span&gt;
&lt;span class="token comment"&gt;&amp;lt;!-- role="tooltip": tells assistive technology what this is --&amp;gt;&lt;/span&gt;
&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class="token attr-name"&gt;id&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;tip-1&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="token attr-name"&gt;popover&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;manual&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="token attr-name"&gt;role&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;tooltip&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  This button triggers a helpful tip.
&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;figure class="video-embed-container break-out"&gt;&lt;div class="video-embed-container--wrapper"&gt;&lt;/div&gt;&lt;figcaption&gt;The complete tooltip implementation using the Popover API&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;No
 event listeners. No state tracking. No ARIA updates handled in 
JavaScript. I focused the button, and the tooltip appeared. I pressed 
the &lt;code&gt;Esc&lt;/code&gt; key, and it disappeared.&lt;/p&gt;&lt;h2 id="what-immediately-stood-out"&gt;What Immediately Stood Out&lt;/h2&gt;&lt;p&gt;A few things became obvious within minutes:&lt;/p&gt;&lt;h3 id="i-didn-t-write-any-javascript-to-open-or-close-it"&gt;I Didn’t Write Any JavaScript To Open Or Close It&amp;nbsp;&lt;/h3&gt;&lt;p&gt;The browser handled invocation entirely through HTML. The relationship between trigger and tooltip was explicit.&lt;/p&gt;&lt;h3 id="the-esc-key-just-worked"&gt;The &lt;code&gt;Esc&lt;/code&gt; Key Just Worked&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/03/getting-started-popover-api/#the-esc-key-just-worked"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;I didn’t add a key listener. Pressing the &lt;code&gt;Esc&lt;/code&gt; key properly closed the tooltip because the browser understands that popovers should be dismissible.&lt;/p&gt;&lt;h3 id="aria-state-automatically-synced"&gt;ARIA State Automatically Synced&lt;/h3&gt;&lt;p&gt;The &lt;code&gt;aria-expanded&lt;/code&gt;
 attribute updated on its own when the popover opened and closed. There 
was no need for manual bookkeeping and no risk of stale state.&lt;/p&gt;&lt;figure class="video-embed-container break-out"&gt;&lt;div class="video-embed-container--wrapper"&gt;&lt;/div&gt;&lt;figcaption&gt;The browser’s DevTools showing &lt;code&gt;aria-expanded&lt;/code&gt; automatically updating from &lt;code&gt;false&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt; as the popover opens.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;This was the moment that the Popover API stopped feeling like a convenience and more like true bona fide platform behavior.&lt;/p&gt;&lt;p&gt;What surprised me most was not the reduced code but the &lt;strong&gt;change in responsibility&lt;/strong&gt;.
 Before, the tooltip existed because my JavaScript said so. Now, it 
exists because the browser understands what it is supposed to be and its
 role in the markup. The tooltip is no longer simply a box positioned 
near a button anymore, but participating in the browser’s focus model, 
the accessibility tree, and native dismissal rules.&lt;/p&gt;&lt;p&gt;That’s when my migration to the Popover API started.&lt;/p&gt;&lt;h3 id="understanding-invoker-commands"&gt;Understanding Invoker Commands&lt;/h3&gt;&lt;p&gt;The &lt;code&gt;popovertarget&lt;/code&gt; and &lt;code&gt;popovertargetaction&lt;/code&gt; attributes are part of HTML’s invoker commands, a declarative way to control interactive elements without JavaScript.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;popovertarget="id"&lt;/code&gt;: Connects the button to a popover element.&lt;/li&gt;&lt;li&gt;&lt;code&gt;popovertargetaction&lt;/code&gt;: Specifies what should happen:&lt;ul&gt;&lt;li&gt;&lt;code&gt;show&lt;/code&gt;: Only opens the popover.&lt;/li&gt;&lt;li&gt;&lt;code&gt;hide&lt;/code&gt;: Only closes the popover.&lt;/li&gt;&lt;li&gt;&lt;code&gt;toggle&lt;/code&gt;(default): Opens the popover if closed and closes it if it’s open.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This means you can have multiple triggers for the same tooltip:&lt;/p&gt;&lt;div class="break-out"&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-html"&gt;&lt;code class=" language-html"&gt;&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class="token attr-name"&gt;popovertarget&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;help-tip&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="token attr-name"&gt;popovertargetaction&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;show&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  Show Help
&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class="token attr-name"&gt;popovertarget&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;help-tip&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="token attr-name"&gt;popovertargetaction&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;hide&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  Close Help
&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class="token attr-name"&gt;id&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;help-tip&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="token attr-name"&gt;popover&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;manual&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="token attr-name"&gt;role&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;tooltip&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  Help content
&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The browser coordinates everything with no JavaScript needed for the basic interaction.&lt;/p&gt;&lt;h2 id="free-accessibility-wins"&gt;Free Accessibility Wins&lt;/h2&gt;&lt;p&gt;This
 is the part that made me switch completely. I expected the Popover API 
to reduce code. I didn’t expect it to remove entire categories of 
accessibility bugs I had been chasing for years. Before the migration, 
my tooltip system looked fine at the very least. Keyboard support 
existed, ARIA attributes were present, and screen readers usually 
behaved accordingly. But “usually” did a lot of heavy lifting.&lt;/p&gt;&lt;p&gt;Once I swapped in native popovers, three things changed immediately.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/getting-started-popover-api/3-accessibility-tree-comparison.png"&gt;&lt;img alt="Accessibility tree comparison: Custom vs Native Popover API." height="436" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/getting-started-popover-api/3-accessibility-tree-comparison.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Custom
 implementations use fragile JavaScript to connect triggers and 
tooltips. The Popover API creates a native browser connection that 
assistive technology can trust.&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="1-the-keyboard-just-works"&gt;1. The Keyboard “Just Works”&lt;/h3&gt;&lt;p&gt;Keyboard support depended on multiple layers lining up correctly: focus had to trigger the tooltip, blur had to hide it, &lt;code&gt;Esc&lt;/code&gt;
 had to be wired manually, and timing mattered. If you missed one edge 
case, the tooltip would either stay open too long or disappear before it
 could be read.&lt;/p&gt;&lt;p&gt;With the &lt;code&gt;popover&lt;/code&gt; attribute set to &lt;code&gt;auto&lt;/code&gt; or &lt;code&gt;manual&lt;/code&gt;, the browser takes over the basics: &lt;code&gt;Tab&lt;/code&gt; and &lt;code&gt;Shift&lt;/code&gt;+&lt;code&gt;Tab&lt;/code&gt; behave normally, &lt;code&gt;Esc&lt;/code&gt; closes the tooltip every time, and no extra listeners are required.&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-html"&gt;&lt;code class=" language-html"&gt;&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class="token attr-name"&gt;popover&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;manual&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  Helpful explanation
&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;What disappeared from my codebase were global keydown handlers, &lt;code&gt;Esc&lt;/code&gt;-specific
 cleanup logic, and state checks during keyboard navigation. The 
keyboard experience stopped being something I had to maintain, and it 
became a browser guarantee.&lt;/p&gt;&lt;h3 id="2-screenreader-predictability"&gt;2. Screenreader Predictability&lt;/h3&gt;&lt;p&gt;This
 was the biggest improvement. Even with careful ARIA work, the behavior 
varied, as I outlined earlier. Every small change felt risky. Using a 
popover with a proper role looks and feels a lot more stable and 
predictable as far as what’s going to happen:&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-html"&gt;&lt;code class=" language-html"&gt;&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class="token attr-name"&gt;popover&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;manual&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="token attr-name"&gt;role&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;tooltip&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  Helpful explanation
&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;And here’s another win: After the switch, &lt;a href="https://www.smashingmagazine.com/2024/11/why-optimizing-lighthouse-score-not-enough-fast-website/"&gt;Lighthouse&lt;/a&gt;
 stopped flagging incorrect ARIA state warnings for the interaction, 
largely because there are no longer custom ARIA states for me to 
accidentally get wrong.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/getting-started-popover-api/4-manual-aria-popover-api.png"&gt;&lt;img alt="ARIA state warnings before migration, and 100% audit score after switching to the Popover API." height="436" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/getting-started-popover-api/4-manual-aria-popover-api.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Before
 the migration, Lighthouse flagged accessibility warnings about 
incorrect ARIA state management. After switching to the Popover API, the
 audit score improved.&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="3-focus-management"&gt;3. Focus Management&lt;/h3&gt;&lt;p&gt;Focus
 used to be fragile. Before, I had rules like: let focus trigger show 
tooltip, move focus into tooltip and don’t close, blur trigger when it’s
 too close, and close tooltip and restore focus manually. This worked 
until it didn’t.&lt;/p&gt;&lt;p&gt;With the Popover API, the browser enforces a 
simpler model where focus can more naturally move into the popover. 
Closing the popover returns focus to the trigger, and there are no 
invisible focus traps or lost focus moments. And I didn’t add focus 
restoration code; I removed it.&lt;/p&gt;&lt;figure class="video-embed-container break-out"&gt;&lt;div class="video-embed-container--wrapper"&gt;&lt;/div&gt;&lt;figcaption&gt;Tab to focus the trigger, the tooltip appears, press &lt;code&gt;Escape&lt;/code&gt; to dismiss, and focus automatically returns to the trigger.&lt;/figcaption&gt;&lt;/figure&gt;&lt;h2 id="where-the-popover-api-maybe-still-isn-t-enough"&gt;Where The Popover API Maybe Still Isn’t Enough&amp;nbsp;&lt;/h2&gt;&lt;p&gt;As
 much as the Popover API has simplified my code and improved semantics, 
it still has not completely eliminated JavaScript. That’s not totally a 
bad thing because what’s changed is that JavaScript is no longer a key 
dependency. I am no longer compensating for missing platform behavior 
anymore. I am much more focused on &lt;em&gt;intent&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;Here are a few places where I could see the API continue to improve.&lt;/p&gt;&lt;h3 id="tooltip-timing-still-matters"&gt;Tooltip Timing Still Matters&amp;nbsp;&lt;/h3&gt;&lt;p&gt;Native
 popovers open and close immediately. That is usually the expected 
behavior, but not always ideal for what we consider to be tooltips. In 
those cases, instant dismissal can feel unstable when you move your 
mouse a few pixels too quickly or accidentally brush past the trigger — 
the tooltip will flash, then disappear, which can be jarring.&lt;/p&gt;&lt;p&gt;I 
want to be able to control that timing and apply delays between hover or
 focus and opening the tooltip. So I still add small delays. What 
changed was how much of the interaction logic I actually needed to own. 
Before, even basic open and close behavior required JavaScript. With the
 Popover API, and especially with HTML invoker commands, that 
responsibility shifts back to the browser.&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-html"&gt;&lt;code class=" language-html"&gt;&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt;
  &lt;span class="token attr-name"&gt;popovertarget&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;help-tip&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt;
  &lt;span class="token attr-name"&gt;popovertargetaction&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;show&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  ?
&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class="token attr-name"&gt;id&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;help-tip&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="token attr-name"&gt;popover&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;manual&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt; &lt;span class="token attr-name"&gt;role&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;tooltip&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  This button triggers a helpful tip.
&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;At
 this point, the browser handles invocation, dismissal, and ARIA state 
on its own. There’s no JavaScript involved just to make the tooltip 
appear or disappear.&lt;/p&gt;&lt;p&gt;JavaScript only comes back in when I want 
intentional behavior. In this case, a short delay before hiding the 
tooltip, and cancelling if the pointer moves into it. This isn’t about 
accessibility fixes. It’s about human behavior.&lt;/p&gt;&lt;p&gt;It’s worth noting that CSS is beginning to explore this space as well. The emerging interest/invoker work introduces &lt;a href="https://css-tricks.com/a-first-look-at-the-interest-invoker-api-for-hover-triggered-popovers/#aa-interest-delay-and-the-css-of-it-all"&gt;ways to express entry and exit delays directly in CSS&lt;/a&gt;,
 which could remove this small bit of JavaScript entirely. For now, I 
still handle it imperatively, but the direction of the platform is 
clear.&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token keyword"&gt;let&lt;/span&gt; hideTimeout&lt;span class="token punctuation"&gt;;&lt;/span&gt;

&lt;span class="token keyword"&gt;const&lt;/span&gt; &lt;span class="token function-variable function"&gt;show&lt;/span&gt; &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token operator"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
  &lt;span class="token function"&gt;clearTimeout&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;hideTimeout&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
  tooltip&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;showPopover&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

&lt;span class="token keyword"&gt;const&lt;/span&gt; &lt;span class="token function-variable function"&gt;hide&lt;/span&gt; &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token operator"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
  hideTimeout &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;setTimeout&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token operator"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
    tooltip&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;hidePopover&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
  &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token number"&gt;200&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The
 difference is that this logic stays small and local. It no longer 
defines how the tooltip works. It simply refines how it feels.&lt;/p&gt;&lt;h3 id="hover-intent-with-invoker-commands"&gt;Hover Intent With Invoker Commands&lt;/h3&gt;&lt;p&gt;The
 browser does not know why someone hovers over an element or focuses on 
it. Was it intentional, or was the pointer just passing through? That 
part has always required some judgment.&lt;/p&gt;&lt;p&gt;What changed is where that
 logic lives. With invoker commands handling the core open and close 
behavior, JavaScript no longer owns the interaction model. It only adds 
intent on top of it.&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-html"&gt;&lt;code class=" language-html"&gt;&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt;
 &lt;span class="token attr-name"&gt;popovertarget&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;help-tip&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt;
 &lt;span class="token attr-name"&gt;popovertargetaction&lt;/span&gt;&lt;span class="token attr-value"&gt;&lt;span class="token punctuation attr-equals"&gt;=&lt;/span&gt;&lt;span class="token punctuation"&gt;"&lt;/span&gt;show&lt;span class="token punctuation"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  ?
&lt;span class="token tag"&gt;&lt;span class="token tag"&gt;&lt;span class="token punctuation"&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class="token punctuation"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The
 platform manages invocation, dismissal, and ARIA state. JavaScript is 
only needed when we want behavior that the browser cannot infer, such as
 a short delay before hiding or cancelling dismissal if the pointer 
moves into the tooltip.&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;&lt;span class="token keyword"&gt;let&lt;/span&gt; hideTimeout&lt;span class="token punctuation"&gt;;&lt;/span&gt;

&lt;span class="token keyword"&gt;const&lt;/span&gt; &lt;span class="token function-variable function"&gt;show&lt;/span&gt; &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token operator"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
&lt;span class="token function"&gt;clearTimeout&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;hideTimeout&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
  tooltip&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;showPopover&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;

&lt;span class="token keyword"&gt;const&lt;/span&gt; &lt;span class="token function-variable function"&gt;hide&lt;/span&gt; &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token operator"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
  hideTimeout &lt;span class="token operator"&gt;=&lt;/span&gt; &lt;span class="token function"&gt;setTimeout&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt; &lt;span class="token operator"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="token punctuation"&gt;{&lt;/span&gt;
    tooltip&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;hidePopover&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
  &lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;,&lt;/span&gt; &lt;span class="token number"&gt;200&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;span class="token punctuation"&gt;}&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;And
 again, CSS is beginning to explore this space with new interaction 
primitives, which may reduce the need for custom hover intent code even 
further.&lt;/p&gt;&lt;h3 id="manual-popovers-and-focus"&gt;Manual Popovers And Focus&amp;nbsp;&lt;/h3&gt;&lt;p&gt;For &lt;code&gt;popover="manual"&lt;/code&gt;,
 the browser does not restore focus automatically the way it can for 
auto popovers. That responsibility remains explicit. When a tooltip 
opens on focus and closes on blur, I return focus deliberately to the 
trigger:&lt;/p&gt;&lt;div class="code-toolbar"&gt;&lt;pre class=" language-javascript"&gt;&lt;code class=" language-javascript"&gt;tooltip&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;hidePopover&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
trigger&lt;span class="token punctuation"&gt;.&lt;/span&gt;&lt;span class="token function"&gt;focus&lt;/span&gt;&lt;span class="token punctuation"&gt;(&lt;/span&gt;&lt;span class="token punctuation"&gt;)&lt;/span&gt;&lt;span class="token punctuation"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="toolbar"&gt;&lt;div class="toolbar-item"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This is not a limitation but a clear boundary between platform behavior and person intent.&lt;/p&gt;&lt;h3 id="the-honest-take"&gt;The Honest Take&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/03/getting-started-popover-api/#the-honest-take"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The
 Popover API does not magically solve tooltips. It stopped forcing me to
 rebuild fragile infrastructure. I still write JavaScript and think 
about edge cases, but now I am solving product problems instead of 
recreating UI primitives the browser should already understand.&lt;/p&gt;&lt;h2 id="when-i-would-still-reach-for-a-tooltip-library"&gt;When I would Still Reach For A Tooltip Library&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/03/getting-started-popover-api/#when-i-would-still-reach-for-a-tooltip-library"&gt;#&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Even
 after migrating my tooltips to the Popover API, I did not walk away 
thinking libraries were old and obsolete. They have earned their place, 
just in more specific situations.&lt;/p&gt;&lt;h3 id="1-large-or-mature-design-systems"&gt;1. Large Or Mature Design Systems&lt;/h3&gt;&lt;p&gt;If
 you are maintaining a large design system used across multiple teams, a
 tooltip library can still make sense because centralized behavior, 
documented patterns, and consistent defaults across products. In those 
environments, changing the underlying interaction model is not just a 
technical decision; it is an organizational one. A well-maintained 
library gives teams guardrails, especially when not everyone is deeply 
familiar with accessibility nuances.&lt;/p&gt;&lt;h3 id="2-complex-positioning-requirements"&gt;2. Complex Positioning Requirements&lt;/h3&gt;&lt;p&gt;For
 most tooltips, native positioning is enough, but if you need collision 
detection across nested scroll containers, custom flipping logic, or 
fine-grained control over offsets and boundaries, libraries like &lt;a href="https://floating-ui.com"&gt;Floating UI&lt;/a&gt; still shine. They are optimized for geometry problems that the platform is only beginning to address.&lt;/p&gt;&lt;p&gt;It is also worth mentioning &lt;a href="https://css-tricks.com/css-anchor-positioning-guide/"&gt;CSS anchor positioning&lt;/a&gt;,
 which is starting to cover many of the problems that tooltip libraries 
historically solved. Anchors allow a popover to be positioned relative 
to a trigger using pure CSS, including viewport-aware placement and edge
 flipping. This moves even more responsibility back to the platform 
instead of JavaScript.&lt;/p&gt;&lt;p&gt;That said, anchor positioning is still new and &lt;a href="https://css-tricks.com/css-anchor-positioning-guide/#aa-known-bugs"&gt;there are known issues,&lt;/a&gt; although the good news is that they are part of Interop, meaning &lt;a href="https://webstatus.dev/features/popover?q=baseline_date%3A2025-01-01..2025-12-31&amp;amp;start=25"&gt;we can look forward to full and consistent browser support&lt;/a&gt;.
 For teams that need consistent cross-browser behavior today, libraries 
remain the practical choice. The direction is clear that the platform is
 steadily absorbing work that once required dedicated positioning 
engines.&lt;/p&gt;&lt;h3 id="3-teams-without-accessibility-experience"&gt;3. Teams Without Accessibility Experience&lt;/h3&gt;&lt;p&gt;This
 one matters. If a team does not have strong accessibility knowledge, a 
good library can act as a safety net, though it will not guarantee 
perfect accessibility. It can, however, prevent the many common 
mistakes. The Popover API gives you better defaults, but it still 
assumes you know when to add roles, labels, focus management, and 
testing. Without that understanding, even native tools can be misused.&lt;/p&gt;&lt;h2 id="the-decision-line"&gt;The Decision Line&amp;nbsp;&lt;/h2&gt;&lt;p&gt;For me, the choice now looks like this:&lt;/p&gt;&lt;blockquote class="pull-quote"&gt;&lt;p&gt;&lt;a aria-label="Share on Twitter" class="pull-quote__link" href="https://twitter.com/share?text=%0aUse%20the%20Popover%20API%20for%20simplicity,%20clarity,%20and%20platform-aligned%20behavior.%20Use%20a%20library%20when%20scale,%20customization,%20or%20constraints%20demand%20it.%20It%e2%80%99s%20not%20about%20purity.%20It%e2%80%99s%20about%20choosing%20the%20right%20level%20of%20abstraction%20for%20the%20problem%20in%20front%20of%20you.%0a&amp;amp;url=https://smashingmagazine.com%2f2026%2f03%2fgetting-started-popover-api%2f"&gt;Use
 the Popover API for simplicity, clarity, and platform-aligned behavior.
 Use a library when scale, customization, or constraints demand it. It’s
 not about purity. It’s about choosing the right level of abstraction 
for the problem in front of you.&lt;/a&gt;&lt;/p&gt;&lt;div class="pull-quote__quotation"&gt;&lt;div class="pull-quote__bg"&gt;&lt;span class="pull-quote__symbol"&gt;“&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;p&gt;And sometimes the right tool is still a library — just no longer by default.&lt;/p&gt;&lt;figure&gt;&lt;a href="https://files.smashing.media/articles/getting-started-popover-api/5-popover-api-browser-support.png"&gt;&lt;img alt="" height="800" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/getting-started-popover-api/5-popover-api-browser-support.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;&lt;br /&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;h2 id="conclusion"&gt;Conc&lt;/h2&gt;&lt;p&gt;The
 Popover API means that tooltips are no longer something you simulate. 
They’re something the browser understands. Opening, closing, keyboard 
behavior, Escape handling, and a big chunk of accessibility now come 
from the platform itself, not from ad-hoc JavaScript.&lt;/p&gt;&lt;p&gt;That does 
not mean tooltip libraries are obsolete because they still make sense 
for complex design systems, heavy customization, or legacy constraints, 
but &lt;strong&gt;the default has shifted&lt;/strong&gt;. For the first time, the 
simplest tooltip can also be the most correct one. If you are curious, 
try this experiment: Simply replace just one tooltip in your product 
with the Popover API, do not rewrite everything, do not migrate a whole 
system, and just pick one and see what disappears from your code.&lt;/p&gt;&lt;p&gt;When
 the platform gives you a better primitive, the win is not just fewer 
lines of JavaScript, but it is fewer things you have to worry about at 
all.&lt;/p&gt;&lt;p&gt;Check out the full source code in &lt;a href="https://github.com/BboyGT/PopOver-API"&gt;my GitHub repo&lt;/a&gt;.&lt;/p&gt;&lt;h3 id="further-reading"&gt;Further Reading&lt;/h3&gt;&lt;p&gt;For deeper dives into popovers and related APIs:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;“&lt;a href="https://css-tricks.com/poppin-in/"&gt;Poppin’ In&lt;/a&gt;”, Geoff Graham&lt;/li&gt;&lt;li&gt;“&lt;a href="https://css-tricks.com/clarifying-the-relationship-between-popovers-and-dialogs/"&gt;Clarifying the Relationship Between Popovers and Dialogs&lt;/a&gt;”, Zell Liew&lt;/li&gt;&lt;li&gt;“&lt;a href="https://una.im/popover-hint/"&gt;What is popover=hint?&lt;/a&gt;”, Una Kravets&lt;/li&gt;&lt;li&gt;“&lt;a href="https://css-tricks.com/invoker-commands-additional-ways-to-work-with-dialog-popover-and-more/"&gt;Invoker Commands&lt;/a&gt;”, Daniel Schwarz&lt;/li&gt;&lt;li&gt;“&lt;a href="https://css-tricks.com/creating-an-auto-closing-notification-with-an-html-popover/"&gt;Creating an Auto-Closing Notification with an HTML Popover&lt;/a&gt;”, Preethi&lt;/li&gt;&lt;li&gt;&lt;a href="https://open-ui.org/components/popover.research.explainer/"&gt;Open UI Popover API Explainer&lt;/a&gt;&lt;/li&gt;&lt;li&gt;“&lt;a href="https://css-tricks.com/popover-the-balloons/"&gt;Pop(over) the Balloons&lt;/a&gt;”, John Rhea&lt;/li&gt;&lt;li&gt;“&lt;a href="https://css-tricks.com/css-anchor-positioning-guide/"&gt;CSS Anchor Positioning&lt;/a&gt;”, Juan Diego Rodríguez&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;MDN also &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Popover_API"&gt;offers comprehensive technical documentation&lt;/a&gt; for the Popover API.&lt;/p&gt;</description><link>http://honeyvig.blogspot.com/2026/03/getting-started-with-popover-api.html</link><author>noreply@blogger.com (H)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-9165069509664255576.post-4743564950652050552</guid><pubDate>Tue, 10 Mar 2026 10:26:00 +0000</pubDate><atom:updated>2026-03-10T03:26:00.121-07:00</atom:updated><title>Building Digital Trust: An Empathy-Centred UX Framework For Mental Health Apps</title><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="c-garfield-summary"&gt;&lt;section aria-label="Quick summary" class="article__summary"&gt;Designing
 for mental health means designing for vulnerability. Empathy-Centred UX
 becomes not a “nice to have” but a fundamental design requirement. 
Here’s a practical framework for building trust-first mental health 
products.&lt;/section&gt;&lt;/div&gt;&lt;p&gt;Imagine a user opening a mental health app 
while feeling overwhelmed with anxiety. The very first thing they 
encounter is a screen with a bright, clashing colour scheme, followed by
 a notification shaming them for breaking a 5-day “mindfulness streak,” 
and a paywall blocking the meditation they desperately need at that very
 moment. This experience isn’t just poor design; it can be actively 
harmful. It betrays the user’s vulnerability and erodes the very trust 
the app aims to build.&lt;/p&gt;&lt;p&gt;When designing for mental health, this 
becomes both a critical challenge and a valuable opportunity. Unlike a 
utility or entertainment app, the user’s emotional state cannot be 
treated as a secondary context. It &lt;em&gt;is&lt;/em&gt; the environment your product operates in.&lt;/p&gt;&lt;p&gt;&lt;a href="https://www.who.int/news/item/02-09-2025-over-a-billion-people-living-with-mental-health-conditions-services-require-urgent-scale-up"&gt;With over a billion people&lt;/a&gt;
 living with mental health conditions and persistent gaps in access to 
care, safe and evidence-aligned digital support is increasingly 
relevant. The margin for error is negligible. &lt;strong&gt;Empathy-Centred UX&lt;/strong&gt;
 becomes not a “nice to have” but a fundamental design requirement. It 
is an approach that moves beyond mere functionality to deeply 
understand, respect, and design for the user’s intimate emotional and 
psychological needs.&lt;/p&gt;&lt;p&gt;But how do we translate this principle into 
practice? How do we build digital products that are not just useful, but
 truly trustworthy?&lt;/p&gt;&lt;p&gt;Throughout my career as a product designer, 
I’ve found that trust is built by consistently meeting the user’s 
emotional needs at every stage of their journey. In this article, I will
 translate these insights into a &lt;strong&gt;hands-on empathy-centred UX framework&lt;/strong&gt;.
 We will move beyond theory to dive deeper into applicable tools that 
help create experiences that are both humane and highly effective.&lt;/p&gt;&lt;p&gt;In this article, I’ll share a practical, repeatable framework built around three pillars:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Onboarding&lt;/strong&gt; as a supportive first conversation.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Interface design&lt;/strong&gt; for a brain in distress.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Retention patterns&lt;/strong&gt; that deepen trust rather than pressure users.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Together,
 these pillars offer a grounded way to design mental health experiences 
that prioritise trust, emotional safety, and real user needs at every 
step.&lt;/p&gt;&lt;h2 id="the-onboarding-conversation-from-a-checklist-to-a-trusted-companion"&gt;The Onboarding Conversation: From a Checklist to a Trusted Companion&lt;/h2&gt;&lt;p&gt;Onboarding
 is “a first date” between a user and the app — and the first impression
 carries immense stakes, determining whether the user decides to 
continue engaging with the app. In mental health tech, with up to &lt;a href="https://link.springer.com/article/10.1186/s13690-024-01362-w"&gt;20,000 mental-health-related apps&lt;/a&gt;
 on the market, product designers face a dilemma of how to integrate 
onboarding’s primary goals without making the design feel too clinical 
or dismissive for a user seeking help.&lt;/p&gt;&lt;blockquote&gt;&lt;strong&gt;The Empathy Tool&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;In my experience, I have found it essential &lt;strong&gt;to design onboarding as the first supportive conversation.&lt;/strong&gt;
 The goal is to help the user feel seen and understood by delivering a 
small dose of relief quickly, not just overload them with data and the 
app’s features.&lt;/blockquote&gt;&lt;h3 id="case-study-a-teenager-s-parenting-journey"&gt;Case Study: A Teenager’s Parenting Journey&lt;/h3&gt;&lt;p&gt;At &lt;a href="https://play.google.com/store/apps/details?id=world.dobra.teeni"&gt;&lt;em&gt;Teeni&lt;/em&gt;&lt;/a&gt;,
 an app for parents of teenagers, onboarding requires an approach that 
solves two problems: (1) acknowledge the emotional load of parenting 
teens and show how the app can share that load; (2) collect just enough 
information to make the first feed relevant.&lt;/p&gt;&lt;h4 id="recognition-and-relief"&gt;Recognition And Relief&lt;/h4&gt;&lt;p&gt;Interviews surfaced a recurring feeling among parents: &lt;em&gt;“I’m a bad parent, I’ve failed at everything.”&lt;/em&gt;
 My design idea was to provide early relief and normalisation through a 
city-at-night metaphor with lit windows: directly after the welcome 
page, a user engages with three brief, animated and optional stories 
based on frequent challenges of teenage parenting, in which they can 
recognise themselves (e.g., a story of a mother learning to manage her 
reaction to her teen rolling their eyes). This narrative approach 
reassures parents that they are not alone in their struggles, 
normalising and helping them cope with &lt;a href="https://www.npr.org/sections/health-shots/2014/07/16/326953698/want-more-stress-in-your-life-try-parenting-a-teenager#"&gt;stress&lt;/a&gt; and other &lt;a href="https://www.nhs.uk/mental-health/children-and-young-adults/advice-for-parents/cope-with-your-teenager/"&gt;complex emotions&lt;/a&gt; from the very beginning.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/building-empathy-centred-ux-framework-mental-health-apps/1-teeni-onboarding.png"&gt;&lt;img alt="Teeni onboarding" height="450" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/building-empathy-centred-ux-framework-mental-health-apps/1-teeni-onboarding.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Teeni
 onboarding is designed as support first: it acknowledges the emotional 
load of parenting teens, then uses optional peer stories to help parents
 feel less alone.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;
 Early usability sessions indicated strong emotional resonance, but 
post-launch analytics showed that the optionality of the storytelling 
must be explicit. The goal is to balance the storytelling to avoid 
overwhelming the distressed parent, directly acknowledging their 
reality: &lt;em&gt;“Parenting is tough. You’re not alone.”&lt;/em&gt;&lt;/p&gt;&lt;h4 id="progressive-profiling"&gt;Progressive Profiling&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/02/building-empathy-centred-ux-framework-mental-health-apps/#progressive-profiling"&gt;#&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;To
 tailor guidance to each family, we defined the minimal data needed for 
personalisation. On the first run, we collect only the essentials for a 
basic setup (e.g., parent role, number of teens, and each teen’s age). 
Additional, yet still important, details (specific challenges, wishes, 
requests) are gathered gradually as users progress through the app, 
avoiding long forms for those who need support immediately.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/building-empathy-centred-ux-framework-mental-health-apps/2-progressive-profiling-teeni.png"&gt;&lt;img alt="Progressive profiling in Teeni" height="450" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/building-empathy-centred-ux-framework-mental-health-apps/2-progressive-profiling-teeni.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Progressive profiling in Teeni: Collect minimum data during onboarding and ask for additional details later when needed.&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;The
 entire onboarding is centred around a consistently supportive choice of
 words, turning a typically highly practical, functional process into a 
way to connect with the vulnerable user on a deeper emotional level, 
while keeping an explicit fast path.&lt;/p&gt;&lt;h3 id="your-toolbox"&gt;Your Toolbox&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Use Validating Language&lt;/strong&gt;&lt;br /&gt;Start with “It’s okay to feel this way,” not “Allow notifications.”&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Understand “Why”, not just “What”&lt;/strong&gt;&lt;br /&gt;Collect
 only what you’ll use now and defer the rest via progressive profiling. 
Use simple, goal-focused questions to personalise users’ experience.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Prioritise Brevity and Respect&lt;/strong&gt;&lt;br /&gt;Keep
 onboarding skimmable, make optionality explicit, and let user testing 
define the minimum effective length &amp;amp;mdashl the shorter is usually 
the better.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Keep an Eye on Feedback and Iterate&lt;/strong&gt;&lt;br /&gt;Track time-to-first-value and step drop-offs; pair these with quick usability sessions, then adjust based on what you learn.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This
 initial conversation sets the stage for trust. But this trust is 
fragile. The next step is to ensure the app’s very environment doesn’t 
break it.&lt;/p&gt;&lt;h2 id="the-emotional-interface-maintaining-trust-in-a-safe-environment"&gt;The Emotional Interface: Maintaining Trust In A Safe Environment&lt;/h2&gt;&lt;p&gt;A user experiencing anxiety or depression often shows &lt;a href="https://pmc.ncbi.nlm.nih.gov/articles/PMC6520478/"&gt;reduced cognitive capacity, which affects their attention span and the speed with which they process information&lt;/a&gt;
 and lowers tolerance for dense layouts and fast, highly stimulating 
visuals. This means that high-saturation palettes, abrupt contrast 
changes, flashing, and dense text can feel overwhelming for them.&lt;/p&gt;&lt;blockquote&gt;&lt;strong&gt;The Empathy Tool&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;When
 designing a user flow for a mental health app, I always apply the Web 
Content Accessibility Guidelines 2.2 as a foundational baseline. On top 
of that, I choose a &lt;strong&gt;“low-stimulus”&lt;/strong&gt;, “familiar and safe”
 visual language to minimise the user’s cognitive load and create a 
calm, predictable, and personalised environment. Where appropriate, I 
add subtle, opt-in haptics and gentle micro-interactions for sensory 
grounding, and offer voice features as an option in high-stress moments 
(alongside low-effort tap flows) to enhance accessibility.&lt;/blockquote&gt;&lt;p&gt;Imagine
 you need to guide your users “by the hand”: we want to make sure their 
experience is as effortless as possible, and they are quickly guided to 
the support they need, so we avoid complicated forms and long wordings.&lt;/p&gt;&lt;h3 id="case-digital-safe-space"&gt;Case: Digital Safe Space&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/02/building-empathy-centred-ux-framework-mental-health-apps/#case-digital-safe-space"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;For the app focused on instant stress relief, &lt;em&gt;&lt;a href="https://play.google.com/store/apps/details?id=world.dobra.bearroom"&gt;Bear Room&lt;/a&gt;&lt;/em&gt;,
 I tested a “cosy room” design. My initial hypothesis was validated 
through a critical series of user interviews: the prevailing design 
language of many mental health apps appeared misaligned with the needs 
of our audience. Participants grappling with conditions such as PTSD and
 depression repeatedly described competing apps as “too bright, too 
happy, and too overwhelming,” which only intensified their sense of 
alienation instead of providing solace. This suggested a mismatch for 
our segment, which instead sought a sense of safety in the digital 
environment.&lt;/p&gt;&lt;p&gt;This feedback informed a low-arousal design strategy.
 Rather than treating “safe space” as a visual theme, we approached it 
as a &lt;strong&gt;holistic sensory experience&lt;/strong&gt;. The resulting 
interface is a direct antithesis to digital overload; it gently guides 
the user through the flow, keeping in mind that they are likely in a 
state where they lack the capacity to concentrate. The text is divided 
into smaller parts and is easily scannable and quickly defined. The 
emotional support tools — such as a pillow — are highlighted on purpose 
for convenience.&lt;/p&gt;&lt;p&gt;The interface employs a carefully curated, 
non-neon, earthy palette that feels grounding rather than stimulating, 
and it rigorously eliminates any sudden animations or jarring bright 
alerts that could trigger a stress response. This deliberate calmness is
 not an aesthetic afterthought but the app’s most critical feature, 
establishing a foundational sense of &lt;strong&gt;digital safety&lt;/strong&gt;.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/building-empathy-centred-ux-framework-mental-health-apps/3-bear-room-interface.png"&gt;&lt;img alt="Bear Room’s “cosy room” interface" height="450" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/building-empathy-centred-ux-framework-mental-health-apps/3-bear-room-interface.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Bear Room’s “cosy room” interface uses a low-arousal visual language, validated by user interviews as calming and welcoming.&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;To
 foster a sense of personal connection and psychological ownership, the 
room introduces three opt-in “personal objects”: Mirror, Letter, and 
Frame. Each invites a small, successful act of contribution (e.g., 
leaving a short message to one’s future self or curating a set of 
personally meaningful photos), drawing on the &lt;a href="https://www.hbs.edu/ris/Publication%20Files/11-091.pdf"&gt;IKEA effect&lt;/a&gt; (PDF).&lt;/p&gt;&lt;p&gt;For
 instance, Frame functions as a personal archive of comforting photo 
albums that users can revisit when they need warmth or reassurance. 
Because Frame is represented in the digital room as a picture frame on 
the wall, I designed an optional layer of customisation to deepen this 
connection: users can replace the placeholder with an image from their 
collection — a loved one, a pet, or a favourite landscape — displayed in
 the room each time they open the app. This choice is voluntary, 
lightweight, and reversible, intended to help the space feel more “mine”
 and deepen attachment without increasing cognitive load.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;
 Always adapt to the context. Try to avoid making the colour palette too
 pastel. It is useful to balance the brightness based on the user 
research, to protect the right level of the app’s contrast.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/building-empathy-centred-ux-framework-mental-health-apps/4-teeni-palette-option.png"&gt;&lt;img alt="Parent preference feedback for Teeni’s palette options" height="450" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/building-empathy-centred-ux-framework-mental-health-apps/4-teeni-palette-option.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Parent
 preference feedback for Teeni’s palette options: the selected scheme 
felt “teen-parenting appropriate,” while brighter/pastel options were 
rejected as “too bright,” “too toddler-ish,” or not matching parenting a
 teen.&amp;nbsp;&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="case-emotional-bubbles"&gt;Case: Emotional Bubbles&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/02/building-empathy-centred-ux-framework-mental-health-apps/#case-emotional-bubbles"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;In &lt;a href="https://play.google.com/store/apps/details?id=world.dobra.food4mood"&gt;&lt;em&gt;Food for Mood&lt;/em&gt;&lt;/a&gt;,
 I used a visual metaphor: coloured bubbles representing goals and 
emotional states (e.g., a dense red bubble for “Performance”). This 
allows users to externalise and visualise complex feelings without the 
cognitive burden of finding the right words. It’s a UI that speaks the 
language of emotion directly.&lt;/p&gt;&lt;p&gt;In an informal field test with young
 professionals (the target audience) in a co-working space, participants
 tried three interactive prototypes and rated each on simplicity and 
enjoyment. The standard card layout scored higher on simplicity, but the
 bubble carousel scored better on engagement and positive affect — and 
became the preferred option for the first iteration. Given that the 
simplicity trade-off was minimal (&lt;sup&gt;4&lt;/sup&gt;⁄&lt;sub&gt;5&lt;/sub&gt; vs. &lt;sup&gt;5&lt;/sup&gt;⁄&lt;sub&gt;5&lt;/sub&gt;)
 and limited to the first few seconds of use, I prioritised the concept 
that made the experience feel more emotionally rewarding.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/building-empathy-centred-ux-framework-mental-health-apps/5-concept-stage-field-test-scores.png"&gt;&lt;img alt="Concept-stage field test scores" height="450" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/building-empathy-centred-ux-framework-mental-health-apps/5-concept-stage-field-test-scores.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Concept-stage field test scores: the bubble carousel balanced high enjoyment (5/5) with near-top simplicity (4/5).&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id="case-micro-interactions-and-sensory-grounding"&gt;Case: Micro-interactions And Sensory Grounding&lt;/h3&gt;&lt;p&gt;Adding a touch of tactile micro-interactions like bubble-wrap popping in &lt;a href="https://play.google.com/store/apps/details?id=world.dobra.bearroom"&gt;&lt;em&gt;Bear Room&lt;/em&gt;&lt;/a&gt;,
 may also offer users moments of kinetic relief. Integrating deliberate,
 tactile micro-interactions, such as the satisfying bubble-wrap popping 
mechanic, provides a focused act that can help an overwhelmed user feel 
more grounded. It offers a moment of pure, sensory distraction for a 
person stuck in a torrent of stressful thoughts. This isn’t about 
gamification in the traditional, points-driven sense; it’s about 
offering a &lt;strong&gt;controlled, sensory interruption to the cycle of anxiety&lt;/strong&gt;.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/building-empathy-centred-ux-framework-mental-health-apps/10-bear-room-bubble-wrap.png"&gt;&lt;img alt="Bear Room’s “bubble-wrap” grounding micro-interaction" height="450" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/building-empathy-centred-ux-framework-mental-health-apps/10-bear-room-bubble-wrap.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Bear Room’s “bubble-wrap” grounding micro-interaction, with opt-in vibration and sound.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;
 Make tactile effects opt-in and predictable. Unexpected sensory 
feedback can increase arousal rather than reduce it for some users.&lt;/p&gt;&lt;h3 id="case-voice-assistants"&gt;Case: Voice Assistants&amp;nbsp;&lt;/h3&gt;&lt;p&gt;When
 a user is in a state of high anxiety or depression, it can become an 
extra effort for them to type something in the app or make choices. In 
moments when attention is impaired, and a simple, low-cognitive choice 
(e.g., ≤4 clearly labelled options) isn’t enough, voice input can offer a
 lower-friction way to engage and communicate empathy.&lt;/p&gt;&lt;p&gt;In both &lt;a href="https://play.google.com/store/apps/details?id=world.dobra.teeni"&gt;&lt;em&gt;Teeni&lt;/em&gt;&lt;/a&gt; and &lt;a href="https://play.google.com/store/apps/details?id=world.dobra.bearroom"&gt;&lt;em&gt;Bear Room&lt;/em&gt;&lt;/a&gt;,
 voice was integrated as a primary path for flows related to fatigue, 
emotional overwhelm, and acute stress — always alongside a text input 
alternative. Simply &lt;a href="https://journals.sagepub.com/doi/10.1111/j.1467-9280.2007.01916.x?"&gt;putting feelings into words&lt;/a&gt;
 (affect labelling) has been shown to reduce emotional intensity for 
some users, and spoken input also provides a richer context for 
tailoring support.&lt;/p&gt;&lt;p&gt;For &lt;em&gt;Bear Room&lt;/em&gt;, we give users a choice 
to share what’s on their mind via a prominent mic button (with text 
input available below. The app then analyses their response with AI 
(does not diagnose) and provides a set of tailored practices to help 
them cope. This approach gives users a space for the raw, unfiltered 
expression of emotion when texting feels too heavy.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/building-empathy-centred-ux-framework-mental-health-apps/9-bear-room-voice-first-support-flow.png"&gt;&lt;img alt="Bear Room’s voice-first support flow" height="450" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/building-empathy-centred-ux-framework-mental-health-apps/9-bear-room-voice-first-support-flow.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Bear
 Room’s voice-first support flow lets users talk or type what’s 
happening, then suggests a tailored set of practices; essential coping 
tools are never paywalled.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Similarly, &lt;em&gt;Teeni’s&lt;/em&gt;
 “Hot flow” lets parents vent frustration and describe a difficult 
trigger via voice. Based on the case description, AI gives a one-screen 
piece of psychoeducational content, and in a few steps, the app suggests
 an appropriate calming tool, uniting both emotional and relational 
support.&lt;/p&gt;&lt;blockquote class="pull-quote"&gt;&lt;p&gt;&lt;a aria-label="Share on Twitter" class="pull-quote__link" href="https://twitter.com/share?text=%0aBy%20meeting%20the%20user%20at%20their%20level%20of%20low%20cognitive%20capacity%20and%20accepting%20their%20input%20in%20the%20most%20accessible%20form,%20we%20build%20a%20deeper%20trust%20and%20reinforce%20the%20app%20as%20a%20truly%20adaptive,%20reliable,%20and%20non-judgmental%20space.%0a&amp;amp;url=https://smashingmagazine.com%2f2026%2f02%2fbuilding-empathy-centred-ux-framework-mental-health-apps%2f"&gt;By
 meeting the user at their level of low cognitive capacity and accepting
 their input in the most accessible form, we build a deeper trust and 
reinforce the app as a truly adaptive, reliable, and non-judgmental 
space.&lt;/a&gt;&lt;/p&gt;&lt;div class="pull-quote__quotation"&gt;&lt;div class="pull-quote__bg"&gt;&lt;span class="pull-quote__symbol"&gt;“&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;
 Mental-health topics are highly sensitive, and many people feel 
uncomfortable sharing sensitive data with an app — especially amid 
frequent news about data breaches and data being sold to third parties. 
Before recording, show a concise notice that explains how audio is 
processed, where it’s processed, how long it’s stored, and that it is 
not sold or shared with third parties. Present this in a clear, consent 
step (e.g., GDPR-style). For products handling personal data, it’s also 
best practice to provide an obvious “Delete all data” option.&lt;/p&gt;&lt;h3 id="your-toolbox-1"&gt;Your Toolbox&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/02/building-empathy-centred-ux-framework-mental-health-apps/#your-toolbox-1"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Accessibility-Friendly User Flow&lt;/strong&gt;&lt;br /&gt;Aim
 to become your user’s guide. Only use the text that is important, 
highlight key actions, and provide simple, step-by-step paths.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Muted Palettes&lt;/strong&gt;&lt;br /&gt;There’s
 no one-size-fits-all colour rule for mental-health apps. Align palette 
with purpose and audience; if you use muted palettes, verify WCAG 2.2 
contrast thresholds and avoid flashing.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Tactile Micro-interactions&lt;/strong&gt;&lt;br /&gt;Use subtle, predictable, opt-in haptics and gentle micro-interactions for moments of kinetic relief.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Voice-First Design&lt;/strong&gt;&lt;br /&gt;Offer voice input as an alternative to typing or single-tap actions in low-energy/high-pressure states&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Subtle Personalisation&lt;/strong&gt;&lt;br /&gt;Integrate small, voluntary customisations (like a personal photo in a digital frame) to foster a stronger emotional bond.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Privacy by Default&lt;/strong&gt;&lt;br /&gt;Ask
 for explicit consent to process personal data. State clearly how, 
where, and for how long data is processed, and that it’s not sold or 
shared — and honour it.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;A safe interface builds trust in the moment. The final pillar is about earning the trust that brings users back, day after day.&lt;/p&gt;&lt;h2 id="the-retention-engine-deepening-trust-through-genuine-connection"&gt;The Retention Engine: Deepening Trust Through Genuine Connection&lt;/h2&gt;&lt;p&gt;Encouraging
 consistent use without manipulation often requires innovative solutions
 in mental health. The app, as a business, faces an ethical dilemma: its
 mission is to prioritise user wellbeing, which means it cannot indulge 
users simply to maximise their screen time. Streaks, points, and time 
limits can also induce anxiety and shame, negatively affecting the 
user’s mental health. The goal is not to maximise screen time, but to 
foster a &lt;strong&gt;supportive rhythm of use&lt;/strong&gt; that aligns with the non-linear journey of mental health.&lt;/p&gt;&lt;blockquote&gt;&lt;strong&gt;The Empathy Tool&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;I
 replace anxiety-inducing gamification with retention engines powered by
 empathy. This involves designing loops that intrinsically motivate 
users through three core pillars: granting them &lt;strong&gt;agency&lt;/strong&gt; with customisable tools, connecting them to a supportive &lt;strong&gt;community&lt;/strong&gt;, and ensuring the app itself acts as a consistent source of &lt;strong&gt;support&lt;/strong&gt;, making return visits feel like a choice, not a chore or pressure.&lt;/blockquote&gt;&lt;h3 id="case-key-economy"&gt;Case: “Key” Economy&lt;/h3&gt;&lt;p&gt;In search of reimagining retention mechanics away from punitive streaks and towards a model of compassionate encouragement, the &lt;em&gt;Bear Room&lt;/em&gt;
 team came up with the idea of the so-called “Key” economy. Unlike a 
streak that shames users for missing a day, users are envisioned to earn
 “keys” for logging in every third day — a rhythm that acknowledges the 
non-linear nature of healing and reduces the pressure of daily 
performance. Keys never gate SOS sets or essential coping practices. 
Keys only unlock more objects and advanced content; the core toolkit is 
always free. The app should also preserve users’ progress regardless of 
their level of engagement.&lt;/p&gt;&lt;p&gt;The system’s most empathetic 
innovation, however, lies in the ability for users to gift their 
hard-earned keys to others in the community who may be in greater need 
(still in the process of making). This intends to transform the act of 
retention from a self-focused chore into a generous, community-building 
gesture.&lt;/p&gt;&lt;p&gt;It aims to foster a &lt;strong&gt;culture of mutual support&lt;/strong&gt;, where consistent engagement is not about maintaining a personal score, but about accumulating the capacity to help others.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Why it Works&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;It’s Forgiving.&lt;/strong&gt;&lt;br /&gt;Unlike a streak, missing a day doesn’t reset progress; it just delays the next key. This removes shame.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;It’s Community-driven.&lt;/strong&gt;&lt;br /&gt;Users can &lt;em&gt;give their keys to others&lt;/em&gt;. This transforms retention from a selfish act into a generous one, reinforcing the app’s core value of community support.&lt;/li&gt;&lt;/ul&gt;&lt;h3 id="case-the-letter-exchange"&gt;Case: The Letter Exchange&lt;/h3&gt;&lt;p&gt;Within &lt;em&gt;Bear Room&lt;/em&gt;,
 users can write and receive supportive letters anonymously to other 
users around the world. This tool leverages AI-powered anonymity to 
create a safe space for radical vulnerability. It provides a real human 
connection while completely protecting user privacy, directly addressing
 the trust deficit. It shows users they are not alone in their 
struggles, a powerful retention driver.&lt;/p&gt;&lt;figure class="break-out article__image"&gt;&lt;a href="https://files.smashing.media/articles/building-empathy-centred-ux-framework-mental-health-apps/11-bear-room-letter-exchange.png"&gt;&lt;img alt="Bear Room’s Letter Exchange" height="450" src="https://res.cloudinary.com/indysigner/image/fetch/f_auto,q_80/w_400/https://files.smashing.media/articles/building-empathy-centred-ux-framework-mental-health-apps/11-bear-room-letter-exchange.png" width="800" /&gt;&lt;/a&gt;&lt;figcaption class="op-vertical-bottom"&gt;Bear Room’s Letter Exchange: AI-assisted delivery keeps peer-support letters anonymous and safe.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;
 Data privacy is always a priority in product design, but (again) it’s 
crucial to approach it firsthand in mental health. In the case of the 
letter exchange, robust anonymity isn’t just a setting; it is the 
foundational element that creates the safety required for users to be 
vulnerable and supportive with strangers.&lt;/p&gt;&lt;h3 id="case-teenager-translator"&gt;Case: Teenager Translator&lt;/h3&gt;&lt;p&gt;The “Teenager Translator” in &lt;em&gt;Teeni&lt;/em&gt;
 became a cornerstone of our retention strategy by directly addressing 
the moment of crisis where parents were most likely to disengage. When a
 parent inputs their adolescent’s angry words like &lt;em&gt;“What’s wrong with you? It’s my phone, I will watch what I want, just leave me alone!”&lt;/em&gt;,
 the tool instantly provides an empathetic translation of the emotional 
subtext, a de-escalation guide, and a practical script for how to 
respond.&lt;/p&gt;&lt;p&gt;This immediate, actionable support at the peak of frustration transforms the app from a passive resource into an indispensable &lt;strong&gt;crisis-management tool&lt;/strong&gt;.
 By delivering profound value exactly when and where users need it most,
 it creates powerful positive reinforcement that builds &lt;strong&gt;habit&lt;/strong&gt; and &lt;strong&gt;loyalty&lt;/strong&gt;, ensuring parents return to the app not just to learn, but to actively navigate their most challenging moments.&lt;/p&gt;&lt;h3 id="your-toolbox-2"&gt;Your Toolbox&amp;nbsp;&lt;a class="anchor" href="https://www.smashingmagazine.com/2026/02/building-empathy-centred-ux-framework-mental-health-apps/#your-toolbox-2"&gt;#&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Reframe Metrics&lt;/strong&gt;&lt;br /&gt;Change &lt;em&gt;“You broke your 7-day streak!”&lt;/em&gt; to &lt;em&gt;“You’ve practiced 5 of the last 10 days. Every bit helps.”&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Compassion Access Policy&lt;/strong&gt;&lt;br /&gt;Never gate crisis or core coping tools behind paywalls or keys.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Build Community Safely&lt;/strong&gt;&lt;br /&gt;Facilitate anonymous, moderated peer support.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Offer Choice&lt;/strong&gt;&lt;br /&gt;Let users control the frequency and type of reminders.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Keep an Eye on Reviews&lt;/strong&gt;&lt;br /&gt;Monitor
 app-store reviews and social mentions regularly; tag themes (bugs, UX 
friction, feature requests), quantify trends, and close the loop with 
quick fixes or clarifying updates.&lt;/li&gt;&lt;/ul&gt;&lt;h2 id="your-empathy-first-launchpad-three-pillars-to-trust"&gt;Your Empathy-First Launchpad: Three Pillars To Trust&amp;nbsp;&lt;/h2&gt;&lt;p&gt;Let’s
 return to the overwhelmed user from the introduction. They open an app 
that greets them with a tested, audience-aligned visual language, a 
validating first message, and a retention system that supports rather 
than punishes.&lt;/p&gt;&lt;p&gt;This is the power of an &lt;strong&gt;Empathy-Centred UX Framework&lt;/strong&gt;.
 It forces us to move beyond pixels and workflows to the heart of the 
user experience: emotional safety. But to embed this philosophy in 
design processes, we need a structured, scalable approach. My designer 
path led me to the following three core pillars:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;The Onboarding Conversation&lt;/strong&gt;&lt;br /&gt;Start
 by transforming the initial setup from a functional checklist into the 
first supportive, therapy-informed dialogue. This pillar is rooted in 
using validating language, keeping asking “why” to understand deeper 
needs, and prioritising brevity and respect to make the user feel seen 
and understood from their very first interactions.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The Emotional Interface&lt;/strong&gt;&lt;br /&gt;Adjust
 the design to a low-stimulus digital environment for a brain in 
distress. This pillar focuses on the visual and interactive tools: muted
 palettes, calming micro-interactions, voice-first features, and 
personalisation, to make sure a user enters a calm, predictable, and 
safe digital environment. Certainly, these tools are not limited to the 
ones I applied throughout my experience, and there is always room for 
creativity, keeping in mind users’ preferences and scientific research.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The Retention Engine&lt;/strong&gt;&lt;br /&gt;Be
 persistent in upholding genuine connection over manipulative 
gamification. This pillar focuses on building lasting engagement through
 forgiving systems (like the “Key” economy), community-driven support 
(like letter exchanges), and tools that offer profound value in moments 
of crisis (like the Teenager Translator). When creating such tools, aim 
for a supportive rhythm of use that aligns with the non-linear journey 
of mental health.&lt;/li&gt;&lt;/ol&gt;&lt;h2 id="trust-is-the-success-balancing-game"&gt;Trust Is The Success: Balancing Game&amp;nbsp;&lt;/h2&gt;&lt;p&gt;While
 we, as designers, don’t directly define the app’s success metrics, we 
cannot deny that our work influences the final outcomes. This is where 
our practical tools in mental health apps may come in partnership with 
the product owner’s goals. All the tools are designed based on 
hypotheses, evaluations of whether users need them, further testing, and
 metric analysis.&lt;/p&gt;&lt;p&gt;I would argue that one of the most critical success components for a mental health app is &lt;strong&gt;trust&lt;/strong&gt;.
 Although it is not easy to measure, our role as designers lies 
precisely in creating a UX Framework that respects and listens to its 
users and makes the app fully &lt;strong&gt;accessible&lt;/strong&gt; and &lt;strong&gt;inclusive&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;The trick is to achieve a &lt;strong&gt;sustainable balance between helping users reach their wellness goals and the gaming effect&lt;/strong&gt;,
 so they also benefit from the process and atmosphere. It is a blend of 
enjoyment from the process and fulfillment from the health benefits, 
where we want to make a routine meditation exercise something pleasant. 
Our role as product designers is to always keep in mind that the end 
goal for the user is to achieve a positive psychological effect, not to 
remain in a perpetual gaming loop.&lt;/p&gt;&lt;p&gt;Of course, we need to keep in 
mind that the more responsibility the app takes for its users’ health, 
the more requirements there arise for its design.&lt;/p&gt;&lt;p&gt;When this 
balance is struck, the result is more than just better metrics; it’s a 
profound positive impact on your users’ lives. In the end, empowering a 
user’s well-being is the highest achievement our craft can aspire to.&lt;/p&gt;</description><link>http://honeyvig.blogspot.com/2026/03/building-digital-trust-empathy-centred.html</link><author>noreply@blogger.com (H)</author><thr:total>0</thr:total><enclosure length="-1" type="application/pdf;charset=utf-8" url="https://www.hbs.edu/ris/Publication%20Files/11-091.pdf"/><itunes:explicit>no</itunes:explicit><itunes:subtitle>&amp;nbsp;Designing for mental health means designing for vulnerability. Empathy-Centred UX becomes not a “nice to have” but a fundamental design requirement. Here’s a practical framework for building trust-first mental health products. Imagine a user opening a mental health app while feeling overwhelmed with anxiety. The very first thing they encounter is a screen with a bright, clashing colour scheme, followed by a notification shaming them for breaking a 5-day “mindfulness streak,” and a paywall blocking the meditation they desperately need at that very moment. This experience isn’t just poor design; it can be actively harmful. It betrays the user’s vulnerability and erodes the very trust the app aims to build. When designing for mental health, this becomes both a critical challenge and a valuable opportunity. Unlike a utility or entertainment app, the user’s emotional state cannot be treated as a secondary context. It is the environment your product operates in. With over a billion people living with mental health conditions and persistent gaps in access to care, safe and evidence-aligned digital support is increasingly relevant. The margin for error is negligible. Empathy-Centred UX becomes not a “nice to have” but a fundamental design requirement. It is an approach that moves beyond mere functionality to deeply understand, respect, and design for the user’s intimate emotional and psychological needs. But how do we translate this principle into practice? How do we build digital products that are not just useful, but truly trustworthy? Throughout my career as a product designer, I’ve found that trust is built by consistently meeting the user’s emotional needs at every stage of their journey. In this article, I will translate these insights into a hands-on empathy-centred UX framework. We will move beyond theory to dive deeper into applicable tools that help create experiences that are both humane and highly effective. In this article, I’ll share a practical, repeatable framework built around three pillars:Onboarding as a supportive first conversation.Interface design for a brain in distress.Retention patterns that deepen trust rather than pressure users. Together, these pillars offer a grounded way to design mental health experiences that prioritise trust, emotional safety, and real user needs at every step.The Onboarding Conversation: From a Checklist to a Trusted Companion Onboarding is “a first date” between a user and the app — and the first impression carries immense stakes, determining whether the user decides to continue engaging with the app. In mental health tech, with up to 20,000 mental-health-related apps on the market, product designers face a dilemma of how to integrate onboarding’s primary goals without making the design feel too clinical or dismissive for a user seeking help.The Empathy Tool In my experience, I have found it essential to design onboarding as the first supportive conversation. The goal is to help the user feel seen and understood by delivering a small dose of relief quickly, not just overload them with data and the app’s features.Case Study: A Teenager’s Parenting Journey At Teeni, an app for parents of teenagers, onboarding requires an approach that solves two problems: (1) acknowledge the emotional load of parenting teens and show how the app can share that load; (2) collect just enough information to make the first feed relevant.Recognition And Relief Interviews surfaced a recurring feeling among parents: “I’m a bad parent, I’ve failed at everything.” My design idea was to provide early relief and normalisation through a city-at-night metaphor with lit windows: directly after the welcome page, a user engages with three brief, animated and optional stories based on frequent challenges of teenage parenting, in which they can recognise themselves (e.g., a story of a mother learning to manage her reaction to her teen rolling their eyes). This narrative approach reassures parents that they are not alone in their struggles, normalising and helping them cope with stress and other complex emotions from the very beginning.Teeni onboarding is designed as support first: it acknowledges the emotional load of parenting teens, then uses optional peer stories to help parents feel less alone. Note: Early usability sessions indicated strong emotional resonance, but post-launch analytics showed that the optionality of the storytelling must be explicit. The goal is to balance the storytelling to avoid overwhelming the distressed parent, directly acknowledging their reality: “Parenting is tough. You’re not alone.”Progressive Profiling&amp;nbsp;# To tailor guidance to each family, we defined the minimal data needed for personalisation. On the first run, we collect only the essentials for a basic setup (e.g., parent role, number of teens, and each teen’s age). Additional, yet still important, details (specific challenges, wishes, requests) are gathered gradually as users progress through the app, avoiding long forms for those who need support immediately.Progressive profiling in Teeni: Collect minimum data during onboarding and ask for additional details later when needed.&amp;nbsp; The entire onboarding is centred around a consistently supportive choice of words, turning a typically highly practical, functional process into a way to connect with the vulnerable user on a deeper emotional level, while keeping an explicit fast path.Your ToolboxUse Validating Language Start with “It’s okay to feel this way,” not “Allow notifications.”Understand “Why”, not just “What” Collect only what you’ll use now and defer the rest via progressive profiling. Use simple, goal-focused questions to personalise users’ experience.Prioritise Brevity and Respect Keep onboarding skimmable, make optionality explicit, and let user testing define the minimum effective length &amp;amp;mdashl the shorter is usually the better.Keep an Eye on Feedback and Iterate Track time-to-first-value and step drop-offs; pair these with quick usability sessions, then adjust based on what you learn. This initial conversation sets the stage for trust. But this trust is fragile. The next step is to ensure the app’s very environment doesn’t break it.The Emotional Interface: Maintaining Trust In A Safe Environment A user experiencing anxiety or depression often shows reduced cognitive capacity, which affects their attention span and the speed with which they process information and lowers tolerance for dense layouts and fast, highly stimulating visuals. This means that high-saturation palettes, abrupt contrast changes, flashing, and dense text can feel overwhelming for them.The Empathy Tool When designing a user flow for a mental health app, I always apply the Web Content Accessibility Guidelines 2.2 as a foundational baseline. On top of that, I choose a “low-stimulus”, “familiar and safe” visual language to minimise the user’s cognitive load and create a calm, predictable, and personalised environment. Where appropriate, I add subtle, opt-in haptics and gentle micro-interactions for sensory grounding, and offer voice features as an option in high-stress moments (alongside low-effort tap flows) to enhance accessibility. Imagine you need to guide your users “by the hand”: we want to make sure their experience is as effortless as possible, and they are quickly guided to the support they need, so we avoid complicated forms and long wordings.Case: Digital Safe Space&amp;nbsp;# For the app focused on instant stress relief, Bear Room, I tested a “cosy room” design. My initial hypothesis was validated through a critical series of user interviews: the prevailing design language of many mental health apps appeared misaligned with the needs of our audience. Participants grappling with conditions such as PTSD and depression repeatedly described competing apps as “too bright, too happy, and too overwhelming,” which only intensified their sense of alienation instead of providing solace. This suggested a mismatch for our segment, which instead sought a sense of safety in the digital environment. This feedback informed a low-arousal design strategy. Rather than treating “safe space” as a visual theme, we approached it as a holistic sensory experience. The resulting interface is a direct antithesis to digital overload; it gently guides the user through the flow, keeping in mind that they are likely in a state where they lack the capacity to concentrate. The text is divided into smaller parts and is easily scannable and quickly defined. The emotional support tools — such as a pillow — are highlighted on purpose for convenience. The interface employs a carefully curated, non-neon, earthy palette that feels grounding rather than stimulating, and it rigorously eliminates any sudden animations or jarring bright alerts that could trigger a stress response. This deliberate calmness is not an aesthetic afterthought but the app’s most critical feature, establishing a foundational sense of digital safety.Bear Room’s “cosy room” interface uses a low-arousal visual language, validated by user interviews as calming and welcoming.&amp;nbsp; To foster a sense of personal connection and psychological ownership, the room introduces three opt-in “personal objects”: Mirror, Letter, and Frame. Each invites a small, successful act of contribution (e.g., leaving a short message to one’s future self or curating a set of personally meaningful photos), drawing on the IKEA effect (PDF). For instance, Frame functions as a personal archive of comforting photo albums that users can revisit when they need warmth or reassurance. Because Frame is represented in the digital room as a picture frame on the wall, I designed an optional layer of customisation to deepen this connection: users can replace the placeholder with an image from their collection — a loved one, a pet, or a favourite landscape — displayed in the room each time they open the app. This choice is voluntary, lightweight, and reversible, intended to help the space feel more “mine” and deepen attachment without increasing cognitive load. Note: Always adapt to the context. Try to avoid making the colour palette too pastel. It is useful to balance the brightness based on the user research, to protect the right level of the app’s contrast.Parent preference feedback for Teeni’s palette options: the selected scheme felt “teen-parenting appropriate,” while brighter/pastel options were rejected as “too bright,” “too toddler-ish,” or not matching parenting a teen.&amp;nbsp;Case: Emotional Bubbles&amp;nbsp;# In Food for Mood, I used a visual metaphor: coloured bubbles representing goals and emotional states (e.g., a dense red bubble for “Performance”). This allows users to externalise and visualise complex feelings without the cognitive burden of finding the right words. It’s a UI that speaks the language of emotion directly. In an informal field test with young professionals (the target audience) in a co-working space, participants tried three interactive prototypes and rated each on simplicity and enjoyment. The standard card layout scored higher on simplicity, but the bubble carousel scored better on engagement and positive affect — and became the preferred option for the first iteration. Given that the simplicity trade-off was minimal (4⁄5 vs. 5⁄5) and limited to the first few seconds of use, I prioritised the concept that made the experience feel more emotionally rewarding.Concept-stage field test scores: the bubble carousel balanced high enjoyment (5/5) with near-top simplicity (4/5).Case: Micro-interactions And Sensory Grounding Adding a touch of tactile micro-interactions like bubble-wrap popping in Bear Room, may also offer users moments of kinetic relief. Integrating deliberate, tactile micro-interactions, such as the satisfying bubble-wrap popping mechanic, provides a focused act that can help an overwhelmed user feel more grounded. It offers a moment of pure, sensory distraction for a person stuck in a torrent of stressful thoughts. This isn’t about gamification in the traditional, points-driven sense; it’s about offering a controlled, sensory interruption to the cycle of anxiety.Bear Room’s “bubble-wrap” grounding micro-interaction, with opt-in vibration and sound. Note: Make tactile effects opt-in and predictable. Unexpected sensory feedback can increase arousal rather than reduce it for some users.Case: Voice Assistants&amp;nbsp; When a user is in a state of high anxiety or depression, it can become an extra effort for them to type something in the app or make choices. In moments when attention is impaired, and a simple, low-cognitive choice (e.g., ≤4 clearly labelled options) isn’t enough, voice input can offer a lower-friction way to engage and communicate empathy. In both Teeni and Bear Room, voice was integrated as a primary path for flows related to fatigue, emotional overwhelm, and acute stress — always alongside a text input alternative. Simply putting feelings into words (affect labelling) has been shown to reduce emotional intensity for some users, and spoken input also provides a richer context for tailoring support. For Bear Room, we give users a choice to share what’s on their mind via a prominent mic button (with text input available below. The app then analyses their response with AI (does not diagnose) and provides a set of tailored practices to help them cope. This approach gives users a space for the raw, unfiltered expression of emotion when texting feels too heavy.Bear Room’s voice-first support flow lets users talk or type what’s happening, then suggests a tailored set of practices; essential coping tools are never paywalled. Similarly, Teeni’s “Hot flow” lets parents vent frustration and describe a difficult trigger via voice. Based on the case description, AI gives a one-screen piece of psychoeducational content, and in a few steps, the app suggests an appropriate calming tool, uniting both emotional and relational support. By meeting the user at their level of low cognitive capacity and accepting their input in the most accessible form, we build a deeper trust and reinforce the app as a truly adaptive, reliable, and non-judgmental space.“ Note: Mental-health topics are highly sensitive, and many people feel uncomfortable sharing sensitive data with an app — especially amid frequent news about data breaches and data being sold to third parties. Before recording, show a concise notice that explains how audio is processed, where it’s processed, how long it’s stored, and that it is not sold or shared with third parties. Present this in a clear, consent step (e.g., GDPR-style). For products handling personal data, it’s also best practice to provide an obvious “Delete all data” option.Your Toolbox&amp;nbsp;#Accessibility-Friendly User Flow Aim to become your user’s guide. Only use the text that is important, highlight key actions, and provide simple, step-by-step paths.Muted Palettes There’s no one-size-fits-all colour rule for mental-health apps. Align palette with purpose and audience; if you use muted palettes, verify WCAG 2.2 contrast thresholds and avoid flashing.Tactile Micro-interactions Use subtle, predictable, opt-in haptics and gentle micro-interactions for moments of kinetic relief.Voice-First Design Offer voice input as an alternative to typing or single-tap actions in low-energy/high-pressure statesSubtle Personalisation Integrate small, voluntary customisations (like a personal photo in a digital frame) to foster a stronger emotional bond.Privacy by Default Ask for explicit consent to process personal data. State clearly how, where, and for how long data is processed, and that it’s not sold or shared — and honour it. A safe interface builds trust in the moment. The final pillar is about earning the trust that brings users back, day after day.The Retention Engine: Deepening Trust Through Genuine Connection Encouraging consistent use without manipulation often requires innovative solutions in mental health. The app, as a business, faces an ethical dilemma: its mission is to prioritise user wellbeing, which means it cannot indulge users simply to maximise their screen time. Streaks, points, and time limits can also induce anxiety and shame, negatively affecting the user’s mental health. The goal is not to maximise screen time, but to foster a supportive rhythm of use that aligns with the non-linear journey of mental health.The Empathy Tool I replace anxiety-inducing gamification with retention engines powered by empathy. This involves designing loops that intrinsically motivate users through three core pillars: granting them agency with customisable tools, connecting them to a supportive community, and ensuring the app itself acts as a consistent source of support, making return visits feel like a choice, not a chore or pressure.Case: “Key” Economy In search of reimagining retention mechanics away from punitive streaks and towards a model of compassionate encouragement, the Bear Room team came up with the idea of the so-called “Key” economy. Unlike a streak that shames users for missing a day, users are envisioned to earn “keys” for logging in every third day — a rhythm that acknowledges the non-linear nature of healing and reduces the pressure of daily performance. Keys never gate SOS sets or essential coping practices. Keys only unlock more objects and advanced content; the core toolkit is always free. The app should also preserve users’ progress regardless of their level of engagement. The system’s most empathetic innovation, however, lies in the ability for users to gift their hard-earned keys to others in the community who may be in greater need (still in the process of making). This intends to transform the act of retention from a self-focused chore into a generous, community-building gesture. It aims to foster a culture of mutual support, where consistent engagement is not about maintaining a personal score, but about accumulating the capacity to help others. Why it WorksIt’s Forgiving. Unlike a streak, missing a day doesn’t reset progress; it just delays the next key. This removes shame.It’s Community-driven. Users can give their keys to others. This transforms retention from a selfish act into a generous one, reinforcing the app’s core value of community support.Case: The Letter Exchange Within Bear Room, users can write and receive supportive letters anonymously to other users around the world. This tool leverages AI-powered anonymity to create a safe space for radical vulnerability. It provides a real human connection while completely protecting user privacy, directly addressing the trust deficit. It shows users they are not alone in their struggles, a powerful retention driver.Bear Room’s Letter Exchange: AI-assisted delivery keeps peer-support letters anonymous and safe. Note: Data privacy is always a priority in product design, but (again) it’s crucial to approach it firsthand in mental health. In the case of the letter exchange, robust anonymity isn’t just a setting; it is the foundational element that creates the safety required for users to be vulnerable and supportive with strangers.Case: Teenager Translator The “Teenager Translator” in Teeni became a cornerstone of our retention strategy by directly addressing the moment of crisis where parents were most likely to disengage. When a parent inputs their adolescent’s angry words like “What’s wrong with you? It’s my phone, I will watch what I want, just leave me alone!”, the tool instantly provides an empathetic translation of the emotional subtext, a de-escalation guide, and a practical script for how to respond. This immediate, actionable support at the peak of frustration transforms the app from a passive resource into an indispensable crisis-management tool. By delivering profound value exactly when and where users need it most, it creates powerful positive reinforcement that builds habit and loyalty, ensuring parents return to the app not just to learn, but to actively navigate their most challenging moments.Your Toolbox&amp;nbsp;#Reframe Metrics Change “You broke your 7-day streak!” to “You’ve practiced 5 of the last 10 days. Every bit helps.”Compassion Access Policy Never gate crisis or core coping tools behind paywalls or keys.Build Community Safely Facilitate anonymous, moderated peer support.Offer Choice Let users control the frequency and type of reminders.Keep an Eye on Reviews Monitor app-store reviews and social mentions regularly; tag themes (bugs, UX friction, feature requests), quantify trends, and close the loop with quick fixes or clarifying updates.Your Empathy-First Launchpad: Three Pillars To Trust&amp;nbsp; Let’s return to the overwhelmed user from the introduction. They open an app that greets them with a tested, audience-aligned visual language, a validating first message, and a retention system that supports rather than punishes. This is the power of an Empathy-Centred UX Framework. It forces us to move beyond pixels and workflows to the heart of the user experience: emotional safety. But to embed this philosophy in design processes, we need a structured, scalable approach. My designer path led me to the following three core pillars:The Onboarding Conversation Start by transforming the initial setup from a functional checklist into the first supportive, therapy-informed dialogue. This pillar is rooted in using validating language, keeping asking “why” to understand deeper needs, and prioritising brevity and respect to make the user feel seen and understood from their very first interactions.The Emotional Interface Adjust the design to a low-stimulus digital environment for a brain in distress. This pillar focuses on the visual and interactive tools: muted palettes, calming micro-interactions, voice-first features, and personalisation, to make sure a user enters a calm, predictable, and safe digital environment. Certainly, these tools are not limited to the ones I applied throughout my experience, and there is always room for creativity, keeping in mind users’ preferences and scientific research. The Retention Engine Be persistent in upholding genuine connection over manipulative gamification. This pillar focuses on building lasting engagement through forgiving systems (like the “Key” economy), community-driven support (like letter exchanges), and tools that offer profound value in moments of crisis (like the Teenager Translator). When creating such tools, aim for a supportive rhythm of use that aligns with the non-linear journey of mental health.Trust Is The Success: Balancing Game&amp;nbsp; While we, as designers, don’t directly define the app’s success metrics, we cannot deny that our work influences the final outcomes. This is where our practical tools in mental health apps may come in partnership with the product owner’s goals. All the tools are designed based on hypotheses, evaluations of whether users need them, further testing, and metric analysis. I would argue that one of the most critical success components for a mental health app is trust. Although it is not easy to measure, our role as designers lies precisely in creating a UX Framework that respects and listens to its users and makes the app fully accessible and inclusive. The trick is to achieve a sustainable balance between helping users reach their wellness goals and the gaming effect, so they also benefit from the process and atmosphere. It is a blend of enjoyment from the process and fulfillment from the health benefits, where we want to make a routine meditation exercise something pleasant. Our role as product designers is to always keep in mind that the end goal for the user is to achieve a positive psychological effect, not to remain in a perpetual gaming loop. Of course, we need to keep in mind that the more responsibility the app takes for its users’ health, the more requirements there arise for its design. When this balance is struck, the result is more than just better metrics; it’s a profound positive impact on your users’ lives. In the end, empowering a user’s well-being is the highest achievement our craft can aspire to.</itunes:subtitle><itunes:author>noreply@blogger.com (H)</itunes:author><itunes:summary>&amp;nbsp;Designing for mental health means designing for vulnerability. Empathy-Centred UX becomes not a “nice to have” but a fundamental design requirement. Here’s a practical framework for building trust-first mental health products. Imagine a user opening a mental health app while feeling overwhelmed with anxiety. The very first thing they encounter is a screen with a bright, clashing colour scheme, followed by a notification shaming them for breaking a 5-day “mindfulness streak,” and a paywall blocking the meditation they desperately need at that very moment. This experience isn’t just poor design; it can be actively harmful. It betrays the user’s vulnerability and erodes the very trust the app aims to build. When designing for mental health, this becomes both a critical challenge and a valuable opportunity. Unlike a utility or entertainment app, the user’s emotional state cannot be treated as a secondary context. It is the environment your product operates in. With over a billion people living with mental health conditions and persistent gaps in access to care, safe and evidence-aligned digital support is increasingly relevant. The margin for error is negligible. Empathy-Centred UX becomes not a “nice to have” but a fundamental design requirement. It is an approach that moves beyond mere functionality to deeply understand, respect, and design for the user’s intimate emotional and psychological needs. But how do we translate this principle into practice? How do we build digital products that are not just useful, but truly trustworthy? Throughout my career as a product designer, I’ve found that trust is built by consistently meeting the user’s emotional needs at every stage of their journey. In this article, I will translate these insights into a hands-on empathy-centred UX framework. We will move beyond theory to dive deeper into applicable tools that help create experiences that are both humane and highly effective. In this article, I’ll share a practical, repeatable framework built around three pillars:Onboarding as a supportive first conversation.Interface design for a brain in distress.Retention patterns that deepen trust rather than pressure users. Together, these pillars offer a grounded way to design mental health experiences that prioritise trust, emotional safety, and real user needs at every step.The Onboarding Conversation: From a Checklist to a Trusted Companion Onboarding is “a first date” between a user and the app — and the first impression carries immense stakes, determining whether the user decides to continue engaging with the app. In mental health tech, with up to 20,000 mental-health-related apps on the market, product designers face a dilemma of how to integrate onboarding’s primary goals without making the design feel too clinical or dismissive for a user seeking help.The Empathy Tool In my experience, I have found it essential to design onboarding as the first supportive conversation. The goal is to help the user feel seen and understood by delivering a small dose of relief quickly, not just overload them with data and the app’s features.Case Study: A Teenager’s Parenting Journey At Teeni, an app for parents of teenagers, onboarding requires an approach that solves two problems: (1) acknowledge the emotional load of parenting teens and show how the app can share that load; (2) collect just enough information to make the first feed relevant.Recognition And Relief Interviews surfaced a recurring feeling among parents: “I’m a bad parent, I’ve failed at everything.” My design idea was to provide early relief and normalisation through a city-at-night metaphor with lit windows: directly after the welcome page, a user engages with three brief, animated and optional stories based on frequent challenges of teenage parenting, in which they can recognise themselves (e.g., a story of a mother learning to manage her reaction to her teen rolling their eyes). This narrative approach reassures parents that they are not alone in their struggles, normalising and helping them cope with stress and other complex emotions from the very beginning.Teeni onboarding is designed as support first: it acknowledges the emotional load of parenting teens, then uses optional peer stories to help parents feel less alone. Note: Early usability sessions indicated strong emotional resonance, but post-launch analytics showed that the optionality of the storytelling must be explicit. The goal is to balance the storytelling to avoid overwhelming the distressed parent, directly acknowledging their reality: “Parenting is tough. You’re not alone.”Progressive Profiling&amp;nbsp;# To tailor guidance to each family, we defined the minimal data needed for personalisation. On the first run, we collect only the essentials for a basic setup (e.g., parent role, number of teens, and each teen’s age). Additional, yet still important, details (specific challenges, wishes, requests) are gathered gradually as users progress through the app, avoiding long forms for those who need support immediately.Progressive profiling in Teeni: Collect minimum data during onboarding and ask for additional details later when needed.&amp;nbsp; The entire onboarding is centred around a consistently supportive choice of words, turning a typically highly practical, functional process into a way to connect with the vulnerable user on a deeper emotional level, while keeping an explicit fast path.Your ToolboxUse Validating Language Start with “It’s okay to feel this way,” not “Allow notifications.”Understand “Why”, not just “What” Collect only what you’ll use now and defer the rest via progressive profiling. Use simple, goal-focused questions to personalise users’ experience.Prioritise Brevity and Respect Keep onboarding skimmable, make optionality explicit, and let user testing define the minimum effective length &amp;amp;mdashl the shorter is usually the better.Keep an Eye on Feedback and Iterate Track time-to-first-value and step drop-offs; pair these with quick usability sessions, then adjust based on what you learn. This initial conversation sets the stage for trust. But this trust is fragile. The next step is to ensure the app’s very environment doesn’t break it.The Emotional Interface: Maintaining Trust In A Safe Environment A user experiencing anxiety or depression often shows reduced cognitive capacity, which affects their attention span and the speed with which they process information and lowers tolerance for dense layouts and fast, highly stimulating visuals. This means that high-saturation palettes, abrupt contrast changes, flashing, and dense text can feel overwhelming for them.The Empathy Tool When designing a user flow for a mental health app, I always apply the Web Content Accessibility Guidelines 2.2 as a foundational baseline. On top of that, I choose a “low-stimulus”, “familiar and safe” visual language to minimise the user’s cognitive load and create a calm, predictable, and personalised environment. Where appropriate, I add subtle, opt-in haptics and gentle micro-interactions for sensory grounding, and offer voice features as an option in high-stress moments (alongside low-effort tap flows) to enhance accessibility. Imagine you need to guide your users “by the hand”: we want to make sure their experience is as effortless as possible, and they are quickly guided to the support they need, so we avoid complicated forms and long wordings.Case: Digital Safe Space&amp;nbsp;# For the app focused on instant stress relief, Bear Room, I tested a “cosy room” design. My initial hypothesis was validated through a critical series of user interviews: the prevailing design language of many mental health apps appeared misaligned with the needs of our audience. Participants grappling with conditions such as PTSD and depression repeatedly described competing apps as “too bright, too happy, and too overwhelming,” which only intensified their sense of alienation instead of providing solace. This suggested a mismatch for our segment, which instead sought a sense of safety in the digital environment. This feedback informed a low-arousal design strategy. Rather than treating “safe space” as a visual theme, we approached it as a holistic sensory experience. The resulting interface is a direct antithesis to digital overload; it gently guides the user through the flow, keeping in mind that they are likely in a state where they lack the capacity to concentrate. The text is divided into smaller parts and is easily scannable and quickly defined. The emotional support tools — such as a pillow — are highlighted on purpose for convenience. The interface employs a carefully curated, non-neon, earthy palette that feels grounding rather than stimulating, and it rigorously eliminates any sudden animations or jarring bright alerts that could trigger a stress response. This deliberate calmness is not an aesthetic afterthought but the app’s most critical feature, establishing a foundational sense of digital safety.Bear Room’s “cosy room” interface uses a low-arousal visual language, validated by user interviews as calming and welcoming.&amp;nbsp; To foster a sense of personal connection and psychological ownership, the room introduces three opt-in “personal objects”: Mirror, Letter, and Frame. Each invites a small, successful act of contribution (e.g., leaving a short message to one’s future self or curating a set of personally meaningful photos), drawing on the IKEA effect (PDF). For instance, Frame functions as a personal archive of comforting photo albums that users can revisit when they need warmth or reassurance. Because Frame is represented in the digital room as a picture frame on the wall, I designed an optional layer of customisation to deepen this connection: users can replace the placeholder with an image from their collection — a loved one, a pet, or a favourite landscape — displayed in the room each time they open the app. This choice is voluntary, lightweight, and reversible, intended to help the space feel more “mine” and deepen attachment without increasing cognitive load. Note: Always adapt to the context. Try to avoid making the colour palette too pastel. It is useful to balance the brightness based on the user research, to protect the right level of the app’s contrast.Parent preference feedback for Teeni’s palette options: the selected scheme felt “teen-parenting appropriate,” while brighter/pastel options were rejected as “too bright,” “too toddler-ish,” or not matching parenting a teen.&amp;nbsp;Case: Emotional Bubbles&amp;nbsp;# In Food for Mood, I used a visual metaphor: coloured bubbles representing goals and emotional states (e.g., a dense red bubble for “Performance”). This allows users to externalise and visualise complex feelings without the cognitive burden of finding the right words. It’s a UI that speaks the language of emotion directly. In an informal field test with young professionals (the target audience) in a co-working space, participants tried three interactive prototypes and rated each on simplicity and enjoyment. The standard card layout scored higher on simplicity, but the bubble carousel scored better on engagement and positive affect — and became the preferred option for the first iteration. Given that the simplicity trade-off was minimal (4⁄5 vs. 5⁄5) and limited to the first few seconds of use, I prioritised the concept that made the experience feel more emotionally rewarding.Concept-stage field test scores: the bubble carousel balanced high enjoyment (5/5) with near-top simplicity (4/5).Case: Micro-interactions And Sensory Grounding Adding a touch of tactile micro-interactions like bubble-wrap popping in Bear Room, may also offer users moments of kinetic relief. Integrating deliberate, tactile micro-interactions, such as the satisfying bubble-wrap popping mechanic, provides a focused act that can help an overwhelmed user feel more grounded. It offers a moment of pure, sensory distraction for a person stuck in a torrent of stressful thoughts. This isn’t about gamification in the traditional, points-driven sense; it’s about offering a controlled, sensory interruption to the cycle of anxiety.Bear Room’s “bubble-wrap” grounding micro-interaction, with opt-in vibration and sound. Note: Make tactile effects opt-in and predictable. Unexpected sensory feedback can increase arousal rather than reduce it for some users.Case: Voice Assistants&amp;nbsp; When a user is in a state of high anxiety or depression, it can become an extra effort for them to type something in the app or make choices. In moments when attention is impaired, and a simple, low-cognitive choice (e.g., ≤4 clearly labelled options) isn’t enough, voice input can offer a lower-friction way to engage and communicate empathy. In both Teeni and Bear Room, voice was integrated as a primary path for flows related to fatigue, emotional overwhelm, and acute stress — always alongside a text input alternative. Simply putting feelings into words (affect labelling) has been shown to reduce emotional intensity for some users, and spoken input also provides a richer context for tailoring support. For Bear Room, we give users a choice to share what’s on their mind via a prominent mic button (with text input available below. The app then analyses their response with AI (does not diagnose) and provides a set of tailored practices to help them cope. This approach gives users a space for the raw, unfiltered expression of emotion when texting feels too heavy.Bear Room’s voice-first support flow lets users talk or type what’s happening, then suggests a tailored set of practices; essential coping tools are never paywalled. Similarly, Teeni’s “Hot flow” lets parents vent frustration and describe a difficult trigger via voice. Based on the case description, AI gives a one-screen piece of psychoeducational content, and in a few steps, the app suggests an appropriate calming tool, uniting both emotional and relational support. By meeting the user at their level of low cognitive capacity and accepting their input in the most accessible form, we build a deeper trust and reinforce the app as a truly adaptive, reliable, and non-judgmental space.“ Note: Mental-health topics are highly sensitive, and many people feel uncomfortable sharing sensitive data with an app — especially amid frequent news about data breaches and data being sold to third parties. Before recording, show a concise notice that explains how audio is processed, where it’s processed, how long it’s stored, and that it is not sold or shared with third parties. Present this in a clear, consent step (e.g., GDPR-style). For products handling personal data, it’s also best practice to provide an obvious “Delete all data” option.Your Toolbox&amp;nbsp;#Accessibility-Friendly User Flow Aim to become your user’s guide. Only use the text that is important, highlight key actions, and provide simple, step-by-step paths.Muted Palettes There’s no one-size-fits-all colour rule for mental-health apps. Align palette with purpose and audience; if you use muted palettes, verify WCAG 2.2 contrast thresholds and avoid flashing.Tactile Micro-interactions Use subtle, predictable, opt-in haptics and gentle micro-interactions for moments of kinetic relief.Voice-First Design Offer voice input as an alternative to typing or single-tap actions in low-energy/high-pressure statesSubtle Personalisation Integrate small, voluntary customisations (like a personal photo in a digital frame) to foster a stronger emotional bond.Privacy by Default Ask for explicit consent to process personal data. State clearly how, where, and for how long data is processed, and that it’s not sold or shared — and honour it. A safe interface builds trust in the moment. The final pillar is about earning the trust that brings users back, day after day.The Retention Engine: Deepening Trust Through Genuine Connection Encouraging consistent use without manipulation often requires innovative solutions in mental health. The app, as a business, faces an ethical dilemma: its mission is to prioritise user wellbeing, which means it cannot indulge users simply to maximise their screen time. Streaks, points, and time limits can also induce anxiety and shame, negatively affecting the user’s mental health. The goal is not to maximise screen time, but to foster a supportive rhythm of use that aligns with the non-linear journey of mental health.The Empathy Tool I replace anxiety-inducing gamification with retention engines powered by empathy. This involves designing loops that intrinsically motivate users through three core pillars: granting them agency with customisable tools, connecting them to a supportive community, and ensuring the app itself acts as a consistent source of support, making return visits feel like a choice, not a chore or pressure.Case: “Key” Economy In search of reimagining retention mechanics away from punitive streaks and towards a model of compassionate encouragement, the Bear Room team came up with the idea of the so-called “Key” economy. Unlike a streak that shames users for missing a day, users are envisioned to earn “keys” for logging in every third day — a rhythm that acknowledges the non-linear nature of healing and reduces the pressure of daily performance. Keys never gate SOS sets or essential coping practices. Keys only unlock more objects and advanced content; the core toolkit is always free. The app should also preserve users’ progress regardless of their level of engagement. The system’s most empathetic innovation, however, lies in the ability for users to gift their hard-earned keys to others in the community who may be in greater need (still in the process of making). This intends to transform the act of retention from a self-focused chore into a generous, community-building gesture. It aims to foster a culture of mutual support, where consistent engagement is not about maintaining a personal score, but about accumulating the capacity to help others. Why it WorksIt’s Forgiving. Unlike a streak, missing a day doesn’t reset progress; it just delays the next key. This removes shame.It’s Community-driven. Users can give their keys to others. This transforms retention from a selfish act into a generous one, reinforcing the app’s core value of community support.Case: The Letter Exchange Within Bear Room, users can write and receive supportive letters anonymously to other users around the world. This tool leverages AI-powered anonymity to create a safe space for radical vulnerability. It provides a real human connection while completely protecting user privacy, directly addressing the trust deficit. It shows users they are not alone in their struggles, a powerful retention driver.Bear Room’s Letter Exchange: AI-assisted delivery keeps peer-support letters anonymous and safe. Note: Data privacy is always a priority in product design, but (again) it’s crucial to approach it firsthand in mental health. In the case of the letter exchange, robust anonymity isn’t just a setting; it is the foundational element that creates the safety required for users to be vulnerable and supportive with strangers.Case: Teenager Translator The “Teenager Translator” in Teeni became a cornerstone of our retention strategy by directly addressing the moment of crisis where parents were most likely to disengage. When a parent inputs their adolescent’s angry words like “What’s wrong with you? It’s my phone, I will watch what I want, just leave me alone!”, the tool instantly provides an empathetic translation of the emotional subtext, a de-escalation guide, and a practical script for how to respond. This immediate, actionable support at the peak of frustration transforms the app from a passive resource into an indispensable crisis-management tool. By delivering profound value exactly when and where users need it most, it creates powerful positive reinforcement that builds habit and loyalty, ensuring parents return to the app not just to learn, but to actively navigate their most challenging moments.Your Toolbox&amp;nbsp;#Reframe Metrics Change “You broke your 7-day streak!” to “You’ve practiced 5 of the last 10 days. Every bit helps.”Compassion Access Policy Never gate crisis or core coping tools behind paywalls or keys.Build Community Safely Facilitate anonymous, moderated peer support.Offer Choice Let users control the frequency and type of reminders.Keep an Eye on Reviews Monitor app-store reviews and social mentions regularly; tag themes (bugs, UX friction, feature requests), quantify trends, and close the loop with quick fixes or clarifying updates.Your Empathy-First Launchpad: Three Pillars To Trust&amp;nbsp; Let’s return to the overwhelmed user from the introduction. They open an app that greets them with a tested, audience-aligned visual language, a validating first message, and a retention system that supports rather than punishes. This is the power of an Empathy-Centred UX Framework. It forces us to move beyond pixels and workflows to the heart of the user experience: emotional safety. But to embed this philosophy in design processes, we need a structured, scalable approach. My designer path led me to the following three core pillars:The Onboarding Conversation Start by transforming the initial setup from a functional checklist into the first supportive, therapy-informed dialogue. This pillar is rooted in using validating language, keeping asking “why” to understand deeper needs, and prioritising brevity and respect to make the user feel seen and understood from their very first interactions.The Emotional Interface Adjust the design to a low-stimulus digital environment for a brain in distress. This pillar focuses on the visual and interactive tools: muted palettes, calming micro-interactions, voice-first features, and personalisation, to make sure a user enters a calm, predictable, and safe digital environment. Certainly, these tools are not limited to the ones I applied throughout my experience, and there is always room for creativity, keeping in mind users’ preferences and scientific research. The Retention Engine Be persistent in upholding genuine connection over manipulative gamification. This pillar focuses on building lasting engagement through forgiving systems (like the “Key” economy), community-driven support (like letter exchanges), and tools that offer profound value in moments of crisis (like the Teenager Translator). When creating such tools, aim for a supportive rhythm of use that aligns with the non-linear journey of mental health.Trust Is The Success: Balancing Game&amp;nbsp; While we, as designers, don’t directly define the app’s success metrics, we cannot deny that our work influences the final outcomes. This is where our practical tools in mental health apps may come in partnership with the product owner’s goals. All the tools are designed based on hypotheses, evaluations of whether users need them, further testing, and metric analysis. I would argue that one of the most critical success components for a mental health app is trust. Although it is not easy to measure, our role as designers lies precisely in creating a UX Framework that respects and listens to its users and makes the app fully accessible and inclusive. The trick is to achieve a sustainable balance between helping users reach their wellness goals and the gaming effect, so they also benefit from the process and atmosphere. It is a blend of enjoyment from the process and fulfillment from the health benefits, where we want to make a routine meditation exercise something pleasant. Our role as product designers is to always keep in mind that the end goal for the user is to achieve a positive psychological effect, not to remain in a perpetual gaming loop. Of course, we need to keep in mind that the more responsibility the app takes for its users’ health, the more requirements there arise for its design. When this balance is struck, the result is more than just better metrics; it’s a profound positive impact on your users’ lives. In the end, empowering a user’s well-being is the highest achievement our craft can aspire to.</itunes:summary></item></channel></rss>