[{"data":1,"prerenderedAt":163},["ShallowReactive",2],{"post-dark-mode-is-a-second-design-en":3,"related-posts-dark-mode-is-a-second-design-en":127,"related-categories-dark-mode-is-a-second-design-en":151},{"id":4,"title":5,"author":6,"authorImageUrl":7,"authorUrl":8,"body":9,"categorySlug":103,"categoryText":104,"dateModified":105,"datePublished":106,"description":107,"extension":108,"faqs":109,"image":116,"language":117,"meta":118,"navigation":119,"path":120,"seo":121,"stem":122,"tags":123,"__hash__":126},"blog\u002Fblog\u002Fdark-mode-is-a-second-design.md","Dark Mode Is a Second Design, Not a Filter","Bruma","\u002Fimages\u002Fauthors\u002Fbruma.jpg","https:\u002F\u002Fbrumaombra.com",{"type":10,"value":11,"toc":93},"minimark",[12,17,21,24,28,60,66,73,78,81,86,90],[13,14,16],"h2",{"id":15},"the-theme-that-looks-almost-right","The theme that looks almost right",[18,19,20],"p",{},"The quickest way to ship dark mode is to swap white for black and black for white. It works, in the sense that text stays readable. It also looks slightly off in a way that is hard to name: shadows vanish, the accent color glares, and every border seems either too loud or missing.",[18,22,23],{},"That is because a dark theme is not the light theme with the lights off. Colors behave differently on a dark background, and a few of them need their own decisions.",[13,25,27],{"id":26},"name-colors-by-job-not-by-shade","Name colors by job, not by shade",[18,29,30,31,35,36,39,40,43,44,35,47,35,50,35,53,35,56,59],{},"The fix that does most of the work is a vocabulary change. Instead of components using ",[32,33,34],"code",{},"white",", ",[32,37,38],{},"gray-100",", or ",[32,41,42],{},"#1b222d",", they use names that describe a job: ",[32,45,46],{},"background",[32,48,49],{},"card",[32,51,52],{},"surface",[32,54,55],{},"border",[32,57,58],{},"muted-foreground",". Each theme then decides what those jobs look like.",[61,62],"flow",{":items":63,"orientation":64,"title":65},"[\"A component asks for bg-card\",\"The token points to --card\",\"The light or dark theme defines --card\",\"Every card updates at once\"]","vertical","How a token becomes a color",[18,67,68,69,72],{},"In practice, this means a component written once never needs a ",[32,70,71],{},"dark:"," variant for its colors. When the theme changes, every surface changes with it.",[74,75,77],"h3",{"id":76},"three-things-tokens-dont-solve","Three things tokens don't solve",[18,79,80],{},"That sounds like the whole job, but a few details still need a human eye:",[82,83],"blog-list",{":items":84,"variant":85},"[\"Accent colors need a lighter, slightly warmer value in dark mode, or they glare against the background\",\"Shadows need much higher opacity, because a soft shadow disappears on a dark surface\",\"Images and illustrations may need their own dark versions, since tokens can't recolor a photo\"]","numbered",[13,87,89],{"id":88},"two-designs-one-vocabulary","Two designs, one vocabulary",[18,91,92],{},"The point is not that dark mode is twice the work. With semantic tokens, most of it really is automatic. It is that the remaining part, the accents, the depth, the imagery, deserves the same attention as the light theme. People who choose dark mode often use it all day, and they notice when it was an afterthought.",{"title":94,"searchDepth":95,"depth":95,"links":96},"",2,[97,98,102],{"id":15,"depth":95,"text":16},{"id":26,"depth":95,"text":27,"children":99},[100],{"id":76,"depth":101,"text":77},3,{"id":88,"depth":95,"text":89},"design-systems","Design Systems","2026-09-10T00:00:00Z","2026-09-08T00:00:00Z","Inverting colors gives you a dark theme that technically works and looks slightly wrong everywhere. Semantic tokens fix most of it. Shadows and accents need extra care.","md",[110,113],{"question":111,"answer":112},"Should dark mode follow the operating system?","As a default, yes. The theme selector in UI Vintage starts in auto mode and follows the system, but lets people pick light or dark explicitly and remembers the choice.",{"question":114,"answer":115},"Why are dark shadows so much stronger?","Because a shadow needs contrast against the surface behind it. On a dark background, a soft shadow is almost invisible, so the dark theme uses deeper, more opaque values to create the same sense of depth.","\u002Fimages\u002Fblog\u002Fdark-mode-is-a-second-design\u002Fcover.jpg","en",{},true,"\u002Fblog\u002Fdark-mode-is-a-second-design",{"title":5,"description":107},"blog\u002Fdark-mode-is-a-second-design",[104,124,125],"Theming","CSS","2HGVsqUbwWk1OoSNXc3D6uf_TMssndsWLkwc3Vkn1hE",[128,134,139,145],{"title":129,"description":130,"image":131,"categoryText":132,"path":133},"Designing Focus States People Actually Notice","Keyboard users rely on the focus ring to know where they are. Most designs hide it or make it faint. A few small rules make it both visible and good-looking.","\u002Fimages\u002Fblog\u002Ffocus-states-people-notice\u002Fcover.jpg","Accessibility","\u002Fblog\u002Ffocus-states-people-notice",{"title":135,"description":136,"image":137,"categoryText":104,"path":138},"Designing a Reusable Editorial System","How we turned a one-off blog UI into a reusable content surface that still feels intentional once it leaves the original product.","\u002Fimages\u002Fblog\u002Fdesigning-a-reusable-editorial-system\u002Fcover.jpg","\u002Fblog\u002Fdesigning-a-reusable-editorial-system",{"title":140,"description":141,"image":142,"categoryText":143,"path":144},"Shipping the Blog Migration Into the Library","A practical summary of what changed once the original blog implementation was moved into a reusable Nuxt-friendly component library.","\u002Fimages\u002Fblog\u002Fshipping-the-blog-migration\u002Fcover.jpg","Product Updates","\u002Fblog\u002Fshipping-the-blog-migration",{"title":146,"description":147,"image":148,"categoryText":149,"path":150},"Why Spring Animations Feel Faster Than They Are","A spring that overshoots slightly can take longer than a plain fade and still feel quicker. Here is why, and where the trick stops working.","\u002Fimages\u002Fblog\u002Fwhy-spring-animations-feel-faster\u002Fcover.jpg","Motion Design","\u002Fblog\u002Fwhy-spring-animations-feel-faster",[152,155,159,161],{"name":132,"slug":153,"count":154,"image":131},"accessibility",1,{"name":156,"slug":157,"count":154,"image":158},"Engineering","engineering","\u002Fimages\u002Fblog\u002Fsource-published-packages\u002Fcover.jpg",{"name":149,"slug":160,"count":154,"image":148},"motion-design",{"name":143,"slug":162,"count":154,"image":142},"product-updates",1792259222134]