daverupert.com The personal blog of Dave Rupert, web developer and podcaster from Austin, TX. https://daverupert.com Every token is a feature <p>I’m in the middle of a design tokens project and I thought I’d share something I’m learning that is probably obvious to everyone else; every design token is a feature.</p> <p>A token is a magical contract between design and engineering, if we agree to use the same name to abstractly refer to the same value, it will produce a desired outcome. That bridge alone is probably worth the investment, but tokens solve even more organizational problems. The mobile app and the website can look the same by sharing a single JSON file. But wait, there’s more! If the blue a different team chose is not blue enough for you, you can make your own blue and apply it at the global scope or the individual element scope. Tokens as an organizational feature are a powerful concept but there’s tons of nuance packed behind it.</p> <p>Like features, too many tokens can bloat your system. I recently learned –because I’m lucky to work with people who work on browsers– there’s a not-so-theoretical limit where the browser starts taking a performance hit based purely on the number of CSS variables. There’s no hard upper limit on the number of variables (we drew a line at ~500) because the limit ultimately depends on the size and the depth of your DOM. Style recalcs and tree walking are expensive problems for a browser. Alias tokens like <code>--foo: var(--bar)</code> compound the problem and the more static you can be, like <code>--foo: #bada55</code>, the better. Infinite customizability and peak performance are often at odds.</p> <p>Like features, too many tokens can create organizational problems! This is the opposite of what I said above, how can that be? It’s possible to generate enough tokens that they become their own <a href="https://robinrendle.com/essays/systems-mistakes-and-the-sea/">hyperobject</a>, impossible to comprehend from the outside, so well-meaning people eject from the system. Detached instances. One-offs. Snowflakes.</p> <p>Like features, tokens can create little piles of <a href="https://daverupert.com/2020/11/technical-debt-as-a-lack-of-understanding/">technical debt</a>. “Is anyone still using <code>--color-beefcake-primary-2</code>?” you shout into the void of the team chat. No one responds because no one knows. The person who does know left the company five months ago. Alas, we’ll bolt on more until we find time to fix it. Always adding. Never subtracting.</p> <p>Like features, some tokens are going to have a massive payoff if implemented and some tokens the user benefit is less clear. <a href="https://en.wikipedia.org/wiki/Conway%27s_law">You’re passing organizational complexity on to the user</a>. Like features, you can build over-complicated machinery around a simple concept like sharing values. Like features, people will build every part without considering whether they actually need each facet.</p> <p>Generally speaking, if someone wants to implement hundreds or thousands of little features in an application, that’s probably a red flag. <a href="https://daverupert.com/2018/09/if-statements-should-cost-10000/">If-statements are expensive over their lifetime</a>. But from my experience, a good system of tokens inside a cascade of meaningful componentry can make a product resonate with consistency across many surfaces, while providing just enough customizability to differentiate when necessary.</p> Thu, 19 Dec 2024 15:12:00 +0000 https://daverupert.com/2024/12/every-token-is-a-feature/ https://daverupert.com/2024/12/every-token-is-a-feature/ Intermittent fasting <aside> <p>⚠️ Content warning: Weight loss, feel free to skip if that is not a good topic for you.</p> </aside> <p>A doctor told me to look into intermittent fasting. Not for weight loss, but for ADHD. There’s some <a href="https://www.addrc.org/the-role-of-brain-insulin-in-adhd-emerging-evidence/">new data that suggests a link between ADHD and insulin in the brain</a>. Based on that science, intermittent fasting or a ketogenic diet –which can help improve insulin resistance– might help my brain. I’m a week into it and am seeing some weight loss, but it’s hard to tell with the ADHD without measuring my brainflorps per second. I might be more focused, but hunger and “hangry” bring their own distractions.</p> <p>I’m skeptical, to say the least. Intermittent fasting makes frequent appearances in my YouTube shorts with balding Joe Rogan clones dressed in all black selling workout supplements. It has a whiff of being a cure-all. To counter that skepticism, I read a book called <a href="https://amzn.to/4fRPUMt"><em>Life in the Fasting Lane</em></a> co-authored by Dr Jason Fung, who was specifically recommended to me. It’s a mix of doctorly advice and testimonials from advocates who have had success with fasting. As scientific as the book tries to be, it undoes its own credibility pitching intermittent fasting with all the hallmarks of a fad elimination diet:</p> <ul> <li>Lose weight in 30 days</li> <li>Reduce cravings</li> <li>Live longer</li> <li>Reverse diseases</li> <li>Helps you focus at work</li> <li>Improves your sex life</li> <li>Big pharma doesn’t want you to know about this one weird trick!</li> <li>Used by ancient civilizations. Ugh. The appeal to history (ancient, therefore good!) is a major pet peeve of mine.</li> <li>And my least favorite: It doesn’t cure cancer, but it cures obesity, which causes all different kinds of cancer… so we’re not gonna say it cures cancer because that’s a douchebag thing to say, but it <em>doesn’t not</em> cure cancer if you catch our drift (wink).</li> </ul> <p>I do appreciate that the book calls out “Calories-In/Calories-Out” as a myth that works 1% of the time. But it’s hard to shake the feeling that eliminating meals or days worth of food isn’t a macro-version of calories-in/calories-out, where you measure calories in weeks instead of per meal. I suppose the key difference is the duration between meals allows my body to enter ketosis (read: a starving state) which will consume my excess fat stores instead of my morning breakfast tacos adding to those fat stores.</p> <p>To be honest, I’m a good candidate for this fad diet. I can sustain myself on a couple meals a day. I could skip lunch most days. Skipping breakfast though is hard. Not putting creamer in my morning coffee is hard. Not having a little after dinner snack with the kids is hard. Not eating is not my favorite, but I’m going to trust the process for a bit and hopefully it’ll help a weary brain like mine.</p> Wed, 11 Dec 2024 04:10:00 +0000 https://daverupert.com/2024/12/intermittent-fasting/ https://daverupert.com/2024/12/intermittent-fasting/ I got the ADHD, too <p>This month I got my official diagnosis for Adult ADHD. It’s fun to share experiences with <a href="https://bradfrost.com/blog/post/my-adhd-diagnosis-process/">friends</a>. While ADHD presents some new waters to navigate, it isn’t exactly news to me. Thanks to Dr. TikTok, I’ve suspected this outcome for a few years now. It’s nice to have a proper diagnosis though. If I’m struggling to focus or feeling overwhelmed, I know the probable root cause is how my brain processes dopamine and norepinephrine impacting my executive function.</p> <p>There are different flavors of ADHD, so I can only describe my experience:</p> <ul> <li>I crave “optimal stimulation” – 1 task = too little. 3-5 tasks = perfect, ideal. 6+ tasks = uh-oh, all the spinning plates come crashing down.</li> <li>I experience periods of hyperfocus – I often will lock in on an interesting problem and work for hours and forget to eat.</li> <li>Difficulty with tasks when overwhelmed – When overwhelmed (which is always, I have some generalized anxiety too), I’m unable to summon focus for even the smallest of tasks.</li> <li>Sensitivity to messy environments – Related to optimal stimulation, cluttered and messy environments (a common ADHD issue) creates a feeling of overwhelm for me.</li> <li>Sensory-seeking behaviors and fidgeting (classic restless leg syndrome)</li> <li>I don’t have the hyperactive part of ADHD.</li> <li>I’m pretty attentive and a good listener… until I’m not.</li> </ul> <p>I’ve developed a lot of coping and masking strategies over the years that have allowed me to maintain a decent level of productivity. In my 20s I used to manage this by brute force and caffeine. But now that I’m in my 40s with a lot more responsibilities and spinning plates, I feel the reins slipping a bit. To help with this, I’m trying out a non-stimulant sNRI medication that tries to repair that norepinephrine processing. It takes a week or so to fully activate so it’s not an instant fix, and to be honest I don’t quite know what to expect. I’m excited to see if it makes a difference but even if it doesn’t I’m happy to be on a journey.</p> <p>Anyways, cheers to unique brains.</p> Fri, 06 Dec 2024 15:29:00 +0000 https://daverupert.com/2024/12/adhd/ https://daverupert.com/2024/12/adhd/ Goodbye, Moogs <img src="https://cdn.daverupert.com/posts/2024/moogs.jpg" alt="a tuxedo cat with green eyes looking away from the camera" height="900" width="1200"/> <p>The people who found you in the alley called you Cowboy. We called you Moogs, Moogers, Moogerton, Mr Moogs, Meesta, Two Meestas, Beef, Roast Beef, Roast Beefy Weefy, Kitty, Kitty cat, Long cat, Kitty kitty, Pretty kitty, and Meow meow. Those were all your names.</p> <p>Today we had to say goodbye to our cat Moogs (pronounced “Moo” like the cow says + “gs”). He was nearly 19 years old, which is about all you can ask for from a great cat. A senior cat with a thyroid problem – so his passing is not an incredible surprise – but he took a sudden downturn over the weekend. He died in his sleep.</p> <p>My wife adopted him before we were even dating in 2006. I never had a cat, was more of a dog person, and I made it my mission to befriend the cat to win her over. I succeeded in my goal and he let me hold him like a baby. Little did I know he would spend the next 18 years of my life with him sitting on my body for warmth and waking me up at six in the morning.</p> <p>When we lived in LA he would perch majestically on the sills of the open windows basking in the warm sun’s rays because that’s how LA’s perfect weather works. He’d hop in-and-out of the house, hunting, cruising, and getting into tussles with the other alley cats. We paid a lot in vet bills but he had a good life jumping along the craftsman rooftops.</p> <p>He didn’t enjoy moving to Austin, he howled the whole 1400 mile journey and when we got to Austin, he hid himself in the exposed soffit of our mid-remodel kitchen. After two weeks he came out and got used to the new home and got comfortable being an indoor-outdoor cat again. He’d spend days in our neighbor Cleo’s wisteria bushes hunting small birds. He was there when we adopted <a href="https://daverupert.com/2023/04/goodbye-rudy/">our dog Rudy</a> and learned to hold his own against dogs. And he was there when we brought our babies home from the hospital and he learned to tolerate toddlers.</p> <p>When we moved a second time to North Austin, he didn’t like that move either. He quit going outside as much and I think after that his quality of life started to decline. Three years ago, I noticed he was losing weight, felt like a skeleton with fur, and was extra ornery about food. The vet diagnosed him with hyperthyroidism and he needed to be on medication.</p> <p>Moogs was sweet and friendly – well, as friendly as cats can be. When guests came over he would saunter into the room and find the person most allergic to cats and nuzzle them. He had an uncanny talent for that. He was social, but not. He would give an affectionate little headbutt whenever he wanted attention. He’d knead his claws into your thigh when you tried to watch television. And he’d prowl the house at night and wake you up with a butthole to the face. Cats, man. Cats.</p> <p>Moogs was an incredible cat. My first and probably only cat, to be honest. I won’t miss his howls for breakfast each morning, but I will miss the soft brushes against my legs to say hello. He was a part of our family from the beginning, it will be different without him.</p> Tue, 26 Nov 2024 03:08:00 +0000 https://daverupert.com/2024/11/goodbye-moogs/ https://daverupert.com/2024/11/goodbye-moogs/ Hammers <p>I bet if you were someone who could make a hammer that would have been a good stable job for years, centuries even. Almost everyone needs a hammer at some point in their life.</p> <p>“Hey, where’d you get that hammer?”<br /> “Oh, you gotta talk to Bartholomew.”</p> <p>Then some guy, Greg, would see how busy the hammersmith is making hammers one at-a-time and say, “I’m going to make hammers one hundred at a time!” He’d pay Bartholomew not to make him one hammer, but to make a mold that could make one hundred hammers at a time. Greg has rich parents, he can afford this sort of risky business venture. One hundred hammers for the price of ten, that’s profit.</p> <p>After the hammer mold, Bartholomew would still get paid. No one actually likes pouring molten iron and hammering, but Bartholomew doesn’t mind. He’s making less money per hammer, but he’s also producing more hammers with a lot less effort, so it nets out okay. The job is less interesting – making hammers and nothing else – but he didn’t like being a salesman and dealing with wayward customer requests anyways. There’s lots of money in churning out hammers this way, it’s more efficient and people like Greg love selling them and making money. Bartholomew buys himself a new ox cart.</p> <p>Then some other guy, Jeff, seeing all those hammers and all that money, would say “I’m going to make a machine that makes a million hammers a day.” Jeff knows a regional lord who is friends with the king and has big treasure chests. He’d hire Bartholomew and his hammersmith friends to build a giant complex machine with whistles and gauges and a furnace that makes ten hammers a second. A million hammers a day for the price of a thousand hammers, <em>now that’s profit!</em></p> <p>The profit charts are going up. Hammers are about as cheap as possible to mass produce… except now Bartholomew and his hammersmith friends are starting to catch the ire of bookkeepers. They’re starting to look expensive compared to the penny hammers that sell for $10. They fire Bartholomew. He’s given three months of pay, which is nice, but in exchange he has to sign a contract saying he’ll never make another hammer machine again in his life. Hopefully Bartholomew squirreled away enough money to retire with dignity, otherwise what’s an old hammersmith do when there’s no more hammers to make?</p> Tue, 22 Oct 2024 14:15:00 +0000 https://daverupert.com/2024/10/hammers/ https://daverupert.com/2024/10/hammers/ Where web components shine <img src="https://cdn.daverupert.com/posts/2024/cavern.jpg" alt="vintage illustration of three explorers in a cave holding torches to light their way" width="1000" height="734"/> <p>In this job <a href="https://daverupert.com/2024/04/thoughts-on-cosmotechnics/">we need to think a lot about the tools we choose and why</a>, so I cataloged all the places where web components (for me) feel like “the right tool for the job”. Your list may be different and I’d love to read it. And because I don’t want this to be 100% propaganda, I’ll also cover some of the not-so-great parts of web components as well.</p> <h2>The good parts</h2> <p>Here’s an incomplete list of situations where I think web components are a good choice.</p> <ul> <li>For leaf nodes - <a href="https://nolanlawson.com/2023/08/23/use-web-components-for-what-theyre-good-at/">Web components are great at leaf nodes</a>.</li> <li>For presentational components that wrap other components - The <code>&lt;slot&gt;</code> element is fantastic for this, but you could write a basic CSS class instead. The first rule of web components is: <em>Not everything needs to be a web component.</em></li> <li>For building a design system - <a href="https://nordhealth.design/">They do this too.</a></li> <li>For progressively enhancing regular ass HTML - <a href="https://meyerweb.com/eric/thoughts/2023/11/01/blinded-by-the-light-dom/">Super good at this.</a></li> <li>When you want to View Source - Most folks don’t care about this anymore but debugging <code>my-button</code> is a lot easier than <code>div.spf50</code> and you don’t have to rely on sourcemaps.</li> <li>When you want to make a site without build tools - <a href="https://open-wc.org/guides/developing-components/going-buildless/">Build tooling is typically not the starting point</a> for most web component projects.</li> <li>When building a one-off project - In the same vein as “buildless” components, eliminating dependencies decreases maintenance burdens over the long haul when you have to come back to the project weeks, months, or years later.</li> <li>For prototyping - More buildless talk, but if you need to get up and going fast, web components zoom.</li> <li>When you need to keep a low-memory profile - I think you’ll find <a href="https://krausest.github.io/js-framework-benchmark/2024/table_chrome_129.0.6668.58.html">on average your performance floor is much lower with web components</a>, which makes them blazingly fast.</li> <li>When you need style encapsulation - imho, web components are a little <em>too</em> good at this but good to know <a href="https://nolanlawson.com/2021/08/15/does-shadow-dom-improve-style-performance/">Shadow DOM style application is also blazingly fast</a>.</li> <li>When you want small, atomic template updates - Some (not all) web component libraries use an html tagged template literal which gives you JSX-like template authoring without a transformer or compiler. <a href="https://youtu.be/Io6JjgckHbg?si=gQ1REfZSsMIPnFxw&amp;t=383">Tagged template literals are also blazingly fast with atomic updates</a> over full component re-renders.</li> <li>When your components need to exist across different tech stacks - If your company lets departments pick their own tech stack or your company acquires other companies and you need a bit of UI consistency between projects, web components are a great choice.</li> <li>When you’re demoing an accessibility pattern, animation, or CSS-Trick - Why not package it in a web component so people can pick it up and drop it into their project? These puppies are hyper-distributable.</li> <li>When you make a third-party embed widget - If you need <a href="https://cdn.daverupert.com/posts/2024/spicy-iframes.png">a spicy <code>&lt;iframe&gt;</code></a>, web components do that and the style encapsulation of the Shadow DOM would probably make your life easier with less code.</li> <li>When you want to build big applications - You can build <a href="https://web.dev/articles/ps-on-the-web">Photoshop with web components</a>. Companies build apps with web components every day. And they use Shadow DOM.</li> <li>When you have designers who can code - Most designers don’t have an appetite or ability to spin up a whole dev environment, but you might be able to convince some to write HTML in a CodePen. If your designer is cool with spinning up a local dev environment, pay them more.</li> </ul> <h2>The not-so great parts</h2> <p>No technology is perfect so here are some of the rough edges of web components, where people commonly have trouble, or where I’ve found them to not be the best abstraction.</p> <ul> <li>Shadow DOM - I think everyone’s first encounter with the Shadow DOM ends in catastrophe. It can be confusing and even smart people I know have beef with it. I can say that the more you work with it the more intuitive it becomes, but Shadow DOM does have some gotcha moments that can be frustrating.</li> <li>SSR - <a href="https://www.spicyweb.dev/web-components-ssr-node/">You can SSR web components</a> using Declarative Shadow DOM, but there’s not a lot of literature out there which leads me to believe it’s either kludgy, too library-specific, or both. If this is a non-starter for you, check out <a href="https://enhance.dev/">Enhance</a> which does this out of the box.</li> <li>Pages - You can use a web component as your page-level abstraction and leverage some kind of <a href="https://github.com/vaadin/router">web component-based router</a>… but you’re probably better off keeping it simple and using server generated HTML as your page-level abstraction.</li> <li>Accessibility - There’s been some long standing issues with Cross-Root ARIA (e.g. associating a label in the document with an input inside a shadow root). Workarounds exist but the good news is that <a href="https://github.com/WICG/webcomponents/blob/gh-pages/proposals/reference-target-explainer.md"><code>referencetarget</code></a> is rolling out in Chromium and solves this problem. Hopefully other browsers pick it up soon.</li> <li>Making a compiler for your JS framework - This is another post entirely, but I can say that over the last couple weeks I’ve had about three years worth of Community Group discussions. Hopefully some ombudsman-ship and progress can happen here.</li> </ul> <p>As always, your mileage may vary. Ultimately the technologies you choose probably come down to <a href="https://bradfrost.com/blog/link/why-were-breaking-up-with-css-in-js/">what’s cool at the time</a>, <a href="https://alexsexton.com/blog/2014/11/the-monty-hall-rewrite">what people <em>think</em> solves their problems</a>, and what your team and decision makers feel comfortable with at the time. That said, in the year 2024 of our <small>LORD</small>, despite the apparent limitations I do think these are scenarios where web components are a great fit.</p> Mon, 21 Oct 2024 14:28:00 +0000 https://daverupert.com/2024/10/super-web-components-sunshine/ https://daverupert.com/2024/10/super-web-components-sunshine/ Vibe Check №35 <p>School is back in session, sports are in full swing, we’re tossed and turned by the weekly routine. This past month has been a season of fixing and repair and I’m thankful everything went well and we’re (hopefully) through the hard parts.</p> <h2>Fixing electrical problems</h2> <p>Ramping up to Spooky Month, the lights in our house were acting up. We’ve always had the occasional power problem; lights dimming, oven clocks resetting, but they were random and isolated. But around the beginning of September our lights would flicker for a solid minute every time the A/C kicked on. I was getting concerned about a potential fire – and no matter what anyone says, I was not concerned about a ghost, ghoul, specter, gremlin, dracula or otherwise – so I scheduled a bunch of maintenance calls:</p> <ul> <li>An electrician - He didn’t see any <del>ghosts</del> red flags, but a bar in our main breaker panel was a little loose and possibly shaking when the A/C kicked on, causing the flicker. He also swapped out a non-LED dimmer for an LED dimmer and that seems to have fixed the extra-spooky dining room.</li> <li>A dryer vent cleaner - Thanks to a <code>D80</code> code on our LG dryer, I got suspicious that a clogged dryer vent was causing extra draw on electrical system. An older gentleman who liked to talk helped us clean out the 7ft pipe that shoots hot air and lint out of our roof. Works great now <del>and no gremlins</del>.</li> <li>A refrigerator repair man - The stainless steel column in the middle of our side-by-side fridge was hot to the touch. Heat means energy. Heat is also not what you want in a fridge. Our fridge was over-working to keep itself cool but also freezing our groceries in the non-freezer side. A repair man pulled the fridge out and vacuumed the condenser unit <del>like Luigi’s mansion</del>. Easy enough and cool to the touch again.</li> <li>A new garage door opener - The electrical surges in our house fried the motherboard in our garage door opener, so we replaced the unit and now it has Wi-Fi, an app, and other features I don’t need. It’s so much quieter now and does not sounds like a T-Rex <del>or a howling wolf man</del> anymore.</li> </ul> <p>The flickering lights seem to have resolved. All ghosts busted.</p> <h2>Fixing a knee</h2> <p>It wouldn’t be a year at the Ruperts house without maxing out our deductible. This time my wife’s tennis habit got the best of her and she needed to undergo laparoscopic surgery to repair a torn meniscus. Surgery went fine, she was walking the same day and (even in bandages) was walking better than before. Surgeries are no fun, but necessary at times.</p> <h2>Fixing the dogs</h2> <p>The week after my wife’s surgery our two new adopted pups had their scheduled appointment from the adoption center to get spayed. A non-event except that two young dogs in two cones is an absolute ruckus. Days and days of bonking into doors and knees (some of which had surgery the week before).</p> <p>After a week the cones were off and they’re back to themselves; eating rocks, wrassling, and digging holes in my yard and whatnot.</p> <h2>Fixes on the horizon</h2> <p>Thousands of dollars and a handful of stressful weeks later we’re on a path to recovery. Shaking off the stress of the last six weeks is yet another thing to fix. And the fixes don’t stop. The near future is going to be figuring out our next major family expense. We need to update both our cars, the kids want a camper again, and almost all the rooms in our house need updating. I also made an enormous mess decanting all our hoarding piles while trying to clean the garage and need new shelving and storage. Oops, will fix.</p> <h2>Stats</h2> <h3>🧠 <strong>Learning</strong></h3> <ul> <li>Went on a deep dive about Kowloon Walled City, the densest city in the world renown for its lawlessness, crime, and poverty. Kowloon has a deep history under Chinese and British occupation in Hong Kong. A Chinese settlement within Hong Kong territory, Kowloon self-regulated. While I knew about pre-modern China’s opiod crisis, I didn’t understand England’s role and learned how they were the drug dealers in this situation, trading opium from (occupied) India so they could get cheap tea and dinnerware. Fast-forward a few wars, opium dens and organized crime play a prominent role in the story of Kowloon but somehow the urban maze of dystopian unregulated buildings has a charming sense of community to it. <ul> <li><a href="https://www.youtube.com/watch?v=4YuNvIfM-YA">The Densest City on Earth</a></li> <li><a href="https://www.youtube.com/watch?v=hoNclh1K_zY">The Densest City In The World Had a Strange Secret…</a></li> </ul> </li> </ul> <h3>📖 <strong>Reading</strong></h3> <p><strong>Finished</strong></p> <ul> <li><a href="https://amzn.to/3yfwkJr">The Adventure Zone Vol. 6</a> by McElroy, Pietsch, McElroy - My annual reading of tres horny boys. Its been long enough I forget moments from the original podcast so it’s fun to relive them in graphic novel form.</li> <li><a href="https://amzn.to/3MH78PP">Awe</a> by Dacher Keltner - I love the notion of “micromoments of awe” and consider myself an awe-seeker, but I don’t think I’m new age enough for this book.</li> <li><a href="https://amzn.to/3Zdx8JR">The Anxious Generation</a> by Jonathan Haidt - Phones and access to social media are harming our children. As a parent, I think there are valid concerns about device usage but I don’t think you can take this book as gospel. There’s a <a href="https://podcasts.apple.com/us/podcast/the-anxious-generation/id1651876897?i=1000664706439">If Books Could Kill episode on Anxious Generation</a> that makes for a good pairing.</li> <li><a href="https://amzn.to/3N6gyEJ">Coda: False Dawns</a> by Spurrier &amp; Bergara - A continuation of the super good Coda post-apocalyptic fantasy universe. This time a preacher comes to town.</li> <li><a href="https://amzn.to/3TXR7sq">Where Good Ideas Come From</a> by Stephen Johnson - A recommendation from a coworker and probably my favorite book of the past two months. Validates a lot of how my own brain works by making connections in adjacent ideas and technologies.</li> </ul> <p><strong>Started</strong></p> <ul> <li><a href="https://amzn.to/3XHSrT7">A Wizard of Earthsea</a> by Ursula K. Le Guin</li> <li>Misc. comics</li> </ul> <h3>📝 <strong>Blogging</strong></h3> <ul> <li><a href="https://daverupert.com/2024/09/dev-tools-performance-monitor-panel/">The Dev Tools Performance Monitor Panel</a> - a post about a helpful but somewhat hidden debugging tool in Dev Tools</li> <li><a href="https://daverupert.com/2024/09/fuck-the-book-a-week-club/">Finding questions and answers about why I like books</a> - a post about being a book-a-week person</li> <li><a href="https://daverupert.com/2024/09/good-forms/">Good forms</a> - a post about forms</li> <li><a href="https://daverupert.com/2024/09/hibiclens/">Hibiclens</a> - a post about combatting armpit odor</li> </ul> <h3>📺 Media</h3> <p><strong>Movies</strong></p> <ul> <li>Beetlejuice, Beetlejuice (2024) - A more surreal sequel. Perhaps too many plot lines crammed into one 90 minute film but a fun addition to the series with most of the original cast plus some welcome additions.</li> </ul> <p><strong>Podcasts</strong></p> <ul> <li><a href="https://sceneonradio.org/capitalism/">Scene on Radio S7: Capitalism</a> - An in-depth examination on the origins of capitalism and its impact on democracy. A MUST LISTEN!</li> <li><a href="https://www.dw.com/en/living-planet/program-19028671">Living Planet</a> - An environmentalist podcast that seeks to answer questions like: What’s better: coffee or tea? <a href="https://www.dw.com/en/whats-better-dairy-vs-plant-based-milk/audio-70025717">What’s better: dairy vs plant-based milk?</a> I think about these dichotomies a lot so this feels like a podcast engineered in a lab for me.</li> <li>The Adventure Zone Versus Dracula - Finished this actual play arc. Not my favorite but still fun.</li> <li>The Adventure Zone: Abnimals - New season, I’m a bit lost.</li> </ul> <h3>🎙 <strong>Recording</strong></h3> <p>Some great guests talking about everything from game dev, to AI, to WordPress, to bespoke apps for adding multimedia experiences to live music.</p> <p><strong>ShopTalk</strong></p> <ul> <li><a href="https://shoptalkshow.com/632/">Adam Coster on Game Development and Crashlands 2</a></li> <li><a href="https://shoptalkshow.com/633/">Thomas Steiner on AI in Chrome and the Web</a></li> <li><a href="https://shoptalkshow.com/634/">Fabian Kägy on WordPress, Blocks, and Enterprise Dev</a></li> <li><a href="https://shoptalkshow.com/635/">Jeff Robbins and Visibox as an Instrument for Video</a></li> </ul> <h3>🤖 Gunpla</h3> <ul> <li>Started on the <a href="https://newtype.us/p/8CCmPfZ3J8SsG8zD1R5x/h/mg-mbf-p02kai-gundam-astray-red-frame">MG Gundam Astray Red Frame</a></li> </ul> <h3>⌨️ <strong>Open source</strong></h3> <ul> <li>Been active in the Web Components Community Group for <code>{ reasons }</code></li> </ul> <h3>👾 <strong>Video games</strong></h3> <ul> <li>Brawl Stars - Got roped into playing this with my son and his friends again. There was a Spongebob Squarepants even and that was fun but I’m maxed out and am not picking it up much anymore. It’s a repetitive game but they do good to make it seem different (daily map rotations and updates, etc).</li> <li>Bought the new Zelda, haven’t played it but my son is almost done.</li> </ul> Fri, 11 Oct 2024 04:00:00 +0000 https://daverupert.com/2024/10/vibe-check-35/ https://daverupert.com/2024/10/vibe-check-35/ Hibiclens <p>Every two-to-four years my body chemistry changes and my armpits start to reject my deodorant with an intense itch. All that aluminum has gunked up the works I guess. Usually cycling out deodorants works fine, but this time it didn’t work because my armpits were overpowering all the other deodorants.</p> <p>I tried a tactical reset and took the “<a href="https://daverupert.com/2024/06/vibe-check-33/">No deodorant challenge</a>”, the legend –which I remember my hippie step-brother Nik telling me about thirty years ago– that if you stop using deodorant for two weeks the oils in your body naturally recalibrate and you stops smelling… but this urban legend very much did not work. I smelled horrible all the time.</p> <p>I casually mentioned this issue to my dermatologist and he was quick to recommend this homely teal bottle of over-the-counter 1970s logotype, <a href="https://hibiclens.com/">Hibiclens</a>.</p> <picture> <source srcset="https://cdn.daverupert.com/posts/2024/hibiclens-landscape.png" media="(orientation: landscape)"></source> <img src="https://cdn.daverupert.com/posts/2024/hibiclens.png" alt="A teal blue bottle of medicinal looking antiseptic cleaner"> </picture> <p>I like to think the “hibi” part of Hibiclens stands for “hibiscus” because it’s a pink liquid (or foam) that you apply like soap and rinse off. It’s colored pink because it’s an anti-septic and hospitals like to color their liquids, but the reason it works –as my dermatologist explained– is that <a href="https://www.npr.org/sections/health-shots/2015/03/31/396573607/meet-the-bacteria-that-make-a-stink-in-your-pits">bacteria creates the odor in your armpits</a>. That was news to me. My prior understanding was that puberty causes teenagers to grow green stink lines that shoot out from their bodies. Guess the science there has evolved.</p> <p>I’m happy to report that Hibiclens works wonderfully and I’m pleased with the results. I don’t wear deodorant everyday anymore, my armpits aren’t irritated, and I only need to apply a squeeze of Hibiclens every three days or so (but even that timeline appears to be stretching out). I do sometimes wear deodorant when the stakes are high, but day-to-day working form home is <em>au naturale</em>. There’s a small satisfaction that the answer to my fragile-masculine deodorant FOR MEN problems is a pink liquid in a Tiffany blue teal bottle. Time will tell, however, if it really does solve my problems. I’ll follow up in two-to-four years to see if it still works.</p> Sat, 14 Sep 2024 18:52:00 +0000 https://daverupert.com/2024/09/hibiclens/ https://daverupert.com/2024/09/hibiclens/ Good forms <p><a href="https://brian.io/">Brian LeRoux</a> posted <a href="https://indieweb.social/@brianleroux/112932335725534529">a few thoughts about forms</a> and the idea of a “<a href="https://daverupert.com/2024/04/thoughts-on-cosmotechnics/">good form</a>” resonated with me so I dogpiled some of my own thoughts and experiences on it. Here’s a compilation of those ideas. I’m sure this is incomplete and would love to see your list.</p> <ul> <li>Good forms work without client JavaScript (Brian LeRoux)</li> <li>Good forms always submit (Brian LeRoux)</li> <li>Good forms remember values and display problems inline (Brian LeRoux)</li> <li>Good login forms work with password managers (<a href="https://elk.zone/oldbytes.space/@mingo/112932355524060403">Mingo Hogan</a>)</li> <li>Good forms use a <code>&lt;form&gt;</code> tag</li> <li>Good forms use appropriate input types</li> <li>Good forms have clear labelled inputs and buttons</li> <li>Good forms have focus states</li> <li>Good forms have logical tab order</li> <li>Good forms allow paste</li> <li>Good form elements leverage the <code>inputmode</code> attribute</li> <li>Good form elements leverage the <code>autocomplete</code> attribute</li> <li>Good search forms wrap the <code>&lt;form&gt;</code> tag in a <code>&lt;search&gt;</code> element</li> <li>Good forms can be reset with a <code>&lt;button type=reset&gt;</code></li> <li>Good forms participate in <code>formData</code></li> <li>Good forms don’t use placeholder as a label</li> <li>Good forms work on phones</li> <li>Good forms don’t popup and ask for personal information</li> <li>Good forms only ask for what is necessary and aren’t too long</li> <li>Good forms use HTTPS</li> <li>Good forms use the proper HTTP verbs</li> <li>Good forms validate on the client AND on the server</li> <li>Good forms have been driven with a screen reader <em>before</em> going to production</li> <li>Good forms clearly denote required attributes</li> <li>Good forms warn about costly or destructive actions</li> <li>Good forms make the baby Jesus smile</li> <li>Good authenticated forms should have a server-generated nonce value</li> <li>Good forms should do a pre-flight check for <code>navigator.onLine</code> before attempting a submit</li> <li>Good forms start with <code>accent-color</code> for styling and only get more complex if necessary</li> <li>Good forms see custom controls as a radioactive asset that must be removed at the earliest opportunity</li> </ul> <p>Anyways. People should talk about forms more. Here’s some more resources on good form design.</p> <ul> <li><a href="https://www.smashingmagazine.com/printed-books/form-design-patterns/">Form Design Patterns</a> by Adam Silver</li> <li><a href="https://www.lukew.com/resources/web_form_design.asp">Web Form Design</a> by Luke Wroblewski</li> <li><a href="https://formdesignmastery.com/">Form Design Mastery</a> by Adam Silver</li> <li><a href="https://abookapart.com/products/better-onboarding">Better Onboarding</a> by Krystal Higgins</li> </ul> Fri, 13 Sep 2024 13:25:00 +0000 https://daverupert.com/2024/09/good-forms/ https://daverupert.com/2024/09/good-forms/ Finding questions and answers about why I like books <p>I saw <a href="https://twitter.com/AlexHormozi/status/1543229182796132352">a tweet</a> awhile back that sent my brain to a far off galaxy…</p> <blockquote class="twitter-tweet"> <p lang="en" dir="ltr"> Most people are proud of their reading habit. <br> <br> But for many, it’s just an act of productive procrastination. <br> <br> I’m looking at you “I read a book a week” club <br> <br> Here’s how you know: <br> <br> Are you reading to find answers to questions?…or are you reading to find questions to answer? </p> &mdash; Alex Hormozi (@AlexHormozi) <a href="https://twitter.com/AlexHormozi/status/1543229182796132352?ref_src=twsrc%5Etfw">July 2, 2022</a> </blockquote> <p>Of all the injustices happening in the world… you know who needs to be taken down a peg? The Book-a-Week People. Fuck those guys. With their books in their Zoom backgrounds. That bothers me. Fuck them.</p> <p>I know the original post is part of some weird hustle culture subgenre, but it’s probably no surprise to folks reading that <a href="https://daverupert.com/bookshelf/">I like books</a> and fit this targeted demographic. After pondering whether I’m “finding answers to questions or questions to answer” my answer is a resounding, “…I guess?”</p> <p>A lot of why I read is about juxtaposition. I read business books to juxtapose my experience against the Platonic ideal of “good business”. I read about social justice to juxtapose my lived experience against others lived experience. I read science fiction to juxtapose the present against futures I haven’t imagined. I read non-fiction airport books because I like facts and social science garbage. I read books on topics I’m already an expert in to see if there’s information that further informs my perspective. I read to <a href="https://daverupert.com/2018/06/telepresence/">teleport</a> to different places, minds, times, and rooms where it happened.</p> <p>I read to escape. I read to find myself. I read because I like facts. I read because I like fiction. I read for entertainment. I read to fall asleep. I listen to books to help me finish mundane tasks like doing the dishes every night. And I listen to books because there’s a slight communistic thrill of getting them from the library.</p> <p>There’s a widely accepted idea out there that “the best way to become a better writer is to become a better reader.” I think Stephen King said it, but I can’t find the quote. Either way, I want to become a better writer. Whether fact or fiction, I want the ability to not struggle when putting thoughts on the page. Oh to partake in this magical osmosis! The transitive impartation of skills! Let me flex the language encoding and decoding synapses in my 40-watt brain.</p> <p>And sometimes reading is out of due diligence. Like… if you’re going to start a job as a manager… read a book on management? Or ten? You’re dealing with people’s lives and careers, seems like the least you could do. If you’re going to talk or blog on a topic and there’s a relevant book… read that before <a href="https://www.quora.com/What-does-the-southern-phrase-showing-your-ass-mean">showing your ass</a>? A thought backed by some literature seems better than regurgitating TikToks.</p> <p>Books are strange objects. Chapters and chapters of coherent research and lived experiences assembled by people who wanted to put it all down in one place. Edited by actual editors who like editing. Designed— down to the weight of the paper, the typography, and the illustration on the cover— to make the experience of reading it enjoyable. Books are uncanny and impractical objects. A terribly inefficient way to encode information from one brain to another, but an excellent way to tell a story.</p> <p>You can also just like books for no reason.</p> <p>Anyways, books. Check ‘em out.</p> Thu, 12 Sep 2024 14:28:00 +0000 https://daverupert.com/2024/09/fuck-the-book-a-week-club/ https://daverupert.com/2024/09/fuck-the-book-a-week-club/ The Dev Tools Performance Monitor Panel <p>Weeks ago I was looking in to a performance issue for our animated spinner component and stumbled across a tool in DevTools I hadn’t used before: <a href="https://developer.chrome.com/docs/devtools/performance-monitor">The Performance Monitor Panel</a>. In you open <code>Dev Tools &gt; More Tools &gt; Performance Monitor</code> you’ll see some helpful high-level charts and graphs of the realtime performance data of your UI.</p> <p><img src="https://cdn.daverupert.com/posts/2024/perfmonitorpanel.jpg" alt="The Figma.com homepage with the performance panel open to the side showing 120 style recalcs per second" /></p> <p>The Performance Monitor collects performance data in realtime and puts it on a graph. It’s handy for detecting performance problems at a high-level. If your CPU, memory, DOM node count, or event listeners only go up while <a href="https://blog.jim-nielsen.com/2024/sanding-ui/">clicking around</a>, you probably have a leak in your code. The part I was most interested in were style recalculations per second and layouts per second. Our spinner component was triggering style recalculations and layout calls at a rate of 120 per second. Yikes! That’s a lot of extra work on the CPU.</p> <p>Next I turned on <code>Dev Tools &gt; More Tools &gt; Rendering &gt; Show Paint Flashes</code> and I could immediately see the tactile feedback of green boxes thrashing around as the browser repainted the component hundreds of times per second. The green paint boxes confirmed that this UI work was happening on the main thread instead of the compositor thread. The Performance Monitor showed my CPU usage at 5-9% of my Mackbook Pro. Double Yikes.</p> <p>The Performance Monitor panel pairs nicely with the top-level Performance panel. While the Performance Monitor panel is very high-level, the Performance panel is an in-depth debugging tool where you can inspect a snapshot of your app down to each function and render call.</p> <p><img src="https://cdn.daverupert.com/posts/2024/perfpanel.jpg" alt="A flame graph inside the Performance Panel in dev tools" /></p> <p>Capturing a snapshot in the Performance panel confirmed what I was now seeing. I could see the “red line of death” of dropped frames where I locked the main thread. The remediation steps were pretty simple but I did need to strip down and recode how our animation worked.</p> <ol> <li><a href="https://web.dev/articles/animations-guide">Avoid properties that trigger paint or layout</a></li> <li>Tamp down layout recalcs with <code>contain</code></li> <li>Use <code>overflow: hidden</code> instead of CSS masks</li> </ol> <p>It took a couple of prototypes to shop around a workable solution. The good news is our animation is off-loaded to the compositor instead of the main thread now. CPU use is now at <code>0.2%</code> (down from 5-9%) and our recalcs and layouts are down to <code>0</code> but the animation still chugs along. Truth be told, a loading spinner is a pretty insignificant component and is only temporary, but reducing CPU usage by 10% here makes room for other JavaScript activities… like… y’know… fetching and parsing data.</p> Tue, 03 Sep 2024 14:48:00 +0000 https://daverupert.com/2024/09/dev-tools-performance-monitor-panel/ https://daverupert.com/2024/09/dev-tools-performance-monitor-panel/ Vibe Check №34 <p>The temperatures soared over 100ºF and the yard is dead and everything smells roasted. But the ten day forecast shows a ten degree dip and that is cause for celebration. Another school year has started. My son has started middle school and my daughter is now in third grade. It’s shocking how fast life goes. And on the workfront, the pace is picking up now that everyone has come back from summer vacation.</p> <p>A lot has transpired since the previous vibe check (vacations, new pets, rock shows). To start it off, my family escaped the heat and went to San Diego (as is the custom) for one good week and one awful week…</p> <h2>San Diego: The First Good Week</h2> <p><img src="https://cdn.daverupert.com/posts/2024/sandiego.jpg" alt="Left: a pink beach drink. Right a dark sunset over Mission Bay San Diego" /></p> <p>We flew out to Phoenix to join up with my wife’s family and caravan out to San Diego. We had a family dinner the night before and got to see my one year old grandnephew for the first time in a long while. He’s a sweet kid but does not want his Granduncle Dave holding him yet.</p> <p>The next day we loaded up the beach gear and drove to a resort in Mission Beach in San Diego for a four day stay. We had a great time with my wife’s family letting the cousins run loose while grown-ups played tennis, pickleball, and I played my annual round of golf with my male in-laws. After four days of big family time we scooted up to Encinitas to stay for two nights with our Austin friends whose summer rental had a guest house.</p> <p>Encinitas was super charming. We stayed near <a href="https://www.tripadvisor.com/Attraction_Review-g32355-d12186525-Reviews-Beacon_s_Beach-Encinitas_California.html">Beacons Beach</a> which is one of those cool beaches at the bottom of a cliffside. We beached pretty hard. My daughter and her oldest bestie pranced up and down the shoreline for hours and she even learned to surf. The contrast between Mission and Encinitas couldn’t be more stark. The trip could have ended there and would have been one of the best vacations in the books. But we weren’t done! We planned to extend the trip with a one-week rental in Mission Bay.</p> <h2>San Diego: The Second Awful Week</h2> <p>The minute we checked into our beachside rental the whole vibe shifted. From tranquil Encinitas to getting blasted with the sounds (and smells) of Mission Beach. Honking, motorcycles, bottles clanking, fighting, garbage trucks, neighbors blasting bad music, and smells drifting up from the alleyway. It felt like going from a yoga retreat to a frat house. Then it got worse. That night our daughter said she didn’t feel well and the next day my wife started going downhill.</p> <p>A week of beach fun turned into spending thousands of dollars to be sick inside a beach-adjacent summer rental watching SpongeBob Squarepants on repeat. After three urgent care visits over two days the sick members of our party had the required antibiotics to start feeling better. The next day, we went home.</p> <p>And –as if it couldn’t get any better– I got COVID on the plane ride back. Ughck.</p> <h2>We adopted two new pups</h2> <p><img src="https://cdn.daverupert.com/posts/2024/dogs.jpg" alt="One black dog with one brown eye and one blue eye and a black and white dog with pointy ears and two blue eyes, both staring at the camera" /></p> <ul> <li>Laneige (aka “Laney”) - A black lab mix with one brown eye and one blue eye. She’s an attention thief who is not shy about demanding pets.</li> <li>Rosebud - A lab mix with expressive pointy ears and two blue eyes (some heeler in there?). She’s the more anxious of the two, but once befriended will roll over for belly rubs.</li> </ul> <p>Our kids have been asking for a new dog for over a year. Every day this summer I’d step into the house and my daughter would spin a laptop around to show me the new dogs she found on <a href="https://www.austinpetsalive.org/">the Austin Pets Alive! website</a>. She even wrote a song to try to convince me to get a dog. 🥺 They were dead set on a pup named “Laneige” (named by the shelter after a Korean lip balm).</p> <p>After dropping the kids off at grandma’s house for a long weekend, we set our plan into action: adopt a dog and surprise the kids. But our plans changed when the shelter brought out Laneige’s sister Rosebud (also named after a lip balm) to our meet and greet. Her pointy ears and blue eyes were too cute. We tend to play it more conservative when it comes to big life choices but we decided to go full stupid for once and surprise the kids with not one dog, but two dogs!</p> <p>Names may change and we daily ask ourselves “Did we overdo it?” but generally we’re happy with the new additions.</p> <h2>Frostapalooza</h2> <figure> <p><img src="https://cdn.daverupert.com/posts/2024/frostapalooza.jpg" alt="Me playing bass guitar drowned in moody green and purple rock show lighting" /></p> <figcaption> <p>Photo by <a href="https://wbrowar.com/">Will Brower</a></p> </figcaption> </figure> <p>A year ago Brad Frost called my wife and I to share a wild idea for his 40th birthday party: get all his musician friends from all over the world together on one stage for one night of rocking out. Over the course of the next year we picked songs, learned parts, recorded tracks, hoping –but never knowing– how it would all turn out when we assembled in Pittsburgh for one night of rock.</p> <p>It. Was. Phenomenal.</p> <p>Nothing could have prepared me for the blast from the five piece horn section. It sounded perfect. It felt big. Dozens of people on stage playing together for the first time, but you wouldn’t know it. Music –good music– filling the halls of an old church. I’m a foot away from a bass guitar amp but I can’t hear the bass because there’s so much music happening. In the crowd I see people listening to my wife sing –they’re singing along– and it takes me back to when I first heard her sing at a karaoke bar in Los Angeles when I fell in love with her.</p> <figure> <p><img src="https://cdn.daverupert.com/posts/2024/webnerds.jpg" alt="Twenty or so web luminaries (most named below)" /></p> <figcaption> <p>Photo from Brad Frost</p> </figcaption> </figure> <p>Outside the main event, it felt good to put kindling on some friendships. I got to see <a href="https://chriscoyier.net/">Chris</a>, which is always pleasant to see the one person I’m guaranteed to have an hour long conversation every week. <a href="https://www.zachmeyer.com/">Zach</a> &amp; Danh (my co-hosts from <a href="https://asidequest.simplecast.com/">Aside Quest</a>) flew up on the same flight. But I got to see and chat with new and old friends as well; <a href="https://ianfrostweather.com/">Ian</a>, <a href="https://www.dandenney.com/">Dan</a>, <a href="https://bencallahan.com/">Ben</a>, <a href="https://www.hawksworx.com/about">Phil</a>, <a href="https://www.mikeaparicio.com/">Mike</a>, <a href="https://www.jina.me/">Jina</a>, <a href="https://github.com/break-stuff">Burton</a>, <a href="https://www.adekunleoduye.com/">Adekunle</a>, <a href="https://kevincoyle.co.uk/">Kevin</a>, <a href="https://bkardell.com/">Brian</a>, <a href="https://jenson.org/">Scott</a>, <a href="https://bigmedium.com/">Josh</a>, Veronika, <a href="https://ryantrimble.com/">Ryan</a>, <a href="https://joshuasager.com/">Joshua</a>, <a href="https://www.jjeff.com/">Jeff</a> &amp; <a href="http://www.littlechair.com/">Jenn</a> &amp; <a href="https://arlorobbins.com/">Arlo</a>, <a href="https://adactio.com/">Jeremy</a> &amp; Jessica, <a href="https://bethan.bandcamp.com/">Daniel &amp; Jessi</a>, <a href="https://www.lovejerks.com/">Rebecca &amp; Ryan</a>, and countless more folks. Since the US web development conference scene has more or less imploded since the pandemic, this felt a bit like a family reunion with some of my favorite people from around the world.</p> <p>In the end, <a href="https://frostapalooza.bradfrost.com/">Frostapalooza</a> was a magical night celebrating the power of music and friendship. It feels a bit like a dream now and when I explain it to people my words fall short. An ephemeral joyous moment and I have no idea if I’ll do anything like that in my life again. That’s special. The biggest thanks to Brad, Melissa, and Ella who sacrificed a lot of time, money, and life-force to pull it off.</p> <h2>The stats, o the stats.</h2> <p>Okay, quantifiers. Calm down. Here’s your beefsteak of itemized inputs and outputs.</p> <h3>🧠 Learning</h3> <ul> <li>When I got sick I did a deep dive in playing with <a href="https://obsidian.md/">Obsidian</a> and building a vault. I’m still on Notion (for now) but the jump is less intimidating. I like the indie/privacy angle of Obsidian a lot but from a UX perspective it feels “finicky” when mousing over content in a way that Notion doesn’t. The level of customization is also nicer in Obsidian, but also a potential endless rabbit hole for my distracted brain. Moving my “second brain” is not a task I want to take lightly.</li> <li>Watching countless Obsidian videos exposed me to a new organization system: <a href="https://www.youtube.com/watch?v=d93SGaf82OM">August Bradley’s “Pillars, Pipelines, and Vaults” (PPV) system</a>. I’m not ready to ditch <a href="https://daverupert.com/2022/04/productivity-sniped-by-para/">my Notion PARA setup</a>, but the idea PPV introduces that I’m gravitating towards is that my brain is a system of “Inputs” (links, books, and notes vaults) and “Outputs” (blog posts, side projects, and task pipelines) and those exist across “Areas” (pillars) in my life. Inputs need organization (e.g. folders and/or tags) and outputs need a process (e.g. <a href="https://daverupert.com/2021/09/my-notion-blogging-kanban/">a kanban</a>). I think Obsidian fits this paradigm better than Notion.</li> </ul> <h3>📖 <strong>Reading</strong></h3> <p>Not my best summer of reading but I’m enjoying the slower pace.</p> <p><strong>Finished</strong></p> <ul> <li><a href="https://amzn.to/4ckSatD">Like, Comment, Subscribe</a> by Mark Bergen - The history of YouTube. A great look into how this product which changed the world evolved (and also failed to evolve).</li> <li><a href="https://amzn.to/4foUaD6">Read Write Own</a> by Chris Dixon - On a recommendation I read a book about crypto. Shockingly, I didn’t disagree with much here… except that crypto is the solution to the problems outlined in the book. He spent chapters pitching ideas that crypto could solve (decentralized social networks, carrying over video game assets, etc) and those have since been debunked. There’s <em>still</em> no job that crypto does better than a database. Ultimately I think it’s a question of “Who benefits?” when it comes to this technology and I think the answer is: the people who already own a lot of it.</li> <li>Humankind by Rutger Bregman - I’ve read this book before but it’s a pleasant little dose of positivity. Are we humans that trample each other while leaving a burning plane? Or are we humans that help each other get off the plane? The answer might surprise you.</li> <li>Slow Productivity by Cal Newport - I liked this book better than the last but I think it suffers from the same problems all his books do… he’s shielded by academia and not that busy of a person. I laughed out loud when he used Jane Austen as an example of Slow Productivity (paraphrasing) “After her father sold the farm and the school and they moved to a beach town, she was able to slow down.” Like, yeah dude, I could slow down too if my dad retired and sold the literal farm.</li> </ul> <p><strong>In Progress</strong></p> <ul> <li><a href="https://amzn.to/3XHSrT7">A Wizard of Earthsea</a> by Ursula K. Le Guin</li> <li>The Adventure Zone Vol. 6 by McElroy, Pietsch, McElroy</li> <li>Awe by Dacher Keltner</li> </ul> <h3>📝 <strong>Blogging</strong></h3> <p>Not my best summer of blogging. But the drafts folder is going wild. Trust me. Lol.</p> <ul> <li><a href="https://daverupert.com/2024/06/mini-4wd/">Mini 4WD</a> - a new hobby</li> <li><a href="https://daverupert.com/2024/07/summer-rental/">Summer rental</a> - a post about vacation</li> <li><a href="https://daverupert.com/2024/08/fueling-my-body/">The cost of fueling my body</a> - a quantification of self</li> </ul> <h3>📺 Media</h3> <p>Not my best summer of media consumption. But I’m back on Dropout which is nice.</p> <p><strong>TV</strong></p> <ul> <li>Wimbledon 2024 - Watched a lot of the Wimbledon finals with my wife.</li> </ul> <p><strong>Streaming</strong></p> <ul> <li><a href="https://www.dropout.tv/make-some-noise/season:3">Make Some Noise S3</a> (Dropout) w- My favorite improv show. It’s punchier this season.</li> <li><a href="https://www.dropout.tv/thousandaires">Thousandaires</a> (Dropout) - What would you do with $1,000!?</li> <li><a href="https://www.dropout.tv/dimension-20-never-stop-blowing-up">Dimension 20: Never Stop Blowing Up</a> (Dropout) - A VHS action movie fever dream but with dice.</li> </ul> <p><strong>Anime</strong></p> <ul> <li>Goldenboy (1995) - Full of fan service but has a main character that flips the genre on its head a bit.</li> <li>Mob Psycho 100 S2 (2019) - Mob is at it again. Such a weird, fun series.</li> <li>Gundam Breaker Battlogue (2021) - A short web series to promote a new line of Gundam models. Not my favorite “Builder” series nor is it my favorite line of Gundam models. Battlogue on all fronts feels rushed and cheap.</li> </ul> <h3>🧶 <strong>Crafts</strong></h3> <ul> <li><a href="https://daverupert.com/2024/06/mini-4wd/">Tamiya Mini 4WD Blast Arrow Starter Pack</a> - I got into watching min-cars race around a track. I bought one for me and one for my son. I finished mine. My son didn’t finish his. But we don’t have a track to race on… so I either need to pony up cash or figure out another way to race.</li> </ul> <h3>🤖 Gunpla</h3> <p><img src="https://cdn.daverupert.com/posts/2024/pgu-rx-78-2.jpg" alt="Left: the black inner frame of the 12 inch tall perfect grade gundam model. Right: the completed gundam model classic red white and blue armor applied. Smaller model of same mech included for scale in both photos." /></p> <p>I built the <a href="https://www.youtube.com/watch?v=xfmD1yYqP6k">Perfect Grade Unleashed RX-78-2 Gundam</a> - The granddaddy of all granddaddies. This was an incredible build start to finish. I stalled out for two weeks over adhering some metal etching parts but I tried out different glues and cements and ended up using a <a href="https://www.scotchbrand.com/3M/en_US/p/d/cbgnhw011037/">Scotch Restickable Glue Stick</a> (the same glue for Post-it Notes) and it worked great.</p> <p>From the inner frame to the outer shell of the body armor, this model is jaw dropping. It has heft, but not too heavy. It poses but feels sturdy. Bandai nestled in gimmicks everywhere but also so subtle you’d never know they were there from a distance. I need to finish putting on all the stickers, but it’s already so incredible to look at that I fear over-decorating.</p> <h3>⌨️ <strong>Open source</strong></h3> <p>Nothing official. Except for my job I guess which is technically open source.</p> <h3>👾 <strong>Video games</strong></h3> <ul> <li><a href="https://thankgoodness.game/">Thank Goodness You’re Here</a> (Switch) - A hilarious little slapformer (not for kids)</li> </ul> Sat, 24 Aug 2024 03:37:00 +0000 https://daverupert.com/2024/08/vibe-check-34/ https://daverupert.com/2024/08/vibe-check-34/ The cost of fueling my body <p>I’ve become a bit obsessed with how much it costs to fuel my body during the working hours.</p> <table> <thead> <tr> <th>Item</th> <th>Cost/Serving</th> <th>Qty/Day</th> <th>Cost/Day</th> <th>Qty/Month</th> <th>Cost/Month</th> </tr> </thead> <tbody> <tr> <td><a href="https://daverupert.com/2023/10/snap-kitchen/">Snap Kitchen 500cal meal</a></td> <td>$10.00</td> <td>1</td> <td>$10.00</td> <td>22</td> <td>$220</td> </tr> <tr> <td>Fairlife 42g Protein Shake</td> <td>$3.50</td> <td>1</td> <td>$3.50</td> <td>22</td> <td>$77</td> </tr> <tr> <td><a href="https://daverupert.com/2023/07/liquid-death/">Liquid Death</a></td> <td>$1.75</td> <td>1</td> <td>$1.75</td> <td>22</td> <td>$38.50</td> </tr> <tr> <td>Ruta Maya Dark Roast</td> <td>$0.25</td> <td>3</td> <td>$0.75</td> <td>66</td> <td>$16.50</td> </tr> <tr> <td><a href="https://daverupert.com/2023/10/califia-farms-oat-barista/">Califia Farms Café Oat</a></td> <td>$0.11</td> <td>3</td> <td>$0.33</td> <td>66</td> <td>$7.26</td> </tr> <tr> <td>Total</td> <td></td> <td></td> <td>$16.33</td> <td></td> <td>$359.26</td> </tr> </tbody> </table> <p>To keep me and my brain running during working hours costs me ~$359.26/month. Not much to say beyond that –no grand epiphanies– except that I think it’s too expensive. Sitting in an office by myself costs me $16.33/day (or $2/hour). This budget doesn’t include breakfast, dinner, exercise, healthcare, transit, internet, electricity, or office supplies… all necessities that enable the work. This is just the daily cost of caloric fuel to keep my body going during the nine-to-five. My family has three other humans in it too, so this seems collossaly expensive.</p> <p>If I wanted to save money (I sort of do), here’s what I’d could try to optimize from top to bottom:</p> <ul> <li>I could make my own pre-made meals for about ~$2/meal. I’ve had success with this but it requires a lot of weekend logistics to execute properly. This would be the most significant cost reduction, costing only $44/month and saving $176/month.</li> <li>I could buy whey protein in bulk. A 5 lb bag of Muscle Milk (nearest approximate flavor) is $72/bag and contains 68 servings for a reduced costs of $1.05/serving. However, one serving only has 25g of protein, so if I’d need to double the scoops. The total cost would then be $2.11/serving or $46.42/month. Buying bulk powder makes fiscal sense, but $30/month to not have to deal with drinking clumpy protein shakes and washing crusted stinky shakers seems almost worth it.</li> <li>I considered eggs as an alternate source of protein instead. A single egg has ~6g of protein and costs about 50¢. The cost could potentially come down but the bigger issue is to get the same 42g of protein I’d need to eat 7 eggs. I don’t know if you’ve eaten eggs before but <u>7 eggs is a lot of eggs</u>. Imagine woofing down 7 sweaty hard-boiled orbs a couple times a day, yikes.</li> <li>I could brew my own agave-sweetened tea. I’ve done this once, but the crisp flavor profile wasn’t the same so I wouldn’t call it a success. Needs more experimentation.</li> <li>Thanks to Costco selling our favorite local coffee roaster in bulk, we have caffeine ritual costs dialed down about as low as they can go. Feel comfortable there.</li> </ul> <p>Lowering my lunch costs stands out as the best candidate for improvement. But <a href="https://daverupert.com/2023/10/snap-kitchen/">as I noted before</a>, adding even a small pile of extra duties risks toppling the wagon and I’m back to eating emergency $14 Spicy Chicken Sando Combos to quench my hunger. I wonder where my daily costs fit on a graph of national statistics. Is this average? Is this Bidenomic inflation? Am I making myself poor with my avocado toast? Someone who understands finances help me budget! Ack!</p> Thu, 08 Aug 2024 14:22:00 +0000 https://daverupert.com/2024/08/fueling-my-body/ https://daverupert.com/2024/08/fueling-my-body/ Summer rental <p>4:05am<br /> The windows are open, hoping to capture the faint winds and convert them into a mythical cooling cross-breeze. A gust passes through vacuuming all the doors shut, cancelling hope for a miracle.<br /> I’m awake. It’s cool but I’m on top of the covers and not cool enough.<br /> The plastic thump-thump-thump of the oscillating fan reaching the end of its arc is rhythmic yet not. After three-to-six attempts, it yields to the resistance and heads the other way. It will be back soon.<br /> Another fan in the room sounds like a far off propeller plane looping around the property. I await its arrival at each approach.<br /> The alleyway ebbs and flows throughout the night with the smell of marijuana smoke, teens cussing, and the clinking of bottles as passers-by rummage through recycling bins.<br /> There’s a sick child in the other room. My child. Been sick for days, poor thing. On antibiotics now. Spit the first dose on the floor because she didn’t like the taste.<br /> I can hear her labored breath as different subconscious systems battle for what they deem as comfortable. Warm, yet shivering. Cold, yet burning up. Asleep, yet aware.<br /> My wife is there next to her. Also sick with a persistent unspecified cough.<br /> Since arriving at the rental three days ago, I have only left the house to buy medicine and wine.</p> <p>7:23am<br /> Scuttling in the alleyway. Two voices. A truck starts. A woman pleads, “I’m sorry, I fucked up.” The truck drives off.<br /> I put on a pot of coffee.</p> <p>9:15am<br /> Left the rental to walk and pick up breakfast. Peeked at the ocean to remind myself of the magnitude. I’m a block away but hadn’t seen it in days.<br /> I got a breakfast burrito. The potatoes were a little al dente, but it had black beans and wasn’t a soupy mess so I call that a win.<br /> PCR tests came back and it’s not Covid and it’s not strep, but we don’t have any answer for what sickness(es?) our family is dealing with.<br /> I’m on vacation but it’s not quite vacation anymore.<br /> I’m working a bit. Dysfunctional but I appreciate a place to channel anxiety.<br /> Caretaking is much harder than computer work.</p> <p>4:46pm<br /> We made it to the beach. Wife and son thought it was too windy for my solar shade —and it was— but I persevered. After naysaying me they had the audacity to want to join me in my solar fortress. Haha. Nice try.<br /> My congested little one made me pretend food with wet sand. She’s allowed to join me in my fortress.<br /> We left as the tide came in and ordered pizza. The pizza was just okay.</p> <p>9:44pm<br /> A good day. A long day.<br /> Another member of the family is reporting a sore throat, so that’s less than ideal.<br /> “When this vacation is over I’m going to need another vacation,” the protagonist says looking directly through the fourth wall. The canned laughter erupts.<br /> Do wells of rage fill up faster than waters of peace? Am I broken or is the underlying system broken?</p> <p>5:32am<br /> Awakened by two crows squawking at each other.<br /> I went to bed after midnight. A new day begins.</p> Thu, 18 Jul 2024 23:10:00 +0000 https://daverupert.com/2024/07/summer-rental/ https://daverupert.com/2024/07/summer-rental/ Mini 4WD <p>The algorithm sucked me into another model craft hobby: Mini 4WD racing (ミニ四駆). A Mini 4WD is a 1:32 scale model that is a mix between slot cars and RC cars. You don’t control these cars with a remote control nor do they drive in an electrified slot, rather you place your racecar in a plastic track with high walls and send them speeding down the track at ~40km/h.</p> <iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/2ZZL5i8vOXM?si=ED2YFsLdI9z7BMbG" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> <p>The twist is you don’t know <a href="https://tamiya.com/japan/mini4wd/feature/2019/1206.html">what the track looks like</a> until race day, so you have to be ready to adapt. There might a big jump, moguls, or a tall mountain to climb. Once racers have seen the course, they have some time to make adjustments by balancing engineering choices about weight, power, braking, handling, batteries, downforce, and more. Are you going to make your car lighter and full send it over the tabletops? Or is slow and steady going to win the race? The races are a brief cacophony of slapping plastic and whirring motors but I can feel the electricity of the room through the screen.</p> <p><img src="https://cdn.daverupert.com/posts/2024/jcjc.jpg" alt="Untitled" /></p> <p>Where YouTube hooked me was watching custom 4WD Mini builders like <a href="https://www.youtube.com/@azpaca0">アズパカ</a>, <a href="https://www.youtube.com/@Niwakara">にわから</a>, and <a href="https://www.youtube.com/@techyuuta">ユウタ</a>. They are hellbent on making their cars as fast as possible. In Japanese they call it “タイムアタック” (“Time Attack”). For their time attacks, they use the <a href="https://d7z22c0gz59ng.cloudfront.net/cms/japan/mini4wd/topics/feature/2019_12/circuit_1911_2c1_002.jpg">Japan Cup Junior Circuit</a> (JCJC) course; a three lane track with a wave feature and a wicked lane change from the inner lane to the outer lane that will send light or fast cars flying off the course. The standardized course (and video format<sup class="footnote-ref"><a href="#fn1" id="fnref1">1</a></sup>) is where the similarities stop because their cars are anything but conventional.</p> <p>The videos are all about iteration and experimentation. Testing all kinds of parts and gimmicks like 3D printed chassis, side rollers, battery types, motors, wheels, and downforce options. Sometimes the tweaks are small, sometimes they are radical innovations:</p> <ul> <li><a href="https://www.youtube.com/watch?v=P8mXdQ9oW2c">An entirely “blade” flat chassis</a></li> <li><a href="https://www.youtube.com/watch?v=2rgALusRMAs&amp;t=396s">A chassis with all the weight to one side</a></li> <li><a href="https://www.youtube.com/watch?v=-o--_xP1xBA">A bendy chassis to bend around corners.</a></li> <li><a href="https://www.youtube.com/watch?v=HKWx_TMOzvo">A chassis with a motor on each wheel</a></li> <li><a href="https://www.youtube.com/watch?v=P8mXdQ9oW2c">A chassis with a computer fan in the middle</a></li> <li><a href="https://www.youtube.com/watch?v=FlLuqw_Bf08">A car with knives</a></li> <li><a href="https://www.youtube.com/watch?v=S1J8fqEXrv0">A dual-fan chassis that looks like a GPU</a>.</li> <li>A car with model rocket engines!? <a href="https://www.youtube.com/watch?v=cRpmNh-kOkE">Why not</a>.</li> </ul> <p>That sort of raw, no-rules experimentation is refreshing to watch. It looks like dumb fun. A reason to own a 3D printer. They experiments don’t always work and will fail spectacularly, but lessons get learned. And if you watch enough videos, you see them getting faster.</p> <ul> <li>A stock car will complete all three laps in about 5 seconds.</li> <li>Cars they made a year ago will go around in 3 seconds.</li> <li>Cars they made six months ago, 2 seconds.</li> <li><a href="https://www.youtube.com/watch?v=Lyoc3my8suY&amp;t=3s">A car from one month ago, 1.63 seconds.</a></li> </ul> <p>I’m not sure why Mini 4WD strikes such a chord with me. It could be nostalgia for my RC car days as a ten year old. It could be my penchant for Japanese model making. But I probably know what hooks me the most: this is the flavor of engineering optimization work I like to do. Make it lighter, faster, and able to handle bumps in the road. Websites are of course vastly different than mechanical engineering… but the correlation between weight and speed are enough to <a href="https://web.archive.org/web/20240227130052/https://www.youtube.com/watch?v=alZvGsOVh3o">activate my brain</a>.</p> <p><img src="https://cdn.daverupert.com/posts/2024/mini4wd.jpg" alt="Untitled" /></p> <p>So I bought a <a href="https://amzn.to/3W5aHoc">Mini 4WD Starter Pack</a> (and one for my son) to close the loop on my curiosity. They’re only ~$20, so why not. The hitch in the plan is that a beginner track costs $120. It would nice to have an opportunity to run around a complex track without an upfront cost. My hobby shop used to host races and have a track in-store before COVID, but not anymore. Maybe I can provide this as a service to my kids’ friends… yeah… that’s a good justification.</p> <section class="footnotes"> <ol> <li id="fn1"> <p>I secretly love the unified video format: a robotic female voice over narrating an engineering process. Don’t mess with success, boys, the formula is working just fine. <a href="#fnref1" class="footnote-backref">↩</a></p> </li> </ol> </section> Sun, 30 Jun 2024 21:08:00 +0000 https://daverupert.com/2024/06/mini-4wd/ https://daverupert.com/2024/06/mini-4wd/ Vibe Check №33 <p>The cicadas hum their ancient alien tune in the treetops above. The asphalt is hot to the touch. Cars and homes fill with the white noise of air conditioning in attempts to keep those inside alive. My enemy, the Sun, beams its photonic radiation at me –only me– and mocks my every step and sows humiliation as sweat pours down my back to pool betwixt my buttocks. We trudge through hot air to make due with our curse.</p> <p>I started a new job. We went on a trip. Saw Mount Rushmore. Saw Austin FC win. School ended. Sports are over but a new –more committed– cheer season is already underway. Swim team ends today and I will not miss those steaming hot Saturday mornings, but will miss the thrill of seeing my kids continuously improve and rack up personal bests. My son returned from sleep away camp. And we’re all looking forward to a proper vacation soon.</p> <h2>Newly employed at Microsoft</h2> <p>At the beginning of May <a href="https://daverupert.com/2024/05/dave-goes-microsoft/">I started my new job at Microsoft</a>. It’s already been nearly two months and I think I’m adjusting nicely to corporate life. Thankfully, the immediate group I work with has tons of nice and talented people so that makes it easy to feel welcome.</p> <p>My plate of responsibilities is still being assembled but the bulk of my work thus far has been refactoring some web components. Web components are pretty fast out of the box (look, ma! free lifecycle and reactivity code!) but we’re working to make our components <a href="https://blogs.windows.com/msedgedev/2024/05/28/an-even-faster-microsoft-edge/">be super fast</a>. While the scope of what I do is a fraction of my previous agency and startup life, it’s nice to be able to focus on isolated components.</p> <h2>I lost my publish button</h2> <p>It took me awhile to pinpoint this feeling but the biggest change since joining a large corporation is that I’ve lost my publish button. There’s probably ten people between me and code going to production. Gone are the days of making ten deploys a day. Gone are the days of yeeting a blog post on the company blog. Gone are the days of ssh’ing into a box to make some hot fixes. It’s for good reasons, of course.</p> <p>My personal publish button usage has also declined during this time. I blame onboarding to a new job, busy summers, and a small RSI flare up. But I’m not cooking drafts up like I used to either. I intentionally didn’t install Notion on my work machine to prevent distractions and so far that plan has worked. All is not lost, I burned some midnight oil last night and summoned a small quiver of drafts and I think shorter posts will lead the way.</p> <h2>The no deodorant challenge</h2> <p>I tried that hippie myth where you don’t use deodorant for two weeks and your body naturally adjusts and your armpits don’t smell bad…</p> <p>…this did not work. It very much did not work. I’m sorry.</p> <h2>A nephew’s graduation in South Dakota</h2> <p>Four days into my new job I took some time off to travel to South Dakota. My nephew graduated as valedictorian of his small high school in Hill City, SD. The kid has a lot going for him; a National Merit Scholar, cross country state champion, Gatorade’s 2024 Cross Country Player of the Year for South Dakota, a volunteer fire fighter, among other great qualities that he’ll bring with him to MIT in the fall.</p> <p><img src="https://cdn.daverupert.com/posts/2024/bros.jpg" alt="My brother and I giving a cool peace sign in front of Mount Rushmore on a cloudy day" /></p> <p>My nephew’s high school has the unique honor of being able to have their graduation at Mount Rushmore (his high school is also the only school that can have Smokey the Bear as a mascot, <a href="https://en.wikipedia.org/wiki/Smokey_Bear#Popularity">but that’s another story</a>). It’s a dramatic event to see kids transition into their future under the long gazes of those gargantuan stone presidents. It’s not often you get to attend an event like that and I’m glad our kids got to be there for it.</p> <p>Great to see family. We don’t have occasion to get everyone together often, so I’m glad I had the chance to yuck it up with my brother, nephews, cousins, in-laws, aunts, and uncles. Kids and adults played wiffle ball in the yard and we rode minibikes around the field. A good short trip to the Black Hills, we should do it more often.</p> <h2>🧠 <strong>Learning</strong></h2> <p>Most of my learning brain cells have gone towards learning how to do my new job. I think that’s okay.</p> <h2>📖 <strong>Reading</strong></h2> <p>I came across some great books since the last vibe check. I might actually do full posts for some of them… they were that good.</p> <p><strong>Finished</strong></p> <ul> <li><a href="https://amzn.to/453vjjP">Solaris</a> by Stanisław Lem - The audiobook from my library was a radio adaptation and I think I need to read the actual book.</li> <li><a href="https://amzn.to/3UMl3HJ">Your Brain on Art</a> by Susan Magsamen &amp; Ivy Ross - This book will change your behavior and how you spend your time.</li> <li><a href="https://amzn.to/3UMBeF9">The Communist Manifesto</a> by Marx &amp; Engles - Never actually read this until now. I don’t fully agree with them –particularly that Communism requires revolution because history shows that creates a power vacuum to fill with corruption– but the boys in red make some good points about Capitalism.</li> <li><a href="https://amzn.to/4apKyo0">How Big Things Get Done</a> by Flyvbjerg &amp; Gardner - My favorite book of the year so far. Validates a lot of what I talk about in regards to prototyping.</li> <li><a href="https://amzn.to/3WX7uYC">The Country of the Blind</a> by Andrew Leland – Columnist Andrew Leland has a degenerative eye condition and is going blind… is blind but not yet blind and unsure about claiming his blindness. An honest account of a slow but serious life change, breaking apart a lot of the misconceptions we as society hold about blindness.</li> <li><a href="https://amzn.to/3RxdqnI">A Fever in the Heartland</a> by Timothy Egan - I knew the KKK was a Southern thing, but did you know there was a large KKK presence in the North as well? This book tells about the rise of D.C. Stephenson, a Grand Dragon who rose to power and held a tight grip on the state of Indiana and the midwest. His rule would have continued if not for his perversion and one woman –Madge Oberholtzer– who revealed who his true character in her death and destroyed the clan’s presence in the state. I mean this without hyperbole, I felt like I was reading the story of Steve Bannon or Donald Trump. Horrific people who abuse fears to enrich themselves and exert their shitty brand of authoritarianism.</li> <li><a href="https://amzn.to/3VxleqD">The Art of Small Talk</a> by Casey Wilson &amp; Jessica St. Clair (Spotify) – A riotous look at how small talk benefits our lives. I nodded along the whole way until the penultimate chapter where it gets spiritual and talks about hairdressers speaking prophecies over people… other than that, great!</li> </ul> <p><strong>Started</strong></p> <ul> <li><a href="https://amzn.to/4ckSatD">Like, Comment, Subscribe</a> by Mark Bergen</li> <li><a href="https://amzn.to/3XHSrT7">A Wizard of Earthsea</a> by Ursula K. Le Guin</li> </ul> <h2>📝 <strong>Blogging</strong></h2> <p>A small handful of blog posts since the last update but the quality has never been higher.</p> <ul> <li><a href="https://daverupert.com/2024/05/light-dark-experiment/">A quick light-dark() experiment</a> - I love CSS.</li> <li><a href="https://daverupert.com/2024/05/dave-goes-microsoft/">Dave Goes Microsoft</a> - I got a new job.</li> <li><a href="https://daverupert.com/2024/05/cold-turkey-wont-fix-your-javascript-addiction/">A common web component learning blunder</a> - Web component libraries are okay to use and people might be doing themselves a disservice by <em>not</em> using them.</li> </ul> <h2>📺 Media</h2> <p>I started watching movies again. I don’t know what got into me but I’m finding enjoyment in watching movies right now. It might take me three days and countless interruptions to finish a movie, but there’s good stories in there.</p> <p><strong>Movies</strong></p> <ul> <li><a href="https://letterboxd.com/film/furiosa-a-mad-max-saga/">Furiosa</a> (2024) - Disappointed after seeing this in the theater. I understand the movie a bit more now as a fusion between the old hokey grindhouse Mad Max and the new grittier, jaw-dropping cinematic Fury Road. But <em>even</em> given that concession, it felt disjointed like two directors made it.</li> <li><a href="https://letterboxd.com/film/rrr/">RRR</a> (2022) - Long overdue. A slow warm for me, I didn’t lock in until later in the third act. But it’s a phenomenal, over-the-top film with a bit of welcome anti-Imperialist messaging mixed in.</li> <li><a href="https://letterboxd.com/film/the-black-hole/">Black Hole</a> (1979) - Saw a shitty sci-fi movie in my recommendations, watched that shitty sci-fi movie. It’s as if someone saw Star Wars’ success and Disney said, “We have R2-D2 at home.” Then decided they could make a cooler R2-D2 by making him talk. Weirdly though, I enjoyed it.</li> <li><a href="https://letterboxd.com/film/hunt-for-the-wilderpeople/">Hunt for the Wilderpeople</a> (2016) - Taika Waititi can do no wrong. A bizarre coming of age story, but charming nonetheless.</li> <li><a href="https://letterboxd.com/film/tokyo-godfathers/">Tokyo Godfathers</a> (2003) - What happens when three homeless people; a young girl, a drunk, and a drag queen find an abandoned baby on Christmas? This is like The Pogues’ Fairytale of New York in anime form and I’ll watch it over and over and reach for at the holidays.</li> <li><a href="https://letterboxd.com/film/inside-out-2-2024/">Inside Out 2</a> (2024) - A worthy sequel a blockbuster movie on mental health. Anxiety steals the show and is super relatable.</li> <li><a href="https://letterboxd.com/film/godzilla-minus-one/">Godzilla Minus One</a> (2023) - I heard this was good and they were wrong… it’s great! A perfect Godzilla movie for me.</li> <li><a href="https://letterboxd.com/film/starship-troopers/">Starship Troopers</a> (1997) - Clearing out my list of shame, I watched Starship Troopers. An interesting piece of satire to say the least, yet the characters and plot move you along. No wonder it’s a classic.</li> </ul> <p><strong>YouTube</strong></p> <ul> <li><a href="https://www.youtube.com/watch?v=b3gZOt1Lo4A&amp;t=3964s">I don’t know James Wolfe</a> by Folding Ideas – A hypnotizing analysis of a YouTube star, a callback to an arthouse film, and now I see nerdrage all over the internet, following me around like a haunted doll.</li> </ul> <p><strong>TV</strong></p> <ul> <li><a href="https://www.hulu.com/series/lego-masters-fd4ada37-965a-4f86-9ea4-0b214f3e6d7e">Lego Masters S4</a> (Hulu) - Something the whole family will watch and enjoy.</li> </ul> <p><strong>Anime</strong></p> <ul> <li><a href="https://www.netflix.com/title/81564899">Delicious in Dungeon</a> (Netflix) - Stuck in a rut on this, but will finish.</li> </ul> <h2>🎙 <strong>Recording</strong></h2> <p>We’ve been doing a little micro-series on ShopTalk about niche app builders. People who build bespoke apps and try to turn it into a business. The feedback has been good and I enjoy peeking into how others are making their dreams happen.</p> <p><strong>Niche app builders series</strong></p> <ul> <li><a href="https://shoptalkshow.com/616/">616: Strum Machine with Luke Abbott</a></li> <li><a href="https://shoptalkshow.com/618/">618: Matt Visiwig on SVGBackgrounds</a></li> <li><a href="https://shoptalkshow.com/619/">619: Svencodes</a></li> </ul> <p><strong>Other fantastic guests</strong></p> <ul> <li><a href="https://shoptalkshow.com/614/">614: CSS Grid Level 3 aka Masonry with Adam Argyle</a></li> <li><a href="https://shoptalkshow.com/615/">615: Dave Goes Windows For Real</a></li> <li><a href="https://shoptalkshow.com/617/">617: Economic &amp; AI Vibes with Jason Grigsby</a></li> </ul> <h2>🤖 Gunpla &amp; Plamo</h2> <p>I started on my Perfect Grade Unleashed RX-78-2 and I’m half-way finished. It’s a fantastic model. I also picked up a new Mini 4WD car… which I’ll post more about later.</p> <p><img src="https://cdn.daverupert.com/posts/2024/pgu-rx-78-2-wip.jpg" alt="A before and after of the inner frame of the Perfect Grade Unleashed RX-78-2 Gundam plastic model. The inner frame is all black and skinny in the before shot and all black but thick and has metal accents in the after shot. It’s about twelve inches tall and in both shots it’s next to the completed Entry grade version of the same plastic robot model that’s only 5.5 inches tall. " /></p> <h2>⌨️ <strong>Open source</strong></h2> <p>A couple CodePen web components, nothing officially open sourced. I tend to get productive in the summer and have an uptick in productivity and crash in August.</p> <ul> <li><a href="https://codepen.io/davatron5000/pen/RwmpaJE">debug-formdata</a> - Debugging the <code>FormData</code> object with web components and <code>elementInternals</code> is a pain. This help that.</li> <li><a href="https://codepen.io/davatron5000/pen/bGyvWNP">aria-debugger</a> - Scanning for changes in accessibility related props and attributes on a group of elements is a small nightmare, this is a proof of concept to make that easier. I think I need to make walk the DOM tree a bit deeper (three levels deep?) and add shadow DOM support. Sounds like work tho.</li> </ul> <h2>👾 <strong>Video games</strong></h2> <p>I’m struggling with the fact that staying up past my bedtime to play video games is bad for my health. I need to figure out a better way to game.</p> <ul> <li>There was <a href="https://www.dexerto.com/call-of-duty/mw3-warzone-x-mobile-suit-gundam-event-dates-more-2757789/">a Gundam cross-over event in Call of Duty: Warzone</a>, so I broke my rule about never paying money for cosmetics. I look cool in the video game now and it only cost me $20/ea.</li> <li>Got back into <a href="https://www.reachthefinals.com/">The Finals</a>. Looking at the landscape, probably my favorite co-op shooter.</li> </ul> Sat, 29 Jun 2024 21:48:00 +0000 https://daverupert.com/2024/06/vibe-check-33/ https://daverupert.com/2024/06/vibe-check-33/ Sneak Peek: Mundango <p><tt>It’s a secret to everyone! This post is for RSS subscribers only. <a href="https://daverupert.com/rss-club/">Read more about RSS Club</a>. </tt></p> <img src="https://cdn.daverupert.com/posts/2024/mundango.png" alt="Screenshot of a Mundango bingo board" width="1200" height="719"> <p><a href="https://mundango.daverupert.com/" class="button">Play Mundango</a></p> <p>I’ve got something for you. Lately I’ve been getting a lot of joy from life’s small moments; like texting an old friend, seeing a cool bug, or a watching the cardinals zip through my backyard. To nudge my brain towards absorbing more of these mundane pleasures, I built a little game.</p> <p>Mundango is a game about finding life’s normal things. Each day you get a new game of moments to capture and enjoy. It’s up to you how you play. You can play it like Pokémon Go and try to catch ‘em all or you can visit the board at the end of the day for a bit of reflection. Me? I plunk on it when I’ve got a few spare minutes throughout the day.</p> <p>I’ve got a couple feature requests on deck but it’s at a point where I’d love more feedback. <a href="https://mastodon.social/@davatron5000/112611154594927376">The activities were crowdsourced on Mastodon</a> so if you have some more suggestions of small simple moments that bring you joy, I’d love to hear them. Or if you have general ideas about what would this more interesting (e.g., a turtle mascot), let me know.</p> Thu, 20 Jun 2024 13:26:00 +0000 https://daverupert.com/2024/06/sneak-peek-mundango/ https://daverupert.com/2024/06/sneak-peek-mundango/ A common web component learning blunder <p>Through stalking the <a href="https://mastodon.social/tags/webcomponents">#WebComponents</a> hashtag and <a href="https://frontendmasters.com/courses/web-components/">my Frontend Masters course</a>, I’m privy to a lot of developers’ first experiences with web components. There’s a wide range of people digging in, but the most common first-time experience I come across is a developer coming from a classical component framework like React with JSX going straight to writing vanilla Web Components, becoming frustrated, and then deeming web components “not ready for primetime.”</p> <p>Ignoring for a moment that web components <em>do</em> exist in the primetime and power some big and complex primetime web applications like Adobe’s Photoshop for Web, I half-understand this perspective. I understand the desire to not have a major dependency. I hate this bloated <code>node_modules</code> hellhole we’ve built over the last decade and while I’m not a <code>npm install</code> my problems away guy… I think this puritanical approach to dependencies is a misstep when diving into web components for the first time.</p> <p>The analogy I’ve been using is that this is like jumping from a tall 130 kilobyte-story building (ReactDOM) right into the zero kilobyte sewers of web components. If you take anything from this post, please understand this: <em>web components (most likely) weren’t designed for you</em>. Not to dissuade you from using them, but they were <a href="https://blog.domenic.me/the-extensible-web/">purposefully designed</a> to be <a href="https://extensiblewebmanifesto.org/">a low-level bare metal primitive</a> for library authors to build on; they were designed to be used with a library, a thin layer of abstraction butter on top.</p> <p>To understand this disparity further, let’s look at an example of what writing a component in a “modern” framework <em>feels</em> like…</p> <div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code data-lang="js"><span class="c1">// React</span> <span class="k">export</span> <span class="k">default</span> <span class="kd">function</span> <span class="nf">MyApp</span><span class="p">()</span> <span class="p">{</span> <span class="nf">handleClick</span><span class="p">()</span> <span class="p">{</span> <span class="nf">alert</span><span class="p">(</span><span class="dl">'</span><span class="s1">hi</span><span class="dl">'</span><span class="p">)</span> <span class="p">}</span> <span class="k">return </span><span class="p">(</span> <span class="o">&lt;</span><span class="nx">div</span><span class="o">&gt;</span> <span class="o">&lt;</span><span class="nx">h1</span><span class="o">&gt;</span><span class="nx">Welcome</span> <span class="nx">to</span> <span class="nx">my</span> <span class="nx">app</span><span class="o">&lt;</span><span class="sr">/h1</span><span class="err">&gt; </span> <span class="o">&lt;</span><span class="nx">button</span> <span class="nx">onClick</span><span class="o">=</span><span class="p">{</span><span class="nx">handleClick</span><span class="p">}</span><span class="o">&gt;</span><span class="nx">I</span><span class="err">’</span><span class="nx">m</span> <span class="nx">a</span> <span class="nx">button</span><span class="o">&lt;</span><span class="sr">/button</span><span class="err">&gt; </span> <span class="o">&lt;</span><span class="sr">/div</span><span class="err">&gt; </span> <span class="p">);</span> <span class="p">}</span> </code></pre></div></div> <p>Can you do this in vanilla web components? Sure. But it looks like this…</p> <div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code data-lang="js"><span class="c1">// Vanilla web component</span> <span class="kd">const</span> <span class="nx">myAppTmpl</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">template</span><span class="dl">'</span><span class="p">)</span> <span class="nx">myAppTmpl</span><span class="p">.</span><span class="nx">innerHTML</span> <span class="o">=</span> <span class="s2">` &lt;h1&gt;Welcome to my app&lt;/h1&gt; &lt;button&gt;I’m a button&lt;/button&gt; `</span><span class="p">;</span> <span class="kd">class</span> <span class="nc">MyApp</span> <span class="kd">extends</span> <span class="nc">HTMLElement</span> <span class="p">{</span> <span class="nf">constructor</span><span class="p">()</span> <span class="p">{</span> <span class="k">super</span><span class="p">();</span> <span class="k">this</span><span class="p">.</span><span class="nx">_shadowRoot</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nf">attachShadow</span><span class="p">({</span> <span class="na">mode</span><span class="p">:</span> <span class="dl">'</span><span class="s1">open</span><span class="dl">'</span> <span class="p">})</span> <span class="k">this</span><span class="p">.</span><span class="nx">_shadowRoot</span><span class="p">.</span><span class="nf">appendChild</span><span class="p">(</span><span class="nx">myAppTmpl</span><span class="p">.</span><span class="nx">content</span><span class="p">.</span><span class="nf">cloneNode</span><span class="p">(</span><span class="kc">true</span><span class="p">))</span> <span class="k">this</span><span class="p">.</span><span class="nx">_shadowRoot</span> <span class="p">.</span><span class="nf">querySelector</span><span class="p">(</span><span class="dl">'</span><span class="s1">button</span><span class="dl">'</span><span class="p">)</span> <span class="p">.</span><span class="nf">addEventListener</span><span class="p">(</span><span class="dl">'</span><span class="s1">click</span><span class="dl">'</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">handleClick</span><span class="p">);</span> <span class="p">}</span> <span class="nf">handleClick</span><span class="p">()</span> <span class="p">{</span> <span class="nf">alert</span><span class="p">(</span><span class="dl">'</span><span class="s1">hi</span><span class="dl">'</span><span class="p">)</span> <span class="p">}</span> <span class="p">}</span> <span class="nx">customElements</span><span class="p">.</span><span class="nf">define</span><span class="p">(</span><span class="dl">'</span><span class="s1">my-app</span><span class="dl">'</span><span class="p">,</span> <span class="nx">MyApp</span><span class="p">)</span> </code></pre></div></div> <p>This is a boring, imperative set of instructions for building the component with a little bit of <code>dangerouslySetInnerHTML</code><sup class="footnote-ref"><a href="#fn1" id="fnref1">1</a></sup> mixed in there… and ugchk… it sucks. It’s even more verbose with more interactive elements or a slew of reactive props and attributes.</p> <p>Let’s see what 7 kilobytes of Lit gets us….</p> <div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code data-lang="js"><span class="k">import</span> <span class="p">{</span> <span class="nx">LitElement</span><span class="p">,</span> <span class="nx">html</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">lit</span><span class="dl">'</span> <span class="kd">class</span> <span class="nc">MyApp</span> <span class="kd">extends</span> <span class="nc">LitElement</span> <span class="p">{</span> <span class="nf">handleClick</span><span class="p">()</span> <span class="p">{</span> <span class="nf">alert</span><span class="p">(</span><span class="dl">'</span><span class="s1">hi</span><span class="dl">'</span><span class="p">)</span> <span class="p">}</span> <span class="nf">render</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="nx">html</span><span class="s2">` &lt;h1&gt;Welcome to my app&lt;/h1&gt; &lt;button @click=</span><span class="p">${</span><span class="k">this</span><span class="p">.</span><span class="nx">handleClick</span><span class="p">}</span><span class="s2">&gt;I’m a button&lt;/button&gt; `</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="nx">customElements</span><span class="p">.</span><span class="nf">define</span><span class="p">(</span><span class="dl">'</span><span class="s1">my-app</span><span class="dl">'</span><span class="p">,</span> <span class="nx">MyApp</span><span class="p">)</span> </code></pre></div></div> <p>Now we have a component that’s almost identical to the familiar world of JSX but <em>without any Babel transforms or build steps</em>. For 7 kilobytes you get a lot more than some syntactic sugar, you get…</p> <ul> <li>A thin, tree-shakeable layer of abstraction for a modern developer experience</li> <li>Reactive updates without VDOM</li> <li>A more granular component lifecycle with a <code>render()</code> function</li> <li>A cleaner way of registering and using reactive attributes and properties without overloading the <code>attributeChangedCallback</code></li> <li>Template directives like <code>@click</code> for event handling and directives for JavaScript values (arrays, objects, etc).</li> <li>And an <code>html</code> tagged template literal with an under-appreciated superpower ✨ that gives your components atomic updates under-the-hood.</li> </ul> <p>There’s value in learning how bare metal vanilla web components work in the same way there’s value in knowing how <code>Intl.RelativeTimeFormat()</code> works, but you probably want to use <a href="https://day.js.org/">Day.js</a> for your day-to-day work. You can totally <a href="https://hawkticehurst.com/writing/bring-your-own-base-class/">write your own base class abstraction</a> – and I want you to have the <code>JeffElement</code> base class of your dreams, I do – but you may find out (<a href="https://www.abeautifulsite.net/posts/building-custom-elements-with-a-library/">like Cory LaViska from Shoelace found out</a>) that after you write all your little helper functions and utilities that you’ll end up with something almost the exact same size and feature set as Lit, but not as well supported nor as battle-tested.</p> <p>This makes me sound anti-vanilla web components and I’m not that by any means. Vanilla web components are a perfect fit for <a href="https://github.com/davatron5000/awesome-standalones">standalone components</a> and the Light DOM-forward flavor of “<a href="https://adactio.com/journal/20618">HTML web components</a>”, but I think the people having the most fun in this space are JavaScript minimalists who already prefer writing vanilla JavaScript. People like myself.</p> <p>“If I have to use a library how is this any different than any other framework lock-in?” This is a valid question and one worthy of its own post, but I think you’ll find the lock-in costs of a web component library pretty minimal. Because all web components libraries extend a common base class, there’s a linear pathway out of vendor lock-in if necessary.</p> <p>What I’m saying is this; next time you’re thinking about jumping from 130 kilobytes of developer convenience, maybe consider giving yourself a 7 kilobyte landing pad to cushion the fall.</p> <section class="footnotes"> <ol> <li id="fn1"> <p>There’s ways around the <code>innerHTML</code> call like by writing the template in your HTML instead. <a href="#fnref1" class="footnote-backref">↩</a></p> </li> </ol> </section> Tue, 28 May 2024 14:17:00 +0000 https://daverupert.com/2024/05/cold-turkey-wont-fix-your-javascript-addiction/ https://daverupert.com/2024/05/cold-turkey-wont-fix-your-javascript-addiction/ Dave Goes Microsoft <p>Last Monday was my first day as an official employee of Microsoft where I’ll be working on web components as part of the <a href="https://fluent2.microsoft.design/">Fluent</a> design system team. As longtime readers already know, I’ve had a long term relationship with Microsoft – from <a href="https://paravelinc.com/work/microsoft/">Paravel’s 2012 responsive redesign of the Microsoft homepage</a> to the five year <a href="https://daverupert.com/tag/davegoeswindows">#davegoeswindows</a> stunt –  it feels like a new chapter in the career story arc to finally acquire one of the famous blue badges. I’m still new and have barely setup my computer but so far my team of peers, the larger group, the project itself, and the other folks across Microsoft I’ve connected with are all great.</p> <p>Going from a company with two coworkers to a company with 200K coworkers is certainly an adjustment. It’s my first job in 18 years where I’m not working for myself but by far the biggest eye-opener throughout this process was doing tech interviews! I learned a lot about myself; like how after decades of coding in a room by myself, performing in front of someone else isn’t natural for me. Weirdly for me, a live demo in front of thousands of people… no problem. A random generated coding challenge in front of one person… palms sweaty, mom’s spaghetti levels of difficult. I also learned that too much caffeine and the panic-flavored adrenaline of interviewing is a lot of chemistry for my active brain to process.</p> <p>I eventually figured out how to interview and I had a lot of great conversations with great people at great companies. That said, this experience left me with lingering qualms about the tech interview process. A lot of it comes down to the information asymmetry where the seller (the hiring company) has more information than the buyer (the job candidate) and it’s hard to get any feedback for self-improvement. Even in my limited experience, it’s not uncommon to sink 15+ hours into a take home coding test and interview loop only to receive a terse rejection. Granted there’s promise of a six figure salary at the end of the rainbow, these jobs don’t fall out of the sky so you need to put in work, but I think that situation needs to be a bit more equitable to candidates – a Newtonian dynamic of matching effort.</p> <p>One question they ask you at interviews is “What are you looking for in your next role?” and while that sparks thousands of ideas, I boiled my needs and wants down to two core concepts:</p> <ul> <li><strong>Be a part of a larger team of engineers</strong> - I’d like to work on a larger team of developers. I want to be in a situation where I can actively and passively learn from other engineers who are subject matter experts in different subjects. As a life-long learner, I’d like to take myself out of the “lone developer” paradigm and absorb as much as I can.</li> <li><strong>Be tangential to the money machine</strong> - When you run your own business there’s a tight coupling between <em>how much you work</em> and <em>how much money you make</em> and you’re constantly aware of that fact. After 18 years of running my own business and two particularly intense years of startup burnout, I’d like to try something different and play a more supportive operational role for a bit.</li> </ul> <p>I think I found that in Microsoft. There’s a multitude of people I can ping about niche technology choices. There’s even access to a library of research papers. And already I can see how operating in a product support role seems to provide more opportunity for strategy to the broader needs of the organization as opposed to reactivity to the needs <em>du jour</em> that happen in Productland.</p> <p>I’m sure throughput will be a bit slower without direct access to the publish to production button. I’m sure there’s topics I won’t be able to talk about on this here blog (but I tend not to blog about specific work-related activities here anyways so that won’t change). And I’m sure I’ll have to put a disclaimer here and there that these ideas are my own and not reflective of my employer. Henceforth and furthermore all bad ideas are copyright of Dave Rupert LLC®.</p> <p>It’s the end of an era for sure but also the beginning of a new one and potentially the beginning of lots of new ones, who knows. Thanks to Trent and Reagan. Thanks to everyone who provided emotional support on this journey. Thanks to esteemed friends who provided referrals. Given the current macroeconomic situation, I feel lucky to have landed somewhere familiar with great opportunities and many Dave Rupert-shaped problems.</p> Thu, 16 May 2024 14:02:00 +0000 https://daverupert.com/2024/05/dave-goes-microsoft/ https://daverupert.com/2024/05/dave-goes-microsoft/ A quick light-dark() experiment <p>I wanted to experiment with the new CSS function <code>light-dark()</code> and get a sense of how to use it in a CSS architecture of nested (web) components. I think it’s going to be a powerful tool in <a href="https://web.dev/articles/new-responsive">the new responsive</a> world of component architecture but I don’t want to recommend something unless I have experience with it in a project first.</p> <p>My first pass was to add <code>light-dark()</code> to my components…</p> <div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code data-lang="css"><span class="c">/* global.css */</span> <span class="nd">:root</span> <span class="p">{</span> <span class="py">--dark</span><span class="p">:</span> <span class="m">#000</span><span class="p">;</span> <span class="py">--light</span><span class="p">:</span> <span class="m">#fff</span><span class="p">;</span> <span class="p">}</span> <span class="c">/* Inside &lt;my-component&gt;'s Shadow DOM */</span> <span class="nd">:host</span> <span class="p">{</span> <span class="nl">background-color</span><span class="p">:</span> <span class="n">light-dark</span><span class="p">(</span><span class="n">var</span><span class="p">(</span><span class="n">--light</span><span class="p">),</span> <span class="n">var</span><span class="p">(</span><span class="n">--dark</span><span class="p">));</span> <span class="nl">color</span><span class="p">:</span> <span class="n">light-dark</span><span class="p">(</span><span class="n">var</span><span class="p">(</span><span class="n">--dark</span><span class="p">),</span> <span class="n">var</span><span class="p">(</span><span class="n">--light</span><span class="p">));</span> <span class="p">}</span> </code></pre></div></div> <p>But if every component is in charge of it’s own <code>light-dark()</code> handling for <code>border</code>, <code>background</code>, and <code>color</code> on every element… the codebase will get messy managing dark mode in a lot of different places, leading to a lot of inconsistencies over time. A more elegant solution for me would be to handle this job in a single location at the root scope level and leverage the cascade a bit.</p> <div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code data-lang="css"><span class="nd">:root</span> <span class="p">{</span> <span class="py">color-scheme</span><span class="p">:</span> <span class="n">light</span> <span class="n">dark</span><span class="p">;</span> <span class="py">--surface-color</span><span class="p">:</span> <span class="n">light-dark</span><span class="p">(</span> <span class="m">#fff</span><span class="p">,</span> <span class="m">#000</span> <span class="p">);</span> <span class="py">--text-color</span><span class="p">:</span> <span class="n">light-dark</span><span class="p">(</span> <span class="m">#000</span><span class="p">,</span> <span class="m">#fff</span> <span class="p">);</span> <span class="p">}</span> </code></pre></div></div> <p>The nice thing about using <code>light-dark()</code> at the root token level is your components can be dumber. You provide default light-dark experience and, like good children, your components abide in their parent’s decision. Of course, due to the nature of CSS custom properties, your components aren’t locked into the system and your component level styles can opt out (read: not include) or override the global variables if necessary.</p> <div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code data-lang="css"><span class="c">/* Inside &lt;my-component&gt;'s Shadow DOM */</span> <span class="nd">:host</span> <span class="p">{</span> <span class="nl">background</span><span class="p">:</span> <span class="n">var</span><span class="p">(</span><span class="n">--surface-color</span><span class="p">);</span> <span class="nl">color</span><span class="p">:</span> <span class="n">var</span><span class="p">(</span><span class="n">--text-color</span><span class="p">);</span> <span class="p">}</span> <span class="c">/* this is a real example from my past */</span> <span class="nd">:host</span><span class="o">[</span><span class="nt">theme</span><span class="o">=</span><span class="s1">"lunar-new-year"</span><span class="o">]</span> <span class="p">{</span> <span class="py">--surface-color</span><span class="p">:</span> <span class="no">red</span><span class="p">;</span> <span class="py">--text-color</span><span class="p">:</span> <span class="no">black</span><span class="p">;</span> <span class="p">}</span> </code></pre></div></div> <p>At this point in the experiment I was pleased with the results… until I deployed it to production. I overestimated the browser support for <code>light-dark()</code> and it didn’t work on my phone running Safari 17.4 (but it’s coming in Safari 17.5). I replicated the issue by changing <code>light-dark()</code> to <code>light-d0rk()</code> to verify and fixed it by adding a tried-and-true CSS <code>@supports</code> query.</p> <div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code data-lang="css"><span class="nd">:root</span> <span class="p">{</span> <span class="py">--surface-color</span><span class="p">:</span> <span class="m">#000</span><span class="p">;</span> <span class="py">--text-color</span><span class="p">:</span> <span class="m">#fff</span><span class="p">;</span> <span class="c">/* NOTE: For Safari 17.4 (2024-05) */</span> <span class="err">@supports</span> <span class="err">(</span><span class="nl">color</span><span class="p">:</span> <span class="n">light-dark</span><span class="p">(</span><span class="no">black</span><span class="p">,</span> <span class="no">white</span><span class="p">))</span> <span class="err">{</span> <span class="n">color-scheme</span><span class="p">:</span> <span class="n">light</span> <span class="n">dark</span><span class="p">;</span> <span class="py">--surface-color</span><span class="p">:</span> <span class="n">light-dark</span><span class="p">(</span> <span class="m">#fff</span><span class="p">,</span> <span class="m">#000</span> <span class="p">);</span> <span class="py">--text-color</span><span class="p">:</span> <span class="n">light-dark</span><span class="p">(</span> <span class="m">#000</span><span class="p">,</span> <span class="m">#fff</span> <span class="p">);</span> <span class="p">}</span> <span class="err">}</span> </code></pre></div></div> <p>Now Safari 17.4 and other browsers that lack support will only have a dark theme and newer browsers will get the <code>light-dark()</code> enhancement. I also threw a little <code>NOTE:</code> and datestamp in there so future versions of me will know when and <a href="https://frontendmasters.com/blog/you-want-border-color-transparent-not-border-none/">why I built this fence</a>.</p> Sun, 05 May 2024 15:27:00 +0000 https://daverupert.com/2024/05/light-dark-experiment/ https://daverupert.com/2024/05/light-dark-experiment/