:root{--bg: #ffffff;--fg: #1d1d1f;--muted: #6b6b6b;--accent: #1a1a1a;--rule: #e8e8e8;--divider: #aeb4c9;--maxw: 38rem;--serif: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;--sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif}@media(prefers-color-scheme:dark){:root{--bg: #111111;--fg: #e6e6e6;--muted: #9a9a9a;--accent: #ffffff;--rule: #2a2a2a;--divider: #3d4356}}*{box-sizing:border-box}html{-webkit-text-size-adjust:100%}body{margin:0;background:var(--bg);color:var(--fg);font-family:var(--sans);font-size:15px;line-height:1.7;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}.wrap{max-width:var(--maxw);margin:0 auto;padding:5.5rem 1.5rem 6rem}h1,h2,h3{font-family:var(--serif);font-weight:600;line-height:1.18;letter-spacing:-.015em;text-wrap:balance}h1{font-size:1.6rem;margin:0 0 .25rem}h2{font-size:1.12rem;margin:3rem 0 1rem}h3{font-size:1rem;margin:2rem 0 .75rem}a{color:var(--accent);text-decoration:none;border-bottom:1px solid var(--rule);transition:border-color .15s ease}a:hover{border-color:var(--accent)}p{margin:0 0 1.15rem;text-wrap:pretty}.muted{color:var(--muted)}.lede{font-size:.92rem;line-height:1.6}.inline-links{display:flex;flex-wrap:wrap;gap:1rem;margin:1.25rem 0 0;padding:0;list-style:none}.posts{list-style:none;padding:0;margin:0}.posts li{display:flex;justify-content:space-between;gap:1rem;padding:.35rem 0}.posts li a{border-bottom:none}.posts li a:hover{border-bottom:1px solid var(--accent)}.posts .date{color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap;flex-shrink:0}.year{color:var(--muted);font-family:var(--serif);font-size:.85rem;margin:2rem 0 .5rem}.project-grid{position:relative;display:grid;grid-template-columns:repeat(3,1fr);margin:.5rem 0 0;padding:.35rem}.project-grid:before{content:"";position:absolute;inset:0;background-color:var(--divider);-webkit-mask:url(/strokes/box.svg) no-repeat center / 100% 100%;mask:url(/strokes/box.svg) no-repeat center / 100% 100%;pointer-events:none}.project-card{position:relative;display:flex;flex-direction:column;gap:.15rem;padding:.85rem .95rem;border-bottom:none;border-radius:4px;color:var(--fg);transition:background-color .15s ease}.project-card:hover{background-color:color-mix(in srgb,var(--fg) 6%,transparent)}.pc-name{font-weight:600;font-size:.95rem;letter-spacing:-.01em;line-height:1.2}.pc-desc{color:var(--muted);font-size:.78rem;line-height:1.3}.project-card:after{content:"";position:absolute;top:16%;bottom:16%;right:0;width:7px;transform:translate(50%);background-color:var(--divider);-webkit-mask:url(/strokes/divider-v.svg) no-repeat center / 100% 100%;mask:url(/strokes/divider-v.svg) no-repeat center / 100% 100%;pointer-events:none}.project-card:before{content:"";position:absolute;left:12%;right:12%;bottom:0;height:6px;transform:translateY(50%);background-color:var(--divider);-webkit-mask:url(/strokes/divider-h.svg) no-repeat center / 100% 100%;mask:url(/strokes/divider-h.svg) no-repeat center / 100% 100%;pointer-events:none}.project-card.no-v:after{display:none}.project-card.no-h:before{display:none}@media(max-width:36rem){.project-grid{grid-template-columns:1fr}.project-card:after{display:none}.project-card:before{left:6%;right:6%}.project-card.no-h:before{display:block}.project-card:last-child:before{display:none}}article{position:relative}article :where(h2,h3){margin-top:2.5rem}article img{max-width:100%;height:auto}article pre{overflow-x:auto;padding:1rem;border-radius:6px;font-size:.8rem}.back{display:inline-block;margin-bottom:2rem;font-size:.82rem}.post-meta{color:var(--muted);font-size:.82rem;margin-bottom:1.5rem}.app-embed{display:flex;justify-content:center;margin:2rem 0 2.5rem}.app-embed iframe{border:1px solid var(--rule);background:#0b0b10}.app-embed.phone iframe{width:390px;max-width:100%;height:780px;border-radius:28px}.app-embed.wide iframe{width:100%;height:640px;border-radius:12px}@font-face{font-family:Caveat;src:url(/fonts/caveat-600.woff2) format("woff2");font-weight:600;font-style:normal;font-display:swap}:root{--hand: "Caveat", "Bradley Hand", "Segoe Print", ui-rounded, cursive;--ink: #2f5fd0;--ink-red: #d6453c;--marker-rgb: 255, 213, 92;--marker-a: .5}@media(prefers-color-scheme:dark){:root{--ink: #8fa8ff;--ink-red: #ff7d74;--marker-rgb: 240, 205, 110;--marker-a: .22}}.hl{background-image:linear-gradient(101deg,rgba(var(--marker-rgb),0) .5%,rgba(var(--marker-rgb),var(--marker-a)) 1.6% 98.4%,rgba(var(--marker-rgb),0) 99.5%);background-repeat:no-repeat;background-size:100% .92em;background-position:0 62%;padding:0 .08em;border-radius:.1em;-webkit-box-decoration-break:clone;box-decoration-break:clone}.ul,.st,.ring{position:relative;white-space:nowrap}.ul:after,.st:after,.ring:after{content:"";position:absolute;pointer-events:none}.ul:after{left:-.06em;right:-.06em;bottom:-.16em;height:.46em;background-color:var(--ink);-webkit-mask:url(/strokes/underline.svg) no-repeat center / 100% 100%;mask:url(/strokes/underline.svg) no-repeat center / 100% 100%}.st:after{left:-.05em;right:-.05em;top:50%;height:.38em;transform:translateY(-50%);background-color:var(--ink-red);-webkit-mask:url(/strokes/strike.svg) no-repeat center / 100% 100%;mask:url(/strokes/strike.svg) no-repeat center / 100% 100%}.ring{padding:0 .15em}.ring:after{inset:-.3em -.38em;background-color:var(--ink);-webkit-mask:url(/strokes/ring.svg) no-repeat center / 100% 100%;mask:url(/strokes/ring.svg) no-repeat center / 100% 100%}.note{float:right;clear:right;width:12rem;margin:.15rem -14.5rem .7rem 1.6rem;font-family:var(--hand);font-weight:600;font-size:1.22rem;line-height:1.22;color:var(--ink);text-align:left;transform:rotate(-1.6deg);transform-origin:top left}.note.left{float:left;clear:left;margin:.15rem 1.6rem .7rem -14.5rem;transform:rotate(1.4deg);transform-origin:top right}.note.red{color:var(--ink-red)}.note-inline{font-family:var(--hand);font-weight:600;font-size:1.1em;color:var(--ink)}@media(max-width:68rem){.note,.note.left{float:none;width:auto;margin:.7rem 0 1.2rem;padding-left:.9rem;border-left:2px solid var(--ink);transform:rotate(-.5deg);font-size:1.16rem}}.kmenu-trigger{position:fixed;bottom:1.25rem;right:1.25rem;z-index:50;display:inline-flex;align-items:center;gap:.15rem;padding:.4rem .55rem;background:var(--bg);border:1px solid var(--rule);border-radius:8px;color:var(--muted);cursor:pointer;box-shadow:0 1px 3px #0000000f;transition:border-color .15s ease,color .15s ease}.kmenu-trigger:hover{border-color:var(--accent);color:var(--fg)}.kmenu-trigger kbd,.kmenu-footer kbd{font-family:var(--sans);font-size:.72rem;line-height:1;padding:.15rem .3rem;border-radius:4px;background:var(--rule);color:var(--muted)}.kmenu-overlay{position:fixed;inset:0;z-index:100;display:flex;align-items:flex-start;justify-content:center;padding:12vh 1.5rem 1.5rem;background:#0a0a0a59;backdrop-filter:blur(2px);opacity:0;transition:opacity .12s ease}.kmenu-overlay[hidden]{display:none}.kmenu-overlay.is-open{opacity:1}.kmenu-panel{width:100%;max-width:32rem;background:var(--bg);border:1px solid var(--rule);border-radius:12px;box-shadow:0 16px 48px #00000038;overflow:hidden;transform:translateY(-6px);transition:transform .12s ease}.kmenu-overlay.is-open .kmenu-panel{transform:translateY(0)}.kmenu-input{width:100%;box-sizing:border-box;border:none;border-bottom:1px solid var(--rule);background:transparent;color:var(--fg);font-family:var(--sans);font-size:1rem;padding:1rem 1.1rem;outline:none}.kmenu-input::placeholder{color:var(--muted)}.kmenu-list{list-style:none;margin:0;padding:.4rem;max-height:48vh;overflow-y:auto}.kmenu-group{padding:.6rem .7rem .3rem;font-size:.72rem;letter-spacing:.04em;text-transform:uppercase;color:var(--muted)}.kmenu-option{display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:.55rem .7rem;border-radius:8px;cursor:pointer;color:var(--fg)}.kmenu-option.is-active{background:var(--rule)}.kmenu-option-label{font-size:.95rem}.kmenu-option-hint{font-size:.8rem;color:var(--muted);font-variant-numeric:tabular-nums;flex-shrink:0}.kmenu-empty{padding:1.4rem;text-align:center;color:var(--muted);font-size:.9rem}.kmenu-footer{display:flex;gap:1.1rem;padding:.6rem 1.1rem;border-top:1px solid var(--rule);font-size:.78rem;color:var(--muted)}.kmenu-footer span{display:inline-flex;align-items:center;gap:.3rem}@media(max-width:480px){.kmenu-overlay{padding:8vh 1rem 1rem}.kmenu-footer{display:none}}
