<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: owen</title>
    <description>The latest articles on DEV Community by owen (@owen090).</description>
    <link>https://dev.to/owen090</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4063284%2F91e16f9f-c744-4bc3-be5b-98257619ac0f.png</url>
      <title>DEV Community: owen</title>
      <link>https://dev.to/owen090</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/owen090"/>
    <language>en</language>
    <item>
      <title>I built a tool that turns aurora data into a single decision: GO, MAYBE, or NO</title>
      <dc:creator>owen</dc:creator>
      <pubDate>Fri, 28 Aug 2026 03:47:14 +0000</pubDate>
      <link>https://dev.to/owen090/i-built-a-tool-that-turns-aurora-data-into-a-single-decision-go-maybe-or-no-2h8i</link>
      <guid>https://dev.to/owen090/i-built-a-tool-that-turns-aurora-data-into-a-single-decision-go-maybe-or-no-2h8i</guid>
      <description>&lt;p&gt;Every time a geomagnetic storm makes the news, the same thing happens in my household: someone asks "can we see the northern lights tonight?", and I open three tabs — a Kp index chart, a cloud forecast, and a light pollution map — and still can't give a straight answer.&lt;/p&gt;

&lt;p&gt;The existing aurora tools are built by and for space-weather people. They show you the raw data: planetary K-index, aurora oval plots, solar wind speed. That's great if you know what "Bz = -12 nT" means for your driveway. Most people don't. Some sites go the other way and print invented precision like "73% chance of aurora tonight" — a number nobody can honestly produce.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;Aurora Tonight&lt;/strong&gt; (&lt;a href="https://aurora-tonight.com" rel="noopener noreferrer"&gt;aurora-tonight.com&lt;/a&gt;): enter your city or ZIP, get one of four answers — GO, MAYBE, NO, or UNKNOWN — plus the best viewing window, the main obstacle in plain language, and which direction to look.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stack
&lt;/h2&gt;

&lt;p&gt;Nothing exotic, and that was the point:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js&lt;/strong&gt; on Vercel. Forecast pages are served via ISR — the answer for a given city only changes as fast as the upstream data does, so per-request rendering was just burning invocations for identical bytes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NOAA's aurora oval data&lt;/strong&gt; for geomagnetic activity. This is the authoritative public source; I deliberately don't layer a proprietary "prediction" on top of it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open-Meteo&lt;/strong&gt; for cloud cover snapshots. Clouds are the #1 reason a strong geomagnetic night is still a NO, and most aurora sites ignore them entirely.&lt;/li&gt;
&lt;li&gt;Darkness, moonlight, and light pollution are computed or looked up server-side. Everything is cached at the edge; the whole site is static-ish and free to run, which is why the tool can be free with no signup.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The interesting design decision: what not to compute
&lt;/h2&gt;

&lt;p&gt;The hardest part wasn't the data pipeline — it was deciding the output contract. Three rules I ended up with:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;No fake percentages.&lt;/strong&gt; The model's output is a categorical call, not a probability. If you can't defend "73%", don't print it. GO / MAYBE / NO maps to what a person actually does with the answer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UNKNOWN is a first-class state.&lt;/strong&gt; If the cached data snapshot is stale, the page says UNKNOWN instead of extrapolating a confident-looking guess from old data. This costs us some "always has an answer" slickness, and it's worth it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The main obstacle is part of the answer.&lt;/strong&gt; "NO" alone is useless. "NO — overcast until after 1am" tells you whether to set an alarm.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I wrote up the full scoring logic on the &lt;a href="https://aurora-tonight.com/methodology" rel="noopener noreferrer"&gt;methodology page&lt;/a&gt; if you're curious how the calls are made — it documents exactly what goes into a GO versus a MAYBE.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current scope and honest limitations
&lt;/h2&gt;

&lt;p&gt;It covers 15+ indexed US states and cities — Fairbanks and Alaska down through mid-latitude places like Colorado, Ohio, and Chicago, where aurora is a rare-event question rather than a nightly one. Northern hemisphere, mid-to-high latitudes only. It won't tell you anything useful in Texas, and it says so.&lt;/p&gt;

&lt;p&gt;If you're building anything in the "raw public data → plain-language decision" space, I'd genuinely like to hear how you handled the honesty-vs-slickness tradeoff. The temptation to print a number that looks more confident than the data deserves is real.&lt;/p&gt;

