Skip to content
Kumar Chandrachooda
kc@kumarChandrachooda.com:~$ cd /design-system/chrome && read --section="01 brand" 0%
KC Design System — Green-bar / Marginalia

Printed to last.
One system, every component.

The green-bar style prints the system on continuous form in design-system-greenbar.css: IBM Plex Mono capitals, banded paper punched down both edges, torn rules and [ BRACKET ] buttons. Same components, same markup — straight off the line printer.

Reading in an unnamed pair — greenbar / marginalia Browse all 8 →

01

Brand marks

Four lockups the name can wear, all one block. The base .ds-brand is what the site ships — the bitmap logo beside the full name — and the three modifiers are the alternatives. --monogram sets the initials in the signature 2px box beside the name; --plate is the postmark, the name stacked over a mono role kicker on a filled slab; and --dot is the compact mark, lowercase mono initials closed by the single full stop that carries the accent. None of them fork for dark: every colour resolves through a --ds-brand-* property, so an ink surface declares .ds-on-dark once and the marks follow — the same eight tokens the scrolled header already flips, which is why it is named in that block rather than restating them.
The base lockup (.ds-brand, no modifier). The mark the site actually wears: the 40px bitmap logo and the full name, set at --ds-text-md bold with a touch of tracking. It is the only lockup whose glyph is an image rather than type, so on ink it cannot recolour through a token — it inverts, exactly as the scrolled band inverts it. The name is an unclassed span, which is why the dark rule has to come from the surface rather than from the element.
The monogram (.ds-brand--monogram). Initials in the signature 2px box, name alongside — the smallest lockup that still says both things. The box stays an outline on either surface and only its stroke colour moves, so the mark never turns into a different shape in the dark; hover fills it periwinkle, the one move it borrows from the button. Square corners: it is a surface, not a control.
The plate (.ds-brand--plate). The postmark: the name over a mono role kicker in a drawn 2px frame — the one place the brand is allowed two lines. It used to be a filled slab, which made it the only lockup that inverted against its surface rather than with it. It no longer does: the frame stays an outline on both surfaces and only its stroke colour moves, exactly as the monogram's box does, so the lockup never becomes a different shape in the dark. That costs one token (--ds-brand-plate-edge) and buys back a whole category of surprise.
The frame is a pseudo-element, not a border on the box, and that is not a flourish: a real border occupies layout, so it could not be absent from a folded plate without shifting every row by 2px. Being a pseudo lets it be drawn — which is the last beat of the fold below. The three rows are three elements, each leading with a .ds-brand__seed: the glyph of the dot mark that row grew from.
The dot (.ds-brand--dot). Lowercase mono initials closed by a full stop — the compact mark, for the places a full name will not fit. The stop is the only place the accent is spent, and it is the only thing that moves in the dark: periwinkle on paper, violet on ink, where the stronger tone would vibrate. --ds-brand-dot-size carries the same mark from this header scale to the 3rem loader splash without a second rule. It reads as initials, not a word, so the link carries the name in its aria-label.
Plate to dot, and back (.ds-brand-fold). The last two lockups are not two marks — the plate is the dot, unfolded. Each of the plate's three rows carries the glyph it grew from, so folding does not swap one lockup for another, it stands the same three glyphs back down into a row. That is what lets a column narrow to 84px without the identity at the top of it blinking into something else.
Four beats, in order: kc. stands up from a row into a column and shrinks to the plate's own size as it goes; the frame is drawn round the column it now encloses; each glyph hands off; each word writes out, one row after another. The glyph is gone before its word arrives — lowercase mono cannot be interpolated into bold sans, and two typefaces caught overlapping read as a glitch rather than as a handoff.
A fold only means anything at two widths, so each frame below is a column that narrows, built from the rail's own tokens. Hover one, or tab into it. On the live rail the same two states are the collapse and the breather. Both surfaces, as everywhere else on this page — and nothing in the pair is restated for the dark one. The frame, the glyphs and the kicker all read the plate's own tokens, so the fold inverts by standing on a different surface rather than by being told to.
02

