<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://mattj.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://mattj.io/" rel="alternate" type="text/html" /><updated>2025-04-09T05:05:58+00:00</updated><id>https://mattj.io/feed.xml</id><title type="html">Matt Joseph</title><subtitle>Matt Joseph - Engineering leader, geek, photographer, cook, creator, and more.
</subtitle><entry><title type="html">Framing engineering discussions with a business perspective</title><link href="https://mattj.io/posts/2024-04-09-framing-engineering-with-business/" rel="alternate" type="text/html" title="Framing engineering discussions with a business perspective" /><published>2024-04-09T00:00:00+00:00</published><updated>2024-04-09T00:00:00+00:00</updated><id>https://mattj.io/posts/framing-engineering-with-business</id><content type="html" xml:base="https://mattj.io/posts/2024-04-09-framing-engineering-with-business/"><![CDATA[<h1 id="framing-engineering-discussions-with-a-business-perspective">Framing engineering discussions with a business perspective</h1>

<p>Tuesday, April 9, 2024</p>

<p><a href="/posts/">Click here to go to all posts</a>.</p>

<p>As software engineers, we often focus on “what” to build and “how” to do it. Yet “why” is an important question, often left to other roles like product managers or business leads. In many cases, software engineers aren’t expected to consider the business in their engineering decisions until more senior levels.</p>

<p>Is it surprising? No. After all, we probably shouldn’t expect every engineer to think about business-critical impact or top-line/bottom-line impact during their day-to-day work. Even for line managers, the expectation is often on execution rather than any personal impact on business metrics.</p>

<p>However, this lack of emphasis does not mean that engineers at all levels should avoid using, or be deprived of, business framing. That’s what this doc is about: framing engineering discussions with a business perspective, with the purpose of guiding, simplifying, and expediting those discussions.</p>

<h2 id="starting-with-users">Starting with users</h2>

<p>Often, engineers feel deeply connected with a focus on the user. Incorporating business perspectives into engineering discussions is an important way to incorporate user-centered product development into everyday decision making.</p>

<p>To some, this may seem counterintuitive. It can seem that “focus on the user” is antithetical to requiring products to have sustainable plans that involve balancing benefit and cost.</p>

<p>For any company, users and customers are ultimately people. Even business customers are made up of people.</p>

<p>Those people are trusting us to provide them with solutions to better their lives and enable their business; they are relying on us. We must respect them by understanding their needs through evidence-based research and only pursuing and offering solutions that we can afford to support long term and with appropriate amounts of risk to where you work and your customers.</p>

<p>We should start small and commit only to implementing, QAing, launching, and supporting work that we understand and can staff, while experimenting with new work in ways that don’t put our customers’ experiences or businesses at risk. Often, what may seem easy to implement with huge upside may be prohibitively expensive to productionize and maintain.</p>

<h2 id="simple-business-framing">Simple business framing</h2>

<h3 id="framing-benefits">Framing benefits</h3>

<p>While there are certainly many other framing mechanisms, authoritative texts, and expert sources out there, I choose to use these areas for categorizing the benefits of any given engineering work:</p>

<ul>
  <li>Generate revenue and positive outcomes</li>
  <li>Generate opportunities</li>
  <li>Reduce or mitigate cost</li>
  <li>Avoid cost</li>
</ul>

<p>What do each of these mean?</p>

<p><strong>Generating revenue and positive outcomes</strong> is straightforward: does this positively impact some one/customer/organization in a way that matters to them and—in a for-profit environment—does it cause increased revenue?</p>

<p><strong>Generating opportunities</strong> is interesting. Opportunity can be a variety of things: future business leads, future users, future product features, future revenue, increased resources/capacity, problems we can solve, etc. The premise is that the work is not directly generating those things, but it is producing a prerequisite for those things to happen.</p>

<p><strong>Reducing and mitigating cost</strong> is straightforward as well. If cost is X now, and is less than X once the work is done, then X has reduced cost. There’s some nuance here about implementation costs, recurring costs, and such, but those are best left for later.</p>

<p><strong>Avoiding cost</strong> is even better than reducing costs, as it focuses on building a sustainable business. One could say that it is the cost that might have otherwise occurred had the work not been done. A great example of this is risk: by doing the right safety, security, and related work, businesses avoid costs to themselves and their users. Often, this work is the hardest to highlight and reward, similar to encouraging building inspection rather than exclusively relying on firefighters.</p>

<h3 id="framing-costs">Framing costs</h3>

<p>I also do an exercise of framing costs for any engineering discussion. In an effort to avoid a real finance conversation at every turn, I tend to simplify* to these categories:</p>

<ul>
  <li>Implementation cost</li>
  <li>Maintenance cost</li>
  <li>Risk cost</li>
  <li>Opportunity cost</li>
</ul>

<p><em>*A note on costs: this is an incredibly simplified view to be useful for engineering discussions. If you’re curious, I encourage further reading on the costs of running a business.</em></p>

<p>What do each of these mean?</p>

<p><strong>Implementation cost</strong> refers to the cost of initial implementation, including the time and resources used by engineers, product managers, UX designers, quality assurance (QA), technical program managers, and anyone else involved.</p>

<p><strong>Maintenance cost</strong> refers to what it takes to keep the implementation running as is. This includes ongoing QA, support, account management, developer relations (DevRel), site reliability engineering (SRE), on-call, engineering maintenance, general upkeep, and more.</p>

<p><strong>Risk cost</strong> is the cost associated with any possible risks, such as security, accessibility, privacy, brand perception, liability, and more. These ultimately represent a potential cost to our business.</p>

<p><strong>Opportunity cost</strong> has a lot of available definitions (example: <a href="https://en.wikipedia.org/wiki/Opportunity_cost" target="_blank" rel="noopener">Wikipedia</a>). Essentially, it’s what we lose from alternative opportunities by going with the option we settled on.</p>

<h2 id="common-examples">Common examples</h2>

<h3 id="the-pile-of-tech-debt">The pile of tech debt</h3>

<p>“Let’s refactor service X!”, someone says. “We made some serious tradeoffs for launch. We need to get rid of this tech debt before it becomes a problem.”</p>

<p>Let’s examine this case more closely. What is the problem?</p>

<ul>
  <li>Is the tech debt preventing the development of critical feature X? → sounds like this work is related to <strong>generating revenue and positive outcomes</strong>.</li>
  <li>Cleaning up this tech debt will create room for innovation and lead to increased inbound customer leads. → looks like we want to <strong>generate more opportunities</strong>.</li>
  <li>The tech debt is taking 20% of the team’s sprints to maintain. → that’s a <strong>cost reduction</strong> argument at its core.</li>
  <li>Is the code unstable, liable to break with dependency changes? → sounds like we’re trying to reduce risk and <strong>avoid a cost</strong>.</li>
</ul>

<p>And how much will it cost to solve this problem?</p>

<ul>
  <li>It’s going to take 3 engineer-months to clean up this tech debt. → straightforward <strong>implementation cost of cleaning up the tech debt</strong>.</li>
  <li>Doing this cleanup will require careful attention to detail so we don’t break any existing features and don’t open up any security or privacy issues. → there might be a lot of <strong>risk cost associated with this tech debt cleanup work</strong>.</li>
  <li>Due to this tech debt cleanup, we’re not going to be able to deliver critical features X and Y to customers and we’re going to have to ignore some business opportunities. → That’s some serious <strong>opportunity cost associated with this cleanup</strong>.</li>
</ul>

<p>In other words, whether or not cleaning up this pile of tech debt is not just a technical conversation, it’s a business conversation with several dimensions. By using business framing, engineers can work towards expressing the need to clean up tech debt in more collaborative ways. It may turn out that—when framed in business terms—tech debt is more impactful to the business than the equivalent feature work.</p>

<h3 id="the-aspirational-design">The aspirational design</h3>

<p>“I need to write a detailed design doc,” the engineer says. “We have to ensure that we are architecturally prepared for all of the users/customers/use cases we will have. Then we need to spend several quarters <em>getting it right</em>, otherwise we’re in trouble.”</p>

<p>This is a great example of the <a href="https://en.wikipedia.org/wiki/Nirvana_fallacy" target="_blank" rel="noopener">nirvana fallacy</a>. Nothing short of perfect will suffice; we must <em>get it right, or else</em>.</p>

<p>A way to avoid this fallacy is to combine two things:</p>

<ul>
  <li>Evaluate the design fairly.</li>
  <li>Genuinely consider bona fide alternatives.</li>
</ul>

<p>The business framing we’ve touched on is a great way to expand the advantages and disadvantages of a given design to cover more than the purely technical aspects.</p>

<p>Let’s start with translating some of the benefits:</p>

<ul>
  <li>Does this design or an alternative result in a greater impact to our bottom line or our customer’s experience? → sounds like we’re trying to <strong>generate more revenue or increase the net positive outcome</strong>.</li>
  <li>Does this design provide a platform for future features and future business? → That might be some clear line of sight to <strong>generating more opportunities</strong>.</li>
  <li>Does this design mean we can build X, Y, and Z features with faster and cheaper going forward? → We’re trying to <strong>reduce our implementation costs in general</strong>.</li>
  <li>Does this design or an alternative present more risk to our team, product, company, users, or the world? → we’re trying to <strong>avoid the cost of those risks</strong> turning into reality, or at the very least, <strong>reduce/mitigate the likelihood of those costs</strong>.</li>
</ul>

<p>Let’s look at some possible costs as well.</p>

<ul>
  <li>We need to spend an entire quarter designing this solution, evaluating prototypes, and reviewing with the team. → Time spent designing is <strong>a significant implementation cost</strong>.</li>
  <li>Once implemented, this design will require any new engineer on the team to learn a bespoke way of building services/UI/etc. → Overhead created by a design is <strong>an ongoing maintenance cost</strong>, even if it’s not maintenance of the implementation itself.</li>
  <li>By doing this design, we’ll get an accessibility exception because other roles have asked us to create custom UX that doesn’t include built-in accessibility (a11y) features. → This <strong>design has a risk cost</strong> associated with it because it chooses to take on a11y risk.</li>
  <li>We can’t do this iteratively, it needs to be done all at once. → By eliminating more iterative alternatives that deliver value sooner, this <strong>design has a possible opportunity cost</strong>.</li>
</ul>

<p>As part of a well-reasoned design doc, consider a tabular view comparing the preferred option with the alternatives, not only showing the technical characteristics, but also the business benefits and costs as well.</p>

<h3 id="the-long-list-of-medium-priority-issues">The long list of medium priority issues</h3>

<p>“I know these aren’t absolutely essential to our product,” the tech lead says, “but we have so many things we really, really need to do to fully call this project ‘done’.”</p>

<p>Sometimes, it seems like a project or feature never ends. There’s a never ending list of medium priority bugs, cleanups, enhancements, and docs that <em>should</em> get done. Where do we draw the line?</p>

<p>Formulating the discussion in business terms will help draw that line using language that anyone in any role can participate in and understand. Let’s look at some examples.</p>

