Something went wrong. Try again.
Monorepo for Aesthetic.Computer aesthetic.computer
Something went wrong. Try again.
HTML
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="icon" href="/icon/128x128/prompt.png" type="image/png"><title>aesthetic.computer is home to · Aesthetic Computer</title><meta property="og:title" content="aesthetic.computer is home to"><meta property="og:description" content="30 domains & subdomains, ~355 disk routes, ~85 API endpoints, and more across the Aesthetic Computer network."><meta property="og:image" content="https://aesthetic.computer/preview/1200x630/prompt.png"><meta property="og:url" content="https://sitemap.aesthetic.computer"><meta property="og:type" content="website"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:image" content="https://aesthetic.computer/preview/1200x630/prompt.png"><style> ::-webkit-scrollbar { display: none; } html { cursor: url("/aesthetic.computer/cursors/precise.svg") 12 12, auto; } body { margin: 0; font-size: 15px; font-family: monospace; -webkit-text-size-adjust: none; overflow-x: hidden; line-height: 1.45; } h1 { font-weight: normal; font-size: 15px; margin: 0 0 0.35em; } h1 a, h1 a:visited { color: inherit; cursor: inherit; text-decoration: none; } #pals { position: fixed; bottom: 5px; right: 12px; user-select: none; z-index: 10; } section.main { margin: 8px 12px; } .stats { display: flex; gap: 0.5em; flex-wrap: wrap; margin-bottom: 0.75em; font-size: 0.85em; } .stat { padding: 0.25em 0.5em; border-radius: 3px; } .stat strong { font-size: 1.1em; } #search { border: 1px solid; padding: 0.3em 0.5em; font-family: inherit; font-size: 1em; width: 100%; max-width: 22em; border-radius: 3px; margin-bottom: 0.75em; outline: none; cursor: inherit; } #search::placeholder { opacity: 0.4; } .card { border-radius: 3px; margin-bottom: 0.4em; overflow: hidden; } details > summary { padding: 0.35em 0.6em; cursor: inherit; user-select: none; display: flex; align-items: center; gap: 0.4em; list-style: none; font-size: 0.9em; } details > summary::-webkit-details-marker { display: none; } details > summary::before { content: "\25b6"; font-size: 0.5em; transition: transform 0.2s; opacity: 0.4; } details[open] > summary::before { transform: rotate(90deg); } .tag { font-size: 0.55em; padding: 1px 4px; border-radius: 2px; font-weight: bold; text-transform: uppercase; letter-spacing: 0.03em; } .section-title { font-weight: bold; font-size: 0.95em; } .section-count { opacity: 0.35; font-size: 0.75em; margin-left: auto; } .section-desc { font-size: 0.78em; opacity: 0.6; padding: 0.2em 0.6em 0.4em; line-height: 1.5; } .routes { padding: 0.3em 0.6em; display: grid; grid-template-columns: repeat(auto-fill, minmax(13em, 1fr)); gap: 0.1em 0.6em; max-height: 32em; overflow-y: auto; } .routes.single-col { grid-template-columns: 1fr; } .route { font-size: 0.78em; padding: 1px 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .route::before { content: "/"; opacity: 0.3; } .route.full-url::before { content: ""; } .route-group-label { font-size: 0.68em; padding: 0.4em 0.6em 0.1em; text-transform: uppercase; letter-spacing: 0.05em; font-weight: bold; grid-column: 1 / -1; } .redirect-row { font-size: 0.76em; padding: 2px 0; display: grid; grid-template-columns: 1fr auto 1fr auto; gap: 0.3em; align-items: center; } .redirect-from { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .redirect-arrow { opacity: 0.3; } .redirect-to { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .redirect-status { font-size: 0.65em; padding: 1px 3px; border-radius: 2px; font-weight: bold; } .dynamic-pattern { font-size: 0.76em; padding: 2px 0; font-style: italic; } .dynamic-pattern::before { content: "\2731 "; } .note { font-size: 0.7em; opacity: 0.35; padding: 0.3em 0.6em; } .hidden { display: none !important; }
/* Status lights inline */ .service-light { width: 0.55em; height: 0.55em; border-radius: 50%; flex-shrink: 0; display: inline-block; } .service-light-green { background: rgb(92, 205, 155); box-shadow: 0 0 0 1px rgba(92, 205, 155, 0.25), 0 0 0.3em rgba(92, 205, 155, 0.5); } .service-light-yellow { background: rgb(205, 155, 92); box-shadow: 0 0 0 1px rgba(205, 155, 92, 0.25), 0 0 0.3em rgba(205, 155, 92, 0.4); } .service-light-red { background: rgb(230, 102, 102); box-shadow: 0 0 0 1px rgba(230, 102, 102, 0.25), 0 0 0.3em rgba(230, 102, 102, 0.5); } .service-light-unknown { background: rgba(200, 200, 200, 0.4); box-shadow: 0 0 0 1px rgba(200, 200, 200, 0.15); } .live-status-bar { font-size: 0.7em; opacity: 0.5; padding: 0.5em 0 0.25em; }
.card-thumb { width: 24px; height: 24px; border-radius: 3px; object-fit: cover; flex-shrink: 0; display: block; }
/* Dark mode */ @media (prefers-color-scheme: dark) { body { background-color: rgb(64, 56, 74); color: rgba(255, 255, 255, 0.85); } h1 a:hover { color: rgb(205, 92, 155); } .stat { background: rgba(255,255,255,0.06); } .stat strong { color: rgb(92, 205, 155); } #search { background: rgba(255,255,255,0.06); border-color: rgba(255,255,255,0.15); color: rgba(255,255,255,0.85); } #search:focus { border-color: rgb(205, 92, 155); } .card { background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08); } details > summary:hover { background: rgba(255,255,255,0.04); } .tag-primary { background: rgb(205, 92, 155); color: #fff; } .tag-subdomain { background: rgb(92, 205, 155); color: rgb(20, 40, 30); } .tag-redirect { background: rgb(205, 155, 92); color: rgb(40, 30, 20); } .tag-api { background: rgb(92, 155, 205); color: rgb(20, 30, 40); } .tag-external { background: rgba(255,255,255,0.15); color: rgba(255,255,255,0.7); } .tag-infra { background: rgba(255,255,255,0.15); color: rgba(255,255,255,0.7); } .route-group-label { color: rgb(92, 205, 155); } .redirect-to { color: rgb(92, 205, 155); } .dynamic-pattern { color: rgb(155, 120, 205); } .dynamic-pattern::before { color: rgb(205, 92, 155); } .status-200 { background: rgba(92, 205, 155, 0.2); color: rgb(92, 205, 155); } .status-301 { background: rgba(205, 155, 92, 0.2); color: rgb(205, 155, 92); } .status-302 { background: rgba(155, 120, 205, 0.2); color: rgb(155, 120, 205); } a, a:visited { color: rgb(205, 92, 155); } .card-thumb { background: rgba(255,255,255,0.06); } }
/* Light mode */ @media (prefers-color-scheme: light) { body { background-color: rgba(244, 235, 250); color: rgb(64, 56, 74); } h1 a:hover { color: rgb(205, 92, 155); } .stat { background: rgba(64, 56, 74, 0.06); } .stat strong { color: rgb(30, 120, 80); } #search { background: rgba(64, 56, 74, 0.04); border-color: rgba(64, 56, 74, 0.2); color: rgb(64, 56, 74); } #search:focus { border-color: rgb(205, 92, 155); } .card { background: rgba(64, 56, 74, 0.04); border: 1px solid rgba(64, 56, 74, 0.08); } details > summary:hover { background: rgba(64, 56, 74, 0.04); } .tag-primary { background: rgb(180, 72, 135); color: #fff; } .tag-subdomain { background: rgb(30, 140, 90); color: #fff; } .tag-redirect { background: rgb(180, 130, 60); color: #fff; } .tag-api { background: rgb(60, 120, 180); color: #fff; } .tag-external { background: rgba(64, 56, 74, 0.15); color: rgb(64, 56, 74); } .tag-infra { background: rgba(64, 56, 74, 0.15); color: rgb(64, 56, 74); } .route-group-label { color: rgb(30, 140, 90); } .redirect-to { color: rgb(30, 140, 90); } .dynamic-pattern { color: rgb(120, 80, 180); } .dynamic-pattern::before { color: rgb(180, 72, 135); } .status-200 { background: rgba(30, 140, 90, 0.15); color: rgb(20, 100, 60); } .status-301 { background: rgba(180, 130, 60, 0.15); color: rgb(140, 100, 40); } .status-302 { background: rgba(120, 80, 180, 0.15); color: rgb(100, 60, 160); } a, a:visited { color: rgb(180, 72, 135); } .card-thumb { background: rgba(64,56,74,0.06); } }
@media (max-width: 600px) { .routes { grid-template-columns: 1fr; } .redirect-row { grid-template-columns: 1fr; gap: 0.1em; } .stats { flex-direction: column; } }</style></head><body>
<section class="main"><h1><span id="title"><a href="/sitemap">aesthetic.computer is home to</a></span></h1>
<div><div class="stats"> <div class="stat">Domains & Subdomains: <strong>30</strong></div> <div class="stat">Disk Routes: <strong>~355</strong></div> <div class="stat">API Endpoints: <strong>~85</strong></div> <div class="stat">Functions: <strong>~106</strong></div> <div class="stat">Redirects: <strong>~120</strong></div></div>
<input type="text" id="search" placeholder="Filter routes..." autofocus><div class="live-status-bar" id="live-status-bar">Loading service statuses...</div></div>
<!-- aesthetic.computer --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/prompt.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="Netlify"></span> <span class="tag tag-primary">Primary</span> <span class="section-title">aesthetic.computer</span> <span class="section-count">~355 disk routes</span></summary><div class="section-desc">The main platform. A creative computing environment where every .mjs disk becomes a live, shareable tool — drawing, music, games, programming, and more. User profiles live at /@handle.</div><div class="route-group-label">Core / Navigation</div><div class="routes"> <div class="route">about</div> <div class="route">ads</div> <div class="route">opinion</div> <div class="route">login-pattern</div> <div class="route">login-wait</div> <div class="route">profile</div> <div class="route">handle</div> <div class="route">handles</div> <div class="route">get-handle</div> <div class="route">connect-wallet</div> <div class="route">wallet</div> <div class="route">token</div> <div class="route">desktop</div> <div class="route">download</div> <div class="route">delete-erase-and-forget-me</div> <div class="route">404</div> <div class="route">error</div> <div class="route">support</div> <div class="route">privacy-policy</div> <div class="route">aesthetic-direct</div></div><div class="route-group-label">Creative Tools / Drawing</div><div class="routes"> <div class="route">paint</div> <div class="route">nopaint</div> <div class="route">line</div> <div class="route">pline</div> <div class="route">oldline</div> <div class="route">shape</div> <div class="route">oldshape</div> <div class="route">oval</div> <div class="route">rect</div> <div class="route">fill</div> <div class="route">spray</div> <div class="route">smear</div> <div class="route">marker</div> <div class="route">crayon</div> <div class="route">sparkle-brush</div> <div class="route">multipen</div> <div class="route">doodle</div> <div class="route">wand</div> <div class="route">oldwand</div> <div class="route">crop</div> <div class="route">stamp</div> <div class="route">stample</div> <div class="route">blur</div> <div class="route">wipe</div> <div class="route">snap</div> <div class="route">paste</div> <div class="route">pull</div> <div class="route">oldpull</div> <div class="route">make</div> <div class="route">oldmake</div> <div class="route">painting</div> <div class="route">handprint</div> <div class="route">nail</div> <div class="route">colors</div> <div class="route">colplay</div> <div class="route">gradient-test</div> <div class="route">graphics</div> <div class="route">plot</div> <div class="route">icon</div> <div class="route">images</div> <div class="route">selfie</div> <div class="route">camera</div> <div class="route">cards</div></div><div class="route-group-label">Music / Audio</div><div class="routes"> <div class="route">notepat</div> <div class="route">notepat-tv</div> <div class="route">beat</div> <div class="route">tone</div> <div class="route">chord</div> <div class="route">melody</div> <div class="route">song</div> <div class="route">sing</div> <div class="route">bleep</div> <div class="route">say</div> <div class="route">whistle</div> <div class="route">metronome</div> <div class="route">microphone</div> <div class="route">uke</div> <div class="route">pedal</div> <div class="route">amp</div> <div class="route">bgm</div> <div class="route">sfx</div> <div class="route">r8dio</div> <div class="route">baktok</div> <div class="route">squaresong</div> <div class="route">rattle</div> <div class="route">visualizer</div> <div class="route">tracker</div> <div class="route">3x3</div> <div class="route">shh</div></div><div class="route-group-label">KidLisp / Programming</div><div class="routes"> <div class="route">kidlisp</div> <div class="route">kidlisp-piece</div> <div class="route">kidlisp-in-js</div> <div class="route">kidlisp-gb-test</div> <div class="route">debug-kidlisp-hud</div> <div class="route">keep</div> <div class="route">kept</div> <div class="route">learn</div> <div class="route">lang</div> <div class="route">decode</div> <div class="route">encode</div> <div class="route">prompt</div> <div class="route">chat</div> <div class="route">docgen</div> <div class="route">docs/*</div></div><div class="route-group-label">Games / Interactive</div><div class="routes"> <div class="route">game</div> <div class="route">play</div> <div class="route">1v1</div> <div class="route">brick-breaker</div> <div class="route">flap</div> <div class="route">fly</div> <div class="route">hop</div> <div class="route">scawy-snake</div> <div class="route">run&gun</div> <div class="route">gostop</div> <div class="route">staka</div> <div class="route">pond</div> <div class="route">balls</div> <div class="route">box</div> <div class="route">boxes</div> <div class="route">bubble</div> <div class="route">rain</div> <div class="route">sno</div> <div class="route">starfield</div> <div class="route">metaballs</div> <div class="route">noise</div> <div class="route">ant</div> <div class="route">field</div> <div class="route">a-star</div> <div class="route">toss</div></div><div class="route-group-label">Social / Community</div><div class="routes"> <div class="route">mood</div> <div class="route">moods</div> <div class="route">share</div> <div class="route">sign</div> <div class="route">signature</div> <div class="route">mail</div> <div class="route">list</div> <div class="route">insta</div></div><div class="route-group-label">Media / TV / Tapes</div><div class="routes"> <div class="route">tv</div> <div class="route">tapes</div> <div class="route">screen</div> <div class="route">screenshots</div> <div class="route">screentest</div> <div class="route">replay</div> <div class="route">video</div></div><div class="route-group-label">Whistlegraph</div><div class="routes"> <div class="route">whistlegraph</div> <div class="route">wg</div> <div class="route">wgr</div> <div class="route">m2w2</div> <div class="route">wipppps</div> <div class="route">oldwipppps</div> <div class="route">neo-wipppps</div> <div class="route">merry-fade</div></div><div class="route-group-label">Shop / Commerce</div><div class="routes"> <div class="route">mug</div> <div class="route">mugs</div> <div class="route">paintball</div> <div class="route">shop/*</div></div><div class="route-group-label">Utilities / System</div><div class="routes"> <div class="route">blank</div> <div class="route">blank-canvas2d</div> <div class="route">blank-webgl2</div> <div class="route">blank-blend2d</div> <div class="route">blank-thorvg</div> <div class="route">blank-vello</div> <div class="route">debug</div> <div class="route">test</div> <div class="route">perf</div> <div class="route">fps</div> <div class="route">clock</div> <div class="route">clocks</div> <div class="route">demo</div> <div class="route">desk</div> <div class="route">stage</div> <div class="route">keys</div> <div class="route">gamepad</div> <div class="route">gameboy</div> <div class="route">gameboy-lab</div> <div class="route">typecheck</div> <div class="route">gesture</div> <div class="route">pressure</div> <div class="route">transform</div> <div class="route">rotate-text-demo</div> <div class="route">zoom-test</div> <div class="route">cross-tab-test</div> <div class="route">sab</div> <div class="route">udp</div> <div class="route">wave</div> <div class="route">weather</div> <div class="route">commits</div> <div class="route">aframe</div> <div class="route">ableton</div> <div class="route">imessage</div> <div class="route">ptt</div> <div class="route">booted-by</div> <div class="route">run</div> <div class="route">dync</div></div><div class="route-group-label">People / Characters</div><div class="routes"> <div class="route">mom</div> <div class="route">dad</div> <div class="route">brother</div> <div class="route">sister</div> <div class="route">husband</div> <div class="route">wife</div> <div class="route">boyfriend</div> <div class="route">girlfriend</div> <div class="route">kid</div> <div class="route">angel</div> <div class="route">robo</div> <div class="route">sage</div> <div class="route">tobby</div> <div class="route">valbear</div> <div class="route">gargoyle</div> <div class="route">dolls</div></div><div class="route-group-label">Experiments / Misc</div><div class="routes"> <div class="route">liar</div> <div class="route">hell_-world</div> <div class="route">hha</div> <div class="route">hw</div> <div class="route">horizon</div> <div class="route">seashells</div> <div class="route">sparkle</div> <div class="route">sprinkles</div> <div class="route">spline</div> <div class="route">split</div> <div class="route">sprite</div> <div class="route">stick</div> <div class="route">throb</div> <div class="route">tremory</div> <div class="route">triquilt</div> <div class="route">rainbow-x</div> <div class="route">freaky-flowers</div> <div class="route">lmn-flower</div> <div class="route">lmn-petal</div> <div class="route">pip</div> <div class="route">slip</div> <div class="route">word</div> <div class="route">words</div> <div class="route">textfence</div> <div class="route">chart</div> <div class="route">vary</div> <div class="route">ordfish</div> <div class="route">ordsy</div> <div class="route">zzzwap</div> <div class="route">basic-line-pointer</div> <div class="route">phand</div> <div class="route">cap</div> <div class="route">boots</div> <div class="route">bits</div> <div class="route">mobile</div> <div class="route">handtime</div> <div class="route">description</div> <div class="route">autopat</div> <div class="route">deck</div> <div class="route">snappidagg</div> <div class="route">snappidaggs</div> <div class="route">botce</div> <div class="route">alex-row</div> <div class="route">alphapoet</div> <div class="route">amby</div> <div class="route">sb</div> <div class="route">ss</div> <div class="route">mo</div> <div class="route">kpbj</div> <div class="route">slgb</div> <div class="route">prutti</div> <div class="route">hueber</div> <div class="route">merry</div> <div class="route">merryo</div> <div class="route">f3ral3xp</div> <div class="route">digitpain0</div> <div class="route">digitpain1</div> <div class="route">digitpain2</div> <div class="route">digitpain3</div> <div class="route">bundle</div> <div class="route">neural-garden</div> <div class="route">dollhouse</div></div><div class="route-group-label">Language Variants</div><div class="routes"> <div class="route">en</div> <div class="route">es</div> <div class="route">da</div> <div class="route">english</div> <div class="route">spanish</div> <div class="route">danish</div> <div class="route">laer-klokken</div></div><div class="route-group-label">UCLA Course Disks</div><div class="routes"> <div class="route">ucla-1</div> <div class="route">ucla-2</div> <div class="route">ucla-3</div> <div class="route">ucla-3-keyboard</div> <div class="route">ucla-4</div> <div class="route">ucla-4-box</div> <div class="route">ucla-5</div> <div class="route">ucla-6</div> <div class="route">ucla-6-turtle</div> <div class="route">ucla-7</div> <div class="route">ucla-7-balls</div> <div class="route">ucla-7-dial</div> <div class="route">ucla-7-jump</div></div><div class="route-group-label">Single-Letter & Numeric Routes</div><div class="routes"> <div class="route">$</div> <div class="route">0</div><div class="route">1</div><div class="route">2</div><div class="route">3</div><div class="route">4</div><div class="route">5</div><div class="route">6</div><div class="route">7</div><div class="route">8</div><div class="route">9</div> <div class="route">a</div><div class="route">b</div><div class="route">c</div><div class="route">d</div><div class="route">e</div><div class="route">f</div><div class="route">g</div><div class="route">h</div><div class="route">i</div><div class="route">j</div><div class="route">k</div><div class="route">l</div><div class="route">m</div><div class="route">n</div><div class="route">o</div><div class="route">p</div><div class="route">q</div><div class="route">r</div><div class="route">s</div><div class="route">t</div><div class="route">u</div><div class="route">v</div><div class="route">w</div><div class="route">x</div><div class="route">y</div><div class="route">z</div></div><div class="route-group-label">FF1 Device System</div><div class="routes"> <div class="route">ff</div> <div class="route">ff1</div> <div class="route">ff1-debug</div></div><div class="route-group-label">Dynamic Route Patterns</div><div class="routes single-col"> <div class="dynamic-pattern">/* → SPA catch-all via index serverless function</div> <div class="dynamic-pattern">/preview/* → oven.aesthetic.computer screenshot proxy</div> <div class="dynamic-pattern">/icon/* → oven.aesthetic.computer icon proxy</div> <div class="dynamic-pattern">/media/* → edge function (media processing)</div> <div class="dynamic-pattern">/session/* → Jamsocket session creation</div> <div class="dynamic-pattern">/reload/* → Redis cache reload</div> <div class="dynamic-pattern">/@:handle → user profile (dynamic, via index function)</div> <div class="dynamic-pattern">/@:handle/:piece → user piece (dynamic, via index function)</div> <div class="dynamic-pattern">/disks/* → raw disk .mjs files</div> <div class="dynamic-pattern">/assets/* → S3 proxy (assets.aesthetic.computer)</div> <div class="dynamic-pattern">/assets/type/* → local font files (overrides S3)</div></div></details></div>
<!-- API --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/prompt.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="tag tag-api">API</span> <span class="section-title">aesthetic.computer/api/*</span> <span class="section-count">~85 endpoints</span></summary><div class="section-desc">The serverless backbone. Covers auth, user management, KidLisp storage, media processing, payments (Stripe/PayPal), AI (Anthropic/OpenAI), Tezos NFT minting, and more. Also exposes a remote MCP server and machine-readable API docs.</div><div class="route-group-label">Auth & Users</div><div class="routes"> <div class="route">api/authorized</div> <div class="route">api/auth/cli-callback</div> <div class="route">api/auth0-events</div> <div class="route">api/profile/*</div> <div class="route">api/delete-erase-and-forget-me</div> <div class="route">api/email</div> <div class="route">api/unsubscribe</div> <div class="route">api/mail-status</div> <div class="route">api/atproto-user-stats</div> <div class="route">handle</div> <div class="route">user</div> <div class="route">api/handles</div></div><div class="route-group-label">KidLisp & Keeps</div><div class="routes"> <div class="route">api/store-kidlisp</div> <div class="route">api/kidlisp-count</div> <div class="route">api/store-piece</div> <div class="route">api/piece-metadata</div> <div class="route">api/piece-hit</div> <div class="route">api/piece-fans</div> <div class="route">api/keep-mint</div> <div class="route">api/keep-confirm</div> <div class="route">api/keep-update</div> <div class="route">api/bundle-html</div> <div class="route">api/bundle-telemetry</div> <div class="route">api/bundle-telemetry-query</div> <div class="route">api/boot-log</div></div><div class="route-group-label">Media & Tapes</div><div class="routes"> <div class="route">api/track-media</div> <div class="route">api/track-tape</div> <div class="route">api/tape-convert-background</div> <div class="route">api/get-tape</div> <div class="route">api/get-tape-status</div> <div class="route">api/oven-complete</div> <div class="route">api/tv</div> <div class="route">api/tv-tapes</div> <div class="route">api/painting-code</div> <div class="route">api/painting-metadata</div> <div class="route">api/bdf-glyph</div> <div class="route">media-collection/*</div></div><div class="route-group-label">Commerce & Payments</div><div class="routes"> <div class="route">api/print/*</div> <div class="route">api/mug</div> <div class="route">api/mugs</div> <div class="route">api/mockup-gif</div> <div class="route">api/mockup-webp</div> <div class="route">api/ticket/*</div> <div class="route">api/shop</div> <div class="route">api/give</div> <div class="route">api/gives</div> <div class="route">api/give-portal</div> <div class="route">api/give-image</div> <div class="route">api/billing</div> <div class="route">api/metrics</div> <div class="route">api/paypal</div></div><div class="route-group-label">Content & AI</div><div class="routes"> <div class="route">api/ask</div> <div class="route">api/say</div> <div class="route">api/vary</div> <div class="route">api/mood/*</div> <div class="route">api/chat/messages</div> <div class="route">api/news</div> <div class="route">api/news/*</div> <div class="route">api/news/toll</div> <div class="route">api/playlist</div> <div class="route">api/stretched-paintings</div> <div class="route">api/jas-tags</div> <div class="route">api/subscribe-to-topic</div></div><div class="route-group-label">System / Infra</div><div class="routes"> <div class="route">api/version</div> <div class="route">api/logo/*</div> <div class="route">api/logo.png</div> <div class="route">api/pixel/*</div> <div class="route">api/clock</div> <div class="route">api/store-clock</div> <div class="route">api — API docs</div> <div class="route">api/ff1/*</div> <div class="route">mcp — Remote MCP server</div> <div class="route">docs/*</div> <div class="route">docs.json</div> <div class="route">slash</div> <div class="route">run</div> <div class="route">redirect-proxy</div> <div class="route">presigned-upload-url/*</div> <div class="route">presigned-download-url/*</div> <div class="route">.well-known/apple-developer-merchantid-domain-association</div></div></details></div>
<!-- news.aesthetic.computer --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/prompt.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="Netlify"></span> <span class="tag tag-subdomain">Subdomain</span> <span class="section-title">news.aesthetic.computer</span> <span class="section-count">Newsletter</span></summary><div class="section-desc">Server-rendered newsletter with a Stripe-powered paywall. CRUD API for managing posts and a guidelines page for contributors.</div><div class="routes single-col"> <div class="route full-url">news.aesthetic.computer/ — Latest newsletter (SSR)</div> <div class="route full-url">news.aesthetic.computer/guidelines — Posting guidelines</div> <div class="route full-url">news.aesthetic.computer/* — Individual issues</div> <div class="route full-url">news.aesthetic.computer/api/news — News CRUD API</div> <div class="route full-url">news.aesthetic.computer/api/news/* — Issue operations</div> <div class="route full-url">news.aesthetic.computer/api/news/toll — Stripe paywall</div></div></details></div>
<!-- give.aesthetic.computer --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/prompt.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="Netlify"></span> <span class="tag tag-subdomain">Subdomain</span> <span class="section-title">give.aesthetic.computer</span> <span class="section-count">Donations</span></summary><div class="section-desc">Support page for AC. Accepts payments via Stripe with a subscriber portal. Localized into Danish, Spanish, German, and Chinese.</div><div class="routes single-col"> <div class="route full-url">give.aesthetic.computer/ — Main donation page</div> <div class="route full-url">give.aesthetic.computer/da — Danish (DKK)</div> <div class="route full-url">give.aesthetic.computer/es — Spanish (USD)</div> <div class="route full-url">give.aesthetic.computer/de — German (EUR)</div> <div class="route full-url">give.aesthetic.computer/cn — Chinese (USD)</div> <div class="route full-url">give.aesthetic.computer/api/give → Stripe payment</div> <div class="route full-url">give.aesthetic.computer/api/give-portal → Stripe portal</div> <div class="route full-url">give.aesthetic.computer/api/billing → Billing data</div></div></details></div>
<!-- shop.aesthetic.computer --><div class="card"><details><summary> <img class="card-thumb" src="https://icons.duckduckgo.com/ip3/shop.aesthetic.computer.ico" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="Shopify"></span> <span class="tag tag-external">External</span> <span class="section-title">shop.aesthetic.computer</span> <span class="section-count">~30 product shortcuts</span></summary><div class="section-desc">Shopify storefront for physical goods — books, prints, bikes, shirts, tools, music. Short-code URLs on AC redirect to product pages.</div><div class="routes single-col"> <div class="redirect-row"> <span class="redirect-from">/shop/@jeffrey/help</span> <span class="redirect-arrow">→</span> <span class="redirect-to">45 min computer help</span> <span class="redirect-status status-301">301</span> </div> <div class="redirect-row"> <span class="redirect-from">/shop/*</span> <span class="redirect-arrow">→</span> <span class="redirect-to">shop.aesthetic.computer/*</span> <span class="redirect-status status-301">301</span> </div></div><div class="route-group-label">Books</div><div class="routes"> <div class="route">25.4.8.21.19 — Shape of Things (Flusser)</div> <div class="route">25.4.8.21.17 — Art as Social System (Luhmann)</div> <div class="route">25.4.8.21.11 — Play (Garvey)</div> <div class="route">25.4.8.21.08 — What is Landscape (Stilgoe)</div> <div class="route">25.4.8.21.07 — Complete Poems (Dickinson)</div> <div class="route">25.11.17.19.03 — Radical Computer Music</div> <div class="route">25.4.8.21.0 — Art of Seeing (Huxley)</div> <div class="route">25.4.8.20.47 — Does Writing Have Future</div> <div class="route">25.4.8.21.13 — Musical Gestures</div></div><div class="route-group-label">Music / Pictures / Bikes / Tools / Shirts</div><div class="routes"> <div class="route">25.11.3.14.17 — Baktok 7-inch</div> <div class="route">25.4.13.17.47 — Picture</div> <div class="route">25.4.13.19.06 — Picture</div> <div class="route">25.4.13.18.18 — Picture</div> <div class="route">25.4.13.19.24 — Picture</div> <div class="route">25.4.13.18.54 — Picture</div> <div class="route">25.12.4.10.09 — Adult Bike</div> <div class="route">25.12.4.10.08 — Kids Bike</div> <div class="route">25.12.4.11.21 — New Experiences</div> <div class="route">25.12.4.11.22 — Prompt AC</div> <div class="route">25.12.4.11.23 — My Songs</div> <div class="route">25.12.4.11.24 — Pretty Pictures</div> <div class="route">25.12.4.11.25 — Play</div> <div class="route">26.1.3.0.02 — Beige Abex Tee M</div> <div class="route">26.1.3.0.00 — Coral Abex Tee L</div></div></details></div>
<!-- gift.aesthetic.computer --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/prompt.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="Netlify"></span> <span class="tag tag-subdomain">Subdomain</span> <span class="section-title">gift.aesthetic.computer</span> <span class="section-count">1 page</span></summary><div class="section-desc">Gift card or gifting page for Aesthetic Computer.</div><div class="routes single-col"> <div class="route full-url">gift.aesthetic.computer/ — Gift page</div></div></details></div>
<!-- pals.aesthetic.computer --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/prompt.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="Netlify"></span> <span class="tag tag-subdomain">Subdomain</span> <span class="section-title">pals.aesthetic.computer</span> <span class="section-count">Logo proxy</span></summary><div class="section-desc">Dynamic logo generation service. All requests proxy to /api/logo/* for partner/pal branding assets.</div><div class="routes single-col"> <div class="route full-url">pals.aesthetic.computer/* → /api/logo/*</div></div></details></div>
<!-- bills.aesthetic.computer --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/prompt.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="Netlify"></span> <span class="tag tag-subdomain">Subdomain</span> <span class="section-title">bills.aesthetic.computer</span> <span class="section-count">Dashboard</span></summary><div class="section-desc">Financial status dashboard for AC infrastructure. Tracks ~$151/month across 16 services, shows overdue payments, cost trends, DigitalOcean droplet breakdown, and priority action items.</div><div class="routes single-col"> <div class="route full-url">bills.aesthetic.computer/ — Billing dashboard</div></div></details></div>
<!-- papers.aesthetic.computer --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/prompt.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="Netlify"></span> <span class="tag tag-subdomain">Subdomain</span> <span class="section-title">papers.aesthetic.computer</span> <span class="section-count">Research</span></summary><div class="section-desc">Academic papers portal by @jeffrey. arXiv preprints, JOSS summaries, and ELS proceedings on Aesthetic Computer and KidLisp. Multi-language support, dark/light theme, PDF hit tracking.</div><div class="routes single-col"> <div class="route full-url">papers.aesthetic.computer/ — Papers index with PDF downloads</div></div></details></div>
<!-- l5.aesthetic.computer --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/prompt.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="Netlify"></span> <span class="tag tag-subdomain">Subdomain</span> <span class="section-title">l5.aesthetic.computer</span> <span class="section-count">Learning</span></summary><div class="section-desc">Live playground and API explorer for L5, a Processing-style Lua language on Aesthetic Computer. JS-driven SPA with docs endpoint.</div><div class="routes single-col"> <div class="route full-url">l5.aesthetic.computer/ — Try L5 on AC (SPA)</div> <div class="route full-url">l5.aesthetic.computer/docs.json — API docs</div> <div class="route full-url">l5.aesthetic.computer/docs/* — Doc pages</div></div></details></div>
<!-- processing.aesthetic.computer --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/prompt.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="Netlify"></span> <span class="tag tag-subdomain">Subdomain</span> <span class="section-title">processing.aesthetic.computer</span> <span class="section-count">Learning</span></summary><div class="section-desc">Processing-style Java playground that transpiles to the L5 Lua runtime on Aesthetic Computer. JS-driven SPA.</div><div class="routes single-col"> <div class="route full-url">processing.aesthetic.computer/ — Try Processing on AC (SPA)</div> <div class="route full-url">processing.aesthetic.computer/docs.json — API docs</div> <div class="route full-url">processing.aesthetic.computer/docs/* — Doc pages</div></div></details></div>
<!-- p5.aesthetic.computer --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/prompt.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="Netlify"></span> <span class="tag tag-subdomain">Subdomain</span> <span class="section-title">p5.aesthetic.computer</span> <span class="section-count">Learning</span></summary><div class="section-desc">Alias for processing.aesthetic.computer. Same Processing-to-L5 playground, served under a p5-branded subdomain.</div><div class="routes single-col"> <div class="route full-url">p5.aesthetic.computer/* → processing.aesthetic.computer (200 proxy)</div></div></details></div>
<!-- oven.aesthetic.computer --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/prompt.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="Oven"></span> <span class="tag tag-api">Infra</span> <span class="section-title">oven.aesthetic.computer</span> <span class="section-count">Internal service</span></summary><div class="section-desc">Internal screenshot and asset generation service. AC proxies preview images, icons, and bundle-html requests through it. Node.js + Caddy on DigitalOcean (137.184.237.166).</div><div class="routes single-col"> <div class="route full-url">/preview/* → oven.aesthetic.computer/preview/:splat</div> <div class="route full-url">/icon/* → oven.aesthetic.computer/icon/:splat</div> <div class="route full-url">/api/bundle-html → oven.aesthetic.computer/bundle-html</div></div></details></div>
<!-- at.aesthetic.computer --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/prompt.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="AT Proto PDS"></span> <span class="tag tag-api">Infra</span> <span class="section-title">at.aesthetic.computer</span> <span class="section-count">AT Protocol PDS</span></summary><div class="section-desc">Personal Data Server (PDS) for the AT Protocol / Bluesky network. Every AC user gets a DID and handle at <em>{handle}.at.aesthetic.computer</em>. Moods, paintings, pieces, and KidLisp are dual-written here. Handles account creation, invite codes, deletion, and Bluesky mirroring.</div><div class="routes single-col"> <div class="route full-url">at.aesthetic.computer/ — PDS root (AT Protocol)</div> <div class="route full-url">at.aesthetic.computer/xrpc/* — AT Protocol XRPC API</div> <div class="dynamic-pattern">{handle}.at.aesthetic.computer → user DID / identity</div> <div class="dynamic-pattern">api/atproto-user-stats → aggregated user stats</div></div></details></div>
<!-- feed.aesthetic.computer --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/prompt.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="Cloudflare Workers"></span> <span class="tag tag-api">Edge</span> <span class="section-title">feed.aesthetic.computer</span> <span class="section-count">DP1 Feed Worker</span></summary><div class="section-desc">Cloudflare Worker serving the DP-1 playlist/feed protocol. Manages KidLisp, Top 100, Colors, and Chords playlists. Ed25519-signed, OpenAPI 3.1 compliant. Backed by Cloudflare KV and a write-queue.</div><div class="routes single-col"> <div class="route full-url">feed.aesthetic.computer/api/v1/playlists — Playlists CRUD</div> <div class="route full-url">feed.aesthetic.computer/api/v1/channels — Channels CRUD</div> <div class="route full-url">feed.aesthetic.computer/api/v1/items — Playlist items CRUD</div></div></details></div>
<!-- grab.aesthetic.computer --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/prompt.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="Cloudflare Workers"></span> <span class="tag tag-api">Edge</span> <span class="section-title">grab.aesthetic.computer</span> <span class="section-count">Screenshot Worker</span></summary><div class="section-desc">Cloudflare Worker using the Browser Rendering API to generate and cache screenshots of AC pieces. Rate-limited (60 req/min), 7-day cache, up to 10 concurrent browser sessions. Used for social previews and thumbnails.</div><div class="routes single-col"> <div class="dynamic-pattern">grab.aesthetic.computer/* → screenshot generation & cache</div></div></details></div>
<!-- silo.aesthetic.computer --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/prompt.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="Silo"></span> <span class="tag tag-api">Infra</span> <span class="section-title">silo.aesthetic.computer</span> <span class="section-count">Data dashboard</span></summary><div class="section-desc">Internal MongoDB data & storage dashboard for AC. Admin-only access. Node.js + Caddy on DigitalOcean (64.23.151.169).</div><div class="routes single-col"> <div class="route full-url">silo.aesthetic.computer/ — Dashboard</div></div></details></div>
<!-- help.aesthetic.computer --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/prompt.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="Help"></span> <span class="tag tag-api">Infra</span> <span class="section-title">help.aesthetic.computer</span> <span class="section-count">AI assistant</span></summary><div class="section-desc">Claude-powered AI assistant for the AC community. Auth0 sign-in required; users bring their own Anthropic API key. RBAC tool system (create-kidlisp, fork-piece, search-docs, explain-piece). Node.js + Caddy on DigitalOcean (146.190.150.173).</div><div class="routes single-col"> <div class="route full-url">help.aesthetic.computer/ — Landing + chat UI</div> <div class="route full-url">help.aesthetic.computer/auth/config — Auth0 config</div> <div class="route full-url">help.aesthetic.computer/api/chat — Claude streaming (SSE)</div> <div class="route full-url">help.aesthetic.computer/api/settings — API key management</div> <div class="route full-url">help.aesthetic.computer/api/conversations — History</div></div></details></div>
<!-- Edge functions --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/prompt.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="tag tag-api">Edge</span> <span class="section-title">Edge Functions</span> <span class="section-count">1 function</span></summary><div class="section-desc">Deno-based edge functions running at the CDN layer for low-latency processing.</div><div class="routes single-col"> <div class="route full-url">/media/* — media.js edge function</div></div></details></div>
<!-- Desktop downloads --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/prompt.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="tag tag-redirect">Downloads</span> <span class="section-title">Desktop App Downloads</span> <span class="section-count">5 platforms</span></summary><div class="section-desc">Short URLs that redirect to the latest GitHub release for each platform.</div><div class="routes single-col"> <div class="redirect-row"> <span class="redirect-from">/desktop/mac</span> <span class="redirect-arrow">→</span> <span class="redirect-to">GitHub Release (.dmg)</span> <span class="redirect-status status-302">302</span> </div> <div class="redirect-row"> <span class="redirect-from">/desktop/win</span> <span class="redirect-arrow">→</span> <span class="redirect-to">GitHub Release (.exe)</span> <span class="redirect-status status-302">302</span> </div> <div class="redirect-row"> <span class="redirect-from">/desktop/linux</span> <span class="redirect-arrow">→</span> <span class="redirect-to">GitHub Release (.AppImage)</span> <span class="redirect-status status-302">302</span> </div> <div class="redirect-row"> <span class="redirect-from">/desktop/fedora</span> <span class="redirect-arrow">→</span> <span class="redirect-to">GitHub Release (.rpm)</span> <span class="redirect-status status-302">302</span> </div> <div class="redirect-row"> <span class="redirect-from">/desktop/deb</span> <span class="redirect-arrow">→</span> <span class="redirect-to">GitHub Release (.deb)</span> <span class="redirect-status status-302">302</span> </div></div></details></div>
<!-- Domain aliases --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/prompt.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="tag tag-redirect">Redirects</span> <span class="section-title">Domain Aliases & Redirects</span> <span class="section-count">8 domains</span></summary><div class="section-desc">Vanity domains, legacy redirects, and shortcut aliases that funnel into the core AC platform.</div><div class="routes single-col"> <div class="redirect-row"> <span class="redirect-from">botce.ac</span> <span class="redirect-arrow">→</span> <span class="redirect-to">aesthetic.computer/botce</span> <span class="redirect-status status-200">200</span> </div> <div class="redirect-row"> <span class="redirect-from">wand.ac</span> <span class="redirect-arrow">→</span> <span class="redirect-to">aesthetic.computer/wand</span> <span class="redirect-status status-301">301</span> </div> <div class="redirect-row"> <span class="redirect-from">edit.ac</span> <span class="redirect-arrow">→</span> <span class="redirect-to">vscode.dev/.../blank.mjs</span> <span class="redirect-status status-301">301</span> </div> <div class="redirect-row"> <span class="redirect-from">prompt.ac/*</span> <span class="redirect-arrow">→</span> <span class="redirect-to">aesthetic.computer/*</span> <span class="redirect-status status-301">301</span> </div> <div class="redirect-row"> <span class="redirect-from">4esthetic.com/*</span> <span class="redirect-arrow">→</span> <span class="redirect-to">aesthetic.computer/*</span> <span class="redirect-status status-301">301</span> </div> <div class="redirect-row"> <span class="redirect-from">whistlegraph.com/*</span> <span class="redirect-arrow">→</span> <span class="redirect-to">trio.whistlegraph.com/*</span> <span class="redirect-status status-301">301</span> </div> <div class="redirect-row"> <span class="redirect-from">m2w2.whistlegraph.com</span> <span class="redirect-arrow">→</span> <span class="redirect-to">aesthetic.computer/wg~m2w2</span> <span class="redirect-status status-200">200</span> </div> <div class="redirect-row"> <span class="redirect-from">digitpain.com/*</span> <span class="redirect-arrow">→</span> <span class="redirect-to">jas.life/*</span> <span class="redirect-status status-301">301</span> </div></div></details></div>
<!-- kidlisp.com --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/kidlisp.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="Netlify"></span> <span class="tag tag-subdomain">Subdomain</span> <span class="section-title">kidlisp.com</span> <span class="section-count">6 pages + 5 subdomains</span></summary><div class="section-desc">A Lisp-based creative programming language built on Aesthetic Computer. Write code, save “keeps” (minted artifacts), pair with physical FF1 devices, and browse a top-100 playlist.</div><div class="routes single-col"> <div class="route full-url">kidlisp.com/ — Main editor (SPA)</div> <div class="route full-url">kidlisp.com/keeps — Keeps gallery</div> <div class="route full-url">kidlisp.com/learn — Learning/reference</div> <div class="route full-url">kidlisp.com/pj/* — Piece Jockey mode</div> <div class="route full-url">kidlisp.com/api/* → proxied to aesthetic.computer/api/*</div> <div class="route full-url">kidlisp.com/api/ff1/* → FF1 device API</div></div><div class="route-group-label">keep.kidlisp.com (Mint & Index)</div><div class="routes single-col"> <div class="route full-url">keep.kidlisp.com/ — Living index of all $codes + Tezos NFT minting (Auth0 + Beacon wallet)</div> <div class="route full-url">keep.kidlisp.com/api/* → proxied to aesthetic.computer/api/*</div></div><div class="route-group-label">learn.kidlisp.com (Reference & Analytics)</div><div class="routes single-col"> <div class="route full-url">learn.kidlisp.com/ — 118-function reference, usage analytics, and top-hits community browser</div> <div class="route full-url">learn.kidlisp.com/api/* → proxied to aesthetic.computer/api/*</div></div><div class="route-group-label">calm.kidlisp.com (Ambient Display)</div><div class="routes single-col"> <div class="route full-url">calm.kidlisp.com/ — Auto-shuffle calm playlist with 50s crossfade, 24fps, no UI — for screens & installations</div> <div class="route full-url">calm.kidlisp.com/js/* — Static JS assets</div></div><div class="route-group-label">pj.kidlisp.com (Piece Jockey)</div><div class="routes single-col"> <div class="route full-url">pj.kidlisp.com/ — PJ editor page</div> <div class="route full-url">pj.kidlisp.com/* — PJ with code param</div></div><div class="route-group-label">device.kidlisp.com (FF1 Display)</div><div class="routes single-col"> <div class="route full-url">device.kidlisp.com/ — Device display mode</div> <div class="route full-url">device.kidlisp.com/:codeId — Run specific code</div> <div class="route full-url">device.kidlisp.com/qr/:token — QR pairing page</div> <div class="route full-url">device.kidlisp.com/js/* — Static JS assets</div> <div class="route full-url">device.kidlisp.com/api/ff1/* — FF1 API</div></div><div class="route-group-label">top.kidlisp.com (Top 100 Playlist)</div><div class="routes single-col"> <div class="route full-url">top.kidlisp.com/ — Top 100 device display</div> <div class="route full-url">top.kidlisp.com/js/* — Static JS assets</div> <div class="route full-url">top.kidlisp.com/* — Catch-all to device.html</div></div></details></div>
<!-- sotce.net --><div class="card"><details><summary> <img class="card-thumb" src="https://icons.duckduckgo.com/ip3/sotce.net.ico" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="Netlify"></span> <span class="tag tag-subdomain">Subdomain</span> <span class="section-title">sotce.net</span> <span class="section-count">Dynamic SSR</span></summary><div class="section-desc">Server-rendered social platform with its own identity system. Fully generated by a single Netlify function — handles auth, user profiles, email, and content.</div><div class="routes single-col"> <div class="route full-url">sotce.net/ — Main page (serverless rendered)</div> <div class="route full-url">sotce.net/* — All routes via sotce-net function</div> <div class="route full-url">sotce.net/user → user function</div> <div class="route full-url">sotce.net/handle → handle function</div> <div class="route full-url">sotce.net/api/email → email function</div> <div class="route full-url">sotce.net/aesthetic.computer/* → AC static assets</div> <div class="route full-url">sotce.net/redirect-proxy-sotce → redirect proxy</div></div><div class="note">Also accessible at /sotce-net/* and /sotce.net/* on main domain.</div></details></div>
<!-- justanothersystem.org --><div class="card"><details><summary> <img class="card-thumb" src="https://icons.duckduckgo.com/ip3/justanothersystem.org.ico" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="Netlify"></span> <span class="tag tag-subdomain">Subdomain</span> <span class="section-title">justanothersystem.org</span> <span class="section-count">Gallery + API</span></summary><div class="section-desc">Jeffrey Alan Scudder's stretched paintings gallery with a CRUD API for paintings and a tagging system. Admin-only write access via Auth0.</div><div class="routes single-col"> <div class="route full-url">justanothersystem.org/ — Stretched paintings gallery</div> <div class="route full-url">justanothersystem.org/* — Static content</div> <div class="route full-url">justanothersystem.org/api/stretched-paintings — Paintings CRUD</div> <div class="route full-url">justanothersystem.org/api/stretched-paintings/* — By ID</div> <div class="route full-url">justanothersystem.org/api/tags — Tags CRUD</div> <div class="route full-url">justanothersystem.org/api/tags/* — Tag operations</div></div><div class="note">www.justanothersystem.org → 301 to naked domain.</div></details></div>
<!-- jas.life --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/prompt.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="Netlify"></span> <span class="tag tag-subdomain">Subdomain</span> <span class="section-title">jas.life</span> <span class="section-count">Portfolio</span></summary><div class="section-desc">Jeffrey Alan Scudder's personal portfolio and CV. Supersedes the older digitpain.com domain.</div><div class="routes single-col"> <div class="route full-url">jas.life/ — Portfolio home</div> <div class="route full-url">jas.life/* — Static sub-pages</div></div><div class="note">Also at /jas.life/* on main domain. digitpain.com 301s here.</div></details></div>
<!-- false.work --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/prompt.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="Netlify"></span> <span class="tag tag-subdomain">Subdomain</span> <span class="section-title">false.work</span> <span class="section-count">Studio + builds</span></summary><div class="section-desc">Studio landing page. builds.false.work is a password-protected dashboard for tracking cross-platform app builds, roadmap, and build reports.</div><div class="routes single-col"> <div class="route full-url">false.work/ — Landing page</div> <div class="route full-url">false.work/* — Static content</div></div><div class="route-group-label">builds.false.work</div><div class="routes single-col"> <div class="route full-url">builds.false.work/ — Build dashboard</div> <div class="route full-url">builds.false.work/roadmap.html — Roadmap</div> <div class="route full-url">builds.false.work/ios-build-status.html — iOS status</div> <div class="route full-url">builds.false.work/ios/ — iOS build details</div> <div class="route full-url">builds.false.work/api/register-build</div> <div class="route full-url">builds.false.work/api/get-builds</div> <div class="route full-url">builds.false.work/api/verify-password</div></div></details></div>
<!-- notepat.com --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/notepat.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="Netlify"></span> <span class="tag tag-subdomain">Subdomain</span> <span class="section-title">notepat.com</span> <span class="section-count">Proxied</span></summary><div class="section-desc">Standalone domain for the Notepat music tool. Transparently proxies to aesthetic.computer/notepat.</div><div class="routes single-col"> <div class="route full-url">notepat.com/ → aesthetic.computer/notepat (200 proxy)</div> <div class="route full-url">notepat.com/* → aesthetic.computer/* (200 proxy)</div></div></details></div>
<!-- sundarakarma.com --><div class="card"><details><summary> <img class="card-thumb" src="https://icons.duckduckgo.com/ip3/sundarakarma.com.ico" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="Netlify"></span> <span class="tag tag-subdomain">Subdomain</span> <span class="section-title">sundarakarma.com</span> <span class="section-count">Band site</span></summary><div class="section-desc">Hosted site for the band Sundara Karma. Static pages served from AC's public directory.</div><div class="routes single-col"> <div class="route full-url">sundarakarma.com/ — Main page</div> <div class="route full-url">sundarakarma.com/oscar — Oscar page</div></div></details></div>
<!-- wipppps.world --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/wipppps.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="Netlify"></span> <span class="tag tag-subdomain">Subdomain</span> <span class="section-title">wipppps.world</span> <span class="section-count">Proxied</span></summary><div class="section-desc">Vanity domain for the Wipppps interactive piece. Transparently proxies to aesthetic.computer/wipppps.</div><div class="routes single-col"> <div class="route full-url">wipppps.world → aesthetic.computer/wipppps (200 proxy)</div></div></details></div>
<!-- aesthetic.direct --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/aesthetic-direct.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="Netlify"></span> <span class="tag tag-subdomain">Subdomain</span> <span class="section-title">aesthetic.direct</span> <span class="section-count">1 page</span></summary><div class="section-desc">Direct access landing page. Proxies to /aesthetic-direct on AC.</div><div class="routes single-col"> <div class="route full-url">aesthetic.direct → aesthetic.computer/aesthetic-direct (200 proxy)</div></div></details></div>
<!-- jas.life legacy sites (pre-2016 / pre-AC) --><div class="card"><details><summary> <img class="card-thumb" src="/icon/128x128/prompt.png" loading="lazy" onerror="this.style.display='none'" alt=""> <span class="service-light service-light-unknown" data-service="jas.life Legacy"></span> <span class="tag tag-infra">Legacy</span> <span class="section-title">*.jas.life — Pre-AC Archive (2014–2016)</span> <span class="section-count">14 sites</span></summary><div class="section-desc">Jeffrey Scudder's projects predating Aesthetic Computer, hosted on a legacy DigitalOcean droplet (Ubuntu 16.04) and served via Cloudflare-proxied subdomains of jas.life. Includes drawing apps, hypertext poetry, course syllabi, artist portfolios, and a 109 GB personal file archive.</div>
<div class="route-group-label">Web Apps (Rails / Passenger)</div><div class="routes single-col"> <div class="redirect-row"><a class="redirect-from" href="https://bigwalt59-com.jas.life" target="_blank">bigwalt59-com.jas.life</a><span class="redirect-arrow">—</span><span class="redirect-to">Hypertext poem (Lali Foster & Jeffrey Scudder, Global Game Jam 2015)</span><span class="redirect-status status-200">200</span></div> <div class="redirect-row"><a class="redirect-from" href="https://drawings-rey-sc.jas.life" target="_blank">drawings-rey-sc.jas.life</a><span class="redirect-arrow">—</span><span class="redirect-to">Drawing app — 3 996 files in PostgreSQL</span><span class="redirect-status status-200">200</span></div> <div class="redirect-row"><a class="redirect-from" href="https://nopaint-org.jas.life" target="_blank">nopaint-org.jas.life</a><span class="redirect-arrow">—</span><span class="redirect-to">No Paint</span><span class="redirect-status status-200">200</span></div> <div class="redirect-row"><a class="redirect-from" href="https://ww-rey-sc.jas.life" target="_blank">ww-rey-sc.jas.life</a><span class="redirect-arrow">—</span><span class="redirect-to">Word Web</span><span class="redirect-status status-200">200</span></div></div>
<div class="route-group-label">Static Sites & Portfolios</div><div class="routes single-col"> <div class="redirect-row"><a class="redirect-from" href="https://rey-sc.jas.life" target="_blank">rey-sc.jas.life</a><span class="redirect-arrow">—</span><span class="redirect-to">Jeffrey Scudder — CV, portfolio, course pages</span><span class="redirect-status status-200">200</span></div> <div class="redirect-row"><a class="redirect-from" href="https://syl-rey-sc.jas.life" target="_blank">syl-rey-sc.jas.life</a><span class="redirect-arrow">—</span><span class="redirect-to">Course syllabi (PSAM 3210, PUCD 2035/2126)</span><span class="redirect-status status-200">200</span></div> <div class="redirect-row"><a class="redirect-from" href="https://gordilloscudder-com.jas.life" target="_blank">gordilloscudder-com.jas.life</a><span class="redirect-arrow">—</span><span class="redirect-to">Gordillo–Scudder artist portfolio & press</span><span class="redirect-status status-200">200</span></div> <div class="redirect-row"><a class="redirect-from" href="https://daisychainbook-com.jas.life" target="_blank">daisychainbook-com.jas.life</a><span class="redirect-arrow">—</span><span class="redirect-to">Daisy Chain Book</span><span class="redirect-status status-200">200</span></div> <div class="redirect-row"><a class="redirect-from" href="https://maskware-net.jas.life" target="_blank">maskware-net.jas.life</a><span class="redirect-arrow">—</span><span class="redirect-to">Maskware</span><span class="redirect-status status-200">200</span></div> <div class="redirect-row"><a class="redirect-from" href="https://teacherdirectedactivity-com.jas.life" target="_blank">teacherdirectedactivity-com.jas.life</a><span class="redirect-arrow">—</span><span class="redirect-to">TDA — audio + interactive</span><span class="redirect-status status-200">200</span></div> <div class="redirect-row"><a class="redirect-from" href="https://traveller-minnna.jas.life" target="_blank">traveller-minnna.jas.life</a><span class="redirect-arrow">—</span><span class="redirect-to">Traveller (2014)</span><span class="redirect-status status-200">200</span></div></div>
<div class="route-group-label">Art Projects & Archives</div><div class="routes single-col"> <div class="redirect-row"><a class="redirect-from" href="https://interludes-and-remnants-net.jas.life" target="_blank">interludes-and-remnants-net.jas.life</a><span class="redirect-arrow">—</span><span class="redirect-to">Interludes & Remnants (401 MB)</span><span class="redirect-status status-200">200</span></div> <div class="redirect-row"><a class="redirect-from" href="https://digpain-org.jas.life" target="_blank">digpain-org.jas.life</a><span class="redirect-arrow">—</span><span class="redirect-to">Digital Pain</span><span class="redirect-status status-200">200</span></div> <div class="redirect-row"><a class="redirect-from" href="https://bin-sc.jas.life" target="_blank">bin-sc.jas.life</a><span class="redirect-arrow">—</span><span class="redirect-to">File archive — 109 GB (Projects, Teaching, JeffreyPaint)</span><span class="redirect-status status-200">200</span></div></div></details></div>
</section>
<img id="pals" width="48" src="https://aesthetic.computer/purple-pals.svg">
<script>const search = document.getElementById("search");const SEARCHABLE_SELECTOR = ".route, .redirect-row, .dynamic-pattern";
function applySearchFilter() { const q = search.value.toLowerCase().trim(); document.querySelectorAll(SEARCHABLE_SELECTOR).forEach(el => { const searchText = el.getAttribute("data-search-text") || el.textContent; const text = searchText.toLowerCase(); el.classList.toggle("hidden", q && !text.includes(q)); }); document.querySelectorAll("details").forEach(det => { const visible = det.querySelectorAll(".route:not(.hidden), .redirect-row:not(.hidden), .dynamic-pattern:not(.hidden)"); det.closest(".card").classList.toggle("hidden", q && visible.length === 0); if (q && visible.length > 0) det.open = true; });}
search.addEventListener("input", applySearchFilter);
// Service status lights — fetched from bills.aesthetic.computer and baked into each cardconst STATUS_PRIORITY = { red: 0, yellow: 1, green: 2, unknown: 3 };const BILLS_FETCH_URLS = ["https://bills.aesthetic.computer/index.html", "/bills.aesthetic.computer/index.html"];
function normalizeSpace(text) { return (text || "").replace(/\s+/g, " ").trim();}
function mapServiceClassToState(serviceNode) { if (serviceNode.classList.contains("down")) return "red"; if (serviceNode.classList.contains("warn")) return "yellow"; if (serviceNode.classList.contains("ok") || serviceNode.classList.contains("free")) return "green"; return "unknown";}
function classifyStatusText(statusText) { const status = (statusText || "").toLowerCase(); if (!status) return "unknown"; if (status.includes("suspend") || status.includes("overdue") || status.includes("down") || status.includes("off") || status.includes("locked")) return "red"; if (status.includes("past due") || status.includes("warn") || status.includes("degrad") || status.includes("risk")) return "yellow"; if (status.includes("active") || status.includes("free") || status.includes("ok") || status.includes("online") || status.includes("up")) return "green"; return "unknown";}
function formatTimeUTC(date) { return date.toISOString().slice(11, 19) + " UTC";}
function parseBillsSnapshot(html) { const doc = new DOMParser().parseFromString(html, "text/html");
const subtitle = normalizeSpace(doc.querySelector(".subtitle")?.textContent); const snapshotDate = subtitle.split("—").pop()?.trim() || "";
const topStats = {}; const topStatsContainer = doc.querySelector(".stats"); if (topStatsContainer) { Array.from(topStatsContainer.querySelectorAll(".stat-box")).forEach(box => { const label = normalizeSpace(box.querySelector(".stat-label")?.textContent).toLowerCase(); const value = normalizeSpace(box.querySelector(".stat-value")?.textContent); if (label && value) topStats[label] = value; }); }
const servicesByName = new Map();
Array.from(doc.querySelectorAll(".service-map .svc")).forEach(serviceNode => { const name = normalizeSpace(serviceNode.querySelector(".svc-name")?.textContent); if (!name) return; const state = mapServiceClassToState(serviceNode); servicesByName.set(name.toLowerCase(), { name, state }); });
const allServicesHeading = Array.from(doc.querySelectorAll("h2")) .find(node => normalizeSpace(node.textContent).toLowerCase() === "all services"); const allServicesTable = allServicesHeading?.nextElementSibling?.tagName === "TABLE" ? allServicesHeading.nextElementSibling : null;
if (allServicesTable) { Array.from(allServicesTable.querySelectorAll("tbody tr")).forEach(row => { const cells = row.querySelectorAll("td"); if (cells.length < 2) return; const statusText = normalizeSpace(cells[0].textContent); const name = normalizeSpace(cells[1].textContent); if (!name) return; const key = name.toLowerCase(); if (servicesByName.has(key)) return; const state = classifyStatusText(statusText); servicesByName.set(key, { name, state }); }); }
return { snapshotDate, topStats, services: servicesByName };}
function applyStatusLights(serviceMap) { // Map service names from bills to data-service attributes on lights document.querySelectorAll(".service-light[data-service]").forEach(light => { const key = light.getAttribute("data-service").toLowerCase(); // Try exact match first, then fuzzy let match = serviceMap.get(key); if (!match) { for (const [k, v] of serviceMap) { if (k.includes(key) || key.includes(k)) { match = v; break; } } } if (match) { light.className = `service-light service-light-${match.state}`; light.title = `${match.name}: ${match.state}`; } });}
async function fetchBillsHTML() { let lastError = null; for (const url of BILLS_FETCH_URLS) { const abortController = new AbortController(); const timeout = setTimeout(() => abortController.abort(), 8000); try { const response = await fetch(url, { cache: "no-store", signal: abortController.signal }); if (!response.ok) throw new Error(`${response.status}`); return await response.text(); } catch (error) { lastError = error; } finally { clearTimeout(timeout); } } throw lastError || new Error("fetch failed");}
const statusBar = document.getElementById("live-status-bar");
async function refreshLiveStatus() { try { const billsHTML = await fetchBillsHTML(); const snapshot = parseBillsSnapshot(billsHTML); applyStatusLights(snapshot.services); const counts = { green: 0, yellow: 0, red: 0, unknown: 0 }; for (const [, svc] of snapshot.services) counts[svc.state] = (counts[svc.state] || 0) + 1; statusBar.textContent = `${counts.green} on · ${counts.yellow} at risk · ${counts.red} off · updated ${formatTimeUTC(new Date())}`; } catch (error) { statusBar.textContent = `Status poll failed · ${formatTimeUTC(new Date())}`; }}
refreshLiveStatus();setInterval(refreshLiveStatus, 30000);</script></body></html>