Icons

One canvas, one stroke, one place they live (_Icon): 24×24, bare geometry carrying nothing but coordinates, and a 2.4 stroke supplied by whatever surface the mark lands on. Nothing here names a colour, which is the only reason the same forty-six marks can sit on paper in one row and inside an ink plate in the next without a second copy of themselves — the two panels below are that claim, run twice on identical markup. Square caps and miter joins because there is not a rounded corner anywhere in this system; angles of 0, 45 and 90 and nothing else. The set is also honest about itself. The thirty-nine destination marks and the seven chrome marks meet the contract; the thirteen below the fold do not, and each one says which rule it breaks and where it ships. They are drawn at the weight they actually render, not corrected on the way to the page. The full contract — counter minimums, the element budget, the five-question review test — is in docs/guidelines/icon-style-guide.md.
The whole governed set at 20px — the size the rail renders, which is the only size the review test is run at. The two panels are the same forty-six <partial> calls; the ink one declares a colour and changes nothing else.
On paper
On ink

Destinations

The rail set — thirty-nine marks, six of them level one and the rest level two, each app followed by its own rows. Collapsed, the rail is 84px and the icon is the row — so these carry the least detail in the system, and the app marks carry the least of all.
app-resume frame + three pips
app-blog page, turned corner
app-design four brackets
app-workshop bench, the piece on it
app-control a panel of three switches
app-identity one figure
home house
about bust
skills bars on a floor
experience a climb
projects a hung selection
certifications medal and ribbon
overview front page as layout
topics four equal cells
series stacked sheets
articles marked rows
components four parts on a grid
studio two tracks, two handles
themes swatch of three stops
foundations four courses on a base
screens a screen with its message
classic square cut down
flow square cut across
sketch square drawn freehand
blotter index card with a head rule
transit line through a roundel
greenbar punched sheet
blueprint sheet with a title block
marginalia lines with a gloss
drafts sheet, corner turned
new sheet, corner turned, a plus
review sheet, corner turned, a tick
switches one switch, thrown
people two figures
queue a stack, one stepped out
audit ruled entries, a margin
account card, portrait and two rules
settings three faders
switch-viewer a figure, two ways

Chrome

The marks on controls. Same canvas, same stroke, same silence about colour. close was inline in nine places before this section existed — three in the drawer, three in the modal, two in the toast, one in this page's own chrome — and every copy agreed, which is the kind of agreement that holds until someone edits one of them.
sign-in an arrow into a bracket
sign-out an arrow out of a bracket
close drawer, modal, toast
menu drawer tab
chevron-left carousel, rail latch
chevron-right carousel, cta
download rail cv button

Off the contract

The thirteen marks that ship and do not meet the rules. They are drawn here exactly as they render on their own pages — the 1.6-weight ones at 1.6, the round caps round, the solid ones solid — because a specimen redrawn to the contract would quietly hide the thing worth seeing. Set them beside the panels at the top of this section: the feature and counter marks read as a lighter, softer family, and they are on the same screen as the rail. Nothing here is a bug. It is a list of decisions that were made one at a time, before there was a set to make them against.
download-document resume cv buttons Filled, and bezier arcs in the corners. Draws the same action as the hollow download above it.
linkedin site footer Filled, bezier throughout. A third-party brand mark — kept whole on purpose, since a redrawn LinkedIn is still theirs.
lightbulb skills · feature card Bezier curves; drawn at stroke-width 1.6 rather than 2.4.
monitor skills · feature card rx="2" corner radius; stroke-width 1.6.
flag skills · feature card Half-unit coordinates, and the angles they make are neither 45 nor 90; stroke-width 1.6.
code-brackets skills · feature card The slash is six degrees off vertical where only 0, 45 and 90 are permitted; stroke-width 1.6.
compass skills · counter Half-unit coordinates and free angles; stroke-width 1.6 with round caps and joins.
pencil skills · counter Bezier arc in the nib, half-unit coordinates; 1.6 with round caps.
monitor-stat skills · counter rx="2"; 1.6 with round caps. A second monitor, one unit shorter than the first — two marks for one object.
award skills · counter Decimal coordinates; 1.6 with round caps. The same award as certifications, drawn again to different rules.
caret-right deck indicator A closed triangle, and one of the two side carets that carry fill and stroke on the path itself — the only marks in the system that do.
caret-left deck indicator The same triangle mirrored, with the same attributes on the path. Strip them to obey the contract and the deck's indicator goes solid.
caret-down deck indicator Filled. It marks the current slide, and solid is how the indicator says so.

