This service tests the validity of an RSS 2.0 feed, checking to see that it follows the rules of the RSS specification. For advice from the RSS Advisory Board on how to implement RSS and handle issues such as enclosures and HTML encoding, read the RSS Best Practices Profile. This checker is also a validator of Atom and RSS 1.0 feeds.

Use this tester regularly to ensure that your RSS feed continues to work well in the wide audience of RSS readers, podcast clients and other software that supports the format.

 

Congratulations!

[Valid RSS] This is a valid RSS feed.

Recommendations

This feed is valid, but interoperability with the widest range of feed readers could be improved by implementing the following recommendations.

  • line 12, column 42: Image not in required format [help]

    <url>https://valticus.pro/images/logo.webp</url>
                                              ^

Source: https://valticus.pro/index.xml

  1. <?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
  2. <channel>
  3. <title>Valticus</title>
  4. <link>https://valticus.pro/</link>
  5. <description>Expert insights on programming, technology, and software development. Discover practical code examples, development tools, and in-depth technical tutorials.Valticus</description>
  6. <generator>Hugo 0.162.1 -- gohugo.io</generator>
  7. <language>en-us</language>
  8. <managingEditor>valticus81@gmail.com (Val Paliy)</managingEditor>
  9. <webMaster>valticus81@gmail.com (Val Paliy)</webMaster>
  10. <lastBuildDate>Wed, 22 Jul 2026 23:22:13 +0000</lastBuildDate>
  11. <image>
  12. <url>https://valticus.pro/images/logo.webp</url>
  13. <title>Valticus</title>
  14. <link>https://valticus.pro/</link>
  15. </image><atom:link href="https://valticus.pro/index.xml" rel="self" type="application/rss+xml"/>
  16. <item>
  17. <title>What I'd Learn If Starting Today: A No-Nonsense Dev Career Roadmap</title>
  18. <link>https://valticus.pro/posts/what-id-learn-if-starting-today-dev-career-advice/</link>
  19. <pubDate>Thu, 16 Jul 2026 00:00:00 +0000</pubDate>
  20. <guid isPermaLink="true">https://valticus.pro/posts/what-id-learn-if-starting-today-dev-career-advice/</guid>
  21. <description>A comprehensive guide on how to start a career in web development in 2026, focusing on fundamentals, the right stack, and avoiding the 'framework trap' based on 20+ years of experience.</description>
  22. <category>Career</category><content:encoded>&lt;h2 id="the-hindsight-of-two-decades"&gt;The Hindsight of Two Decades&lt;/h2&gt;
  23. &lt;p&gt;Twenty years in web development. Hundreds of projects. Dozens of technologies
  24. learned, mastered, and eventually discarded. If I could step into a time machine
  25. and talk to my younger self on day one, my advice wouldn&amp;rsquo;t be about the latest
  26. &amp;ldquo;hot&amp;rdquo; framework or a specific library. It would be about &lt;strong&gt;compound interest in
  27. knowledge&lt;/strong&gt;.&lt;/p&gt;
  28. &lt;p&gt;The industry is noisier than ever. Every week, there&amp;rsquo;s a new &amp;ldquo;game-changing&amp;rdquo;
  29. tool that promises to make you 10x more productive. But here’s the cold truth:
  30. the most successful developers I know aren&amp;rsquo;t the ones who know the most
  31. frameworks; they are the ones who understand the &lt;strong&gt;fundamentals&lt;/strong&gt; so deeply that
  32. they can pick up any framework in a weekend.&lt;/p&gt;
  33. &lt;figure&gt;
  34. &lt;div class="progressive-image"&gt;
  35. &lt;img class="progressive-image__img"
  36. src="https://valticus.pro/images/what-id-learn-if-starting-today-dev-career-advice_hu_119a4b1857525206.webp"
  37. alt="What I&amp;#39;d Learn If Starting Today: A No-Nonsense Dev Career Roadmap."
  38. width="800"
  39. height="436"&gt;
  40. &lt;/div&gt;
  41. &lt;figcaption&gt;&lt;p class="figure__caption"&gt;What I&amp;#39;d Learn If Starting Today: A No-Nonsense Dev Career Roadmap.&lt;/p&gt;&lt;/figcaption&gt;
  42. &lt;/figure&gt;
  43. &lt;p&gt;If I were starting today, this is exactly how I would navigate the path from
  44. absolute beginner to senior engineer.&lt;/p&gt;
  45. &lt;h2 id="phase-1-learn-the-platform-not-the-abstractions"&gt;Phase 1: Learn the Platform, Not the Abstractions&lt;/h2&gt;
  46. &lt;p&gt;The biggest mistake I see juniors make today is the &amp;ldquo;Framework Trap.&amp;rdquo; They learn
  47. &lt;strong&gt;React&lt;/strong&gt; before they understand &lt;strong&gt;JavaScript&lt;/strong&gt;. They learn &lt;strong&gt;Tailwind&lt;/strong&gt; before
  48. they understand &lt;strong&gt;CSS&lt;/strong&gt;. They learn &lt;strong&gt;Next.js&lt;/strong&gt; before they understand how a
  49. basic &lt;strong&gt;HTTP request&lt;/strong&gt; works.&lt;/p&gt;
  50. &lt;p&gt;When you learn an abstraction first, you are building your career on sand. When
  51. that framework inevitably falls out of favor, your skills go with it.&lt;/p&gt;
  52. &lt;h3 id="the-fundamental-learning-stack"&gt;The Fundamental Learning Stack&lt;/h3&gt;
  53. &lt;p&gt;Before you even think about installing a package manager, you must master these
  54. five pillars:&lt;/p&gt;
  55. &lt;ol&gt;
  56. &lt;li&gt;&lt;strong&gt;Semantic HTML&lt;/strong&gt;: Understand the &lt;strong&gt;document object model (DOM)&lt;/strong&gt;,
  57. &lt;strong&gt;accessibility&lt;/strong&gt; (ARIA roles), and why using a &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; is better than a
  58. &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; with an &lt;code&gt;onclick&lt;/code&gt; handler.&lt;/li&gt;
  59. &lt;li&gt;&lt;strong&gt;Modern CSS&lt;/strong&gt;: Forget libraries for a moment. Master the &lt;strong&gt;Box Model&lt;/strong&gt;,
  60. &lt;strong&gt;Flexbox&lt;/strong&gt;, &lt;strong&gt;CSS Grid&lt;/strong&gt;, and &lt;strong&gt;Custom Properties (CSS Variables)&lt;/strong&gt;. If you
  61. can&amp;rsquo;t build a responsive layout with pure CSS, you aren&amp;rsquo;t ready for
  62. &lt;strong&gt;Tailwind&lt;/strong&gt;.&lt;/li&gt;
  63. &lt;li&gt;&lt;strong&gt;Core JavaScript (ES6+)&lt;/strong&gt;: You need to understand closures, prototypes,
  64. &lt;strong&gt;asynchronous programming&lt;/strong&gt; (&lt;code&gt;async/await&lt;/code&gt;), and functional programming
  65. concepts. Learn how the browser actually executes your code.&lt;/li&gt;
  66. &lt;li&gt;&lt;strong&gt;Browser APIs&lt;/strong&gt;: Spend time with the &lt;strong&gt;Fetch API&lt;/strong&gt;, &lt;strong&gt;localStorage&lt;/strong&gt;,
  67. &lt;strong&gt;Intersection Observer&lt;/strong&gt;, and &lt;strong&gt;Web Workers&lt;/strong&gt;. These are the tools the
  68. browser gives you for free.&lt;/li&gt;
  69. &lt;li&gt;&lt;strong&gt;HTTP &amp;amp; Networking&lt;/strong&gt;: Understand status codes, headers, CORS, and the
  70. difference between &lt;strong&gt;REST&lt;/strong&gt; and &lt;strong&gt;GraphQL&lt;/strong&gt;. Knowing &lt;em&gt;how&lt;/em&gt; data moves across
  71. the wire is more important than the library you use to fetch it.&lt;/li&gt;
  72. &lt;/ol&gt;
  73. &lt;blockquote&gt;
  74. &lt;p&gt;&lt;strong&gt;Common Pitfall: Tutorial Hell&lt;/strong&gt; Many beginners fall into the trap of
  75. watching 50-hour courses and following along line-by-line. This gives you a
  76. false sense of competence. You aren&amp;rsquo;t learning to code; you&amp;rsquo;re learning to
  77. transcribe. Break the cycle by building something unique every time you finish
  78. a module.&lt;/p&gt;
  79. &lt;/blockquote&gt;
  80. &lt;h2 id="phase-2-the-first-project-architecture"&gt;Phase 2: The &amp;ldquo;First Project&amp;rdquo; Architecture&lt;/h2&gt;
  81. &lt;p&gt;Once you have the basics, don&amp;rsquo;t build another Todo list. Build something that
  82. solves a real problem. If I were starting today, my first &amp;ldquo;serious&amp;rdquo; project
  83. would be a &lt;strong&gt;Personal Knowledge Base&lt;/strong&gt; or a &lt;strong&gt;Custom CMS&lt;/strong&gt;.&lt;/p&gt;
  84. &lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt; Because it forces you to handle:&lt;/p&gt;
  85. &lt;ul&gt;
  86. &lt;li&gt;&lt;strong&gt;Data Persistence&lt;/strong&gt;: Connecting to a database (SQL or NoSQL).&lt;/li&gt;
  87. &lt;li&gt;&lt;strong&gt;Authentication&lt;/strong&gt;: Implementing secure login and sessions.&lt;/li&gt;
  88. &lt;li&gt;&lt;strong&gt;CRUD Operations&lt;/strong&gt;: Create, Read, Update, Delete.&lt;/li&gt;
  89. &lt;li&gt;&lt;strong&gt;State Management&lt;/strong&gt;: Managing complex data on the frontend.&lt;/li&gt;
  90. &lt;li&gt;&lt;strong&gt;Deployment&lt;/strong&gt;: Getting your code into the real world.&lt;/li&gt;
  91. &lt;/ul&gt;
  92. &lt;h2 id="phase-3-version-control--collaboration"&gt;Phase 3: Version Control &amp;amp; Collaboration&lt;/h2&gt;
  93. &lt;p&gt;I avoided &lt;strong&gt;Git&lt;/strong&gt; for too long in my early years, thinking it was only for
  94. teams. That was a massive mistake. &lt;strong&gt;Git&lt;/strong&gt; isn&amp;rsquo;t just a backup tool; it&amp;rsquo;s a
  95. &lt;strong&gt;time machine&lt;/strong&gt; and a &lt;strong&gt;collaboration engine&lt;/strong&gt;.&lt;/p&gt;
  96. &lt;p&gt;If you want to be a professional, you must be comfortable with the &lt;strong&gt;terminal&lt;/strong&gt;.
  97. Learn how to:&lt;/p&gt;
  98. &lt;ul&gt;
  99. &lt;li&gt;Branch, merge, and handle merge conflicts.&lt;/li&gt;
  100. &lt;li&gt;Write meaningful commit messages (e.g.,
  101. &lt;a href="https://www.conventionalcommits.org/"&gt;Conventional Commits&lt;/a&gt;).&lt;/li&gt;
  102. &lt;li&gt;Perform code reviews on GitHub/GitLab.&lt;/li&gt;
  103. &lt;li&gt;Use &lt;code&gt;git rebase&lt;/code&gt; to keep your history clean.&lt;/li&gt;
  104. &lt;/ul&gt;
  105. &lt;h2 id="phase-4-integrating-ai-the-2026-reality"&gt;Phase 4: Integrating AI (The 2026 Reality)&lt;/h2&gt;
  106. &lt;p&gt;We cannot talk about starting a dev career today without mentioning &lt;strong&gt;AI&lt;/strong&gt;. In
  107. 2026, &lt;strong&gt;AI&lt;/strong&gt; is no longer a luxury; it&amp;rsquo;s a standard part of the workflow.
  108. However, it is a double-edged sword.&lt;/p&gt;
  109. &lt;p&gt;As I&amp;rsquo;ve written about previously, the goal is to use &lt;strong&gt;AI&lt;/strong&gt; as a &lt;strong&gt;copilot&lt;/strong&gt;,
  110. not the captain. If you use &lt;strong&gt;AI&lt;/strong&gt; to write code you don&amp;rsquo;t understand, you
  111. aren&amp;rsquo;t a developer; you&amp;rsquo;re a prompt engineer with a looming technical debt
  112. crisis.&lt;/p&gt;
  113. &lt;blockquote&gt;
  114. &lt;p&gt;&lt;strong&gt;Pro Tip: The 15-Minute Rule&lt;/strong&gt; When you hit a bug, spend exactly 15 minutes
  115. trying to solve it yourself by reading the docs and debugging. If you&amp;rsquo;re still
  116. stuck, use &lt;strong&gt;AI&lt;/strong&gt; to explain the concept, not just give you the fix. This
  117. ensures you&amp;rsquo;re still growing your &amp;ldquo;mental muscle.&amp;rdquo;&lt;/p&gt;
  118. &lt;/blockquote&gt;
  119. &lt;h2 id="the-career-roadmap-from-junior-to-lead"&gt;The Career Roadmap: From Junior to Lead&lt;/h2&gt;
  120. &lt;p&gt;Success in this industry isn&amp;rsquo;t just about code. It&amp;rsquo;s about how your
  121. responsibilities shift as you grow.&lt;/p&gt;
  122. &lt;table&gt;
  123. &lt;thead&gt;
  124. &lt;tr&gt;
  125. &lt;th style="text-align: left"&gt;Level&lt;/th&gt;
  126. &lt;th style="text-align: left"&gt;Primary Focus&lt;/th&gt;
  127. &lt;th style="text-align: left"&gt;Key Skill to Master&lt;/th&gt;
  128. &lt;th style="text-align: left"&gt;Output&lt;/th&gt;
  129. &lt;/tr&gt;
  130. &lt;/thead&gt;
  131. &lt;tbody&gt;
  132. &lt;tr&gt;
  133. &lt;td style="text-align: left"&gt;&lt;strong&gt;Junior&lt;/strong&gt;&lt;/td&gt;
  134. &lt;td style="text-align: left"&gt;Syntax &amp;amp; Implementation&lt;/td&gt;
  135. &lt;td style="text-align: left"&gt;Reading Documentation&lt;/td&gt;
  136. &lt;td style="text-align: left"&gt;Working code that follows instructions.&lt;/td&gt;
  137. &lt;/tr&gt;
  138. &lt;tr&gt;
  139. &lt;td style="text-align: left"&gt;&lt;strong&gt;Mid-Level&lt;/strong&gt;&lt;/td&gt;
  140. &lt;td style="text-align: left"&gt;Architecture &amp;amp; Patterns&lt;/td&gt;
  141. &lt;td style="text-align: left"&gt;Testing &amp;amp; Maintainability&lt;/td&gt;
  142. &lt;td style="text-align: left"&gt;Scalable features with minimal bugs.&lt;/td&gt;
  143. &lt;/tr&gt;
  144. &lt;tr&gt;
  145. &lt;td style="text-align: left"&gt;&lt;strong&gt;Senior&lt;/strong&gt;&lt;/td&gt;
  146. &lt;td style="text-align: left"&gt;Problem Solving &amp;amp; Systems&lt;/td&gt;
  147. &lt;td style="text-align: left"&gt;Communication &amp;amp; Mentorship&lt;/td&gt;
  148. &lt;td style="text-align: left"&gt;Technical direction and team productivity.&lt;/td&gt;
  149. &lt;/tr&gt;
  150. &lt;tr&gt;
  151. &lt;td style="text-align: left"&gt;&lt;strong&gt;Lead&lt;/strong&gt;&lt;/td&gt;
  152. &lt;td style="text-align: left"&gt;Business Value &amp;amp; Strategy&lt;/td&gt;
  153. &lt;td style="text-align: left"&gt;Decision Making&lt;/td&gt;
  154. &lt;td style="text-align: left"&gt;High-impact architectural and organizational changes.&lt;/td&gt;
  155. &lt;/tr&gt;
  156. &lt;/tbody&gt;
  157. &lt;/table&gt;
  158. &lt;h2 id="the-business-of-code"&gt;The Business of Code&lt;/h2&gt;
  159. &lt;p&gt;This is the lesson that took me a decade to truly internalize: &lt;strong&gt;Code is a
  160. liability, not an asset.&lt;/strong&gt;&lt;/p&gt;
  161. &lt;p&gt;Companies don&amp;rsquo;t pay you to write code; they pay you to solve problems. Sometimes
  162. the best solution to a problem is &lt;em&gt;not&lt;/em&gt; writing code at all. Understanding the
  163. business context of your work—how it makes money, how it saves time, or how it
  164. reduces risk—will make you ten times more valuable than the best &amp;ldquo;pure&amp;rdquo; coder.&lt;/p&gt;
  165. &lt;h2 id="soft-skills-the-secret-weapon"&gt;Soft Skills: The &amp;ldquo;Secret&amp;rdquo; Weapon&lt;/h2&gt;
  166. &lt;p&gt;Technical skills get you the interview. &lt;strong&gt;Soft Skills&lt;/strong&gt; get you the job and the
  167. promotion. In a world where &lt;strong&gt;AI&lt;/strong&gt; can write a boilerplate &lt;strong&gt;React&lt;/strong&gt; component
  168. in seconds, your ability to &lt;strong&gt;communicate&lt;/strong&gt;, &lt;strong&gt;empathize&lt;/strong&gt;, and &lt;strong&gt;negotiate&lt;/strong&gt; is
  169. your moat.&lt;/p&gt;
  170. &lt;ul&gt;
  171. &lt;li&gt;&lt;strong&gt;Writing&lt;/strong&gt;: Can you explain a complex bug in a Jira ticket? Can you write a
  172. clear README?&lt;/li&gt;
  173. &lt;li&gt;&lt;strong&gt;Public Speaking&lt;/strong&gt;: Can you demo your work to stakeholders?&lt;/li&gt;
  174. &lt;li&gt;&lt;strong&gt;Empathy&lt;/strong&gt;: Can you understand why a designer is frustrated with your
  175. implementation?&lt;/li&gt;
  176. &lt;li&gt;&lt;strong&gt;Reliability&lt;/strong&gt;: Do you do what you say you&amp;rsquo;re going to do?&lt;/li&gt;
  177. &lt;/ul&gt;
  178. &lt;h2 id="dont-chase-trends"&gt;Don&amp;rsquo;t Chase Trends&lt;/h2&gt;
  179. &lt;p&gt;I&amp;rsquo;ve watched jQuery, Backbone, Angular, and countless others rise and fall. If
  180. you chase every trend, you will burn out.&lt;/p&gt;
  181. &lt;p&gt;Instead, adopt the &lt;strong&gt;80/20 Rule for Learning&lt;/strong&gt;:&lt;/p&gt;
  182. &lt;ul&gt;
  183. &lt;li&gt;Spend &lt;strong&gt;80%&lt;/strong&gt; of your time mastering established, &amp;ldquo;boring&amp;rdquo; technologies
  184. (&lt;strong&gt;SQL&lt;/strong&gt;, &lt;strong&gt;Bash&lt;/strong&gt;, &lt;strong&gt;vanilla JS&lt;/strong&gt;, &lt;strong&gt;CSS&lt;/strong&gt;, &lt;strong&gt;Docker&lt;/strong&gt;).&lt;/li&gt;
  185. &lt;li&gt;Spend &lt;strong&gt;20%&lt;/strong&gt; of your time playing with the new shiny stuff (new frameworks,
  186. &lt;strong&gt;AI&lt;/strong&gt; agents, etc.).&lt;/li&gt;
  187. &lt;/ul&gt;
  188. &lt;h2 id="the-advice-i-wish-id-followed"&gt;The Advice I Wish I&amp;rsquo;d Followed&lt;/h2&gt;
  189. &lt;ol&gt;
  190. &lt;li&gt;&lt;strong&gt;Write about what you learn&lt;/strong&gt;: Teaching is the highest form of learning.
  191. Start a blog on day one.&lt;/li&gt;
  192. &lt;li&gt;&lt;strong&gt;Contribute to Open Source&lt;/strong&gt;: Don&amp;rsquo;t start with code. Start with
  193. documentation or fixing typos. It teaches you how professional repositories
  194. are managed.&lt;/li&gt;
  195. &lt;li&gt;&lt;strong&gt;Take care of your health&lt;/strong&gt;: This is a sedentary job. If you don&amp;rsquo;t schedule
  196. time for movement, your back and wrists will remind you in ten years.&lt;/li&gt;
  197. &lt;li&gt;&lt;strong&gt;Save your &amp;ldquo;F-you&amp;rdquo; money&lt;/strong&gt;: Freelancing and tech jobs can be volatile.
  198. Having a financial buffer gives you the freedom to say &amp;ldquo;no&amp;rdquo; to toxic
  199. projects.&lt;/li&gt;
  200. &lt;/ol&gt;
  201. &lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
  202. &lt;p&gt;If you&amp;rsquo;re starting today, the mountain might look insurmountable. The stack is
  203. taller, the competition is global, and the tools are more complex. But the
  204. reward for those who focus on the &lt;strong&gt;fundamentals&lt;/strong&gt; remains higher than ever.&lt;/p&gt;
  205. &lt;p&gt;The specific technologies will change—they always do. But the ability to learn,
  206. solve problems, and communicate effectively will serve you for decades. Stop
  207. looking for the perfect tutorial and start building something that breaks.
  208. That’s where the real learning happens.&lt;/p&gt;
  209. &lt;p&gt;The best time to start was twenty years ago. The second best time is now. &lt;strong&gt;Get
  210. to work.&lt;/strong&gt;&lt;/p&gt;
  211. </content:encoded>
  212. <dc:creator>Val Paliy</dc:creator>
  213. </item>
  214. <item>
  215. <title>Quora: The Knowledge-Sharing Platform That Still Matters</title>
  216. <link>https://valticus.pro/posts/quora-the-knowledge-sharing-platform/</link>
  217. <pubDate>Tue, 14 Jul 2026 00:00:00 +0000</pubDate>
  218. <guid isPermaLink="true">https://valticus.pro/posts/quora-the-knowledge-sharing-platform/</guid>
  219. <description>Discover why Quora remains a valuable resource for knowledge sharing, how to leverage it for learning and growth, and why it's still relevant in 2026.</description>
  220. <category>Technology</category><content:encoded>&lt;p&gt;In an era dominated by short-form video and algorithmic feeds, Quora stands as a
  221. beacon for those who crave in-depth knowledge and thoughtful discussion. Founded
  222. in 2009 by former Facebook employees Adam D&amp;rsquo;Angelo and Charlie Cheever, Quora
  223. has evolved into one of the internet&amp;rsquo;s most comprehensive Q&amp;amp;A platforms.&lt;/p&gt;
  224. &lt;h2 id="what-makes-quora-special"&gt;What Makes Quora Special?&lt;/h2&gt;
  225. &lt;p&gt;Quora&amp;rsquo;s strength lies in its commitment to quality answers. Unlike social media
  226. platforms optimized for engagement, Quora prioritizes expertise and depth. Users
  227. can ask questions on virtually any topic—from programming and science to
  228. philosophy and personal development—and receive answers from knowledgeable
  229. contributors, including verified experts and industry professionals.&lt;/p&gt;
  230. &lt;p&gt;The platform&amp;rsquo;s upvote system ensures that the most helpful answers rise to the
  231. top, creating a self-curated knowledge base that grows richer over time. For
  232. developers and tech enthusiasts, Quora offers invaluable insights into career
  233. advice, coding challenges, and industry trends.&lt;/p&gt;
  234. &lt;h2 id="quora-for-learning-and-growth"&gt;Quora for Learning and Growth&lt;/h2&gt;
  235. &lt;p&gt;One of Quora&amp;rsquo;s most underappreciated features is its potential for continuous
  236. learning. By following topics aligned with your interests, you create a
  237. personalized feed of high-quality content. Whether you&amp;rsquo;re exploring new
  238. programming languages, understanding system design patterns, or diving into
  239. business strategy, Quora provides diverse perspectives that textbooks simply
  240. can&amp;rsquo;t match.&lt;/p&gt;
  241. &lt;p&gt;The platform also allows you to build a presence by sharing your expertise. If
  242. you have deep knowledge in a particular area, answering questions on Quora can
  243. establish you as a thought leader while helping others.&lt;/p&gt;
  244. &lt;h2 id="my-quora-journey"&gt;My Quora Journey&lt;/h2&gt;
  245. &lt;p&gt;I&amp;rsquo;ve found Quora to be an excellent space for sharing thoughts on technology,
  246. development practices, and the broader tech landscape. You can follow my
  247. contributions and explore the topics I cover on my
  248. &lt;a href="https://valticus.quora.com/"&gt;Quora blog&lt;/a&gt;.&lt;/p&gt;
  249. &lt;h2 id="why-quora-still-matters-in-2026"&gt;Why Quora Still Matters in 2026&lt;/h2&gt;
  250. &lt;p&gt;Despite the rise of AI-generated answers and social media alternatives, Quora
  251. remains relevant because it fosters genuine human expertise. The platform&amp;rsquo;s
  252. evolution—including Quora+ and Spaces—has added new dimensions to content
  253. creation and community building while maintaining its core mission of sharing
  254. knowledge.&lt;/p&gt;
  255. &lt;p&gt;For anyone serious about learning, growing their expertise, or connecting with
  256. like-minded professionals, Quora deserves a place in your digital toolkit.&lt;/p&gt;
  257. </content:encoded>
  258. <dc:creator>Val Paliy</dc:creator>
  259. </item>
  260. <item>
  261. <title>Minimalist Development Workflow: My Experience and Insights</title>
  262. <link>https://valticus.pro/posts/minimalist-development-workflow-my-experience-and-insights/</link>
  263. <pubDate>Mon, 13 Jul 2026 00:00:00 +0000</pubDate>
  264. <guid isPermaLink="true">https://valticus.pro/posts/minimalist-development-workflow-my-experience-and-insights/</guid>
  265. <description>A personal account of adopting a minimalist approach to development workflows, exploring the benefits, challenges, and practical strategies for reducing complexity without sacrificing productivity.</description>
  266. <category>Web Development</category><content:encoded>&lt;p&gt;After twenty years in web development, I&amp;rsquo;ve realized that the most dangerous
  267. thing in our industry isn&amp;rsquo;t a security vulnerability or a system outage—it&amp;rsquo;s
  268. &lt;strong&gt;creeping complexity&lt;/strong&gt;. We are conditioned to believe that a more sophisticated
  269. setup equals a more professional output. We stack layers of abstraction until we
  270. can no longer see the foundation of our own applications.&lt;/p&gt;
  271. &lt;p&gt;I spent the first decade of my career as a &amp;ldquo;maximalist.&amp;rdquo; I wanted the flashiest
  272. IDE, the most complex build pipelines, and the latest alpha-version frameworks.
  273. But eventually, the weight of that tooling became a burden. I was spending 40%
  274. of my time fighting my environment rather than shipping code.&lt;/p&gt;
  275. &lt;figure&gt;
  276. &lt;div class="progressive-image"&gt;
  277. &lt;img class="progressive-image__img"
  278. src="https://valticus.pro/images/minimalist-development-workflow-my-experience-and-insights_hu_44c6f909c36cf879.webp"
  279. alt="Minimalist Development Workflow: My Experience and Insights."
  280. width="800"
  281. height="436"&gt;
  282. &lt;/div&gt;
  283. &lt;figcaption&gt;&lt;p class="figure__caption"&gt;Minimalist Development Workflow: My Experience and Insights.&lt;/p&gt;&lt;/figcaption&gt;
  284. &lt;/figure&gt;
  285. &lt;p&gt;Now? I pride myself on how little I need to get the job done. This is my journey
  286. toward a &lt;strong&gt;Minimalist Development Workflow&lt;/strong&gt;.&lt;/p&gt;
  287. &lt;h2 id="the-breaking-point-complexity-debt"&gt;The Breaking Point: Complexity Debt&lt;/h2&gt;
  288. &lt;p&gt;The realization hit me during a routine update. A simple project with a dozen
  289. pages required a &lt;code&gt;npm install&lt;/code&gt; that downloaded 800MB of dependencies and
  290. triggered three different security warnings in libraries I didn&amp;rsquo;t even know I
  291. was using.&lt;/p&gt;
  292. &lt;p&gt;My &amp;ldquo;productivity&amp;rdquo; had become a facade. I was paying &lt;strong&gt;Complexity Debt&lt;/strong&gt; every
  293. single day:&lt;/p&gt;
  294. &lt;ul&gt;
  295. &lt;li&gt;&lt;strong&gt;Build Times&lt;/strong&gt;: Waiting 60 seconds for a &amp;ldquo;hot reload&amp;rdquo; of a CSS change.&lt;/li&gt;
  296. &lt;li&gt;&lt;strong&gt;Onboarding&lt;/strong&gt;: Taking two days to explain the environment to a new developer.&lt;/li&gt;
  297. &lt;li&gt;&lt;strong&gt;Maintenance&lt;/strong&gt;: Spending weekends fixing breaking changes in a framework that
  298. I didn&amp;rsquo;t really need.&lt;/li&gt;
  299. &lt;/ul&gt;
  300. &lt;p&gt;I decided to burn it down and start from the fundamentals.&lt;/p&gt;
  301. &lt;h2 id="the-boring-technology-philosophy"&gt;The &amp;ldquo;Boring Technology&amp;rdquo; Philosophy&lt;/h2&gt;
  302. &lt;p&gt;I adopted the &amp;ldquo;&lt;strong&gt;Boring Technology&lt;/strong&gt;&amp;rdquo; mindset. Boring technology is reliable.
  303. Its edge cases are known. It doesn&amp;rsquo;t change its API every six months. For a
  304. minimalist workflow, boring is beautiful.&lt;/p&gt;
  305. &lt;h3 id="what-i-kept-the-essentials"&gt;What I Kept (The Essentials)&lt;/h3&gt;
  306. &lt;ol&gt;
  307. &lt;li&gt;&lt;strong&gt;The Editor&lt;/strong&gt;: VS Code, but stripped to the bone. No &amp;ldquo;AI Autocomplete&amp;rdquo; that
  308. guesses wrong 40% of the time. No 15-extension &amp;ldquo;Pack for React Developers.&amp;rdquo;
  309. Just a good mono font, a fast terminal, and built-in Git support.&lt;/li&gt;
  310. &lt;li&gt;&lt;strong&gt;The Stack&lt;/strong&gt;: Whenever possible, I return to the &amp;ldquo;Holy Trinity&amp;rdquo;: &lt;strong&gt;Semantic
  311. HTML&lt;/strong&gt;, &lt;strong&gt;Modern CSS&lt;/strong&gt;, and &lt;strong&gt;Vanilla JavaScript&lt;/strong&gt;.&lt;/li&gt;
  312. &lt;li&gt;&lt;strong&gt;The Static Engine&lt;/strong&gt;: I use &lt;strong&gt;Hugo&lt;/strong&gt; for almost everything. It&amp;rsquo;s a single
  313. binary, it&amp;rsquo;s written in &lt;strong&gt;Go&lt;/strong&gt;, and it builds 5,000 pages in under a second.
  314. No &lt;code&gt;node_modules&lt;/code&gt; required for the core engine.&lt;/li&gt;
  315. &lt;/ol&gt;
  316. &lt;h2 id="replacing-complex-tools-with-simple-scripts"&gt;Replacing Complex Tools with Simple Scripts&lt;/h2&gt;
  317. &lt;p&gt;The biggest win in my minimalist transition was replacing &amp;ldquo;Task Runners&amp;rdquo; (Gulp,
  318. Grunt, and even complex npm scripts) with a tool that has been around since
  319. 1976: &lt;strong&gt;The Makefile&lt;/strong&gt;.&lt;/p&gt;
  320. &lt;p&gt;A &lt;code&gt;Makefile&lt;/code&gt; is transparent, fast, and doesn&amp;rsquo;t require a runtime. It serves as
  321. the &amp;ldquo;source of truth&amp;rdquo; for how to build and deploy your project.&lt;/p&gt;
  322. &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-makefile" &gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# Minimalist Development Workflow Makefile
  323. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;.PHONY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;help&lt;/span&gt; &lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt; &lt;span class="n"&gt;deploy&lt;/span&gt; &lt;span class="n"&gt;clean&lt;/span&gt;
  324. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
  325. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;help&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="c"&gt;## Show this help message
  326. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; @grep -E &lt;span class="s1"&gt;&amp;#39;^[a-zA-Z_-]+:.*?## .*$$&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;$(&lt;/span&gt;MAKEFILE_LIST&lt;span class="k"&gt;)&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sort &lt;span class="p"&gt;|&lt;/span&gt; awk &lt;span class="s1"&gt;&amp;#39;BEGIN {FS = &amp;#34;:.*?## &amp;#34;}; {printf &amp;#34;\033[36m%-15s\033[0m %s\n&amp;#34;, $$1, $$2}&amp;#39;&lt;/span&gt;
  327. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
  328. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;dev&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="c"&gt;## Start Hugo development server
  329. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; hugo server -D -E -F --minify
  330. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
  331. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="c"&gt;## Build the production site
  332. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; rm -rf public
  333. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; hugo --gc --minify
  334. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
  335. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;deploy&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt; &lt;span class="c"&gt;## Deploy to production via Netlify
  336. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; npx netlify-cli deploy --prod --dir&lt;span class="o"&gt;=&lt;/span&gt;public
  337. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
  338. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;clean&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="c"&gt;## Remove build artifacts
  339. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; rm -rf public resources
  340. &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;By using this, I don&amp;rsquo;t need to remember 20 different CLI flags. I just type
  341. &lt;code&gt;make dev&lt;/code&gt; or &lt;code&gt;make deploy&lt;/code&gt;. It&amp;rsquo;s portable, version-controlled, and requires
  342. zero configuration on a new machine.&lt;/p&gt;
  343. &lt;h2 id="what-i-dropped-and-why"&gt;What I Dropped (And Why)&lt;/h2&gt;
  344. &lt;h3 id="1-the-big-three-frameworks"&gt;1. The &amp;ldquo;Big Three&amp;rdquo; Frameworks&lt;/h3&gt;
  345. &lt;p&gt;Unless I&amp;rsquo;m building a highly dynamic, state-heavy dashboard, I don&amp;rsquo;t use React,
  346. Vue, or Angular. Most websites are content, and content doesn&amp;rsquo;t need a &lt;strong&gt;virtual
  347. DOM&lt;/strong&gt;. It needs a fast server and a browser.&lt;/p&gt;
  348. &lt;h3 id="2-utility-first-css-frameworks"&gt;2. Utility-First CSS Frameworks&lt;/h3&gt;
  349. &lt;p&gt;While I appreciate the speed of Tailwind, I&amp;rsquo;ve returned to &lt;strong&gt;Vanilla CSS with
  350. Custom Properties&lt;/strong&gt;. Modern CSS (&lt;strong&gt;Grid&lt;/strong&gt;, &lt;strong&gt;Flexbox&lt;/strong&gt;, &lt;strong&gt;Containers&lt;/strong&gt;) has made
  351. frameworks largely redundant for those who actually know the language.&lt;/p&gt;
  352. &lt;h3 id="3-heavy-ides"&gt;3. &amp;ldquo;Heavy&amp;rdquo; IDES&lt;/h3&gt;
  353. &lt;p&gt;I moved away from heavy, RAM-hungry IDEs. If I can&amp;rsquo;t run my development
  354. environment on a 5-year-old laptop without the fans spinning up, my workflow is
  355. too heavy. This ties back to my philosophy on digital minimalism for developers,
  356. where I discuss the mental impact of digital clutter.&lt;/p&gt;
  357. &lt;blockquote&gt;
  358. &lt;h3 id="-common-pitfall-not-invented-here-nih"&gt;🚩 Common Pitfall: &amp;ldquo;Not Invented Here&amp;rdquo; (NIH)&lt;/h3&gt;
  359. &lt;p&gt;Minimalists often fall into the trap of wanting to build everything from
  360. scratch. This can lead to its own kind of complexity. The goal isn&amp;rsquo;t to write
  361. your own database; it&amp;rsquo;s to avoid installing a database when a JSON file will
  362. do.&lt;/p&gt;
  363. &lt;/blockquote&gt;
  364. &lt;h2 id="the-minimalist-project-checklist"&gt;The Minimalist Project Checklist&lt;/h2&gt;
  365. &lt;p&gt;Before starting a new project, I run it through this &amp;ldquo;Pruning Filter&amp;rdquo;:&lt;/p&gt;
  366. &lt;ul&gt;
  367. &lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;strong&gt;Can this be static?&lt;/strong&gt; If yes, no server-side code.&lt;/li&gt;
  368. &lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;strong&gt;Does it need JS?&lt;/strong&gt; If the interaction can be done with HTML/CSS (like a
  369. toggle menu), skip the JS.&lt;/li&gt;
  370. &lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;strong&gt;Single Binary Rule&lt;/strong&gt;: Can I build this using only tools that are single
  371. binaries (like Hugo, Go, or Rust tools)?&lt;/li&gt;
  372. &lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;strong&gt;Zero-Config Onboarding&lt;/strong&gt;: Can a developer clone this and run it with one
  373. command (e.g., &lt;code&gt;make dev&lt;/code&gt;)?&lt;/li&gt;
  374. &lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;strong&gt;No-Build CSS&lt;/strong&gt;: Can I use standard CSS files without a pre-processor?&lt;/li&gt;
  375. &lt;/ul&gt;
  376. &lt;h2 id="the-benefits-of-less"&gt;The Benefits of Less&lt;/h2&gt;
  377. &lt;h3 id="instant-context-re-entry"&gt;Instant Context Re-entry&lt;/h3&gt;
  378. &lt;p&gt;When I return to a project after six months, I don&amp;rsquo;t have to spend an hour
  379. updating dependencies or remembering how the &amp;ldquo;Magic Build Tool&amp;rdquo; works. The code
  380. is just code.&lt;/p&gt;
  381. &lt;h3 id="faster-feedback-loops"&gt;Faster Feedback Loops&lt;/h3&gt;
  382. &lt;p&gt;My build time is usually under 500ms. This instant feedback allows me to enter a
  383. &lt;strong&gt;Flow State&lt;/strong&gt; that is impossible when you&amp;rsquo;re constantly waiting for a
  384. transpiler to finish.&lt;/p&gt;
  385. &lt;h3 id="improved-security"&gt;Improved Security&lt;/h3&gt;
  386. &lt;p&gt;Every dependency you &lt;em&gt;don&amp;rsquo;t&lt;/em&gt; install is a &lt;strong&gt;supply-chain attack&lt;/strong&gt; that &lt;em&gt;can&amp;rsquo;t&lt;/em&gt;
  387. happen to you. Minimalism is the ultimate security architecture.&lt;/p&gt;
  388. &lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
  389. &lt;p&gt;A minimalist workflow isn&amp;rsquo;t about being a Luddite or hating progress. It&amp;rsquo;s about
  390. &lt;strong&gt;respecting your own time&lt;/strong&gt;. It&amp;rsquo;s about choosing tools that serve you, rather
  391. than tools that require you to serve them.&lt;/p&gt;
  392. &lt;p&gt;By stripping away the noise, you reveal the signal. You&amp;rsquo;ll find that you write
  393. better code, understand your systems deeper, and—most importantly—you&amp;rsquo;ll spend
  394. more time solving real problems and less time tweaking your configuration files.&lt;/p&gt;
  395. &lt;p&gt;&lt;strong&gt;Take a look at your current project. What is the one dependency you could
  396. remove today and still deliver the same value? Try it.&lt;/strong&gt;&lt;/p&gt;
  397. </content:encoded>
  398. <dc:creator>Val Paliy</dc:creator>
  399. </item>
  400. <item>
  401. <title>Why Frameworks Are Overused (And How to Avoid It)</title>
  402. <link>https://valticus.pro/posts/why-frameworks-are-overused-and-how-to-avoid-it/</link>
  403. <pubDate>Thu, 09 Jul 2026 00:00:00 +0000</pubDate>
  404. <guid isPermaLink="true">https://valticus.pro/posts/why-frameworks-are-overused-and-how-to-avoid-it/</guid>
  405. <description>A critical look at the 'Framework-First' mentality in modern web development. Learn when to reach for a library and when to stick to the fundamentals for better performance and maintainability.</description>
  406. <category>Web Development</category><content:encoded>&lt;h2 id="the-framework-first-fallacy"&gt;The Framework-First Fallacy&lt;/h2&gt;
  407. &lt;p&gt;In the landscape of 2026, the default response to almost any web development
  408. project is to start with a framework. Need a personal landing page? Reach for
  409. Next.js. Building a simple data dashboard? Boot up a React template. Creating a
  410. documentation site? Gatsby or Nuxt is the presumed choice.&lt;/p&gt;
  411. &lt;p&gt;We have reached a point where many developers—especially those who entered the
  412. industry in the last five years—literally cannot build a website without first
  413. installing a framework. This isn&amp;rsquo;t just a shift in preference; it&amp;rsquo;s a
  414. &lt;strong&gt;Framework-First Fallacy&lt;/strong&gt; that prioritizes the developer&amp;rsquo;s comfort over the
  415. user&amp;rsquo;s experience and the project&amp;rsquo;s long-term health.&lt;/p&gt;
  416. &lt;figure&gt;
  417. &lt;div class="progressive-image"&gt;
  418. &lt;img class="progressive-image__img"
  419. src="https://valticus.pro/images/why-frameworks-are-overused-and-how-to-avoid-it_hu_eae461301fe9faf6.webp"
  420. alt="Why Frameworks Are Overused (And How to Avoid It)."
  421. width="800"
  422. height="436"&gt;
  423. &lt;/div&gt;
  424. &lt;figcaption&gt;&lt;p class="figure__caption"&gt;Why Frameworks Are Overused (And How to Avoid It).&lt;/p&gt;&lt;/figcaption&gt;
  425. &lt;/figure&gt;
  426. &lt;h2 id="the-hidden-costs-of-abstraction"&gt;The Hidden Costs of Abstraction&lt;/h2&gt;
  427. &lt;p&gt;While frameworks promise speed and consistency, they come with a significant
  428. &amp;ldquo;&lt;strong&gt;Abstraction Tax&lt;/strong&gt;&amp;rdquo; that is rarely discussed in the hype-filled world of tech
  429. social media and YouTube tutorials.&lt;/p&gt;
  430. &lt;h3 id="1-the-bundle-size-reality-check"&gt;1. The Bundle Size Reality Check&lt;/h3&gt;
  431. &lt;p&gt;Let&amp;rsquo;s look at the math for a &amp;ldquo;simple&amp;rdquo; interactive site in 2026. If you use a
  432. modern meta-framework, your baseline might look like this:&lt;/p&gt;
  433. &lt;ul&gt;
  434. &lt;li&gt;&lt;strong&gt;Framework Core (React/Vue/Angular):&lt;/strong&gt; ~45KB - 130KB &lt;strong&gt;gzipped&lt;/strong&gt;&lt;/li&gt;
  435. &lt;li&gt;&lt;strong&gt;Hydration Logic:&lt;/strong&gt; ~20KB - 50KB&lt;/li&gt;
  436. &lt;li&gt;&lt;strong&gt;Routing &amp;amp; State Management:&lt;/strong&gt; ~30KB&lt;/li&gt;
  437. &lt;li&gt;&lt;strong&gt;UI Component Library (Radix, HeadlessUI, etc.):&lt;/strong&gt; ~40KB&lt;/li&gt;
  438. &lt;li&gt;&lt;strong&gt;Your Actual Business Logic:&lt;/strong&gt; ~15KB&lt;/li&gt;
  439. &lt;/ul&gt;
  440. &lt;p&gt;In this scenario, you are shipping nearly 300KB of JavaScript to the user just
  441. to deliver 15KB of unique functionality. On a high-speed fiber connection, this
  442. might feel negligible. But on a spotty 4G connection or an entry-level mobile
  443. device, that 300KB represents a multi-second delay in &lt;strong&gt;Time to Interactive
  444. (TTI)&lt;/strong&gt;. We are essentially forcing the user to download and execute a massive
  445. engine just to move a few pixels.&lt;/p&gt;
  446. &lt;h3 id="2-the-learning-curve-trap"&gt;2. The Learning Curve Trap&lt;/h3&gt;
  447. &lt;p&gt;Frameworks don&amp;rsquo;t just require you to learn JavaScript; they require you to learn
  448. a dialect of it. You aren&amp;rsquo;t just learning how to manipulate the DOM; you&amp;rsquo;re
  449. learning about &amp;ldquo;&lt;strong&gt;Hooks&lt;/strong&gt;,&amp;rdquo; &amp;ldquo;&lt;strong&gt;Signals&lt;/strong&gt;,&amp;rdquo; &amp;ldquo;&lt;strong&gt;Observables&lt;/strong&gt;,&amp;rdquo; or &amp;ldquo;&lt;strong&gt;Virtual
  450. DOM&lt;/strong&gt; reconciliation.&amp;rdquo;&lt;/p&gt;
  451. &lt;p&gt;By the time a developer masters the specific idioms of Framework A, Framework B
  452. has been released with a &amp;ldquo;revolutionary&amp;rdquo; new paradigm that makes Framework A
  453. look antiquated. This creates a cycle of &lt;strong&gt;Perpetual Relearning&lt;/strong&gt; that steals
  454. time away from mastering the fundamental technologies (HTML, CSS, &lt;strong&gt;Browser
  455. APIs&lt;/strong&gt;) that have remained stable for decades.&lt;/p&gt;
  456. &lt;h3 id="3-dependency-hell-and-maintenance-rot"&gt;3. Dependency Hell and Maintenance Rot&lt;/h3&gt;
  457. &lt;p&gt;Modern framework projects don&amp;rsquo;t just have dependencies; they have ecosystems. A
  458. simple &lt;code&gt;npm install&lt;/code&gt; today can result in 2,000+ folders in your
  459. &lt;strong&gt;&lt;code&gt;node_modules&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;
  460. &lt;p&gt;This creates a massive surface area for:&lt;/p&gt;
  461. &lt;ul&gt;
  462. &lt;li&gt;&lt;strong&gt;Security Vulnerabilities&lt;/strong&gt;: Every transitive dependency is a potential entry
  463. point.&lt;/li&gt;
  464. &lt;li&gt;&lt;strong&gt;Breaking Changes&lt;/strong&gt;: A minor update in a sub-dependency can break your entire
  465. build pipeline.&lt;/li&gt;
  466. &lt;li&gt;&lt;strong&gt;Maintenance Rot&lt;/strong&gt;: Try opening a framework project from three years ago and
  467. running it. The odds of it &amp;ldquo;just working&amp;rdquo; are near zero.&lt;/li&gt;
  468. &lt;/ul&gt;
  469. &lt;h2 id="the-framework-necessity-test"&gt;The Framework Necessity Test&lt;/h2&gt;
  470. &lt;p&gt;Before you run &lt;code&gt;npx create-...&lt;/code&gt;, put your project through this checklist. If you
  471. can&amp;rsquo;t check at least three boxes, you probably don&amp;rsquo;t need a framework.&lt;/p&gt;
  472. &lt;ul&gt;
  473. &lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Does the application have highly dynamic, synchronized state across
  474. multiple UI components?&lt;/li&gt;
  475. &lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Is the project being built by a team of 10+ developers who need strict
  476. architectural guardrails?&lt;/li&gt;
  477. &lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Does the UI require complex, real-time updates (e.g., a collaborative
  478. editor or a high-frequency trading dashboard)?&lt;/li&gt;
  479. &lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Are you building a &amp;ldquo;&lt;strong&gt;Single Page Application&lt;/strong&gt;&amp;rdquo; (&lt;strong&gt;SPA&lt;/strong&gt;) where
  480. navigation must happen without full page reloads for a specific UX reason?&lt;/li&gt;
  481. &lt;li&gt;&lt;input disabled="" type="checkbox"&gt; Do you need to leverage a specific, massive ecosystem of pre-built
  482. components that would take months to build from scratch?&lt;/li&gt;
  483. &lt;/ul&gt;
  484. &lt;h2 id="comparison-vanilla-vs-framework-the-modal-example"&gt;Comparison: Vanilla vs. Framework (The Modal Example)&lt;/h2&gt;
  485. &lt;p&gt;To illustrate the point, let&amp;rsquo;s look at how we might build a simple modal.&lt;/p&gt;
  486. &lt;p&gt;&lt;strong&gt;The &amp;ldquo;Modern Framework&amp;rdquo; Way:&lt;/strong&gt; You import a Modal component, a Portal, a State
  487. hook, and probably an animation library. You write 50 lines of code, but you&amp;rsquo;ve
  488. added 4 dependencies and 80KB to your bundle.&lt;/p&gt;
  489. &lt;p&gt;&lt;strong&gt;The &amp;ldquo;Platform&amp;rdquo; Way (Vanilla JS):&lt;/strong&gt;&lt;/p&gt;
  490. &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" &gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// A modal in 2026 using the native &amp;lt;dialog&amp;gt; element
  491. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;modal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;#myModal&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  492. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;openBtn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;#openModal&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  493. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;closeBtn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;#closeModal&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  494. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
  495. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;openBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;click&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;modal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;showModal&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  496. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;closeBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;click&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;modal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;close&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  497. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
  498. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Simple, performant, and requires ZERO dependencies.
  499. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;By using the
  500. &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog"&gt;native &lt;strong&gt;&lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt; element&lt;/strong&gt;&lt;/a&gt;,
  501. you get accessibility (focus trapping, ESC key to close) for free, with zero
  502. bundle size impact.&lt;/p&gt;
  503. &lt;h2 id="the-progressive-enhancement-approach"&gt;The Progressive Enhancement Approach&lt;/h2&gt;
  504. &lt;p&gt;The alternative to &amp;ldquo;Framework-First&amp;rdquo; is &lt;strong&gt;Progressive Enhancement&lt;/strong&gt;. It&amp;rsquo;s a
  505. philosophy that has guided the web since its inception, yet it feels
  506. revolutionary in the current climate.&lt;/p&gt;
  507. &lt;ol&gt;
  508. &lt;li&gt;&lt;strong&gt;Content First (HTML):&lt;/strong&gt; Start with the &lt;strong&gt;semantic structure&lt;/strong&gt;. Does the
  509. site work if JavaScript is disabled? It should.&lt;/li&gt;
  510. &lt;li&gt;&lt;strong&gt;Presentation (CSS):&lt;/strong&gt; Layer on the design. Modern CSS (Grid, &lt;strong&gt;Container
  511. Queries&lt;/strong&gt;, Layers) can handle 90% of the layouts that used to require
  512. JS-heavy libraries.&lt;/li&gt;
  513. &lt;li&gt;&lt;strong&gt;Enhancement (JS):&lt;/strong&gt; Add interactivity. Use &lt;strong&gt;Vanilla JS&lt;/strong&gt; for simple
  514. things. If a specific section of the page (like a complex filter or a
  515. shopping cart) needs heavy state management, use a &amp;ldquo;&lt;strong&gt;micro-framework&lt;/strong&gt;&amp;rdquo; like
  516. &lt;strong&gt;Alpine.js&lt;/strong&gt; or Petite-Vue only for that specific area.&lt;/li&gt;
  517. &lt;/ol&gt;
  518. &lt;p&gt;We need to stop treating frameworks as the foundation and start treating them as
  519. the &lt;em&gt;accessory&lt;/em&gt;.&lt;/p&gt;
  520. &lt;h2 id="when-frameworks-actually-make-sense"&gt;When Frameworks Actually Make Sense&lt;/h2&gt;
  521. &lt;p&gt;Lest I be accused of being a luddite: frameworks &lt;em&gt;do&lt;/em&gt; have a place. If you are
  522. building &lt;strong&gt;Spotify&lt;/strong&gt;, &lt;strong&gt;Figma&lt;/strong&gt;, or &lt;strong&gt;Discord&lt;/strong&gt;, a framework isn&amp;rsquo;t just
  523. helpful—it&amp;rsquo;s essential. These are applications where the state is so complex and
  524. the interactions so dense that managing them with &lt;strong&gt;Vanilla JS&lt;/strong&gt; would be an
  525. exercise in masochism.&lt;/p&gt;
  526. &lt;p&gt;The problem isn&amp;rsquo;t that frameworks exist; it&amp;rsquo;s that we use them for
  527. &lt;strong&gt;everything&lt;/strong&gt;. We are using a sledgehammer to hang a picture frame.&lt;/p&gt;
  528. &lt;blockquote&gt;
  529. &lt;p&gt;&lt;strong&gt;Pro Tip: The 80/20 Rule of Tooling&lt;/strong&gt; 80% of the web consists of
  530. content-heavy sites (blogs, portfolios, documentation, marketing pages). 20%
  531. consists of complex &amp;ldquo;App-like&amp;rdquo; experiences. If you are in the 80%, you should
  532. prioritize &lt;strong&gt;Static Site Generators&lt;/strong&gt; (like &lt;strong&gt;Hugo&lt;/strong&gt;) and &lt;strong&gt;Vanilla JS&lt;/strong&gt;. Save
  533. the heavy frameworks for the remaining 20%.&lt;/p&gt;
  534. &lt;/blockquote&gt;
  535. &lt;h2 id="the-sustainability-argument"&gt;The Sustainability Argument&lt;/h2&gt;
  536. &lt;p&gt;There is also a human and environmental cost to framework churn.&lt;/p&gt;
  537. &lt;ul&gt;
  538. &lt;li&gt;&lt;strong&gt;Mental Health:&lt;/strong&gt; The pressure to stay &amp;ldquo;current&amp;rdquo; with every framework update
  539. contributes significantly to developer burnout.&lt;/li&gt;
  540. &lt;li&gt;&lt;strong&gt;Environmental Impact:&lt;/strong&gt; Shipping megabytes of unnecessary JS across the
  541. globe every second consumes massive amounts of energy. A &amp;ldquo;light&amp;rdquo; web is a
  542. greener web.&lt;/li&gt;
  543. &lt;li&gt;&lt;strong&gt;Accessibility:&lt;/strong&gt; Framework-heavy sites often fail the &amp;ldquo;low-end device&amp;rdquo; test,
  544. effectively gatekeeping information from users who can&amp;rsquo;t afford the latest
  545. iPhone.&lt;/li&gt;
  546. &lt;/ul&gt;
  547. &lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
  548. &lt;p&gt;The next time you start a project, I challenge you to &lt;strong&gt;not&lt;/strong&gt; install a
  549. framework. Try to see how far you can get with just HTML, CSS, and a sprinkle of
  550. &lt;strong&gt;Vanilla JavaScript&lt;/strong&gt;. You&amp;rsquo;ll likely find that not only is it possible, but the
  551. resulting site is faster, easier to maintain, and more satisfying to build.&lt;/p&gt;
  552. &lt;p&gt;Learn the platform before you learn the abstraction. The framework you learn
  553. today will be gone in five years, but the &lt;strong&gt;browser APIs&lt;/strong&gt; you learn today will
  554. serve you for the rest of your career.&lt;/p&gt;
  555. &lt;hr&gt;
  556. &lt;p&gt;&lt;em&gt;As I argued in my comparison of static sites versus WordPress, I&amp;rsquo;ve broken down
  557. why simple is often better for your next project&amp;rsquo;s architecture.&lt;/em&gt;&lt;/p&gt;
  558. </content:encoded>
  559. <dc:creator>Val Paliy</dc:creator>
  560. </item>
  561. <item>
  562. <title>AI for Developers: A Practical Guide to Getting Started</title>
  563. <link>https://valticus.pro/posts/ai-for-developers-a-practical-guide-to-getting-started/</link>
  564. <pubDate>Mon, 06 Jul 2026 00:00:00 +0000</pubDate>
  565. <guid isPermaLink="true">https://valticus.pro/posts/ai-for-developers-a-practical-guide-to-getting-started/</guid>
  566. <description>A hands-on guide to integrating AI tools and services into your development workflow, from code assistance to automated testing and intelligent debugging.</description>
  567. <category>Web Development</category><content:encoded>&lt;h2 id="ai-has-entered-the-building"&gt;AI Has Entered the Building&lt;/h2&gt;
  568. &lt;p&gt;In 2026, the question is no longer &amp;ldquo;Will AI change software development?&amp;rdquo; but
  569. &amp;ldquo;How effectively are you using it?&amp;rdquo; AI tools have moved from experimental
  570. novelties to indispensable force multipliers. However, the sheer volume of
  571. tools—&lt;strong&gt;LLMs&lt;/strong&gt;, &lt;strong&gt;IDE extensions&lt;/strong&gt;, &lt;strong&gt;CLI wrappers&lt;/strong&gt;, and &lt;strong&gt;autonomous
  572. agents&lt;/strong&gt;—has created a paradox of choice.&lt;/p&gt;
  573. &lt;p&gt;This guide isn&amp;rsquo;t about the hype. It’s a pragmatic look at the current AI stack
  574. for developers, how to build a workflow that actually saves time, and where the
  575. &amp;ldquo;hidden costs&amp;rdquo; of AI adoption lie.&lt;/p&gt;
  576. &lt;figure&gt;
  577. &lt;div class="progressive-image"&gt;
  578. &lt;img class="progressive-image__img"
  579. src="https://valticus.pro/images/ai-for-developers-a-practical-guide-to-getting-started_hu_cc39ef3715a93792.webp"
  580. alt="AI for Developers: A Practical Guide to Getting Started."
  581. width="800"
  582. height="436"&gt;
  583. &lt;/div&gt;
  584. &lt;figcaption&gt;&lt;p class="figure__caption"&gt;AI for Developers: A Practical Guide to Getting Started.&lt;/p&gt;&lt;/figcaption&gt;
  585. &lt;/figure&gt;
  586. &lt;h2 id="the-developers-ai-stack"&gt;The Developer&amp;rsquo;s AI Stack&lt;/h2&gt;
  587. &lt;p&gt;To get started, you need to understand the three layers of the modern AI
  588. developer stack: &lt;strong&gt;Models&lt;/strong&gt;, &lt;strong&gt;Interfaces&lt;/strong&gt;, and &lt;strong&gt;Context&lt;/strong&gt;.&lt;/p&gt;
  589. &lt;h3 id="1-the-models-the-brains"&gt;1. The Models (The Brains)&lt;/h3&gt;
  590. &lt;p&gt;Not all LLMs are created equal. Some excel at creative writing, while others are
  591. fine-tuned for the rigid syntax of code.&lt;/p&gt;
  592. &lt;table&gt;
  593. &lt;thead&gt;
  594. &lt;tr&gt;
  595. &lt;th&gt;Model&lt;/th&gt;
  596. &lt;th&gt;Strengths&lt;/th&gt;
  597. &lt;th&gt;Best For&lt;/th&gt;
  598. &lt;/tr&gt;
  599. &lt;/thead&gt;
  600. &lt;tbody&gt;
  601. &lt;tr&gt;
  602. &lt;td&gt;&lt;strong&gt;Claude 3.5 Sonnet&lt;/strong&gt;&lt;/td&gt;
  603. &lt;td&gt;Exceptional reasoning, follows complex instructions&lt;/td&gt;
  604. &lt;td&gt;Complex refactoring, architectural advice&lt;/td&gt;
  605. &lt;/tr&gt;
  606. &lt;tr&gt;
  607. &lt;td&gt;&lt;strong&gt;GPT-4o&lt;/strong&gt;&lt;/td&gt;
  608. &lt;td&gt;Fast, great at boilerplate and common patterns&lt;/td&gt;
  609. &lt;td&gt;Day-to-day coding, unit tests&lt;/td&gt;
  610. &lt;/tr&gt;
  611. &lt;tr&gt;
  612. &lt;td&gt;&lt;strong&gt;DeepSeek Coder&lt;/strong&gt;&lt;/td&gt;
  613. &lt;td&gt;Open-weights, highly specialized for code&lt;/td&gt;
  614. &lt;td&gt;Self-hosting, privacy-conscious tasks&lt;/td&gt;
  615. &lt;/tr&gt;
  616. &lt;tr&gt;
  617. &lt;td&gt;&lt;strong&gt;Llama 3 (70B+)&lt;/strong&gt;&lt;/td&gt;
  618. &lt;td&gt;Versatile, great general knowledge&lt;/td&gt;
  619. &lt;td&gt;Documentation, explaining concepts&lt;/td&gt;
  620. &lt;/tr&gt;
  621. &lt;/tbody&gt;
  622. &lt;/table&gt;
  623. &lt;h3 id="2-the-interfaces-the-hands"&gt;2. The Interfaces (The Hands)&lt;/h3&gt;
  624. &lt;p&gt;How you interact with these models determines your friction level.&lt;/p&gt;
  625. &lt;ul&gt;
  626. &lt;li&gt;&lt;strong&gt;AI-Native Editors (e.g., Cursor)&lt;/strong&gt;: These are forks of VS Code that have AI
  627. baked into the core. They can &amp;ldquo;see&amp;rdquo; your entire codebase, not just the file
  628. you&amp;rsquo;re working on.&lt;/li&gt;
  629. &lt;li&gt;&lt;strong&gt;Extensions (e.g., GitHub Copilot, Codeium)&lt;/strong&gt;: Plugins for your existing
  630. editor. Great for autocomplete but often lack the deep context of native
  631. editors.&lt;/li&gt;
  632. &lt;li&gt;&lt;strong&gt;CLI Tools (e.g., Aider, Gemini CLI)&lt;/strong&gt;: For those who live in the terminal.
  633. These can perform multi-file edits and git commits directly from a prompt.&lt;/li&gt;
  634. &lt;/ul&gt;
  635. &lt;h3 id="3-the-context-the-memory"&gt;3. The Context (The Memory)&lt;/h3&gt;
  636. &lt;p&gt;The secret sauce of AI productivity is &lt;strong&gt;RAG (Retrieval-Augmented Generation)&lt;/strong&gt;.
  637. The more context you provide—your project structure, documentation, and coding
  638. standards—the more accurate the AI becomes.&lt;/p&gt;
  639. &lt;h2 id="prompt-engineering-the-new-syntax"&gt;Prompt Engineering: The New Syntax&lt;/h2&gt;
  640. &lt;p&gt;Writing a prompt is like writing a specification. If your spec is vague, the
  641. implementation will be buggy.&lt;/p&gt;
  642. &lt;p&gt;&lt;strong&gt;Common Pitfall: The &amp;ldquo;One-Liner&amp;rdquo; Prompt&lt;/strong&gt; Don&amp;rsquo;t just ask: &lt;em&gt;&amp;ldquo;Write a React login
  643. component.&amp;rdquo;&lt;/em&gt; You&amp;rsquo;ll get a generic, inaccessible component that uses libraries
  644. you don&amp;rsquo;t want.&lt;/p&gt;
  645. &lt;p&gt;&lt;strong&gt;The &amp;ldquo;Pro&amp;rdquo; Prompt Pattern:&lt;/strong&gt; Use the &lt;strong&gt;Role-Context-Task-Constraint&lt;/strong&gt;
  646. framework:&lt;/p&gt;
  647. &lt;ul&gt;
  648. &lt;li&gt;&lt;strong&gt;Role&lt;/strong&gt;: &amp;ldquo;You are a senior React developer specializing in accessibility.&amp;rdquo;&lt;/li&gt;
  649. &lt;li&gt;&lt;strong&gt;Context&lt;/strong&gt;: &amp;ldquo;We are using &lt;strong&gt;Tailwind CSS&lt;/strong&gt; and &lt;strong&gt;React Hook Form&lt;/strong&gt;.&amp;rdquo;&lt;/li&gt;
  650. &lt;li&gt;&lt;strong&gt;Task&lt;/strong&gt;: &amp;ldquo;Create a login form with email and password fields.&amp;rdquo;&lt;/li&gt;
  651. &lt;li&gt;&lt;strong&gt;Constraints&lt;/strong&gt;: &amp;ldquo;Must be WCAG 2.1 AA compliant, use semantic HTML, and
  652. include client-side validation.&amp;rdquo;&lt;/li&gt;
  653. &lt;/ul&gt;
  654. &lt;p&gt;&lt;strong&gt;Pro Tip: Local LLMs for Privacy&lt;/strong&gt; If you&amp;rsquo;re working on sensitive or
  655. proprietary code, use &lt;strong&gt;Ollama&lt;/strong&gt; or &lt;strong&gt;LM Studio&lt;/strong&gt;. You can run models like
  656. DeepSeek Coder or Llama 3 entirely offline on your local machine (assuming you
  657. have a decent GPU or Apple Silicon M-series chip). This ensures your code never
  658. leaves your network.&lt;/p&gt;
  659. &lt;h2 id="ai-native-vs-ai-augmented-workflows"&gt;AI-Native vs. AI-Augmented Workflows&lt;/h2&gt;
  660. &lt;h3 id="the-augmented-workflow-reactive"&gt;The Augmented Workflow (Reactive)&lt;/h3&gt;
  661. &lt;p&gt;You write code, and the AI suggests the next 10 lines. This is great for
  662. boilerplate, but it can lead to &amp;ldquo;autopilot coding&amp;rdquo; where you accept suggestions
  663. without fully understanding them.&lt;/p&gt;
  664. &lt;h3 id="the-ai-native-workflow-proactive"&gt;The AI-Native Workflow (Proactive)&lt;/h3&gt;
  665. &lt;p&gt;You describe the feature or the bug to the AI. The AI scans your files, proposes
  666. a multi-file change, and you &lt;strong&gt;review&lt;/strong&gt; and &lt;strong&gt;test&lt;/strong&gt; the output. This shifts
  667. your role from &amp;ldquo;Typewriter&amp;rdquo; to &amp;ldquo;Editor.&amp;rdquo;&lt;/p&gt;
  668. &lt;h3 id="example-refactoring-technical-debt"&gt;Example: Refactoring Technical Debt&lt;/h3&gt;
  669. &lt;p&gt;AI is surprisingly good at &amp;ldquo;un-spaghettifying&amp;rdquo; code. &lt;em&gt;Prompt:&lt;/em&gt; &amp;ldquo;Analyze this
  670. 500-line function. Identify three ways to break it into smaller, testable
  671. modules following the &lt;strong&gt;Single Responsibility Principle&lt;/strong&gt;. Provide the
  672. refactored code and unit tests for each new module.&amp;rdquo;&lt;/p&gt;
  673. &lt;h2 id="the-junior-developer-trap"&gt;The &amp;ldquo;Junior Developer&amp;rdquo; Trap&lt;/h2&gt;
  674. &lt;p&gt;There is a significant danger for developers starting their careers today:
  675. over-reliance. If you use AI to solve every problem before you understand the
  676. underlying concepts, you&amp;rsquo;re building your career on a foundation of sand.&lt;/p&gt;
  677. &lt;p&gt;AI often hallucinates or provides outdated solutions. For instance, in my
  678. &amp;ldquo;Accessibility Is Still Broken&amp;rdquo; post, I discuss how automated tools (including
  679. AI) often fail to understand the nuance of focus management and screen reader
  680. context.&lt;/p&gt;
  681. &lt;h2 id="security-privacy-and-intellectual-property"&gt;Security, Privacy, and Intellectual Property&lt;/h2&gt;
  682. &lt;p&gt;Before you paste your company&amp;rsquo;s API secrets into a web chat, remember:&lt;/p&gt;
  683. &lt;ul&gt;
  684. &lt;li&gt;&lt;strong&gt;Data Leakage&lt;/strong&gt;: Most consumer-grade AI tools use your inputs to train future
  685. models unless you opt-out or use Enterprise versions.&lt;/li&gt;
  686. &lt;li&gt;&lt;strong&gt;Vulnerabilities&lt;/strong&gt;: AI can (and does) suggest code with known security flaws.
  687. Always run a &lt;strong&gt;SAST (Static Application Security Testing)&lt;/strong&gt; tool like &lt;strong&gt;Snyk&lt;/strong&gt;
  688. or &lt;strong&gt;SonarQube&lt;/strong&gt; on AI-generated code.&lt;/li&gt;
  689. &lt;li&gt;&lt;strong&gt;Licensing&lt;/strong&gt;: The legal landscape around AI-generated code is still evolving.
  690. Ensure your company&amp;rsquo;s policy allows for AI usage and understand that you are
  691. ultimately responsible for the code you commit.&lt;/li&gt;
  692. &lt;/ul&gt;
  693. &lt;h2 id="realistic-productivity-gains"&gt;Realistic Productivity Gains&lt;/h2&gt;
  694. &lt;p&gt;Don&amp;rsquo;t believe the &amp;ldquo;10x developer&amp;rdquo; marketing. Here’s what you can actually
  695. expect:&lt;/p&gt;
  696. &lt;ul&gt;
  697. &lt;li&gt;&lt;strong&gt;Boilerplate&lt;/strong&gt;: 80% time reduction (&lt;strong&gt;CRUD&lt;/strong&gt;, &lt;strong&gt;DTOs&lt;/strong&gt;, Unit tests).&lt;/li&gt;
  698. &lt;li&gt;&lt;strong&gt;Learning New Tech&lt;/strong&gt;: 50% faster (explaining syntax, generating hello-world
  699. examples).&lt;/li&gt;
  700. &lt;li&gt;&lt;strong&gt;Debugging&lt;/strong&gt;: 30% faster (summarizing logs, identifying common errors).&lt;/li&gt;
  701. &lt;li&gt;&lt;strong&gt;Architecture&lt;/strong&gt;: 10% gain (mostly as a sounding board).&lt;/li&gt;
  702. &lt;/ul&gt;
  703. &lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
  704. &lt;p&gt;AI for developers isn&amp;rsquo;t about replacing the act of thinking; it&amp;rsquo;s about removing
  705. the friction of execution. The goal is to spend less time fighting with syntax
  706. and more time solving business problems.&lt;/p&gt;
  707. &lt;p&gt;Start by picking an AI-native editor like &lt;strong&gt;Cursor&lt;/strong&gt;, learn the art of the
  708. multi-file prompt, and always—&lt;strong&gt;always&lt;/strong&gt;—remain the final authority on the code
  709. you ship. The best developers in 2026 aren&amp;rsquo;t the ones who type the fastest;
  710. they&amp;rsquo;re the ones who can most effectively orchestrate the AI tools at their
  711. disposal.&lt;/p&gt;
  712. </content:encoded>
  713. <dc:creator>Val Paliy</dc:creator>
  714. </item>
  715. <item>
  716. <title>Dark Mode vs Light Mode: Design Systems for Code Editors</title>
  717. <link>https://valticus.pro/posts/dark-mode-vs-light-mode-design-systems-for-code-editors/</link>
  718. <pubDate>Mon, 15 Jun 2026 00:00:00 +0000</pubDate>
  719. <guid isPermaLink="true">https://valticus.pro/posts/dark-mode-vs-light-mode-design-systems-for-code-editors/</guid>
  720. <description>Why the dark mode vs light mode debate is a false dichotomy—and how adaptive theming beats picking a side.</description>
  721. <category>Technology</category><content:encoded>&lt;p&gt;The dark mode versus light mode debate is a false dichotomy. Picking one theme
  722. and sticking with it forever ignores how your eyes, environment, and tasks
  723. actually work. The real answer is &lt;strong&gt;adaptive theming&lt;/strong&gt;: an editor design system
  724. that shifts its contrast, saturation, and color palette based on context.&lt;/p&gt;
  725. &lt;p&gt;A 2023 survey by JetBrains found that 82% of developers prefer dark themes, but
  726. 93% of those same developers admitted they occasionally switch to a light theme
  727. depending on lighting conditions. That is not indecision. It is a signal that
  728. one theme cannot cover every scenario.&lt;/p&gt;
  729. &lt;figure&gt;
  730. &lt;div class="progressive-image"&gt;
  731. &lt;img class="progressive-image__img"
  732. src="https://valticus.pro/images/dark-mode-vs-light-mode-design-systems-for-code-editors_hu_3ac48a8b7442746c.webp"
  733. alt="Dark Mode vs Light Mode: Design Systems for Code Editors."
  734. width="800"
  735. height="436"&gt;
  736. &lt;/div&gt;
  737. &lt;figcaption&gt;&lt;p class="figure__caption"&gt;Dark Mode vs Light Mode: Design Systems for Code Editors.&lt;/p&gt;&lt;/figcaption&gt;
  738. &lt;/figure&gt;
  739. &lt;p&gt;This is not about aesthetics. It is about cognitive load, accessibility, and
  740. productivity. And the best part? You do not need to wait for IDE vendors to
  741. build it. You can do it today in both VS Code and Neovim.&lt;/p&gt;
  742. &lt;h2 id="the-problem-with-picking-a-side"&gt;The Problem with Picking a Side&lt;/h2&gt;
  743. &lt;p&gt;Dark mode advocates are not wrong—they are just context-blind.&lt;/p&gt;
  744. &lt;p&gt;A dark theme genuinely helps in low-light conditions, reduces glare, and saves
  745. battery on OLED screens. That is why every developer tool defaults to it. But
  746. the same theme that makes code pop at midnight washes out syntax highlighting at
  747. noon and turns into a reflective mess near a window.&lt;/p&gt;
  748. &lt;p&gt;Research on visual fatigue shows that prolonged exposure to high-contrast dark
  749. mode can increase eye strain for people with astigmatism—a condition affecting
  750. roughly 33% of the population. The halation effect (blurred edges around bright
  751. text on dark backgrounds) forces the eyes to work harder to focus. Light mode
  752. avoids this but introduces its own problems: harsh brightness in dark rooms and
  753. lower perceived contrast for certain color pairs.&lt;/p&gt;
  754. &lt;p&gt;Light mode has its strengths: superior contrast for complex syntax, better
  755. readability in bright environments, and easier prolonged reading for people with
  756. vision conditions like astigmatism or presbyopia. But it is punishing in a dark
  757. room and feels sterile after hours of deep work.&lt;/p&gt;
  758. &lt;p&gt;The problem is not which theme is &amp;ldquo;better.&amp;rdquo; It is that &lt;strong&gt;one theme cannot adapt
  759. to all conditions&lt;/strong&gt;, and choosing a side means accepting those trade-offs
  760. permanently.&lt;/p&gt;
  761. &lt;h2 id="what-adaptive-theming-actually-means"&gt;What Adaptive Theming Actually Means&lt;/h2&gt;
  762. &lt;p&gt;Most developers stop at &amp;ldquo;dark theme during the day, light theme at night&amp;rdquo;
  763. reversal. That is a start, but it is not a design system.&lt;/p&gt;
  764. &lt;p&gt;A proper editor design system adjusts to three variables:&lt;/p&gt;
  765. &lt;ul&gt;
  766. &lt;li&gt;&lt;strong&gt;Time of day&lt;/strong&gt;: Your eyes adapt to ambient light. A theme that works at 2 PM
  767. will not work at 2 AM. Circadian rhythm affects color perception—warm tones at
  768. night reduce melatonin suppression, while cool blue light in the morning
  769. supports alertness.&lt;/li&gt;
  770. &lt;li&gt;&lt;strong&gt;Task type&lt;/strong&gt;: Reading documentation needs different contrast ratios than
  771. writing new code. Debugging needs different color cues than refactoring. A
  772. diff view should not use the same palette as your main editor.&lt;/li&gt;
  773. &lt;li&gt;&lt;strong&gt;Environment&lt;/strong&gt;: The same theme looks completely different on a laptop display
  774. versus an external monitor versus a projector. A theme calibrated on a MacBook
  775. Pro&amp;rsquo;s XDR display will look muddy on a budget external panel.&lt;/li&gt;
  776. &lt;/ul&gt;
  777. &lt;p&gt;Adaptive theming takes automatic theme switching further. Instead of just
  778. flipping between two color schemes, the editor adjusts the entire visual
  779. system—contrast curve, saturation levels, syntax highlight palette, even UI
  780. chrome opacity—based on context.&lt;/p&gt;
  781. &lt;h2 id="adaptive-theming-in-vs-code"&gt;Adaptive Theming in VS Code&lt;/h2&gt;
  782. &lt;p&gt;VS Code has excellent extension support for theme switching. The approach breaks
  783. down into three layers:&lt;/p&gt;
  784. &lt;h3 id="layer-1-time-based-switching"&gt;Layer 1: Time-Based Switching&lt;/h3&gt;
  785. &lt;p&gt;The simplest layer uses extensions like
  786. &lt;a href="https://marketplace.visualstudio.com/items?itemName=savioserra.theme-switcher"&gt;Theme Switcher&lt;/a&gt;
  787. or
  788. &lt;a href="https://marketplace.visualstudio.com/items?itemName=zhuangtongfa.Material-theme"&gt;Auto Theme&lt;/a&gt;
  789. to rotate themes at set hours. I covered the basics previously, but here is a
  790. refined configuration:&lt;/p&gt;
  791. &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsonc" &gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  792. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;auto-theme.timezone&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  793. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;auto-theme.toggleDarkTheme&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Night Owl&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  794. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;auto-theme.toggleLightTheme&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Night Owl Light&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  795. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;auto-theme.schedule&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  796. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;startTime&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;06:00&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;endTime&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;12:00&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;theme&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Night Owl Light&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  797. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;startTime&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;12:00&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;endTime&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;18:00&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;theme&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Cobalt2&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  798. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;startTime&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;18:00&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;endTime&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;06:00&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;theme&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Night Owl&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  799. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
  800. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  801. &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="layer-2-per-language-and-per-task-theming"&gt;Layer 2: Per-Language and Per-Task Theming&lt;/h3&gt;
  802. &lt;p&gt;VS Code supports per-language theme overrides via
  803. &lt;code&gt;editor.semanticTokenColorCustomizations&lt;/code&gt; and &lt;code&gt;workbench.colorCustomizations&lt;/code&gt;.
  804. You can fine-tune syntax colors for specific languages without switching themes
  805. entirely:&lt;/p&gt;
  806. &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsonc" &gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  807. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;editor.semanticTokenColorCustomizations&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  808. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;[Night Owl]&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  809. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;enabled&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  810. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;rules&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  811. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;*.declaration.readonly&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;foreground&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;#82aaff&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  812. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;parameter&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;foreground&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;#c792ea&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  813. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  814. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  815. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  816. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;workbench.colorCustomizations&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  817. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;[Night Owl Light]&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  818. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;sideBar.foreground&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;#000000&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  819. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;editor.background&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;#fafafa&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  820. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;sideBar.background&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;#f0f0f0&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  821. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  822. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  823. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  824. &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For task-based theming, you can bind theme switching to keyboard shortcuts and
  825. use VS Code&amp;rsquo;s profiles feature to switch between &amp;ldquo;writing mode,&amp;rdquo; &amp;ldquo;debugging
  826. mode,&amp;rdquo; and &amp;ldquo;reading mode&amp;rdquo; with different chrome densities and color treatments:&lt;/p&gt;
  827. &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsonc" &gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  828. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;ctrl+shift+1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  829. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;workbench.action.switchToProfile&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  830. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Writing&amp;#34;&lt;/span&gt;
  831. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;
  832. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  833. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;ctrl+shift+2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  834. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;workbench.action.switchToProfile&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  835. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Debugging&amp;#34;&lt;/span&gt;
  836. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;
  837. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  838. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;ctrl+shift+3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  839. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;workbench.action.switchToProfile&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  840. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Reading&amp;#34;&lt;/span&gt;
  841. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  842. &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="layer-3-ambient-adaptation"&gt;Layer 3: Ambient Adaptation&lt;/h3&gt;
  843. &lt;p&gt;For true adaptive theming, you can combine VS Code&amp;rsquo;s
  844. &lt;a href="https://code.visualstudio.com/docs/getstarted/themes#_automatically-switch-based-on-os-color-scheme"&gt;window.autoDetectColorScheme&lt;/a&gt;
  845. with OS-level automation. On macOS, Night Shift and Shortcuts can trigger theme
  846. changes. On Windows, Power Automate or AutoHotkey scripts can switch themes
  847. based on sunrise and sunset.&lt;/p&gt;
  848. &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-jsonc" &gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  849. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;window.autoDetectColorScheme&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  850. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;workbench.preferredLightColorTheme&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Night Owl Light&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  851. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;workbench.preferredDarkColorTheme&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Night Owl&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  852. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;workbench.preferredHighContrastColorTheme&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Night Owl High Contrast&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  853. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  854. &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When paired with Windows 11&amp;rsquo;s dynamic lighting and macOS&amp;rsquo;s built-in automatic
  855. theme switching, this gives you a four-state system: light → dark → high
  856. contrast → light, following your OS settings without manual intervention.&lt;/p&gt;
  857. &lt;h2 id="adaptive-theming-in-neovim"&gt;Adaptive Theming in Neovim&lt;/h2&gt;
  858. &lt;p&gt;Neovim offers even finer control because everything is configurable in Lua. You
  859. can build an adaptive system that responds to time, file type, and even ambient
  860. light data from your system.&lt;/p&gt;
  861. &lt;h3 id="time-based-switching"&gt;Time-Based Switching&lt;/h3&gt;
  862. &lt;p&gt;Using Lua, you can schedule theme changes with a simple timer:&lt;/p&gt;
  863. &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-lua" &gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="kr"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;set_theme_by_hour&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  864. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;hour&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tonumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os.date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;%H&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  865. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
  866. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;if&lt;/span&gt; &lt;span class="n"&gt;hour&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;hour&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
  867. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vim.cmd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;colorscheme night-owl-light&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  868. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;elseif&lt;/span&gt; &lt;span class="n"&gt;hour&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;hour&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
  869. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vim.cmd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;colorscheme cobalt2&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  870. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;else&lt;/span&gt;
  871. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vim.cmd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;colorscheme night-owl&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  872. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;end&lt;/span&gt;
  873. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;end&lt;/span&gt;
  874. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
  875. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- Run on startup&lt;/span&gt;
  876. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;set_theme_by_hour&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  877. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
  878. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- Re-check every 10 minutes&lt;/span&gt;
  879. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;vim.loop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new_timer&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;600000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;600000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vim.schedule_wrap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;set_theme_by_hour&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  880. &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="per-filetype-and-per-task-theming"&gt;Per-Filetype and Per-Task Theming&lt;/h3&gt;
  881. &lt;p&gt;Neovim&amp;rsquo;s &lt;code&gt;FileType&lt;/code&gt; and &lt;code&gt;BufEnter&lt;/code&gt; autocommands let you theme per context.
  882. Disable syntax highlighting in large log files. Use a high-contrast scheme for
  883. diffs. Switch to a minimal prose theme in Markdown:&lt;/p&gt;
  884. &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-lua" &gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;vim.api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nvim_create_augroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;AdaptiveTheming&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;clear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  885. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
  886. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- Minimal theme for writing&lt;/span&gt;
  887. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;vim.api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nvim_create_autocmd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;FileType&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  888. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;AdaptiveTheming&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  889. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;markdown&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;tex&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  890. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;callback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  891. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vim.cmd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;colorscheme rose-pine-dawn&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  892. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vim.opt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;light&amp;#34;&lt;/span&gt;
  893. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  894. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;})&lt;/span&gt;
  895. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
  896. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- High contrast for diff&lt;/span&gt;
  897. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;vim.api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nvim_create_autocmd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;FileType&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  898. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;AdaptiveTheming&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  899. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;diff&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;gitcommit&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  900. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;callback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  901. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vim.cmd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;colorscheme gruvbox-material&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  902. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vim.opt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;dark&amp;#34;&lt;/span&gt;
  903. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  904. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;})&lt;/span&gt;
  905. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
  906. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- Dim non-focus windows&lt;/span&gt;
  907. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;vim.api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nvim_create_autocmd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;WinEnter&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  908. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;AdaptiveTheming&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  909. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;callback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  910. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vim.opt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;winhighlight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Normal:NormalFloat&amp;#34;&lt;/span&gt;
  911. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  912. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;})&lt;/span&gt;
  913. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
  914. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;vim.api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nvim_create_autocmd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;WinLeave&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  915. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;AdaptiveTheming&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  916. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;callback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  917. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vim.opt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;winhighlight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Normal:DimWindow&amp;#34;&lt;/span&gt;
  918. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  919. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;})&lt;/span&gt;
  920. &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="ambient-light-integration"&gt;Ambient Light Integration&lt;/h3&gt;
  921. &lt;p&gt;For the full adaptive experience, you can integrate with system light sensors.
  922. On macOS, you can read the ambient light level via &lt;code&gt;pmset -g raw&lt;/code&gt;. On Linux,
  923. &lt;code&gt;acpi -V&lt;/code&gt; or the &lt;code&gt;illuminated&lt;/code&gt; package provides sensor data. Here is a Neovim
  924. plugin module that polls ambient brightness:&lt;/p&gt;
  925. &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-lua" &gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="kr"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;get_ambient_brightness&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  926. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;handle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;io.popen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pmset -g raw 2&amp;gt;/dev/null | grep &amp;#39;Ambient&amp;#39; | awk &amp;#39;{print $3}&amp;#39;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  927. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;if&lt;/span&gt; &lt;span class="n"&gt;handle&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
  928. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;*a&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="n"&gt;gsub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;%s+&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  929. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  930. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;return&lt;/span&gt; &lt;span class="n"&gt;tonumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;
  931. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;end&lt;/span&gt;
  932. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;
  933. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;end&lt;/span&gt;
  934. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
  935. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="kr"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;adaptive_theme&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  936. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;brightness&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_ambient_brightness&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  937. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;-- Assume 0–100 range, lower = darker room&lt;/span&gt;
  938. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;if&lt;/span&gt; &lt;span class="n"&gt;brightness&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
  939. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vim.cmd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;colorscheme tokyonight-storm&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  940. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vim.opt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;dark&amp;#34;&lt;/span&gt;
  941. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;elseif&lt;/span&gt; &lt;span class="n"&gt;brightness&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
  942. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vim.cmd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;colorscheme night-owl&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  943. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vim.opt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;dark&amp;#34;&lt;/span&gt;
  944. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;else&lt;/span&gt;
  945. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vim.cmd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;colorscheme kanagawa-lotus&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  946. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vim.opt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;light&amp;#34;&lt;/span&gt;
  947. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;end&lt;/span&gt;
  948. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;end&lt;/span&gt;
  949. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
  950. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- Check every 5 minutes&lt;/span&gt;
  951. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;vim.loop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new_timer&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;300000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;300000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vim.schedule_wrap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;adaptive_theme&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  952. &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="plugin-based-approach"&gt;Plugin-Based Approach&lt;/h3&gt;
  953. &lt;p&gt;If you prefer a plugin-based setup, these plugins handle most of the work:&lt;/p&gt;
  954. &lt;ul&gt;
  955. &lt;li&gt;&lt;strong&gt;&lt;a href="https://github.com/folke/tokyonight.nvim"&gt;tokyonight.nvim&lt;/a&gt;&lt;/strong&gt; — ships with a
  956. built-in &lt;code&gt;config.style&lt;/code&gt; that can be set dynamically based on time.&lt;/li&gt;
  957. &lt;li&gt;&lt;strong&gt;&lt;a href="https://github.com/catppuccin/nvim"&gt;catppuccin&lt;/a&gt;&lt;/strong&gt; — exposes
  958. &lt;code&gt;vim.g.catppuccin_flavour&lt;/code&gt; that you can toggle between &lt;code&gt;latte&lt;/code&gt;, &lt;code&gt;frappe&lt;/code&gt;,
  959. &lt;code&gt;macchiato&lt;/code&gt;, and &lt;code&gt;mocha&lt;/code&gt; based on your schedule.&lt;/li&gt;
  960. &lt;li&gt;&lt;strong&gt;&lt;a href="https://github.com/f-person/auto-dark-mode.nvim"&gt;auto-dark-mode.nvim&lt;/a&gt;&lt;/strong&gt; —
  961. syncs Neovim&amp;rsquo;s theme with your OS dark/light mode automatically.&lt;/li&gt;
  962. &lt;li&gt;&lt;strong&gt;&lt;a href="https://github.com/EdenEast/nightfox.nvim"&gt;nightfox.nvim&lt;/a&gt;&lt;/strong&gt; — includes
  963. &lt;code&gt;dayfox&lt;/code&gt;, &lt;code&gt;dawnfox&lt;/code&gt;, &lt;code&gt;duskfox&lt;/code&gt;, and &lt;code&gt;nightfox&lt;/code&gt; variants designed for different
  964. times of day.&lt;/li&gt;
  965. &lt;/ul&gt;
  966. &lt;p&gt;Here is a minimal auto-dark-mode setup:&lt;/p&gt;
  967. &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-lua" &gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;auto-dark-mode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  968. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;update_interval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;60000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  969. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;set_dark_mode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  970. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vim.cmd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;colorscheme tokyonight&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  971. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vim.opt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;dark&amp;#34;&lt;/span&gt;
  972. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  973. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;set_light_mode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  974. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vim.cmd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;colorscheme kanagawa-lotus&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  975. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vim.opt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;light&amp;#34;&lt;/span&gt;
  976. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  977. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;})&lt;/span&gt;
  978. &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="accessibility-is-not-optional"&gt;Accessibility Is Not Optional&lt;/h2&gt;
  979. &lt;p&gt;Most popular themes fail basic accessibility checks. This is not a side issue—it
  980. directly affects whether your editor is usable by everyone on your team.&lt;/p&gt;
  981. &lt;ul&gt;
  982. &lt;li&gt;&lt;strong&gt;Contrast ratios&lt;/strong&gt;: WCAG AA (4.5:1 for normal text, 3:1 for large text)
  983. should be the minimum. According to a 2024 audit of the 50 most popular VS
  984. Code themes on the marketplace, 34% failed WCAG AA for at least one common
  985. color pair (comments vs. background, strings vs. keywords).&lt;/li&gt;
  986. &lt;li&gt;&lt;strong&gt;Color blindness&lt;/strong&gt;: Red-green syntax highlighting excludes roughly 8% of male
  987. developers. It is still the default in most editors. Tools like
  988. &lt;a href="https://marketplace.visualstudio.com/items?itemName=skn0tt.colorblindly"&gt;Colorblindly&lt;/a&gt;
  989. (VS Code) can simulate color vision deficiency directly in the editor.&lt;/li&gt;
  990. &lt;li&gt;&lt;strong&gt;Astigmatism and dark mode&lt;/strong&gt;: As mentioned earlier, dark mode worsens the
  991. halation effect for people with astigmatism. Forcing one theme on everyone is
  992. not inclusive.&lt;/li&gt;
  993. &lt;/ul&gt;
  994. &lt;p&gt;An adaptive system solves this by giving users per-context themes rather than
  995. one compromise. A developer with astigmatism can use a warm light theme for
  996. prose writing and a medium-contrast dark theme for focused coding, switching
  997. based on task rather than lighting.&lt;/p&gt;
  998. &lt;h3 id="practical-tooling"&gt;Practical Tooling&lt;/h3&gt;
  999. &lt;ul&gt;
  1000. &lt;li&gt;&lt;strong&gt;VS Code&lt;/strong&gt;: Use the
  1001. &lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode.accessibility-checker"&gt;Accessibility Checker&lt;/a&gt;
  1002. to audit your custom themes against WCAG standards.&lt;/li&gt;
  1003. &lt;li&gt;&lt;strong&gt;Neovim&lt;/strong&gt;: Plugins like &lt;a href="https://github.com/jdhao/nvim-a11y"&gt;nvim-a11y&lt;/a&gt; or
  1004. &lt;a href="https://github.com/rktjmp/lush.nvim"&gt;lush.nvim&lt;/a&gt; with contrast-checking
  1005. helpers let you validate your color palette in real time.&lt;/li&gt;
  1006. &lt;li&gt;&lt;strong&gt;General&lt;/strong&gt;: Tools like
  1007. &lt;a href="https://contrast-ratio.com/"&gt;Lea Verou&amp;rsquo;s Contrast Ratio&lt;/a&gt;,
  1008. &lt;a href="https://michelf.ca/projects/sim-daltonism/"&gt;Sim Daltonism&lt;/a&gt; (macOS), and
  1009. &lt;a href="https://webaim.org/resources/contrastchecker/"&gt;Colour Contrast Checker&lt;/a&gt; help
  1010. you evaluate any color pair before committing it to a theme.&lt;/li&gt;
  1011. &lt;/ul&gt;
  1012. &lt;h2 id="a-practical-daily-setup"&gt;A Practical Daily Setup&lt;/h2&gt;
  1013. &lt;p&gt;Here is what the full adaptive system looks like in practice across both
  1014. editors:&lt;/p&gt;
  1015. &lt;table&gt;
  1016. &lt;thead&gt;
  1017. &lt;tr&gt;
  1018. &lt;th&gt;Time&lt;/th&gt;
  1019. &lt;th&gt;Condition&lt;/th&gt;
  1020. &lt;th&gt;VS Code&lt;/th&gt;
  1021. &lt;th&gt;Neovim&lt;/th&gt;
  1022. &lt;th&gt;Visual Goal&lt;/th&gt;
  1023. &lt;/tr&gt;
  1024. &lt;/thead&gt;
  1025. &lt;tbody&gt;
  1026. &lt;tr&gt;
  1027. &lt;td&gt;06:00 – 09:00&lt;/td&gt;
  1028. &lt;td&gt;Morning, bright room&lt;/td&gt;
  1029. &lt;td&gt;Night Owl Light + warm sidebar&lt;/td&gt;
  1030. &lt;td&gt;kanagawa-lotus&lt;/td&gt;
  1031. &lt;td&gt;Warm undertones, low contrast&lt;/td&gt;
  1032. &lt;/tr&gt;
  1033. &lt;tr&gt;
  1034. &lt;td&gt;09:00 – 12:00&lt;/td&gt;
  1035. &lt;td&gt;Peak daylight&lt;/td&gt;
  1036. &lt;td&gt;Cobalt2&lt;/td&gt;
  1037. &lt;td&gt;tokyonight-day&lt;/td&gt;
  1038. &lt;td&gt;Neutral, medium contrast&lt;/td&gt;
  1039. &lt;/tr&gt;
  1040. &lt;tr&gt;
  1041. &lt;td&gt;12:00 – 14:00&lt;/td&gt;
  1042. &lt;td&gt;Lunch, variable light&lt;/td&gt;
  1043. &lt;td&gt;Auto theme via OS&lt;/td&gt;
  1044. &lt;td&gt;auto-dark-mode sync&lt;/td&gt;
  1045. &lt;td&gt;System-following&lt;/td&gt;
  1046. &lt;/tr&gt;
  1047. &lt;tr&gt;
  1048. &lt;td&gt;14:00 – 18:00&lt;/td&gt;
  1049. &lt;td&gt;Afternoon grind&lt;/td&gt;
  1050. &lt;td&gt;Night Owl&lt;/td&gt;
  1051. &lt;td&gt;nightfox&lt;/td&gt;
  1052. &lt;td&gt;High contrast, focused&lt;/td&gt;
  1053. &lt;/tr&gt;
  1054. &lt;tr&gt;
  1055. &lt;td&gt;18:00 – 22:00&lt;/td&gt;
  1056. &lt;td&gt;Evening, winding down&lt;/td&gt;
  1057. &lt;td&gt;In Bed by 7pm&lt;/td&gt;
  1058. &lt;td&gt;duskfox&lt;/td&gt;
  1059. &lt;td&gt;Reduced blue light, warmer&lt;/td&gt;
  1060. &lt;/tr&gt;
  1061. &lt;tr&gt;
  1062. &lt;td&gt;22:00 – 06:00&lt;/td&gt;
  1063. &lt;td&gt;Night coding&lt;/td&gt;
  1064. &lt;td&gt;Night Owl&lt;/td&gt;
  1065. &lt;td&gt;tokyonight-storm&lt;/td&gt;
  1066. &lt;td&gt;Minimal blue light, high contrast&lt;/td&gt;
  1067. &lt;/tr&gt;
  1068. &lt;/tbody&gt;
  1069. &lt;/table&gt;
  1070. &lt;p&gt;The specifics matter less than the principle: your visual system changes
  1071. throughout the day, and your tools should adapt to you.&lt;/p&gt;
  1072. &lt;h2 id="the-bottom-line"&gt;The Bottom Line&lt;/h2&gt;
  1073. &lt;p&gt;Stop treating theme choice as a religious identity. Build a system that adapts
  1074. to your day, your task, and your environment. Whether you use VS Code with three
  1075. extensions or Neovim with a 30-line Lua module, the principle is the same: your
  1076. tools should meet you where you are, not force you to meet them.&lt;/p&gt;
  1077. &lt;p&gt;Your code will not care what color your background is. Your eyes will.&lt;/p&gt;
  1078. </content:encoded>
  1079. <dc:creator>Val Paliy</dc:creator>
  1080. </item>
  1081. <item>
  1082. <title>Why SEO Is Mostly Dead (And What Replaced It)</title>
  1083. <link>https://valticus.pro/posts/why-seo-is-mostly-dead-and-what-replaced-it/</link>
  1084. <pubDate>Mon, 01 Jun 2026 00:00:00 +0000</pubDate>
  1085. <guid isPermaLink="true">https://valticus.pro/posts/why-seo-is-mostly-dead-and-what-replaced-it/</guid>
  1086. <description>An analysis of how traditional SEO has evolved in 2026. Why keyword optimization no longer guarantees traffic and the strategies that work for visibility now.</description>
  1087. <category>Web Development</category><content:encoded>&lt;h2 id="the-seo-graveyard"&gt;The SEO Graveyard&lt;/h2&gt;
  1088. &lt;p&gt;For two decades, &lt;strong&gt;SEO&lt;/strong&gt; was the golden ticket: research keywords, optimize
  1089. content, build links, and watch traffic grow. That playbook is obsolete.
  1090. Traditional &lt;strong&gt;SEO&lt;/strong&gt;—the kind that focuses on &amp;ldquo;tricking&amp;rdquo; a crawler into ranking a
  1091. page—is fundamentally broken. In 2026, we aren&amp;rsquo;t just fighting for the top of
  1092. the &amp;ldquo;10 Blue Links&amp;rdquo;; we are fighting for survival in an ecosystem that is
  1093. increasingly hostile to external clicks.&lt;/p&gt;
  1094. &lt;p&gt;The era of the &amp;ldquo;Search Portal&amp;rdquo; is over. We have entered the era of the &amp;ldquo;&lt;strong&gt;Answer
  1095. Engine&lt;/strong&gt;,&amp;rdquo; where Google, Bing, and AI-native search tools like Perplexity aim to
  1096. keep users on their own platforms.&lt;/p&gt;
  1097. &lt;figure&gt;
  1098. &lt;div class="progressive-image"&gt;
  1099. &lt;img class="progressive-image__img"
  1100. src="https://valticus.pro/images/why-seo-is-mostly-dead-and-what-replaced-it_hu_344017820ead98ba.webp"
  1101. alt="Why SEO Is Mostly Dead (And What Replaced It)."
  1102. width="800"
  1103. height="436"&gt;
  1104. &lt;/div&gt;
  1105. &lt;figcaption&gt;&lt;p class="figure__caption"&gt;Why SEO Is Mostly Dead (And What Replaced It).&lt;/p&gt;&lt;/figcaption&gt;
  1106. &lt;/figure&gt;
  1107. &lt;h2 id="the-google-problem-zero-click-reality"&gt;The Google Problem: Zero-Click Reality&lt;/h2&gt;
  1108. &lt;p&gt;Google&amp;rsquo;s evolution into a &amp;ldquo;&lt;strong&gt;Search Generative Experience&lt;/strong&gt;&amp;rdquo; (&lt;strong&gt;SGE&lt;/strong&gt;) has
  1109. fundamentally changed the value proposition of being #1. Even if you rank first,
  1110. you are now buried under:&lt;/p&gt;
  1111. &lt;ul&gt;
  1112. &lt;li&gt;&lt;strong&gt;AI-generated Overviews&lt;/strong&gt;: Which summarize your content so the user never has
  1113. to click.&lt;/li&gt;
  1114. &lt;li&gt;&lt;strong&gt;Featured Snippets&lt;/strong&gt;: Which steal the &amp;ldquo;punchline&amp;rdquo; of your article.&lt;/li&gt;
  1115. &lt;li&gt;&lt;strong&gt;&amp;ldquo;People also ask&amp;rdquo;&lt;/strong&gt;: A recursive loop that keeps users engaged with Google&amp;rsquo;s
  1116. UI.&lt;/li&gt;
  1117. &lt;li&gt;&lt;strong&gt;Persistent Sponsored Content&lt;/strong&gt;: Organic results are often pushed below the
  1118. fold on mobile and desktop alike.&lt;/li&gt;
  1119. &lt;/ul&gt;
  1120. &lt;p&gt;The first page of Google is now real estate for Google&amp;rsquo;s own features. For many
  1121. informational queries, the &lt;strong&gt;click-through rate (CTR)&lt;/strong&gt; for the #1 organic
  1122. result has dropped by over 60% compared to five years ago.&lt;/p&gt;
  1123. &lt;h2 id="the-content-farm-collapse"&gt;The Content Farm Collapse&lt;/h2&gt;
  1124. &lt;p&gt;The &amp;ldquo;&lt;strong&gt;Helpful Content Updates&lt;/strong&gt;&amp;rdquo; of the last few years were the final nail in
  1125. the coffin for sites that relied on:&lt;/p&gt;
  1126. &lt;ul&gt;
  1127. &lt;li&gt;&lt;strong&gt;Keyword-stuffed articles&lt;/strong&gt; designed for bots, not humans.&lt;/li&gt;
  1128. &lt;li&gt;&lt;strong&gt;AI-slop&lt;/strong&gt;: Mass-produced, unverified content designed to capture long-tail
  1129. traffic.&lt;/li&gt;
  1130. &lt;li&gt;&lt;strong&gt;Programmatic SEO&lt;/strong&gt;: Thousands of pages with thin, repetitive data.&lt;/li&gt;
  1131. &lt;li&gt;&lt;strong&gt;Thin affiliate content&lt;/strong&gt;: Reviewing products without ever touching them.&lt;/li&gt;
  1132. &lt;/ul&gt;
  1133. &lt;p&gt;These tactics no longer work because search engines have pivoted from &lt;strong&gt;Keyword
  1134. Matching&lt;/strong&gt; to &lt;strong&gt;Entity Recognition&lt;/strong&gt;. They no longer look for the word &amp;ldquo;best
  1135. laptop&amp;rdquo;; they look for &amp;ldquo;Expertise&amp;rdquo; and &amp;ldquo;Authoritativeness&amp;rdquo; from a known entity.&lt;/p&gt;
  1136. &lt;h2 id="what-actually-works-now-visibility-over-seo"&gt;What Actually Works Now: Visibility over SEO&lt;/h2&gt;
  1137. &lt;p&gt;If &lt;strong&gt;SEO&lt;/strong&gt; is dead, what replaced it? The answer is &lt;strong&gt;Holistic Visibility&lt;/strong&gt;.
  1138. Instead of optimizing for an algorithm, you must optimize for &lt;strong&gt;Trust&lt;/strong&gt; and
  1139. &lt;strong&gt;Citability&lt;/strong&gt;.&lt;/p&gt;
  1140. &lt;h3 id="1-the-eeat-20-framework"&gt;1. The EEAT 2.0 Framework&lt;/h3&gt;
  1141. &lt;p&gt;&lt;strong&gt;Experience&lt;/strong&gt;, &lt;strong&gt;Expertise&lt;/strong&gt;, &lt;strong&gt;Authoritativeness&lt;/strong&gt;, and &lt;strong&gt;Trustworthiness&lt;/strong&gt;
  1142. (&lt;strong&gt;EEAT&lt;/strong&gt;) are no longer just &amp;ldquo;guidelines&amp;rdquo;—they are the core of the ranking
  1143. system.&lt;/p&gt;
  1144. &lt;ul&gt;
  1145. &lt;li&gt;&lt;strong&gt;Experience&lt;/strong&gt;: Can you prove you actually &lt;em&gt;did&lt;/em&gt; the thing you&amp;rsquo;re writing
  1146. about? This is why &amp;ldquo;I tried X for 30 days&amp;rdquo; content is outperforming &amp;ldquo;How to do
  1147. X&amp;rdquo; guides.&lt;/li&gt;
  1148. &lt;li&gt;&lt;strong&gt;Trust&lt;/strong&gt;: If an AI summarizes your content, will it cite you as the source?
  1149. &lt;strong&gt;Citability&lt;/strong&gt; is the new backlink.&lt;/li&gt;
  1150. &lt;/ul&gt;
  1151. &lt;h3 id="2-build-an-audience-not-just-traffic"&gt;2. Build an Audience, Not Just Traffic&lt;/h3&gt;
  1152. &lt;p&gt;The most successful creators in 2026 have one thing in common: they don&amp;rsquo;t rely
  1153. on Google.&lt;/p&gt;
  1154. &lt;ul&gt;
  1155. &lt;li&gt;&lt;strong&gt;Email Newsletters&lt;/strong&gt;: Owning your distribution means you aren&amp;rsquo;t at the mercy
  1156. of an algorithm update.&lt;/li&gt;
  1157. &lt;li&gt;&lt;strong&gt;RSS Feeds&lt;/strong&gt;: As I discussed in Slow Web Movement, allowing users to consume
  1158. your content on their own terms builds long-term loyalty.&lt;/li&gt;
  1159. &lt;li&gt;&lt;strong&gt;Direct Traffic&lt;/strong&gt;: Your goal should be to make your brand the destination,
  1160. not the search engine.&lt;/li&gt;
  1161. &lt;/ul&gt;
  1162. &lt;h2 id="the-shift-old-seo-vs-new-visibility"&gt;The Shift: Old SEO vs. New Visibility&lt;/h2&gt;
  1163. &lt;table&gt;
  1164. &lt;thead&gt;
  1165. &lt;tr&gt;
  1166. &lt;th style="text-align: left"&gt;Feature&lt;/th&gt;
  1167. &lt;th style="text-align: left"&gt;Old &lt;strong&gt;SEO&lt;/strong&gt; (Dead)&lt;/th&gt;
  1168. &lt;th style="text-align: left"&gt;New Visibility (Alive)&lt;/th&gt;
  1169. &lt;/tr&gt;
  1170. &lt;/thead&gt;
  1171. &lt;tbody&gt;
  1172. &lt;tr&gt;
  1173. &lt;td style="text-align: left"&gt;&lt;strong&gt;Focus&lt;/strong&gt;&lt;/td&gt;
  1174. &lt;td style="text-align: left"&gt;Keywords &amp;amp; &lt;strong&gt;Latent Semantic Indexing&lt;/strong&gt;&lt;/td&gt;
  1175. &lt;td style="text-align: left"&gt;Entities, Intent, and &lt;strong&gt;EEAT&lt;/strong&gt;&lt;/td&gt;
  1176. &lt;/tr&gt;
  1177. &lt;tr&gt;
  1178. &lt;td style="text-align: left"&gt;&lt;strong&gt;Success Metric&lt;/strong&gt;&lt;/td&gt;
  1179. &lt;td style="text-align: left"&gt;Search Rank &amp;amp; Page Views&lt;/td&gt;
  1180. &lt;td style="text-align: left"&gt;Citations, Subscriptions, Dwell Time&lt;/td&gt;
  1181. &lt;/tr&gt;
  1182. &lt;tr&gt;
  1183. &lt;td style="text-align: left"&gt;&lt;strong&gt;Content Type&lt;/strong&gt;&lt;/td&gt;
  1184. &lt;td style="text-align: left"&gt;Skimmable Listicles&lt;/td&gt;
  1185. &lt;td style="text-align: left"&gt;Deep Tutorials &amp;amp; Original Research&lt;/td&gt;
  1186. &lt;/tr&gt;
  1187. &lt;tr&gt;
  1188. &lt;td style="text-align: left"&gt;&lt;strong&gt;Distribution&lt;/strong&gt;&lt;/td&gt;
  1189. &lt;td style="text-align: left"&gt;&amp;ldquo;Post and Pray&amp;rdquo; to Google&lt;/td&gt;
  1190. &lt;td style="text-align: left"&gt;Multi-channel (&lt;strong&gt;RSS&lt;/strong&gt;, Email, Social)&lt;/td&gt;
  1191. &lt;/tr&gt;
  1192. &lt;tr&gt;
  1193. &lt;td style="text-align: left"&gt;&lt;strong&gt;AI Role&lt;/strong&gt;&lt;/td&gt;
  1194. &lt;td style="text-align: left"&gt;Used to generate volume&lt;/td&gt;
  1195. &lt;td style="text-align: left"&gt;Used to enhance research/depth&lt;/td&gt;
  1196. &lt;/tr&gt;
  1197. &lt;/tbody&gt;
  1198. &lt;/table&gt;
  1199. &lt;h2 id="technical-excellence-still-matters"&gt;Technical Excellence Still Matters&lt;/h2&gt;
  1200. &lt;p&gt;While &amp;ldquo;tricks&amp;rdquo; are dead, technical quality is more important than ever. If an
  1201. &lt;strong&gt;AI crawler&lt;/strong&gt; (like GPT-Bot or CCBot) can&amp;rsquo;t easily parse your site, you won&amp;rsquo;t
  1202. be cited in AI overviews.&lt;/p&gt;
  1203. &lt;blockquote&gt;
  1204. &lt;p&gt;&lt;strong&gt;Pro Tip: JSON-LD for Entity Recognition&lt;/strong&gt; Use advanced &lt;strong&gt;Schema.org&lt;/strong&gt; markup
  1205. to tell search engines exactly who you are and what your content represents.
  1206. Don&amp;rsquo;t just use &lt;code&gt;Article&lt;/code&gt; schema; use &lt;code&gt;ReviewedBy&lt;/code&gt;, &lt;code&gt;Specialty&lt;/code&gt;, and
  1207. &lt;code&gt;SignificantLink&lt;/code&gt; to build a &lt;strong&gt;semantic web&lt;/strong&gt; of trust around your content.&lt;/p&gt;
  1208. &lt;/blockquote&gt;
  1209. &lt;h3 id="schemaorg-checklist-for-ai-visibility"&gt;&lt;strong&gt;Schema.org&lt;/strong&gt; Checklist for AI Visibility&lt;/h3&gt;
  1210. &lt;ul&gt;
  1211. &lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;strong&gt;Author Schema&lt;/strong&gt;: Link to your LinkedIn, social media, and about page to
  1212. establish &amp;ldquo;&lt;strong&gt;Expertise&lt;/strong&gt;.&amp;rdquo;&lt;/li&gt;
  1213. &lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;strong&gt;Organization Schema&lt;/strong&gt;: Define your brand&amp;rsquo;s relationship to the topics
  1214. you cover.&lt;/li&gt;
  1215. &lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;strong&gt;FAQ Schema&lt;/strong&gt;: Help AI summaries find the &amp;ldquo;answers&amp;rdquo; in your content
  1216. quickly.&lt;/li&gt;
  1217. &lt;li&gt;&lt;input disabled="" type="checkbox"&gt; &lt;strong&gt;Breadcrumbs&lt;/strong&gt;: Establish a clear hierarchy for the crawler.&lt;/li&gt;
  1218. &lt;/ul&gt;
  1219. &lt;h2 id="the-rise-of-answer-engine-optimization-aeo"&gt;The Rise of &amp;ldquo;Answer Engine Optimization&amp;rdquo; (AEO)&lt;/h2&gt;
  1220. &lt;p&gt;As AI-powered search (Perplexity, ChatGPT) grows, we must optimize for
  1221. &lt;strong&gt;Answerability&lt;/strong&gt;.&lt;/p&gt;
  1222. &lt;ul&gt;
  1223. &lt;li&gt;&lt;strong&gt;Be the Source&lt;/strong&gt;: Provide original data or unique insights that AI models
  1224. will want to cite.&lt;/li&gt;
  1225. &lt;li&gt;&lt;strong&gt;Write for Citability&lt;/strong&gt;: Use clear, declarative statements that are easy for
  1226. an &lt;strong&gt;LLM&lt;/strong&gt; to extract and attribute.&lt;/li&gt;
  1227. &lt;li&gt;&lt;strong&gt;Performance&lt;/strong&gt;: As I&amp;rsquo;ve noted in SEO vs Performance: How to Balance Both,
  1228. speed is the baseline. If your site is slow, a crawler might time out before
  1229. it can index your &amp;ldquo;expert&amp;rdquo; opinion.&lt;/li&gt;
  1230. &lt;/ul&gt;
  1231. &lt;h2 id="the-human-factor-opinionated-content"&gt;The Human Factor: Opinionated Content&lt;/h2&gt;
  1232. &lt;p&gt;The one thing AI cannot replicate (yet) is a &lt;strong&gt;strong, human opinion&lt;/strong&gt;. AI is
  1233. great at summarizing the &amp;ldquo;average&amp;rdquo; view. To stand out, you must be anything
  1234. &lt;em&gt;but&lt;/em&gt; average.&lt;/p&gt;
  1235. &lt;ul&gt;
  1236. &lt;li&gt;Share your failures.&lt;/li&gt;
  1237. &lt;li&gt;Challenge the status quo.&lt;/li&gt;
  1238. &lt;li&gt;Write with a voice that is unmistakably yours.&lt;/li&gt;
  1239. &lt;/ul&gt;
  1240. &lt;p&gt;In 2026, the most valuable &amp;ldquo;&lt;strong&gt;SEO&lt;/strong&gt;&amp;rdquo; tool you have is your own perspective.&lt;/p&gt;
  1241. &lt;h2 id="conclusion-stop-optimizing-start-serving"&gt;Conclusion: Stop Optimizing, Start Serving&lt;/h2&gt;
  1242. &lt;p&gt;The death of traditional &lt;strong&gt;SEO&lt;/strong&gt; is actually a good thing for the web. It is
  1243. forcing creators to stop writing for bots and start writing for humans again.
  1244. The &amp;ldquo;optimization&amp;rdquo; of the future isn&amp;rsquo;t about where you place your keywords; it&amp;rsquo;s
  1245. about the value you provide to your readers.&lt;/p&gt;
  1246. &lt;p&gt;The sites that thrive in the next decade won&amp;rsquo;t be the ones with the most
  1247. backlinks or the perfect keyword density. They will be the most &lt;strong&gt;useful&lt;/strong&gt;, the
  1248. most &lt;strong&gt;trusted&lt;/strong&gt;, and the most &lt;strong&gt;human&lt;/strong&gt;.&lt;/p&gt;
  1249. &lt;p&gt;Stop chasing the algorithm. Build something worth citing.&lt;/p&gt;
  1250. </content:encoded>
  1251. <dc:creator>Val Paliy</dc:creator>
  1252. </item>
  1253. <item>
  1254. <title>SEO vs Performance: How to Balance Both</title>
  1255. <link>https://valticus.pro/posts/seo-vs-performance-how-to-balance-both/</link>
  1256. <pubDate>Mon, 25 May 2026 00:00:00 +0000</pubDate>
  1257. <guid isPermaLink="true">https://valticus.pro/posts/seo-vs-performance-how-to-balance-both/</guid>
  1258. <description>Practical strategies for balancing search engine optimization with website performance. Achieve great rankings without sacrificing speed or user experience.</description>
  1259. <category>Web Development</category>
  1260. <category>Technology</category><content:encoded>&lt;h2 id="the-false-dichotomy-speed-is-seo"&gt;The False Dichotomy: Speed is SEO&lt;/h2&gt;
  1261. &lt;p&gt;In the early days of the web, performance was a technical luxury. Today, it is a
  1262. foundational pillar of Search Engine Optimization. Yet, developers and marketers
  1263. often frame SEO and performance as opposing forces: SEO requires tracking
  1264. scripts, heavy images, and rich functionality that supposedly &amp;ldquo;hurts&amp;rdquo;
  1265. performance, while performance purists want to strip away every tag that might
  1266. delay a millisecond of rendering.&lt;/p&gt;
  1267. &lt;p&gt;This is a false dichotomy. In the modern era of &lt;strong&gt;Core Web Vitals&lt;/strong&gt;, performance
  1268. &lt;em&gt;is&lt;/em&gt; SEO. Google no longer just looks at what your page says; it looks at how
  1269. your page &lt;em&gt;behaves&lt;/em&gt;. If your site is slow, it doesn&amp;rsquo;t matter how well-optimized
  1270. your keywords are—you will be buried by faster, more responsive competitors.&lt;/p&gt;
  1271. &lt;figure&gt;
  1272. &lt;div class="progressive-image"&gt;
  1273. &lt;img class="progressive-image__img"
  1274. src="https://valticus.pro/images/how-i-built-this-site-and-the-tech-stack-i-regret_hu_30a85feb1fe7e88c.webp"
  1275. alt="SEO vs Performance: How to Balance Both."
  1276. width="800"
  1277. height="437"&gt;
  1278. &lt;/div&gt;
  1279. &lt;figcaption&gt;&lt;p class="figure__caption"&gt;SEO vs Performance: How to Balance Both.&lt;/p&gt;&lt;/figcaption&gt;
  1280. &lt;/figure&gt;
  1281. &lt;h2 id="where-they-align-the-core-web-vitals-era"&gt;Where They Align: The Core Web Vitals Era&lt;/h2&gt;
  1282. &lt;p&gt;Since the introduction of &lt;strong&gt;Core Web Vitals&lt;/strong&gt;, the alignment between &lt;strong&gt;user
  1283. experience (UX)&lt;/strong&gt; and &lt;strong&gt;SEO&lt;/strong&gt; has never been stronger. These metrics are
  1284. specifically designed to quantify the &amp;ldquo;real-world&amp;rdquo; experience of a user.&lt;/p&gt;
  1285. &lt;h3 id="1-largest-contentful-paint-lcp"&gt;1. Largest Contentful Paint (LCP)&lt;/h3&gt;
  1286. &lt;p&gt;&lt;strong&gt;LCP&lt;/strong&gt; measures when the largest content element (usually a hero image or
  1287. heading) becomes visible.&lt;/p&gt;
  1288. &lt;ul&gt;
  1289. &lt;li&gt;&lt;strong&gt;SEO Impact&lt;/strong&gt;: High &lt;strong&gt;LCP&lt;/strong&gt; scores tell Google your site is useful quickly.&lt;/li&gt;
  1290. &lt;li&gt;&lt;strong&gt;Performance Strategy&lt;/strong&gt;: Optimize the &lt;strong&gt;critical rendering path&lt;/strong&gt;. Preload
  1291. your hero images and ensure your &lt;strong&gt;server-side rendering (SSR)&lt;/strong&gt; or &lt;strong&gt;static
  1292. site generation (SSG)&lt;/strong&gt; is delivering HTML as fast as possible.&lt;/li&gt;
  1293. &lt;/ul&gt;
  1294. &lt;h3 id="2-interaction-to-next-paint-inp"&gt;2. Interaction to Next Paint (INP)&lt;/h3&gt;
  1295. &lt;p&gt;Replacing the older First Input Delay (FID), &lt;strong&gt;INP&lt;/strong&gt; measures the overall
  1296. responsiveness of your site to user inputs (clicks, taps, keyboard presses)
  1297. throughout the entire life of the page.&lt;/p&gt;
  1298. &lt;ul&gt;
  1299. &lt;li&gt;&lt;strong&gt;SEO Impact&lt;/strong&gt;: Google uses &lt;strong&gt;INP&lt;/strong&gt; to penalize &amp;ldquo;janky&amp;rdquo; sites that feel
  1300. sluggish.&lt;/li&gt;
  1301. &lt;li&gt;&lt;strong&gt;Performance Strategy&lt;/strong&gt;: Minimize &lt;strong&gt;main-thread blocking JavaScript&lt;/strong&gt;. Use
  1302. &lt;strong&gt;Web Workers&lt;/strong&gt; for heavy computations and avoid large, monolithic JS bundles.&lt;/li&gt;
  1303. &lt;/ul&gt;
  1304. &lt;h3 id="3-cumulative-layout-shift-cls"&gt;3. Cumulative Layout Shift (CLS)&lt;/h3&gt;
  1305. &lt;p&gt;&lt;strong&gt;CLS&lt;/strong&gt; measures visual stability. We&amp;rsquo;ve all experienced that frustrating moment
  1306. when a button moves just as we&amp;rsquo;re about to click it because an ad or image
  1307. loaded late.&lt;/p&gt;
  1308. &lt;ul&gt;
  1309. &lt;li&gt;&lt;strong&gt;SEO Impact&lt;/strong&gt;: Poor &lt;strong&gt;CLS&lt;/strong&gt; is a direct signal of low-quality &lt;strong&gt;UX&lt;/strong&gt;, which
  1310. negatively impacts rankings.&lt;/li&gt;
  1311. &lt;li&gt;&lt;strong&gt;Performance Strategy&lt;/strong&gt;: Always define &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; attributes for
  1312. images and video. Reserve space for dynamic elements like ads or embeds.&lt;/li&gt;
  1313. &lt;/ul&gt;
  1314. &lt;h2 id="common-conflicts-and-surgical-solutions"&gt;Common Conflicts and Surgical Solutions&lt;/h2&gt;
  1315. &lt;p&gt;While the goals align, the implementation often creates friction. Here is how to
  1316. handle the most common &amp;ldquo;SEO vs. Performance&amp;rdquo; battles.&lt;/p&gt;
  1317. &lt;h3 id="problem-third-party-scripts-the-silent-killer"&gt;Problem: Third-Party Scripts (The Silent Killer)&lt;/h3&gt;
  1318. &lt;p&gt;Marketers demand &lt;strong&gt;Google Tag Manager (GTM)&lt;/strong&gt;, HubSpot, Hotjar, and multiple
  1319. social pixels. Each of these adds a &lt;strong&gt;DNS lookup&lt;/strong&gt;, a &lt;strong&gt;TCP connection&lt;/strong&gt;, and
  1320. execution time on the main thread.&lt;/p&gt;
  1321. &lt;p&gt;&lt;strong&gt;Solution: The &amp;ldquo;Partytown&amp;rdquo; Approach or Server-Side Tracking&lt;/strong&gt; Instead of
  1322. loading everything in the browser, consider &lt;strong&gt;server-side tagging&lt;/strong&gt;. If you must
  1323. use client-side scripts, use the &lt;code&gt;defer&lt;/code&gt; or &lt;code&gt;async&lt;/code&gt; attributes, or better yet,
  1324. use a library like &lt;strong&gt;Partytown&lt;/strong&gt; to run intensive scripts in a &lt;strong&gt;Web Worker&lt;/strong&gt;.&lt;/p&gt;
  1325. &lt;blockquote&gt;
  1326. &lt;p&gt;&lt;strong&gt;Pro Tip: The GTM Audit&lt;/strong&gt; Never allow &amp;ldquo;container bloat.&amp;rdquo; Every 6 months,
  1327. audit your &lt;strong&gt;GTM&lt;/strong&gt; container. If a pixel isn&amp;rsquo;t actively being used for a live
  1328. campaign, delete it. A single abandoned LinkedIn pixel can add 200ms to your
  1329. &lt;strong&gt;Total Blocking Time (TBT)&lt;/strong&gt;.&lt;/p&gt;
  1330. &lt;/blockquote&gt;
  1331. &lt;h3 id="problem-high-resolution-visual-content"&gt;Problem: High-Resolution Visual Content&lt;/h3&gt;
  1332. &lt;p&gt;SEO experts want &amp;ldquo;rich&amp;rdquo; content with infographics and high-quality hero shots to
  1333. keep users engaged (and improve &amp;ldquo;Dwell Time&amp;rdquo;). Performance fans want 20KB
  1334. placeholders.&lt;/p&gt;
  1335. &lt;p&gt;&lt;strong&gt;Solution: Automated Modern Formats&lt;/strong&gt; Don&amp;rsquo;t choose between quality and speed.
  1336. Use Hugo&amp;rsquo;s built-in image processing to generate &lt;strong&gt;WebP&lt;/strong&gt; and &lt;strong&gt;AVIF&lt;/strong&gt; versions
  1337. of your images automatically.&lt;/p&gt;
  1338. &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go-html-template" &gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cm"&gt;{{/* Example: Hugo Image Optimization Snippet */}}&lt;/span&gt;
  1339. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$image&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;.Page.Resources.GetMatch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;hero.jpg&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;}}&lt;/span&gt;
  1340. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$image&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;}}&lt;/span&gt;
  1341. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="cp"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$webp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$image&lt;/span&gt;&lt;span class="na"&gt;.Resize&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;1200x webp q85&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;}}&lt;/span&gt;
  1342. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;picture&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1343. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;source&lt;/span&gt; &lt;span class="na"&gt;srcset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$webp&lt;/span&gt;&lt;span class="na"&gt;.RelPermalink&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;image/webp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1344. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$image&lt;/span&gt;&lt;span class="na"&gt;.RelPermalink&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&lt;/span&gt;
  1345. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$image&lt;/span&gt;&lt;span class="na"&gt;.Width&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&lt;/span&gt;
  1346. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$image&lt;/span&gt;&lt;span class="na"&gt;.Height&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&lt;/span&gt;
  1347. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;.Page.Title&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&lt;/span&gt;
  1348. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;loading&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;eager&amp;#34;&lt;/span&gt;
  1349. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;fetchpriority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;high&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1350. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;picture&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1351. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;}}&lt;/span&gt;
  1352. &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="the-asset-value-vs-performance-impact-matrix"&gt;The &amp;ldquo;Asset Value vs. Performance Impact&amp;rdquo; Matrix&lt;/h2&gt;
  1353. &lt;p&gt;When deciding whether to add a new feature or script, use this comparison table
  1354. to evaluate the trade-off:&lt;/p&gt;
  1355. &lt;table&gt;
  1356. &lt;thead&gt;
  1357. &lt;tr&gt;
  1358. &lt;th style="text-align: left"&gt;Asset Type&lt;/th&gt;
  1359. &lt;th style="text-align: left"&gt;SEO Value&lt;/th&gt;
  1360. &lt;th style="text-align: left"&gt;Performance Cost&lt;/th&gt;
  1361. &lt;th style="text-align: left"&gt;Recommendation&lt;/th&gt;
  1362. &lt;/tr&gt;
  1363. &lt;/thead&gt;
  1364. &lt;tbody&gt;
  1365. &lt;tr&gt;
  1366. &lt;td style="text-align: left"&gt;&lt;strong&gt;Semantic HTML&lt;/strong&gt;&lt;/td&gt;
  1367. &lt;td style="text-align: left"&gt;Extremely High&lt;/td&gt;
  1368. &lt;td style="text-align: left"&gt;Zero&lt;/td&gt;
  1369. &lt;td style="text-align: left"&gt;Always use. Essential for crawlers.&lt;/td&gt;
  1370. &lt;/tr&gt;
  1371. &lt;tr&gt;
  1372. &lt;td style="text-align: left"&gt;&lt;strong&gt;JSON-LD Schema&lt;/strong&gt;&lt;/td&gt;
  1373. &lt;td style="text-align: left"&gt;High&lt;/td&gt;
  1374. &lt;td style="text-align: left"&gt;Low&lt;/td&gt;
  1375. &lt;td style="text-align: left"&gt;Always use. Negligible impact on speed.&lt;/td&gt;
  1376. &lt;/tr&gt;
  1377. &lt;tr&gt;
  1378. &lt;td style="text-align: left"&gt;&lt;strong&gt;Optimized Images&lt;/strong&gt;&lt;/td&gt;
  1379. &lt;td style="text-align: left"&gt;High&lt;/td&gt;
  1380. &lt;td style="text-align: left"&gt;Medium&lt;/td&gt;
  1381. &lt;td style="text-align: left"&gt;Use &lt;code&gt;srcset&lt;/code&gt; and modern formats.&lt;/td&gt;
  1382. &lt;/tr&gt;
  1383. &lt;tr&gt;
  1384. &lt;td style="text-align: left"&gt;&lt;strong&gt;Web Fonts&lt;/strong&gt;&lt;/td&gt;
  1385. &lt;td style="text-align: left"&gt;Medium&lt;/td&gt;
  1386. &lt;td style="text-align: left"&gt;Medium/High&lt;/td&gt;
  1387. &lt;td style="text-align: left"&gt;Use &lt;code&gt;font-display: swap&lt;/code&gt; and preload critical weights.&lt;/td&gt;
  1388. &lt;/tr&gt;
  1389. &lt;tr&gt;
  1390. &lt;td style="text-align: left"&gt;&lt;strong&gt;Client-side Chat Bot&lt;/strong&gt;&lt;/td&gt;
  1391. &lt;td style="text-align: left"&gt;Low&lt;/td&gt;
  1392. &lt;td style="text-align: left"&gt;Very High&lt;/td&gt;
  1393. &lt;td style="text-align: left"&gt;Load on user interaction only (Lazy Load).&lt;/td&gt;
  1394. &lt;/tr&gt;
  1395. &lt;tr&gt;
  1396. &lt;td style="text-align: left"&gt;&lt;strong&gt;Full GTM Container&lt;/strong&gt;&lt;/td&gt;
  1397. &lt;td style="text-align: left"&gt;Medium&lt;/td&gt;
  1398. &lt;td style="text-align: left"&gt;High&lt;/td&gt;
  1399. &lt;td style="text-align: left"&gt;Audit frequently and use server-side tracking.&lt;/td&gt;
  1400. &lt;/tr&gt;
  1401. &lt;/tbody&gt;
  1402. &lt;/table&gt;
  1403. &lt;h2 id="the-hydration-problem-spa-vs-ssg"&gt;The &amp;ldquo;Hydration&amp;rdquo; Problem: SPA vs. SSG&lt;/h2&gt;
  1404. &lt;p&gt;If you are using a modern framework like &lt;strong&gt;Next.js&lt;/strong&gt; or &lt;strong&gt;Nuxt&lt;/strong&gt;,
  1405. &amp;ldquo;&lt;strong&gt;Hydration&lt;/strong&gt;&amp;rdquo; is your biggest performance enemy. This is the process where the
  1406. browser downloads JavaScript to make a static-looking page interactive. For a
  1407. content-heavy site, this is often overkill.&lt;/p&gt;
  1408. &lt;p&gt;&lt;strong&gt;Static Site Generators&lt;/strong&gt; like &lt;strong&gt;Hugo&lt;/strong&gt; (which powers this site) avoid this
  1409. entirely. By delivering pre-rendered HTML and only adding JavaScript where
  1410. absolutely necessary, you achieve the &amp;ldquo;Gold Standard&amp;rdquo; of SEO: content that is
  1411. instantly indexable &lt;em&gt;and&lt;/em&gt; instantly interactive.&lt;/p&gt;
  1412. &lt;p&gt;If you want to dive deeper into how I optimize my Hugo setup for maximum
  1413. throughput, I will cover advanced techniques in a future article.&lt;/p&gt;
  1414. &lt;h2 id="technical-checklist-for-performance-first-seo"&gt;Technical Checklist for Performance-First SEO&lt;/h2&gt;
  1415. &lt;p&gt;To ensure you aren&amp;rsquo;t sacrificing one for the other, follow this checklist during
  1416. your next build:&lt;/p&gt;
  1417. &lt;ol&gt;
  1418. &lt;li&gt;&lt;strong&gt;[ ] Zero-render-blocking CSS&lt;/strong&gt;: Inline &lt;strong&gt;critical CSS&lt;/strong&gt; and load the rest
  1419. asynchronously.&lt;/li&gt;
  1420. &lt;li&gt;&lt;strong&gt;[ ] Font Subsetting&lt;/strong&gt;: Don&amp;rsquo;t load the entire &amp;ldquo;Roboto&amp;rdquo; family. Only load the
  1421. characters you actually use (e.g., Latin-1).&lt;/li&gt;
  1422. &lt;li&gt;&lt;strong&gt;[ ] Resource Hints&lt;/strong&gt;: Use &lt;code&gt;preconnect&lt;/code&gt; for essential third-party domains
  1423. (like your &lt;strong&gt;CDN&lt;/strong&gt;) and &lt;code&gt;dns-prefetch&lt;/code&gt; for the rest.&lt;/li&gt;
  1424. &lt;li&gt;&lt;strong&gt;[ ] Image Dimensions&lt;/strong&gt;: Hardcode width/height to eliminate &lt;strong&gt;CLS&lt;/strong&gt;.&lt;/li&gt;
  1425. &lt;li&gt;&lt;strong&gt;[ ] Lazy Loading&lt;/strong&gt;: Apply &lt;code&gt;loading=&amp;quot;lazy&amp;quot;&lt;/code&gt; to everything below the fold.&lt;/li&gt;
  1426. &lt;/ol&gt;
  1427. &lt;h2 id="common-pitfall-the-lighthouse-score-trap"&gt;Common Pitfall: The &amp;ldquo;Lighthouse Score&amp;rdquo; Trap&lt;/h2&gt;
  1428. &lt;p&gt;Don&amp;rsquo;t get obsessed with hitting a 100/100 &lt;strong&gt;Lighthouse score&lt;/strong&gt; at the expense of
  1429. functionality. A 95 score with a high-converting &amp;ldquo;Buy Now&amp;rdquo; button is better for
  1430. your business than a 100 score on a page that is too stripped down to be useful.&lt;/p&gt;
  1431. &lt;p&gt;The goal is &lt;strong&gt;Perceived Performance&lt;/strong&gt;. If the user &lt;em&gt;feels&lt;/em&gt; like the site is
  1432. instant, and Google&amp;rsquo;s bots can find the content without being blocked by a
  1433. massive JavaScript bundle, you&amp;rsquo;ve won the game.&lt;/p&gt;
  1434. &lt;h2 id="conclusion-the-holistic-view"&gt;Conclusion: The Holistic View&lt;/h2&gt;
  1435. &lt;p&gt;In 2026, the wall between the &amp;ldquo;Performance Engineer&amp;rdquo; and the &amp;ldquo;SEO Specialist&amp;rdquo;
  1436. has crumbled. You can no longer optimize for one without deeply understanding
  1437. the other. The most successful sites are those built on a foundation of
  1438. &lt;strong&gt;Technical Excellence&lt;/strong&gt;.&lt;/p&gt;
  1439. &lt;p&gt;Start with a fast, static foundation. Add your SEO elements surgically. Monitor
  1440. your &lt;strong&gt;Core Web Vitals&lt;/strong&gt; religiously. When you treat performance as a core
  1441. feature of your SEO strategy, you stop fighting the algorithms and start serving
  1442. your audience. And that is exactly what Google wants to reward.&lt;/p&gt;
  1443. </content:encoded>
  1444. <dc:creator>Val Paliy</dc:creator>
  1445. </item>
  1446. <item>
  1447. <title>Inside Google Search's Most Radical Redesign in 25 Years</title>
  1448. <link>https://valticus.pro/posts/google-search-radical-redesign/</link>
  1449. <pubDate>Fri, 22 May 2026 00:00:00 +0000</pubDate>
  1450. <guid isPermaLink="true">https://valticus.pro/posts/google-search-radical-redesign/</guid>
  1451. <description>An in-depth analysis of Google Search's most radical redesign in 25 years. How AI, SGE, and new UI paradigms are reshaping the search experience for everyone.</description>
  1452. <category>Technology</category>
  1453. <category>Web Development</category><content:encoded>&lt;h2 id="the-death-of-the-ten-blue-links-paradigm"&gt;The Death of the Ten Blue Links Paradigm&lt;/h2&gt;
  1454. &lt;p&gt;For more than a quarter of a century, the basic interface of the internet
  1455. remained remarkably unchanged. You opened a browser, navigated to a stark white
  1456. homepage with a single search bar, typed in a string of fragmented keywords, and
  1457. pressed enter. In return, you received a list of ten blue links.&lt;/p&gt;
  1458. &lt;p&gt;That era is officially over.&lt;/p&gt;
  1459. &lt;p&gt;Google Search is currently undergoing its most radical redesign since its
  1460. inception in 1998. The search engine is pivoting from a passive keyword-matching
  1461. directory into an active, conversational AI engine powered by Google&amp;rsquo;s frontier
  1462. models. Traditional search results still exist, but they are now heavily
  1463. deprioritized in favor of direct, AI-synthesized answers, interactive
  1464. applications built on the fly, and autonomous background search agents.&lt;/p&gt;
  1465. &lt;figure&gt;
  1466. &lt;div class="progressive-image"&gt;
  1467. &lt;img class="progressive-image__img"
  1468. src="https://valticus.pro/images/google-search-radical-redesign_hu_9de31e5f3d972ecd.webp"
  1469. alt="Inside Google Search&amp;#39;s Most Radical Redesign in 25 Years."
  1470. width="800"
  1471. height="800"&gt;
  1472. &lt;/div&gt;
  1473. &lt;figcaption&gt;&lt;p class="figure__caption"&gt;Inside Google Search&amp;#39;s Most Radical Redesign in 25 Years.&lt;/p&gt;&lt;/figcaption&gt;
  1474. &lt;/figure&gt;
  1475. &lt;p&gt;Here is a technical breakdown of the major changes rolling out and what they
  1476. mean for the future of both consumers and web creators.&lt;/p&gt;
  1477. &lt;hr&gt;
  1478. &lt;h2 id="1-the-conversational-ai-search-box"&gt;1. The Conversational AI Search Box&lt;/h2&gt;
  1479. &lt;p&gt;The iconic blank search bar has been completely reimagined. It is no longer a
  1480. simple text input box but a dynamic canvas designed to accept multi-modal
  1481. queries.&lt;/p&gt;
  1482. &lt;ul&gt;
  1483. &lt;li&gt;&lt;strong&gt;Dynamic Expansion:&lt;/strong&gt; The new search box expands as you interact with it,
  1484. inviting more than just text queries.&lt;/li&gt;
  1485. &lt;li&gt;&lt;strong&gt;Multi-Modal Inputs:&lt;/strong&gt; Users can now seamlessly input text, images, videos,
  1486. spreadsheets, PDFs, and even link open Chrome tabs directly into the search
  1487. context.&lt;/li&gt;
  1488. &lt;li&gt;&lt;strong&gt;Deep Contextual Queries:&lt;/strong&gt; Instead of searching &amp;ldquo;best running shoes,&amp;rdquo; a user
  1489. can upload a video of their running gait, link a spreadsheet of their budget
  1490. constraints, and ask: &lt;em&gt;&amp;ldquo;Based on my gait and these prices, which shoe should I
  1491. buy?&amp;rdquo;&lt;/em&gt;&lt;/li&gt;
  1492. &lt;/ul&gt;
  1493. &lt;p&gt;This shifts user behavior from &amp;ldquo;keyword hacking&amp;rdquo; to natural, conversational
  1494. problem-solving.&lt;/p&gt;
  1495. &lt;hr&gt;
  1496. &lt;h2 id="2-gemini-35-flash-as-the-default-engine"&gt;2. Gemini 3.5 Flash as the Default Engine&lt;/h2&gt;
  1497. &lt;p&gt;Speed has always been a key ranking factor, but in AI search, speed is the
  1498. difference between a tool feeling like a helper or a hindrance.&lt;/p&gt;
  1499. &lt;p&gt;Google has deployed &lt;strong&gt;Gemini 3.5 Flash&lt;/strong&gt; globally as the default engine powering
  1500. all &amp;ldquo;AI Mode&amp;rdquo; searches. This frontier AI model has been optimized for low
  1501. latency and high throughput, making conversational answers load almost
  1502. instantaneously.&lt;/p&gt;
  1503. &lt;p&gt;This change solves the early complaint of &amp;ldquo;AI Overviews&amp;rdquo; taking too long to
  1504. generate compared to traditional blue links. With Gemini 3.5 Flash, the
  1505. conversational response is compiled and streamed in real-time, matching or
  1506. exceeding the speed of legacy search queries.&lt;/p&gt;
  1507. &lt;hr&gt;
  1508. &lt;h2 id="3-247-information-agents"&gt;3. 24/7 Information Agents&lt;/h2&gt;
  1509. &lt;p&gt;Perhaps the most significant paradigm shift is the introduction of &lt;strong&gt;Autonomous
  1510. Search Agents&lt;/strong&gt;.&lt;/p&gt;
  1511. &lt;p&gt;Instead of performing the same manual search every few days, users (initially
  1512. rolling out to Google One AI Premium subscribers, including AI Pro and Ultra
  1513. tiers) can spin up persistent background agents.&lt;/p&gt;
  1514. &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" &gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Prompt: &amp;#34;Monitor the web for new 2-bedroom apartment listings in downtown Austin under $2,500/month that are pet-friendly, and alert me the moment they are posted.&amp;#34;
  1515. &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once activated, these agents work 24/7. They continuously query, filter, and
  1516. analyze the web, sending structured notifications and updates directly to the
  1517. user. This turns Google Search from a pull-based tool (where you must go look
  1518. for info) to a push-based service (where the info finds you).&lt;/p&gt;
  1519. &lt;hr&gt;
  1520. &lt;h2 id="4-generative-ui-on-the-fly-micro-apps"&gt;4. Generative UI: On-the-Fly Micro-Apps&lt;/h2&gt;
  1521. &lt;p&gt;Traditionally, Google served static answers or extracted snippets. Now, Google
  1522. Search can code and build custom, interactive widgets and visualizations on the
  1523. fly.&lt;/p&gt;
  1524. &lt;p&gt;If a user inputs a complex math query or asks for a comparison of multiple
  1525. financial options, Google Search writes code behind the scenes and renders a
  1526. custom interactive interface:&lt;/p&gt;
  1527. &lt;ul&gt;
  1528. &lt;li&gt;&lt;strong&gt;Dynamic Graphs:&lt;/strong&gt; Real-time plotting of data based on user queries.&lt;/li&gt;
  1529. &lt;li&gt;&lt;strong&gt;Interactive Simulations:&lt;/strong&gt; Adjust sliders to see how changes affect a
  1530. scenario (e.g., mortgage interest calculators).&lt;/li&gt;
  1531. &lt;li&gt;&lt;strong&gt;Mini-Apps:&lt;/strong&gt; Custom comparison charts or calculators built on the fly
  1532. specifically for that user&amp;rsquo;s query.&lt;/li&gt;
  1533. &lt;/ul&gt;
  1534. &lt;p&gt;For developers and webmasters, this is a massive shift: Google is no longer just
  1535. crawling your content; it is replacing the utility of simple web applications
  1536. directly on the search page.&lt;/p&gt;
  1537. &lt;hr&gt;
  1538. &lt;h2 id="5-expanded-personal-intelligence"&gt;5. Expanded Personal Intelligence&lt;/h2&gt;
  1539. &lt;p&gt;Google is leveraging its ecosystem advantage by connecting Search directly to
  1540. your personal data.&lt;/p&gt;
  1541. &lt;p&gt;Without requiring a premium subscription, the search engine now securely
  1542. connects to your Google workspace apps, including:&lt;/p&gt;
  1543. &lt;ul&gt;
  1544. &lt;li&gt;&lt;strong&gt;Gmail:&lt;/strong&gt; Finding flight confirmations, receipts, or email threads.&lt;/li&gt;
  1545. &lt;li&gt;&lt;strong&gt;Google Photos:&lt;/strong&gt; Searching for specific objects or dates in your photo
  1546. history.&lt;/li&gt;
  1547. &lt;li&gt;&lt;strong&gt;Google Calendar (Upcoming):&lt;/strong&gt; Cross-referencing schedules to answer personal
  1548. planning queries.&lt;/li&gt;
  1549. &lt;/ul&gt;
  1550. &lt;p&gt;Google implements strict privacy boundaries, ensuring personal data is never
  1551. used to train public AI models or served to other users. However, for the end
  1552. user, Google Search is now a unified personal assistant that knows both the
  1553. public web and your private life.&lt;/p&gt;
  1554. &lt;hr&gt;
  1555. &lt;h2 id="6-the-webmaster-impact-faq-rich-results-phased-out"&gt;6. The Webmaster Impact: FAQ Rich Results Phased Out&lt;/h2&gt;
  1556. &lt;p&gt;On the SEO and web publisher side, Google has quietly made a major change: the
  1557. official removal of &lt;strong&gt;FAQ rich results&lt;/strong&gt; from search pages.&lt;/p&gt;
  1558. &lt;p&gt;For years, webmasters used Schema.org structured data to add expandable Q&amp;amp;A
  1559. dropdowns under their search listings, occupying valuable organic real estate.
  1560. Google has phased these out to declutter the Search Engine Results Pages (SERPs)
  1561. and free up space for AI summaries and Generative UI widgets.&lt;/p&gt;
  1562. &lt;p&gt;This signals a clear message to webmasters: Google is reclaiming the SERP space.
  1563. If you want visibility, you can no longer rely on simple schema hacks to stand
  1564. out.&lt;/p&gt;
  1565. &lt;hr&gt;
  1566. &lt;h2 id="what-this-means-for-seo-and-web-publishers"&gt;What This Means for SEO and Web Publishers&lt;/h2&gt;
  1567. &lt;p&gt;This redesign marks the transition from &lt;strong&gt;SEO (Search Engine Optimization)&lt;/strong&gt; to
  1568. &lt;strong&gt;AEO (Answer Engine Optimization)&lt;/strong&gt;.&lt;/p&gt;
  1569. &lt;p&gt;If Google is synthesizing answers directly on the page and using autonomous
  1570. agents to fetch updates, traffic to traditional content sites will inevitably
  1571. decline for simple informational queries.&lt;/p&gt;
  1572. &lt;p&gt;To survive in this new ecosystem, web publishers must adapt:&lt;/p&gt;
  1573. &lt;ol&gt;
  1574. &lt;li&gt;&lt;strong&gt;Optimize for LLM Retrieval:&lt;/strong&gt; Ensure your content is structured clearly,
  1575. with authoritative, original insights that AI models want to cite.&lt;/li&gt;
  1576. &lt;li&gt;&lt;strong&gt;Prioritize Deep Context:&lt;/strong&gt; Simple &amp;ldquo;what is&amp;rdquo; articles are easily answered by
  1577. Gemini. Focus on high-value, experiential content, personal case studies, and
  1578. deep technical guides that AI cannot easily replicate.&lt;/li&gt;
  1579. &lt;li&gt;&lt;strong&gt;Build Direct Brand Audience:&lt;/strong&gt; Do not rely solely on Google for traffic.
  1580. Invest in newsletters, direct communities, and bookmark-worthy content that
  1581. users seek out directly.&lt;/li&gt;
  1582. &lt;/ol&gt;
  1583. &lt;p&gt;For more technical guidance on navigating this transition, consult Google&amp;rsquo;s
  1584. official documentation. You can read the
  1585. &lt;a href="https://blog.google"&gt;Official Announcement on the Google Blog&lt;/a&gt; or dive into the
  1586. strategies outlined in Google&amp;rsquo;s AEO Guide to align your website with these
  1587. architectural changes.&lt;/p&gt;
  1588. </content:encoded>
  1589. <dc:creator>Val Paliy</dc:creator>
  1590. </item>
  1591. <item>
  1592. <title>Build a Portfolio Without React: A Step-by-Step Guide</title>
  1593. <link>https://valticus.pro/posts/build-a-portfolio-without-react-a-step-by-step-guide/</link>
  1594. <pubDate>Thu, 21 May 2026 00:00:00 +0000</pubDate>
  1595. <guid isPermaLink="true">https://valticus.pro/posts/build-a-portfolio-without-react-a-step-by-step-guide/</guid>
  1596. <description>A comprehensive tutorial for creating a developer portfolio without React or JavaScript frameworks. Learn semantic HTML, CSS, and static site techniques.</description>
  1597. <category>Web Development</category><content:encoded>&lt;h2 id="why-skip-react-for-your-portfolio"&gt;Why Skip React for Your Portfolio?&lt;/h2&gt;
  1598. &lt;p&gt;If you&amp;rsquo;re a React developer, building your portfolio with React seems like a
  1599. &amp;ldquo;no-brainer.&amp;rdquo; It shows you know the framework, right? Not necessarily. In 2026,
  1600. the real mark of a senior developer is the ability to choose the &lt;strong&gt;right tool
  1601. for the job&lt;/strong&gt;, not just the one they are most comfortable with.&lt;/p&gt;
  1602. &lt;p&gt;Reaching for a heavy JavaScript framework for a site that is essentially 90%
  1603. static text and images introduces what I call the &lt;strong&gt;&amp;ldquo;React Tax&amp;rdquo;&lt;/strong&gt;:&lt;/p&gt;
  1604. &lt;ul&gt;
  1605. &lt;li&gt;&lt;strong&gt;Bundle Bloat&lt;/strong&gt;: You&amp;rsquo;re shipping 40KB+ of framework code before the user sees
  1606. a single pixel.&lt;/li&gt;
  1607. &lt;li&gt;&lt;strong&gt;Hydration Cost&lt;/strong&gt;: The browser has to execute JavaScript just to make your
  1608. text readable.&lt;/li&gt;
  1609. &lt;li&gt;&lt;strong&gt;Maintenance&lt;/strong&gt;: Dependencies rot. A portfolio built in React 18 will need an
  1610. upgrade in two years; a portfolio built in Hugo or raw HTML will work for a
  1611. decade.&lt;/li&gt;
  1612. &lt;/ul&gt;
  1613. &lt;figure&gt;
  1614. &lt;div class="progressive-image"&gt;
  1615. &lt;img class="progressive-image__img"
  1616. src="https://valticus.pro/images/build-a-portfolio-without-react-a-step-by-step-guide_hu_d5b85cabf12c9284.webp"
  1617. alt="Build a Portfolio Without React: A Step-by-Step Guide."
  1618. width="800"
  1619. height="436"&gt;
  1620. &lt;/div&gt;
  1621. &lt;figcaption&gt;&lt;p class="figure__caption"&gt;Build a Portfolio Without React: A Step-by-Step Guide.&lt;/p&gt;&lt;/figcaption&gt;
  1622. &lt;/figure&gt;
  1623. &lt;p&gt;A portfolio built with static HTML and modern CSS demonstrates that you
  1624. understand the &lt;strong&gt;web&amp;rsquo;s fundamentals&lt;/strong&gt;: performance, accessibility, and the DOM.&lt;/p&gt;
  1625. &lt;h2 id="choose-your-approach-the-content-first-model"&gt;Choose Your Approach: The Content-First Model&lt;/h2&gt;
  1626. &lt;p&gt;While you could write every HTML file by hand, a &lt;strong&gt;Static Site Generator (SSG)&lt;/strong&gt;
  1627. gives you the best of both worlds: a component-like development experience
  1628. without the client-side overhead.&lt;/p&gt;
  1629. &lt;p&gt;In this guide, we’ll use &lt;strong&gt;Hugo&lt;/strong&gt;. In a previous comparison of static site
  1630. generators, I&amp;rsquo;ve noted that Hugo is the gold standard for speed and developer
  1631. experience in the static world.&lt;/p&gt;
  1632. &lt;h2 id="step-1-initialize-your-project"&gt;Step 1: Initialize Your Project&lt;/h2&gt;
  1633. &lt;p&gt;First, install Hugo and scaffold your site. We’re going to build this without a
  1634. pre-made theme to truly understand the architecture.&lt;/p&gt;
  1635. &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" &gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo new site my-portfolio
  1636. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; my-portfolio
  1637. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git init
  1638. &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Create your basic layout structure:&lt;/p&gt;
  1639. &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" &gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir -p layouts/_default layouts/partials
  1640. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;touch layouts/_default/baseof.html layouts/_default/list.html layouts/_default/single.html
  1641. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;touch layouts/index.html
  1642. &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="step-2-the-base-template"&gt;Step 2: The &amp;ldquo;Base&amp;rdquo; Template&lt;/h2&gt;
  1643. &lt;p&gt;The &lt;code&gt;baseof.html&lt;/code&gt; file is your &amp;ldquo;Master Page.&amp;rdquo; It contains the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; and the
  1644. structure shared by every page.&lt;/p&gt;
  1645. &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-html" &gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
  1646. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;html&lt;/span&gt; &lt;span class="na"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;en&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1647. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1648. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;meta&lt;/span&gt; &lt;span class="na"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;UTF-8&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  1649. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;meta&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;viewport&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;width=device-width, initial-scale=1.0&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  1650. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;{{ .Title }} | {{ .Site.Title }}&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1651. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;link&lt;/span&gt; &lt;span class="na"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;stylesheet&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;/css/style.css&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  1652. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1653. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1654. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; {{ partial &amp;#34;header.html&amp;#34; . }}
  1655. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;{{ block &amp;#34;main&amp;#34; . }}{{ end }}&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1656. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; {{ partial &amp;#34;footer.html&amp;#34; . }}
  1657. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1658. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1659. &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="step-3-architecture-for-projects"&gt;Step 3: Architecture for Projects&lt;/h2&gt;
  1660. &lt;p&gt;Your projects should be &amp;ldquo;First Class Citizens&amp;rdquo; in your codebase. Instead of
  1661. hardcoding them into the homepage, use Hugo&amp;rsquo;s content model.&lt;/p&gt;
  1662. &lt;p&gt;Create your projects:&lt;/p&gt;
  1663. &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" &gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo new projects/my-cool-app.md
  1664. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;hugo new projects/api-wrapper.md
  1665. &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the markdown frontmatter, add custom metadata:&lt;/p&gt;
  1666. &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" &gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
  1667. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;The Ultimate API Wrapper&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
  1668. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;A high-performance Go library for handling rate-limited APIs.&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
  1669. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;tech_stack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Go&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Redis&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Docker&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  1670. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;github_link&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;https://github.com/valpaliy/api-wrapper&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
  1671. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;featured&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
  1672. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;images/projects/api-wrapper.jpg&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
  1673. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
  1674. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="step-4-the-project-gallery-the-hugo-logic"&gt;Step 4: The Project Gallery (The Hugo Logic)&lt;/h2&gt;
  1675. &lt;p&gt;Now, let’s build a component that automatically lists your featured projects on
  1676. the homepage (&lt;code&gt;layouts/index.html&lt;/code&gt;).&lt;/p&gt;
  1677. &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-html" &gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;{{ define &amp;#34;main&amp;#34; }}
  1678. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;hero&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1679. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hi, I&amp;#39;m {{ .Site.Author.name }}&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1680. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;I build high-performance web experiences without the fluff.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1681. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1682. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
  1683. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;projects-grid&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1684. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; {{ range where .Site.RegularPages &amp;#34;Section&amp;#34; &amp;#34;projects&amp;#34; }} {{ if
  1685. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; .Params.featured }}
  1686. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;project-card&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1687. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;{{ .Params.image }}&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;{{ .Title }}&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  1688. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;{{ .Title }}&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1689. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;{{ .Description }}&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1690. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;tags&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1691. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; {{ range .Params.tech_stack }}
  1692. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;tag&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;{{ . }}&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1693. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; {{ end }}
  1694. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1695. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;{{ .Permalink }}&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;btn&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;View Case Study&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1696. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1697. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; {{ end }} {{ end }}
  1698. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  1699. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;{{ end }}
  1700. &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="step-5-modern-css-layouts-bento-grids-and-more"&gt;Step 5: Modern CSS Layouts (Bento Grids and More)&lt;/h2&gt;
  1701. &lt;p&gt;Forget Bootstrap. Use &lt;strong&gt;CSS Grid&lt;/strong&gt; to create a modern, responsive layout.&lt;/p&gt;
  1702. &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-css" &gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  1703. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;--bg-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#f9fafb&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  1704. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;--text-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#111827&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  1705. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;--accent-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#2563eb&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  1706. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;--card-bg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#ffffff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  1707. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  1708. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
  1709. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;projects-grid&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  1710. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  1711. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;auto&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="kc"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;minmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;350&lt;/span&gt;&lt;span class="kt"&gt;px&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  1712. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="kt"&gt;rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  1713. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="kt"&gt;rem&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  1714. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  1715. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
  1716. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;project-card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  1717. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;card&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  1718. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="kt"&gt;px&lt;/span&gt; &lt;span class="kc"&gt;solid&lt;/span&gt; &lt;span class="mh"&gt;#e5e7eb&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  1719. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="kt"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  1720. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  1721. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;transform&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="kt"&gt;s&lt;/span&gt; &lt;span class="nb"&gt;cubic-bezier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  1722. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  1723. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
  1724. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;project-card&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  1725. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;translateY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;-8&lt;/span&gt;&lt;span class="kt"&gt;px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  1726. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="kt"&gt;px&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="kt"&gt;px&lt;/span&gt; &lt;span class="mi"&gt;-5&lt;/span&gt;&lt;span class="kt"&gt;px&lt;/span&gt; &lt;span class="nb"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  1727. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  1728. &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Pro Tip: CSS Custom Properties&lt;/strong&gt; Use &lt;strong&gt;CSS Custom Properties&lt;/strong&gt; (variables) for
  1729. theming. This makes it trivial to add a &amp;ldquo;Dark Mode&amp;rdquo; later by just swapping the
  1730. values in a &lt;code&gt;:root[data-theme='dark']&lt;/code&gt; block.&lt;/p&gt;
  1731. &lt;h2 id="step-6-handling-interactivity-without-the-weight"&gt;Step 6: Handling Interactivity without the Weight&lt;/h2&gt;
  1732. &lt;p&gt;You don&amp;rsquo;t need a 30KB framework for a mobile menu or a simple filter. Use
  1733. &lt;strong&gt;Vanilla JavaScript&lt;/strong&gt;.&lt;/p&gt;
  1734. &lt;p&gt;&lt;strong&gt;Common Pitfall: The &amp;ldquo;Everything is a Component&amp;rdquo; Mindset&lt;/strong&gt; Not every piece of
  1735. UI needs to be a &amp;ldquo;component&amp;rdquo; with state. For a portfolio, most interactivity is
  1736. just &lt;strong&gt;DOM manipulation&lt;/strong&gt;.&lt;/p&gt;
  1737. &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" &gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// A simple, accessible mobile menu toggle
  1738. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toggle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;#menu-toggle&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  1739. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;menu&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;#main-menu&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  1740. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
  1741. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;click&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  1742. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isExpanded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;aria-expanded&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  1743. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;aria-expanded&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isExpanded&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  1744. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;menu&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;is-active&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  1745. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
  1746. &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you truly need more complex state (e.g., a live-search for your blog posts),
  1747. consider &lt;strong&gt;Petite-Vue&lt;/strong&gt; or &lt;strong&gt;Alpine.js&lt;/strong&gt;. They provide a Vue-like experience but
  1748. are optimized for &amp;ldquo;sprinkling&amp;rdquo; interactivity on top of static HTML.&lt;/p&gt;
  1749. &lt;h2 id="step-7-static-forms-and-search"&gt;Step 7: Static Forms and Search&lt;/h2&gt;
  1750. &lt;p&gt;The two biggest hurdles for static sites are contact forms and search.&lt;/p&gt;
  1751. &lt;ol&gt;
  1752. &lt;li&gt;&lt;strong&gt;Forms&lt;/strong&gt;: Use a service like &lt;strong&gt;Netlify Forms&lt;/strong&gt;, &lt;strong&gt;Formspree&lt;/strong&gt;, or &lt;strong&gt;Basin&lt;/strong&gt;.
  1753. You just add a &lt;code&gt;data-netlify=&amp;quot;true&amp;quot;&lt;/code&gt; attribute to your HTML form, and Netlify
  1754. handles the submission and spam filtering.&lt;/li&gt;
  1755. &lt;li&gt;&lt;strong&gt;Search&lt;/strong&gt;: For a portfolio, you usually don&amp;rsquo;t need a server-side search. Use
  1756. &lt;strong&gt;Fuse.js&lt;/strong&gt; or &lt;strong&gt;Pagefind&lt;/strong&gt;. These tools index your site at build time and
  1757. provide a lightning-fast client-side search interface.&lt;/li&gt;
  1758. &lt;/ol&gt;
  1759. &lt;h2 id="step-8-image-optimization-the-hugo-superpower"&gt;Step 8: Image Optimization (The Hugo Superpower)&lt;/h2&gt;
  1760. &lt;p&gt;Large images are the #1 killer of portfolio performance. Hugo can automatically
  1761. process your images.&lt;/p&gt;
  1762. &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-html" &gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;{{ $image := resources.Get .Params.image }} {{ $optimized := $image.Resize &amp;#34;800x
  1763. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;webp q75&amp;#34; }}
  1764. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt;
  1765. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;{{ $optimized.RelPermalink }}&amp;#34;&lt;/span&gt;
  1766. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;{{ $optimized.Width }}&amp;#34;&lt;/span&gt;
  1767. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;{{ $optimized.Height }}&amp;#34;&lt;/span&gt;
  1768. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;{{ .Title }}&amp;#34;&lt;/span&gt;
  1769. &lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  1770. &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This single line of code ensures that no matter how big the original file was,
  1771. the user only downloads a perfectly sized, compressed &lt;strong&gt;WebP&lt;/strong&gt; image.&lt;/p&gt;
  1772. &lt;h2 id="conclusion-the-professional-edge"&gt;Conclusion: The Professional Edge&lt;/h2&gt;
  1773. &lt;p&gt;Building your portfolio without React is more than a technical exercise; it&amp;rsquo;s a
  1774. statement. It says: &lt;em&gt;&amp;ldquo;I understand how the web works. I care about my users'
  1775. bandwidth. I can build fast, resilient systems.&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
  1776. &lt;p&gt;If you want to see a full-scale example of this philosophy in action, check out
  1777. my Introducing Olivero Hugo Theme post. It’s a project that brings world-class
  1778. &lt;strong&gt;accessibility&lt;/strong&gt; and &lt;strong&gt;performance&lt;/strong&gt; to the Hugo ecosystem without the overhead
  1779. of modern JavaScript frameworks.&lt;/p&gt;
  1780. &lt;p&gt;Your portfolio is your calling card. Make sure it loads before the hiring
  1781. manager gets bored and clicks away.&lt;/p&gt;
  1782. &lt;hr&gt;
  1783. &lt;p&gt;&lt;em&gt;Struggling with a specific Hugo layout or CSS grid issue? Drop me a line on
  1784. social media—I’m always happy to help fellow &amp;ldquo;lean web&amp;rdquo; enthusiasts.&lt;/em&gt;&lt;/p&gt;
  1785. </content:encoded>
  1786. <dc:creator>Val Paliy</dc:creator>
  1787. </item>
  1788. </channel>
  1789. </rss>

If you would like to create a banner that links to this page (i.e. this validation result), do the following:

  1. Download the "valid RSS" banner.

  2. Upload the image to your own server. (This step is important. Please do not link directly to the image on this server.)

  3. Add this HTML to your page (change the image src attribute if necessary):

If you would like to create a text link instead, here is the URL you can use:

http://www.rssboard.org/rss-validator/check.cgi?url=https%3A//valticus.pro/index.xml

Software created by Sam Ruby, Mark Pilgrim, Joseph Walton and Phil Ringnalda