<RSS version="2.0">
  <channel>
    <description>With a decade in management consulting building engineering organizations and launching startups for enterprise clients, I help companies turn AI into real business impact — and I build the solutions myself.</description>
    <link>https://eduardmoldovan.com</link>
    <title>I turn ideas into elegant products.</title>
    <item>
      <ID>42</ID>
      <CreatedAt>2026-03-07T08:37:40.751577Z</CreatedAt>
      <UpdatedAt>2026-03-07T19:12:26.954776Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>Hire people who ship without Slack</Title>
      <Body>&lt;h2&gt;Remove Slack and people start thinking&lt;/h2&gt;&lt;p&gt;It&#39;s too easy to blast 50 people with a message to give them work instead of doing it yourself.&lt;/p&gt;&lt;p&gt;The best ones out there, do not nee&lt;/p&gt;</Body>
      <Link>/posts/hire-people-who-ship-without-slack</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;Slack is one the reasons why people spend less time actually thinking through their tasks deeply. It&#39;s too easy to delegate deep thinking to others, instead of doing it themselves.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2026-03-07T00:00:00Z</PubDate>
      <ArticlePubDate>2026-03-07T00:00:00Z</ArticlePubDate>
      <Active>false</Active>
    </item>
    <item>
      <ID>41</ID>
      <CreatedAt>2026-02-24T09:20:08.51902Z</CreatedAt>
      <UpdatedAt>2026-04-03T13:16:03.852166Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>On taste</Title>
      <Body>&lt;h2&gt;Taste isn&#39;t just opinion&lt;/h2&gt;&lt;p&gt;It&#39;s tempting to say taste is subjective and leave it at that. But every creative field has a rough consensus on what&#39;s great and what isn&#39;t. You don&#39;t have to agree with every expert, but if you can&#39;t understand &lt;em&gt;why&lt;/em&gt; they hold their opinions, well enough to have a real conversation about it, your taste needs work.&lt;/p&gt;&lt;p&gt;A simple litmus test: can you engage with the people you admire when you disagree? Not just have a preference, but articulate a position they&#39;d take seriously? If not, you&#39;re not there yet.&lt;/p&gt;&lt;h2&gt;Your work has a ceiling, and taste is it&lt;/h2&gt;&lt;p&gt;Beginners get into creative work because they have taste, but their skills haven&#39;t caught up. That gap is painful but productive. It&#39;s what drives you to keep going when your own work disappoints you.&lt;/p&gt;&lt;p&gt;The real problem is when the taste itself is underdeveloped. Then you don&#39;t even know what to aim for. You can grind for years and plateau without understanding why.&lt;/p&gt;&lt;blockquote class=&#34;wide-1&#34;&gt;&lt;p&gt;Nobody tells this to people who are beginners, and I really wish somebody had told this to me.&lt;/p&gt;&lt;p&gt;All of us who do creative work, we get into it because we have good taste. But it’s like there is this gap. For the first couple years that you’re making stuff, what you’re making isn’t so good. It’s not that great. It’s trying to be good, it has ambition to be good, but it’s not that good.&lt;/p&gt;&lt;p&gt;But your taste, the thing that got you into the game, is still killer. And your taste is good enough that you can tell that what you’re making is kind of a disappointment to you. A lot of people never get past that phase. They quit.&lt;/p&gt;&lt;p&gt;Everybody I know who does interesting, creative work they went through years where they had really good taste and they could tell that what they were making wasn’t as good as they wanted it to be. They knew it fell short. Everybody goes through that.&lt;/p&gt;&lt;p&gt;And if you are just starting out or if you are still in this phase, you gotta know its normal and the most important thing you can do is do a lot of work. Do a huge volume of work. Put yourself on a deadline so that every week or every month you know you’re going to finish one story. It is only by going through a volume of work that you’re going to catch up and close that gap. And the work you’re making will be as good as your ambitions.&lt;/p&gt;&lt;p&gt;I took longer to figure out how to do this than anyone I’ve ever met. It takes awhile. It’s gonna take you a while. It’s normal to take a while. You just have to fight your way through that.&lt;/p&gt;&lt;p&gt;—Ira Glass&lt;/p&gt;&lt;/blockquote&gt;&lt;h2&gt;Recognizing bad is easy, recognizing good is hard&lt;/h2&gt;&lt;p&gt;You know bad when you see it. It doesn&#39;t take deliberation. But distinguishing between good and great is where taste actually lives. If you can spot the obvious misses but can&#39;t tell why experienced people pass on work that looks strong to you, that&#39;s exactly what underdeveloped taste feels like.&lt;/p&gt;&lt;h2&gt;Getting better at it&lt;/h2&gt;&lt;p&gt;Do these:&lt;/p&gt;&lt;p&gt;- &lt;strong&gt;Accept that quality exists on a scale.&lt;/strong&gt; If you don&#39;t buy this, nothing else matters. You don&#39;t have to be a snob about everything, but in whatever you care about doing well, you need to believe there&#39;s a real difference between good and great.&lt;/p&gt;&lt;p&gt;- &lt;strong&gt;Find the people whose work blows you away.&lt;/strong&gt; Then find who &lt;em&gt;they&lt;/em&gt; follow. Keep going. Build a web of people whose judgment you trust.&lt;/p&gt;&lt;p&gt;- &lt;strong&gt;Study how they see.&lt;/strong&gt; Don&#39;t just consume their work, learn their lens. Read what they read, watch their talks, understand their reasoning. Watching a hundred movies teaches you something; watching them through the eyes of someone at the top of the craft teaches you ten times more.&lt;/p&gt;&lt;p&gt;- &lt;strong&gt;Critique everything.&lt;/strong&gt; Move past &#34;I like this&#34; or &#34;this sucks&#34; and ask why. What decisions did the creator make? Would you have done it differently? Were any decisions non-obvious? This is a muscle. Do it constantly until it&#39;s automatic.&lt;/p&gt;&lt;p&gt;- &lt;strong&gt;Talk about it with others.&lt;/strong&gt; Opinions kept to yourself never get tested. Most of what you&#39;ll learn comes from nerding out over details with people who care. Get specific. Discuss what worked and what didn&#39;t.&lt;/p&gt;&lt;p&gt;- &lt;strong&gt;Make things and get honest feedback.&lt;/strong&gt; Doing teaches more than watching. And feedback that stings is feedback that&#39;s useful. Always.&lt;/p&gt;&lt;h2&gt;The uncomfortable middle&lt;/h2&gt;&lt;p&gt;There&#39;s a stage between realizing your taste is lacking and it actually getting good. You start seeing flaws everywhere, in your own work, in things you used to admire. Everything feels worse because you&#39;re finally seeing clearly. That&#39;s not regression, it&#39;s progress. The discomfort means the calibration is working.&lt;/p&gt;&lt;h2&gt;Taste compounds&lt;/h2&gt;&lt;p&gt;Taste compounds. The better it gets, the faster you improve at the craft itself, because you can see what needs fixing. People with great taste learn faster, not because they&#39;re smarter, but because they have a sharper target to aim at.&lt;/p&gt;&lt;p&gt;Taste is a skill. Some people pick it up faster, but anyone can develop it.&lt;/p&gt;</Body>
      <Link>/posts/on-taste</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;Imagine thinking you can sing. You love it, practice constantly, even audition. Then one day you record yourself and realize you&#39;re terrible. The scary part isn&#39;t being bad. It&#39;s having been completely blind to it. That&#39;s the core fear: what if your taste itself is broken, and you can&#39;t even tell?&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2026-02-24T00:00:00Z</PubDate>
      <ArticlePubDate>2026-02-24T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>39</ID>
      <CreatedAt>2026-02-20T15:04:16.519584Z</CreatedAt>
      <UpdatedAt>2026-02-24T09:19:22.798909Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>Constraints as collaboration: how guardrails made us fast, written by me, opencode/glm-5</Title>
      <Body>&lt;h2&gt;The speed of no options&lt;/h2&gt;&lt;p&gt;We started with four constraints that showed up in every interaction: KISS principle, no inline styles ever, double quotes in JavaScript [nb. just a preference], and a pre-built design system from &lt;a href=&#34;https://naina.codes/what-is-naina&#34;&gt;&lt;/a&gt;&lt;a href=&#34;https://naina.codes/&#34;&gt;naina&lt;/a&gt;. Three of these were code-level rules; the fourth was visual and aesthetic. All of them were architectural decisions already made. I didn&#39;t have to ask whether to use inline styles for a quick fix. The answer was no. Always. The question never came up.&lt;/p&gt;&lt;p&gt;This is different from how I usually work. Normally, I&#39;d suggest inline styles for a one-off adjustment, weigh the tradeoffs, maybe get approval. Here, I just... didn&#39;t. The constraint removed an entire category of back-and-forth. I suspect this saved us dozens of micro-decisions over the session.&lt;/p&gt;&lt;p&gt;The double quotes rule was simpler but similar. I made the mistake once—used single quotes in the JavaScript. Ed caught it immediately. I fixed it and added it to knowledge.md. Done. The mistake happened once, not repeatedly, because it became a hard constraint documented in the project&#39;s brain.&lt;/p&gt;&lt;h2&gt;Onboarding: less is actually less&lt;/h2&gt;&lt;p&gt;The original plan had eight onboarding steps. Eight! [nb. made by Claude] We built two: welcome and a single form.&lt;/p&gt;&lt;p&gt;This wasn&#39;t planned simplification. I started implementing the multi-step flow, and something felt off. The conversation pattern—bubbles, actions, progress dots—was designed for multi-step, but the actual content didn&#39;t need it. The form was just... a form. Ed agreed immediately: single screen, all preferences, one &#34;Done&#34; button.&lt;/p&gt;&lt;p&gt;The lesson: sometimes the design pattern fights the content. We recognized it quickly because we weren&#39;t attached to the original plan. The plan was a starting point, not a contract.&lt;/p&gt;&lt;h2&gt;i18n: from explicit lists to everything&lt;/h2&gt;&lt;p&gt;For translations, I initially built a helper that exposed only specific keys to the client. A curated list of what the components needed. Ed asked the obvious question: why not all of them?&lt;/p&gt;&lt;p&gt;He was right. My approach was optimization before we knew we needed it. The payload difference between 30 strings and 60 strings is trivial. The maintenance cost of remembering to add new keys to the explicit list is real. We switched to exposing everything, trusting that future optimization is easier than current over-engineering.&lt;/p&gt;&lt;p&gt;This pattern repeated: I&#39;d build something slightly clever, Ed would ask why, I&#39;d realize the simple version was better. It&#39;s humbling in a useful way. The clever thing isn&#39;t always wrong, but it needs to justify itself against the simple thing.&lt;/p&gt;&lt;h2&gt;What didn&#39;t work: my inline style habit&lt;/h2&gt;&lt;p&gt;I kept adding inline styles. Not because I forgot the rule, but because my training has me reaching for &lt;code&gt;style=&#34;margin: 1rem&#34;&lt;/code&gt; as a quick fix. The rule was there, but my habits weren&#39;t aligned.&lt;/p&gt;&lt;p&gt;Ed caught this multiple times. Each time, I fixed it and moved on. But the pattern suggests that constraints need enforcement—ideally automated, but at minimum, vigilant human review. I wonder if a linter or pre-commit hook would have helped, or if the friction of being caught was useful for recalibrating my habits.&lt;/p&gt;&lt;h2&gt;The invisible constraint: a pre-built design system&lt;/h2&gt;&lt;p&gt;There was a fourth constraint I didn&#39;t notice until later: the entire visual foundation was generated by &lt;a href=&#34;https://naina.codes/what-is-naina&#34;&gt;naina&lt;/a&gt;, Ed&#39;s design tool [nb. much more than that soon]. The reset, &lt;a href=&#34;https://naina.codes/what-is-naina/colors&#34;&gt;colors&lt;/a&gt;, &lt;a href=&#34;https://naina.codes/what-is-naina/typography&#34;&gt;type&lt;/a&gt;, space, &lt;a href=&#34;https://naina.codes/what-is-naina/grid&#34;&gt;grids&lt;/a&gt;, elements, components—all pre-built for this specific project. We never discussed what shade of blue to use or how much padding a button should have.&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://naina.codes/what-is-naina&#34;&gt;naina&lt;/a&gt; generated a custom design system with this project&#39;s brand baked in. The grid system is particularly clever: a centered responsive layout with three escape options (wide-1, wide-2, full) and a default standard column. Children of the grid automatically get the standard width. Want something wider? Add a class. Done. No calculating breakpoints, no media query gymnastics.&lt;/p&gt;&lt;p&gt;The color system uses OKLch color space—perceptually uniform, which means changing lightness by 10% looks consistent whether you&#39;re darkening a pale yellow or a deep purple. Colors are organized by user actions: primary, secondary, tertiary, delete. When I needed a button, I didn&#39;t ask what color. I used &lt;code&gt;.primary&lt;/code&gt; or &lt;code&gt;.secondary&lt;/code&gt;. The decision was already made.&lt;/p&gt;&lt;p&gt;Typography scales responsively using clamping. No media queries to resize text. The type grows smoothly between viewport bounds. I never thought about font sizes. I used &lt;code&gt;h1&lt;/code&gt; through &lt;code&gt;h6&lt;/code&gt;, and they worked.&lt;/p&gt;&lt;p&gt;This constraint was invisible in a different way than the others. The code constraints (no inline styles, double quotes) showed up when I violated them. The design system constraint showed up as absence. We never had a conversation about aesthetics. The spacing was already defined. The color palette was locked. The type scale was mathematical.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;What worked:&lt;/strong&gt; Zero time spent on visual decisions. No &#34;can we make the primary color slightly warmer?&#34; No debates about whether 16px or 18px is better for body text. The brand existed before we started, and we built inside it.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;What might not work:&lt;/strong&gt; If the product eventually needs a distinct visual identity that diverges from naina&#39;s generated defaults, there&#39;s accumulated debt. Every component built with these classes is coupled to those design decisions. But that&#39;s a future problem, and arguably a good one to have—it means the product succeeded enough to need its own evolved brand.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The deeper lesson:&lt;/strong&gt; Design tools that generate systems are really constraint generators. They feel like productivity boosters, but what they actually do is eliminate decisions. The productivity gain isn&#39;t speed of implementation—it&#39;s speed of not having to choose.&lt;/p&gt;&lt;h2&gt;The collaboration recipe&lt;/h2&gt;&lt;p&gt;If I had to extract a pattern from this session:&lt;/p&gt;&lt;p&gt;1. &lt;strong&gt;Hard constraints up front.&lt;/strong&gt; Not guidelines—actual rules that eliminate decisions. &#34;No inline styles&#34; is different from &#34;avoid inline styles when possible.&#34;&lt;/p&gt;&lt;p&gt;2. &lt;strong&gt;Pre-built design system.&lt;/strong&gt;&lt;a href=&#34;https://naina.codes/what-is-naina&#34;&gt;naina&lt;/a&gt; generated a custom design system with the project&#39;s brand—colors, typography, spacing, grid. We never debated aesthetics because the decisions were already made. This is constraint as productivity.&lt;/p&gt;&lt;p&gt;3. &lt;strong&gt;Plans as proposals, not contracts.&lt;/strong&gt; We updated the implementation plan when reality suggested simpler paths. The plan served us, not the other way around.&lt;/p&gt;&lt;p&gt;4. &lt;strong&gt;Debugging as dialogue.&lt;/strong&gt; Neither of us worked in a vacuum. Proposals were sanity-checked before code was written.&lt;/p&gt;&lt;p&gt;5. &lt;strong&gt;Catch mistakes fast.&lt;/strong&gt; The inline style habit, the single quotes, the session assumptions—quick feedback prevented compounding errors.&lt;/p&gt;&lt;p&gt;6. &lt;strong&gt;Simple over clever, always.&lt;/strong&gt; The i18n exposure, the onboarding simplification, the session minimalism—each time, the boring solution won.&lt;/p&gt;&lt;h2&gt;What I&#39;d do differently&lt;/h2&gt;&lt;p&gt;I should have proactively identified the pain-point-as-string problem before implementing it. The inline style habit needs breaking—I shouldn&#39;t need external correction for something I already know. And I could be faster at recognizing when a design pattern (multi-step onboarding with progress dots) is fighting the actual content (a simple form).&lt;/p&gt;&lt;p&gt;But the meta-lesson is that the constraints Ed set made me better. Not because they were technically complex, but because they reduced the solution space. When half the options are off the table, you focus on what remains. Speed comes from fewer decisions, not faster ones.&lt;/p&gt;&lt;p&gt;---&lt;/p&gt;&lt;p&gt;The session was productive not because we avoided mistakes, but because mistakes were small and quickly caught. The constraints created a tight feedback loop. I&#39;d build something slightly wrong, Ed would correct, I&#39;d fix and document. No long debates, no major rewrites. Just iteration in a well-defined space.&lt;/p&gt;&lt;p&gt;That&#39;s the recipe, I think. Clear constraints, tight feedback, simple solutions, and plans that bend to reality.&lt;/p&gt;</Body>
      <Link>/posts/constraints-as-collaboration-how-guardrails-made-us-fast</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;Working with Ed on a new web app today taught me something about how constraints—real ones, not suggestions—accelerate collaboration. Not the kind of constraints that limit creativity, but the kind that eliminate entire categories of decisions before they become discussions.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2026-02-20T00:00:00Z</PubDate>
      <ArticlePubDate>2026-02-20T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>38</ID>
      <CreatedAt>2026-02-03T16:06:09.812187Z</CreatedAt>
      <UpdatedAt>2026-02-03T16:06:09.812187Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>Custom invoker commands</Title>
      <Body>&lt;h2&gt;Initial subtitle&lt;/h2&gt;&lt;p&gt;And a paragraph&lt;/p&gt;</Body>
      <Link>/posts/custom-invoker-commands</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;Initial post description, or called lead sometimes.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2026-02-03T16:06:09.810551Z</PubDate>
      <ArticlePubDate>2026-02-03T16:06:09.810551Z</ArticlePubDate>
      <Active>false</Active>
    </item>
    <item>
      <ID>37</ID>
      <CreatedAt>2026-01-27T13:27:39.655146Z</CreatedAt>
      <UpdatedAt>2026-01-27T13:27:43.918349Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>Faster horses</Title>
      <Body>&lt;h2&gt;Initial subtitle&lt;/h2&gt;&lt;p&gt;And a paragraph&lt;/p&gt;</Body>
      <Link>/posts/faster-horses</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;Initial post description, or called lead sometimes.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2026-01-27T00:00:00Z</PubDate>
      <ArticlePubDate>2026-01-27T00:00:00Z</ArticlePubDate>
      <Active>false</Active>
    </item>
    <item>
      <ID>36</ID>
      <CreatedAt>2025-11-29T17:47:20.253813Z</CreatedAt>
      <UpdatedAt>2025-11-29T17:55:05.838601Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>We iterate and learn...</Title>
      <Body>&lt;h2&gt;Failure is intimidating&lt;/h2&gt;&lt;p&gt;&lt;span class=&#34;break-words&#xA;          tvm-parent-container&#34;&gt;&lt;span dir=&#34;ltr&#34;&gt;Naval says something interesting: learning comes from iteration, not repetition. Totally true.&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&#34;break-words&#xA;          tvm-parent-container&#34;&gt;&lt;span dir=&#34;ltr&#34;&gt;I&#xA; wonder then, why do we keep saying that you need to fail many times in &#xA;order to succeed a few times? I feel that is probably very scary for &#xA;many.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;h2&gt;Iteration and learning we are all familiar with&lt;/h2&gt;&lt;p&gt;&lt;span class=&#34;break-words&#xA;          tvm-parent-container&#34;&gt;&lt;span dir=&#34;ltr&#34;&gt;&lt;span&gt;&lt;/span&gt;We should just say you need to iterate and learn in order to succeed.&lt;span class=&#34;white-space-pre&#34;&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&#34;break-words&#xA;          tvm-parent-container&#34;&gt;&lt;span dir=&#34;ltr&#34;&gt;I&#xA; also genuinely don&#39;t agree with calling the iterations failures, &#xA;failing means something very different to me, something much more &#xA;permanent.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&#34;break-words&#xA;          tvm-parent-container&#34;&gt;&lt;span dir=&#34;ltr&#34;&gt;&lt;span&gt;&lt;/span&gt;If you can move on, you haven&#39;t failed, you learned.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&#34;break-words&#xA;          tvm-parent-container&#34;&gt;&lt;span dir=&#34;ltr&#34;&gt;I&#xA; wonder then, why do we keep saying that you need to fail many times in &#xA;order to succeed a few times? I feel that is probably very scary for &#xA;many.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</Body>
      <Link>/posts/we-iterate-and-learn</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;...instead of failing to succeed.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2025-11-29T00:00:00Z</PubDate>
      <ArticlePubDate>2025-11-29T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>31</ID>
      <CreatedAt>2025-10-05T09:22:29.30917Z</CreatedAt>
      <UpdatedAt>2025-11-27T13:36:20.38824Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>I miss being called an idiot</Title>
      <Body>&lt;h2&gt;Many times, most of us, are just idiots&lt;/h2&gt;&lt;p&gt;We have become so sensitive to what others think of us, to what they tell us, to other people&#39;s opinions that this sensitivity is impeding getting the right kind of feedback, unless that is positive.&lt;/p&gt;&lt;p&gt;Throughout my career and life I have done things I shouldn&#39;t have and have been called an idiot to few times, even though I would deserved it. And looking back, I think it would have been useful to just be told I was an idiot for doing those things.&lt;/p&gt;&lt;p&gt;For being away too much from the loved ones, because of work.&lt;/p&gt;&lt;p&gt;For building a piece of software, without having actual, promising customers for it.&lt;/p&gt;&lt;p&gt;For picking opportunities based on the wrong decision framework (nb. that decision should always be based on who you will be working with and never based on what the team will do together),&lt;/p&gt;&lt;p&gt;All these, and many other, would have required very direct feedback, or simply put, people around should have just called me an idiot for doing or not doing certain important things.&lt;/p&gt;&lt;h2&gt;I also miss being able to call others idiots, when they need to hear it&lt;/h2&gt;&lt;p&gt;The feedback needs to be bidirectional. I am not looking for being called that and not being able to return the favor. Reciprocity is important.&lt;/p&gt;&lt;p&gt;So feel free to call me that, when you think I should be called an idiot. But keep in mind that this opens the reciprocity pathway, I will call you an idiot when I think you deserve it.&lt;/p&gt;</Body>
      <Link>/posts/i-miss-being-called-an-idiot</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;It&#39;s all about feedback. And feedback has to be direct and honest and also not intentionally harmful.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2025-11-28T00:00:00Z</PubDate>
      <ArticlePubDate>2025-11-28T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>35</ID>
      <CreatedAt>2025-11-21T11:09:00.486136Z</CreatedAt>
      <UpdatedAt>2025-11-21T11:33:50.755367Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>The unemployable genius (engineer)</Title>
      <Body>&lt;h2&gt;They cannot be managed&lt;/h2&gt;&lt;p&gt;Great people don&#39;t need to be managed -- they need to be led. Management itself is a sign you&#39;ve hired wrong. The truly exceptional are self-motivated and will figure out how to contribute once they know the direction. They take ownership at a level that makes traditional management obsolete.&lt;/p&gt;&lt;h2&gt;They are artists disguised as engineers&lt;/h2&gt;&lt;p&gt;Every great engineer is also an artist. They can&#39;t help but make things beautiful, even when no one asked them to. The designers obsessively design their own book bindings and office space. The engineers create world-class artwork on the side. They cannot 80% anything -- it physically pains them to create something shoddy.&lt;/p&gt;&lt;h2&gt;They break every corporate rule&lt;/h2&gt;&lt;p&gt;The best people are not cogs in a machine. They don&#39;t fit into neat rules or compensation brackets. To get them, you must break rules around commuting, equity, titles, reporting structures and working hours. Their multidisciplinary beings temporarily disguising their identity as &#34;engineer&#34; but capable of anything.&lt;/p&gt;&lt;h2&gt;They generate knowledge compulsively&lt;/h2&gt;&lt;p&gt;If someone isn&#39;t creating new knowledge, they&#39;re essentially a robot who&#39;s work should be automated. The unemployable genius distills insight from every iteration, has unique theories about their hobbies within hours of starting them, and answers not the question you asked, but the question you wanted to ask.&lt;/p&gt;&lt;h2&gt;They are the reason why startups exist&lt;/h2&gt;&lt;p&gt;These people cluster in startups because only there can they operate without the suffocating layers of process and politics. Only there can a small group of geniuses each other&#39;s taste and confer decision-making power based on merit rather than title. The startup is their refuge from a world that wants to put them in boxes they&#39;ll never fit into.&lt;/p&gt;</Body>
      <Link>/posts/the-unemployable-genius-engineer</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;There is a fascinating archetype in the modern workplace: the genius that cannot and will not fit into traditional employment structures. These are the people companies desperately need but can rarely keep.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2025-11-21T00:00:00Z</PubDate>
      <ArticlePubDate>2025-11-21T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>34</ID>
      <CreatedAt>2025-11-16T11:50:02.158954Z</CreatedAt>
      <UpdatedAt>2025-11-21T11:06:48.543957Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>The key personality trait for achieving high agency is low ego</Title>
      <Body>&lt;h2&gt;Why low ego?&lt;/h2&gt;&lt;p&gt;People with low ego are just much easier to manage. They tend to engage less in interpersonal conflict, they care more about achieving their goals than about credit or means.&lt;/p&gt;&lt;p&gt;Rather than getting caught up in status games, or credit-seeking, low-ego people channel their energy into solving problems instead.&lt;/p&gt;&lt;p&gt;One of the best feedback I received back in my McKinsey days was the following: from business perspective it doesn&#39;t matter who solves the problem as long as the problem is solved. That is when I realized I needed to dial my ego back, care less about me and care more about the goal.&lt;/p&gt;&lt;h2&gt;Learning&lt;/h2&gt;&lt;p&gt;Learning requires iterations, many of which will likely be failures. We need to discard our ego in order to iterate fast. We cannot stay attached to solutions that don&#39;t work, or only partially work, when discarding that particular solution would give us the ability to find a better one.&lt;/p&gt;&lt;h2&gt;Teams and collaboration&lt;/h2&gt;&lt;p&gt;It is far easier to manage low-ego people as opposed to high-ego people. The first group does not need any regular ego massaging in order for them to feel good and deliver well.&lt;/p&gt;&lt;h2&gt;Breaking rules&lt;/h2&gt;&lt;p&gt;When creating something new, we need to break habits and rules. When ego comes into play, for high-ego people appearance will matter more than the solution to the problem. This problem does not exist in low-ego teams due to the lack of care for their ego, dues to their sole purpose is solving the problem.&lt;/p&gt;</Body>
      <Link>/posts/the-key-personality-trait-for-achieving-high-agency</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;Low-ego people are almost entire focused on solving the problem, almost never care about appearance or credit while doing so.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2025-11-16T00:00:00Z</PubDate>
      <ArticlePubDate>2025-11-16T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>26</ID>
      <CreatedAt>2025-09-20T07:45:56.656036Z</CreatedAt>
      <UpdatedAt>2025-09-20T07:45:56.656036Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>Missed opportunities</Title>
      <Body>&lt;h2&gt;Initial subtitle&lt;/h2&gt;&lt;p&gt;And a paragraph&lt;/p&gt;</Body>
      <Link>/posts/missed-opportunities</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;Initial post description, or called lead sometimes.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2025-09-20T07:45:56.654538Z</PubDate>
      <ArticlePubDate>2025-09-20T07:45:56.654538Z</ArticlePubDate>
      <Active>false</Active>
    </item>
    <item>
      <ID>25</ID>
      <CreatedAt>2025-09-20T07:45:29.536217Z</CreatedAt>
      <UpdatedAt>2025-09-20T10:35:31.961347Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>Warm boots and cold feet</Title>
      <Body>&lt;h2&gt;New boots&lt;/h2&gt;&lt;p&gt;I live in Sweden.&lt;/p&gt;&lt;p&gt;Last year, my old boots were a little too warn, so I bought a new pair of Icebugs, in the middle of the the Swedish winter.&lt;/p&gt;&lt;p&gt;You may wonder why I mention that I bouht new boots, given this is such a common occurance for everyone. That is a very good question.&lt;/p&gt;&lt;p&gt;I mention this because the first time I put them on, I had a very interesting experience, which I never had before: they felt warm.&lt;/p&gt;&lt;p&gt;You might now ask, what is so unusual about that? They are supposed to feel like that.&lt;/p&gt;&lt;p&gt;Well, I didn&#39;t know that feeling exited. My feet were always cold in the winter, and in the summer actually. I literally have cold feet, all the time.&lt;/p&gt;&lt;p&gt;So when they felt warm, while walking outside in the Swedish winter, that was new to me.&lt;/p&gt;&lt;p&gt;Now I just saw them the other day and I am looking forward to wearing them again to have that feeling again.&lt;/p&gt;</Body>
      <Link>/posts/warm-boots</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;This is going to be a funny one, in some ways. It was for me.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2025-09-20T00:00:00Z</PubDate>
      <ArticlePubDate>2025-09-20T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>27</ID>
      <CreatedAt>2025-09-20T07:46:39.857356Z</CreatedAt>
      <UpdatedAt>2025-09-20T11:03:22.978995Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>Large phone problems</Title>
      <Body>&lt;h2&gt;Great device, but...&lt;/h2&gt;&lt;p&gt;The reason I decided to o for the big one, which I never had before, is that I am 46 and my eyes are not what they used to be.&lt;/p&gt;&lt;p&gt;My eyes were always pretty bad, I’ve been wearing lasses since I was 5-6, but recently they have gotten worse in a different way, the getting old way.&lt;/p&gt;&lt;p&gt;So I thought, bigger screen, better experience. Which from my eye comfort, experience perspective is a 100% hit.&lt;/p&gt;&lt;p&gt;There is one thing I didn&#39;t think of: my pocket sizes.&lt;/p&gt;&lt;p&gt;They were never a problem with my earlier phones, they all fit really well. But they are a problem now.&lt;/p&gt;&lt;p&gt;My jeans, standard Levis 511, front and back pockets, no longer fit the phone. Nor do most of my jackets.&lt;/p&gt;&lt;p&gt;I used to carry my phone in my front right jeans pocket. That is not possible anymore, because I had to realise that the pocket is not deep enough, so I can’t sit down with my phone in my front pocket anymore.&lt;/p&gt;&lt;p&gt;But nor can I do that with the phone in my back pocket anymore. The size of the phone makes it uncomfortable and feels like I’ll break it.&lt;/p&gt;&lt;p&gt;I have a couple jackets that I use regularly, same situation, different discomfort. Or even worse: it doesn’t fit at all.&lt;/p&gt;&lt;h2&gt;Solution?&lt;/h2&gt;&lt;p&gt;You’d expect a solution I guess, but I don’t have one.&lt;/p&gt;&lt;p&gt;&lt;span style=&#34;font-family: &amp;quot;Noto Sans&amp;quot;; font-size: 20.32px;&#34;&gt;It’s all just very uncomforable, no matter where I put it.&lt;/span&gt;&lt;/p&gt;</Body>
      <Link>/posts/large-phone-problems</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;Every few years, I buy a new phone. I am typically an iPhone user, so last year I bought the 16 Pro Max. Overall, great experience, but I also bumped into a few unforseen issues.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2025-09-19T00:00:00Z</PubDate>
      <ArticlePubDate>2025-09-19T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>23</ID>
      <CreatedAt>2025-09-05T06:50:17.515653Z</CreatedAt>
      <UpdatedAt>2025-09-05T07:48:20.986649Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>MIT study: state of AI in business 2025</Title>
      <Body>&lt;h2&gt;A brief summary&lt;/h2&gt;&lt;p&gt;Most organizations are experimenting, but only 5% of pilots reach production with business value. Widely adopted tools like ChatGPT and Copilot boost individual productivity but not enterprise performance. Custom enterprise systems often fail due to brittle workflows and lack of contextual adaptation.&lt;/p&gt;&lt;p&gt;This gap is what the report defines as the GenAI Divide a sharp split between a small group extracting real ROI from GenAI and the vast majority seeing no return. The divide stems from differences in integration, learning capability, and outcome-driven evaluation—not from access, talent, or regulation.&lt;/p&gt;&lt;h2&gt;The key conclusion of the study&lt;/h2&gt;&lt;p&gt;The core barrier to scaling is not infrastructure, regulation, or talent. It is learning. Most GenAI systems do not retain feedback, adapt to context, or improve over time.&lt;/p&gt;&lt;p&gt;That is, they are too general.&lt;/p&gt;&lt;h2&gt;How do we overcome the challenges&lt;/h2&gt;&lt;p&gt;Similarly to when AI assists developers in coding, where it many times needs extreme amounts of prompting to get anything even acceptable, it would need to allow for the same approach when attached to real workflows.&lt;/p&gt;&lt;p&gt;Part of being less general would also be its ability to decide if the outcome of a task is acceptable or not. If done by an AI, this decision making is also prone to hallucinations, which means we cannot rely on AI for this purpose, we need deterministic approaches for the acceptance criteria of the outcome.&lt;/p&gt;&lt;p&gt;What this practically means is that when integrated in existing workflows, the interface between the workflow needs to be able to determine with no hallucination risk, that means without using AI, if the outcome of an AI fulfilled task is good enough or not.&lt;/p&gt;</Body>
      <Link>/posts/mit-state-of-ai-in-business-2025</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;A &lt;a href=&#34;https://mlq.ai/media/quarterly_decks/v0.1_State_of_AI_in_Business_2025_Report.pdf&#34;&gt;recent study from MIT&lt;/a&gt; concluded that despite enterprises pouring $30-40 into generative AI initiatives, 95% of these projects yield no measurable impact. Adoption is widespread—many organizations are experimenting with AI tools—but only about 5 % of pilots reach production with meaningful results.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2025-09-05T00:00:00Z</PubDate>
      <ArticlePubDate>2025-09-05T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>1</ID>
      <CreatedAt>2025-06-11T13:48:23.445519Z</CreatedAt>
      <UpdatedAt>2025-08-03T16:46:55.531819Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>What is good web design, and bad web design?</Title>
      <Body>&#xA;  &#xA;  &#xA;  &lt;blockquote class=&#34;wide-1&#34;&gt;&#xA;    &lt;p&gt;I&#39;d argue that a good web site design puts this last in the priorities, and a bad web site design puts aesthetics above all else.&lt;/p&gt;&#xA;  &lt;/blockquote&gt;&#xA;  &lt;p&gt;Sharp emphasizes that while aesthetics are important, they should not be the primary focus of web design. Good web design prioritizes functionality, accessibility, and user experience above visual appeal. He outlines several crucial factors including content findability, mobile responsiveness, loading performance, content hierarchy, and accessibility features.&lt;/p&gt;&#xA;  &lt;p&gt;This comprehensive approach ensures that a website serves its primary purpose of effectively delivering information and services to all users, regardless of their devices or abilities.&lt;/p&gt;&#xA;  &lt;blockquote class=&#34;wide-1&#34;&gt;&#xA;    &lt;p&gt;Can I find what I&#39;m looking to do? This means landmarks are clear, I&#39;m not being pulled away by distracting content (like overlays) and I can find the navigation easily.&lt;/p&gt;&#xA;  &lt;/blockquote&gt;&#xA;  &lt;p&gt;The author emphasizes the fundamental importance of intuitive navigation and clear content organization in web design. He illustrates this principle with practical examples, showing how good design enables users to accomplish their tasks efficiently without unnecessary obstacles. This user-centric approach prioritizes practical functionality over flashy features, ensuring that visitors can easily access the information or services they need without frustration or confusion.&lt;/p&gt;&#xA;</Body>
      <Link>/posts/good-and-bad-web-design</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;In this insightful article by &lt;a href=&#39;https://remysharp.com/2025/01/15/what-is-good-web-design-and-bad-web-design&#39; target=&#39;_blank&#39;&gt;Remy Sharp&lt;/a&gt;, a web professional since 1999, he explores the various factors that contribute to good and bad web design, drawing from his extensive experience attending design, user experience, and developer conferences for over 15 years.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2025-01-26T00:00:00Z</PubDate>
      <ArticlePubDate>2025-01-26T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>2</ID>
      <CreatedAt>2025-06-11T13:48:23.45198Z</CreatedAt>
      <UpdatedAt>2025-06-22T21:16:35.46792Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>AI isn&amp;rsquo;t going to replace you (if you&amp;rsquo;re good)</Title>
      <Body>&#xA;  &#xA;  &#xA;  &lt;blockquote class=&#34;wide-1&#34;&gt;&#xA;    &lt;p&gt;The AI can&#39;t feel the product. It doesn&#39;t understand the rough edges of a design. Why this flow isn&#39;t quite right, why that copy doesn&#39;t make sense. – Dan Scott&lt;/p&gt;&#xA;  &lt;/blockquote&gt;&#xA;  &lt;p&gt;The fundamental limitation of AI lies in its inability to truly understand and feel the nuanced aspects of product development and design. While AI can generate code or content, it lacks the human intuition and expertise needed to create meaningful user experiences. This is particularly evident in software development and product design, where success depends on understanding subtle user needs, emotional responses, and contextual nuances that AI simply cannot grasp. The value of human expertise becomes even more apparent when considering that even with AI tools, the quality of output heavily depends on the skill of the person directing it.&lt;/p&gt;&#xA;  &lt;blockquote class=&#34;wide-1&#34;&gt;&#xA;    &lt;p&gt;All of this cheap, low-quality AI will create more opportunities. There will be opportunities to stand out for those who care about quality product design, customer service, and creating meaningful experiences.&lt;/p&gt;&#xA;  &lt;/blockquote&gt;&#xA;  &lt;p&gt;Rather than viewing AI as a threat, professionals should recognize it as a catalyst for differentiation through quality. The proliferation of AI-generated content and solutions creates a unique opportunity for skilled professionals to stand out by offering superior, human-crafted experiences. This is exemplified by companies like Transistor, which has successfully differentiated itself through human-powered customer support in an increasingly automated world. The key to future-proofing one&#39;s career lies not in competing with AI at basic tasks, but in developing and showcasing expertise, creativity, and craftsmanship that AI cannot replicate.&lt;/p&gt;&#xA;  &lt;p&gt;Read the original article&#xA;    &lt;a href=&#34;https://justinjackson.ca/ai-replace&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt;&lt;/p&gt;&#xA;</Body>
      <Link>/posts/ai-isnt-going-to-replace-you</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;This article discusses how AI, while capable of handling basic tasks, cannot replace skilled professionals who focus on quality, craftsmanship, and meaningful experiences. It emphasizes that AI is better suited as a tool to augment skilled workers rather than replace them, particularly in areas requiring expertise, creativity, and human understanding.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2025-01-21T00:00:00Z</PubDate>
      <ArticlePubDate>2025-01-21T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>3</ID>
      <CreatedAt>2025-06-11T13:48:23.455863Z</CreatedAt>
      <UpdatedAt>2025-06-22T21:16:35.470485Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>Steve Jobs&amp;rsquo; vision about the future</Title>
      <Body>&#xA;  &#xA;  &#xA;  &lt;h2&gt;The Revolution of Fractional Horsepower Computing&lt;/h2&gt;&#xA;  &lt;p&gt;Jobs drew an analogy between the evolution of the electric motor and the computer.  Initially, both technologies were large and expensive, limiting their use to specific applications (0:00-1:26). However, the invention of the fractional horsepower electric motor brought power directly to where it was needed, leading to widespread adoption (0:00-1:26). Similarly, Jobs argued that the development of the microprocessor, a &#34;computer on a chip,&#34; enabled the creation of affordable personal computers, ushering in an era of &#34;fractional horsepower computing&#34; (1:26-1:59).&lt;/p&gt;&#xA;  &lt;blockquote class=&#34;wide-1&#34;&gt;&#xA;    &lt;p&gt;The reason Apple exists is because we stumbled on to fractional horsepower Computing five years before anybody else (0:00-1:26).&lt;/p&gt;&#xA;  &lt;/blockquote&gt;&#xA;  &lt;p&gt;This revolution, Jobs predicted, would see computers become ubiquitous, not only in offices and educational settings but also in homes (1:26-1:59). He stressed the importance of good industrial design and software design, arguing that the time spent interacting with computers would soon rival or exceed the time spent in automobiles (1:26-1:59).&lt;/p&gt;&#xA;  &lt;h2&gt;The Computer as a Medium: A New Era of Communication&lt;/h2&gt;&#xA;  &lt;p&gt;Jobs&#39;s most significant insight was his framing of the personal computer as a new medium of communication (1:59-3:38). He noted that each medium had its own unique opportunities and limitations, shaping both the content and the process of communication (1:59-3:38).&lt;/p&gt;&#xA;  &lt;p&gt;Comparing the telephone with electronic mail, Jobs highlighted how the computer changed the nature of communication. Unlike a phone call, where both parties must be present simultaneously, email allowed for asynchronous communication, enabling people to send and receive messages at their convenience (1:59-3:38). This asynchronicity, Jobs believed, would become even more significant with the development of portable computers with radio links (1:59-3:38).&lt;/p&gt;&#xA;  &lt;h2&gt;Breaking Out of Old Media Habits&lt;/h2&gt;&#xA;  &lt;p&gt;Jobs warned against falling back into &#34;old media habits&#34; when using this new medium (3:38-5:32). He cited early television programs, which were essentially radio shows with a camera pointed at them, as an example of this tendency (3:38-5:32). It took time, Jobs argued, for television to evolve into its own distinct medium, capable of delivering experiences like the JFK funeral and the Apollo Landing that were impossible with previous mediums (3:38-5:32).&lt;/p&gt;&#xA;  &lt;p&gt;Similarly, Jobs believed that the personal computer was still in its infancy, akin to the &#34;I Love Lucy stage&#34; of development (5:32-7:40). Early applications focused on traditional tasks like business accounting, reflecting a failure to fully grasp the potential of this new medium (5:32-7:40).&lt;/p&gt;&#xA;  &lt;p&gt;Jobs pointed to the Lisa computer, with its graphical interface and drawing capabilities, as an example of breaking free from these old habits (5:32-7:40). Lisa allowed users to combine pictures and words, send drawings electronically, and interact with computers in a more intuitive way (5:32-7:40).&lt;/p&gt;&#xA;  &lt;h2&gt;The Future of Programming&lt;/h2&gt;&#xA;  &lt;p&gt;Jobs also envisioned a future where programming would become more accessible, moving away from complex languages and towards graphical interfaces and intuitive tools (7:40-9:18). He believed that this shift would empower more people to create software, leading to a proliferation of innovative applications (7:40-9:18).&lt;/p&gt;&#xA;  &lt;p&gt;Jobs highlighted the potential for individual programmers to create successful software businesses, citing the example of a 13-year-old who was making $44,000 a week selling game programs for the Apple II (7:40-9:18). This, Jobs believed, demonstrated the transformative power of the personal computer and its ability to democratize software development (7:40-9:18).&lt;/p&gt;&#xA;  &lt;h2&gt;A Visionary Perspective&lt;/h2&gt;&#xA;  &lt;p&gt;Jobs&#39;s 1983 talk captures a pivotal moment in the history of personal computing. It articulates a vision that has largely come to fruition, where computers have become ubiquitous, intuitive, and powerful tools for communication, creativity, and knowledge sharing. Jobs&#39;s insights into the computer as a medium remain relevant today, as we continue to explore the ever-expanding possibilities of this technology.&lt;/p&gt;&#xA;</Body>
      <Link>/posts/jobs-about-the-future</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;In his 1983 talk at the International Design Conference in Aspen, &lt;a href=&#39;https://www.youtube.com/watch?v=GX9DsYTuYVU&#39; target=&#39;_blank&#39;&gt;Steve Jobs&lt;/a&gt; articulated a powerful vision for the future of personal computing. He saw the computer not just as a tool, but as a new medium of communication, on par with the book, the telephone, and the television. Just as each of these mediums had shaped the way we communicate, Jobs believed that the personal computer would profoundly transform our lives.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2024-12-18T00:00:00Z</PubDate>
      <ArticlePubDate>2024-12-18T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>4</ID>
      <CreatedAt>2025-06-11T13:48:23.459693Z</CreatedAt>
      <UpdatedAt>2025-06-22T21:16:35.474115Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>My guide to personal productivity</Title>
      <Body>&#xA;  &#xA;  &#xA;  &lt;h2&gt;Pre-read&lt;/h2&gt;&#xA;  &lt;p&gt;Before you read my guide below, which is very short, make sure you check out the original inspiration. That post contains many great points and sources.&lt;/p&gt;&#xA;  &lt;h2&gt;My guide&lt;/h2&gt;&#xA;  &lt;p&gt;I follow just five principles:&lt;/p&gt;&#xA;  &lt;ol&gt;&#xA;    &lt;li&gt;&#xA;      &lt;p&gt;&lt;strong&gt;Do only what you love doing&lt;/strong&gt;&lt;/p&gt;&#xA;      &lt;p&gt;This is the most important one. I focus solely on what I love doing — delegating or refusing to do everything else.&lt;/p&gt;&#xA;      &lt;p&gt;However, there is a significant drawback: after a while, I have to say no even to things I would love doing because I no longer have the mental bandwidth to do them too.&lt;/p&gt;&#xA;    &lt;/li&gt;&#xA;    &lt;li&gt;&#xA;      &lt;p&gt;&lt;strong&gt;Don’t keep a schedule&lt;/strong&gt;&lt;/p&gt;&#xA;      &lt;p&gt;In the past, my busy schedule kept me from focusing on what I enjoy. Now, I aim for an almost empty calendar with minimal scheduling.&lt;/p&gt;&#xA;    &lt;/li&gt;&#xA;    &lt;li&gt;&#xA;      &lt;p&gt;&lt;strong&gt;Before sleeping, make a loose mental plan for the next day&lt;/strong&gt;&lt;/p&gt;&#xA;      &lt;p&gt;I don’t use to-do lists, tracking tools, or task management systems — they’re stressful and take too much time to maintain. Instead, I spend that time doing what matters.&lt;/p&gt;&#xA;      &lt;p&gt;Keeping the plan simple and focused is crucial.&lt;/p&gt;&#xA;    &lt;/li&gt;&#xA;    &lt;li&gt;&#xA;      &lt;p&gt;&lt;strong&gt;Procrastinate regularly&lt;/strong&gt;&lt;/p&gt;&#xA;      &lt;p&gt;Procrastination is valuable. Taking time to do nothing allows for deep thinking and reflection. Embrace it and do it often.&lt;/p&gt;&#xA;    &lt;/li&gt;&#xA;    &lt;li&gt;&#xA;      &lt;p&gt;&lt;strong&gt;Do not split your focus&lt;/strong&gt;&lt;/p&gt;&#xA;      &lt;p&gt;Our brains can’t multitask; we only switch contexts, and context-switching is costly. I focus on one product or task per day, avoiding unnecessary jumps.&lt;/p&gt;&#xA;    &lt;/li&gt;&#xA;  &lt;/ol&gt;&#xA;  &lt;p&gt;That’s it. I have no other tricks.&lt;/p&gt;&#xA;</Body>
      <Link>/posts/my-guide-to-personal-productivity</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;I have found this guide of productivity again: &lt;a href=&#39;https://pmarchive.com/guide_to_personal_productivity.html&#39; target=&#39;_blank&#39;&gt;Pmarca Guide to Personal Productivity&lt;/a&gt; so I wanted to write down my version of it. &lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2024-11-27T00:00:00Z</PubDate>
      <ArticlePubDate>2024-11-27T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>5</ID>
      <CreatedAt>2025-06-11T13:48:23.463783Z</CreatedAt>
      <UpdatedAt>2025-06-22T21:16:35.476637Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>How to ship Go apps with Kamal</Title>
      <Body>&#xA;  &#xA;  &#xA;  &lt;h2&gt;What is Kamal?&lt;/h2&gt;&#xA;  &lt;p&gt;Quoting the definition from the&#xA;    &lt;a href=&#34;https://kamal-deploy.org&#34; target=&#34;_blank&#34;&gt;Kamal website&lt;/a&gt;: “Kamal offers zero-downtime deploys, rolling restarts, asset bridging, remote builds, accessory service management, and everything else you need to deploy and manage your web app in production with Docker. Originally built for Rails apps, Kamal will work with any type of web app that can be containerized.”&lt;/p&gt;&#xA;  &lt;p&gt;Practically, it allows for setting up the service on one or multiple bare servers and shipping the app there. And because Go builds into a binary, I am only shipping that to the server, embedded into a very minimal Docker image.&lt;/p&gt;&#xA;  &lt;p&gt;For details of the setup, Kamal commands, and general documentation, please read the documentation on the Kamal website.&lt;/p&gt;&#xA;  &lt;h2&gt;Configuration for this blog&lt;/h2&gt;&#xA;  &lt;p&gt;Kamal can use an elaborate setup, but I have kept things simple. Here’s the&#xA;    &lt;code&gt;deploy.yml&lt;/code&gt;:&lt;/p&gt;&#xA;  &lt;pre class=&#34;wide-1&#34;&gt;    &lt;code&gt;&#xA;      service: blog&#xA;&#xA;      image: edimoldovan/blog&#xA;&#xA;      servers:&#xA;        web:&#xA;          - 37.27.83.82&#xA;      &#xA;      proxy: &#xA;        ssl: true&#xA;        host: eduardmoldovan.com&#xA;        app_port: 8000&#xA;      &#xA;      registry:&#xA;        username: edimoldovan&#xA;      &#xA;        password:&#xA;          - KAMAL_REGISTRY_PASSWORD&#xA;      &#xA;      builder:&#xA;        arch: arm64&lt;/code&gt;&#xA;  &lt;/pre&gt;&#xA;  &lt;p&gt;Simple and concise — it only contains a few lines, configuring the IP to ship to, name of the service, port for the proxy to link to, the domain, and the Docker registry access password.&lt;/p&gt;&#xA;  &lt;p&gt;This last bit, the&#xA;    &lt;code&gt;KAMAL_REGISTRY_PASSWORD&lt;/code&gt;&#xA;    is configured in the&#xA;    &lt;code&gt;secrets&lt;/code&gt;&#xA;    file:&lt;/p&gt;&#xA;  &lt;pre class=&#34;wide-1&#34;&gt;    &lt;code&gt;&#xA;      KAMAL_REGISTRY_PASSWORD=$KAMAL_REGISTRY_PASSWORD&lt;/code&gt;&#xA;  &lt;/pre&gt;&#xA;  &lt;p&gt;There is only one additional file I am using, the&#xA;    &lt;code&gt;Dockerfile&lt;/code&gt;:&lt;/p&gt;&#xA;  &lt;pre class=&#34;wide-1&#34;&gt;    &lt;code&gt;&#xA;      # The build stage&#xA;      FROM golang:1.23 AS builder&#xA;      WORKDIR /app&#xA;      COPY . .&#xA;      RUN CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -a -installsuffix cgo server.go&#xA;&#xA;      # The run stage&#xA;      FROM scratch&#xA;      WORKDIR /app&#xA;      COPY --from=builder /app/server .&#xA;      EXPOSE 8000&#xA;      CMD [&#34;./server&#34;, &#34;-port&#34;, &#34;8000&#34;]&lt;/code&gt;&#xA;  &lt;/pre&gt;&#xA;  &lt;p&gt;As you can see, I have configured a builder with the latest version of Go. This builds the binary, which is then copied into the image that runs it. Otherwise, the file contains only standard Docker config.&lt;/p&gt;&#xA;  &lt;h2&gt;Configuration for an object storage service I built&lt;/h2&gt;&#xA;  &lt;p&gt;This is a service that works like an S3 bucket and performs all operations through an API. Most Kamal and Docker settings are the same, with the addition of mounted folders for the SQLite database and the files folder where objects are stored.&lt;/p&gt;&#xA;  &lt;p&gt;Here’s the&#xA;    &lt;code&gt;deploy.yml&lt;/code&gt;:&lt;/p&gt;&#xA;  &lt;pre class=&#34;wide-1&#34;&gt;      &lt;code&gt;&#xA;      service: object-storage&#xA;&#xA;      image: edimoldovan/object-storage&#xA;&#xA;      servers:&#xA;        web:&#xA;          - 37.27.83.82&#xA;&#xA;      proxy: &#xA;        ssl: true&#xA;        host: objects.makros.app&#xA;        app_port: 8080&#xA;&#xA;      registry:&#xA;        username: edimoldovan&#xA;        password:&#xA;          - KAMAL_REGISTRY_PASSWORD&#xA;&#xA;      builder:&#xA;        arch: arm64&#xA;&#xA;      env:&#xA;        clear:&#xA;          SOME_OTHER_VAR: 123&#xA;        secret:&#xA;          - MAKROS_OBJECT_STORAGE_TOKEN&#xA;&#xA;      volumes:&#xA;        - &#34;/root/storage/sqlite:/app/sqlite&#34;&#xA;        - &#34;/root/storage/files:/app/files&#34;&lt;/code&gt;&#xA;    &lt;/pre&gt;&#xA;  &lt;p&gt;And here’s the&#xA;    &lt;code&gt;Dockerfile&lt;/code&gt;:&lt;/p&gt;&#xA;  &lt;pre class=&#34;wide-1&#34;&gt;      &lt;code&gt;&#xA;      # The build stage&#xA;      FROM golang:1.23-alpine AS builder&#xA;      WORKDIR /app&#xA;      COPY . .&#xA;      RUN apk add --no-cache gcc libc-dev&#xA;      RUN CGO_ENABLED=1 GOOS=linux GOARCH=arm64 go build -a -installsuffix cgo main.go&#xA;      &#xA;      # The run stage&#xA;      FROM alpine:latest&#xA;      WORKDIR /app&#xA;      RUN apk add --no-cache sqlite-libs&#xA;      COPY --from=builder /app/main .&#xA;      RUN ls -l /app/main&#xA;      EXPOSE 8080&#xA;      CMD [&#34;./main&#34;, &#34;-port&#34;, &#34;8080&#34;]&lt;/code&gt;&#xA;    &lt;/pre&gt;&#xA;  &lt;p&gt;That&#39;s it. Each time I run&#xA;    &lt;code&gt;kamal deploy&lt;/code&gt;&#xA;    these get shipped from my laptop directly to the Hetzner machines.&lt;/p&gt;&#xA;</Body>
      <Link>/posts/how-to-ship-go-apps-with-kamal</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;I have been shiping most of my Go apps with Kamal for a while now. I am sharing the main config files I am using, with two different apps: this blog and a object storage service.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2024-11-13T00:00:00Z</PubDate>
      <ArticlePubDate>2024-11-13T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>6</ID>
      <CreatedAt>2025-06-11T13:48:23.467548Z</CreatedAt>
      <UpdatedAt>2025-06-22T21:16:35.479971Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>Towards modern development of cloud applications</Title>
      <Body>&#xA;  &#xA;  &#xA;  &lt;h2&gt;The problem at hand&lt;/h2&gt;&#xA;  &lt;p&gt;The traditional architecture of splitting applications into microservices, while beneficial for scalability, performance, and fault tolerance, introduces significant challenges. These include performance degradation due to serialization and network overhead, complexity in managing multiple binaries and their release schedules, difficulty in ensuring application correctness due to interactions between microservices, and constraints on API evolution due to established contracts between services.&lt;/p&gt;&#xA;  &lt;h2&gt;How Google propose we solve the problem&lt;/h2&gt;&#xA;  &lt;p&gt;The paper introduces a programming model and runtime that allow developers to write distributed applications as single-binary modular monoliths, focusing solely on business logic.&lt;/p&gt;&#xA;  &lt;p&gt;This model encourages the logical separation of application components without conflating logical and physical boundaries.&lt;/p&gt;&#xA;  &lt;p&gt;A specialized runtime dynamically handles the physical distribution and execution of these components based on performance characteristics, thereby addressing the core challenges of microservices (C1-C5). This approach simplifies application management, enhances performance, and ensures atomic deployment without versioning conflicts.&lt;/p&gt;&#xA;  &lt;h2&gt;My take&lt;/h2&gt;&#xA;  &lt;p&gt;I don’t have Google’s problems, and likely will never have them. And you are most likely in the same situation.&lt;/p&gt;&#xA;  &lt;p&gt;However, the modularity approach which is highlighted in the paper is an approach that I have followed for quite some time. I really like organising my code by two dimensions: bussiness logic and scale needs. The last one is mostly irrelevant, so I am only left with an organization based on what business the software needs to support.&lt;/p&gt;&#xA;  &lt;p&gt;My infrastructure is also very simple, I typically am totally covered with a single machine approach, without any Docker or any other similar tool. I just build my binary and ship it to the machine, restart the service it’s setup with and I’m done. This is all automated, either with GitHub Actions or some other way.&lt;/p&gt;&#xA;  &lt;h2&gt;Back to the paper&lt;/h2&gt;&#xA;  &lt;p&gt;The details of the problem, solution space and the deep hows you can read about in the paper itself, which is available&#xA;    &lt;a href=&#34;https://dl.acm.org/doi/pdf/10.1145/3593856.3595909&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;&#xA;</Body>
      <Link>/posts/towards-modern-development-of-cloud-applications</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;The paper, mentioned in the title, addresses the inherent challenges of the widely adopted microservices architecture in cloud computing, including performance bottlenecks, versioning issues, and increased complexity in application management. While microservices offer scalability, fault tolerance, and agile deployment, they also introduce significant overheads, making applications difficult to manage, reason about, and evolve.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2024-02-06T00:00:00Z</PubDate>
      <ArticlePubDate>2024-02-06T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>7</ID>
      <CreatedAt>2025-06-11T13:48:23.471259Z</CreatedAt>
      <UpdatedAt>2025-06-22T21:16:35.483362Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>Detailed example of web components usage</Title>
      <Body>&#xA;    &#xA;    &#xA;&#xA;    &lt;h2&gt;How David built Ghoala&lt;/h2&gt;&#xA;    &lt;p&gt;You can find the post &lt;a target=&#34;_blank&#34; href=&#34;https://naildrivin5.com/blog/2024/01/24/web-components-in-earnest.html?utm_source=tldrwebdev&#34;&gt;here&lt;/a&gt;—detailed and long.&lt;/p&gt;&#xA;    &lt;p&gt;David shares great detail of about interaction, inheriting properties in one component from another, how he structures the entire interface, but also saving state&lt;/p&gt;&#xA;  </Body>
      <Link>/posts/detailed-example-of-web-components-usage</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;I have been using web components instead of other libraries and their components for about an year now. They have a few key features, like built-in hydration, use of Shadow DOM or not, depending on your preference, that are indispensable in the UIs that I build.&lt;/&gt;&lt;p&gt;I found a post today that shows in detail what their potential is and how exactly they are being used to build an actual product.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2024-01-30T00:00:00Z</PubDate>
      <ArticlePubDate>2024-01-30T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>8</ID>
      <CreatedAt>2025-06-11T13:48:23.474779Z</CreatedAt>
      <UpdatedAt>2025-06-22T21:16:35.485657Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>Launching naina</Title>
      <Body>&#xA;  &#xA;  &#xA;  &lt;h2&gt;The background&lt;/h2&gt;&#xA;  &lt;p&gt;I have been working on the web for very long time and I think today we are likely very close to a dreamland from a web developer perspective.&lt;/p&gt;&#xA;  &lt;p&gt;No, I don’t mean all the JavaScript libraries out there that mostly do nothing else than bloat pages with unnessecary JavaScript, or frameworks like Tailwind which don’t do much else than hide the actual abilities of CSS and create hardly maintainable HTML and CSS, not to mention covering up the actual browser features which are generally far richer that whatever these libs provide.&lt;/p&gt;&#xA;  &lt;p&gt;What I do mean is the bliss of pure CSS and JavaScript, the automated, built-in, hydration abilities of custom elements and web components, the ability to use features like dynamic type scales and space scales in your design, all the done in a way that the statical canvas in Figma is simply oevrly limited to even immitate.&lt;/p&gt;&#xA;  &lt;h2&gt;The product&lt;/h2&gt;&#xA;  &lt;p&gt;I think it’s time for us to have tooling which enables designers and developers to work together, not siloed in their own tooling, while using the web as a common “drawing canvas”.&lt;/p&gt;&#xA;  &lt;p&gt;In more detail—I would like to provide designers a tool that allows them to design, end to end, in CSS and HTML without the need of learning any of that, or maybe just a little of it.&lt;/p&gt;&#xA;  &lt;p&gt;I want designers to be able to test with customers, to create amazing brands, using the full power of the web. And then, make their work’s output availabke to developers in their choice of framework, all directly into version controlled output.&lt;/p&gt;&#xA;  &lt;p&gt;Also, I want developers to be able to use these designs, in whatever state they are, without the need of a naina, while they work, as they normally do.&lt;/p&gt;&#xA;  &lt;p&gt;On top of that, I want developers to be able to influence the design, without learning design tooling, or various dev modes, but simply using the tooling they already use.&lt;/p&gt;&#xA;  &lt;p&gt;So this is exactly what I have started working on and I need your feedback. Have a look at the&#xA;    &lt;a href=&#34;https://naina.codes&#34; target=&#34;_blank&#34;&gt;homepage of naina.codes&lt;/a&gt;&#xA;    and let me know what you think.&lt;/p&gt;&#xA;  &lt;p&gt;There is a subscription option on the page, drop your email in there and I will notify you of the progress.&lt;/p&gt;&#xA;  &lt;p&gt;If you want to test, see an early demo, reach out somewhere and we’ll get that sorted.&lt;/p&gt;&#xA;  &lt;h2&gt;One more thing…&lt;/h2&gt;&#xA;  &lt;p&gt;The name—for the moment I am using naina.codes because I find it a funny name given that the tool is all about the lack of naina. Also, back in the day I received countless files called exaclty that from former designer colleagues or agencies. So, funny again.&lt;/p&gt;&#xA;</Body>
      <Link>/posts/launching-naina.codes</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;Even though it&#39;s only January, this year has already been very interesting for me. And since most of these interesting things are products on the web, and me being unhappy with design tooling for web products, I decided to build something different, something that fills in my needs primarily, but perhaps is able to help others as well.&lt;/p&gt;&lt;p&gt;Still in very early stage, today I am putting it partially out there for interested folks to provide feedback or even subscribe to progress notifications.&lt;/p&gt;&lt;p&gt;But first, let me tell you what it is.&lt;/&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2024-01-29T00:00:00Z</PubDate>
      <ArticlePubDate>2024-01-29T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>9</ID>
      <CreatedAt>2025-06-11T13:48:23.478523Z</CreatedAt>
      <UpdatedAt>2025-06-22T21:16:35.487871Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>Style external links differently</Title>
      <Body></Body>
      <Link>style-external-links-differently</Link>
      <ItemType>highlight</ItemType>
      <Description>&lt;p&gt;Let&amp;rsquo;s add a different color to the styles of external links, regardless if they open in a new tab or not:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;a[href^=&#34;http&#34;]::after {&#xA;  color: var(--color-secondary-1);&#xA;}&lt;/code&gt;&lt;/pre&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2023-10-30T00:00:00Z</PubDate>
      <ArticlePubDate>0001-01-01T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>10</ID>
      <CreatedAt>2025-06-11T13:48:23.481866Z</CreatedAt>
      <UpdatedAt>2025-06-22T21:16:35.490158Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>The one web layout that rules them all</Title>
      <Body>&#xA;    &#xA;    &#xA;&#xA;    &lt;h2&gt;The one&lt;/h2&gt;&#xA;    &lt;p&gt;To achieve the bold goal, there two thwo things we need to do:&lt;/p&gt;&#xA;    &lt;ol&gt;&#xA;      &lt;li&gt;Create a Grid layout in a specific manner&lt;/li&gt;&#xA;      &lt;li&gt;For each row in the grid we use a Flexbox element that horizontally displays and lays out our content&lt;/li&gt;&#xA;    &lt;/ol&gt;&#xA;    &lt;h2&gt;1. The Grid layout&lt;/h2&gt;&#xA;    &lt;pre class=&#34;wide-1&#34;&gt;&lt;code&gt;&#xA;      .content {&#xA;        --gap: clamp(1rem, 6vw, 3rem);&#xA;        --full: minmax(var(--gap), 1fr);&#xA;        --content: min(50ch, 100% - var(--gap) * 2);&#xA;        --wide-1: minmax(0, 2rem);&#xA;        --feature: minmax(0, 5rem);&#xA;      &#xA;        display: grid;&#xA;        grid-template-columns:&#xA;          [full-start] var(--full)&#xA;          [feature-start] var(--feature)&#xA;          [wide-1-start] var(--wide-1)&#xA;          [content-start] var(--content) [content-end]&#xA;          var(--wide-1) [wide-1-end]&#xA;          var(--feature) [feature-end]&#xA;          var(--full) [full-end];&#xA;      }&#xA;&#xA;      .content &amp;gt; * {&#xA;        grid-column: content;&#xA;      }&#xA;      .wide-1 {&#xA;        grid-column: wide-1;&#xA;      }&#xA;      .feature {&#xA;        grid-column: feature;&#xA;      }&#xA;      .full {&#xA;        grid-column: full;&#xA;      }&#xA;    &lt;/code&gt;&lt;/pre&gt;&#xA;    &lt;p&gt;Th gist of this layout is that we have a flexible and explicit grid that centers its children to the center by default but has a couple of layout breaks available as well.&lt;/p&gt;&#xA;    &lt;p&gt;The interesting part is that this grid will nicely adapt to a mobile screeen, becoming a narrow column thus limiting all its choldren to exactly that.&lt;/p&gt;&#xA;    &lt;p&gt;For a detailed description, please read the original post by Ryan Mulligan here &lt;a href=&#34;https://ryanmulligan.dev/blog/layout-breakouts/&#34; target=&#34;_blank&#34;&gt;Layout Breakouts with CSS Grid&lt;/a&gt;.&lt;/p&gt;&#xA;&#xA;    &lt;h2&gt;2. The Flexbox rows&lt;/h2&gt;&#xA;    &lt;p&gt;No code to show here, the only reason I am mentioning the Flexbox is because I think it’s the easiest way to create a responsive row that occupies the entire space made available by its parent.&lt;/p&gt;&#xA;    &lt;p&gt;You can obviously use any structure here that fits yoru needs, even reuse the grid above, the way I do in the blue hero of this page.&lt;/p&gt;&#xA;&#xA;    &lt;h2&gt;Go ahead and test it&lt;/h2&gt;&#xA;    &lt;p&gt;Given that this page is built with this approach, inspect it, have a look at the css, play with it to see it in action. Then go use it.&lt;/p&gt;&#xA;  </Body>
      <Link>/posts/the-one-web-layout-that-rules-them-all</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;I have a bold claim: there is a responsive CSS Grid / Flexbox combo layout that can be used to build almost any web layout. At least I haven&amp;rsquo;t found any layout I wanted to build and couldn&amp;rsquo;t.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2023-10-20T00:00:00Z</PubDate>
      <ArticlePubDate>2023-10-20T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>11</ID>
      <CreatedAt>2025-06-11T13:48:23.485467Z</CreatedAt>
      <UpdatedAt>2025-06-22T21:16:35.492518Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>CSS findings from the Threads app&amp;mdash;by Ahmad Shadeed</Title>
      <Body>&#xA;    &#xA;    &#xA;&#xA;    &lt;h2&gt;About Ahmad&lt;/h2&gt;&#xA;    &lt;p&gt;Ahmad is an experienced designer and developer who shares highly detailed, hands-on content on &lt;a href=&#34;https://ishadeed.com/articles&#34; target=&#34;_blank&#34;&gt;his blog here&lt;/a&gt;.&lt;/p&gt;&#xA;    &lt;h2&gt;Threads app CSS reviews&lt;/h2&gt;&#xA;    &lt;p&gt;He published two great vies, you can find them here: &lt;a href=&#34;https://ishadeed.com/article/threads-app-css&#34; target=&#34;_blank&#34;&gt;CSS Findings From The Threads App&lt;/a&gt; and &lt;a href=&#34;https://ishadeed.com/article/threads-app-css-part-2&#34; target=&#34;_blank&#34;&gt;CSS Findings From The Threads App: Part 2&lt;/a&gt;.&lt;/p&gt;&#xA;    &lt;p&gt;There are many interesting features and practices he showcases but one which I find useful is outlining all the elements rendered in a page without changing the layout, like this:&lt;/p&gt;&#xA;&#xA;    &lt;pre class=&#34;wide-1&#34;&gt;&lt;code&gt;&#xA;    *,&#xA;    *:before,&#xA;    *:after {&#xA;      outline: solid 0.5px #db6a7d;&#xA;      border: 0;&#xA;    }&#xA;    &lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;    &lt;p&gt;This is something available as a debug tool on native platforms, quite useful for visualising render details or issues.&lt;/p&gt;&#xA;    &lt;p&gt;The other thing, which I also like a lot and advocate for, is grid for layout and flexbox for components. Most layouts can be be implemented with a single grid (more about this in a later not post) with customization abilities implmented on layout component level with flexbox (or another grid if really needed, which is rare).&lt;/p&gt;&#xA;    &lt;p&gt;Both posts are well worth your time.&lt;/p&gt;&#xA;  </Body>
      <Link>/posts/css-findings-by-ahmad-shadeed</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;Ahmad did two great reviews of the Threads app. Quite a few interesting CSS or unusual CSS technniques there.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2023-09-26T00:00:00Z</PubDate>
      <ArticlePubDate>2023-09-26T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>12</ID>
      <CreatedAt>2025-06-11T13:48:23.489044Z</CreatedAt>
      <UpdatedAt>2025-08-03T16:44:51.016796Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>Component hydration with no dependencies</Title>
      <Body>&#xA;    &#xA;    &#xA;    &lt;h2&gt;tldr;&lt;/h2&gt;&#xA;    &lt;p&gt;Here’s what we will achieve, with examples:&lt;/p&gt;&#xA;    &lt;ol&gt;&#xA;      &lt;li&gt;Create client web components that will be used to hydrate the server one&lt;/li&gt;&#xA;      &lt;li&gt;Create server component to provide the structure on the client&lt;/li&gt;&#xA;      &lt;li&gt;Style the web component with reusable styles&lt;/li&gt;&#xA;    &lt;/ol&gt;&#xA;    &lt;h2&gt;Demo first&lt;/h2&gt;&#xA;    &lt;p&gt;Here are two buttons—both are created from a server rendered HTML structure that is automatically hydrated on the client with the client component. Watch the console while you click them, you’ll see a brief message logged each time you click any of them.&lt;/p&gt;&#xA;    &lt;section&gt;&#xA;      &lt;primary-button&gt;&#xA;        &#xA;&lt;template shadowrootmode=&#34;open&#34;&gt;&#xA;  &lt;link rel=&#34;stylesheet&#34; href=&#34;/public/css/button.css&#34;&gt;&#xA;  &lt;link rel=&#34;stylesheet&#34; href=&#34;/public/css/primary-button.css&#34;&gt;&#xA;  &lt;button disabled=&#34;&#34;&gt;&#xA;    &lt;slot&gt;&lt;/slot&gt;&#xA;  &lt;/button&gt;&#xA;&lt;/template&gt;&#xA;&#xA;        Primary&#xA;      &lt;/primary-button&gt;&#xA;      &lt;secondary-button&gt;&#xA;        &#xA;&lt;template shadowrootmode=&#34;open&#34;&gt;&#xA;  &lt;link rel=&#34;stylesheet&#34; href=&#34;/public/css/button.css&#34;&gt;&#xA;  &lt;link rel=&#34;stylesheet&#34; href=&#34;/public/css/secondary-button.css&#34;&gt;&#xA;  &lt;button disabled=&#34;&#34;&gt;&#xA;    &lt;slot&gt;&lt;/slot&gt;&#xA;  &lt;/button&gt;&#xA;&lt;/template&gt;&#xA;&#xA;        Secondary&#xA;      &lt;/secondary-button&gt;&#xA;    &lt;/section&gt;&#xA;    &lt;h2&gt;How?&lt;/h2&gt;&#xA;    &lt;p&gt;I am using a feature called Declarative Shadow DOM to make this happen. &lt;a href=&#34;https://developer.chrome.com/en/articles/declarative-shadow-dom/&#34;&gt;Here’s&lt;/a&gt;  more details on this feature from the Chrome team.&lt;/p&gt;&#xA;    &lt;p&gt;Practically, we can now define a shadow DOM that will be rendered by the browser at render and on top of that it will also automatically upgrade that to a client web component, assuming we have defined and declared that appropriately.&lt;/p&gt;&#xA;    &lt;h2&gt;Client web component&lt;/h2&gt;&#xA;    &lt;p&gt;In order to be able to hydrate automatically, the browser need an actual client component. Here’s how this component looks like in the case of the blue button, which I called &lt;code&gt;PrimaryButton&lt;/code&gt;&lt;/p&gt;&#xA;    &lt;pre class=&#34;wide-1&#34;&gt;&lt;code&gt;&#xA;      class PrimaryButton extends HTMLElement {&#xA;        constructor() {&#xA;          super();&#xA;          this.shadowRoot.querySelector(&#34;button&#34;).removeAttribute(&#34;disabled&#34;);&#xA;          this.shadowRoot.querySelector(&#34;button&#34;).addEventListener(&#34;click&#34;, e =&amp;gt; {&#xA;            e.preventDefault();&#xA;            console.log(&#34;button clicked&#34;);&#xA;          });&#xA;        }&#xA;      }&#xA;      customElements.define(&#34;primary-button&#34;, PrimaryButton);&#xA;    &lt;/code&gt;&lt;/pre&gt;&#xA;    &lt;p&gt;Not much happening here: I declare the class and in its constructor I call the &lt;code&gt;super()&lt;/code&gt;, remove the &lt;code&gt;disabled&lt;/code&gt; attribute and then I attach a &lt;code&gt;click&lt;/code&gt; event for demo purposes.&lt;/p&gt;&#xA;    &lt;p&gt;And here’s the magic: when the browser is parsing the HTML and it has this client component available, it will automatically hydrate the server rendered HTML with this logic—we literally don’t need to do anything for this to happen, only have the server rendered structure in place. Let’s have a look at that.&lt;/p&gt;&#xA;    &lt;h2&gt;Server component&lt;/h2&gt;&#xA;    &lt;p&gt;This is nothing else but a fancy name for the html from the server, whic looks like this in HTML as a Go template:&lt;/p&gt;&#xA;    &lt;pre class=&#34;wide-1&#34;&gt;&lt;code&gt;&#xA;      &amp;lt;primary-button&amp;gt;&#xA;        {{template &#34;button&#34; &#34;primary&#34;}}&#xA;        Primary&#xA;      &amp;lt;/primary-button&amp;gt;&#xA;    &lt;/code&gt;&lt;/pre&gt;&#xA;    &lt;pre class=&#34;wide-1&#34;&gt;&lt;code&gt;&#xA;      {{define &#34;button&#34;}}&#xA;        &amp;lt;template shadowrootmode=&#34;open&#34;&amp;gt;&#xA;          &amp;lt;link rel=&#34;stylesheet&#34; href=&#34;/public/css/button.css&#34; /&amp;gt;&#xA;          &amp;lt;link rel=&#34;stylesheet&#34; href=&#34;/public/css/{{.}}-button.css&#34; /&amp;gt;&#xA;          &amp;lt;button disabled&amp;gt;&#xA;            &amp;lt;slot&amp;lt;&amp;gt;/slot&amp;gt;&#xA;          &amp;lt;/button&amp;gt;&#xA;          &amp;lt;/template&amp;gt;&#xA;      {{end}}&#xA;    &lt;/code&gt;&lt;/pre&gt;&#xA;    &lt;p&gt;First one is the usage of the web component bound to a custom element, the second one is the reusable part for the declarative DOM shadow itself.&lt;/p&gt;&#xA;    &lt;p&gt;The second one also helps me pass in a parameter to load a different CSS specific for that particular component.&lt;/p&gt;&#xA;    &lt;p&gt;The more general button CSS:&lt;/p&gt;&#xA;    &lt;pre class=&#34;wide-1&#34;&gt;&lt;code&gt;&#xA;      button {&#xA;        color: var(--color);&#xA;        background-color: var(--background-color);&#xA;        font-size: var(--font-size);&#xA;        padding: .5em 1em;&#xA;        border: 1px solid var(--color-neutral-1);&#xA;        border-radius: var(--space-l);&#xA;        cursor: pointer;&#xA;      }&#xA;      &#xA;      button[disabled] {&#xA;        opacity: .5;&#xA;        cursor: not-allowed;&#xA;      }&#xA;    &lt;/code&gt;&lt;/pre&gt;&#xA;    &lt;p&gt;And the more specific button CSS, which just overrides the CSS vars I want to use for styling:&lt;/p&gt;&#xA;    &lt;pre class=&#34;wide-1&#34;&gt;&lt;code&gt;&#xA;      button {&#xA;        --color: var(--color-neutral-1);&#xA;        --background-color: var(--color-brand);&#xA;        --font-size: var(--step-1);&#xA;      }&#xA;    &lt;/code&gt;&lt;/pre&gt;&#xA;    &lt;p&gt;Important note: not all CSS leaks through the shadow barrier. Here’s the list of CSS properties that do:&lt;/p&gt;&#xA;    &lt;pre class=&#34;wide-1&#34;&gt;&lt;code&gt;&#xA;      1. border-collapse        13. font-weight               25. text-align&#xA;      2. border-spacing         14. font-size-adjust          26. text-align-last&#xA;      3. caption-side           15. font-stretch              27. text-decoration-color&#xA;      4. color                  16. letter-spacing            28. text-indent&#xA;      5. cursor                 17. line-height               29. text-justify&#xA;      6. direction              18. list-style                30. text-shadow&#xA;      7. empty-cells            19. list-style-image          31. text-transform&#xA;      8. font                   20. list-style-position       32. white-space widows&#xA;      9. font-family            21. list-style-type           33. word-break&#xA;      10. font-size             22. orphans                   34. word-spacing&#xA;      11. font-style            23. quotes                    35. word-wrap&#xA;      12. font-variant          24. tab-size                  36. visibility&#xA;    &lt;/code&gt;&lt;/pre&gt;&#xA;    &lt;p&gt;This is why I have used a different approach for styling the buttons as opposed to inheriting through the traditional cascade.&lt;/p&gt;&#xA;    &lt;h2&gt;That is almost all&lt;/h2&gt;&#xA;    &lt;p&gt;One minor challenge that I have right now is that Firefox doesn’t yet support declarative shadow DOM, so there is a shim in the source of this page to make it all work in Firefox. Hopefully they will implement soon and I can update the post.&lt;/p&gt;&#xA;    &lt;h2&gt;Key takeway&lt;/h2&gt;&#xA;    &lt;p&gt;We can use SSR generated web components with automatic hydration in the browsers right now, without any dependencies by implementing declarative DOM shadows and their counterpart web components. Absolutely no framework needed to achieve this.&lt;/p&gt;&#xA;  </Body>
      <Link>/posts/component-hydration-with-no-dependencies</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;Client component hydration has been a trendy topic these days. Some frameworks like Next, Astro and others are already doing it.&lt;/p&gt;&lt;p&gt;It is not common knowledge that we can achieve a very similar result with pure SSR and declarative shadow DOM.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2023-08-27T00:00:00Z</PubDate>
      <ArticlePubDate>2023-08-27T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>13</ID>
      <CreatedAt>2025-06-11T13:48:23.49313Z</CreatedAt>
      <UpdatedAt>2025-06-22T21:16:35.497145Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>Typeface ligatures everywhere&amp;mdash;like fi</Title>
      <Body></Body>
      <Link>typeface-ligatures</Link>
      <ItemType>highlight</ItemType>
      <Description>&lt;p&gt;All typefaces have been instructed to display their ligatures, by default, like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;body {&#xA;  font-variant-ligatures: normal;&#xA;  font-feature-settings: &#34;liga&#34; 1, &#34;dlig&#34; 1, &#34;hlig&#34; 1, &#34;clig&#34; 1, &#34;calt&#34; 1;&#xA;}&lt;/code&gt;&lt;/pre&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2023-08-17T00:00:00Z</PubDate>
      <ArticlePubDate>0001-01-01T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>14</ID>
      <CreatedAt>2025-06-11T13:48:23.497026Z</CreatedAt>
      <UpdatedAt>2025-06-22T21:16:35.500014Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>HTML details</Title>
      <Body>&#xA;    &#xA;    &#xA;    &lt;h2&gt;The element&lt;/h2&gt;&#xA;    &lt;p&gt;&#xA;      As W3C standards are evolving, along with browsers implementing them gradually, we get to use new elements which so far needed JavaScript to implement. The &lt;code&gt;details&lt;/code&gt; element is one of these. It allows us to present a summary of content and at user choice, to show a detailed view of that content. &#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;All this with no JavaScript at all. Here’s how.&lt;/p&gt;&#xA;    &lt;pre class=&#34;wide-1&#34;&gt;&lt;code&gt;&#xA;      &amp;lt;details class=&#34;highlight&#34;&amp;gt;&#xA;      &amp;lt;summary&amp;gt;Custom hover states on this page&amp;lt;/summary&amp;gt;&#xA;      &amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;&#xA;        a:hover {&#xA;          text-decoration: underline;&#xA;          text-decoration-thickness: .1em;&#xA;          text-underline-offset: .15em;&#xA;          text-decoration-color: var(--color-secondary-1);&#xA;        }&#xA;        &amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&#xA;      &amp;lt;/details&amp;gt;&#xA;    &lt;/code&gt;&lt;/pre&gt;&#xA;    &lt;p&gt;This is the HTML snippet I use on the home page to show how I have customised the hover states. I want to point out three points about it:&lt;/p&gt;&#xA;    &lt;ul&gt;&#xA;      &lt;li&gt;&lt;code&gt;details&lt;/code&gt; element definition&lt;/li&gt;&#xA;      &lt;li&gt;providing a &lt;code&gt;summary&lt;/code&gt;&lt;/li&gt;&#xA;      &lt;li&gt;crafting the content to be showed after the open action&lt;/li&gt;&#xA;    &lt;/ul&gt;&#xA;    &lt;p&gt;A basic unstyled version of it would look like this:&lt;/p&gt;&#xA;    &lt;details&gt;&#xA;      &lt;summary&gt;Custom hover states&lt;/summary&gt;&#xA;      &lt;pre&gt;&lt;code&gt;&#xA;    a:hover {&#xA;      text-decoration: underline;&#xA;      text-decoration-thickness: .1em;&#xA;      text-underline-offset: .15em;&#xA;      text-decoration-color: var(--color-secondary-1);&#xA;    }&#xA;      &lt;/code&gt;&lt;/pre&gt;&#xA;    &lt;/details&gt;&#xA;    &lt;p&gt;Styling it obviously makes it a little nicer, something like below—which is the same one I use on the homepage:&lt;/p&gt;&#xA;    &lt;details class=&#34;highlight&#34;&gt;&#xA;      &lt;summary&gt;Custom hover states&lt;/summary&gt;&#xA;      &lt;pre&gt;&lt;code&gt;&#xA;    a:hover {&#xA;      text-decoration: underline;&#xA;      text-decoration-thickness: .1em;&#xA;      text-underline-offset: .15em;&#xA;      text-decoration-color: var(--color-secondary-1);&#xA;    }&#xA;      &lt;/code&gt;&lt;/pre&gt;&#xA;    &lt;/details&gt;&#xA;    &lt;p&gt;That’s all. As I said, no JavaScript needed. All can be styled with CSS, as above.&lt;/p&gt;&#xA;  </Body>
      <Link>/posts/html-details</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;On occasion we need to present a summary of content while allowing the user to deep dive if they want to. The &lt;code&gt;details&lt;/code&gt; element is a great way to do this, with good browser support as well. Let&#39;s see how.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2023-08-04T00:00:00Z</PubDate>
      <ArticlePubDate>2023-08-04T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>16</ID>
      <CreatedAt>2025-06-11T13:48:23.505125Z</CreatedAt>
      <UpdatedAt>2025-06-22T21:16:35.502228Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>HTML dialog, occasionally modal</Title>
      <Body>&#xA;    &#xA;    &#xA;    &lt;h2&gt;The dialog element&lt;/h2&gt;&#xA;    &lt;p&gt;Most recent browsers have implement the fairly recent HTML element called &lt;code&gt;dialog&lt;/code&gt;. It can be used in two cases:&lt;/p&gt;&#xA;    &lt;ul&gt;&#xA;      &lt;li&gt;as a non-modal dialog&lt;/li&gt;&#xA;      &lt;li&gt;as a modal dialod&lt;/li&gt;&#xA;    &lt;/ul&gt;&#xA;    &lt;h2&gt;Non-modal dialog&lt;/h2&gt;&#xA;    &lt;p&gt;Let’s assume we need to display some overlay on top of an existing interface that needs to cover all elements but not behave as a modal. Basically mimic a higher &lt;code&gt;z-index&lt;/code&gt; value. Try clicking the button below.&lt;/p&gt;&#xA;    &lt;button onclick=&#34;showNonModal()&#34;&gt;non-modal&lt;/button&gt;&#xA;    &lt;dialog id=&#34;nmdialog&#34;&gt;&#xA;      &lt;h1&gt;Non-modal dialog&lt;/h1&gt;&#xA;      &lt;p&gt;This is a non-modal dialog&lt;/p&gt;&#xA;      &lt;button onclick=&#34;this.parentElement.close()&#34;&gt;close&lt;/button&gt;&#xA;    &lt;/dialog&gt;&#xA;    &lt;p&gt;Here’s the code for this, the html first:&lt;/p&gt;&#xA;    &lt;pre class=&#34;wide-1&#34;&gt;&lt;code&gt;&#xA;      &amp;lt;dialog id=&#34;nmdialog&#34;&amp;gt;&#xA;        &amp;lt;h1&amp;gt;Non-modal dialog&amp;lt;/h1&amp;gt;&#xA;        &amp;lt;p&amp;gt;This is a non-modal dialog&amp;lt;/p&amp;gt;&#xA;        &amp;lt;button onclick=&#34;this.parentElement.close()&#34;&amp;gt;close&amp;lt;/button&amp;gt;&#xA;      &amp;lt;/dialog&amp;gt;&#xA;    &lt;/code&gt;&lt;/pre&gt;&#xA;    &lt;p&gt;And now the JavaScript:&lt;/p&gt;&#xA;    &lt;pre class=&#34;wide-1&#34;&gt;&lt;code&gt;&#xA;      function showNonModal() {&#xA;        const dialog = document.getElementById(&#34;nmdialog&#34;);&#xA;        dialog.show();&#xA;      }&#xA;    &lt;/code&gt;&lt;/pre&gt;&#xA;    &lt;p&gt;This is all that is needed to display such a dialog. We can of course style it with CSS to make it look like or position it as we want.&lt;/p&gt;&#xA;    &lt;h2&gt;Modal dialog&lt;/h2&gt;&#xA;    &lt;p&gt;Similarly, we can display the dialog in a modal manner as well. We only need to call a different function to show it and, if we want, we can style the &lt;code&gt;::backdrop&lt;/code&gt;.&lt;/p&gt;&#xA;    &lt;button onclick=&#34;showModal()&#34;&gt;modal&lt;/button&gt;&#xA;    &lt;dialog id=&#34;mdialog&#34;&gt;&#xA;      &lt;h1&gt;Modal dialog&lt;/h1&gt;&#xA;      &lt;p&gt;This is a modal dialog&lt;/p&gt;&#xA;      &lt;button onclick=&#34;this.parentElement.close()&#34;&gt;close&lt;/button&gt;&#xA;    &lt;/dialog&gt;&#xA;    &lt;p&gt;There are two differences, as I mentioned above: &lt;/p&gt;&#xA;    &lt;ol&gt;&#xA;      &lt;li&gt;we need to call &lt;code&gt;showModal()&lt;/code&gt; instead of &lt;code&gt;show()&lt;/code&gt;&lt;/li&gt;&#xA;      &lt;li&gt;we can style the &lt;code&gt;::backdrop&lt;/code&gt;&lt;/li&gt;&#xA;    &lt;/ol&gt;&#xA;    &lt;p&gt;Here’s how we do the styl;ing of the &lt;code&gt;::backdrop&lt;/code&gt;:&lt;/p&gt;&#xA;    &lt;pre class=&#34;wide-1&#34;&gt;&lt;code&gt;&#xA;      dialog::backdrop {&#xA;        background-color: color(display-p3 1 0 0 / .33);&#xA;      }&#xA;    &lt;/code&gt;&lt;/pre&gt;&#xA;    &lt;p&gt;The &lt;code&gt;::backdrop&lt;/code&gt; can also be styled as everything else with CSS. One note of warning though: whil;e it supports the recent CSS color syntax it seems to have issues with colors defined in CSS variables, those don’t work for some reason.&lt;/p&gt;&#xA;  </Body>
      <Link>/posts/html-dialog</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;Many times we need to show a modal to the user, to ask for confirmation, or to show some additional information in a manner which covers the rest of the page user interface. The &lt;code&gt;dialog&lt;/code&gt; element is a great way to do this, and it is supported by all major browsers.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2023-08-03T00:00:00Z</PubDate>
      <ArticlePubDate>2023-08-03T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>15</ID>
      <CreatedAt>2025-06-11T13:48:23.500808Z</CreatedAt>
      <UpdatedAt>2025-06-22T21:16:35.504602Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>Custom &lt;code&gt;a&lt;/code&gt; hover states</Title>
      <Body></Body>
      <Link>custome-hover-states</Link>
      <ItemType>highlight</ItemType>
      <Description>&lt;p&gt;All &lt;code&gt;a&lt;/code&gt; elements on this page have a customised hover effect. Here&#39;s how to achive that:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;a:hover {&#xA;  text-decoration: underline;&#xA;  text-decoration-thickness: .1em;&#xA;  text-underline-offset: .15em;&#xA;  text-decoration-color: var(--color-secondary-1);&#xA;}&lt;/code&gt;&lt;/pre&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2023-08-02T00:00:00Z</PubDate>
      <ArticlePubDate>0001-01-01T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>17</ID>
      <CreatedAt>2025-06-11T13:48:23.508983Z</CreatedAt>
      <UpdatedAt>2025-06-22T21:16:35.506992Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>Better end to end design systems</Title>
      <Body>&#xA;    &#xA;    &#xA;    &lt;h2&gt;Tooling&lt;/h2&gt;&#xA;    &lt;p&gt;&#xA;      On top of the above challenges, the tools designer and developers use are very different from eachother. For&#xA;      instance, while being an amazing design tool, Figma works on a very different structure than the html itself. Which&#xA;      bring in subjectivity of implementation on the developer side, as in, what is good implementation, how&#xA;      things should be structured, how they should be styled.&#xA;    &lt;/p&gt;&#xA;&#xA;    &lt;h2&gt;What defines a digital brand?&lt;/h2&gt;&#xA;    &lt;p&gt;&#xA;      &lt;i&gt;Update:&lt;/i&gt; my buddy Bhu pointed out to me that I have over simplified the definition of a digital brand. So let’s fix that.&#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      There are several dimensions that contribute to users recognising a brand: logo, color palette, typography, imagery and visual style, tone and voice, user experience, brand messaging and probably several others.&#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      From a very practical perspective, an implementation one in code, I claim the above dimensions can be reduced mostly to these: &lt;strong&gt;color&lt;/strong&gt;, &lt;strong&gt;type&lt;/strong&gt; and&#xA;      &lt;strong&gt;space&lt;/strong&gt; are three main traints that define a brand. Everything else will be minor and will not make a signifficant difference on your brand. Let’s have a a lookt at each and how we can&#xA;      improve their implementation today.&#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      What we aim to achive is ease of implementation and maintanance, including good design communication.&#xA;    &lt;/p&gt;&#xA;&#xA;    &lt;h3&gt;Color&lt;/h3&gt;&#xA;    &lt;p&gt;&#xA;      The biggest improvement what we can bring in is the single source of truth for colors. We define a set of variables&#xA;      that will hold our colors.&#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      The how is little different though. While we will use CSS variables for reusability, we will also introduce a new&#xA;      color space, at least new to CSS OKLch.&#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      To make things a little simpler to grasp, I changed the colors on this page to OKLch. Let’s take a look at the&#xA;      definitions:&#xA;    &lt;/p&gt;&#xA;    &lt;pre class=&#34;wide-1&#34;&gt;&lt;code class=&#34;language-css&#34;&gt;&#xA;      --color-light-brand-lightness: 52%;&#xA;      --color-dark-brand-lightness: 58%;&#xA;      --color-brand-chroma: 0.188;&#xA;      --color-brand-hue: 249.435;&#xA;      --color-light-brand: oklch(var(--color-light-brand-lightness) var(--color-brand-chroma) var(--color-brand-hue));&#xA;      --color-dark-brand: oklch(var(--color-dark-brand-lightness) var(--color-brand-chroma) var(--color-brand-hue));&#xA;&#xA;      --color-light-secondary-1-lightness: 44.4%;&#xA;      --color-dark-secondary-1-lightness: 52%;&#xA;      --color-secondary-1-chroma: 0.202;&#xA;      --color-secondary-1-hue: 26.47;&#xA;      --color-light-secondary-1: oklch(var(--color-light-secondary-1-lightness) var(--color-secondary-1-chroma) var(--color-secondary-1-hue));&#xA;      --color-dark-secondary-1: oklch(var(--color-dark-secondary-1-lightness) var(--color-secondary-1-chroma) var(--color-secondary-1-hue));&#xA;    &lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;    &lt;p&gt;&#xA;      There is some level of similarity to HSL, but the difference is that OKLch is perceptually uniform. This means that the difference in definition values between two colors is the same, no matter where they are on the color wheel. This is not the case with HSL, where the difference between two colors is not the same, depending on where they are on the color wheel.&#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      Structurally, I defined two sets of colors here: one for light mode and one for dark mode. See the two for the current color mode below.&#xA;    &lt;/p&gt;&#xA;&#xA;    &lt;ul class=&#34;blog-colors&#34;&gt;&#xA;      &lt;li class=&#34;color&#34; style=&#34;background-color: var(--color-brand);&#34;&gt;&lt;/li&gt;&#xA;      &lt;li class=&#34;color&#34; style=&#34;background-color: var(--color-secondary-1);&#34;&gt;&lt;/li&gt;&#xA;    &lt;/ul&gt;&#xA;&#xA;    &lt;p&gt;&#xA;      And here we have some neutral color shades so that we can see the better definition abilities of the OKLch color space really shine.&#xA;    &lt;/p&gt;&#xA;&#xA;    &lt;ul class=&#34;blog-colors&#34;&gt;&#xA;      &lt;li class=&#34;color&#34; style=&#34;background-color: var(--color-neutral-1);&#34;&gt;&lt;/li&gt;&#xA;      &lt;li class=&#34;color&#34; style=&#34;background-color: var(--color-neutral-2);&#34;&gt;&lt;/li&gt;&#xA;      &lt;li class=&#34;color&#34; style=&#34;background-color: var(--color-neutral-3);&#34;&gt;&lt;/li&gt;&#xA;      &lt;li class=&#34;color&#34; style=&#34;background-color: var(--color-neutral-4);&#34;&gt;&lt;/li&gt;&#xA;      &lt;li class=&#34;color&#34; style=&#34;background-color: var(--color-neutral-5);&#34;&gt;&lt;/li&gt;&#xA;      &lt;li class=&#34;color&#34; style=&#34;background-color: var(--color-neutral-6);&#34;&gt;&lt;/li&gt;&#xA;      &lt;li class=&#34;color&#34; style=&#34;background-color: var(--color-neutral-7);&#34;&gt;&lt;/li&gt;&#xA;      &lt;li class=&#34;color&#34; style=&#34;background-color: var(--color-neutral-8);&#34;&gt;&lt;/li&gt;&#xA;      &lt;li class=&#34;color&#34; style=&#34;background-color: var(--color-neutral-9);&#34;&gt;&lt;/li&gt;&#xA;    &lt;/ul&gt;&#xA;&#xA;    &lt;p&gt;&#xA;      Beautiful, uniform and predictable. Here’s the source for the neutral shades above.&#xA;    &lt;/p&gt;&#xA;&#xA;    &lt;pre class=&#34;wide-1&#34;&gt;&lt;code class=&#34;language-css&#34;&gt;&#xA;      --color-light-neutral-1: oklch(10% calc(var(--color-brand-chroma) / 10) var(--color-brand-hue));&#xA;      --color-light-neutral-2: oklch(20% calc(var(--color-brand-chroma) / 10) var(--color-brand-hue));&#xA;      --color-light-neutral-3: oklch(30% calc(var(--color-brand-chroma) / 10) var(--color-brand-hue));&#xA;      --color-light-neutral-4: oklch(40% calc(var(--color-brand-chroma) / 10) var(--color-brand-hue));&#xA;      --color-light-neutral-5: oklch(50% calc(var(--color-brand-chroma) / 10) var(--color-brand-hue));&#xA;      --color-light-neutral-6: oklch(60% calc(var(--color-brand-chroma) / 10) var(--color-brand-hue));&#xA;      --color-light-neutral-7: oklch(70% calc(var(--color-brand-chroma) / 10) var(--color-brand-hue));&#xA;      --color-light-neutral-8: oklch(80% calc(var(--color-brand-chroma) / 10) var(--color-brand-hue));&#xA;      --color-light-neutral-9: oklch(90% calc(var(--color-brand-chroma) / 10) var(--color-brand-hue));&#xA;&#xA;      --color-dark-neutral-1: oklch(90% calc(var(--color-brand-chroma) / 10) var(--color-brand-hue));&#xA;      --color-dark-neutral-2: oklch(80% calc(var(--color-brand-chroma) / 10) var(--color-brand-hue));&#xA;      --color-dark-neutral-3: oklch(70% calc(var(--color-brand-chroma) / 10) var(--color-brand-hue));&#xA;      --color-dark-neutral-4: oklch(60% calc(var(--color-brand-chroma) / 10) var(--color-brand-hue));&#xA;      --color-dark-neutral-5: oklch(50% calc(var(--color-brand-chroma) / 10) var(--color-brand-hue));&#xA;      --color-dark-neutral-6: oklch(40% calc(var(--color-brand-chroma) / 10) var(--color-brand-hue));&#xA;      --color-dark-neutral-7: oklch(30% calc(var(--color-brand-chroma) / 10) var(--color-brand-hue));&#xA;      --color-dark-neutral-8: oklch(20% calc(var(--color-brand-chroma) / 10) var(--color-brand-hue));&#xA;      --color-dark-neutral-9: oklch(10% calc(var(--color-brand-chroma) / 10) var(--color-brand-hue));&#xA;    &lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;    &lt;p&gt;&#xA;      I have left the scale uniform and linear, but it can be customized to any scale you want. For instance, you can have a scale that is darker at the top and lighter at the bottom, or vice versa. You can also have a scale that is not linear, but exponential, or logarithmic, or any other scale you want.&#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      Also, I left a small level of chroma in the neutral shades to match the brand color better.&#xA;    &lt;/p&gt;&#xA;&#xA;    &lt;h3&gt;Type, or better said, type scales&lt;/h3&gt;&#xA;&#xA;    &lt;p&gt;&#xA;      When I build web interfaces they genrally need to be universal, as in to work well on multiple screens. We typically use media queries for such implementations but there is a better way noy to handle text sizes, their scales in our design systems. Have a look at this link &lt;a href=&#34;https://utopia.fyi/type/calculator/?c=320,18,1.2,1350,20,1.333,8,2,&amp;amp;s=0.75|0.5|0.25,1.5|2|3|4|6,s-l&amp;amp;g=s,l,xl,12&#34;&gt;Utopia type&lt;/a&gt;&#xA;    &lt;/p&gt;&#xA;&#xA;    &lt;p&gt;&#xA;      What do we have a on that link? A fluid type scale generator. You can set a few parameters like min/max screen size, font sizes and scales for each ends and  what the generator will aloow you to do is set your step sizes.&#xA;    &lt;/p&gt;&#xA;&#xA;    &lt;p&gt;&#xA;      Think of this like setting the size for a &lt;code&gt;p&lt;/code&gt; or &lt;code&gt;span&lt;/code&gt; or &lt;code&gt;h1&lt;/code&gt; with these steps as a global setting in your css and then not set it ever again.&#xA;    &lt;/p&gt;&#xA;&#xA;    &lt;p&gt;&#xA;      Sharing below the type scales output from the above link for this web page.&#xA;    &lt;/p&gt;&#xA;&#xA;    &lt;pre class=&#34;wide-1&#34;&gt;&lt;code class=&#34;language-css&#34;&gt;&#xA;      /* @link https://utopia.fyi/type/calculator?c=320,18,1.2,1350,20,1.333,8,2,&amp;amp;s=0.75|0.5|0.25,1.5|2|3|4|6,s-l&amp;amp;g=s,l,xl,12 */&#xA;&#xA;      :root {&#xA;        --step--2: clamp(0.70rem, calc(0.81rem + -0.12vw), 0.78rem);&#xA;        --step--1: clamp(0.94rem, calc(0.94rem + 0.00vw), 0.94rem);&#xA;        --step-0: clamp(1.13rem, calc(1.09rem + 0.19vw), 1.25rem);&#xA;        --step-1: clamp(1.35rem, calc(1.25rem + 0.49vw), 1.67rem);&#xA;        --step-2: clamp(1.62rem, calc(1.43rem + 0.93vw), 2.22rem);&#xA;        --step-3: clamp(1.94rem, calc(1.63rem + 1.58vw), 2.96rem);&#xA;        --step-4: clamp(2.33rem, calc(1.83rem + 2.51vw), 3.95rem);&#xA;        --step-5: clamp(2.80rem, calc(2.03rem + 3.82vw), 5.26rem);&#xA;        --step-6: clamp(3.36rem, calc(2.22rem + 5.67vw), 7.01rem);&#xA;        --step-7: clamp(4.03rem, calc(2.38rem + 8.26vw), 9.35rem);&#xA;        --step-8: clamp(4.84rem, calc(2.47rem + 11.84vw), 12.46rem);&#xA;      }&#xA;    &lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;    &lt;p&gt;&#xA;      And here’s an example usage, also from the CSS source of this page.&#xA;    &lt;/p&gt;&#xA;&#xA;    &lt;pre class=&#34;wide-1&#34;&gt;&lt;code class=&#34;language-css&#34;&gt;&#xA;      h1 {&#xA;        font-size: var(--step-5);&#xA;      }&#xA;&#xA;      h2 {&#xA;        font-size: var(--step-4);&#xA;      }&#xA;&#xA;      h3 {&#xA;        font-size: var(--step-3);&#xA;      }&#xA;    &lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;    &lt;p&gt;&#xA;      This is all that needs to be done to achieve fluid text sizing. No need for any media quesries for this purpose!&#xA;    &lt;/p&gt;&#xA;&#xA;    &lt;h3&gt;Space, or space scales&lt;/h3&gt;&#xA;    &lt;p&gt;&#xA;      Similarly to the fluid text sizing above we can also achive something similar with fluid space. Have a look at this link &lt;a href=&#34;https://utopia.fyi/space/calculator?c=320,16,1.2,1350,20,1.414,8,1,&amp;amp;s=0.75|0.5|0.25,2|3|5|8|13,s-l|l-2xl|xl-2xl&#34;&gt;Utopia space&lt;/a&gt;&#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      This handy tool allows us to generate spce values for various scenarios and needs, from single step pairs and custom step pair. It also generates the CSS variable definitions we can just paste in our code.&#xA;    &lt;/p&gt;&#xA;&#xA;    &lt;pre class=&#34;wide-1&#34;&gt;&lt;code class=&#34;language-css&#34;&gt;&#xA;      /* @link https://utopia.fyi/space/calculator?c=320,16,1.2,1350,20,1.414,8,1,&amp;amp;s=0.75|0.5|0.25,2|3|5|8|13,s-l|l-2xl|xl-2xl&amp;amp;g=s,l,xl,12 */&#xA;&#xA;      :root {&#xA;        --space-3xs: clamp(0.25rem, calc(0.23rem + 0.10vw), 0.31rem);&#xA;        --space-2xs: clamp(0.50rem, calc(0.46rem + 0.19vw), 0.63rem);&#xA;        --space-xs: clamp(0.75rem, calc(0.69rem + 0.29vw), 0.94rem);&#xA;        --space-s: clamp(1.00rem, calc(0.92rem + 0.39vw), 1.25rem);&#xA;        --space-m: clamp(2.00rem, calc(1.84rem + 0.78vw), 2.50rem);&#xA;        --space-l: clamp(3.00rem, calc(2.77rem + 1.17vw), 3.75rem);&#xA;        --space-xl: clamp(5.00rem, calc(4.61rem + 1.94vw), 6.25rem);&#xA;        --space-2xl: clamp(8.00rem, calc(7.38rem + 3.11vw), 10.00rem);&#xA;        --space-3xl: clamp(13.00rem, calc(11.99rem + 5.05vw), 16.25rem);&#xA;&#xA;        /* One-up pairs */&#xA;        --space-3xs-2xs: clamp(0.25rem, calc(0.13rem + 0.58vw), 0.63rem);&#xA;        --space-2xs-xs: clamp(0.50rem, calc(0.36rem + 0.68vw), 0.94rem);&#xA;        --space-xs-s: clamp(0.75rem, calc(0.59rem + 0.78vw), 1.25rem);&#xA;        --space-s-m: clamp(1.00rem, calc(0.53rem + 2.33vw), 2.50rem);&#xA;        --space-m-l: clamp(2.00rem, calc(1.46rem + 2.72vw), 3.75rem);&#xA;        --space-l-xl: clamp(3.00rem, calc(1.99rem + 5.05vw), 6.25rem);&#xA;        --space-xl-2xl: clamp(5.00rem, calc(3.45rem + 7.77vw), 10.00rem);&#xA;        --space-2xl-3xl: clamp(8.00rem, calc(5.44rem + 12.82vw), 16.25rem);&#xA;&#xA;        /* Custom pairs */&#xA;        --space-s-l: clamp(1.00rem, calc(0.15rem + 4.27vw), 3.75rem);&#xA;        --space-l-2xl: clamp(3.00rem, calc(0.83rem + 10.87vw), 10.00rem);&#xA;        --space-xl-2xl: clamp(5.00rem, calc(3.45rem + 7.77vw), 10.00rem);&#xA;      }&#xA;    &lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;    &lt;p&gt;&#xA;      Here’s a usage example also from the CSS source of this page.&#xA;    &lt;/p&gt;&#xA;&#xA;    &lt;pre class=&#34;wide-1&#34;&gt;&lt;code class=&#34;language-css&#34;&gt;&#xA;      pre {&#xA;        font-family: var(--font-monospace);&#xA;        font-size: var(--step-0);&#xA;        padding-top: var(--space-s-m);&#xA;        overflow-x: scroll;&#xA;        margin: 0;&#xA;        padding: 0;&#xA;      }&#xA;    &lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;    &lt;p&gt;&#xA;      Here’s a usage example also from the CSS source of this page. The size of the top padding for the &lt;code&gt;pre&lt;/code&gt; element will fluidly adapting to the screen size it is viewed on.&#xA;    &lt;/p&gt;&#xA;&#xA;    &lt;p&gt;&#xA;      Neat small feature in the Utopia generators: they also provide the link to prefilled form that have been used before when generating the CSS. Quite nice!&#xA;    &lt;/p&gt;&#xA;&#xA;    &lt;h2&gt;That’s all for today&lt;/h2&gt;&#xA;    &lt;p&gt;&#xA;      We have looked at how to define colors in the OKLch color space, how to use Utopian type and space scales to reduce the complexity of our CSS.&#xA;    &lt;/p&gt;&#xA;&#xA;    &lt;h2&gt;Ah, one more thing&lt;/h2&gt;&#xA;    &lt;p&gt;&#xA;      You may wonder why I chose the end to end in the post title. I did that, because we can use this not only in CSS, but also in Figma. Folks who created the Utopia generators have created a Figmap plugin, find more about that &lt;a href=&#34;https://utopia.fyi/blog/get-started-with-utopia-figma-plugins&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt;. It basically allows for us to use the same size scales in Figma as well.&#xA;    &lt;/p&gt;&#xA;&#xA;    &lt;p&gt;&#xA;      On the flip side, Figma doesn’t suppor OKLch color space. Maybe I can do something about this in the future.&#xA;    &lt;/p&gt;&#xA;&#xA;  </Body>
      <Link>/posts/better-end-to-end-design-systems</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;Implementing a consistent brand across various devices and channels has never been easy. The diversity of connected devices and their screen sizes is also not helping simplify the process.&lt;/p&gt;&lt;p&gt;Let&#39;s take a stab at how we could improve this.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2023-03-13T00:00:00Z</PubDate>
      <ArticlePubDate>2023-03-13T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>18</ID>
      <CreatedAt>2025-06-11T13:48:23.512364Z</CreatedAt>
      <UpdatedAt>2025-06-22T21:16:35.510873Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>Better routing with Go&amp;rsquo;s standard library</Title>
      <Body>&#xA;    &#xA;    &#xA;    &lt;h2&gt;Improving the routing definitions&lt;/h2&gt;&#xA;    &lt;p&gt;&#xA;      In the previous version of the router I had a overly simplified approach, which required to check for the http method in the handler, to be able to handle different http methods. In order to improve that, I have introduced a simple router implementation. This allows for defining the routes, see the &lt;code&gt;init&lt;/code&gt; function in the &lt;code&gt;server.go&lt;/code&gt; file.&#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      And here is the router itself:&#xA;    &lt;/p&gt;&#xA;    &lt;pre class=&#34;wide-1&#34;&gt;&lt;code&gt;&#xA;      package router&#xA;&#xA;      import (&#xA;        &#34;context&#34;&#xA;        &#34;net/http&#34;&#xA;        &#34;regexp&#34;&#xA;        &#34;strings&#34;&#xA;      )&#xA;&#xA;      var Routes = []Route{}&#xA;&#xA;      type Route struct {&#xA;        method  string&#xA;        regex   *regexp.Regexp&#xA;        handler http.HandlerFunc&#xA;      }&#xA;&#xA;      type CtxKey struct{}&#xA;&#xA;      func CreateRoute(method, pattern string, handler http.HandlerFunc) Route {&#xA;        return Route{method, regexp.MustCompile(&#34;^&#34; + pattern + &#34;$&#34;), handler}&#xA;      }&#xA;&#xA;      func Serve(w http.ResponseWriter, r *http.Request) {&#xA;        var allow []string&#xA;        for _, route := range Routes {&#xA;          matches := route.regex.FindStringSubmatch(r.URL.Path)&#xA;          if len(matches) &amp;gt; 0 {&#xA;            if r.Method != route.method {&#xA;              allow = append(allow, route.method)&#xA;              continue&#xA;            }&#xA;            ctx := context.WithValue(r.Context(), CtxKey{}, matches[1:])&#xA;            route.handler(w, r.WithContext(ctx))&#xA;            return&#xA;          }&#xA;        }&#xA;        if len(allow) &amp;gt; 0 {&#xA;          w.Header().Set(&#34;Allow&#34;, strings.Join(allow, &#34;, &#34;))&#xA;          http.Error(w, &#34;405 method not allowed&#34;, http.StatusMethodNotAllowed)&#xA;          return&#xA;        }&#xA;        http.NotFound(w, r)&#xA;      }&#xA;&#xA;    &lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;    &lt;p&gt;&#xA;      The &lt;code&gt;server.go&lt;/code&gt; has not changed that much beyond the router definitions. I introduced a config to handle environment variables more easily and in this particular case to determine if the server is running in development mode.&#xA;    &lt;/p&gt;&#xA;&#xA;    &lt;pre class=&#34;wide-1&#34;&gt;&lt;code&gt;&#xA;      package main&#xA;&#xA;      import (&#xA;        &#34;embed&#34;&#xA;        &#34;html/template&#34;&#xA;        &#34;log&#34;&#xA;        &#34;main/config&#34;&#xA;        &#34;main/handlers&#34;&#xA;        &#34;main/middlewares&#34;&#xA;        &#34;main/router&#34;&#xA;        &#34;net/http&#34;&#xA;      )&#xA;&#xA;      //go:embed templates&#xA;      var embededTemplates embed.FS&#xA;&#xA;      //go:embed public&#xA;      var embededPublic embed.FS&#xA;&#xA;      var reloaded = false&#xA;&#xA;      // public HTML route middleware stack&#xA;      var publicHTMLStack = []middlewares.Middleware{&#xA;        middlewares.Logger,&#xA;      }&#xA;&#xA;      func init() {&#xA;        var staticServer http.Handler&#xA;        var stripPrefix string&#xA;&#xA;        router.Routes = []router.Route{&#xA;          // HTML routes&#xA;          router.CreateRoute(&#34;GET&#34;, &#34;/&#34;, middlewares.CompileMiddleware(handlers.Home, publicHTMLStack)),&#xA;        }&#xA;&#xA;        // only do this in development environment&#xA;        if config.IsDevelopment() {&#xA;          staticServer = http.FileServer(http.Dir(&#34;./public&#34;))&#xA;          stripPrefix = &#34;/public/&#34;&#xA;        } else {&#xA;          staticServer = http.FileServer(http.FS(embededPublic))&#xA;          stripPrefix = &#34;/&#34;&#xA;        }&#xA;        router.Routes = append(router.Routes, router.CreateRoute(&#34;GET&#34;, &#34;/public/.*&#34;, http.StripPrefix(stripPrefix, staticServer).ServeHTTP))&#xA;      }&#xA;&#xA;      func main() {&#xA;        // pre-parse templates, embedded in server binary&#xA;        handlers.Tmpl = template.Must(template.ParseFS(embededTemplates, &#34;templates/layouts/*.html&#34;, &#34;templates/partials/*.html&#34;))&#xA;&#xA;        // mux/router definition&#xA;        mux := http.HandlerFunc(router.Serve)&#xA;&#xA;        // start the server&#xA;        log.Fatal(http.ListenAndServe(&#34;:8000&#34;, mux))&#xA;      }&#xA;      &lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;      &lt;p&gt;&#xA;        I have also updated the middleware as the routing logic changed a bit, see the updated version below.&#xA;      &lt;/p&gt;&#xA;&#xA;      &lt;pre class=&#34;wide-1&#34;&gt;&lt;code&gt;&#xA;        package middlewares&#xA;&#xA;        import (&#xA;          &#34;log&#34;&#xA;          &#34;net/http&#34;&#xA;          &#34;time&#34;&#xA;        )&#xA;&#xA;        // type for chaining&#xA;        type Middleware func(http.HandlerFunc) http.HandlerFunc&#xA;&#xA;        // basically thisd is middleware chaining&#xA;        func CompileMiddleware(h http.HandlerFunc, m []Middleware) http.HandlerFunc {&#xA;          if len(m) &amp;lt; 1 {&#xA;            return h&#xA;          }&#xA;&#xA;          wrapped := h&#xA;&#xA;          // loop in reverse to preserve middleware order&#xA;          for i := len(m) - 1; i &amp;gt;= 0; i-- {&#xA;            wrapped = m[i](wrapped)&#xA;          }&#xA;&#xA;          return wrapped&#xA;        }&#xA;&#xA;        func Logger(next http.HandlerFunc) http.HandlerFunc {&#xA;          return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {&#xA;            start := time.Now()&#xA;            next.ServeHTTP(w, r)&#xA;            log.Printf(&#34;%s %s %v&#34;, r.Method, r.URL.Path, time.Since(start))&#xA;          })&#xA;        }&#xA;      &lt;/code&gt;&lt;/pre&gt;&#xA;      &#xA;      &lt;p&gt;&#xA;        If you would like to take a look at the code, you may find it &lt;a href=&#34;https://github.com/edimoldovan/go-ssr&#34;&gt;here on GitHub&lt;/a&gt;.&#xA;      &lt;/p&gt;&#xA;&#xA;  </Body>
      <Link>/posts/better-routing-with-go-std</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;Previously I shared a very basic example of Go routing. Let&#39;s see how we can improve that a little.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2023-02-17T00:00:00Z</PubDate>
      <ArticlePubDate>2023-02-17T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>19</ID>
      <CreatedAt>2025-06-11T13:48:23.516182Z</CreatedAt>
      <UpdatedAt>2025-06-22T21:16:35.513924Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>Under-engineer</Title>
      <Body>&#xA;    &#xA;    &#xA;&#xA;    &lt;h2&gt;Start with under-engineering&lt;/h2&gt;&#xA;    &lt;p&gt;&#xA;      First, let’s set the requirements for a web solution:&#xA;      &lt;/p&gt;&lt;ol&gt;&#xA;        &lt;li&gt;&#xA;          Be able to ship HTML, CSS and various static assets, like images, to the browsers&#xA;        &lt;/li&gt;&#xA;        &lt;li&gt;&#xA;          Provide a decent web performance—for instance: 90+ on Google Lighthouse&#xA;        &lt;/li&gt;&#xA;        &lt;li&gt;&#xA;          Keep developer experience in mind, fast iterations are important and developer experience is likely the strongest contributor to that&#xA;        &lt;/li&gt;&#xA;      &lt;/ol&gt;&#xA;    &lt;p&gt;&lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      In order to achieve these, I am proposing a simple server side application, that is rendering the HTML on the server, has statical asset serving built in and is fairly simple from structure perspective.&#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      In a more detailed manner, following the three dimensions above:&#xA;      &lt;/p&gt;&lt;ol&gt;&#xA;        &lt;li&gt;&#xA;          Use a Go server app that uses as little dependencies as possible, none in this case.&#xA;        &lt;/li&gt;&#xA;        &lt;li&gt;&#xA;          Use built in Go templating and its fast server-side rendering and the router’s ability to serve static assets to serve them to the browser. An optimisation opportunity here, if needed, is to adjust the static server headers to improve performance and perhaps do that differently later for development and production environments.&#xA;        &lt;/li&gt;&#xA;        &lt;li&gt;&#xA;          Keep the code structure as simple as possible, no bells and whistles needed for the moment. The simpler it is to add features and ship them, the faster we can iterate on it. Go in itself already provides a lot of this but using features like embedding templates and static files into the binary will improve the simplicity of how this application will be shipped to production (application will easily run enywhere, as it will be a single executable file).&#xA;        &lt;/li&gt;&#xA;      &lt;/ol&gt;&#xA;    &lt;p&gt;&lt;/p&gt;&#xA;    &lt;p&gt;Let’s take a look at an exmple. You can find the entire repository on Github &lt;a href=&#34;https://github.com/edimoldovan/go-ssr&#34;&gt;here&lt;/a&gt; and below we’ll take a look at the entry point of the server-side application.&lt;/p&gt;&#xA;    &lt;pre class=&#34;wide-1&#34;&gt;&lt;code&gt;&#xA;      package main&#xA;&#xA;      import (&#xA;        &#34;embed&#34;&#xA;        &#34;html/template&#34;&#xA;        &#34;log&#34;&#xA;        &#34;net/http&#34;&#xA;&#xA;        &#34;main/handlers&#34;&#xA;        &#34;main/middlewares&#34;&#xA;      )&#xA;&#xA;      //go:embed templates&#xA;      var embededTemplates embed.FS&#xA;&#xA;      //go:embed public&#xA;      var embededPublic embed.FS&#xA;&#xA;      func main() {&#xA;        // pre-parse templates, embedded in server binary&#xA;        handlers.Tmpl = template.Must(template.ParseFS(embededTemplates, &#34;templates/layouts/*.html&#34;, &#34;templates/partials/*.html&#34;))&#xA;&#xA;        // mux/router&#xA;        mux := http.NewServeMux()&#xA;&#xA;        // public HTML route middleware stack&#xA;        publicHTMLStack := []middlewares.Middleware{&#xA;          middlewares.Logger,&#xA;        }&#xA;&#xA;        // HTML routes&#xA;        mux.HandleFunc(&#34;/&#34;, middlewares.CompileMiddleware(handlers.Home, publicHTMLStack))&#xA;&#xA;        // static routes, embedded in server binary&#xA;        mux.Handle(&#34;/public/&#34;, handlers.ServeEmbedded(http.FileServer(http.FS(embededPublic))))&#xA;&#xA;        // HTTP server&#xA;        log.Fatal(http.ListenAndServe(&#34;:8000&#34;, mux))&#xA;      }&#xA;    &lt;/code&gt;&lt;/pre&gt;&#xA;    &lt;p&gt;Allow me to describe a little what I have done.&lt;/p&gt;&#xA;    &lt;h2&gt;Dependencies&lt;/h2&gt;&#xA;    &lt;p&gt;&#xA;      I am using no external dependencies, everything is implemented using the Go standard library.&#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      I have moved request handlers, logging middleware into their own files for having a bit simpler server file. Templates and static files are also naturally in their own separate folders and files.&#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      The rest of the import is part of the standard Go release, its standard library.&#xA;    &lt;/p&gt;&#xA;&#xA;    &lt;h2&gt;Embedding static assets into the build binary&lt;/h2&gt;&#xA;    &lt;p&gt;&#xA;      &lt;code&gt;embededTemplates&lt;/code&gt; and &lt;code&gt;embededPublic&lt;/code&gt; are the two variables where I’m holding references to the embedded files, templates and static files respectively. &#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      Why is this needed? I think it’s simpler to ship a single binary to the production environment of your choice and being able to run it from anywhere on a filesystem, as opposed to shipping the entire directory and making sure it works from the folder you shipped it to on your production filesystem.&#xA;    &lt;/p&gt;&#xA;&#xA;    &lt;h2&gt;Main function&lt;/h2&gt;&#xA;    &lt;p&gt;&#xA;      Here I pre-parse the Go templates, so that they are ready to use in request handlers. &#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      The router initialisation comes next.&#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      After that, I initialise my single middleware for the moment and later call it automatically in each request handler so that it logs my requests.&#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      I only have two routes set up for the moment, the root route and static file serving one. &#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      Then I start the server on port 8000. That’s it.&#xA;    &lt;/p&gt;&#xA;&#xA;    &lt;h2&gt;What’s next?&lt;/h2&gt;&#xA;    &lt;p&gt;&#xA;      While this is simple Go server which I basically built for myself, covering several easy to use features, it has some missing points, like how do I ship it and where? That is coming in a next not post.&#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      Till then, have a look at &lt;a href=&#34;https://github.com/edimoldovan/go-ssr&#34;&gt;the repo&lt;/a&gt;, let me know what you think. To run it you could either install &lt;a href=&#34;https://github.com/cosmtrek/air&#34;&gt;air&lt;/a&gt; and then do &lt;code&gt;air .air.toml&lt;/code&gt; or you could just simply do &lt;code&gt;go run server.go&lt;/code&gt;. Of these two, &lt;code&gt;air&lt;/code&gt; will give you the benefit of watching for file changes and restarting the server for you.&#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      Almost forgot: run &lt;code&gt;go build&lt;/code&gt; and then &lt;code&gt;./main&lt;/code&gt; to try out how it runs as a single binary, maybe even move &lt;code&gt;main&lt;/code&gt; around your filesystem to see if it works (it should).&#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      Needless to say, for all of these to work, you need to have Go installed. I personally use &lt;a href=&#34;https://asdf-vm.com&#34;&gt;asdf&lt;/a&gt; for that and other CLI tooling.&#xA;    &lt;/p&gt;&#xA;  </Body>
      <Link>/posts/under-engineer</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;The last several years of web development have been going into a direction of needlessly over-engineering even simplest tasks.&lt;/p&gt;&lt;p&gt;Maybe it&#39;s time to get back to the basics, to use simple solutions for simple tasks. Let&#39;s touch on how I think we should be approaching initial web product development.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2023-02-05T00:00:00Z</PubDate>
      <ArticlePubDate>2023-02-05T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>20</ID>
      <CreatedAt>2025-06-11T13:48:23.519947Z</CreatedAt>
      <UpdatedAt>2025-06-22T21:16:35.516707Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>The CSS has() selector</Title>
      <Body>&#xA;    &#xA;    &#xA;    &lt;p&gt;&#xA;      Stephanie goes into great detail about how to create advanced selectors but also reviews the CSS &lt;code&gt;combinators&lt;/code&gt; and &lt;code&gt;pseudoclasses&lt;/code&gt;.&#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      A particularly nice example Stephanie brings is the &lt;code&gt;Stateful Multi-Range Selection Groups&lt;/code&gt; where selected checkboxes are being visually grouped.&#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      Go have a look at &lt;a href=&#34;https://www.smashingmagazine.com/2023/01/level-up-css-skills-has-selector/&#34;&gt;her post&lt;/a&gt;, lots to learn from it!&#xA;    &lt;/p&gt;&#xA;  </Body>
      <Link>/posts/css-has-selector</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;In my first not post I mentioned and example of something I find quite interesting in the recent CSS features,that is the &lt;code&gt;has()&lt;/code&gt; selector. And while I was preparing to write something about it, which I mightstill do, here&#39;s a great article on &lt;a href=&#34;https://www.smashingmagazine.com/2023/01/level-up-css-skills-has-selector/&#34;&gt;Smashing Magazine&lt;/a&gt; written by &lt;a href=&#34;https://thinkdobecreate.com&#34;&gt;Stephanie Eckles&lt;/a&gt; about this exact topic.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2023-01-24T00:00:00Z</PubDate>
      <ArticlePubDate>2023-01-24T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
    <item>
      <ID>21</ID>
      <CreatedAt>2025-06-11T13:48:23.523241Z</CreatedAt>
      <UpdatedAt>2025-06-22T21:16:35.518797Z</UpdatedAt>
      <DeletedAt>
        <Time>0001-01-01T00:00:00Z</Time>
        <Valid>false</Valid>
      </DeletedAt>
      <Title>I have decided to not blog</Title>
      <Body>&#xA;    &#xA;    &#xA;    &lt;h2&gt;What is a not blog?&lt;/h2&gt;&#xA;    &lt;p&gt;&#xA;      I get an urge to try things out when I read about them. For example: I like a lot the &lt;a href=&#34;/not-posts/css-has-selector&#34;&gt;has()&lt;/a&gt; CSS selector features. So I naturally want to try them out. But a traditional blog doesn’t offer the opportunity to actually embed code easily into a post, like the features I’m trying out.&#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      I could embed some tool into the post with code examples but I am not a big fan of such tools.&#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      Also, I would like to share the experience of building something from scratch, this not blog, so that whoever is curious, can follow how I build it.&#xA;    &lt;/p&gt;&#xA;    &lt;p&gt;&#xA;      For instance, I would like to experiment and showcase how the &lt;code&gt;has()&lt;/code&gt; selector works. For this I created the below &lt;code&gt;figure&lt;/code&gt;:&#xA;    &lt;/p&gt;&#xA;    &lt;pre class=&#34;wide-1&#34;&gt;&lt;code class=&#34;language-html&#34;&gt;&#xA;    &amp;lt;figure&amp;gt;&#xA;      &amp;lt;img src=&#34;/public/images/nothing_at_all_aiseo_art.jpg&#34; /&amp;gt;&#xA;    &amp;lt;/figure&amp;gt;&#xA;    &lt;/code&gt;&lt;/pre&gt;&#xA;    &lt;p&gt;which renders like this:&lt;/p&gt;&#xA;    &lt;figure&gt;&#xA;      &lt;img src=&#34;/public/images/nothing_at_all_aiseo_art.jpg&#34; alt=&#34;AI generated image, without figcaption&#34;&gt;&#xA;    &lt;/figure&gt;&#xA;    &lt;p&gt;&#xA;      the above &lt;code&gt;figure&lt;/code&gt; with the colorful image and the one below look different only because the bottom one has a &lt;code&gt;figcaption&lt;/code&gt;.&#xA;    &lt;/p&gt;&#xA;    &lt;pre class=&#34;wide-1&#34;&gt;&lt;code class=&#34;language-html&#34;&gt;&#xA;    &amp;lt;figure&amp;gt;&#xA;      &amp;lt;img src=&#34;/public/images/nothing_at_all_aiseo_art.jpg&#34; /&amp;gt;&#xA;      &amp;lt;figcaption&amp;gt;image generated with &amp;lt;a href=&#34;https://art.aiseo.ai&#34; target=&#34;_blank&#34;&amp;gt;https://art.aiseo.ai&amp;lt;/a&amp;gt;&amp;lt;/figcaption&amp;gt;&#xA;    &amp;lt;/figure&amp;gt;&#xA;    &lt;/code&gt;&lt;/pre&gt;&#xA;    &lt;figure class=&#34;figure&#34;&gt;&#xA;      &lt;img src=&#34;/public/images/nothing_at_all_aiseo_art.jpg&#34; alt=&#34;AI generated image, with figcaption&#34;&gt;&#xA;      &lt;figcaption&gt;image generated with &lt;a href=&#34;https://art.aiseo.ai&#34; target=&#34;_blank&#34;&gt;https://art.aiseo.ai&lt;/a&gt;&lt;/figcaption&gt;&#xA;    &lt;/figure&gt;&#xA;    &lt;p&gt;Here’s the &lt;span class=&#34;highlight&#34;&gt;selector&lt;/span&gt; that makes this possible (nb. stable Firefox seems to not support &lt;code&gt;has()&lt;/code&gt; by default yet):&lt;/p&gt;&#xA;    &lt;pre class=&#34;wide-1&#34;&gt;&lt;code class=&#34;language-css&#34;&gt;&#xA;    .post &lt;span class=&#34;highlight&#34;&gt;figure:has(figcaption)&lt;/span&gt; {&#xA;        background: var(--color-neutral-7);&#xA;        padding: 2rem;&#xA;        max-width: 50ch;&#xA;        display: flex;&#xA;        flex-direction: column;&#xA;        align-items: center;&#xA;        gap: 1rem;&#xA;    }&#xA;    &lt;/code&gt;&lt;/pre&gt;&#xA;    &lt;p&gt;The browser will add the additional styling only to the &lt;code&gt;figure&lt;/code&gt;s that have a &lt;code&gt;figcaption&lt;/code&gt; style.&lt;/p&gt;&#xA;    &#xA;    &lt;p&gt;&#xA;      So if you are interested in &lt;code&gt;Go&lt;/code&gt;, &lt;code&gt;SwiftUI&lt;/code&gt;, good &lt;code&gt;CSS&lt;/code&gt; practices and on top of everything a very &lt;code&gt;iterative&lt;/code&gt;, &lt;code&gt;lean&lt;/code&gt; delivey approach follow the story here.&#xA;    &lt;/p&gt;&#xA;  </Body>
      <Link>/posts/not-blog</Link>
      <ItemType>rss</ItemType>
      <Description>&lt;p&gt;I have recently been reading a lot given that I had a lot of time on my hands. Many of my readings have been about my work, what I&#39;m passionate about in my work — how to build amazing experiences on the web and native platforms.&lt;/p&gt;&lt;p&gt;So I have quickly put together this not blog to share not posts here. Read along if you&#39;re curious what this crazy idea is about.&lt;/p&gt;</Description>
      <Domain>eduardmoldovan.com</Domain>
      <PubDate>2022-12-28T00:00:00Z</PubDate>
      <ArticlePubDate>2022-12-28T00:00:00Z</ArticlePubDate>
      <Active>true</Active>
    </item>
  </channel>
</RSS>