Injected by the behaviour layer

The behaviour layer builds three marks into elements that do not exist until JavaScript runs — the code block's copy button, its copied state, and the anchor on every prose heading — so a Razor partial cannot reach them. The geometry has a key here and the strings that actually ship live in wwwroot/js/ds/. That is the one real seam in the set: two copies of one drawing, which have to be changed together. Saying so is cheaper than a build step that would prove it.
copy util.js · COPY_ICON Filled, bezier corners.
check util.js · CHECK_ICON Filled; the tick is an outline, so its weight cannot follow the surface.
link prose.js · headings Bezier arcs throughout; stroke-width 2 with round caps.

Using one

<partial name="_Icon" model='@(new IconSpec("close"))' />

<!-- the rail is the one surface that needs a class on the element,
     because it hangs per-glyph modifiers off the same hook -->
<partial name="_Icon" model='@(new IconSpec(app.Icon, "ds-rail__icon"))' />
/* everything else styles the glyph through its container, and the mark
   supplies nothing but coordinates */
.ds-drawer__close svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: square;
  stroke-linejoin: miter;
}
An unrecognised key renders the neutral square — not a dashed box, not a question mark. A rail row can take its key from a registry, and a row registered before its glyph is drawn should show a plain mark rather than a silent gap. It is also why this page is counted rather than written: a mark the renderer gains and this list never hears about leaves no trace at all, so an omission reads exactly like a complete set. The full contract, including the counter minimums that decide what can be drawn at all and the five-question review test, is in docs/guidelines/icon-style-guide.md.
04

Spine rail & two-level navigation