<ul>
  <li>Fixing this open bug will improve our click-through rate (CTR) by 50% for 90% of users. → Sounds like this fix will directly <strong>generate more revenue</strong>.</li>
  <li>We need to address these specific medium priority issues because they are a prerequisite for other deal-critical features. → These high priority features are <strong>generating the opportunity</strong> to deliver other business-critical features.</li>
  <li>By implementing this medium priority feature, we’ll reduce the cost to our internal users by 20%. → <strong>Reducing costs to other internal roles</strong> can be just as important as reducing engineering costs.</li>
  <li>These medium priority issues will take 2 engineer-months. If we don’t do them, we’re going to have to bring on additional headcount. → We’d like to <strong>avoid a larger cost</strong> by paying a smaller cost up front.</li>
</ul>

<p>Along with the benefits of looking at this long list of medium priority issues, we can also look at the costs associated with addressing them.</p>

<ul>
  <li>It’s going to take four engineer-quarters to get all of these medium priority issues done. → That’s a lot of potential <strong>implementation cost</strong> to balance against the benefits.</li>
  <li>When we launch these medium priority features, we’ll need additional on-call support and 50 new QA test cases to keep them stable. → QA and on-call are a form of <strong>ongoing maintenance cost</strong> for these issues that might not be part of initial implementation.</li>
  <li>This is just a small medium priority change that fixes some long-standing quirks with our store page. → Those quirks might be indicative of complex country-specific payments requirements and trying to fix those without care might create additional <strong>commerce risk cost</strong>.</li>
  <li>Can we work on these medium priority issues instead of the high priority issues? They’ve just been sitting in our backlog for so long! → Perhaps those medium priority items are actually high priority and should be reevaluated, or the <strong>opportunity cost</strong> from not working on the high priority issues is too high.</li>
</ul>

<h2 id="putting-this-into-practice">Putting this into practice</h2>

<p>With all this background, the question becomes: how does one put this into practice in day-to-day engineering discussions?</p>

<p>Here are three places to start:</p>

<ul>
  <li><strong>In general conversations</strong>: consider framing your points with the business perspective, similar to the examples we’ve walked through.</li>
  <li><strong>In designs</strong>: fairly evaluate the options in terms of their business benefits and costs, in addition to their technical benefits and cost.</li>
  <li><strong>In planning, goals, and OKRs</strong>: consider defining the measurable outcome of yearly plans, goals, or Objectives and Key Results in terms of business benefit. Additionally, you consider how to translate the organization-level plans/goals/OKRs into team-level plans/goals/OKRs using this framing.</li>
</ul>

<p>Need a template for your design doc? Here’s a quick place to start:</p>

<table class="comparison-table">
  <thead>
    <tr>
      <th style="text-align: left">Factor (Benefit or Cost)</th>
      <th style="text-align: left">(A) Option title A</th>
      <th style="text-align: left">(B) Option title B</th>
      <th style="text-align: left">Approach to measuring (examples)</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left">[Benefit:Revenue] TODO</td>
      <td style="text-align: left">TODO. E.g., Yes, No, High, Low, NUMBER</td>
      <td style="text-align: left">TODO. E.g., Yes, No, High, Low, NUMBER</td>
      <td style="text-align: left">- DAU/MAU for X<br />- CSAT/NPS for X<br />- Onboarding time for X<br />- etc.</td>
    </tr>
    <tr>
      <td style="text-align: left">[Benefit:Opportunity] TODO</td>
      <td style="text-align: left">TODO. E.g., Yes, No, High, Low, NUMBER</td>
      <td style="text-align: left">TODO. E.g., Yes, No, High, Low, NUMBER</td>
      <td style="text-align: left">- User interest<br />- Future features powered<br />- Leads generation<br />- % increase capacity<br />- etc.</td>
    </tr>
    <tr>
      <td style="text-align: left">[Benefit:Reduce cost] TODO</td>
      <td style="text-align: left">TODO. E.g., Yes, No, High, Low, NUMBER</td>
      <td style="text-align: left">TODO. E.g., Yes, No, High, Low, NUMBER</td>
      <td style="text-align: left">- engineer-week reduction<br />- {Role}-hours reduction<br />- QA time reduction<br />- etc.</td>
    </tr>
    <tr>
      <td style="text-align: left">[Benefit:Avoid cost] TODO</td>
      <td style="text-align: left">TODO. E.g., Yes, No, High, Low, NUMBER</td>
      <td style="text-align: left">TODO. E.g., Yes, No, High, Low, NUMBER</td>
      <td style="text-align: left">- engineer-week maintenance cost avoided<br />- QA time avoided<br />- # OMGs avoided<br />- etc.</td>
    </tr>
    <tr>
      <td style="text-align: left">[Cost:Implementation] TODO</td>
      <td style="text-align: left">TODO. E.g., Yes, No, High, Low, NUMBER</td>
      <td style="text-align: left">TODO. E.g., Yes, No, High, Low, NUMBER</td>
      <td style="text-align: left">- engineer-weeks cost<br />- product manager-weeks cost<br />- QA-weeks cost<br />- etc.</td>
    </tr>
    <tr>
      <td style="text-align: left">[Cost:Maintenance] TODO</td>
      <td style="text-align: left">TODO. E.g., Yes, No, High, Low, NUMBER</td>
      <td style="text-align: left">TODO. E.g., Yes, No, High, Low, NUMBER</td>
      <td style="text-align: left">- engineer-weeks cost<br />- product manager-weeks cost<br />- QA-weeks cost<br />- etc.</td>
    </tr>
    <tr>
      <td style="text-align: left">[Cost:Risk] TODO</td>
      <td style="text-align: left">TODO. E.g., Yes, No, High, Low, NUMBER</td>
      <td style="text-align: left">TODO. E.g., Yes, No, High, Low, NUMBER</td>
      <td style="text-align: left">- a11y exceptions in # of issues<br />- Security risks in CVE count<br />- Brand risk in NPS<br />- etc.</td>
    </tr>
    <tr>
      <td style="text-align: left">[Cost:Opportunity] TODO</td>
      <td style="text-align: left">TODO. E.g., Yes, No, High, Low, NUMBER</td>
      <td style="text-align: left">TODO. E.g., Yes, No, High, Low, NUMBER</td>
      <td style="text-align: left">- Number of missed opportunities<br />- Number of features not built<br />- Number of users not gained<br />- etc.</td>
    </tr>
  </tbody>
</table>

<p><em><strong>Note</strong>: Per a11y best practices, use text to differentiate and treat colors as optional!</em></p>

<div class="center width30">
<figure class="fill-parent">
  <picture>
  <source type="image/avif" srcset="/images/posts/2024-04-09-framing-engineering-with-business/2024-04-09-hero.avif" />
    <source type="image/png" srcset="/images/posts/2024-04-09-framing-engineering-with-business/2024-04-09-hero.png" />
    <img src="/images/posts/2024-04-09-framing-engineering-with-business/2024-04-09-hero.png" width="1000" height="750" alt="An image representing software development" class="responsive" />
  </picture>
  <figcaption class="center">An image representing software development</figcaption>
