zen-hi

byReptile Python

hi

No preview

Comments (0)

No comments yet. Be the first!

System Requirements

Page 1 of 22

System Requirements Document for zen-hi

1. Introduction

zen-hi is a personal webapp where a single owner publishes their own writing: long-form articles, personal posts, CVE writeups, and framework teardowns. It is not a multi-tenant platform, not a team blog, and not a SaaS product — it is one person's public notebook on the open web.

The product intent, derived from the authoritative requirement thread, is threefold:

  1. Publish personal writing. The owner posts their own articles and topical posts about CVEs, frameworks, and similar subjects.
  2. Present that writing publicly. Published content is readable by anyone who visits the site, without an account.
  3. Wrap it in a deliberate retro identity. The presentation must carry retro aesthetics with a 90s influence and a 4chan-mixed retro vibe — a hand-built, terminal-and-forum patina rather than a modern content-platform look.

The audience is technical peers and curious readers who grew up on BBSes, IRC, and old forums: people who read CVE writeups for pleasure and who recognize a ruled forum index when they see one. The owner is the sole author and the sole content manager.

Page 2 of 22

2. System Overview

zen-hi is a single-author publishing webapp with a public reading surface and a protected authoring surface.

Current delivery. A first-party web application with custom UI, backed by server-side persistence for posts and author identity. Published posts are served anonymously to any visitor. Authoring, editing, and publishing are performed by the authenticated owner.

Actors.

  • Site Owner / Author — the sole content creator and content manager. Enrolls once, verifies on return, writes and publishes articles and topical posts, and manages what is live.
  • Reader / Visitor — anonymous audience. Browses the board and reads published posts. Never authenticates, never writes.
  • Application (system) — stores posts and author identity, serves published content anonymously, and enforces that authoring surfaces are reachable only by the verified owner.

Accepted behavior. Self-service enrollment for the owner; returning verification; creation, editing, drafting, and publishing of articles and posts about CVEs, frameworks, and similar topics; a public board listing published posts as ruled forum rows; public reading of individual posts; owner-side management of the published set.

Ownership boundaries. All six destinations are first-party application surfaces. There is no third-party publishing provider, no external CMS, and no outbound syndication in the current scope.

Narrow exclusions. zen-hi is a personal webapp for the owner's own content — it is not a multi-author platform, not a community forum with visitor accounts or visitor replies, and not a general-purpose CMS. The 4chan influence is a visual and tonal register (plaintext bluntness, ruled board rows, hard-bordered panels), not a request to build an anonymous imageboard with visitor posting.

Page 3 of 22

2a. Product Interpretation and Delivery Boundary

Delivery ownership. zen-hi is delivered as a first-party web application with its own custom interface. The application owns the reading experience, the authoring experience, and the identity that binds published content to its author. No part of the accepted behavior is delegated to a provider-owned surface or an external destination.

Access ownership. Reading is open: the Landing and Articles destinations are reachable by anyone, with no account and no gate. Authoring is not open. Because the owner must privately own durable, resumable, author-specific state — drafts, edits, and the published set bound to the correct author — the application owns a minimal identity lifecycle: first-use self-service enrollment, and returning verification to resume protected content management. These are journey prerequisites for the accepted publishing work, not a general account-management feature set. There is no invitation flow, no provisioning flow, and no pre-existing account boundary; the owner starts from nothing and enrolls themselves.

Current vs. future. Everything described in Sections 3 through 5 is current. Nothing in this document is deferred. The owner's stated interest in "all of that" — CVEs, frameworks, and similar topics — is satisfied by the same posting capability applied to different subject matter, not by separate modules.

2b. Source Content Inventory

Not applicable. No reference directive in this project declares a content_source, so no verified factual inventory is carried into this document.

Page 4 of 22

2c. Page Content and Component Coverage

The page inventory below is the final, ordered page contract for zen-hi. Each page appears exactly once.