The header turned through ninety degrees (--rail): chrome leaves the top edge for the left margin, and the room that buys pays for the second level of navigation the band never had space for. The three apps stack as one bordered plate; beneath them the 2px rule turns inward into a timeline carrying the current app's sections. Switch app and the spine re-populates — slides in the Resume, archive surfaces in the Blog, the two skins here — while the geometry never moves. Primary wears the ink, secondary wears the accent, so a place you are and a position that moves can sit 40px apart and still never be confused. The latch parks it at one cell wide, and from there hover or focus opens the full column over the page rather than pushing it: horizontal padding is the same at both widths, so the cell lands on the same pixel and collapsing changes what is written beside a row, never where the row is. Below 992px it becomes a slide-over, which keeps the two levels stacked instead of flattening them into one menu.
The rail. The header turned through ninety degrees: chrome leaves the top edge for the left margin, and in the room that buys it grows the second level of navigation the band never had space for. Brand, then the three apps as one bordered plate divided by the 2px rule, then that rule turned inward into a timeline carrying the current app’s sections, then the CV button on the floor. Primary wears the ink, secondary wears the accent — the current app is a filled plate, a place you are; the current section is a periwinkle marker, a position that moves. Two levels, two colours, and no way to confuse them.
Switch app, and the spine re-populates. The geometry never moves — only the label and the rows under it. In the Portfolio the spine reads slides and lists the deck’s panels; in the Blog it reads sections and lists the four surfaces of the archive. Both come from one ISiteNavigation, so a destination cannot exist in the rail and nowhere else.
The shortest spine on the site. This page’s own second level is not its forty-one sections — those are a table of contents for one page, and they stay in the drawer. It is which skin you are reading in: Classic or Flow. Two rows, and the spine still reads as the same component, because a level that can be short without looking broken is a level that can be honest about how much is under it.
Collapsed, and the breather. Hover the rail below. The latch parks it at one cell wide; from there hover or keyboard focus opens the full column over the page rather than pushing it, on the pop shadow that anything floating free of an edge earns. The page’s margin follows the resting width and never the hovered one, so content holds still while the column passes across it — the reason to overlay rather than reflow is that a reader glancing at the nav should not lose their place in the text. Closing carries a --ds-rail-close-delay so a cursor travelling diagonally back to the page does not snap the column shut as it clips the corner; opening has none.
Nothing moves when the rail breathes. Every row is a --ds-rail-cell square plus a label that fades, and the horizontal padding is identical in both states, so the collapsed width is derived — cell plus two paddings — rather than picked. The cell therefore lands on the same pixel either way: collapsing changes what is written beside a row, never where the row is. That is what stops it reading as two components swapping. The same discipline decides the marks: the plate is the lockup drawn for a corner and tops the open column, but 84-odd pixels have room for initials and nothing else, so collapsed always falls back to the dot — and it is swapped by display, not opacity, so only one of the two is ever in the accessibility tree. The icons are load-bearing here, not decoration: collapsed, the cell is the entire row, and a mono number that read fine beside a word does not survive being the only thing left. They follow their own style guide (docs/guidelines/icon-style-guide.md) — 24px canvas, 2.4 stroke, square caps, no curves, because a set that drifts in weight stops reading as one row.
Below 992px, a band and a full-page menu. A phone cannot spare a permanent 264px column, so the rail hands the page its width back and keeps only a band — the mark and the toggle, in both states. What the toggle opens is the page: a 264px drawer is a shape borrowed from the column it came from, and at this width the column is not the point. The map gets the screen, carrying the same two levels in the same order — order kept intact rather than two levels reflowed into one flat menu is the whole reason the component exists. There is no scrim, because a full-page panel has no outside to dim; the toggle stays put above it and becomes the way out. 992px is deliberate: it is the same threshold the deck disengages at, so the Portfolio never has a rail without slides to track. Shown here at desktop width, declared open rather than tapped open.
Two class choices carry the component. The panel is .ds-rail__nav, not .ds-nav: the phone overlay restyles every .ds-nav descendant into the full-screen ink menu — down to a counter on ::before, which is precisely where the spine draws its marker — and that block sorts after this one, so taking a different class is cheaper and steadier than out-specifying it. The section links, though, keep .ds-nav__link, because that is the hook the deck reads: any such link whose fragment names a panel is already wired to page the deck and to receive .is-active as it moves. The spine gets slide tracking for nothing, and pays only by overriding the underline wipe it would otherwise inherit.
06

Context banner

The bar across the top that says what you are looking at (.ds-context-bar), for when what you are looking at is not what a visitor to this URL would see. Full-bleed and above the content, because that is the only position that cannot be mistaken for part of the page it is describing. Three tones and no fourth — you are somewhere unusual, the site is in a state, what you press will not do what it normally does — and the constraint is the component: a banner that can say anything in any colour stops being read, which is the one failure mode that matters for the one thing whose entire job is to be noticed. Three consumers were waiting for it before it existed: the draft preview, maintenance mode, and viewing a page as somebody else.
The bar that says what you are looking at, when what you are looking at is not what a visitor to this URL would see. It is full-bleed and above the content, because that is the only position that cannot be mistaken for part of the page it is describing.
Draft You are looking at a preview. Nobody else can open this link. 19 Sep 2026 (proposed) back to the editor
Notice The site is in maintenance mode. Visitors see the splash; you see the site. turn it off
Acting as You are viewing this as Jo Tan. Anything you press happens as them. stop
07

Reading progress strip