</figure>
</div>]]></content><author><name></name></author><summary type="html"><![CDATA[Framing engineering discussions with a business perspective, with the purpose of guiding, simplifying, and expediting those discussions.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://mattj.io/images/posts/2024-04-09-framing-engineering-with-business/2024-04-09-hero.png" /><media:content medium="image" url="https://mattj.io/images/posts/2024-04-09-framing-engineering-with-business/2024-04-09-hero.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">The nuances of base64 encoding strings in JavaScript</title><link href="https://mattj.io/posts/2023-10-17-base64-encoding/" rel="alternate" type="text/html" title="The nuances of base64 encoding strings in JavaScript" /><published>2023-10-17T00:00:00+00:00</published><updated>2023-10-17T00:00:00+00:00</updated><id>https://mattj.io/posts/base64-encoding</id><content type="html" xml:base="https://mattj.io/posts/2023-10-17-base64-encoding/"><![CDATA[<h1 id="the-nuances-of-base64-encoding-strings-in-javascript">The nuances of base64 encoding strings in JavaScript</h1>

<p>Tuesday, October 17, 2023</p>

<p><a href="/posts/">Click here to go to all posts</a>.</p>

<p>I wrote an article for Web.dev titled <a href="https://web.dev/articles/base64-encoding" target="_blank" rel="noopener"><em>The nuances of base64 encoding strings in JavaScript</em></a>. In the post, cover various cases of base64 encoding and decoding strings in JavaScript, including some edge cases that folks may not be aware of.</p>

<p>A backup of the post is available from the <a href="https://web.archive.org/web/20240221150328/https://web.dev/articles/base64-encoding" target="_blank" rel="noopener">Internet Archive</a>.</p>

<div class="center width30">
<figure class="fill-parent">
  <a href="/images/posts/2023-10-17/web-dev-post.png" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2023-10-17/web-dev-post.avif" />
      <source type="image/png" srcset="/images/posts/2023-10-17/web-dev-post.png" />
      <img src="/images/posts/2023-10-17/web-dev-post.png" width="1920" height="1280" alt="Screenshot of the post on web.dev" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">Screenshot of the post on web.dev</figcaption>
</figure>
</div>]]></content><author><name></name></author><summary type="html"><![CDATA[What happens when you apply base64 encoding and decoding to strings in JavaScript? This post explores the nuances and common pitfalls to avoid.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://mattj.io/images/posts/2023-10-17/web-dev-post.png" /><media:content medium="image" url="https://mattj.io/images/posts/2023-10-17/web-dev-post.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Quirks of the Page Visibility API</title><link href="https://mattj.io/posts/2023-02-01-page-visibility-api/" rel="alternate" type="text/html" title="Quirks of the Page Visibility API" /><published>2023-02-01T00:00:00+00:00</published><updated>2023-02-01T00:00:00+00:00</updated><id>https://mattj.io/posts/page-visibility-api</id><content type="html" xml:base="https://mattj.io/posts/2023-02-01-page-visibility-api/"><![CDATA[<h1 id="quirks-of-the-page-visibility-api">Quirks of the Page Visibility API</h1>

<p>Wednesday, February 1, 2023</p>

<p><a href="/posts/">Click here to go to all posts</a>.</p>

<p>The <a href="https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API" target="_blank" rel="noopener">Page Visibility API</a> is a useful tool for web developers to detect whether a page is visible to a user or not, as well as understand when transitions between those states take place.</p>

<p>When using this API, it is important to understand the limitations in what you can/cannot detect. There are many situations where a developer might consider a page to be “hidden” yet the API will not detect the state as such.</p>

<p>I did some lightweight testing on a few operating systems and browsers, covering scenarios on each that are common for users.</p>

<h2 id="testing-methodology">Testing methodology</h2>

<p>This is not a rigorous lab test. There is a convenient testing page located <a href="https://testdrive-archive.azurewebsites.net/Performance/PageVisibility/Default.html" target="_blank" rel="noopener">here</a>.</p>

<div class="center width70">
<figure class="fill-parent">
  <a href="/images/posts/2023-02-01-page-visibility/page-visibility-api.jpg" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2023-02-01-page-visibility/page-visibility-api.avif" />
      <source type="image/jpeg" srcset="/images/posts/2023-02-01-page-visibility/page-visibility-api.jpg" />
      <img src="/images/posts/2023-02-01-page-visibility/page-visibility-api.jpg" width="1000" height="750" alt="Screenshot of the Page Visibility API tool" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">Screenshot of the Page Visibility API tool</figcaption>
</figure>
</div>

<p>The page was visually inspected to ascertain whether or not the visibility change was detected. In this demo, green segments of the line indicate a visible page and red segments indicate a hidden page, according to the Page Visibility API.</p>

<h2 id="testing">Testing</h2>

<h3 id="macos-131">macOS 13.1</h3>

<p><strong>Chrome 109</strong></p>

<ul>
  <li><strong>Detected via Page Visibility API</strong>: Browser window minimized, browser window covered by another window that is larger, tab hidden in an active browser window, docking/undocking a tab to a browser window, switched to a different desktop,</li>
  <li><strong>Not detected via Page Visibility API</strong>: Browser window covered by another browser window that is the same size or smaller, show desktop via F11 or swipe on touchpad, opening Launchpad, opening Mission Control, dragging the window in Mission Control, browser dialogs (print, save, etc.), during animation to/from full screen</li>
</ul>

<p><strong>Safari 16.2</strong></p>

<ul>
  <li><strong>Detected via Page Visibility API</strong>: Browser window minimized, browser window covered by another window that is larger, tab hidden in an active browser window, switched to a different desktop, during animation to/from full screen</li>
  <li><strong>Not detected via Page Visibility API</strong>: Browser window covered by another browser window that is the same size or smaller, show desktop via F11 or swipe on touchpad, opening Launchpad, opening Mission Control, dragging the window in Mission Control, browser dialogs (print, save, etc.), docking/undocking a tab to a browser window, tab overview</li>
</ul>

<h3 id="windows-10-pro">Windows 10 Pro</h3>

<p><strong>Chrome 109</strong></p>

<ul>
  <li><strong>Detected via Page Visibility API</strong>: Browser window minimized, browser window covered by another window that is larger, browser window covered by another browser window that is the same size, tab hidden in an active browser window, docking/undocking a tab to a browser window</li>
  <li><strong>Not detected via Page Visibility API</strong>: Browser window covered by another browser window that is smaller, browser dialogs (print, save, etc.), during animation to/from full screen, during Task View</li>
</ul>

<h3 id="android-13">Android 13</h3>

<p><strong>Chrome 109</strong></p>

<ul>
  <li><strong>Detected via Page Visibility API</strong>: Another app is active on the screen, another Chrome tab is active on the screen, screen is off, Chrome tab overview as an inactive tab, split screen: entering split screen, going to other features in Chrome (Downloads, Settings, etc.)</li>
  <li><strong>Not detected via Page Visibility API</strong>: Android overview mode, Chrome tab overview while the active tab, split screen: redrawing when split changes, split screen: exiting split screen, Assistant overlay on screen, URL entry mode, during the swipe between tabs, while covered by the notification shade</li>
</ul>

<h3 id="ipad-os-163">iPad OS 16.3</h3>

<p><strong>Chrome 109</strong></p>

<ul>
  <li><strong>Detected via Page Visibility API</strong>: Another app is active on the screen, another Chrome tab is active on the screen, screen is off, Chrome tab overview (all times), going to other features in Chrome (Downloads, Settings, etc.)</li>
  <li><strong>Not detected via Page Visibility API</strong>: Some dialogs (Bookmarks, Reading List, Password Manager, etc.), iPad OS overview screen (swipe up), Control Panel covering screen, Notification Center down, split view: selecting another app, split view: redrawing when split changes, split view: exiting split view, accessing camera from the Notification Center</li>
</ul>

<p><strong>Safari 16.3</strong></p>

<ul>
  <li><strong>Detected via Page Visibility API</strong>: Another app is active on the screen, another Safari tab is active on the screen, screen is off, Safari tab overview as an inactive tab</li>
  <li><strong>Not detected via Page Visibility API</strong>: Some dialogs (Bookmarks, Reading List, Password Manager, etc.), iPad OS overview screen (swipe up), Control Panel covering screen, Notification Center down, split view: selecting another app, split view: redrawing when split changes, split view: exiting split view, Safari tab overview as the active tab, accessing camera from the Notification Center</li>
</ul>

<p><strong>Note</strong>: for testing purposes, I did not use an iOS device, but iPad OS is a reasonable proxy for what might be encountered on iOS.</p>

<h2 id="noteworthy-observations">Noteworthy observations</h2>

<p>There are a few interesting results in this testing:</p>

<ul>
  <li>On iPad OS, you can access the camera and take photos from the Notification Center, and none of this will be detected as hiding the page in Chrome or Safari.</li>
  <li>Operating system-level overview generally isn’t considered hiding the page.</li>
  <li>Whether or not a page will be considered “hidden” in the tab overview depends on the tab’s active/inactive state and which browser you’re using.</li>
  <li>Split screen/split view has OS-specific nuances.</li>
</ul>

<h2 id="video-demo-on-android">Video demo on Android</h2>

<p>I recorded a demo of some of the cases I tested on Android 13:</p>

<div class="center width30">
<figure class="fill-parent">
  <video playsinline="" autoplay="" loop="" muted="" width="332" height="720" class="responsive" title="Demo of the Page Visibility API on Android 13">
    <source src="/images/posts/2023-02-01-page-visibility/demo_video_vp9.webm" type="video/webm" />
    <source src="/images/posts/2023-02-01-page-visibility/demo_video_h264.mp4" type="video/mp4" />
    <div fallback="">
      <p>This browser does not support the video element.</p>
    </div>
  </video>
  <figcaption class="center">Demo of the Page Visibility API on Android 13</figcaption>
</figure>
</div>]]></content><author><name></name></author><summary type="html"><![CDATA[Exploring the quirks of the Page Visibility API across platforms and browsers.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://mattj.io/images/posts/2023-02-01-page-visibility/page-visibility-api.jpg" /><media:content medium="image" url="https://mattj.io/images/posts/2023-02-01-page-visibility/page-visibility-api.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Extending Stadia’s app architecture to more devices</title><link href="https://mattj.io/posts/2022-08-02-extending-stadias-app-architecture-to-more-devices/" rel="alternate" type="text/html" title="Extending Stadia’s app architecture to more devices" /><published>2022-08-02T00:00:00+00:00</published><updated>2022-08-02T00:00:00+00:00</updated><id>https://mattj.io/posts/extending-stadias-app-architecture-to-more-devices</id><content type="html" xml:base="https://mattj.io/posts/2022-08-02-extending-stadias-app-architecture-to-more-devices/"><![CDATA[<h1 id="extending-stadias-app-architecture-to-more-devices">Extending Stadia’s app architecture to more devices</h1>

<p>Tuesday, August 2, 2022</p>

<p><a href="/posts/">Click here to go to all posts</a>.</p>

<p>I wrote a post for the Stadia Dev Blog titled <a href="https://stadia.dev/blog/extending-stadia-s-app-architecture-to-more-devices/" target="_blank" rel="noopener"><em>Extending Stadia’s app architecture to more devices</em></a>. In the post, I share updates to the Stadia TV app architecture with the launches on LG and Samsung TVs.</p>

<p>A backup of the post is available from the <a href="https://web.archive.org/web/20221005115956/https://stadia.dev/intl/en/blog/extending-stadia-s-app-architecture-to-more-devices/" target="_blank" rel="noopener">Internet Archive</a>.</p>

<div class="center width30">
<figure class="fill-parent">
  <a href="/images/posts/2022-08-02/App_arch_view.png" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2022-08-02/App_arch_view.avif" />
      <source type="image/png" srcset="/images/posts/2022-08-02/App_arch_view.png" />
      <img src="/images/posts/2022-08-02/App_arch_view.png" width="1920" height="1280" alt="A simplified view of the architecture on living room devices" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">A simplified view of the architecture on living room devices</figcaption>
</figure>
</div>]]></content><author><name></name></author><summary type="html"><![CDATA[With Stadia’s expansion to new living room devices, such as LG Smart TVs and Samsung Smart TVs, we wanted to provide a brief update on our living room app architecture. Let’s jump in!]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://mattj.io/images/posts/2022-08-02/App_arch_view.png" /><media:content medium="image" url="https://mattj.io/images/posts/2022-08-02/App_arch_view.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Talk - Contributing to open source: Taking your first (empathetic) step</title><link href="https://mattj.io/posts/2022-04-07-comcast-sstx-open-source-presentation/" rel="alternate" type="text/html" title="Talk - Contributing to open source: Taking your first (empathetic) step" /><published>2022-04-07T00:00:00+00:00</published><updated>2022-04-07T00:00:00+00:00</updated><id>https://mattj.io/posts/comcast-sstx-open-source-presentation</id><content type="html" xml:base="https://mattj.io/posts/2022-04-07-comcast-sstx-open-source-presentation/"><![CDATA[<h1 id="talk---contributing-to-open-source-taking-your-first-empathetic-step">Talk - Contributing to open source: Taking your first (empathetic) step</h1>

<p>Thursday, April 7, 2022</p>

<p><a href="/posts/">Click here to go to all posts</a>.</p>

<p>On April 7, 2022, I gave a talk titled <em>Contributing to open source: Taking your first (empathetic) step</em> at an internal Comcast event called SSTx, which is an event for the Software Strategy &amp; Transformation (SST) organization. The theme of the event was “Breaking out of your shell”.</p>

<div class="center width70">
<figure class="fill-parent">
  <a href="/dl/2022-04-07/2022-04-07%20-%20Matt%20Joseph%20-%20Contributing%20to%20open%20source%20Taking%20your%20first%20(empathetic)%20step.pdf" target="_blank" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2022-04-07/2022-04-07-slides-title.avif" />
      <source type="image/jpeg" srcset="/images/posts/2022-04-07/2022-04-07-slides-title.jpg" />
      <img src="/images/posts/2022-04-07/2022-04-07-slides-title.jpg" width="1920" height="1080" alt="Title slide of the presentation" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">Title slide of the presentation</figcaption>
</figure>
</div>

<p>The slides from this talk are available as <a href="/dl/2022-04-07/2022-04-07%20-%20Matt%20Joseph%20-%20Contributing%20to%20open%20source%20Taking%20your%20first%20(empathetic)%20step.pdf" target="_blank">a PDF download</a>.</p>

<p>Note: these slides are a visual aid intended to accompany a spoken talk, so they may not include the full context at all times.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[Talk - Contributing to open source: Taking your first (empathetic) step]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://mattj.io/images/posts/2022-04-07/2022-04-07-slides-title.jpg" /><media:content medium="image" url="https://mattj.io/images/posts/2022-04-07/2022-04-07-slides-title.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Custom foam for the Drop CTRL keyboards (SVG file download)</title><link href="https://mattj.io/posts/2021-12-29-drop-ctrl-foam-layout/" rel="alternate" type="text/html" title="Custom foam for the Drop CTRL keyboards (SVG file download)" /><published>2021-12-29T00:00:00+00:00</published><updated>2021-12-29T00:00:00+00:00</updated><id>https://mattj.io/posts/drop-ctrl-foam-layout</id><content type="html" xml:base="https://mattj.io/posts/2021-12-29-drop-ctrl-foam-layout/"><![CDATA[<h1 id="custom-foam-for-the-drop-ctrl-keyboards-svg-file-download">Custom foam for the Drop CTRL keyboards (SVG file download)</h1>

<p>Wednesday, December 29, 2021</p>

<p><a href="/posts/">Click here to go to all posts</a>.</p>

<p>I decided to create custom foam for the Drop CTRL high profile and Drop CTRL low profile cases that I had on hand. I have previously hand-cut foam, but to speed things up, I decided to laser cut the foam.</p>

<ul>
  <li>Material: 3mm EVA foam (you can probably use 4mm foam but with different speed/power settings)</li>
  <li>Laser settings on a 100w CO<sub>2</sub> laser:
    <ul>
      <li>Cutting: 70mm/s 15% power</li>
      <li>Engraving (text): 250mm/s 10% power</li>
    </ul>
  </li>
  <li>Software used: Inkscape and Lightburn</li>
</ul>

<p><strong>NOTE: I designed these using Drop CTRL keyboards purchased in 2020. Drop may change the design of these keyboards in the future and these files may no longer be accurate.</strong></p>

<h2 id="svg-downloads">SVG downloads</h2>

<p>I chose to design my own layouts for the foam. I did not find any online that met my requirements.</p>

<p>These SVGs are available for you to use to cut your own foam. I designed these layouts based on the physical keyboards and my handy calipers. The SVGs are licensed under a <a href="http://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank" rel="noopener">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.</p>

<p>By downloading these files, you agree to the CC BY-NC-SA 4.0 license. If you use or modify these files, link to this page.</p>

<ul>
  <li><a href="/dl/2021-12-29-foam/Drop%20CTRL%20High%20Profile%20Case%20Foam.svg" target="_blank">Download the Drop CTRL High Profile Case Foam Layout</a></li>
  <li><a href="/dl/2021-12-29-foam/Drop%20CTRL%20High%20Profile%20Plate%20Foam.svg" target="_blank">Download the Drop CTRL High Profile Plate Foam Layout</a></li>
  <li><a href="/dl/2021-12-29-foam/Drop%20CTRL%20Low%20Profile%20Case%20Foam.svg" target="_blank">Download the Drop CTRL Low Profile Case Foam Layout</a></li>
  <li><a href="/dl/2021-12-29-foam/Drop%20CTRL%20Low%20Profile%20Plate%20Foam.svg" target="_blank">Download the Drop CTRL Low Profile Plate Foam Layout</a></li>
</ul>

<h2 id="end-result">End result</h2>

<p>The foam turned out decently. It’s not perfect by any means, but it does the job. In particular, the plate foam is challenging to design due to the additional wavy mid-plate cutouts needed.</p>

<div class="center width70">
<figure class="fill-parent">
  <a href="/images/posts/2021-12-29-foam/CTRL-Foam-03.jpg" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2021-12-29-foam/CTRL-Foam-03.avif" />
      <source type="image/jpeg" srcset="/images/posts/2021-12-29-foam/CTRL-Foam-03.jpg" />
      <img src="/images/posts/2021-12-29-foam/CTRL-Foam-03.jpg" width="3000" height="2000" alt="Plate foam in the Drop CTRL High Profile" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">Plate foam in the Drop CTRL High Profile</figcaption>
</figure>
</div>

<p>The hotswap sockets worked well.</p>

<div class="flex-horizontal">
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-29-foam/CTRL-Foam-01.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-29-foam/CTRL-Foam-01.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-29-foam/CTRL-Foam-01.jpg" />
        <img src="/images/posts/2021-12-29-foam/CTRL-Foam-01.jpg" width="3000" height="2000" alt="Case foam in the Drop CTRL High Profile" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Case foam in the Drop CTRL High Profile</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-29-foam/CTRL-Foam-02.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-29-foam/CTRL-Foam-02.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-29-foam/CTRL-Foam-02.jpg" />
        <img src="/images/posts/2021-12-29-foam/CTRL-Foam-02.jpg" width="3000" height="2000" alt="Case foam in the Drop CTRL High Profile - no diffuser" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Case foam in the Drop CTRL High Profile - no diffuser</figcaption>
</figure>
  </div>
</div>

<div class="flex-horizontal">
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-29-foam/CTRL-Foam-04.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-29-foam/CTRL-Foam-04.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-29-foam/CTRL-Foam-04.jpg" />
        <img src="/images/posts/2021-12-29-foam/CTRL-Foam-04.jpg" width="3000" height="2000" alt="Plate foam in the Drop CTRL High Profile" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Plate foam in the Drop CTRL High Profile</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-29-foam/CTRL-Foam-05.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-29-foam/CTRL-Foam-05.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-29-foam/CTRL-Foam-05.jpg" />
        <img src="/images/posts/2021-12-29-foam/CTRL-Foam-05.jpg" width="3000" height="2000" alt="Plate foam by itself" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Plate foam by itself</figcaption>
</figure>
  </div>
</div>

<p>You’ll notice that the pieces of foam in the middle of the bottom case are not pictured, but they are included in the layout file. For the low profile version of the keyboard, the foam is very similar, but there are differences.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[A post that covers custom laser-cut foam for the Drop CTRL keyboards and includes SVG downloads for the layouts.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://mattj.io/images/posts/2021-12-29-foam/CTRL-Foam-03.jpg" /><media:content medium="image" url="https://mattj.io/images/posts/2021-12-29-foam/CTRL-Foam-03.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Modding the $35 Redragon K552 TKL (80%) keyboard</title><link href="https://mattj.io/posts/2021-12-18-redragon-k552-mod/" rel="alternate" type="text/html" title="Modding the $35 Redragon K552 TKL (80%) keyboard" /><published>2021-12-18T00:00:00+00:00</published><updated>2021-12-18T00:00:00+00:00</updated><id>https://mattj.io/posts/redragon-k552-mod</id><content type="html" xml:base="https://mattj.io/posts/2021-12-18-redragon-k552-mod/"><![CDATA[<h1>Modding the $35 Redragon K552 TKL (80%) keyboard</h1>

<p>Saturday, December 18, 2021</p>

<p><a href="/posts/">Click here to go to all posts</a>.</p>

<p><em>With several modifications, you can turn the Redragon K552 TKL (80%) into a pretty solid keyboard</em></p>

<p><strong>Table of contents</strong></p>

<ul id="markdown-toc">
  <li><a href="#introduction" id="markdown-toc-introduction">Introduction</a></li>
  <li><a href="#starting-point" id="markdown-toc-starting-point">Starting point</a></li>
  <li><a href="#the-mods" id="markdown-toc-the-mods">The mods</a></li>
  <li><a href="#parts-and-prerequisites" id="markdown-toc-parts-and-prerequisites">Parts and prerequisites</a>    <ul>
      <li><a href="#digital-files" id="markdown-toc-digital-files">Digital files</a></li>
    </ul>
  </li>
  <li><a href="#detachable-usb-cable-modification" id="markdown-toc-detachable-usb-cable-modification">Detachable USB cable modification</a></li>
  <li><a href="#design-modifications" id="markdown-toc-design-modifications">Design modifications</a></li>
  <li><a href="#finished-board-and-sound-test" id="markdown-toc-finished-board-and-sound-test">Finished board and sound test</a></li>
  <li><a href="#thoughts-and-future-modifications" id="markdown-toc-thoughts-and-future-modifications">Thoughts and future modifications</a></li>
</ul>

<h2 id="introduction">Introduction</h2>

<div class="center width70">
<figure class="fill-parent">
  <div class="videowrapper">
    <iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/gCaAEuVqOsQ" title="Sound test video on YouTube" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
  </div>
  <figcaption class="center">Before and after sound test</figcaption>
</figure>
</div>

<p>The Redragon K552 is an extremely popular, medium-low cost mechanical keyboard. It comes in a few variations with different mechanical switches and LED configurations.</p>

<p>“Modding” a mechanical keyboard means a variety of things in the keyboard community. In the context of this post, I’m primarily talking about design modifications that don’t change the features of the keyboard. There’s one exception to that, which you’ll note later.</p>

<p>There are likely other—perhaps better—ways to categorize the keyboard experience, but let’s work with this for now!</p>

<p>I decided to start with this medium-low cost keyboard and to try to improve it based on mods I’ve performed on other keyboards, as well as one that I’ve never done before. Note: I’m describing this as medium-low cost as there are certainly less expensive keyboards (e.g., $10) and way more expensive keyboards ($200-2000+).</p>

<h2 id="starting-point">Starting point</h2>

<p>I chose to purchase the linear switch (Red) version of this keyboard with RGB LED lighting. You can find it via this (non-affiliate) <a href="https://smile.amazon.com/gp/product/B016MAK38U/" target="_blank" rel="noopener">Amazon Smile link</a>. Generally, this keyboard goes for about $35. Previously, it has dropped to $20 during sales and I encourage you to check second-hand sites like eBay, as it seems to go for as low as $10-15.</p>

<p>Out of this box, this keyboard has a couple really noticable issues:</p>
<ul>
  <li>It has an attached USB cable. Design aside, this means that you can’t pick a cable of the ideal length for your setup and, should something happen to the cable, makes it so you cannot replace it easily.</li>
  <li>It doesn’t sound great. This keyboard uses Outemu Red switches.</li>
</ul>

<p>The good points about this keyboard:</p>
<ul>
  <li>It uses standard plate-mount stabilizers. Other, more expensive keyboards that I’ve modded, such as the Das Keyboard, use Costar stabilizers, which is less ideal.</li>
  <li>It is pretty easy to open, as it uses only Phillips-head screws.</li>
  <li>It has a metal switch plate, which, while not particularly amazing, is better than lower-quality plastic one.</li>
</ul>

<p>The mixed points about this keyboard:</p>
<ul>
  <li>The switches are <em>sort of</em> hotswap. Specifically, it uses tight sockets soldered to the PCB that only work with Outemu switches, as their metal legs are thinner than other MX-style switches.</li>
</ul>

<h2 id="the-mods">The mods</h2>

<p>Most importantly, I wanted to address the lack of removable USB cable functionality. More on that later!</p>

<p>I also chose to do many common design modifications:</p>
<ul>
  <li>Add silicon to the bottom case to create a heavier feel and dampen the sound.</li>
  <li>Lubricate and modify the stabilizers to create a smoother feel and quieter sound.</li>
  <li>Place pads on the PCB to dampen the sound of the stabilizers.</li>
  <li>Remove the switches and
    <ul>
      <li>lubricate the springs to eliminate the high-pitch ping sound, and</li>
      <li>lubricate the stem and bottom housing to create a smoother feel and quieter sound.</li>
    </ul>
  </li>
  <li>Create and add custom EVA foam between the PCB and the switch plate to dampen the sound.</li>
</ul>

<h2 id="parts-and-prerequisites">Parts and prerequisites</h2>

<p>To do the design modification, you will need:</p>
<ul>
  <li>Something with which to cut EVA foam. Examples:
    <ul>
      <li>Common but time-consuming: a sharp knife, like a hobby knife</li>
      <li>Less common but faster (what I used): a laser engraver</li>
      <li>Untested: an automated cutting machine, but machines like a Cricut may not work with foam of 3mm thickness</li>
    </ul>
  </li>
  <li>Silicon mold making kit: <a href="https://smile.amazon.com/gp/product/B08QD8Y8Z3" target="_blank" rel="noopener">Amazon</a> - ~$9 (only used ~30% of the kit)</li>
  <li>Something to mix the silicon in. I used a plastic takeout container and a wood mixing stick</li>
  <li>3mm EVA foam: <a href="https://smile.amazon.com/gp/product/B07BT1W62K/" target="_blank" rel="noopener">Amazon</a> - ~$3 (only used about ~25% of this roll)</li>
  <li>Lubricant for the stabilizers. I used Krytox 205g0 (various sellers) and Permatex grease <a href="https://smile.amazon.com/Permatex-22058-Dielectric-Tune-Up-Grease/dp/B000AL8VD2" target="_blank" rel="noopener">Amazon</a> - ~$3 (estimated based on the amount I used)</li>
  <li>Lubricant for the switches. I used Krytox 205g0 (various sellers) - ~$2 (estimated based on the amount I used)</li>
  <li>Pads or cut-up bandages to place where the stabilizers may hit the PCB. I used pads from <a href="https://kbdfans.com/products/kbdfans-stabilizers-foam-sticker" target="_blank" rel="noopener">KBDfans</a> - ~$1</li>
</ul>

<p>To do the detachable USB cable modification, you will need:</p>
<ul>
  <li>Access to a 3D printer</li>
  <li>Soldering iron, solder, and basic soldering skills</li>
  <li>1x 3D printed part: <a href="#digital-files">Download files</a> - ~$2 (in material cost)</li>
  <li>2x M2.5 4mm screws: <a href="https://smile.amazon.com/gp/product/B081DWD7N3/" target="_blank" rel="noopener">Amazon</a> - ~$0.05</li>
  <li>1x Micro USB receptacle: <a href="https://smile.amazon.com/gp/product/B07W6T97HZ/" target="_blank" rel="noopener">Amazon</a> - ~$0.85
    <ul>
      <li>Note: you can do USB-C as well, but that’s up to you!</li>
    </ul>
  </li>
  <li>1x Detachable cable (any) - likely $0</li>
</ul>

<p><strong>Parts total cost: ~$21</strong></p>

<h3 id="digital-files">Digital files</h3>

<p>Here are the digital files for these modifications parts:</p>
<ul>
  <li>STL to print: <a href="/dl/2021-12-18-k552/K552-piece-m2.5.stl" target="_blank">.stl file</a>
    <ul>
      <li>Backup download of the STL on <a href="https://www.thingiverse.com/thing:5167481" target="_blank" rel="noopener">Thingiverse</a></li>
    </ul>
  </li>
  <li>Blender project if you want to directly modify this in Blender: <a href="/dl/2021-12-18-k552/K552-piece-m2.5.blend" target="_blank">.blend file</a></li>
</ul>

<p>If you plan on using a laser engraver to cut the EVA foam, here is a Lightburn file: <a href="/dl/2021-12-18-k552/K552Foam.lbrn2" target="_blank">Lightburn file</a>. Note: Remember to adjust the power/speed settings for your machine. There are two problems with this file: it doesn’t have fully straight lines since it was done from a hand tracing and it’s missing some standoffs that you will have to cut out by hand. I may fix this in the future.</p>

<h2 id="detachable-usb-cable-modification">Detachable USB cable modification</h2>

<p>For cost and familiarity purposes, I chose to go with a Micro USB receptacle, rather than the more modern USB-C. For a future keyboard, I’ll likely try USB-C instead. Feel free to try as well!</p>

<p>On the K552, the attached USB cable is held in plate with two points:</p>
<ul>
  <li>A molded plastic piece on the case to hold the cable to the case</li>
  <li>A connector to plug into the receptacle on the keyboard PCB</li>
</ul>

<p>I wanted a pretty clean look to the keyboard, so I decided to try my hand at using Blender to model a new piece for the case from scratch.</p>

<p>Fortunately, a set of digital calipers came in handy here! I chose to do the time-tested method of sketching this out on paper as I was going, which I highly recommend.</p>

<div class="center width70">
<figure class="fill-parent">
  <a href="/images/posts/2021-12-18-k552/K552Sketch.jpg" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2021-12-18-k552/K552Sketch.avif" />
      <source type="image/jpeg" srcset="/images/posts/2021-12-18-k552/K552Sketch.jpg" />
      <img src="/images/posts/2021-12-18-k552/K552Sketch.jpg" width="3000" height="2000" alt="Sketch of the part to print" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">Sketch of the part to print</figcaption>
</figure>
</div>

<p>From there, I modeled the part in Blender. This is my second time doing precision modeling in Blender, so it was a fun learning experience and a mostly straightforward part to begin with. A more advanced modeler could probably create a version that uses less material and prints faster while retaining sufficient structural integrity, but I’m content with where I landed.</p>

<div class="flex-horizontal">
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-18-k552/BlenderInterior.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-18-k552/BlenderInterior.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-18-k552/BlenderInterior.jpg" />
        <img src="/images/posts/2021-12-18-k552/BlenderInterior.jpg" width="3000" height="2000" alt="Interior of the part in Blender" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Interior of the part in Blender</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-18-k552/BlenderExterior.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-18-k552/BlenderExterior.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-18-k552/BlenderExterior.jpg" />
        <img src="/images/posts/2021-12-18-k552/BlenderExterior.jpg" width="3000" height="2000" alt="Exterior of the part in Blender" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Exterior of the part in Blender</figcaption>
</figure>
  </div>
</div>

<p>I printed a couple initial versions to gauge corner rounding, part height, and screw hole dimensions. By the third print, I felt it was sufficiently accurate to proceed. Here are the prints side-by-side, along with the original part.</p>

<div class="center width70">
<figure class="fill-parent">
  <a href="/images/posts/2021-12-18-k552/RedragonK552-11.jpg" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2021-12-18-k552/RedragonK552-11.avif" />
      <source type="image/jpeg" srcset="/images/posts/2021-12-18-k552/RedragonK552-11.jpg" />
      <img src="/images/posts/2021-12-18-k552/RedragonK552-11.jpg" width="3000" height="2000" alt="Comparison of the parts" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">Comparison of the parts</figcaption>
</figure>
</div>

<p>Check the <a href="#digital-files"><strong>Digital files</strong></a> section earlier to download the STL and Blender project for this part.</p>

<p>3D print settings I used:</p>
<ul>
  <li>Material: PETG</li>
  <li>Line height: 0.16mm</li>
  <li>Infill: 20%</li>
  <li>Supports: Yes</li>
  <li>Raft: up to you</li>
  <li>Orientation of the part: I recommend orienting the part so the angled screw wells face down. This makes it easier to remove the tiny supports.</li>
</ul>

<p>You can likely use most common materials, such as PLA, PETG, and ABS. I have only printed this with PETG.</p>

<p>Once you have 3D printed the part, you’re ready to go. To perform this modification, you’ll need to disassemble the keyboard and detach the cable from the PCB, like this:</p>

<div class="center width70">
<figure class="fill-parent">
  <a href="/images/posts/2021-12-18-k552/RedragonK552-02.jpg" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2021-12-18-k552/RedragonK552-02.avif" />
      <source type="image/jpeg" srcset="/images/posts/2021-12-18-k552/RedragonK552-02.jpg" />
      <img src="/images/posts/2021-12-18-k552/RedragonK552-02.jpg" width="3000" height="2000" alt="Detached cable from PCB" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">Detached cable from PCB</figcaption>
</figure>
</div>

<p>Next, you’ll need to cut the USB cable at a good spot. I chose to cut it near where the cable was previously held by the case.</p>

<p>Once you strip the individual wires, they can be soldered to the receptacle. Here are some photos of that.</p>

<div class="flex-horizontal">
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-18-k552/RedragonK552-03.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-18-k552/RedragonK552-03.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-18-k552/RedragonK552-03.jpg" />
        <img src="/images/posts/2021-12-18-k552/RedragonK552-03.jpg" width="3000" height="2000" alt="Wires waiting to be soldered" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Wires waiting to be soldered</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-18-k552/RedragonK552-04.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-18-k552/RedragonK552-04.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-18-k552/RedragonK552-04.jpg" />
        <img src="/images/posts/2021-12-18-k552/RedragonK552-04.jpg" width="3000" height="2000" alt="Soldered wires view from top" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Soldered wires view from top</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-18-k552/RedragonK552-05.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-18-k552/RedragonK552-05.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-18-k552/RedragonK552-05.jpg" />
        <img src="/images/posts/2021-12-18-k552/RedragonK552-05.jpg" width="3000" height="2000" alt="Soldered wires view from beneath" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Soldered wires view from beneath</figcaption>
</figure>
  </div>
</div>

<p>From there, you’ll mount the receptacle to the printed part with the M2.5 4mm screws. I chose these as the right balance of length, width, and head size. Here’s what this looks like when mounted.</p>

<div class="center width70">
<figure class="fill-parent">
  <a href="/images/posts/2021-12-18-k552/RedragonK552-12.jpg" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2021-12-18-k552/RedragonK552-12.avif" />
      <source type="image/jpeg" srcset="/images/posts/2021-12-18-k552/RedragonK552-12.jpg" />
      <img src="/images/posts/2021-12-18-k552/RedragonK552-12.jpg" width="3000" height="2000" alt="Receptacle mounted to printed part" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">Receptacle mounted to printed part</figcaption>
</figure>
</div>

<p>You should now do a test fit on the keyboard to make sure that the part fits and the USB cable can successfully plug into the receptacle. You may need to slightly adjust the receptacle, given that there’s room around the screws.</p>

<div class="center width70">
<figure class="fill-parent">
  <a href="/images/posts/2021-12-18-k552/RedragonK552-13.jpg" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2021-12-18-k552/RedragonK552-13.avif" />
      <source type="image/jpeg" srcset="/images/posts/2021-12-18-k552/RedragonK552-13.jpg" />
      <img src="/images/posts/2021-12-18-k552/RedragonK552-13.jpg" width="3000" height="2000" alt="Mounted in the keyboard case" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">Mounted in the keyboard case</figcaption>
</figure>
</div>

<p>At this point, you can optionally choose to do the design modifications!</p>

<h2 id="design-modifications">Design modifications</h2>

<p>I didn’t take photos of all the modifications, but here are a few.</p>

<p>I took out all of the Outemu switches and lubricated the springs and stems. There are enough videos and guides for this online already! Some videos:</p>

<ul>
  <li>Guide to stabilizer tuning: <a href="https://youtu.be/usNx1_d0HbQ" target="_blank" rel="noopener">https://youtu.be/usNx1_d0HbQ</a></li>
  <li>Guide to bandaid modding (starts at 309 seconds): <a href="https://youtu.be/cD5Zj-ZgMLA?t=309" target="_blank" rel="noopener">https://youtu.be/cD5Zj-ZgMLA?t=309</a></li>
  <li>Silicone mod example tutorial (starts at 210 seconds): <a href="https://youtu.be/5FynctdZqZw?t=210" target="_blank" rel="noopener">https://youtu.be/5FynctdZqZw?t=210</a></li>
</ul>

<p>I cleaned the stabilizers and tuned them up using Krytox 205g0 and Permatex grease. I clipped them and placed pads where the stabilizers may hit the PCB.</p>

<div class="flex-horizontal">
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-18-k552/RedragonK552-07.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-18-k552/RedragonK552-07.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-18-k552/RedragonK552-07.jpg" />
        <img src="/images/posts/2021-12-18-k552/RedragonK552-07.jpg" width="3000" height="2000" alt="Pads on PCB" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Pads on PCB</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-18-k552/RedragonK552-10.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-18-k552/RedragonK552-10.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-18-k552/RedragonK552-10.jpg" />
        <img src="/images/posts/2021-12-18-k552/RedragonK552-10.jpg" width="3000" height="2000" alt="Tuned stabilizers" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Tuned stabilizers</figcaption>
</figure>
  </div>
</div>

<p>Here’s the cured silicon mold in the bottom case. I used a similar mold for the Keychron C2 in <a href="/posts/2021-06-02-keychron-c2-mods/" target="_blank">this post</a>.</p>

<div class="center width70">
<figure class="fill-parent">
  <a href="/images/posts/2021-12-18-k552/RedragonK552-15.jpg" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2021-12-18-k552/RedragonK552-15.avif" />
      <source type="image/jpeg" srcset="/images/posts/2021-12-18-k552/RedragonK552-15.jpg" />
      <img src="/images/posts/2021-12-18-k552/RedragonK552-15.jpg" width="3000" height="2000" alt="Silicon mold in the bottom case" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">Silicon mold in the bottom case</figcaption>
</figure>
</div>

<p>Next up is the custom-cut EVA foam. I chose to use a laser engraver for this. However, I traced this out using the switch plate and…that definitely did not include all of the standoffs from the bottom case!</p>

<div class="center width70">
<figure class="fill-parent">
  <a href="/images/posts/2021-12-18-k552/RedragonK552-01.jpg" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2021-12-18-k552/RedragonK552-01.avif" />
      <source type="image/jpeg" srcset="/images/posts/2021-12-18-k552/RedragonK552-01.jpg" />
      <img src="/images/posts/2021-12-18-k552/RedragonK552-01.jpg" width="3000" height="2000" alt="Tracing the switch plate" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">Tracing the switch plate</figcaption>
</figure>
</div>

<p>I ended up using a hobby knife to trim the foam in a few places to let the standoffs poke through.</p>

<div class="center width70">
<figure class="fill-parent">
  <a href="/images/posts/2021-12-18-k552/RedragonK552-08.jpg" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2021-12-18-k552/RedragonK552-08.avif" />
      <source type="image/jpeg" srcset="/images/posts/2021-12-18-k552/RedragonK552-08.jpg" />
      <img src="/images/posts/2021-12-18-k552/RedragonK552-08.jpg" width="3000" height="2000" alt="Foam on PCB" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">Foam on PCB</figcaption>
</figure>
</div>

<p>Here’s another photo with the PCB, foam, and bottom case.</p>

<div class="center width70">
<figure class="fill-parent">
  <a href="/images/posts/2021-12-18-k552/RedragonK552-09.jpg" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2021-12-18-k552/RedragonK552-09.avif" />
      <source type="image/jpeg" srcset="/images/posts/2021-12-18-k552/RedragonK552-09.jpg" />
      <img src="/images/posts/2021-12-18-k552/RedragonK552-09.jpg" width="3000" height="2000" alt="Foam on PCB in bottom case" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">Foam on PCB in bottom case</figcaption>
</figure>
</div>

<p>From there, it was a matter of assembly.</p>

<div class="flex-horizontal">
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-18-k552/RedragonK552-16.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-18-k552/RedragonK552-16.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-18-k552/RedragonK552-16.jpg" />
        <img src="/images/posts/2021-12-18-k552/RedragonK552-16.jpg" width="3000" height="2000" alt="Foam on PCB in bottom case" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Another photo of the foam on PCB in bottom case</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-18-k552/RedragonK552-17.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-18-k552/RedragonK552-17.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-18-k552/RedragonK552-17.jpg" />
        <img src="/images/posts/2021-12-18-k552/RedragonK552-17.jpg" width="3000" height="2000" alt="Switch plate mounted with stabilizers and a few switches in" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Switch plate mounted with stabilizers and a few switches in</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-18-k552/RedragonK552-18.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-18-k552/RedragonK552-18.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-18-k552/RedragonK552-18.jpg" />
        <img src="/images/posts/2021-12-18-k552/RedragonK552-18.jpg" width="3000" height="2000" alt="All switches in and some keycaps mounted" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">All switches in and some keycaps mounted</figcaption>
</figure>
  </div>
</div>

<h2 id="finished-board-and-sound-test">Finished board and sound test</h2>

<p>The finished board looks pretty much the same, minus the detachable USB cable. Many folks either erase the Redragon logo using a pencil eraser or 3D print a replacement part.</p>

<div class="center width70">
<figure class="fill-parent">
  <a href="/images/posts/2021-12-18-k552/RedragonK552-19.jpg" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2021-12-18-k552/RedragonK552-19.avif" />
      <source type="image/jpeg" srcset="/images/posts/2021-12-18-k552/RedragonK552-19.jpg" />
      <img src="/images/posts/2021-12-18-k552/RedragonK552-19.jpg" width="3000" height="2000" alt="Photo of the finished K552" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">Photo of the finished K552</figcaption>
</figure>
</div>

<p>I chose to use white PETG filament for the part to make the change super visible for this post. I recommend choosing the color that meets your needs, such as black to blend in, or another color to have a bit of pop on the back of the keyboard.</p>

<div class="center width70">
<figure class="fill-parent">
  <a href="/images/posts/2021-12-18-k552/RedragonK552-14.jpg" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2021-12-18-k552/RedragonK552-14.avif" />
      <source type="image/jpeg" srcset="/images/posts/2021-12-18-k552/RedragonK552-14.jpg" />
      <img src="/images/posts/2021-12-18-k552/RedragonK552-14.jpg" width="3000" height="2000" alt="USB receptacle and 3D printed part" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">USB receptacle and 3D printed part</figcaption>
</figure>
</div>

<p>If you didn’t catch it at the beginning of the post, here is the sound test video again.</p>

<div class="center width70">
<figure class="fill-parent">
  <div class="videowrapper">
    <iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/gCaAEuVqOsQ" title="Sound test video on YouTube" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
  </div>
  <figcaption class="center">Before and after sound test</figcaption>
</figure>
</div>

<h2 id="thoughts-and-future-modifications">Thoughts and future modifications</h2>

<p>Overall, this was a pretty fun project. It took the mods I’ve done for other keyboards and combined them with some new skills, such as laser-cut foam and custom printed parts. A great learning experience for sure!</p>

<p>Was it worth it? I think so. I think there’s an entire market of folks who are willing to purchase a keyboard around $50-70 provided it gives them a substantially improved experienced compared to a $35 purchase. With these modifications, it provides pretty compelling value.</p>

<p>I chose not to do further modifications like tape, PE foam, completely replaced switches, etc., but a dedicated hobbyist could surely perform these as well for even more improvement, albeit at further time/materials cost.</p>

<p>One area of particular note: the software configurability of the Redragon K552 is pretty lacking compared to other popular keyboards. QMK is one of the most popular open-source firmware for keyboards.</p>

<p>Interestingly, there’s a port of QMK for keyboards like the K552: <a href="https://github.com/SonixQMK" target="_blank" rel="noopener">SonixQMK</a>.</p>

<p>In theory, this brings all of the power of QMK to this keyboard. I haven’t tried it yet, but I plan to do that as a next step.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[Modding the $35 Redragon K552 TKL (80%) keyboard]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://mattj.io/images/posts/2021-12-18-k552/RedragonK552-13.jpg" /><media:content medium="image" url="https://mattj.io/images/posts/2021-12-18-k552/RedragonK552-13.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Unboxing the KL-90 FE keyboard from Kiko’s Lab</title><link href="https://mattj.io/posts/2021-12-16-kikos-lab-kl-90-fe-unbox/" rel="alternate" type="text/html" title="Unboxing the KL-90 FE keyboard from Kiko’s Lab" /><published>2021-12-16T00:00:00+00:00</published><updated>2021-12-16T00:00:00+00:00</updated><id>https://mattj.io/posts/kikos-lab-kl-90-fe-unbox</id><content type="html" xml:base="https://mattj.io/posts/2021-12-16-kikos-lab-kl-90-fe-unbox/"><![CDATA[<h1 id="unboxing-the-kl-90-fe-founders-edition-keyboard-from-kikos-lab">Unboxing the KL-90 FE (Founder’s Edition) keyboard from Kiko’s Lab</h1>

<p>Thursday, December 16, 2021</p>

<p><a href="/posts/">Click here to go to all posts</a>.</p>

<p><em>A breakdown of what’s included with the KL-90 FE (Founder’s Edition) keyboard from Kiko’s Lab</em></p>

<p>The Kl-90 is a 75% keyboard with macro columns, rotary encoder, and either second rotary encoder or OLED screen support.</p>

<p>The KL-90 aluminum edition group buy ran from November 21, 2020 to December 2, 2020 via <a href="https://kikoslab.com" target="_blank" rel="noopener">the Kiko’s Lab website</a>. The original interest check can be <a href="https://geekhack.org/index.php?topic=108645.0" target="_blank" rel="noopener">found on Geekhack</a>.</p>

<p>The machining and coating of the case parts for this KL-90 aluminum edition is done in the U.S.</p>

<p>In addition to the aluminum edition group buy, a limited number of Founder’s Edition KL-90 keyboards were available via a raffle.</p>

<div class="center width70">
<figure class="fill-parent">
  <a href="/images/posts/2021-12-16-kl-90/KL-90-02.jpg" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-02.avif" />
      <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-02.jpg" />
      <img src="/images/posts/2021-12-16-kl-90/KL-90-02.jpg" width="3000" height="2000" alt="Switch plate inside of the case" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">Switch plate inside of the case</figcaption>
</figure>
</div>

<p>The KL-90 FE includes:</p>

<ul>
  <li>1 x Custom splash cerakoted OLED top case</li>
  <li>1 x Custom splash cerakoted dual encoder top case</li>
  <li>1 x Black or purple anodized bottom case</li>
  <li>2 x KL-90 PCBs (hotswap and/or solder)</li>
  <li>1 x KL-90 titanium anodized switch plate</li>
  <li>1 x Titanium badge</li>
  <li>2 x Zircuti encoder knobs (blend of titanium and zirconium)</li>
  <li>3 x EC-12 encoders</li>
  <li>1 x SSD1306 128x32 OLED screen</li>
  <li>1 x Switch plate foam (from Stupidfish)</li>
  <li>1 x Coiled cable with a custom splash cerakoted FEMO connector (from VoxelMods)</li>
  <li>Gaskets for mounting</li>
  <li>Stickers</li>
</ul>

<p>Let’s take a look at all the parts! If you click or tap on the images, they will open in a new tab.</p>

<h2 id="included-with-the-kl-90">Included with the KL-90</h2>

<p>The KL-90 FE includes two types of top cases: one that supports two encoders and one that supports an encoder on the left and an OLED screen on the right.</p>

<p>Here is the top case with dual encoder support.</p>

<div class="flex-horizontal">
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-22.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-22.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-22.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-22.jpg" width="3000" height="2000" alt="Dual encoder top case exterior" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Dual encoder top case exterior</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-23.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-23.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-23.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-23.jpg" width="3000" height="2000" alt="Dual encoder top case interior" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Dual encoder top case interior</figcaption>
</figure>
  </div>
</div>

<p>Here is the top case with encoder and OLED support.</p>

<div class="flex-horizontal">
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-19.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-19.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-19.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-19.jpg" width="3000" height="2000" alt="Encoder and OLED top case exterior" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Encoder and OLED top case exterior</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-20.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-20.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-20.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-20.jpg" width="3000" height="2000" alt="Encoder and OLED top case interior" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Encoder and OLED top case interior</figcaption>
</figure>
  </div>
</div>

<div class="center width70">
<figure class="fill-parent">
  <a href="/images/posts/2021-12-16-kl-90/KL-90-21.jpg" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-21.avif" />
      <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-21.jpg" />
      <img src="/images/posts/2021-12-16-kl-90/KL-90-21.jpg" width="3000" height="2000" alt="A closer view of the interior of the top case" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">A closer view of the interior of the top case</figcaption>
</figure>
</div>

<p>These top cases feature a custom splash cerakote finish. Each one of the KL-90 FE top cases is unique as a result.</p>

<p>Here is a close up of the top case design:</p>

<div class="center width70">
<figure class="fill-parent">
  <a href="/images/posts/2021-12-16-kl-90/KL-90-10.jpg" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-10.avif" />
      <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-10.jpg" />
      <img src="/images/posts/2021-12-16-kl-90/KL-90-10.jpg" width="3000" height="2000" alt="Macro shot of the top case design" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">Macro shot of the top case design</figcaption>
</figure>
</div>

<p>The switch plate is made of anodized titanium.</p>

<div class="flex-horizontal">
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-17.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-17.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-17.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-17.jpg" width="3000" height="2000" alt="Front of the switch plate" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Front of the switch plate</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-18.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-18.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-18.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-18.jpg" width="3000" height="2000" alt="Back of the switch plate" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Back of the switch plate</figcaption>
</figure>
  </div>
</div>

<div class="center width70">
<figure class="fill-parent">
  <a href="/images/posts/2021-12-16-kl-90/KL-90-34.jpg" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-34.avif" />
      <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-34.jpg" />
      <img src="/images/posts/2021-12-16-kl-90/KL-90-34.jpg" width="3000" height="2000" alt="Switch plate close up" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">Switch plate close up</figcaption>
</figure>
</div>

<p>The switch plate fits well into the top case.</p>

<div class="flex-horizontal">
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-12.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-12.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-12.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-12.jpg" width="3000" height="2000" alt="Switch plate in the top case" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Switch plate in the top case</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-13.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-13.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-13.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-13.jpg" width="3000" height="2000" alt="Closer shot of the switch plate in the top case" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Closer shot of the switch plate in the top case</figcaption>
</figure>
  </div>
</div>

<p>The contrast of the switch plate against the top case is really great.</p>

<div class="center width70">
<figure class="fill-parent">
  <a href="/images/posts/2021-12-16-kl-90/KL-90-02.jpg" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-02.avif" />
      <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-02.jpg" />
      <img src="/images/posts/2021-12-16-kl-90/KL-90-02.jpg" width="3000" height="2000" alt="Switch plate inside of the case" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">Switch plate inside of the case</figcaption>
</figure>
</div>

<p>The bottom case is made from black anodized aluminum.</p>

<div class="flex-horizontal">
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-16.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-16.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-16.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-16.jpg" width="3000" height="2000" alt="Bottom case interior" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Bottom case interior</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-15.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-15.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-15.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-15.jpg" width="3000" height="2000" alt="Bottom case exterior" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Bottom case exterior</figcaption>
</figure>
  </div>
</div>

<p>Starting with the interior of the bottom case, you can see the signatures of Kiko’s Lab and the case manufacturers. You can also see the well-designed plate cutouts.</p>

<div class="flex-horizontal">
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-35.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-35.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-35.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-35.jpg" width="3000" height="2000" alt="Kiko and AF signature" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Kiko and AF signature</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-36.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-36.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-36.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-36.jpg" width="3000" height="2000" alt="CadLab signature" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">CadLab signature</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-37.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-37.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-37.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-37.jpg" width="3000" height="2000" alt="Plate cutouts" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Plate cutouts</figcaption>
</figure>
  </div>
</div>

<p>Going to the exterior of the bottom case, you’ll find the anodized titanium badge.</p>

<div class="center width70">
<figure class="fill-parent">
  <a href="/images/posts/2021-12-16-kl-90/KL-90-03.jpg" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-03.avif" />
      <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-03.jpg" />
      <img src="/images/posts/2021-12-16-kl-90/KL-90-03.jpg" width="3000" height="2000" alt="Badge in the bottom case" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">Badge in the bottom case</figcaption>
</figure>
</div>

<p>This is a great looking badge, so here are a couple close-up photos.</p>

<div class="flex-horizontal">
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-08.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-08.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-08.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-08.jpg" width="3000" height="2000" alt="Close of the badge logo" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Close of the badge logo</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-09.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-09.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-09.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-09.jpg" width="3000" height="2000" alt="Close up of the badge texture" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Close up of the badge texture</figcaption>
</figure>
  </div>
</div>

<p>A keyboard doesn’t do much without a PCB, so let’s take a look at both the hotswap and solder PCBs.</p>

<p>First, the hotswap PCB.</p>

<div class="flex-horizontal">
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-24.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-24.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-24.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-24.jpg" width="3000" height="2000" alt="Hotswap PCB front" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Hotswap PCB front</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-25.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-25.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-25.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-25.jpg" width="3000" height="2000" alt="Hotswap PCB back" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Hotswap PCB back</figcaption>
</figure>
  </div>
</div>

<p>Next, the solder PCB.</p>

<div class="flex-horizontal">
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-26.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-26.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-26.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-26.jpg" width="3000" height="2000" alt="Solder PCB front" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Solder PCB front</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-27.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-27.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-27.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-27.jpg" width="3000" height="2000" alt="Solder PCB back" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Solder PCB back</figcaption>
</figure>
  </div>
</div>

<p>Here are a few close-up photos of the PCB.</p>

<div class="flex-horizontal">
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-31.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-31.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-31.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-31.jpg" width="3000" height="2000" alt="OLED and encoder spots on the hotswap PCB" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">OLED and encoder spots on the hotswap PCB</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-32.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-32.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-32.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-32.jpg" width="3000" height="2000" alt="Kiko logo on the PCB" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Kiko logo on the PCB</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-33.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-33.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-33.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-33.jpg" width="3000" height="2000" alt="Close up of the MCU on the PCB" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Close up of the MCU on the PCB</figcaption>
</figure>
  </div>
</div>

<p>Finally, we can take a look at some of the additional components that come with the KL-90 FE.</p>

<p>Most awesomely, it comes with two zircuti encoder knobs. This is a beautiful blend of titanium and zirconium.</p>

<div class="flex-horizontal">
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-04.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-04.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-04.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-04.jpg" width="3000" height="2000" alt="Encoder knob against a light background" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Encoder knob against a light background</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-05.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-05.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-05.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-05.jpg" width="3000" height="2000" alt="Encoder knob against a dark background" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Encoder knob against a dark background</figcaption>
</figure>
  </div>
</div>

<p>Even the interior of this part looks great.</p>

<div class="flex-horizontal">
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-06.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-06.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-06.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-06.jpg" width="3000" height="2000" alt="Encoder knob interior" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Encoder knob interior</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-07.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-07.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-07.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-07.jpg" width="3000" height="2000" alt="Encoder knob on the side" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Encoder knob on the side</figcaption>
</figure>
  </div>
</div>

<p>Another part is the custom coated coiled USB cable. It goes well with the case.</p>

<div class="flex-horizontal">
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-28.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-28.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-28.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-28.jpg" width="3000" height="2000" alt="Custom coiled cable" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Custom coiled cable</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-29.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-29.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-29.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-29.jpg" width="3000" height="2000" alt="A closer photo of the cable" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">A closer photo of the cable</figcaption>
</figure>
  </div>
</div>

<p>As mentioned at the beginning of this post, the KL-90 FE comes with other parts as well, shown in these photos.</p>

<div class="flex-horizontal">
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-30.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-30.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-30.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-30.jpg" width="3000" height="2000" alt="Accessories laid out" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Accessories laid out</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-12-16-kl-90/KL-90-38.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-38.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-38.jpg" />
        <img src="/images/posts/2021-12-16-kl-90/KL-90-38.jpg" width="3000" height="2000" alt="Switch plate foam" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Switch plate foam</figcaption>
</figure>
  </div>
</div>

<h2 id="final-thoughts">Final thoughts</h2>

<p>The KL-90 FE from Kiko’s Lab is a 75% keyboard with both an interesting layout and unique design. I’m excited to build and try out this keyboard, especially the macro columns and encoders.</p>

<p>One note: the colors on this case make it particularly important to color balance the photos, so if you are interested in comparing this keyboard against a reference palette, here’s a photo that includes one!</p>

<div class="center width70">
<figure class="fill-parent">
  <a href="/images/posts/2021-12-16-kl-90/KL-90-01.jpg" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2021-12-16-kl-90/KL-90-01.avif" />
      <source type="image/jpeg" srcset="/images/posts/2021-12-16-kl-90/KL-90-01.jpg" />
      <img src="/images/posts/2021-12-16-kl-90/KL-90-01.jpg" width="3000" height="2000" alt="KL-90 FE top case with a color palette" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">KL-90 FE top case with a color palette</figcaption>
</figure>
</div>]]></content><author><name></name></author><summary type="html"><![CDATA[Unboxing the KL-90 FE keyboard from Kiko's Lab]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://mattj.io/images/posts/2021-12-16-kl-90/KL-90-02.jpg" /><media:content medium="image" url="https://mattj.io/images/posts/2021-12-16-kl-90/KL-90-02.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Overview of Stadia’s TV app architecture</title><link href="https://mattj.io/posts/2021-08-20-overview-of-stadia-tv-app-architecture/" rel="alternate" type="text/html" title="Overview of Stadia’s TV app architecture" /><published>2021-08-20T00:00:00+00:00</published><updated>2021-08-20T00:00:00+00:00</updated><id>https://mattj.io/posts/overview-of-stadia-tv-app-architecture</id><content type="html" xml:base="https://mattj.io/posts/2021-08-20-overview-of-stadia-tv-app-architecture/"><![CDATA[<h1 id="overview-of-stadias-tv-app-architecture">Overview of Stadia’s TV app architecture</h1>

<p>Friday, August 20, 2021</p>

<p><a href="/posts/">Click here to go to all posts</a>.</p>

<p>I recently wrote a post for the Stadia Dev Blog titled <a href="https://stadia.dev/blog/overview-of-stadias-tv-app-architecture/" target="_blank" rel="noopener"><em>Overview of Stadia’s TV app architecture</em></a>. In the post, I cover the history of Stadia on TVs, detail some of our implementation decisions, and share a summary of our app architecture for Android TV.</p>

<p>You can read the post on the <a href="https://stadia.dev/blog/overview-of-stadias-tv-app-architecture/" target="_blank" rel="noopener">Stadia.dev blog</a>.</p>

<p>A backup of the post is also available from the <a href="https://web.archive.org/web/20210823223710/https://stadia.dev/blog/overview-of-stadias-tv-app-architecture/" target="_blank" rel="noopener">Internet Archive</a>.</p>

<div class="center width70">
<figure class="fill-parent">
  <a href="/images/posts/2021-08-20/2021-08-20-tv.jpg" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2021-08-20/2021-08-20-tv.avif" />
      <source type="image/jpeg" srcset="/images/posts/2021-08-20/2021-08-20-tv.jpg" />
      <img src="/images/posts/2021-08-20/2021-08-20-tv.jpg" width="1920" height="1280" alt="Photo of CCwGTV on a Stadia desk mat" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">Photo of CCwGTV on a Stadia desk mat</figcaption>
</figure>
</div>]]></content><author><name></name></author><summary type="html"><![CDATA[Overview of Stadia’s TV app architecture]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://mattj.io/images/posts/2021-08-20/2021-08-20-tv.jpg" /><media:content medium="image" url="https://mattj.io/images/posts/2021-08-20/2021-08-20-tv.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Sneakbox Disarray 70% with WoB keycaps</title><link href="https://mattj.io/posts/2021-07-24-sneakbox-disarray-wob/" rel="alternate" type="text/html" title="Sneakbox Disarray 70% with WoB keycaps" /><published>2021-07-24T00:00:00+00:00</published><updated>2021-07-24T00:00:00+00:00</updated><id>https://mattj.io/posts/sneakbox-disarray-wob</id><content type="html" xml:base="https://mattj.io/posts/2021-07-24-sneakbox-disarray-wob/"><![CDATA[<h1 id="sneakbox-disarray-70-with-wob-keycaps">Sneakbox Disarray 70% with WoB keycaps</h1>

<p>Saturday, July 24, 2021</p>

<p><a href="/posts/">Click here to go to all posts</a>.</p>

<p>The Sneakbox Disarray started shipping a couple months ago, and I received mine about a month ago. I did an unboxing post with many photos. If you haven’t checked it out, you might want to read that post first: <a href="/posts/2021-06-20-disarray-unboxing/" target="_blank"><em>Unboxing the Sneakbox Disarray 70% keyboard</em></a>.</p>

<p>I ended up building mine with the following configuration (no affiliation for any of the links):</p>

<ul>
  <li>PCB: Staggered: Special Edition FR4 with Mill-Max 7305 sockets to support hot swapping the switches</li>
  <li>Plate: Brass</li>
  <li>Switches: <a href="https://mkultra.click/boba-tactile-u4t-switches/" target="_blank" rel="noopener">Boba U4T 68g tactiles (Pearl)</a></li>
  <li>Stabilizers: Durock v2 with Krytox 205g0 and dielectric grease</li>
  <li>Keycaps: <a href="https://kbdfans.com/products/enjoypbt-abs-doubleshot-mechanical-keyboard-keycaps-set-2" target="_blank" rel="noopener">EnjoyPBT WoB (white-on-black) ABS</a></li>
  <li>Foam: <a href="https://stupidfish.design/products/discipline65-case-and-plate-foam-set" target="_blank" rel="noopener">Stupidfish foam</a> between the plate and PCB, stock foam between the PCB and the case</li>
</ul>

<h2 id="soldering-the-sockets">Soldering the sockets</h2>

<p>If you’re not familiar with Mill-Max sockets, they are essentially small, friction-based metal tubes that will hold the metal legs of the switch in place. They are soldered into the PCB instead of the switches. They’re not as optimal as Kailh or other purpose-built switch sockets, but they get the job done. There are some issues with switches with larger legs.</p>

<p>More info here:</p>

<ul>
  <li><a href="https://www.mill-max.com/products/receptacle/7305/7305-0-15-15-47-27-10-0" target="_blank" rel="noopener">Mill-Max website for the 7305 socket</a></li>
  <li><a href="https://www.mouser.com/ProductDetail/Mill-Max/7305-0-15-15-47-27-10-0?qs=QVz7UnnaAAGZJgZDI7Hd%2FA%3D%3D" target="_blank" rel="noopener">Order the 7305 socket from Mouser</a></li>
</ul>

<p>The process of soldering the Mill-Max sockets doesn’t take much longer than soldering switches. However, you need to be careful not to get any solder into the socket, otherwise the switch will be stuck! A solder sucker is very useful for when that happens.</p>

<div class="center width30">
<figure class="fill-parent">
  <video playsinline="" autoplay="" loop="" muted="" width="540" height="960" class="responsive" title="Soldering Mill-Max 7305 sockets on the PCB (looped)">
    <source src="/images/posts/2021-07-24-disarray/disarraysoldering.webm" type="video/webm" />
    <source src="/images/posts/2021-07-24-disarray/disarraysoldering.mp4" type="video/mp4" />
    <div fallback="">
      <p>This browser does not support the video element.</p>
    </div>
  </video>
  <figcaption class="center">Soldering Mill-Max 7305 sockets on the PCB (looped)</figcaption>
</figure>
</div>

<h2 id="final-build">Final build</h2>

<div class="center width70">
<figure class="fill-parent">
  <a href="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-07.jpg" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-07.avif" />
      <source type="image/jpeg" srcset="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-07.jpg" />
      <img src="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-07.jpg" width="3000" height="2000" alt="Final build on a desk mat" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">Final build on a desk mat</figcaption>
</figure>
</div>

<p>Some of the best aspects of this case are the rotary encoder and the visible internal components. It’s more expensive, both in terms of design and cost, to have the components visible like this, but the result is quite beautiful.</p>

<div class="flex-horizontal">
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-02.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-02.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-02.jpg" />
        <img src="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-02.jpg" width="3000" height="2000" alt="Rotary encoder up closer" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Rotary encoder up closer</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-03.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-03.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-03.jpg" />
        <img src="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-03.jpg" width="3000" height="2000" alt="USB-C port" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">USB-C port</figcaption>
</figure>
  </div>
</div>

<div class="flex-horizontal">
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-04.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-04.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-04.jpg" />
        <img src="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-04.jpg" width="3000" height="2000" alt="ATmega 32U4 visible" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">ATmega 32U4 visible</figcaption>
</figure>
  </div>
  <div class="flex-item-horizontal">
<figure class="fill-parent">
    <a href="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-05.jpg" target="_blank" rel="noopener" class="text-decoration-none">
      <picture>
        <source type="image/avif" srcset="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-05.avif" />
        <source type="image/jpeg" srcset="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-05.jpg" />
        <img src="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-05.jpg" width="3000" height="2000" alt="Another angle on the rotary encoder" class="responsive" />
      </picture>
    </a>
    <figcaption class="center">Another angle on the rotary encoder</figcaption>
</figure>
  </div>
</div>

<p>Here are a couple more images of the final build in different light:</p>

<div class="center width70">
<figure class="fill-parent">
  <a href="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-06.jpg" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-06.avif" />
      <source type="image/jpeg" srcset="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-06.jpg" />
      <img src="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-06.jpg" width="3000" height="2000" alt="Final build with a plain white background" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">Final build with a plain white background</figcaption>
</figure>
</div>

<div class="center width70">
<figure class="fill-parent">
  <a href="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-01.jpg" target="_blank" rel="noopener" class="text-decoration-none">
    <picture>
      <source type="image/avif" srcset="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-01.avif" />
      <source type="image/jpeg" srcset="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-01.jpg" />
      <img src="/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-01.jpg" width="3000" height="2000" alt="Final build with natural sunlight" class="responsive" />
    </picture>
  </a>
  <figcaption class="center">Final build with natural sunlight</figcaption>
</figure>
</div>

<h3 id="a-note-on-the-usb-c-port">A note on the USB-C port</h3>

<p>I noticed that only some of my cables worked with this keyboard, as there is a ~1.2mm gap between the edge of the USB-C receptacle and the interior case well. This normally wouldn’t be an issue, but the case also has a relatively small space to accommodate the molding on the cable.</p>

<p>My solution was to purchase a relatively inexpensive USB-C extender to make it so any of my current or future cables will work. I purchased <a href="https://smile.amazon.com/gp/product/B07MBWH7QG/" target="_blank" rel="noopener">this one from Amazon (no affiliation)</a>.</p>

<h2 id="final-thoughts">Final thoughts</h2>

<p>This is a fantastic case, and despite the fact that all of the Disarray boards were declared as B-stock, I nonetheless found the design, materials, and process to be great. I’m looking forward to more keyboards from Sneakbox in the future!</p>

<p>Related posts on Sneakbox keyboards:</p>

<ul>
  <li><a href="/posts/2021-06-20-disarray-unboxing/" target="_blank"><em>Unboxing the Sneakbox Disarray 70% keyboard</em></a></li>
  <li><a href="/posts/2021-07-24-sneakbox-mga-sa-mizu/" target="_blank"><em>Sneakbox MGA Standard with SA Mizu (unboxing and final build)</em></a></li>
</ul>]]></content><author><name></name></author><summary type="html"><![CDATA[Build of the Sneakbox Disarray 70% with WoB keycaps]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://mattj.io/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-07.jpg" /><media:content medium="image" url="https://mattj.io/images/posts/2021-07-24-disarray/SneakboxDisarrayBuilt-07.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>