component 22 / 28WORKING
SC Apple III 404
- type
- Code Component
- platform
- Framer
- license
- SecretoCho Design
demo · runs with JavaScript
A terminal-style 404 page: ASCII boot banner, glitch burst, then a working command prompt that redirects to the site’s main links.
AppleIII404 is the old site’s 404 screen as a fake terminal. It boots with a SECRETOCHO ASCII banner and progress line, glitches into random symbols, then settles on a 404 banner with a prompt. Visitors can type help, list, home, services, resources, blog, contact, back, retry or cls; the navigation commands redirect to the links set in the controls, everything else prints “not recognized”. A footer row repeats the five links.
- UI
- Text
- Motion
Main
Overview
- Built With
- React (hooks), framer-motion (AnimatePresence), Framer Code Component API
- Layout Support
- Full viewport height (100vh), scrolls inside
- Orientation
- Vertical: banner and prompt on top, link row pinned to the bottom
- Ideal Use Case
- 404 and error pages with a hacker / retro-computer tone
Tags
Code comment
MS404.tsx has no doc comment.
Dependencies
- Technologies
- framer-motion (part of the Framer runtime)
- Notes
- Plays an MP3 from a third-party host at the glitch stage; see Security.
Complexity
- Logic Level
- Low–Medium (three timed stages, a command map, redirect timer)
- Runtime Cost
- Very Low (two timers, one opacity animation)
- Component Size
- ~10 KB TSX (9,530 bytes, 245 lines)
- Notes
- Both timers are cleared on unmount.
Guide
Instructions
- Place AppleIII404 on the 404 page as a full-height layer.
- Set Background and Font Color (default black and phosphor green).
- Set the Font object: family (IBM Plex Mono by default), size, style, weight, letter spacing, line height.
- Fill the five Link controls: Home, Services, Resources, Blog, Contact — the prompt’s commands and the footer row use them.
Examples / Presets
Apple III
The source defaults: black, phosphor green #33FF33, IBM Plex Mono 16 px, no links set.
As on the site
- bgColor
- transparent
- fontColor
- primary--1000
- font.fontFamily
- Recursive
- font.fontWeight
- 300
- homeLink
- /
- servicesLink
- /services
- contactLink
- /contact (the old site’s 404 page)
Mechanics
How it Works
- Stages: on mount a 404 ms timer switches from loading (ASCII SECRETOCHO banner, “SYSTEM BOOTING”, a 99 % bar) to glitch and plays the beep; a 2,000 ms timer switches to done.
- Glitch: two strings of 300 and 120 random characters from !@#$%^&*()_+=-~?><:{}[], in a 0.4 s framer-motion opacity fade with repeat 4, reverse (five alternating legs); the done stage replaces it at 2,000 ms.
- Prompt: an auto-focused <input>; on Enter the lower-cased command is looked up in a map of ten responses, echoed into the history, and for home / services / resources / blog / contact / back the page redirects after 200 ms via window.location.href.
- Unknown commands print “Command '…' not recognized.” cls is in the map but only echoes (nothing clears the history).
- Footer: five plain links in the font colour under a 1 px rule.
Performance & Tuning
- Negligible: two timers and one AnimatePresence transition.
- The glitch strings are regenerated on each render of that stage; it lasts under two seconds.
Compatibility & Limits
- Evergreen browsers; needs framer-motion (bundled with Framer).
- 100vh height: on mobile browsers the bottom link row can sit under the browser chrome.
- Audio autoplay without a gesture is blocked by most browsers, so the beep is often silent (its play() promise is not handled).
- The caret uses a CSS class (blinking-cursor) that the file does not define; it blinks only if the page supplies that style.
Quality
Accessibility
- The prompt is a real, auto-focused text input, so keyboard users can type commands; the footer links are plain <a>s.
- The ASCII banners are raw text to a screen reader; consider aria-hidden on them and a plain heading.
- The glitch flicker is brief but rapid; no reduced-motion check.
Security & Privacy
- Network: line 12 creates an Audio element for a beep on soundjay.com when the module loads (line 41 plays it during the glitch), so the browser requests that file from a third-party host on every page that loads the component. No fetch of its own, no tracking.
- Navigation: window.location.href is set to the configured Link controls, and also for the typed words “constructor” and “__proto__”, which the command lookup matches on the object’s prototype.
- No storage, no permissions; input text is echoed as React text (no HTML injection).
Reference
Props
| name | type | default | description |
|---|---|---|---|
bgColor | color | #000000 | Background. |
fontColor | color | #33FF33 | Font Color. Text, caret, rule and footer links. |
font | object | fontFamily=IBM Plex Mono, fontSize=16, fontStyle=normal, fontWeight=400, letterSpacing=0px, lineHeight=1.6em | Font. Family, size, Normal | Italic, weight, letter spacing, line height. |
homeLink | link | — | Home Link. Target of home and back. |
servicesLink | link | — | Services Link. |
resourcesLink | link | — | Resources Link. |
blogLink | link | — | Blog Link. |
contactLink | link | — | Contact Link. |
The five Link controls have no defaults: an unset link is undefined, so its command sets location.href to the relative path “undefined”, and its footer link renders without an href.
Notes & Tips
- Type help at the prompt to list the commands; list prints the five paths.
- Set the input’s variable-font MONO axis: the file sets font-variation-settings "MONO" 1 on the input for a Recursive-style font.
- Define .blinking-cursor in the page’s CSS if the caret should blink.
Troubleshooting / FAQ
No beep
Autoplay without a user gesture is blocked, or the third-party host did not answer; the file does not handle the rejected play().
cls does not clear the screen
Expected: cls only echoes an empty response; nothing resets the history.
The caret does not blink
The blinking-cursor class is not styled in the file.
A command goes to a page called “undefined”
Its Link control is not set; an unset link is undefined (an empty string would reload the current page).
Source
Key excerpt
The prompt is a ten-entry command map: a known command is echoed with its response and, for the navigation words, redirects after 200 ms; anything else prints “not recognized”.
const handleCommand = (e: React.KeyboardEvent<HTMLInputElement>) => { if (e.key === "Enter") { const cmd = input.trim().toLowerCase() const responses: Record<string, string> = { help: "Available commands: home, services, resources, blog, contact, back, retry, cls, list", back: "Redirecting to homepage...", retry: "Retrying the broken request... nothing changed.", cls: "", list: "./home ./services ./resources ./blog ./contact", home: `Redirecting to /home ...`, services: `Redirecting to /services ...`, resources: `Redirecting to /resources ...`, blog: `Redirecting to /blog ...`, contact: `Redirecting to /contact ...`, } if (cmd in responses) { setHistory((prev) => [...prev, `> ${cmd}`, responses[cmd]]) setInput("") setTimeout(() => { const linkMap: Record<string, string> = { home: homeLink, services: servicesLink, resources: resourcesLink, blog: blogLink, contact: contactLink, back: homeLink, } if (cmd in linkMap) window.location.href = linkMap[cmd] }, 200) return } setHistory((prev) => [...prev, `> ${cmd}`, `Command '${cmd}' not recognized.`]) setInput("") } }Credits
Credits
© SecretoCho Design
- license
- SecretoCho Design
SecretoCho Design
Disclaimer
Provided “as is” for visual/UX purposes. Validate performance, accessibility, and licensing within your project.
Proves
Hiring a design engineer?
I’m open to senior design engineer roles: remote from Belgrade, or relocation with visa sponsorship. Write to me, or read the CV first. Client work stays selective, one project at a time.
sc@secretocho.design