One line of chrome doing four jobs (.ds-progress): identity, app, the section actually being read, and how far through — written as a single shell invocation, because the mono voice is the brand’s own. The prompt holds the left end; the middle is a cd into the page whose --section flag rewrites itself by scroll-spy, caret still blinking; the right side composes up to three optional readouts — section counter, percentage, and the bar itself as either a 2px accent rule along the bottom edge or a ten-glyph ASCII meter drawn in text. Light-mode native on a hairline rather than an ink plate, so it can sit under the white header band without reading as a second header; --pinned sticks it below whatever chrome the page wears via --ds-chrome-top. The markup is passive; progressStrips() drives the flag, the counters and the fill, and speaks the state through role="progressbar". It ships live on all three apps, composed per app through ViewData["DsProgress"]: blog posts read --section over their own h2s with the percentage and the rule; this page reads its catalog into the ASCII meter — look up — and the resume deck presents a --slide flag with a slide counter, fed by the deck itself, because a stage that pages by transform has no scroll to spy on.
The command line — the default. The whole state as a single shell invocation: the prompt, a cd into the page, and a live --section flag that rewrites itself as you scroll, the caret still blinking at the end. The right side carries the section counter and the percentage; the progress bar is the 2px accent rule filling along the strip’s bottom edge — present, never competing with the text. Scroll inside the frame.
kc@kumarChandrachooda.com:~$ cd /blog/an-event-bus-in-seven-files && read --section="01 the-contract" section 1/5 0%

01The contract comes first

02Commands and events on the wire

03A shadow registry of every message

04Swapping the transport underneath

05Seven files, one idea

The ASCII meter — the same strip with the progress drawn in block glyphs instead of a rule: ████░░░░░░, ten characters filling in periwinkle beside the percentage. No track element, no div — the meter is text, which is exactly the joke and exactly the credibility. A strip carries the meter or the fill, never both; two progress readings a rounding error apart read as a bug.
kc@kumarChandrachooda.com:~$ cd /blog/an-event-bus-in-seven-files && read --section="01 the-contract" 0%

01The contract comes first

02Commands and events on the wire

03A shadow registry of every message

04Swapping the transport underneath

05Seven files, one idea

The readouts, composed — the right side is three optional spans, and a page keeps only what it needs: the section counter alone for a piece where the count is the point, the percentage for a long single read, and one of the two bars where the glance should not need numbers at all. Held at sixty-two percent so the four can be compared.
kc@kumarChandrachooda.com:~$ read --section="03 the-registry" section 3/5
kc@kumarChandrachooda.com:~$ read --section="03 the-registry" section 3/5 62%
kc@kumarChandrachooda.com:~$ read --section="03 the-registry" 62%
kc@kumarChandrachooda.com:~$ read --section="03 the-registry" 62%
PieceHookNotes
Strip.ds-progress[data-ds-progress]Wired by progressStrips(). Add --pinned to stick it below the page’s chrome via --ds-chrome-top.
Sections[data-ds-progress-mark="01 name"]On the content, in order. The last mark scrolled past the strip is “current”.
Flag value[data-ds-progress-section]Rewritten, quoted, as the reader scrolls.
Counter[data-ds-progress-index]1-based; the total is server-rendered.
Percentage[data-ds-progress-pct]Whole numbers; __pct reserves 4ch so 9→10 cannot nudge the row.
Rule fill.ds-progress__fillReads --ds-progress off the strip; 2px accent along the bottom edge.
ASCII meter[data-ds-progress-meter-on/-off]Ten glyphs, █ lit / ░ spent. Carry one bar per strip, never both.
AppThe commandThe readouts
Blog postcd /blog/<slug> && read --section=…, spied off the article’s own h2sPercentage + rule fill — a read is one continuous measure.
Design systemcd /design-system && read --section=…, one mark per catalog sectionASCII meter + percentage — the audience that gets the joke.
Resume deckpresent --slide=… — no cd; the prompt is already homeSlide counter + rule fill, fed by ds-deck-state from the deck — six discrete slides make a percentage fake precision.
A page opts in by putting a ProgressStrip in ViewData["DsProgress"]; the layout renders it at the top of main through _ProgressStrip, pinned under the page’s chrome — or fixed over the deck, which has no scroll to pin in. The strip exposes role="progressbar" with aria-valuenow and a spoken aria-valuetext (“section 2 of 5, 34% read”); the meter glyphs and the caret are decoration and say so. Under prefers-reduced-motion the caret holds solid instead of blinking — still live, no longer motion. Below 768px the path drops from the command whole, then the prompt folds to kc:~$ — the constant and the answer survive, the piece already committed to goes first. The whole strip stays one line, under 30px, so it can never become a second header.
08

