@font-face { font-family: "VT323 Local"; src: url("/fonts/VT323-Regular.ttf") format("truetype"); font-display: swap; font-style: normal; font-weight: 400; } :root { --desktop: #c8c8c8; --paper: #ffffff; --ink: #000000; --muted: #2f2f2f; --faint: #555555; --line: #000000; --soft: #efefef; --accent: #000000; --code: #ffffff; --code-ink: #000000; --code-fill: #f5f5f5; --figure-paper: #ffffff; --figure-ink: #111111; --article-width: 42rem; --article-half-width: 21rem; --margin-width: 9rem; --margin-gap: 1.5rem; --panel-padding: 0.85rem; --section-gap: 1.1rem; --bottom-scroll-room: 38vh; --row-padding: 0.2rem; --rule: 2px; --control-size: 0.66rem; --dither-size: 8px; --dither-alpha: 0.08; --scanline-alpha: 0.055; --scanline-soft-alpha: 0.018; --scanline-size: 7px; --scanline-width: 2px; --vignette-alpha: 0.07; --body-font: Monaco, Menlo, "SF Mono", ui-monospace, Consolas, "Courier New", monospace; --display-font: "VT323 Local", "Print Char 21", "Web437 Apple II", "Apple II Screen Typeface", var(--body-font); --signature-font: "Snell Roundhand", "Apple Chancery", "Brush Script MT", "Segoe Script", cursive; } html[data-density="comfortable"] { --panel-padding: 1.1rem; --section-gap: 1.45rem; --row-padding: 0.35rem; --margin-gap: 2rem; } html[data-display="clean"] { --desktop: #eeeeee; --dither-alpha: 0; --scanline-alpha: 0; --vignette-alpha: 0; } html[data-display="plain"] { --desktop: #ffffff; --dither-alpha: 0; --scanline-alpha: 0; --vignette-alpha: 0; } * { box-sizing: border-box; } html { color: var(--ink); background: var(--desktop); font-family: var(--body-font); font-size: 18px; line-height: 1.45; scroll-behavior: smooth; -webkit-font-smoothing: none; font-smooth: never; image-rendering: pixelated; cursor: url("/cursors/mac-arrow.png") 1 1, default; } body { margin: 0; counter-reset: sidenote; background: linear-gradient(45deg, rgb(0 0 0 / var(--dither-alpha)) 25%, transparent 25% 75%, rgb(0 0 0 / var(--dither-alpha)) 75%), linear-gradient(45deg, rgb(0 0 0 / var(--dither-alpha)) 25%, transparent 25% 75%, rgb(0 0 0 / var(--dither-alpha)) 75%), var(--desktop); background-position: 0 0, calc(var(--dither-size) / 2) calc(var(--dither-size) / 2); background-size: var(--dither-size) var(--dither-size); font-weight: 500; } body::before { content: ""; position: fixed; inset: 0; z-index: 9999; pointer-events: none; background: repeating-linear-gradient( to bottom, transparent 0, transparent calc(var(--scanline-size) - var(--scanline-width) - 1px), rgb(0 0 0 / var(--scanline-soft-alpha)) calc(var(--scanline-size) - var(--scanline-width) - 1px), rgb(0 0 0 / var(--scanline-alpha)) calc(var(--scanline-size) - var(--scanline-width)), rgb(0 0 0 / var(--scanline-alpha)) var(--scanline-size) ), radial-gradient(circle at center, transparent 62%, rgb(0 0 0 / var(--vignette-alpha))); background-size: 100% auto, 100% 100%; mix-blend-mode: multiply; } html[data-display="clean"] body::before, html[data-display="plain"] body::before { display: none; } ::selection { background: #d0d0d0; color: var(--ink); } a { color: inherit; text-decoration: none; cursor: url("/cursors/mac-hand.png") 11 1, pointer; } a:hover { background: var(--ink); color: var(--paper); } a:active { transform: translate(1px, 1px); } a:focus-visible, button:focus-visible { outline: var(--rule) solid var(--ink); outline-offset: 2px; background: var(--ink); color: var(--paper); } button, label, summary, [role="button"] { cursor: url("/cursors/mac-hand.png") 11 1, pointer; } :target { scroll-margin-top: 2rem; } .post-content figure:target, .post-content .sidenote:target, .post-content .footnotes li:target, .post-content sup:target { outline: var(--rule) solid var(--line); outline-offset: 0.18rem; } .home { position: relative; width: var(--article-width); max-width: calc(100vw - 2.5rem); margin: 1.5rem auto; background: var(--paper); border: var(--rule) solid var(--line); padding: var(--panel-padding); } .home-intro h1 { margin: 0 0 0.28rem; color: var(--ink); font-family: var(--signature-font); font-size: 2.45rem; font-style: italic; font-weight: 600; line-height: 0.95; letter-spacing: 0; -webkit-font-smoothing: antialiased; } .home-intro p { margin: 0; font-size: 0.95rem; font-weight: 500; line-height: 1.35; color: var(--muted); } .social-links { position: absolute; top: var(--panel-padding); right: var(--panel-padding); display: flex; flex-wrap: wrap; gap: 0.28rem; } .social-link { display: inline-flex; align-items: center; justify-content: center; width: 1.5rem; height: 1.5rem; border: var(--rule) solid var(--line); background: var(--paper); box-shadow: 1px 1px 0 var(--line); } .social-link img { display: block; width: 0.95rem; height: 0.95rem; image-rendering: auto; } .social-link:hover, .social-link:focus-visible { background: var(--ink); color: var(--paper); } .social-link:hover img, .social-link:focus-visible img { filter: invert(1); } .social-link:active { box-shadow: none; transform: translate(1px, 1px); } .file-index { margin-top: var(--section-gap); } .file-tabs { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.12rem; padding-left: 0.25rem; border-bottom: var(--rule) solid var(--line); } .file-tab { display: block; margin-bottom: calc(-1 * var(--rule)); padding: 0.08rem 0.55rem 0.1rem; border: var(--rule) solid var(--line); background: var(--soft); box-shadow: none; font-family: var(--display-font); font-size: 1.12rem; line-height: 1.05; } .file-tab.active { position: relative; z-index: 1; border-bottom-color: var(--paper); background: var(--paper); color: var(--ink); transform: none; } .file-tab:hover, .file-tab:focus-visible { background: var(--ink); color: var(--paper); } .file-tab:not(.active):active { transform: translate(1px, 1px); } .file-tab.active:hover, .file-tab.active:focus-visible { background: var(--paper); color: var(--ink); } .file-panel { min-height: 3rem; padding: 0.34rem 0.42rem 0.42rem; border: var(--rule) solid var(--line); border-top: 0; } .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; } .item-list { display: grid; gap: 0.22rem; } .item-row { display: grid; grid-template-columns: 3.25rem minmax(0, 1fr); gap: 0.28rem; align-items: start; padding: 0.16rem 0.32rem 0.2rem; border: var(--rule) solid var(--line); background: var(--paper); box-shadow: 2px 2px 0 var(--line); } .item-row[data-row-href] { cursor: url("/cursors/mac-hand.png") 11 1, pointer; } .item-row[data-row-href]:hover, .item-row[data-row-href]:focus-visible { box-shadow: 3px 3px 0 var(--line); } .item-row.is-pressed { background: var(--ink); color: var(--paper); box-shadow: none; transform: translate(2px, 2px); } .item-row.is-pressed .row-summary, .item-row.is-pressed .item-year, .item-row.is-pressed .item-status { color: var(--paper); } .item-row + .item-row { border-top: var(--rule) solid var(--line); } .post-list { border-bottom: 0; } .tag-filter-status { display: flex; justify-content: space-between; gap: 0.75rem; margin: 0 0 0.35rem; padding-bottom: 0.3rem; border-bottom: var(--rule) solid var(--line); color: var(--muted); font-size: 0.75rem; font-weight: 600; } .tag-filter-status[hidden] { display: none; } .tag-filter-status a { align-self: baseline; padding: 0 0.22rem; border: var(--rule) solid var(--line); background: var(--paper); color: var(--ink); line-height: 1.1; } .tag-filter-status a:hover, .tag-filter-status a:focus-visible { background: var(--soft); color: var(--ink); } .tag-filter-status a:active { transform: translate(1px, 1px); } .post-row { display: grid; grid-template-columns: 5.85rem minmax(0, 1fr); gap: 0.65rem; align-items: baseline; padding: var(--row-padding) 0; border-top: 0; } .post-row[hidden] { display: none; } .post-row time, .item-year, .post-meta, .item-links { font-size: 0.78rem; font-weight: 600; color: var(--muted); } .post-row time { white-space: nowrap; } .post-title, .item-title { font-family: var(--display-font); font-size: 1.32rem; font-weight: 400; } .item-title { flex: 0 0 auto; font-size: 1.12rem; line-height: 1.05; } .item-title:hover, .item-title:focus-visible { background: transparent; color: var(--ink); } .item-title:active { transform: none; } .item-row.is-pressed .item-title, .item-row.is-pressed .item-status { color: var(--paper); } .post-row-body { display: flex; flex-wrap: wrap; gap: 0.35rem; align-items: baseline; line-height: 1.25; } .item-body { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0.08rem 0.48rem; align-items: baseline; min-width: 0; line-height: 1.15; } .item-head { display: flex; gap: 0.32rem; align-items: baseline; min-width: 0; } .post-title-tags { display: inline-flex; flex-wrap: wrap; gap: 0.18rem; font-family: var(--body-font); font-size: 0.72rem; font-weight: 600; line-height: 1.2; color: var(--muted); } .post-tag { padding: 0 0.08rem; } .post-tag::before { content: "["; } .post-tag::after { content: "]"; } .post-tag.active { background: var(--ink); color: var(--paper); } .post-meta { display: flex; flex-wrap: wrap; gap: 0.25rem; align-items: baseline; } .dot { color: var(--faint); margin: 0 0.15rem; } .row-summary { grid-column: 1 / -1; min-width: 4rem; margin: 0; padding-left: 1rem; overflow: hidden; color: var(--muted); font-size: 0.78rem; line-height: 1.1; text-overflow: ellipsis; white-space: nowrap; } .item-status { display: inline-block; color: var(--muted); font-size: 0.72rem; font-weight: 600; line-height: 1.1; white-space: nowrap; } .item-status::before { content: "ยท "; color: var(--faint); } .item-side { grid-column: 2; grid-row: 1; display: flex; flex-wrap: wrap; margin-left: auto; gap: 0.18rem 0.4rem; align-items: baseline; justify-content: flex-end; min-width: 0; } .item-links { display: inline-flex; flex-wrap: wrap; gap: 0.42rem; margin: 0; } .item-links a { display: inline-block; padding: 0.06rem 0.36rem 0.08rem; border: 1px solid currentColor; background: var(--paper); color: var(--ink); box-shadow: 1px 1px 0 currentColor; line-height: 1.1; } .item-links a:hover, .item-links a:focus-visible { background: var(--ink); color: var(--paper); } .item-links a:active { box-shadow: none; transform: translate(1px, 1px); } .article-links { margin-top: 0.8rem; } .empty-list { margin: 0; color: var(--muted); font-size: 0.85rem; font-weight: 600; } .contact-section { margin-top: var(--section-gap); padding: 0.34rem 0.42rem 0.42rem; border: var(--rule) solid var(--line); } .file-panel .contact-section { margin: 0; padding: 0; border: 0; } .contact-section h2 { margin: 0 0 0.12rem; font-family: var(--display-font); font-size: 1.12rem; font-weight: 400; line-height: 1.05; } .contact-section p { margin: 0; color: var(--muted); font-size: 0.82rem; line-height: 1.2; } .contact-section a { color: var(--ink); font-weight: 600; } .contact-section a:hover, .contact-section a:focus-visible { background: var(--ink); color: var(--paper); } .post { margin: 1.5rem auto; padding: 0 1.25rem var(--bottom-scroll-room); } .post-layout { position: relative; width: var(--article-width); max-width: calc(100vw - 2.5rem); margin: 0 auto; } .post-header { margin: 0 0 1.35rem; } .back-link, .post-button { display: inline-block; min-width: 3.2rem; padding: 0.08rem 0.45rem; border: var(--rule) solid var(--line); background: var(--paper); box-shadow: inset 0 0 0 1px var(--paper); text-align: center; font-size: 0.78rem; font-weight: 600; line-height: 1.25; color: var(--ink); } .back-link:hover, .post-button:hover, .back-link:focus-visible, .post-button:focus-visible { background: var(--ink); color: var(--paper); } .back-link:active, .post-button:active { transform: translate(1px, 1px); } .post-header h1 { margin: 0.55rem 0 0.15rem; color: var(--ink); font-family: var(--display-font); font-size: 2.25rem; font-weight: 400; line-height: 1.06; letter-spacing: 0; } .post-shell { width: 100%; max-width: 100%; margin: 0; background: var(--paper); border: var(--rule) solid var(--line); padding: var(--panel-padding); } .post-content { width: 100%; min-width: 0; font-size: 0.95rem; line-height: 1.55; } .post-footer { margin-top: 1.25rem; padding-top: 0.65rem; border-top: var(--rule) solid var(--line); text-align: right; } .post-content > :first-child { margin-top: 0; } .post-content h2, .post-content h3, .post-content h4 { font-family: var(--display-font); line-height: 1.18; font-weight: 400; letter-spacing: 0; margin-top: 1.75em; margin-bottom: 0.45em; } .post-content h2 { font-size: 1.65rem; } .post-content h3 { font-size: 1.35rem; } .post-content h4 { font-size: 1rem; } .post-content p, .post-content ul, .post-content ol, .post-content blockquote, .post-content pre, .post-content table, .post-content figure, .post-content .highlight { margin-top: 0.9rem; margin-bottom: 0.7rem; } .post-content strong, .post-content b { color: var(--ink); font-weight: 900; text-shadow: 0.035em 0 0 var(--ink); } .post-content blockquote { margin-left: 0; padding: 0.55rem 0.75rem; border: var(--rule) solid var(--line); background: var(--soft); color: var(--muted); } .post-content code { font-size: 0.9em; background: repeating-linear-gradient(45deg, rgb(0 0 0 / 0.08) 0 1px, transparent 1px 4px), var(--code-fill); color: var(--ink); padding: 0.04rem 0.22rem; border: var(--rule) solid var(--line); } .post-content .highlight { background: var(--paper); border: var(--rule) solid var(--line); padding: 0; } .post-content .highlight::before { content: "Code"; display: block; padding: 0.08rem 0.45rem; border-bottom: var(--rule) solid var(--line); background: linear-gradient(var(--paper), var(--paper)) center / 5rem 100% no-repeat, repeating-linear-gradient(0deg, var(--paper) 0 2px, var(--ink) 2px 4px); color: var(--ink); font-family: var(--display-font); font-size: 1.05rem; font-weight: 400; line-height: 1.05; text-align: center; } .post-content .highlight:has(.language-python)::before { content: "Python"; } .post-content .highlight:has(.language-sh)::before, .post-content .highlight:has(.language-bash)::before, .post-content .highlight:has(.language-zsh)::before { content: "Shell"; } .post-content pre { overflow-x: auto; margin: 0; padding: 0.65rem 0.75rem; background: var(--code); color: var(--code-ink); border: 0; font-size: 0.84rem; line-height: 1.45; } .post-content .highlight pre { margin: 0; } .post-content pre code { background: transparent; padding: 0; border: 0; color: inherit; } .chroma .line { display: block; min-height: 1.45em; } .chroma .c, .chroma .c1, .chroma .cm, .chroma .cp, .chroma .cs { color: var(--faint); } .chroma .k, .chroma .kc, .chroma .kd, .chroma .kn, .chroma .kp, .chroma .kr, .chroma .kt, .chroma .nf, .chroma .nc { font-weight: 700; } .chroma .s, .chroma .s1, .chroma .s2 { background: var(--soft); } .post-content img { max-width: 100%; height: auto; } .post-content table { display: block; width: 100%; overflow-x: auto; border-collapse: collapse; border: var(--rule) solid var(--line); font-size: 0.82rem; } .post-content th, .post-content td { border-bottom: var(--rule) solid var(--line); padding: 0.45rem 0.35rem; text-align: left; vertical-align: top; } .post-content figure { margin-left: 0; margin-right: 0; padding: 0.8rem; background: var(--figure-paper); color: var(--figure-ink); border: var(--rule) solid var(--line); text-shadow: none; } .post-content figcaption { margin-top: 0.55rem; font-size: 0.78rem; font-weight: 600; line-height: 1.45; color: var(--muted); } .figure-label { color: var(--ink); font-weight: 600; } .xref { font-size: 0.9em; } .katex-display { overflow-x: auto; overflow-y: hidden; padding-bottom: 0.1rem; } .post-margin { width: 100%; margin-left: 0; margin-bottom: 1rem; position: static; max-height: calc(100vh - 6rem); overflow: auto; font-size: 0.72rem; font-weight: 600; color: var(--ink); background: var(--paper); border: var(--rule) solid var(--line); padding: 0; } .toc-title { margin: 0; padding: 0.08rem 0.35rem; border-bottom: var(--rule) solid var(--line); background: linear-gradient(var(--paper), var(--paper)) center / 4.6rem 100% no-repeat, repeating-linear-gradient(0deg, var(--paper) 0 2px, var(--ink) 2px 4px); color: var(--ink); font-family: var(--display-font); font-size: 1rem; font-weight: 400; line-height: 1.05; text-align: center; } #TableOfContents ul { list-style: none; padding-left: 0; margin: 0; } #TableOfContents > ul { padding: 0.28rem; } #TableOfContents ul ul { padding-left: 0.55rem; margin-top: 0.08rem; } #TableOfContents li { margin: 0.06rem 0; } #TableOfContents a { display: block; padding: 0.04rem 0.12rem; text-decoration: none; line-height: 1.18; white-space: normal; } #TableOfContents ul ul a { font-size: 0.68rem; font-weight: 600; } #TableOfContents a.active { background: var(--ink); color: var(--paper); font-weight: 600; } .sidenote-number { counter-increment: sidenote; } .sidenote-number::after { content: counter(sidenote); margin-left: 0.12rem; color: var(--accent); font-size: 0.78rem; vertical-align: super; } .sidenote { float: right; clear: right; width: 12rem; margin-top: 0.25rem; margin-right: -14rem; margin-bottom: 0.75rem; color: var(--ink); font-size: 0.78rem; line-height: 1.45; } .sidenote::before { content: counter(sidenote); margin-right: 0.35rem; color: var(--accent); font-size: 0.78rem; vertical-align: super; } .sidenote p { display: inline; margin: 0; } @media (min-width: 1281px) { .post-layout.has-toc { display: grid; grid-template-columns: var(--margin-width) var(--margin-gap) minmax(0, var(--article-width)); width: calc(var(--margin-width) + var(--margin-gap) + var(--article-width)); max-width: none; margin-left: calc(50% - var(--margin-width) - var(--margin-gap) - var(--article-half-width)); margin-right: 0; } .post-layout.has-toc .post-shell { grid-column: 3; grid-row: 1; } .post-layout.has-toc .post-margin { grid-column: 1; grid-row: 1; width: var(--margin-width); margin-top: 0; margin-bottom: 0; position: fixed; top: 4rem; left: calc(50% - var(--article-half-width) - var(--margin-gap) - var(--margin-width)); align-self: start; } } @media (max-width: 1280px) { .post-margin { max-height: none; margin-bottom: 2rem; padding-top: 1rem; } .sidenote { display: none; float: none; width: auto; margin: 0.75rem 0; padding: 0.75rem; background: var(--soft); border: var(--rule) solid var(--accent); } .sidenote:target { display: block; } } @media (max-width: 860px) { :root { --panel-padding: 0.72rem; --section-gap: 0.8rem; --bottom-scroll-room: 34vh; --dither-alpha: 0.055; --scanline-alpha: 0.045; --scanline-soft-alpha: 0.014; --vignette-alpha: 0.045; } html { font-size: 16px; } .home, .post { margin-top: 0.75rem; } .home { max-width: calc(100vw - 1rem); } .post { padding-right: 0.5rem; padding-left: 0.5rem; } .post-layout { max-width: calc(100vw - 1rem); } .home-intro h1, .post-header h1 { font-size: 2rem; } .social-links { position: static; gap: 0.22rem; margin-top: 0.45rem; } .file-tabs { flex-wrap: nowrap; gap: 0.08rem; overflow-x: auto; padding-left: 0.12rem; scrollbar-width: none; } .file-tabs::-webkit-scrollbar { display: none; } .file-tab { flex: 0 0 auto; padding-right: 0.42rem; padding-left: 0.42rem; font-size: 1rem; } .file-panel { padding: 0.42rem 0.48rem 0.5rem; } .post-row, .item-row { grid-template-columns: 1fr; gap: 0.08rem; padding: 0.36rem 0; } .post-row + .post-row { border-top: var(--rule) solid var(--line); } .item-row + .item-row { border-top: 1px solid var(--line); } .item-body { grid-template-columns: 1fr; gap: 0.1rem; } .item-side { grid-column: 1; grid-row: auto; margin-left: 0; justify-content: flex-start; } .row-summary { grid-column: 1; } .post-row time, .item-year, .post-meta, .item-meta, .item-links { font-size: 0.72rem; } .post-title, .item-title { font-size: 1.22rem; } .post-title-tags { font-size: 0.68rem; } .post-header { margin-bottom: 1rem; } .post-header h1 { overflow-wrap: anywhere; font-size: 1.85rem; } .post-shell { padding: 0.7rem; } .post-content { font-size: 0.92rem; line-height: 1.5; } .post-content h2 { font-size: 1.42rem; } .post-content h3 { font-size: 1.18rem; } .post-content code { overflow-wrap: anywhere; } .post-content pre { padding: 0.55rem 0.6rem; font-size: 0.78rem; } .post-content table { font-size: 0.76rem; } .post-content figure { padding: 0.45rem; } .post-content figcaption { font-size: 0.72rem; } .post-margin { max-height: 12rem; margin-bottom: 1rem; padding-top: 0; overflow: auto; font-size: 0.72rem; } .toc-title { font-size: 0.95rem; } #TableOfContents > ul { padding: 0.22rem; } } @media (max-width: 420px) { .home-intro h1 { font-size: 1.8rem; } .home-intro p { font-size: 0.88rem; } .social-link { width: 1.42rem; height: 1.42rem; } .social-link img { width: 0.88rem; height: 0.88rem; } .file-tab { padding-right: 0.34rem; padding-left: 0.34rem; font-size: 0.95rem; } .post-title, .item-title { font-size: 1.12rem; } .post-header h1 { font-size: 1.65rem; } } @media (prefers-reduced-transparency: reduce), (prefers-contrast: more) { :root { --dither-alpha: 0; --scanline-alpha: 0; --vignette-alpha: 0; } body::before { display: none; } } @media print { :root { --desktop: #ffffff; --dither-alpha: 0; --scanline-alpha: 0; --vignette-alpha: 0; } body { background: #ffffff; } body::before, .post-margin { display: none; } .home, .post-shell { width: auto; max-width: none; margin: 0; border: 0; } }