Landing

  • Information and state. The public entry surface, rendered as a 90s desktop rather than a marketing hero. A full-width 28px status bar holds the wordmark zen-hi in VT323 at 20px on the left, a live UTC clock in IBM Plex Mono 12px centre-left, and a blinking amber block cursor on the right. Below it, a 12-column visible grid: the left 3 columns hold a stacked 1-bit dithered pixel portrait of the author in amber-on-black inside a hard-bordered window frame with a three-square title bar; the right 9 columns carry the VT323 headline NOTES FROM THE STACK at clamp(40px, 9vw, 96px), stacked over a solid #FFB000 colour block 96px tall that bleeds to the right viewport edge. Under the fold line, a single row of the three latest thread subjects in IBM Plex Mono 14px with amber timestamps, separated by 1px rules. A left rail lists the thread categories — Articles / CVEs / Frameworks / Notes — each with its category cap colour.
  • Primary actions. READ THE BOARD — a chunky 2px-bordered button with a 3px hard offset shadow, pinned beneath the amber block, leading to Articles. Category rail entries lead to Articles filtered by that category.
  • Supporting actions. SIGN IN in the status bar for the returning owner; ENROLL for first-use. Latest-thread rows link to their posts.
  • Domain entities. Post (subject, timestamp, category, reply count), Category (Articles, CVEs, Frameworks, Notes), Author identity display.
  • Component responsibilities. Status bar (persistent across every page: wordmark, UTC clock, signed-in identity, two-frame blinking cursor); dithered portrait window frame; headline block with amber bleed; primary CTA; category rail; latest-thread row list; ASCII divider band (░▒▓ rows in #FFB000 at 30% opacity).
  • States. Loading: the 4-frame pixel boot wipe on first paint, with the status bar and grid rules already present. Empty: when nothing is published yet, the latest-thread row area shows a single ruled row reading that the board is empty, with the category rail still present. Success: portrait, headline, CTA, and up to three latest thread subjects render. Error: if the latest-thread fetch fails, the row area shows a ruled error row with a retry control; the hero, rail, and CTA remain fully usable. Recovery: retry re-fetches the latest threads in place without a full page reload.

Login

  • Information and state. The returning-verification surface for the owner. A hard-bordered panel on the #12100E ground, with the persistent status bar above it. Fields: identity and secret. A 1px amber outline marks focus — never a blue ring.
  • Primary actions. VERIFY — a 2px-bordered chunky button with a 3px hard shadow that snaps flat on :active.
  • Supporting actions. A link to Sign Up for a first-use owner who arrived here by mistake.
  • Domain entities. Author identity, verification session.
  • Component responsibilities. Status bar; credential panel; submit control; inline error region; link to enrollment.
  • States. Loading: the submit control shows a pressed, disabled state while verification is in flight. Empty: fields render empty with labels in IBM Plex Mono uppercase at 11–12px with 0.16em tracking. Success: the owner is taken to Post Manager with the status bar now showing the signed-in identity. Error: incorrect credentials render an inline ruled error row above the form; the entered identity is preserved and the secret is cleared. Recovery: the owner may retry immediately; repeated failure does not lock the account.
Page 5 of 22

Sign Up

  • Information and state. The first-use self-service enrollment surface for the owner. Same hard-bordered panel treatment as Login. Fields: identity, secret, and confirmation of the secret.
  • Primary actions. ENROLL — chunky 2px-bordered button with a 3px hard shadow.
  • Supporting actions. A link to Login for an owner who already enrolled.
  • Domain entities. Author identity, enrollment record.
  • Component responsibilities. Status bar; enrollment panel; submit control; inline validation region; link to verification.
  • States. Loading: submit control pressed and disabled during enrollment. Empty: fields render empty with uppercase micro-labels. Success: the owner lands on Post Manager, signed in, with the status bar showing the new identity. Error: mismatched confirmation or an already-taken identity renders an inline ruled error row; entered values other than the secret are preserved. Recovery: the owner corrects the field and resubmits without losing the rest of the form.

Articles

  • Information and state. The public board and reading destination. The board is a ruled forum index, not a card grid: each published post is a row carrying subject line, timestamp, reply count, and a 4px left cap stripe in its category colour (amber = article, orange = CVE, green = framework, muted = note). A category chip row filters the board. Opening a post renders the article view: a full-bleed ASCII divider band (░▒▓ rows in #FFB000 at 30% opacity), the post title in VT323 at clamp(28px, 5vw, 48px) over a 1px rule, metadata set in a tabular monospace block, and the body at a single 68ch reading measure in IBM Plex Mono 16px mobile / 18px desktop with line-height 1.7. Code, CVE IDs, and version numbers are set in monospace; framework architecture diagrams appear as pixel line art inside hard-bordered window frames with three-square title bars.
  • Primary actions. Select a thread row to read the post. Select a category chip to filter the board.
  • Supporting actions. Return from a post to the board; move to the next or previous published post.
  • Domain entities. Post (subject, body, category, timestamp, reply count), Category, Author byline.
  • Component responsibilities. Status bar; category chip row (horizontally scrollable on mobile); ruled thread row list with cap stripes; article header with ASCII divider band; tabular metadata block; 68ch reading column; window-framed figure blocks; next/previous navigation.
  • States. Loading: ruled placeholder rows in the board; the article view shows the divider band and title rule while the body loads. Empty: when no posts are published, the board shows a single ruled row stating the board is empty; when a category filter matches nothing, the board states that this category has no posts and offers a clear-filter control. Success: rows render with subject, timestamp, reply count, and cap stripe; the article renders at full reading measure. Error: a failed board fetch shows a ruled error row with retry; a failed post fetch shows the error inside the article frame with a retry control and a link back to the board. Recovery: retry re-fetches in place; the category filter and scroll position are preserved.

Post Manager

  • Information and state. The protected owner workspace for the published set. A dense table with visible column rules and tabular numerals: subject, category, status, published timestamp, and last-edited timestamp. Status uses the phosphor green #7FDB3A for published and muted #8A8072 for draft. The status bar shows the signed-in identity.
  • Primary actions. NEW POST — chunky 2px-bordered button leading to Post Editor. Select a row to open that post in Post Editor.
  • Supporting actions. Filter the table by category or status; sort by published or last-edited timestamp.
  • Domain entities. Post (subject, category, status, published timestamp, last-edited timestamp), Author identity.
  • Component responsibilities. Status bar; dense ruled table with tabular numerals; status indicator using palette state colours; filter and sort controls; NEW POST control.
  • States. Loading: ruled skeleton rows with column rules intact. Empty: when the owner has written nothing, the table area shows a ruled row stating there are no posts yet with a NEW POST control beside it. Success: rows render with subject, category, status, and both timestamps. Error: a failed fetch shows a ruled error row with retry; the NEW POST control remains available. Recovery: retry re-fetches the table in place; filters and sort order are preserved.
Page 6 of 22

Post Editor

  • Information and state. The protected owner workspace for creating, editing, and publishing. A two-pane split: markdown textarea on the left, live preview on the right, both inside hard-bordered panels. A fixed bottom action bar holds SAVE DRAFT and PUBLISH and never scrolls away. A subject field and a category selector (Articles / CVEs / Frameworks / Notes) sit above the panes; the selected category determines the cap-stripe colour shown on the board. On mobile the editor collapses to a single pane with a PREVIEW toggle.
  • Primary actions. SAVE DRAFT (floppy pixel glyph) persists the post without publishing. PUBLISH (envelope pixel glyph) makes the post live on Articles.
  • Supporting actions. PREVIEW toggle on mobile; category selection; subject editing; return to Post Manager without saving.
  • Domain entities. Post (subject, body, category, status, timestamps), Author identity.
  • Component responsibilities. Status bar; subject field; category selector with cap-stripe colour preview; markdown textarea; live preview pane; fixed bottom action bar with pixel glyphs; unsaved-change indicator.
  • States. Loading: when opening an existing post, both panes show a ruled loading state and the action bar is disabled. Empty: a new post opens with an empty subject, the default category, and an empty textarea; the preview pane shows a ruled placeholder. Success: SAVE DRAFT confirms with a phosphor-green success toast and the status indicator reads draft; PUBLISH confirms with a phosphor-green success toast and the status indicator reads published. Error: a failed save or publish shows a ruled error row in the action bar with a retry control, and the editor content is never discarded. Recovery: retry re-attempts the same operation with the same content; navigating away with unsaved changes prompts before leaving.
Page 7 of 22

3. Functional Requirements

Each requirement is a distinct story point with provenance, lifecycle facts, and observable acceptance.

FR-1 — Owner enrollment. As a Site Owner / Author, I should be able to enroll myself on first use so that I can begin publishing under my own identity.

  • Provenance: required_inference (self-service enrollment is required to make the accepted publishing journey executable; no invitation, provisioning, or pre-existing account boundary exists).
  • Trigger/input: the owner opens Sign Up and supplies an identity, a secret, and a matching confirmation.
  • Observable result: an author identity exists and the owner is signed in, with the status bar showing that identity.
  • Access state: Sign Up is anonymously reachable; no protected state is exposed before enrollment completes.
  • Failure/recovery: mismatched confirmation or an already-taken identity renders an inline ruled error row; entered values other than the secret are preserved and the owner resubmits.
  • Continuation: the owner lands on Post Manager and can create a first post.

FR-2 — Returning verification. As a Site Owner / Author, I should be able to verify myself on return so that I can resume control of my published content.

  • Provenance: required_inference (returning verification is required to resume durable, author-bound content management).
  • Trigger/input: the owner opens Login and supplies identity and secret.
  • Observable result: the owner is signed in and the status bar shows the signed-in identity.
  • Access state: Login is anonymously reachable; Post Manager and Post Editor remain unavailable until verification succeeds.
  • Failure/recovery: incorrect credentials render an inline ruled error row; the identity is preserved, the secret is cleared, and the owner may retry immediately without lockout.
  • Continuation: the owner lands on Post Manager with the published set available.

FR-3 — Create an article or topical post. As a Site Owner / Author, I should be able to write a new article or post about CVEs, frameworks, or similar topics so that I can publish my own writing.

  • Provenance: explicit (the owner posts their own articles and posts about CVEs, frameworks, and all of that).
  • Trigger/input: from Post Manager, the owner selects NEW POST and supplies a subject, a category (Articles / CVEs / Frameworks / Notes), and a body in the markdown textarea.
  • Observable result: the post exists in the owner's set with the chosen subject, category, and body; the live preview renders the body as it is typed.
  • Access state: Post Editor is reachable only by the verified owner.
  • Failure/recovery: a failed save shows a ruled error row in the fixed action bar with retry; editor content is never discarded.
  • Continuation: the owner saves a draft or publishes, then returns to Post Manager.

FR-4 — Save a draft. As a Site Owner / Author, I should be able to save a draft so that I can finish a post later.

  • Provenance: explicit (implied by the accepted authoring lifecycle; the editor's SAVE DRAFT control is the accepted mechanism).
  • Trigger/input: the owner selects SAVE DRAFT in the fixed bottom action bar.
  • Observable result: the post persists with draft status, shown in muted #8A8072 in Post Manager, and a phosphor-green success toast confirms the save.
  • Access state: verified owner only.
  • Failure/recovery: a failed save shows a ruled error row with retry; content is preserved.
  • Continuation: the owner may keep editing or leave; the draft remains in Post Manager.

FR-5 — Publish a post. As a Site Owner / Author, I should be able to publish a post so that it becomes live on my public board.

  • Provenance: explicit (the owner posts articles and topical posts publicly).
  • Trigger/input: the owner selects PUBLISH in the fixed bottom action bar.
  • Observable result: the post's status becomes published, shown in phosphor green #7FDB3A in Post Manager, and the post appears on Articles with its subject, timestamp, reply count, and category cap stripe.
  • Access state: verified owner only; the resulting published post is anonymously readable.
  • Failure/recovery: a failed publish shows a ruled error row with retry and the post remains a draft; content is preserved.
  • Continuation: the owner returns to Post Manager, or opens the published post on Articles to confirm it reads correctly.

FR-6 — Edit an existing post. As a Site Owner / Author, I should be able to edit a post I already wrote so that I can correct or extend it.

  • Provenance: explicit (the owner manages their own posted content).
  • Trigger/input: the owner selects a row in Post Manager, changing subject, category, or body in Post Editor.
  • Observable result: the updated subject, category, body, and last-edited timestamp are reflected in Post Manager and, for a published post, on Articles.
  • Access state: verified owner only.
  • Failure/recovery: a failed save shows a ruled error row with retry; navigating away with unsaved changes prompts before leaving.
  • Continuation: the owner saves or publishes and returns to Post Manager.

FR-7 — Manage the published set. As a Site Owner / Author, I should be able to see and manage everything I have published so that I know what is live.

  • Provenance: explicit (the owner manages their own posted content).
  • Trigger/input: the owner opens Post Manager and optionally filters by category or status, or sorts by published or last-edited timestamp.
  • Observable result: a dense ruled table lists each post with subject, category, status, published timestamp, and last-edited timestamp in tabular numerals.
  • Access state: verified owner only.
  • Failure/recovery: a failed fetch shows a ruled error row with retry; NEW POST remains available.
  • Continuation: the owner opens a post in Post Editor or starts a new one.

FR-8 — Browse the public board. As a Reader / Visitor, I should be able to browse the owner's published posts so that I can find something worth reading.

  • Provenance: required_inference (published content must be available anonymously for browsing and reading).
  • Trigger/input: the visitor opens Landing and selects READ THE BOARD, or opens Articles directly, and may select a category chip to filter.
  • Observable result: ruled forum rows render with subject, timestamp, reply count, and a 4px category cap stripe; filtering narrows the board to that category.
  • Access state: anonymous; no account required.
  • Failure/recovery: a failed board fetch shows a ruled error row with retry; a category with no posts states so and offers a clear-filter control.
  • Continuation: the visitor selects a row to read the post.

FR-9 — Read a published post. As a Reader / Visitor, I should be able to read a published article or CVE or framework post in full so that I can consume the owner's writing.

  • Provenance: required_inference (published content must be available anonymously for reading).
  • Trigger/input: the visitor selects a thread row on Articles or Landing.
  • Observable result: the post renders with a full-bleed ASCII divider band, the title in VT323 over a 1px rule, a tabular monospace metadata block, and the body at a 68ch reading measure; code, CVE IDs, and version numbers are set in monospace, and framework diagrams appear as pixel line art in hard-bordered window frames.
  • Access state: anonymous; no account required.
  • Failure/recovery: a failed post fetch shows the error inside the article frame with retry and a link back to the board.
  • Continuation: the visitor moves to the next or previous published post, or returns to the board.

FR-10 — Retro presentation across the product. As a Site Owner / Author and as a Reader / Visitor, I should experience the whole product in a retro 90s/4chan-mixed aesthetic so that the site reads as a hand-built personal notebook rather than a modern content platform.

  • Provenance: explicit (retro aesthetics, a little substance from the 90s, a little 4chan mix, retro vibe).
  • Trigger/input: any page load.
  • Observable result: the persistent 28px status bar with wordmark, live UTC clock, signed-in identity, and two-frame blinking amber cursor appears on every page; panels are hard-bordered 0px-radius rectangles; controls are chunky rectangles with a 3px hard offset shadow that snaps flat on :active; the board is ruled rows with category cap stripes; pixel glyphs mark save, publish, CVE, framework, and console actions.
  • Access state: applies to both anonymous and protected surfaces.
  • Failure/recovery: under prefers-reduced-motion, the boot wipe and typewriter reveal are replaced by their final frames and the blinking cursor holds steady.
  • Continuation: the aesthetic persists across every navigation.
Page 8 of 22

4. User Personas

Page 9 of 22

Site Owner / Author

Product context. The owner is the sole author and sole content manager of zen-hi. They built this site for themselves: a personal notebook where long-form articles, CVE writeups, framework teardowns, and shorter notes all live under one identity. They are technically fluent — they write about CVEs and framework internals — and they care about how the site feels, because the retro register is part of the point, not decoration.

Primary goal. To write and publish their own articles and topical posts, and to have a live personal site that presents that writing in a retro 90s/4chan-inspired aesthetic.

Distinct accepted responsibilities. The owner is the only actor who enrolls, verifies, writes, drafts, edits, publishes, and manages the published set. No other actor performs any of these. Their work spans two protected destinations — Post Manager for the published set, Post Editor for the writing itself — and their output is what makes the public board exist at all.

Relevant inputs and decisions. Subject line; category (Articles / CVEs / Frameworks / Notes), which determines the cap-stripe colour on the board; body content in markdown; the decision to save as draft versus publish; the decision to edit an already-published post.

Interactions with other accepted participants. The owner does not interact with readers directly — there are no visitor accounts and no visitor replies in the current scope. The relationship is one-directional: the owner publishes, and the Reader / Visitor reads. The owner's observable success depends on that reader-side outcome being reachable anonymously.

Observable success. A published post appears on Articles with its subject, timestamp, reply count, and category cap stripe; opening it renders the full reading treatment; Post Manager shows it as published in phosphor green with accurate timestamps.

Source-backed constraints. Content is the owner's own — this is a personal webapp, not a multi-author platform. The visual theme is a hard constraint on everything the owner sees and publishes into.

Page 10 of 22

Reader / Visitor

Product context. The reader is a technical peer or curious visitor who arrives at zen-hi from a link, a search, or word of mouth. They grew up on BBSes, IRC, and old forums, and the ruled board index and terminal patina are legible to them rather than confusing. They have no account and never will — reading is the entire relationship.

Primary goal. To find and read the owner's writing — articles, CVE writeups, framework teardowns — without friction.

Distinct accepted responsibilities. The reader browses the public board, filters by category, selects a post, and reads it. They are the only actor who consumes published content, and their successful outcome is the reason the publishing capability has a destination at all.

Relevant inputs and decisions. Which category chip to select; which thread row to open; whether to continue to the next post or return to the board.

Interactions with other accepted participants. The reader never interacts with the Site Owner / Author directly. They see the owner's byline and dithered portrait, and they read what the owner published. Their experience is entirely anonymous and entirely read-only.

Observable success. The board renders ruled rows with subject, timestamp, reply count, and cap stripe; the selected post opens at a comfortable 68ch reading measure with its ASCII divider band, VT323 title, and tabular metadata block; code and CVE IDs are set in monospace and framework diagrams render as pixel line art.

Source-backed constraints. No account, no gate, no visitor posting. The retro presentation applies to them exactly as it applies to the owner — including the readability floor: body text stays at or above 4.5:1 contrast and readable text and controls stay whole at 375px, 768px, and 1280px.

Page 11 of 22

5. Core User Flows

Flow A — The owner enrolls for the first time

  1. The owner opens zen-hi and lands on Landing. The status bar shows the zen-hi wordmark, a live UTC clock, and a blinking amber block cursor. The hero renders the dithered portrait, the NOTES FROM THE STACK headline over the amber block, and the READ THE BOARD CTA.
  2. The owner selects ENROLL in the status bar and arrives at Sign Up.
  3. The owner enters an identity, a secret, and a matching confirmation, then selects ENROLL. The button presses flat in one frame.
  4. Observable result: the author identity is created and the owner is signed in. The status bar now shows the signed-in identity.
  5. Failure path: if the confirmation does not match, or the identity is already taken, an inline ruled error row appears above the form. The identity field is preserved and the secret is cleared. The owner corrects the field and resubmits — no lockout, no lost work.
  6. Continuation: the owner lands on Post Manager, which shows an empty ruled table stating there are no posts yet, with NEW POST beside it.

Flow B — The owner writes and publishes an article

  1. From Post Manager, the owner selects NEW POST and arrives at Post Editor.
  2. The owner types a subject, selects the category Articles (the cap-stripe preview turns amber), and writes the body in the markdown textarea on the left. The live preview on the right renders the body as it is typed.
  3. The owner reviews the preview, then decides between drafting and publishing.
  4. Draft path: the owner selects SAVE DRAFT (floppy glyph) in the fixed bottom action bar. A phosphor-green success toast confirms, and the post persists with draft status.
  5. Publish path: the owner selects PUBLISH (envelope glyph). A phosphor-green success toast confirms, and the post's status becomes published.
  6. Observable result: the post appears in Post Manager with its subject, category, published status in phosphor green, and both timestamps in tabular numerals.
  7. Failure path: if the save or publish fails, a ruled error row appears in the action bar with a retry control. The editor content is never discarded. The owner retries the same operation with the same content.
  8. Continuation: the owner opens the published post on Articles to confirm it reads correctly, or returns to Post Manager to write the next one.
Page 12 of 22

Flow C — The owner writes a CVE or framework post

  1. From Post Manager, the owner selects NEW POST and arrives at Post Editor.
  2. The owner types a subject, selects the category CVEs (cap-stripe preview turns orange) or Frameworks (green), and writes the body. CVE IDs and version numbers are set in monospace; framework architecture diagrams are drawn as pixel line art and placed inside hard-bordered window frames with three-square title bars.
  3. The owner selects PUBLISH.
  4. Observable result: the post appears on Articles as a ruled row with its subject, timestamp, reply count, and the orange or green 4px cap stripe matching its category.
  5. Failure path: as in Flow B — a ruled error row with retry, content preserved.
  6. Continuation: the owner returns to Post Manager, where the post now shows published status.

Flow D — The owner returns and edits a published post

  1. The owner opens zen-hi and selects SIGN IN in the status bar, arriving at Login.
  2. The owner enters identity and secret and selects VERIFY.
  3. Observable result: the owner is signed in; the status bar shows the signed-in identity.
  4. Failure path: incorrect credentials render an inline ruled error row. The identity is preserved, the secret is cleared, and the owner retries immediately.
  5. The owner lands on Post Manager and selects the row for the post they want to change.
  6. Post Editor opens with both panes loading, then renders the existing subject, category, and body. The owner changes the body and selects PUBLISH.
  7. Observable result: the updated body and last-edited timestamp are reflected in Post Manager, and the change is live on Articles.
  8. Failure path: if the owner navigates away with unsaved changes, a prompt appears before leaving. If the save fails, a ruled error row with retry appears and the content is preserved.
  9. Continuation: the owner returns to Post Manager or opens the post on Articles.
Page 13 of 22

Flow E — A visitor browses the board

  1. The visitor opens zen-hi and lands on Landing. The 4-frame pixel boot wipe plays on first paint; the headline types out one character per 24ms. Under prefers-reduced-motion, both render their final frames instantly.
  2. The visitor reads the hero — the dithered portrait, the NOTES FROM THE STACK headline, the amber block — and sees the three latest thread subjects in ruled rows with amber timestamps.
  3. The visitor selects READ THE BOARD and arrives at Articles.
  4. Observable result: the board renders as ruled forum rows, each with subject, timestamp, reply count, and a 4px category cap stripe. Hovering a row inverts it to #EDE6D6 background with #12100E text in a single frame.
  5. The visitor selects the CVEs category chip to narrow the board.
  6. Empty path: if that category has no posts, the board states so and offers a clear-filter control.
  7. Failure path: if the board fetch fails, a ruled error row with retry appears; the category chips remain usable.
  8. Continuation: the visitor selects a row to read.

Flow F — A visitor reads a post

  1. From Articles, the visitor selects a thread row.
  2. Observable result: the post opens with a full-bleed ASCII divider band (░▒▓ rows in #FFB000 at 30% opacity), the title in VT323 at clamp(28px, 5vw, 48px) over a 1px rule, and a tabular monospace metadata block. The body renders at a single 68ch reading measure in IBM Plex Mono, 16px on mobile and 18px on desktop, line-height 1.7.
  3. Code, CVE IDs, and version numbers appear in monospace. Framework diagrams appear as pixel line art inside hard-bordered window frames.
  4. Failure path: if the post fetch fails, the error renders inside the article frame with a retry control and a link back to the board.
  5. Continuation: the visitor moves to the next or previous published post, or returns to the board. No account is ever requested.

6. Visuals, Colors and Theme

Muse: Susan Kare. Headline: Pixel-perfect clarity for a personal security journal.

The visual system is a 90s desktop/terminal surface with forum-board bluntness — small legible symbols with personality, grids you can feel, chunky-outline cards, frame-by-frame micro-animations. It must feel hand-built by one person, not a SaaS product.

Page 14 of 22

Colour tokens (dark mode)

RoleHexUse
Background#12100EThe page ground. Dark 90s-terminal.
Surface#1C1916Panel and thread-card fill, always with a hard 1px #EDE6D6 border — never a soft shadow.
Text#EDE6D6Warm bone, for reading at body size.
Primary#FFB000Amber. The single hot accent: links, the active thread marker, the boot cursor. Used on no more than ~8% of any screen.
Accent#7FDB3APhosphor green. Reserved for state: published, live status, CVE severity low, success toasts.
Muted#8A8072Metadata, timestamps, secondary UI.

Severity coding stays inside the palette: critical = #FFB000, high = #FF6A3D, medium = #7FDB3A, low = #8A8072. No blue anywhere.

Category cap stripes: amber = article, orange = CVE, green = framework, muted = note.

Typography

  • Headings: VT323 — display scale for the wordmark and section heads. Single-weight, uppercase, tracked tight, with a 1px hard text-shadow offset in #FFB000 to mimic CRT phosphor bleed.
  • Body: IBM Plex Mono Medium at 16–18px, line-height 1.7. Monospace voice for all metadata, CVE IDs, version numbers, and code.
  • Labels: IBM Plex Mono uppercase at 11–12px with 0.16em tracking.
  • Never mix in a geometric sans.
  • Scale: 1.25 modular on a 4px baseline — 12 / 14 / 16 / 18 / 24 / 32 / 48 / 64 / 96. Display headline clamp(40px, 9vw, 96px) in VT323; section H2 clamp(28px, 5vw, 48px); body 16px mobile / 18px desktop; metadata 12px; micro-labels 11px.
Page 15 of 22

Shape language

Hard pixel geometry. 0px radius everywhere. 1px solid #EDE6D6 borders on every panel; 2px borders on primary CTAs. Buttons are chunky rectangles with a 3px offset hard shadow (no blur) that snaps to 0 on :active — the classic 90s pressed-button state. Icons are 16×16 and 24×24 hand-drawn pixel glyphs: floppy disk for save draft, envelope for publish, bug for CVE, brackets for framework, terminal for post. Thread cards use a 1px border plus a 4px left cap stripe carrying the category colour. No rounded corners, no blur, no glass.

Layout

A 12-column hard grid with visible 1px column rules on the landing hero only, then a single 68ch reading measure for articles. Landing is a 90s desktop: a top status bar (site name, uptime clock, signed-in identity, blinking cursor), a left rail of thread categories (Articles / CVEs / Frameworks / Notes), and a main board of thread rows — subject line, timestamp, reply count, category cap stripe — like an old forum index, not a card grid. Post Manager is a dense table with column rules and tabular numerals. Post Editor is a two-pane split: markdown textarea left, live preview right, with a fixed bottom action bar (Save Draft / Publish) that never scrolls away. Mobile collapses the rail to a horizontal scrollable chip row and the editor to a single pane with a Preview toggle.

Page 16 of 22

Imagery

Imagery is the interface itself: pixel icon sets, ASCII dividers (a row of ░▒▓ blocks), a 1-bit dithered portrait of the author in the landing hero rendered as a pixel grid, and small schematic diagrams of framework architecture drawn as pixel line art. No photography, no 3D renders, no gradient blobs. Where a real screenshot of a CVE or terminal output is needed, it is presented inside a hard-bordered window frame with a fake title bar of three pixel squares.

Accessibility floor

Body text stays at or above 4.5:1 contrast. Headlines, wordmarks, labels, numbers, card text, and controls stay entirely inside the viewport and their container at 375px, 768px, and 1280px, wrapping or scaling to fit, with no other element covering any part of them. Horizontally scrollable rows (the mobile category chip row) may cross the container edge by design; every item becomes fully readable as it scrolls, and under prefers-reduced-motion the row stops and items wrap or remain reachable by scrolling.

Page 17 of 22

7. Signature Design Concept

The first screen is a 90s desktop, not a SaaS hero.

Top: a full-width 28px status bar in #1C1916 with a 1px #EDE6D6 bottom border, holding the wordmark zen-hi in VT323 at 20px on the left, a live UTC clock in IBM Plex Mono 12px centre-left, and a blinking amber block cursor on the right. This bar is the site's spine and persists across every page.

Below it, a 12-column visible grid. The left 3 columns are a stacked pixel portrait of the author, dithered in amber-on-black, inside a hard-bordered window frame with a three-square title bar. The right 9 columns carry a 9-column-spanning VT323 headline — NOTES FROM THE STACK — at clamp(40px, 9vw, 96px), stacked over a solid #FFB000 colour block 96px tall that bleeds to the right viewport edge. The primary CTA READ THE BOARD is pinned beneath the block as a chunky 2px-bordered button with a 3px hard shadow.

Under the fold line, a single row of the three latest thread subjects in IBM Plex Mono 14px with amber timestamps, separated by 1px rules.

Nothing is centred. Nothing floats. No gradient anywhere. The composition is asymmetric, grid-anchored, and reads as a machine someone assembled by hand.

8. Interaction Model & Motion Direction

Interaction Model: Static Motion Tempo: restrained Hero Dimensionality: flat

Page 18 of 22

Landing Hero Motion Brief

Focal subject. The dithered 1-bit pixel portrait of the author, framed in a hard-bordered window with a three-square title bar, sitting in the left 3 columns of the visible 12-column grid.

Input → transformation → outcome thesis. On first paint, a 4-frame pixel boot wipe resolves the grid and the portrait window into place; the headline then types out one character per 24ms, capped, until NOTES FROM THE STACK is fully set. The outcome is a fully composed 90s desktop — status bar, portrait, headline, amber block, CTA — with the blinking amber block cursor in the status bar continuing its two-frame cycle as the only persistent motion.

Motion vocabulary. Frame-by-frame and mechanical, never eased theatrically. 0ms snap transitions on hover and active states. A 2-frame blinking block cursor in the status bar. A 4-frame pixel boot wipe on first paint. A typewriter reveal on the hero headline at one character per 24ms, capped. Hover on a thread row inverts it to #EDE6D6 background with #12100E text in one frame. No parallax, no float, no scroll-triggered animation.

Composed first frame. The status bar is already present with the wordmark, UTC clock, and cursor. The 12-column rules are drawn. The portrait window and headline block are mid-wipe, resolving left to right.

Reduced-motion state. Under prefers-reduced-motion, the boot wipe and typewriter reveal are disabled and the full composed frame renders instantly: complete headline string, portrait fully resolved, grid rules drawn. The blinking cursor holds steady rather than cycling. No motion is required to read or operate anything.

Page 19 of 22

9. Non-Functional Requirements

NFR-1 — Anonymous public reading. Published posts must be readable without an account, a gate, or a redirect. Provenance: required_inference from the accepted public-reading journey. Rationale: the reader persona has no account and never will; any gate would break the accepted outcome.

NFR-2 — Protected authoring. Post Manager and Post Editor must be reachable only by the verified owner. Provenance: required_inference from the accepted authoring lifecycle. Rationale: drafts and the published set are author-bound durable state; the correct participant must be the one who can change them.

NFR-3 — Content durability. A saved draft or published post must survive session end and be recoverable on the owner's next verified visit. Provenance: required_inference. Rationale: the accepted draft-then-finish-later and edit-published-post journeys are impossible without durable storage.

NFR-4 — Retro presentation consistency. The status bar, hard-bordered panels, 0px radii, chunky pressed-button behavior, pixel glyphs, and ruled board rows must apply across every page, anonymous and protected alike. Provenance: explicit (retro aesthetics, 90s influence, 4chan-mixed retro vibe).

NFR-5 — Readability floor. Body text must meet at least 4.5:1 contrast against its background. Readable text and controls must stay whole inside the viewport and their container at 375px, 768px, and 1280px. Provenance: explicit (the creative direction's readability rule, which takes precedence over any cropping gesture).

NFR-6 — Motion accessibility. All motion — the boot wipe, the typewriter reveal, the blinking cursor — must be disabled or reduced to its final frame under prefers-reduced-motion. Provenance: explicit (creative direction).

NFR-7 — No blue. No blue or indigo may appear anywhere in the UI, including links and focus rings; focus uses a 1px amber outline. Provenance: explicit (creative direction).

NFR-8 — Responsive collapse. The category rail must collapse to a horizontally scrollable chip row on mobile, and the Post Editor must collapse to a single pane with a Preview toggle. Provenance: explicit (creative direction layout rule).

Page 20 of 22

10. Tech Stack

  • Frontend: React, with custom UI built to the visual system in Sections 6–8. No component library that would impose rounded corners, soft shadows, or a geometric sans.
  • Backend: Python with FastAPI, serving the public board and post reads anonymously and the authoring endpoints behind owner verification.
  • Storage: a persistent datastore for posts (subject, body, category, status, timestamps) and author identity. Relational storage is appropriate given the tabular Post Manager view and the category/status filtering it requires.
  • Containerization: Docker with docker-compose for local and single-host deployment.
  • Kubernetes: not required. The deployment shape is a single-author personal webapp; orchestration would add operational weight without a corresponding requirement.

No technology choice in this section was specified by the user; these are [Default — not specified by user] selections consistent with the accepted delivery shape (first-party custom UI, server-side persistence, app-owned identity).

Page 21 of 22

11. Assumptions and Constraints

Constraints (binding).

  • C-1 — Personal webapp. Content is the owner's own articles and posts. zen-hi is not a multi-author platform. Provenance: explicit.
  • C-2 — Retro theme. The visual theme must be retro aesthetics with a 90s influence and a 4chan-mixed retro vibe. Provenance: explicit.
  • C-3 — No blue. Blue and indigo are excluded from the UI entirely. Provenance: explicit (creative direction).
  • C-4 — No rounded corners, soft shadows, glassmorphism, or blurred panels. Every surface is a hard-bordered rectangle. Provenance: explicit (creative direction).
  • C-5 — No photography, 3D renders, or stock imagery. Imagery is pixel art, ASCII, and dithered 1-bit graphics only. Provenance: explicit (creative direction).
  • C-6 — No smooth eased animation, spring physics, parallax, or scroll-linked motion. Motion is frame-stepped and instant. Provenance: explicit (creative direction).
  • C-7 — Typography is VT323 and IBM Plex Mono only. No geometric sans, no system-ui, no Inter/Roboto/Poppins. Provenance: explicit (creative direction).
  • C-8 — 4chan-style visual noise must not break readability. No animated GIF backgrounds, no rainbow text, no sub-4.5:1 body contrast. Provenance: explicit (creative direction).

Assumptions (narrow, labeled).

  • A-1 — The owner is a single individual. No second author, editor, or moderator role exists in the current scope. Labeled assumption; consistent with C-1.
  • A-2 — Readers never authenticate and never write. There are no visitor accounts, visitor replies, or comment threads. Labeled assumption; the 4chan influence is a visual and tonal register, not a request for an anonymous imageboard.
  • A-3 — The "reply count" shown on board rows is a display element of the forum-row treatment. No visitor reply capability is accepted, so this count does not imply one. Labeled assumption.
  • A-4 — The owner's identity is established by self-service enrollment with no invitation, provisioning, or pre-existing account boundary. Labeled assumption; consistent with the planning scope's delivery_shape.app_owned_identity.
  • A-5 — No differentiated permissions exist. There is exactly one privileged actor (the owner) and one anonymous actor (the reader); no role-based visibility over shared state is required. Labeled assumption.
  • A-6 — The site is deployed as a single instance for a single author; horizontal scaling and multi-tenancy are out of scope. Labeled assumption.

Future (not current, not in acceptance).

  • Nothing in the authoritative requirement thread establishes a future horizon. No deferred capability is recorded here, and no future item may be built into the current pages.
Page 22 of 22

12. Glossary

  • Board — The public ruled-row index of published posts on the Articles page, styled as an old forum index rather than a card grid.
  • Cap stripe — The 4px left border on a thread row carrying the post's category colour: amber = article, orange = CVE, green = framework, muted = note.
  • Category — One of Articles, CVEs, Frameworks, or Notes. Determines the cap-stripe colour and the board filter.
  • CVE — Common Vulnerabilities and Exposures; a class of post the owner writes about, marked with the bug pixel glyph and the orange cap stripe.
  • Draft — A post saved but not published. Visible only to the verified owner in Post Manager, shown in muted #8A8072.
  • Enrollment — The owner's first-use self-service creation of their author identity on Sign Up.
  • Post — A unit of content written by the owner: an article, a CVE writeup, a framework teardown, or a note. Carries subject, body, category, status, and timestamps.
  • Published — A post that is live on the public board. Shown in phosphor green #7FDB3A in Post Manager.
  • Reader / Visitor — The anonymous audience persona. Browses and reads; never authenticates, never writes.
  • Site Owner / Author — The sole content creator and content manager persona. The only actor who enrolls, verifies, writes, edits, and publishes.
  • Status bar — The persistent 28px bar across every page holding the zen-hi wordmark in VT323, a live UTC clock, the signed-in identity, and a two-frame blinking amber block cursor.
  • Thread row — A single ruled row on the board representing one published post: subject, timestamp, reply count, and cap stripe.
  • Verification — The owner's returning sign-in on Login, which restores access to Post Manager and Post Editor.

No completed page designs yet.

Completed design pages will appear here when they are ready to preview.

Landing: Arrive and read hero
Landing: Retry failed thread fetch
Articles: 1. Browse ruled board rows
Articles: 2. Filter board by category
Articles: 3. Clear unproductive filter
Articles: 4. Retry failed board fetch
Articles: 5. Open a post to read
Articles: 6. Read published post
Articles: 7. Retry failed post fetch
Articles: 8. Read next or previous post
Articles: 9. Return to the board

No completed page designs yet.

Completed design pages will appear here when they are ready to preview.

Landing: Arrive and read hero
Landing: Retry failed thread fetch
Articles: 1. Browse ruled board rows
Articles: 2. Filter board by category
Articles: 3. Clear unproductive filter
Articles: 4. Retry failed board fetch
Articles: 5. Open a post to read
Articles: 6. Read published post
Articles: 7. Retry failed post fetch
Articles: 8. Read next or previous post
Articles: 9. Return to the board