</description>
      <category>weather</category>
    </item>
    <item>
      <title>I built a roof calculator that does all the math in your browser — no server, no signup, no lead form</title>
      <dc:creator>owen</dc:creator>
      <pubDate>Fri, 28 Aug 2026 02:49:17 +0000</pubDate>
      <link>https://dev.to/owen090/i-built-a-roof-calculator-that-does-all-the-math-in-your-browser-no-server-no-signup-no-lead-3n1a</link>
      <guid>https://dev.to/owen090/i-built-a-roof-calculator-that-does-all-the-math-in-your-browser-no-server-no-signup-no-lead-3n1a</guid>
      <description>&lt;p&gt;Nearly every "roofing calculator" on the internet is a contractor lead form in disguise. You type in your measurements, hit calculate, and the answer is locked until you hand over your phone number. The math was never the product — your contact info was.&lt;/p&gt;

&lt;p&gt;I'm a developer, not a roofer, but I wanted to see what happens if you build the opposite: &lt;strong&gt;&lt;a href="https://pitchcalc.com" rel="noopener noreferrer"&gt;PitchCalc&lt;/a&gt;&lt;/strong&gt;, five roof-math calculators where the answer shows up in about ten seconds, all computation happens locally in your browser, and there is no backend to store anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  The actual math is one triangle
&lt;/h2&gt;

