Shipped the ramp editor. Eight characters and the whole site changes clothes.
Reporting redesign
- Company
- MaintainX
- Role
- Sr. Product Designer
- Status
- draft
The ring is the hero. Tap it to tear it, or feed it a photo in Play.
shadcn-style components in a brutalist ASCII skin. Frames, fills and shadows are strings of characters. Plain HTML underneath, bad signal on top.
Press / for commands. Long-press anything to break it. Scroll fast and the signal tears. The footer is a game.
Thirty components. Weight is character density, frames are strings, color is signal, glitch is feedback. The full rules are at the bottom.
The rim says how loud it is: @ for primary, = for the rest, / for danger.
Focus turns the frame to cyan @. An error turns it into a wall of !.
Use lowercase letters, numbers and hyphens.
Checkbox, radio and switch. Native inputs, the glyph is only the paint.
This one is wired to the page: it sets the RGB split, the tearing and the streaks. A real range input sits on top.
The active tab is a solid slab. Arrow keys move between tabs.
<button class="btn btn-primary
frame tone-heavy">
<span class="mid">
<span class="label">
Publish site
</span>
</span>
</button>
.tone-heavy {
--h: "@@@@@@@@@@@@...";
--s: "@@";
}
.frame::before,
.frame::after {
content: var(--h);
overflow: hidden;
}
.mid::before,
.mid::after {
content: var(--s);
}
Title on a bar of @, walls of #, and a shadow made of colons. Publishing opens the dialog.
Same halftone bar. The spinner lives inside the button.
A native details element. The marker flips between [+] and [-] and the answer decodes as it opens.
Thirty components, one HTML file and no build step. Copy the base once, then any component.
Yes. Every frame reads its characters from two custom properties, so a new tone is two strings.
Inverse slabs for status, brackets for everything else.
A card with a hazard rim. The title says what happened, the body says what to do.
Probes from 3 regions are timing out. Check the load balancer in fra-1.
Maintenance window on Sunday at 03:00 UTC. Probes keep running.
A native select inside the same frame as the input.
Loading is a wave moving through the ramp.
Initials on a slab, or a picture pushed through the LCD.
Slashes do the separating. The current page is a slab.
A month of buttons. Today is magenta, your pick is a slab.
Commands is a component too. It runs this site.
A button that opens a menu. Arrows move, Escape closes.
When there is nothing, say so and offer the next step.
Nothing is broken. Enjoy it, it never lasts.
Six brackets. They advance on their own and take a paste.
Type any six digits.
Keys in brackets. These ones are real.
Brackets around every page, a slab under the current one.
An LCD panel cut into twelve sectors. Every cell is three subpixels and each sector can run its own mode. Tap a sector.
Four weights of nothing.
A dialog that comes up from the bottom in seven steps.
Five ways to wait.
The same frame, four rows tall, with a counter.
0/280
Nodes are @, the wire is colons.
One line, typed in from the left. Lime for good news, yellow for the other kind.
Radios dressed as slabs.
Board view.
Hover, focus or tap. It types itself in.
Components composed into the pieces every product ends up needing. The content is from Static, a made-up uptime monitor that screams when things break. Six of them are about Fede, who made this. Filter by Personal to see only those.
Two fields, one loud button, one quiet one. Submit it empty to see it complain.
The number is a bitmap, the trend is eighteen characters of ramp.
Uptime, last 90 days
99.98 percent.+0.02
p95 latency, milliseconds
182 milliseconds.+14
Incidents this month
2 incidents.-3
A real table. Tap a row to select it.
| ID | Service | Status | Time |
|---|---|---|---|
| INC-481 | api-gateway | Down12m | 12m |
| INC-480 | checkout | Degraded48m | 48m |
| INC-479 | search | Resolved6m | 6m |
| INC-478 | webhooks | Resolved1h 02m | 1h 02m |
| INC-477 | auth | Resolved3m | 3m |
No incident selected.
Three cards. The popular one gets the @ rim.
$0 forever
$29 per month
$199 per month
An about block. The portrait is an LCD panel, so load your own face.
Fede Kotek designs B2B products in Buenos Aires. A decade of it: fintech, marketplaces, and software for people who fix machines.
Interaction, motion and visual craft. Thinks in systems, would rather not run the design system.
A timeline with opinions.
Four cards, four LCD thumbnails. Tap one.
Dashboards people read without being asked to.
One box, every work order, under 200 ms.
If this breaks, then page someone. No code.
Messaging for people wearing gloves.
Pick a case study.
What is going on outside of work.
Sunday asado. Change the servings and the quantities follow, in metric.
A character sheet on the halftone bar. Reroll it.
A checklist that counts. The domain is maintenance, because of course it is.
App navigation with counts. The arrow follows the current page.
These two switches are wired to the real page.
A feedback form with a verdict.
A feed is a timeline with timestamps.
The one page where the signal is lost for real. It never settles.
404.Signal lost. This page went for a walk and did not leave a note.
Charts drawn on the character grid. Density carries the value, color carries the meaning. Tap them.
Requests per day. Bars grow through the ramp and cap out lighter.
Tap a bar.
p95 latency, live. Spikes turn yellow. Tap the chart to break production.
p95 --
Probe success by region, on the same halftone bar as the slider.
Uptime by day. Lime is fine, yellow is degraded, magenta is an outage.
Tap a day.
Traffic by source. Yes, another donut.
Tap a slice.
Six presets, six color roles, four support shades and one ramp. Change any of them and the whole site follows, including the hero, the charts and the game. Copy the tokens when you like what you see.
Pick a signal. The page is the preview.
Every color has a job: surface, text, action, focus, success, warning. The four support shades follow the preset.
Eight characters from lightest to heaviest. Every frame, fill, chart and explosion is an index into them. Swap the characters and you have a different kit.
Classic ramp.
What you would paste into your own project.
The hero, with the hood open. Feed it a picture, type your own words, turn the knobs, then leave with a poster or a snapshot.
Feed the hero a picture. A photo, or the camera. Nothing leaves this page. Ring brings it back.
Two lines, up to 8 characters each. Five or fewer render at double size.
Everything the glitch engine exposes.
A random poster from your code. Reroll until you like one, then save it.
Three phone apps rebuilt in this language. A feed, a player, a chat. They all work as far as a prototype can, so tap around.
A small bird app. Like, repost, post. Counters glitch when they change.
Shipped the ramp editor. Eight characters and the whole site changes clothes.
INC-481 resolved. api-gateway is back. Please stop refreshing.
Hot take: every dashboard is a bar chart wearing a costume.
Walked 2.1 km. Sniffed 44 things. Barked at one leaf.
Expected value of that chest is negative. You opened it anyway. Respect.
A music player. Play generates a little tune from the ramp, so turn sound on.
Bad Signal
Static, Bad Signal LP
Messaging with a bot that answers in ramp. Send anything.
A component kit that looks like a broken broadcast and behaves like plain HTML. Copy a component, own the code, change the characters.
0 dependencies
30 components
8 characters in the ramp
1 type size
Four ideas hold the whole thing together.
Hierarchy comes from which character draws the frame. @ shouts, = talks and . whispers.
Every border, rule and shadow is a run of characters clipped to the box. No images and no SVG.
Tearing, RGB split and shards fire when you touch something or a state changes. One slider turns it all down.
Real buttons, inputs, dialog and details. Keyboards and screen readers get the plain version.
Five small labs. Each one is a piece of the system you can poke.
Brightness picks the character. Drag across the patch to move the light, and use the slider to change the exposure.
A border is one long string clipped by overflow. Type any character and the frame rebuilds itself out of it.
Headlines are a 5 by 7 pixel face where every pixel is four characters. Type up to eight and watch it develop.
Four effects, fired one at a time. On the rest of the page they fire on their own when state changes.
No audio files. Square waves for blips, a sawtooth for errors and filtered noise for the glitches.
The characters are paint. Underneath are native controls with labels, focus states and keyboard support, and decorative glyphs are hidden from assistive tech. Reduced motion switches the glitch off.
No. It is one HTML file. The components are classes and custom properties, so they drop into anything.
The grid is the design. Every width is a number of characters and every height a number of rows, which is what lets strings work as borders.
Yes. The Glitch switch kills it, the slider scales it, and the page respects reduced motion.
Bad signal on the outside, good HTML on the inside.
ascii/ui. An example one pager built from its own components. Set in Geist Mono.