# Keith Reed > Full-stack developer. I'm a former teacher. I started writing software for my tutoring students and kept going. Now I build web apps, APIs, and data tools for other people too, mostly in TypeScript and React on Cloudflare. This page lays the projects out on a {7,3} tiling of the hyperbolic plane, drawn in the Poincare disk. The center cell is the introduction; the seven cells around it are six groups of projects and a plain list; each group's projects sit just outside it. The canvas draws nothing that is not also in the files below. ## Projects ### Learning software Practice apps and teaching tools, most of them built for my own students. - [CalTPA Writing Studio](https://impossible-spaces-landing.pages.dev/api/projects/caltpa.json): A writing workspace for California teaching candidates working on the CalTPA. Each part gets its own template, and a keyword check shows which rubric categories a draft still misses. Live: https://caltpa.rootsofreason.org. Drawing in its cell: CalTPA Writing Studio: the rubric radar filling in as a draft covers each category. One category stays short, which is what the check is there to show. - [Math Mastery](https://impossible-spaces-landing.pages.dev/api/projects/math-mastery.json): Math practice I built for my tutoring students: multiplication, division, fractions, geometry, and word problems, each with a visual model next to the numbers. Live: https://math.rootsofreason.org. Drawing in its cell: Math Mastery: an area model, a by b squares filled in a row at a time - [Code Playground](https://impossible-spaces-landing.pages.dev/api/projects/code-playground.json): A coding sandbox for students where a shape, a set of sliders, and the code that draws it stay in sync. The code can be shown in Luau, GDScript, or Python. Live: https://code.rootsofreason.org. Drawing in its cell: Code Playground: a shape, its sliders, and its code lines all moving together - [Physics flashcards](https://impossible-spaces-landing.pages.dev/api/projects/study-cards.json): Interactive flashcard modules for physics. Each card starts with something you move, then names the idea and asks a few questions about it. Live: https://lms.relay70.dev/cards/. Drawing in its cell: Physics flashcards: a wave whose height the reader controls, with the gauge beside it ### AI infrastructure Tools I use to run my own AI-assisted work. - [auto.relay70](https://impossible-spaces-landing.pages.dev/api/projects/auto-relay.json): Tools that keep my AI coding agents working on a schedule while I'm away, and keep a record of what each run did. Live: https://auto.relay70.dev. Drawing in its cell: auto.relay70: a day of scheduled runs. Each pass of the hand over a job leaves a record; the hollow job is on the list but was never scheduled, so it never gets one. ### Interactive design Instruments, drawing tools, and navigation experiments you can play with. - [Lithorium](https://impossible-spaces-landing.pages.dev/api/projects/lithorium.json): The site for my rock and mineral business. The home page is the menu: five sections orbit a ring of drifting particles. Live: https://lithorium.rocks. Drawing in its cell: Lithorium: five sections orbiting a ring of drifting particles - [Sound Toys](https://impossible-spaces-landing.pages.dev/api/projects/sound-toys.json): Ten instruments that run in the browser. They all color sound the same way: pitch sets the hue, register the saturation, and loudness the brightness. Live: https://sound-toy-deploy.pages.dev. Drawing in its cell: Sound Toys: the shared color rule. Pitch class sets the hue around the wheel; the center trace is the sum of the sounding notes, brighter while they are loud. - [Chromata](https://impossible-spaces-landing.pages.dev/api/projects/chromata.json): A drawing tool that redraws a picture as moving lines. Small pathfinders wander across the image and draw with the colors they pass over. Live: https://chromata.relay70.dev. Drawing in its cell: Chromata: pathfinders crossing a picture they cannot see all at once. At each step a pathfinder looks left, ahead, and right and goes where the picture's color is closest to its own. ### Tools & data Small apps that do one job. - [Focus Matrix](https://impossible-spaces-landing.pages.dev/api/projects/focus-matrix.json): A study-session planner. You list what you're going to do, give each item a timer and a priority, and earn a coin for each one you finish. Live: https://focus-matrix.pages.dev. Drawing in its cell: Focus Matrix: a session plan worked through item by item. Each finished timer pays one coin. ### Commerce & websites Storefronts and sites for businesses, including my own. - [Roots of Reason website](https://impossible-spaces-landing.pages.dev/api/projects/roots-of-reason.json): The website for my tutoring practice. Families read about the services, book a consultation, and fill out intake forms there. Live: https://rootsofreason.org. Drawing in its cell: Roots of Reason: a tree growing above its own roots - [Onleigh Crystals](https://impossible-spaces-landing.pages.dev/api/projects/onleigh.json): The store for my crystal business. I built the current website, and I wrote a Shopify theme from scratch for when the shop moves to Shopify. Live: no public link. Drawing in its cell: Onleigh Crystals: a quartz point turning, six-sided with a pointed end ### Research & models Pictures computed from real math. - [Long Night](https://impossible-spaces-landing.pages.dev/api/projects/long-night.json): A night sky drawn from real star positions for the current time, above a treeline. The same positions are available from an API. Live: https://night.relay70.dev. Drawing in its cell: Long Night: the bright stars over Los Angeles for the current time, placed by placeStars, with the Big Dipper, Cassiopeia, and Orion joined, inside a ring of pines standing on the horizon ## How the page works - Coloring: each unlit cell takes the color of the lit cell it is fewest steps from; light and dark bands count those steps. - Rim: each point of the boundary circle is colored by the region nearest to it from the current view. - Pathfinders: walkers on the tiling edges choose the direction whose cells match their own color, after Chromata by Michael Bromley. - Opening a project: clicking or scrolling into an open cell loads the project in a frame when its site allows it, and goes to the site otherwise. ## Machine-readable endpoints - [/llms.txt](https://impossible-spaces-landing.pages.dev/llms.txt): This summary as plain text. - [/api/index.json](https://impossible-spaces-landing.pages.dev/api/index.json): This list. - [/api/projects.json](https://impossible-spaces-landing.pages.dev/api/projects.json): Every project: text, links, screenshot, how the page opens it, its cell, and its drawing. - [/api/projects/.json](https://impossible-spaces-landing.pages.dev/api/projects/.json): One project, including the full source of its drawing. - [/api/groups.json](https://impossible-spaces-landing.pages.dev/api/groups.json): The six groups and the plain-list cell, in ring order. - [/api/layout.json](https://impossible-spaces-landing.pages.dev/api/layout.json): Tiling parameters, every lit cell, sites, and cell vertices out to ring two. - [/api/regions.json](https://impossible-spaces-landing.pages.dev/api/regions.json): All 2400 cells with their region and step count. - [/api/pathfinders.json](https://impossible-spaces-landing.pages.dev/api/pathfinders.json): The walker rule and a seeded snapshot of every trail. - [/api/stars.json](https://impossible-spaces-landing.pages.dev/api/stars.json): The star catalog behind the Long Night cell. - [/api/sky](https://impossible-spaces-landing.pages.dev/api/sky): Live: star altitudes and azimuths now, or ?at=ISO-time&lat=&lon=. - [/api/source.json](https://impossible-spaces-landing.pages.dev/api/source.json): Every source file with its purpose and exports. - [/list.html](https://impossible-spaces-landing.pages.dev/list.html): The same projects as an ordinary web page. ## Source - [js/art.js](https://impossible-spaces-landing.pages.dev/js/art.js): One moving drawing per project, each showing what that project does. step signature: (ctx, w, h, t, dt, io) - [js/content.js](https://impossible-spaces-landing.pages.dev/js/content.js): generated from relay70 portfolio registry/catalog.json and site.json (entries with preview true, minus impossible-spaces) - [js/dossier.js](https://impossible-spaces-landing.pages.dev/js/dossier.js): the project's text, set in the margins around the opened cell - [js/field.js](https://impossible-spaces-landing.pages.dev/js/field.js): The coloring of the plane and the pathfinders that walk it. - [js/hyper.js](https://impossible-spaces-landing.pages.dev/js/hyper.js): Poincaré disk machinery. Complex numbers are {re, im}; isometries are SU(1,1) matrices [[a,b],[conj(b),conj(a)]] acting z -> (az+b)/(conj(b)z+conj(a)). - [js/layout.js](https://impossible-spaces-landing.pages.dev/js/layout.js): Where everything sits on the plane. Used by the page and by the build that writes /api, so both describe exactly the same layout. - [js/main.js](https://impossible-spaces-landing.pages.dev/js/main.js): a group brought to the middle is enlarged on a phone so its project names fit words for the cell nearest the middle: the introduction at the center, a group's summary on a group - [js/tiling.js](https://impossible-spaces-landing.pages.dev/js/tiling.js): {p,q} tiling generator for the Poincare disk. center of the circle through u and v that meets the unit circle at right angles - [js/view.js](https://impossible-spaces-landing.pages.dev/js/view.js): the group colors are chosen for paper; on the dark ground they are lifted to one lightness