&lt;p&gt;Everything in residential roofing reduces to one right triangle: &lt;code&gt;rise&lt;/code&gt; over &lt;code&gt;run&lt;/code&gt;. The whole engine is a handful of lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ratio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;rise&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pitch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;rise&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/12`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                        &lt;span class="c1"&gt;// X:12 notation (run is usually 12")&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;degrees&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;atan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ratio&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;180&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// 6/12 → 26.6°&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;slopePercent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ratio&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                  &lt;span class="c1"&gt;// 6/12 → 50%&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;multiplier&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;ratio&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;ratio&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// 6/12 → 1.118&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rafterLength&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;rise&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From there it's just unit conventions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sloped roof area&lt;/strong&gt; = footprint × multiplier&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Roofing squares&lt;/strong&gt; = area ÷ 100 (a "square" is 100 sq ft, the unit shingles are sold in)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shingle bundles&lt;/strong&gt; = ceil(squares × 3 × (1 + waste)) — three bundles per square, typically 10% waste&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Five pages, one shared engine: &lt;a href="https://pitchcalc.com" rel="noopener noreferrer"&gt;roof pitch&lt;/a&gt;, &lt;a href="https://pitchcalc.com/roofing-calculator/" rel="noopener noreferrer"&gt;roofing&lt;/a&gt; (area/squares/bundles), &lt;a href="https://pitchcalc.com/roof-area-calculator/" rel="noopener noreferrer"&gt;roof area&lt;/a&gt;, &lt;a href="https://pitchcalc.com/rafter-calculator/" rel="noopener noreferrer"&gt;rafter&lt;/a&gt;, and &lt;a href="https://pitchcalc.com/shingle-calculator/" rel="noopener noreferrer"&gt;shingles&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Local-first as a feature, not a limitation
&lt;/h2&gt;

&lt;p&gt;The page says "Measurements stay in this browser" and means it literally: there is no database, no account system, no analytics event carrying your inputs anywhere. Results recompute on every keystroke, so there's no submit button at all.&lt;/p&gt;

&lt;p&gt;One detail I like: the input state lives in the URL hash, so a calculation is shareable as a plain link — &lt;a href="https://pitchcalc.com/#rise=6&amp;amp;run=12" rel="noopener noreferrer"&gt;pitchcalc.com/#rise=6&amp;amp;run=12&lt;/a&gt; opens with a 6/12 pitch preloaded. No encoding endpoint, no shortened URLs, just &lt;code&gt;location.hash&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trust through visible formulas
&lt;/h2&gt;

&lt;p&gt;Every result panel prints the formula next to the number — &lt;code&gt;√(1 + (rise ÷ run)²)&lt;/code&gt; right beside the multiplier value. If you don't trust the output you can check it with a pencil. That's also why the copy button produces something that reads like a takeoff sheet: the audience is a homeowner about to talk to a contractor, or an estimator checking numbers from a truck. The output had to survive being read aloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stack notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Next.js, fully static — the whole site is pre-rendered pages plus a small client-side engine&lt;/li&gt;
&lt;li&gt;No form libraries or state management; controlled inputs and derived values&lt;/li&gt;
&lt;li&gt;Print stylesheet treats the result panel as the document, not the page chrome&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I'd add next
&lt;/h2&gt;

&lt;p&gt;Waste factors per roof complexity, valleys/hips geometry, metric units. If you do roof math by hand for something else, tell me in the comments — genuinely collecting the backlog.&lt;/p&gt;

&lt;p&gt;Try it: &lt;a href="https://pitchcalc.com" rel="noopener noreferrer"&gt;pitchcalc.com&lt;/a&gt; — free, no signup, and it will never ask for your phone number.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>There's no superscript "q" in Unicode — and other things I learned building a superscript generator</title>
      <dc:creator>owen</dc:creator>
      <pubDate>Thu, 27 Aug 2026 09:16:55 +0000</pubDate>
      <link>https://dev.to/owen090/theres-no-superscript-q-in-unicode-and-other-things-i-learned-building-a-superscript-generator-55gk</link>
      <guid>https://dev.to/owen090/theres-no-superscript-q-in-unicode-and-other-things-i-learned-building-a-superscript-generator-55gk</guid>
      <description>&lt;p&gt;Quick quiz: how do you write "x² + y³" in plain text, no HTML, no LaTeX?&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; Easy, right? `²` and `³` are just characters. Now write "E = mcᵠ" — wait, that should be a superscript "q". Try to find it. I'll wait.

 You won't, because **Unicode has no superscript q**. When I built a [free superscript converter](https://literalkit.com/superscript-generator), this turned out to be the tip of
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;a very weird iceberg. Here's what I learned.&lt;/p&gt;

&lt;h2&gt;
  
  
  Superscripts aren't formatting — they're separate characters
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; Most people assume superscript works like bold: take a character, apply a style. That's how `&amp;lt;sup&amp;gt;` works in HTML, and how rich text editors work.

 Unicode plain text doesn't have styles. Instead, every superscript character is its own pre-composed codepoint, donated to the standard by different communities at different
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;times:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; - `¹²³` live in **Latin-1 Supplement** (U+00B9, U+00B2, U+00B3) — they've been there since the 1980s.
 - `⁰ ⁴-⁹ ⁺ ⁻ ⁽ ⁾` live in the **Superscripts and Subscripts** block (U+2070–U+209F).
 - Superscript *letters* are scattered across **Phonetic Extensions** (U+1D2C–U+1D7F), because linguists needed them for phonetic transcription: `ᵃ ᵇ ᶜ ᵈ ᵉ ᶠ ᵍ ʰ ...`
 - And a few stragglers like `ˣ` (U+02E3) hide in **Spacing Modifier Letters**.

 So "convert text to superscript" really means "look up each character in a hand-built mapping table someone assembled from four different corners of the standard." There's no
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;algorithm. It's a scavenger hunt.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest-output problem
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; Here's where it gets philosophically interesting. The mapping has holes:

 - **No superscript `q`.** It's the famous gap. Proposals exist, but as of today there's no official codepoint.
 - **Uppercase letters are incomplete** — you get `ᴬ ᴮ ᴰ ᴱ ᴳ ᴴ ᴵ ᴶ ᴷ ᴸ ᴹ ᴺ ᴼ ᴾ ᴿ ᵀ ᵁ ⱽ ᵂ`, but try spelling a full sentence in superscript caps and you'll hit walls fast.
 - Subscripts are even sparser: `ₐ ₑ ₕ ᵢ ⱼ ₖ ₗ ₘ ₙ ₒ ₚ ᵣ ₛ ₜ ᵤ ᵥ ₓ` — that's most of what exists.

 Most converters on the web quietly patch the holes with **lookalike characters** — a Greek letter here, a math alphanumeric symbol there. The output *looks* fine until someone
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;copies it into a screen reader, a search box, or a font that renders the substitute as tofu (□).&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; I made a different call: when a character has no real superscript, the tool says so instead of faking it. It feels worse in the demo and better in real life — what you copy is
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;what you meant.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>unicode</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Styling plain text that survives copy-paste: a Unicode primer (and the tools I use)</title>
      <dc:creator>owen</dc:creator>
      <pubDate>Wed, 05 Aug 2026 02:00:34 +0000</pubDate>
      <link>https://dev.to/owen090/styling-plain-text-that-survives-copy-paste-a-unicode-primer-and-the-tools-i-use-220m</link>
      <guid>https://dev.to/owen090/styling-plain-text-that-survives-copy-paste-a-unicode-primer-and-the-tools-i-use-220m</guid>
      <description>&lt;h2&gt;
  
  
  The problem: there is no "bold" in a bio
&lt;/h2&gt;

&lt;p&gt;Here's a scenario you've probably hit: you want to emphasize something in an&lt;br&gt;
Instagram bio, a Discord nickname, a Slack message, or a plain-text README —&lt;br&gt;
and there's no formatting toolbar. No bold, no italic, no superscript button.&lt;/p&gt;

&lt;p&gt;The reason is simple: these fields store &lt;strong&gt;plain text&lt;/strong&gt;. Formatting isn't&lt;br&gt;
data; it's a rendering layer applied by a rich-text editor. Take the editor&lt;br&gt;
away and the formatting never existed.&lt;/p&gt;

&lt;p&gt;The workaround that &lt;em&gt;does&lt;/em&gt; travel with the text is Unicode.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unicode already contains "styled" characters
&lt;/h2&gt;

&lt;p&gt;Unicode isn't just a bigger ASCII. It includes entire blocks of letter&lt;br&gt;
variants — most notably the &lt;strong&gt;Mathematical Alphanumeric Symbols&lt;/strong&gt; block&lt;br&gt;
(U+1D400–U+1D7FF), which encodes bold, italic, script, fraktur, double-struck,&lt;br&gt;
monospace, and more as &lt;em&gt;distinct characters&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;x&lt;/code&gt; → &lt;code&gt;𝐱&lt;/code&gt; (bold), &lt;code&gt;𝑥&lt;/code&gt; (italic), &lt;code&gt;𝚡&lt;/code&gt; (monospace)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;A&lt;/code&gt; → &lt;code&gt;𝔸&lt;/code&gt; (double-struck), &lt;code&gt;𝔄&lt;/code&gt; (fraktur)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2&lt;/code&gt; → &lt;code&gt;²&lt;/code&gt; (superscript, from a much older block)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because these are real characters with their own codepoints, they survive&lt;br&gt;
copy-paste into any plain-text field. That's the whole trick behind "font&lt;br&gt;
generator" sites — no fonts are involved, just a codepoint lookup.&lt;/p&gt;

&lt;h2&gt;
  
  
  The catch: honest vs. fake conversion
&lt;/h2&gt;

&lt;p&gt;There's a subtle quality problem most converters have. Coverage is uneven:&lt;br&gt;
superscript has no lowercase &lt;code&gt;b&lt;/code&gt; (Unicode simply never encoded one), italic&lt;br&gt;
has no capital &lt;code&gt;Q&lt;/code&gt;, and so on.&lt;/p&gt;

&lt;p&gt;Many tools quietly paper over the gaps by borrowing &lt;em&gt;lookalike&lt;/em&gt; characters&lt;br&gt;
from unrelated scripts — a Greek letter here, a Cyrillic one there. It looks&lt;br&gt;
fine until screen readers mangle it, search can't find it, or a font renders&lt;br&gt;
it as tofu. A good converter instead:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;converts what has a real mapping,&lt;/li&gt;
&lt;li&gt;leaves the rest untouched,&lt;/li&gt;
&lt;li&gt;and &lt;strong&gt;tells you&lt;/strong&gt; which characters stayed unchanged.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The tools I settled on
&lt;/h2&gt;

&lt;p&gt;I got tired of hand-searching codepoint tables, so I now use&lt;br&gt;
&lt;a href="https://literalkit.com" rel="noopener noreferrer"&gt;LiteralKit&lt;/a&gt; — a free collection of 50+ focused&lt;br&gt;
Unicode tools. Three things make it work for me as a developer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Everything runs locally in the browser.&lt;/strong&gt; No accounts, no uploads — your&lt;br&gt;
text never leaves the page. Paste, convert, copy, done in seconds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Honest output.&lt;/strong&gt; It never substitutes lookalike characters. Unsupported&lt;br&gt;
characters pass through unchanged, and the page discloses its coverage up&lt;br&gt;
front. For a notation tool, that honesty matters more than a big feature list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One tool per page, one job per tool.&lt;/strong&gt; No popups, no multi-step funnels.&lt;br&gt;
A few I keep bookmarked:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://literalkit.com/superscript-generator" rel="noopener noreferrer"&gt;Superscript Generator&lt;/a&gt; —
x², footnote-style notation for plain-text docs and READMEs&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://literalkit.com/fancy-text-generator" rel="noopener noreferrer"&gt;Fancy Text Generator&lt;/a&gt; —
italic/bold/script/monospace Unicode styles for bios and profiles&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://literalkit.com/case-converter" rel="noopener noreferrer"&gt;Case Converter&lt;/a&gt; — boring, but
I reach for it weekly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The full set (Wingdings and runic translators, symbol pickers, a symbol&lt;br&gt;
identifier, and more) lives in the &lt;a href="https://literalkit.com/tools" rel="noopener noreferrer"&gt;tool directory&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;Styled plain text is just Unicode arithmetic — but doing that arithmetic by&lt;br&gt;
hand is a waste of your time. Know the trick exists, know that coverage has&lt;br&gt;
honest gaps, and let a tool that respects those gaps do the mapping.&lt;/p&gt;

</description>
      <category>unicode</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>nocode</category>
    </item>
  </channel>
</rss>