Top strip family

The dark mono bar above the site header on every private screen (_TopStrip), in three states and one sibling. Default is the site operated as yourself; --alarm is the site saying it is not the site; --preview is a real page that is not published; and .kc-writestrip is the author's own chrome, the same grammar with the colour inverted. Four segments in a fixed order — who, badge, sum, right — and the colour is the only thing that changes between states, so three surfaces read as one system rather than three designs. The badge is the role scale at the strip's own size, six tones from Guest to Owner plus the dashed pill a draft state wears.
One strip, three states, and the colour is the only thing that changes. Default is the site operated as yourself in an app that is not the public site; --alarm is the site saying it is not the site; --preview is a real page that is not published. The segments are who → badge → sum → right, in that order and never a fifth, and the fourth is pushed by margin-left: auto.
acct_01SPECIMEN Owner drafts on · maintenance off · cv shown switches people queue audit
acct_01SPECIMEN Owner drafts on · maintenance on · cv shown switches people queue audit
Draft You are previewing an unpublished postoutbox-without-a-scheduler copy preview link back to editor
Jo Tan Author overview new blog ↗
Jo Tan Owner reviewingoutbox-without-a-scheduler · submitted 3 days ago overview review blog ↗
The six badge tones, at the strip's own scale. Guest → Reader → Pass → Author → Owner is the role scale, and Owner is the solid ink pill because ink is the estate's authority colour, not a danger one. The sixth, --pend, is the dashed warning pill a draft state wears: the one tone about a thing rather than a person.
nobody Guest
Dan Kovac Reader
Maya Hart Pass
Jo Tan Author
acct_01SPECIMEN Owner
Changes requested
09

Step-up card

The interruption a write meets when it needs a credential proved in the last five minutes (_StepUp), and the one card both the Account app and the Control Room render. Kicker, title, how long ago, the mechanisms, the countdown and the server's own verdict, in that order. The mechanisms are the part that changes: a door this composition cannot use is a statement of what it would need, a provider that honours prompt=login turns the same row into a button, and the development satisfier sits under a rule where only Development can draw it.
One card for two dockets. The Account app's step-up and the Control Room's interruption are the same drawing — kicker, title, the age sentence, the mechanisms, the countdown, the server's verdict — so they are one view. The mechanisms are the variable part: a door this composition cannot use is a statement of what it would need, and a provider that can honour prompt=login turns the same row into a button.
confirm it is you

Sign in again to remove a credential

Your last re-authentication was 42 minutes ago. This action needs a credential proved in the last five minutes - it changes who can be you.

A passkey assertion needs WebAuthn

A provider round trip prompt=login

or, on this machine only

this is not a credential and proves nothing about anybody — it exists so a gate nothing can pass does not lock a developer out of their own laptop, and it cannot compose outside Development

step-up valid for 5:00 after it completes · evaluated server-side, never from this page

refused: the last re-authentication is 42 minutes old and this action needs one under five

confirm it is you

Sign in again to remove a credential

Your last re-authentication was 42 minutes ago. This action needs a credential proved in the last five minutes - it changes who can be you.

A passkey assertion needs WebAuthn

A provider round trip prompt=login

nothing to press — a passkey assertion needs WebAuthn and a browser, a provider round trip needs a provider, and the magic link needs mail. The gate is enforced; nothing in this composition can pass it.

step-up valid for 5:00 after it completes · evaluated server-side, never from this page

refused: no mechanism in this composition can produce a fresh re-authentication

confirm it is you

Sign in again to remove a credential

Your last re-authentication was 42 minutes ago. This action needs a credential proved in the last five minutes - it changes who can be you.

A passkey assertion needs WebAuthn

step-up valid for 5:00 after it completes · evaluated server-side, never from this page

refused: the last re-authentication is 42 minutes old and this action needs one under five

10

Roles & grants

