PageSourceSearch

https://charlsyang.com/blog

html charlsyang.com collected 2026-10-04 03:30:41 UTC 37,170 bytes, 102 lines download raw bytes

1<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><title>Blog</title><meta name="next-head-count" content="3"/><link rel="preload" href="/fonts/Marat-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous"/><link rel="preload" href="/fonts/Marat-Light.woff2" as="font" type="font/woff2" crossorigin="anonymous"/><link rel="preload" href="/fonts/ABCDiatypeVariable.woff2" as="font" type="font/woff2" crossorigin="anonymous"/><link rel="stylesheet" href="/fonts.css"/><link href="https://fastly-cloud.typenetwork.com/projects/7347/fontface.css?64a210d9" rel="stylesheet" type="text/css"/><link rel="alternate" type="application/rss+xml" title="Blog RSS Feed" href="/feed.xml"/><link rel="icon" href="/favicons/favicon.ico"/><link rel="mask-icon" href="/favicons/safari-pinned-tab.svg" color="#E54D2E"/><link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon.png"/><link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicons/favicon-16x16.png"/>
1<script defer="" data-domain="charlsyang.com" src="https://plausible.io/js/script.outbound-links.js"></script>
1<noscript data-n-css=""></noscript>
1<script defer="" nomodule="" src="/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script>
1<script src="/_next/static/chunks/webpack-ae762f636dce1194.js" defer=""></script>
1<script src="/_next/static/chunks/framework-305cb810cde7afac.js" defer=""></script>
1<script src="/_next/static/chunks/main-1cff40ce8a7b2418.js" defer=""></script>
1<script src="/_next/static/chunks/pages/_app-e10efa03512564b9.js" defer=""></script>
1<script src="/_next/static/chunks/932-7e35a251aeb138de.js" defer=""></script>
1<script src="/_next/static/chunks/pages/blog-ad28ac990b3daed2.js" defer=""></script>
1<script src="/_next/static/bQMKoKWZsGehBWy3AfpuU/_buildManifest.js" defer=""></script>
1<script src="/_next/static/bQMKoKWZsGehBWy3AfpuU/_ssgManifest.js" defer=""></script>
1<style data-styled="" data-styled-version="6.0.2">html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;vertical-align:baseline;}/*!sc*/
2article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block;}/*!sc*/
3ol,ul{list-style:none;}/*!sc*/
4blockquote,q{quotes:none;}/*!sc*/
5blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;}/*!sc*/
6table{border-collapse:collapse;border-spacing:0;}/*!sc*/
7html{--font-sans:'Diatype','Adjusted Arial',-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;--font-serif:'Marat','Adjusted Georgia',Iowan Old Style,Apple Garamond,Baskerville,Times New Roman,Droid Serif,Times,Source Serif Pro,serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;--font-mono:'Input Mono Reg','SF Mono',Menlo,Consolas,Monaco,Liberation Mono,Lucida Console,monospace;--font-ampersand:Baskerville,Apple Garamond,Iowan Old Style,Athelas,Palatino,Times New Roman,Droid Serif,Times,Source Serif Pro,serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;--font-size-base:16;--font-size-xxs:calc(12 / var(--font-size-base) * 1rem);--font-size-xs:calc(14 / var(--font-size-base) * 1rem);--font-size-s:calc(16 / var(--font-size-base) * 1rem);--font-size-m:calc(18 / var(--font-size-base) * 1rem);--font-size-l:calc(20 / var(--font-size-base) * 1rem);--font-size-xl:calc(24 / var(--font-size-base) * 1rem);--spacing-base:8px;--spacing-s:calc(var(--spacing-base) / 2);--spacing-1x:var(--spacing-base);--spacing-2x:calc(var(--spacing-base) * 2);--spacing-3x:calc(var(--spacing-base) * 3);--spacing-4x:calc(var(--spacing-base) * 4);--spacing-5x:calc(var(--spacing-base) * 5);--spacing-6x:calc(var(--spacing-base) * 6);--nav-height:calc(var(--spacing-base) * 7);--footer-height:calc(var(--spacing-base) * 7);--back-button-height:var(--spacing-6x);--transition-fast:160ms;--transition-default:240ms;--transition-slow:320ms;--duration-load:600ms;--stagger-1:40ms;--stagger-2:80ms;--stagger-3:120ms;--ease-in-out:cubic-bezier(0.65,0.05,0.36,1);--ease-out:cubic-bezier(0.17,0.84,0.44,1);}/*!sc*/
8@-webkit-keyframes onload-fade{from{-webkit-translate:0 20px;-moz-translate:0 20px;-ms-translate:0 20px;translate:0 20px;opacity:0;}to{-webkit-translate:0 0;-moz-translate:0 0;-ms-translate:0 0;translate:0 0;opacity:100%;}}/*!sc*/
9@keyframes onload-fade{from{-webkit-translate:0 20px;-moz-translate:0 20px;-ms-translate:0 20px;translate:0 20px;opacity:0;}to{-webkit-translate:0 0;-moz-translate:0 0;-ms-translate:0 0;translate:0 0;opacity:100%;}}/*!sc*/
10*,*:before,*:after{box-sizing:border-box;font-family:var(--fallback-sans);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:auto;}/*!sc*/
11html,body{font-family:var(--font-sans);line-height:1.5;background:var(--color-bg-base);min-height:100%;}/*!sc*/
12:root{--color-theme:hsl(10, 78.0%, 54.0%);--color-bg-base:hsl(50, 20.0%, 99.0%);--color-bg-solid:hsl(60, 7.7%, 97.5%);--color-bg-interactive:hsl(59, 6.5%, 95.1%);--color-bg-hover:hsl(58, 6.1%, 92.9%);--color-bg-selected:hsl(8, 92.8%, 91.0%);--color-text-base:hsl(50, 6.0%, 10.0%);--color-text-article:hsl(55, 3.7%, 19.9%);--color-text-muted:hsl(50, 2.0%, 43.1%);--color-text-faint:hsl(50, 2.0%, 55.7%);--color-border:hsl(56, 5.9%, 88.4%);--color-link-border:hsl(51, 6.0%, 77.1%);--color-link-hover:var(--color-theme);--color-constant-white:#FFF;--color-bg-inverted:hsl(61, 2.0%, 8.3%);--color-text-inverted:hsl(50, 20.0%, 99.0%);--font-weight-normal:400;--font-weight-medium:500;--font-weight-bold:600;--font-weight-serif:400;--btn-primary-bg:hsl(10, 78.0%, 54.0%);--btn-elevated-bg:color-mix(in srgb, var(--color-bg-inverted), transparent 10%);--btn-elevated-bg-hover:color-mix(in srgb, var(--btn-elevated-bg), var(--color-bg-base) 8%);--btn-elevated-bg-active:color-mix(in srgb, var(--color-bg-inverted), transparent 10%);--btn-elevated-border:0 0 0 1px color-mix(in srgb, var(--color-border), transparent 80%);--shadow-color:0deg 0% 0%;--shadow-elevation-low:0px 0.3px 0.3px hsl(var(--shadow-color) / 0.09),0px 0.6px 0.7px -1.2px hsl(var(--shadow-color) / 0.09),0px 1.3px 1.5px -2.5px hsl(var(--shadow-color) / 0.09);--shadow-elevation-medium:0px 0.3px 0.3px hsl(var(--shadow-color) / 0.1),0px 1.1px 1.2px -0.8px hsl(var(--shadow-color) / 0.1),0px 2.7px 3px -1.7px hsl(var(--shadow-color) / 0.1),0.1px 6.6px 7.4px -2.5px hsl(var(--shadow-color) / 0.1);--shadow-elevation-high:0px 0.5px 0.6px hsl(var(--shadow-color) / 0.1),0px 1.7px 1.9px -0.8px hsl(var(--shadow-color) / 0.1),0px 4.3px 4.8px -1.7px hsl(var(--shadow-color) / 0.1),-0.1px 10.4px 11.7px -2.5px hsl(var(--shadow-color) / 0.1s);}/*!sc*/
13[data-theme='dark']{--color-theme:hsl(10, 81.7%, 59.0%);--color-bg-base:hsl(61, 2.0%, 8.3%);--color-bg-solid:hsl(60, 3.7%, 10.6%);--color-bg-interactive:hsl(58, 3.7%, 13.1%);--color-bg-hover:hsl(57, 3.6%, 15.3%);--color-bg-selected:hsl(7, 60.1%, 20.6%);--color-text-base:hsl(56, 4.0%, 92.8%);--color-text-article:hsl(51, 6.0%, 77.1%);--color-text-muted:hsl(50, 4.0%, 61.8%);--color-text-faint:hsl(50, 4.0%, 42.7%);--color-border:hsl(55, 3.7%, 19.9%);--color-link-border:hsl(50, 3.8%, 30.6%);--color-link-hover:var(--color-theme);--color-bg-inverted:hsl(50, 20.0%, 99.0%);--color-text-inverted:hsl(61, 2.0%, 8.3%);--btn-elevated-bg:color-mix(in srgb, var(--color-bg-inverted), transparent 4%);--btn-elevated-bg-hover:color-mix(in srgb, var(--btn-elevated-bg), var(--color-bg-base) 6%);--btn-elevated-border:0 0 0 1px color-mix(in srgb, var(--color-border), transparent 90%);--btn-elevated-bg-active:color-mix(in srgb, var(--btn-elevated-bg), var(--color-bg-base) 12%
13);--font-weight-normal:360;--font-weight-medium:460;--font-weight-bold:560;--font-weight-serif:300;}/*!sc*/
14a{color:var(--color-text-base);text-decoration-color:var(--color-link-border);text-decoration-thickness:1.5px;text-underline-offset:2.4px;text-decoration-skip-ink:auto;-webkit-transition:all var(--transition-default);transition:all var(--transition-default);}/*!sc*/
15a:hover{color:var(--color-link-hover);text-decoration-color:var(--color-link-hover);-webkit-transition:all var(--transition-fast);transition:all var(--transition-fast);}/*!sc*/
16::selection{background-color:var(--color-bg-selected);}/*!sc*/
17img{max-width:100%;display:block;}/*!sc*/
18data-styled.g1[id="sc-global-iGGBFL1"]{content:"sc-global-iGGBFL1,"}/*!sc*/
19.gUjHeU{display:-ms-grid;display:grid;-ms-grid-columns:repeat(12, 1fr);grid-template-columns:repeat(12, 1fr);-webkit-column-gap:24px;column-gap:24px;row-gap:0;}/*!sc*/
20data-styled.g2[id="sc-6e8f8551-0"]{content:"gUjHeU,"}/*!sc*/
21.bttpCf{position:relative;max-width:min(100%, calc(1200px + 40px * 2));margin-left:auto;margin-right:auto;padding-left:40px;padding-right:40px;}/*!sc*/
22@media (max-width: 34.375rem){.bttpCf{padding-left:var(--spacing-2x);padding-right:var(--spacing-2x);}}/*!sc*/
23data-styled.g3[id="sc-6d191339-0"]{content:"bttpCf,"}/*!sc*/
24.cIeDra{z-index:2;height:var(--nav-height);-webkit-animation:dNlBvn var(--duration-load) var(--ease-out) both;animation:dNlBvn var(--duration-load) var(--ease-out) both;}/*!sc*/
25data-styled.g4[id="sc-9d1e8607-0"]{content:"cIeDra,"}/*!sc*/
26.ifTHFx{padding-top:var(--spacing-2x);}/*!sc*/
27@media (max-width: 34.375rem){.ifTHFx{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;gap:var(--spacing-2x);}}/*!sc*/
28data-styled.g5[id="sc-9d1e8607-1"]{content:"ifTHFx,"}/*!sc*/
29.fsPyfb{position:fixed;top:0;-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);z-index:1;-webkit-mask-image:linear-gradient(to bottom, #000 0, transparent 100%);mask-image:linear-gradient(to bottom, #000 0, transparent 100%);width:100vw;height:48px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;pointer-events:none;}/*!sc*/
30.fsPyfb::after{content:"";inset:0;position:absolute;background-image:linear-gradient(
31      to bottom,
32      var(--color-bg-base) 0,
33      transparent 100%
34    );opacity:0.3;}/*!sc*/
35data-styled.g6[id="sc-9d1e8607-2"]{content:"fsPyfb,"}/*!sc*/
36.coIwdy{max-width:24px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;place-items:center;}/*!sc*/
37data-styled.g7[id="sc-9d1e8607-3"]{content:"coIwdy,"}/*!sc*/
38.dUCfey{display:block;-webkit-transform:scale(0.9) translateY(-1px);-moz-transform:scale(0.9) translateY(-1px);-ms-transform:scale(0.9) translateY(-1px);transform:scale(0.9) translateY(-1px);}/*!sc*/
39.dUCfey path{fill:var(--color-theme);}/*!sc*/
40data-styled.g8[id="sc-9d1e8607-4"]{content:"dUCfey,"}/*!sc*/
41.bPmPlU{-ms-grid-column:7/-1;grid-column:7/-1;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:var(--spacing-4x);position:relative;}/*!sc*/
42.bPmPlU a{font-size:var(--font-size-s);color:var(--color-text-muted);-webkit-text-decoration:none;text-decoration:none;}/*!sc*/
43.bPmPlU a:hover{color:var(--color-text-base);}/*!sc*/
44@media (max-width: 34.375rem){.bPmPlU{gap:var(--spacing-2x);}}/*!sc*/
45data-styled.g9[id="sc-9d1e8607-5"]{content:"bPmPlU,"}/*!sc*/
46.cHlyNU{height:var(--footer-height);position:relative;max-width:min(100%, calc(1200px + 40px * 2));margin-left:auto;margin-right:auto;padding-left:40px;padding-right:40px;-webkit-animation:hrXbvy var(--duration-load) var(--ease-out) both;animation:hrXbvy var(--duration-load) var(--ease-out) both;}/*!sc*/
47@media (max-width: 34.375rem){.cHlyNU{padding-left:24px;padding-right:24px;}}/*!sc*/
48data-styled.g10[id="sc-5aab42d2-0"]{content:"cHlyNU,"}/*!sc*/
49.hhfObf{height:1px;width:100vw;position:absolute;top:0;left:50%;-webkit-transform:translate(-50%, 0);-moz-transform:translate(-50%, 0);-ms-transform:translate(-50%, 0);transform:translate(-50%, 0);background-image:linear-gradient(
50    90deg,
51    var(--color-bg-base) 0%,
52    var(--color-border) 25%,
53    var(--color-border) 50%,
54    var(--color-border) 75%,
55    var(--color-bg-base) 100%
56  );}/*!sc*/
57@media (max-width: 100rem){.hhfObf{background-image:linear-gradient(
58      90deg,
59      var(--color-bg-base) 0%,
60      var(--color-border) 10%,
61      var(--color-border) 50%,
62      var(--color-border) 90%,
63      var(--color-bg-base) 100%
64    );}}/*!sc*/
65data-styled.g11[id="sc-5aab42d2-1"]{content:"hhfObf,"}/*!sc*/
66.UnIeS{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;
66-webkit-justify-content:space-between;justify-content:space-between;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:100%;}/*!sc*/
67data-styled.g12[id="sc-5aab42d2-2"]{content:"UnIeS,"}/*!sc*/
68.keiaTI{font-size:var(--font-size-xs);font-family:var(--font-sans);color:var(--color-text-faint);}/*!sc*/
69data-styled.g13[id="sc-5aab42d2-3"]{content:"keiaTI,"}/*!sc*/
70.gDQgkq{font-family:var(--font-sans);font-size:var(--font-size-xs);color:var(--color-text-faint);-webkit-text-decoration:none;text-decoration:none;}/*!sc*/
71.gDQgkq :hover{color:var(--color-text-base);cursor:pointer;}/*!sc*/
72data-styled.g15[id="sc-5aab42d2-5"]{content:"gDQgkq,"}/*!sc*/
73.cxNAum{min-height:calc(100vh - var(--footer-height) - var(--nav-height));}/*!sc*/
74.cxNAum *{font-family:var(--font-sans);font-weight:var(--font-weight-normal);font-size:var(--font-size-m);}/*!sc*/
75@media (max-width: 68.75rem){.cxNAum *{font-size:var(--font-size-s);}}/*!sc*/
76@media (max-width: 68.75rem){.cxNAum{min-height:calc(100vh - var(--footer-height));}}/*!sc*/
77data-styled.g47[id="sc-52cccab-0"]{content:"cxNAum,"}/*!sc*/
78.hFLKzb{-ms-grid-column:7/-1;grid-column:7/-1;width:min(30rem, 100%);margin-top:10rem;margin-bottom:10rem;}/*!sc*/
79@media (max-width: 34.375rem){.hFLKzb{-ms-grid-column:1/-1;grid-column:1/-1;}}/*!sc*/
80data-styled.g49[id="sc-52cccab-2"]{content:"hFLKzb,"}/*!sc*/
81.dvTLpQ{font-size:var(--font-size-l);font-weight:var(--font-weight-bold);margin-bottom:var(--spacing-s);color:var(--color-text-base);}/*!sc*/
82@media (max-width: 68.75rem){.dvTLpQ{font-size:var(--font-size-m);}}/*!sc*/
83data-styled.g50[id="sc-52cccab-3"]{content:"dvTLpQ,"}/*!sc*/
84.duPaKT{font-size:var(--font-size-s);font-weight:var(--font-weight-normal);color:var(--color-text-muted);}/*!sc*/
85.duPaKT a{font-size:var(--font-size-s);}/*!sc*/
86data-styled.g51[id="sc-52cccab-4"]{content:"duPaKT,"}/*!sc*/
87.kFDnwc{margin-bottom:var(--spacing-6x);-webkit-animation:onload-fade var(--duration-load) var(--ease-out) both;animation:onload-fade var(--duration-load) var(--ease-out) both;}/*!sc*/
88@media (max-width: 68.75rem){.kFDnwc{margin-bottom:var(--spacing-5x);}}/*!sc*/
89data-styled.g52[id="sc-52cccab-5"]{content:"kFDnwc,"}/*!sc*/
90.cLtdkj{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:var(--spacing-3x);-ms-grid-column:2/-1;grid-column:2/-1;-webkit-animation:onload-fade var(--duration-load) var(--ease-out) both;animation:onload-fade var(--duration-load) var(--ease-out) both;-webkit-animation-delay:var(--stagger-1);animation-delay:var(--stagger-1);}/*!sc*/
91data-styled.g53[id="sc-52cccab-6"]{content:"cLtdkj,"}/*!sc*/
92.bzMGYM{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:flex-start;-webkit-box-align:flex-start;-ms-flex-align:flex-start;align-items:flex-start;gap:var(--spacing-s);}/*!sc*/
93data-styled.g54[id="sc-52cccab-7"]{content:"bzMGYM,"}/*!sc*/
94.csIWyR{color:var(--color-text-muted);}/*!sc*/
95data-styled.g55[id="sc-52cccab-8"]{content:"csIWyR,"}/*!sc*/
96@-webkit-keyframes dNlBvn{from{opacity:0;-webkit-translate:0 -8px;-moz-translate:0 -8px;-ms-translate:0 -8px;translate:0 -8px;}to{opacity:100%;-webkit-translate:0 0;-moz-translate:0 0;-ms-translate:0 0;translate:0 0;}}/*!sc*/
97@keyframes dNlBvn{from{opacity:0;-webkit-translate:0 -8px;-moz-translate:0 -8px;-ms-translate:0 -8px;translate:0 -8px;}to{opacity:100%;-webkit-translate:0 0;-moz-translate:0 0;-ms-translate:0 0;translate:0 0;}}/*!sc*/
98data-styled.g136[id="sc-keyframes-dNlBvn"]{content:"dNlBvn,"}/*!sc*/
99@-webkit-keyframes hrXbvy{from{opacity:0;-webkit-translate:0 8px;-moz-translate:0 8px;-ms-translate:0 8px;translate:0 8px;}to{opacity:100%;-webkit-translate:0 0;-moz-translate:0 0;-ms-translate:0 0;translate:0 0;}}/*!sc*/
100@keyframes hrXbvy{from{opacity:0;-webkit-translate:0 8px;-moz-translate:0 8px;-ms-translate:0 8px;translate:0 8px;}to{opacity:100%;-webkit-translate:0 0;-moz-translate:0 0;-ms-translate:0 0;translate:0 0;}}/*!sc*/
101data-styled.g137[id="sc-keyframes-hrXbvy"]{content:"hrXbvy,"}/*!sc*/
102</style></head><body><div id="__next"><div class="sc-9d1e8607-2 fsPyfb"></div><div class="sc-6d191339-0 sc-9d1e8607-0 bttpCf cIeDra"><div class="sc-6e8f8551-0 sc-9d1e8607-1 gUjHeU ifTHFx"><a class="sc-9d1e8607-3 coIwdy" href="/"><svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="none" class="sc-9d1e8607-4 dUCfey"><path fill="#E54D2E" d="M13.5 11.638C19.502 15.155 9 21.31 9 14.276c0 7.034-10.499.88-4.499-2.638-6.001 3.517-6.001-8.793 0-5.276-6.001-3.517 4.5-9.672 4.5-2.638 0-7.034 10.499-.88 4.5 2.638 5.999-3.517 5.999 8.793 0 5.276Z"></path></svg></a><nav class="sc-9d1e8607-5 bPmPlU"><a href="/work">Work</a><a href="/blog">Blog</a></nav></div></div><main>
102<script>!function(){try{var d=document.documentElement,n='data-theme',s='setAttribute';var e=localStorage.getItem('theme');if('system'===e||(!e&&true)){var t='(prefers-color-scheme: dark)',m=window.matchMedia(t);if(m.media!==t||m.matches){d.style.colorScheme = 'dark';d[s](n,'dark')}else{d.style.colorScheme = 'light';d[s](n,'light')}}else if(e){d[s](n,e|| '')}if(e==='light'||e==='dark')d.style.colorScheme=e}catch(e){}}()</script>
102<div class="sc-6d191339-0 bttpCf"><div class="sc-6e8f8551-0 sc-52cccab-0 gUjHeU cxNAum"><div class="sc-52cccab-2 hFLKzb"><div class="sc-52cccab-5 kFDnwc"><h1 class="sc-52cccab-3 dvTLpQ">Blog</h1><p class="sc-52cccab-4 duPaKT">Subscribe via <a href="/feed.xml">RSS</a> or<!-- --> <a href="https://buttondown.email/charlsyang">email</a></p></div><ul class="sc-52cccab-6 cLtdkj"><li class="sc-52cccab-7 bzMGYM"><a href="/blog/working-on-search">Working on Search</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2026-05-09">May 9, 2026</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/the-case-for-canvas">The Case for Canvas</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2026-05-08">May 8, 2026</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/what-i-learned-designing-ads">What I Learned Designing Ads</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2025-12-24">December 24, 2025</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/ads-hater-ads-worker">Ads Hater, Ads Worker</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2025-12-14">December 14, 2025</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/carelessness-hurts">Carelessness Hurts</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2025-11-02">November 2, 2025</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/2024-review">2024 Year in Review</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2025-01-20">January 20, 2025</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/in-praise-of-disposable-camera">In Praise of Disposable Camera</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2024-07-07">July 7, 2024</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/information-diet-principles">Operating Principles for Information Diet</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2024-06-16">June 16, 2024</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/on-copilot-plus-pc-launch">On Copilot+ PC Launch</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2024-05-22">May 22, 2024</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/prototype">Prototype</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2023-11-12">November 12, 2023</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/writing-is-scary">Writing is Scary</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2023-09-04">September 4, 2023</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/vessels-of-design">Vessels of Design</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2023-08-20">August 20, 2023</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/trust-eyes-more-than-numbers">Trust Eyes More Than Numbers</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2023-08-18">August 18, 2023</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/algorithmic-control">Algorithmic Control</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2023-08-17">August 17, 2023</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/a-skillful-answer">
102A Skillful Answer</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2023-08-16">August 16, 2023</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/living-like-weasels">Living Like Weasels</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2023-08-03">August 3, 2023</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/lessons-on-influence">Lessons on Influence</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2023-07-26">July 26, 2023</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/css-considered-feminine">CSS Considered Feminine</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2023-07-24">July 24, 2023</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/the-hard-questions-of-personal-site">The Hard Questions of Personal Site</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2023-07-23">July 23, 2023</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/writing-on-a-social-web">Writing on a Social Web</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2023-07-22">July 22, 2023</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/life-will-find-its-way">Life will find its way</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2023-07-21">July 21, 2023</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/sidenotes">Sidenotes</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2023-07-17">July 17, 2023</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/nora">Nora</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2023-07-16">July 16, 2023</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/invisible-rogue">Invisible Rogue Characters</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2023-07-15">July 15, 2023</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/email-for-distribution">Email for Distribution and Nothing But</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2023-07-11">July 11, 2023</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/typography-is-a-balloon">Typography is a Balloon</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2023-07-08">July 8, 2023</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/untangle-threads">Untangle Threads</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2023-07-07">July 7, 2023</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/code-snippet">Code Snippet</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2023-07-02">July 2, 2023</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/site-meta">The Meta Stuff</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2023-01-31">January 31, 2023</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/analog-vs-digital-designer">Analog vs. Digital Designer</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2022-12-20">December 20, 2022</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/interestingness">Interestingness</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2022-12-19">December 19, 2022</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/photo-human-entanglement">Photo-Human Entanglement</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2022-12-08">December 8, 2022</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/materials-and-makers">Materials and Makers</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2022-08-06">August 6, 2022</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/the-wholeness-of-work">The Wholeness of Work</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2022-07-31">July 31, 2022</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/nobody-else-cares">Nobody Else Cares</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2022-07-23">July 23, 2022</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/software-manifestos">Software Manifestos</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2022-07-23">July 23, 2022</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/impermanence-of-software">The Impermanence of Software</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2022-07-21">July 21, 2022</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/app-site-spectrums">App-Site Spectrums</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2022-07-04">July 4, 2022</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/rhythm">Rhythm</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2022-07-04">July 4, 2022</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/highway">Highway</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2022-06-28">June 28, 2022</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/labor-of-love">
102Labor of Love</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2022-06-26">June 26, 2022</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/taste">Taste</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2022-06-19">June 19, 2022</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/seeing-the-multiverse">Seeing the Multiverse</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2022-05-14">May 14, 2022</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/viscom-additional-channels">VisCom Project: Additional Channels</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2022-05-12">May 12, 2022</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/interface-design">Interface Design</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2022-05-06">May 6, 2022</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/in-present-in-the-woods">In Present, In the Woods</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2022-05-05">May 5, 2022</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/tangibility">Tangibility, Design, and Graphicacy</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2022-04-30">April 30, 2022</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/typography-books">Typography Books</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2022-04-15">April 15, 2022</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/viscom-grids-and-wireframes">VisCom Project: Grids and Wireframes</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2022-04-14">April 14, 2022</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/viscom-moodboards">VisCom Project: Moodboards</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2022-04-05">April 5, 2022</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/viscom-client-and-goals">VisCom Project: Client and Goals</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2022-04-04">April 4, 2022</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/viscom">VisCom Project: Table of Contents</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2022-04-04">April 4, 2022</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/run">To Run or Not to Run</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2021-05-18">May 18, 2021</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/new-avatar">New Avatar</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2021-03-18">March 18, 2021</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/simply">Don’t Simply Write Simply</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2021-03-17">March 17, 2021</time></p></li><li class="sc-52cccab-7 bzMGYM"><a href="/blog/way-of-seeing">Way of Seeing</a><p class="sc-52cccab-8 csIWyR"><time dateTime="2020-08-02">August 2, 2020</time></p></li></ul></div></div></div></main><footer class="sc-5aab42d2-0 cHlyNU"><div class="sc-5aab42d2-1 hhfObf"></div><div class="sc-5aab42d2-2 UnIeS"><p class="sc-5aab42d2-3 keiaTI">© <!-- -->2026<!-- --> · With <!-- -->&lt;<!-- -->3 from San Francisco</p><a href="/colophon" class="sc-5aab42d2-5 gDQgkq">Colophon</a></div></footer></div>
102<script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"allPostsData":[{"slug":"working-on-search","title":"Working on Search","date":"2026-05-09","tags":[],"excerpt":"","isPublished":true},{"slug":"the-case-for-canvas","title":"The Case for Canvas","date":"2026-05-08","tags":[],"excerpt":"","isPublished":true},{"slug":"what-i-learned-designing-ads","title":"What I Learned Designing Ads","date":"2025-12-24","tags":[],"excerpt":"","isPublished":true},{"slug":"ads-hater-ads-worker","title":"Ads Hater, Ads Worker","date":"2025-12-14","tags":[],"excerpt":"","isPublished":true},{"slug":"carelessness-hurts","title":"Carelessness Hurts","date":"2025-11-02","tags":[],"excerpt":"","isPublished":true},{"slug":"2024-review","title":"2024 Year in Review","date":"2025-01-20","tags":[],"excerpt":"","isPublished":true},{"slug":"in-praise-of-disposable-camera","title":"In Praise of Disposable Camera","date":"2024-07-07","tags":[],"excerpt":"Why I love it and you should too","isPublished":true},{"slug":"information-diet-principles","title":"Operating Principles for Information Diet","date":"2024-06-16","tags":[],"excerpt":"","isPublished":true},{"slug":"on-copilot-plus-pc-launch","title":"On Copilot+ PC Launch","date":"2024-05-22","tags":[],"excerpt":"A good prototype is judged by how well it embodies a particular idea to be evaluated.","isPublished":true},{"slug":"prototype","title":"Prototype","date":"2023-11-12","tags":["design"],"excerpt":"A good prototype is judged by how well it embodies a particular idea to be evaluated.","isPublished":true},{"slug":"writing-is-scary","title":"Writing is Scary","date":"2023-09-04","tags":[],"excerpt":"Writing collapses an infinite probability thought space into an arbitrary selection of words","isPublished":true},{"slug":"vessels-of-design","title":"Vessels of Design","date":"2023-08-20","tags":[],"excerpt":"","isPublished":true},{"slug":"trust-eyes-more-than-numbers","title":"Trust Eyes More Than Numbers","date":"2023-08-18","tags":[],"excerpt":"Optical accuracy is not the same as numeric accuracy","isPublished":true},{"slug":"algorithmic-control","title":"Algorithmic Control","date":"2023-08-17","tags":[],"excerpt":"I want to tune my algorithm","isPublished":true},{"slug":"a-skillful-answer","title":"A Skillful Answer","date":"2023-08-16","tags":[],"excerpt":"How to say no without saying no","isPublished":true},{"slug":"living-like-weasels","title":"Living Like Weasels","date":"2023-08-03","tags":[],"excerpt":"I want to fall so deeply into the stasis.","isPublished":true},{"slug":"lessons-on-influence","title":"Lessons on Influence","date":"2023-07-26","tags":[],"excerpt":"How to push for changes in an organization","isPublished":true},{"slug":"css-considered-feminine","title":"CSS Considered Feminine","date":"2023-07-24","tags":["CSS"],"excerpt":"Gender bias in web development","isPublished":true},{"slug":"the-hard-questions-of-personal-site","title":"The Hard Questions of Personal Site","date":"2023-07-23","tags":[],"excerpt":"","isPublished":true},{"slug":"writing-on-a-social-web","title":"Writing on a Social Web","date":"2023-07-22","tags":[],"excerpt":"","isPublished":true},{"slug":"life-will-find-its-way","title":"Life will find its way","date":"2023-07-21","tags":[],"excerpt":"A devil’s ivy and its newly sprouted leave.","isPublished":true},{"slug":"sidenotes","title":"Sidenotes","date":"2023-07-17","tags":[],"excerpt":"Implementing sidenotes with MDX and Next.js","isPublished":true},{"slug":"nora","title":"Nora","date":"2023-07-16","tags":[],"excerpt":"Land of choice, land of estrangement.","isPublished":true},{"slug":"invisible-rogue","title":"Invisible Rogue Characters","date":"2023-07-15","tags":[],"excerpt":"How to resolve the error “input is not proper utf-8, indicate encoding!”","isPublished":true},{"slug":"email-for-distribution","title":"Email for Distribution and Nothing But","date":"2023-07-11","tags":[],"excerpt":"This time I am going to get it right.","isPublished":true},{"slug":"typography-is-a-balloon","title":"Typography is a Balloon","date":"2023-07-08","tags":["design","typography"],"excerpt":"Typography is not a container of text but an embodiment that visually reifies text.","isPublished":true},{"slug":"untangle-threads","title":"Untangle Threads","date":"2023-07-07","tags":[],"excerpt":"Threads and the clash of online identities.","isPublished":true},{"slug":"code-snippet","title":"Code Snippet","date":"2023-07-02","tags":[],"excerpt":"","isPublished":true},{"slug":"site-meta","title":"The Meta Stuff","date":"2023-01-31","tags":[],"excerpt":"","isPublished":true},{"slug":"analog-vs-digital-designer","title":"Analog vs. Digital Designer","date":"2022-12-20","tags":[],"excerpt":"","isPublished":true},{"slug":"interestingness","title":"Interestingness","date":"2022-12-19","tags":[],"excerpt":"","isPublished":true},{"slug":"photo-human-entanglement","title":"Photo-Human Entanglement","date":"2022-12-08","tags":[],"excerpt":"","isPublished":true},{"slug":"materials-and-makers","title":"Materials and Makers","date":"2022-08-06","tags":[],"excerpt":"","isPublished":true},{"slug":"the-wholeness-of-work","title":"The Wholeness of Work","date":"2022-07-31","tags":[],"excerpt":"","isPublished":true},{"slug":"nobody-else-cares","title":"Nobody Else Cares","date":"2022-07-23","tags":["Design"],"excerpt":"","isPublished":true}
102,{"slug":"software-manifestos","title":"Software Manifestos","date":"2022-07-23","tags":[],"excerpt":"","isPublished":true},{"slug":"impermanence-of-software","title":"The Impermanence of Software","date":"2022-07-21","tags":[],"excerpt":"","isPublished":true},{"slug":"app-site-spectrums","title":"App-Site Spectrums","date":"2022-07-04","tags":[],"excerpt":"","isPublished":true},{"slug":"rhythm","title":"Rhythm","date":"2022-07-04","tags":[],"excerpt":"","isPublished":true},{"slug":"highway","title":"Highway","date":"2022-06-28","tags":[],"excerpt":"","isPublished":true},{"slug":"labor-of-love","title":"Labor of Love","date":"2022-06-26","tags":["Design"],"excerpt":"","isPublished":true},{"slug":"taste","title":"Taste","date":"2022-06-19","tags":["Design"],"excerpt":"","isPublished":true},{"slug":"seeing-the-multiverse","title":"Seeing the Multiverse","date":"2022-05-14","tags":[],"excerpt":"","isPublished":true},{"slug":"viscom-additional-channels","title":"VisCom Project: Additional Channels","date":"2022-05-12","tags":["Design"],"excerpt":"","isPublished":true},{"slug":"interface-design","title":"Interface Design","date":"2022-05-06","tags":["Design"],"excerpt":"","isPublished":true},{"slug":"in-present-in-the-woods","title":"In Present, In the Woods","date":"2022-05-05","tags":[],"excerpt":"","isPublished":true},{"slug":"tangibility","title":"Tangibility, Design, and Graphicacy","date":"2022-04-30","tags":["Design"],"excerpt":"","isPublished":true},{"slug":"typography-books","title":"Typography Books","date":"2022-04-15","tags":["Design"],"excerpt":"","isPublished":true},{"slug":"viscom-grids-and-wireframes","title":"VisCom Project: Grids and Wireframes","date":"2022-04-14","tags":["Design"],"excerpt":"","isPublished":true},{"slug":"viscom-moodboards","title":"VisCom Project: Moodboards","date":"2022-04-05","tags":["Design"],"excerpt":"","isPublished":true},{"slug":"viscom-client-and-goals","title":"VisCom Project: Client and Goals","date":"2022-04-04","tags":["Design"],"excerpt":"","isPublished":true},{"slug":"viscom","title":"VisCom Project: Table of Contents","date":"2022-04-04","tags":["Design"],"excerpt":"","isPublished":true},{"slug":"run","title":"To Run or Not to Run","date":"2021-05-18","tags":[],"excerpt":"","isPublished":true},{"slug":"new-avatar","title":"New Avatar","date":"2021-03-18","tags":["Design"],"excerpt":"The process of making is also the process of making sense.","isPublished":true},{"slug":"simply","title":"Don’t Simply Write Simply","date":"2021-03-17","tags":[],"excerpt":"Write poems, proses, and journals. Write for yourself, write freely, write beautifully.","isPublished":true},{"slug":"way-of-seeing","title":"Way of Seeing","date":"2020-08-02","tags":[],"excerpt":"","isPublished":true}]},"__N_SSG":true},"page":"/blog","query":{},"buildId":"bQMKoKWZsGehBWy3AfpuU","isFallback":false,"gsp":true,"scriptLoader":[]}</script>
102</body></html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.