What somebody is and what the page in front of them may offer (_RolePanel, _GrantRow, _GrantWall): one component in two forms, fed a GrantView of what is true and the host's capabilities, and nothing else. The panel's grounds — the owner's, nobody's, a clock cooling, a sentence gone quiet — and the trio it is made of: .kc-grantpill on the role scale, .kc-grantbtn in three tones, and .kc-grantnote, the statement that stands where a button would be. They live in the public bundle because the grant wall is a public page.
What somebody is, and what this host may offer them. The panel takes two records and nothing else: a GrantView of what is true, and the GrantCapabilities of the page placing it. The ground and the badge are read off the view, never computed by a host, so the pill at the top of a page and the pill in its panel cannot disagree.
Owner config-seeded
Account acct_01SPECIMEN
Grant Reader
State Active

Owner is not data. There is no Owner member on the grant kind, so this panel is rendering a role that exists in configuration and in no table - which is why it has nothing on it, on this page and on the console, from one line of code.

config-seeded
Guest not signed in
Account none
Grant none

Everything published is readable without signing in. Signing in is for the things that follow you - your place in a series, a read-later shelf - and for asking for a pass.

nothing to press - there is no account for a grant to hang off
Reader signed in, holding nothing
Account acct_01SPECDAN0
Grant none

Hiring? A pass unlocks the appendix, the referees and the verification links, with a work address, for ninety days. Authors are invited: if you have talked to Kumar about writing here, the invitation arrives by email and carries the role in it - there is nothing to apply for and nothing to wait for.

the only write this host can make
Author granted by acct_01SPECIMEN - 1 May 2026
Account acct_01SPECJOTN
Grant Author
State Active

An authorship lapses if it goes unused for a hundred and eighty days. Publishing, previewing or saving a draft resets the clock; opening this page does not, because a grant that stays alive by being looked at is not measuring anything.

nothing to press - revoking and extending are the owner's
Pass issued by the site - 18 May 2026
Account acct_01SPECMAYA
Grant Pass
State Expired

The ninety days are a server-side check on every appendix request, not a badge this page is displaying. When it ends, this panel says so and the appendix stops answering - in that order, and without either of them consulting the other.

nothing to press - revoking and extending are the owner's
The pill, the button and the note. Six pill tones on the same scale as the strip's badge; two button tones and a plain one; and the note that stands where a button would be — “nothing to press” is an answer, and the absence of one is not. Each declares its own custom properties, so a table cell with nothing in it can host them.
Guest Reader Pass Author Owner Pass requested
config-seeded
The row is the panel's second form, for a host that lists people: the same ground, the same badge, and the affordances its host hands in. The console hands in grant, extend, revoke and invite; the switcher hands in “become”; and the owner's row is inert under every host.
Kumar config-seeded Owner config-seeded
Jo Tan granted by acct_01SPECIMEN - 1 May 2026 Author lapses in 20 days if unused
Pat Lee requested - 18 Aug 2026 Pass requested
Dan Kovac signed in, holding nothing Reader
Guest not signed in Guest
Maya Hart issued by the site - 18 May 2026 Pass expired 16 Aug 2026 - 3 days ago
The grant wall is what an address answers when the affordance behind it needs a grant the reader does not hold: the reason, how that grant is obtained, and the panel in its Guest shape. It is built and placed nowhere yet.

This one needs a Pass

A pass is granted on request, for ninety days, to a signed-in reader with a work address.

Everything published here is readable without signing in, and nothing behind this wall is anything you have already read.

Guest not signed in
Account none
Grant none

Everything published is readable without signing in. Signing in is for the things that follow you - your place in a series, a read-later shelf - and for asking for a pass.

nothing to press - there is no account for a grant to hang off

This one needs a Pass

A pass is granted on request, for ninety days, to a signed-in reader with a work address.

Guest not signed in
Account none
Grant none

Everything published is readable without signing in. Signing in is for the things that follow you - your place in a series, a read-later shelf - and for asking for a pass.

nothing to press - there is no account for a grant to hang off

Markup

As rendered on the page behind this — captured, not transcribed.