Author SHA1 Message Date
archvillainetteandClaude Opus 5 0705b0100e prototype: frame B click-through for the north star ticket
Throwaway prototype backing issue #49. Two pages sharing one shell
(index.html outdoors, forum.html indoors) plus the rejected ledger-frame
option (a-ledger.html) kept for comparison.

Not for merge. Values here are candidates, not tokens.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 12:09:01 +02:00
5 changed files with 448 additions and 133 deletions
-133
View File
@@ -1,133 +0,0 @@
---
name: ui-design-101
description: Design the actions in an interface — buttons, confirmations, destructive operations, bulk edits, admin and moderation tools. Use when building or reviewing anything a user clicks repeatedly, anything that deletes or hides data, any list of rows with per-row actions, or when the user says a tool is tedious, asks for a confirmation dialog, or reports an interface that "does nothing".
---
# UI Design 101: actions
Visual design is a different skill. This one is about what happens when someone
clicks — and, above all, what happens when they click **the hundredth time**.
Every rule here is a checkable property of an interface. Apply all of them to
whatever you are building; an interface that fails any one of them is not done.
## Price every action at its hundredth use
Design for the hundredth click, not the first. An extra dialog, an extra
scroll, an extra page load is nothing once and unbearable a hundred times. Ask
directly: how many times will one person do this in one sitting? If the answer
is more than a handful, the per-use cost is the whole design problem.
The failure has a shape: a tool that is *pleasant to demo and brutal to use*.
Nobody notices it while building, because builders click things twice.
## Ceremony follows reversibility
Undo beats confirm. A confirmation asks the user to be certain in advance; an
undo lets them be wrong cheaply. Prefer the second.
- **Reversible action** (hide, archive, mark, tag): no confirmation. Ever. Do
it, show it happened, offer the undo in the same spot.
- **Irreversible action** (purge, permanent delete, send, publish): confirm
once, and say plainly that it cannot be undone.
Ceremony on a reversible action is worse than useless: it trains the user to
dismiss dialogs without reading, so the one dialog that matters gets dismissed
too.
## Spend one confirmation per intent
The confirmation budget is per *intent*, not per *item*. A user removing a
hundred things decided once; charge them once. A hundred dialogs for a hundred
items is the same as no dialogs at all, minus an hour of their life.
When one confirmation covers many items, make it carry its weight: name the
scope and the exact count ("Purge 143 pages in Skills — this cannot be
undone"), and for the genuinely dangerous ones, require typing something
deliberate rather than a single click.
## Let the reversible state be the selection
Where a flow is *choose many, then commit*, the reversible action is the
selection mechanism. Mark → review → commit. No parallel checkbox concept
required.
Marking beats checkboxes on properties, not just tokens: the marks survive a
reload, they are visible to a colleague looking at the same screen, they can be
undone one at a time, and the user sees the staged set accumulate as they go.
## Act in place
An action reports its result where the user is standing. Re-render the row, the
card, the item. Keep scroll position, keep focus, keep their place in a long
list.
A full page reload after each action is a scroll-position bug wearing a
navigation costume. If the user must find their place again after every click,
the hundredth click costs a hundred scrolls.
## Make silence impossible
Every action ends in an observable outcome: success shown, or failure shown
with a reason. An action that can quietly do nothing is the worst bug class in
interface design, because the user keeps working and only later discovers that
none of it happened.
Own your dialogs for the same reason. Browsers let a user permanently suppress
native `alert`/`confirm`/`prompt` dialogs ("prevent this page from creating
additional dialogs"). Code that reads a suppressed `confirm` sees "cancelled"
and correctly does nothing — forever, silently, until a reload. Use the
platform's or framework's own modal component so the confirmation is yours to
control.
## Give bulk work a bulk path
Wherever the data can hold hundreds of items, the interface offers an action
over the whole set — a filtered set, a marked set, or a namespace. A per-item
action is not a bulk feature no matter how fast the loop.
Bulk operations are partial by nature. Design for it up front:
- Process items independently; one failure does not abandon the rest.
- Report per item: succeeded, failed with a reason, skipped with a reason.
- Show progress while it runs, and let the user cancel between items.
- Leave every item either fully done or fully untouched — never half-applied.
- Chunk the work so a large set cannot time out the request.
## Finish the user's job
Match the actions to the *goal*, not to the data model. If the user's goal is
"make this gone" and the tool only offers "make this quiet", the tool is
incomplete even though every button works. Hidden is not deleted; unpublished
is not removed; archived is not gone.
Where a two-step model exists for safety (hide, then remove), both steps belong
on the screen where the work happens. A second step reachable only from a
different page, one item at a time, is a step that will not be taken.
## Show the outstanding work
Surface the counts that tell the user how much is left: how many items are
marked, how many remain, how many failed. A cleanup task needs a visible
ending, otherwise it is just scrolling.
## Explain a missing action
When a control is absent because of a permission, a state, or a rule, say so in
its place. An unexplained gap reads as a bug and sends the user hunting. State
the reason and, where there is one, the path to earning the action.
## Design check
Before calling an interface done, walk it as a user with a hundred items:
1. Count the interactions for one item. Multiply by a hundred. Is that a
working afternoon?
2. Which actions prompt? Is every one of them irreversible?
3. Which actions are irreversible? Does each state that plainly, once, with the
count?
4. After each action, did the user keep their place?
5. Can any action fail silently? What does the user see when it does?
6. Is there a path that handles the whole set in one decision?
7. Does the tool reach the user's actual goal, or stop at the model's halfway
state?
+144
View File
@@ -0,0 +1,144 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>A — Ledger is the frame</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Cinzel:wght@600&family=Jost:wght@300;400;500&display=swap" rel="stylesheet">
<style>
:root{
--gold:#c2a35a; --gilt:#a8893f; --gold-lit:#e0c878;
--plum-noir:#351e28; --blood:#8e3438; --wax:#a84a4e;
--crypt:#0f0d12; --grave:#09080b;
--panel:#18141d; --panel-deep:#110f15; --panel-raised:#201924;
--bone:#e6e0d6; --ash:#b9b2a6; --dust:#9a9086;
--ink:#d8c28a; --ink-muted:#a99d8f;
--rule:1.78rem;
}
*{box-sizing:border-box}
body{
margin:0; background:var(--grave); color:var(--ash);
font:400 1rem/1.6 Jost, system-ui, sans-serif;
padding:2.5rem 1rem 4rem;
}
h1,h2,h3{font-family:Cinzel,Georgia,serif;font-weight:600;color:var(--bone);margin:0;
text-shadow:0 1px 0 rgba(0,0,0,.9), 0 0 10px rgba(104,32,76,.16)}
.label{font-family:Cinzel,Georgia,serif;font-weight:600;font-size:.78rem;
letter-spacing:.16em;text-transform:uppercase;color:var(--gold)}
/* the book: one bound object, hard edges, margins */
.book{
max-width:1180px;margin:0 auto;background:var(--crypt);
border:1px solid rgba(194,163,90,.22);
box-shadow:0 30px 80px rgba(0,0,0,.65), inset 0 1px 0 rgba(255,255,255,.03);
position:relative;
}
/* corner pieces — bookbinding */
.book::before,.book::after{content:"";position:absolute;width:34px;height:34px;pointer-events:none}
.book::before{top:8px;left:8px;border-top:1px solid var(--gilt);border-left:1px solid var(--gilt)}
.book::after{bottom:8px;right:8px;border-bottom:1px solid var(--gilt);border-right:1px solid var(--gilt)}
/* topbar reads as a running head, not a nav bar */
.runninghead{
display:flex;justify-content:space-between;align-items:baseline;
padding:1.1rem 3.2rem .9rem;border-bottom:1px solid rgba(194,163,90,.18);
background:linear-gradient(180deg,#1a1017,var(--crypt));
}
.runninghead nav{display:flex;gap:1.8rem}
.runninghead a{color:var(--ink-muted);text-decoration:none;font-family:Cinzel,serif;
font-size:.8rem;letter-spacing:.14em;text-transform:uppercase}
.runninghead a:hover{color:var(--gold-lit)}
.folio{color:var(--dust);font-size:.74rem;letter-spacing:.1em}
/* frontispiece — a title page, not a hero */
.frontispiece{padding:4.5rem 3.2rem 3rem;text-align:center;
background:radial-gradient(120% 90% at 50% 0%, rgba(53,30,40,.55), transparent 70%)}
.frontispiece h1{font-size:2.9rem;letter-spacing:.04em}
.frontispiece .sub{color:var(--dust);font-size:.82rem;letter-spacing:.22em;
text-transform:uppercase;font-family:Cinzel,serif;margin-top:.9rem}
.fade-rule{height:1px;margin:1.8rem auto;max-width:420px;
background:linear-gradient(90deg,transparent,var(--gilt),transparent)}
.seal{display:inline-block;margin-top:.4rem;width:44px;height:44px;border-radius:50%;
background:radial-gradient(circle at 35% 30%, var(--wax), #5e2124);
box-shadow:inset 0 -2px 6px rgba(0,0,0,.6), 0 2px 10px rgba(0,0,0,.5)}
.epigraph{max-width:560px;margin:1.6rem auto 0;color:var(--ink-muted);
font-style:italic;font-size:.95rem}
/* the index: entries in ruled columns */
.leaf{padding:1rem 3.2rem 3rem}
.leaf-head{display:flex;justify-content:space-between;align-items:baseline;
padding-bottom:.5rem;border-bottom:1px solid rgba(194,163,90,.14);margin-bottom:.2rem}
.entry{
display:grid;grid-template-columns:1fr 8rem 5rem;gap:1rem;align-items:baseline;
min-height:var(--rule);padding:.42rem 0;
border-bottom:1px solid rgba(194,163,90,.07);
}
.entry:hover{background:linear-gradient(90deg,rgba(53,30,40,.5),transparent)}
.entry .t{color:var(--ink);font-family:Cinzel,serif;font-size:.98rem}
.entry .m{color:var(--dust);font-size:.8rem;text-align:right}
.entry .n{color:var(--gold);font-size:.8rem;text-align:right;font-variant-numeric:tabular-nums}
.two{display:grid;grid-template-columns:1fr 300px;gap:3rem;padding:0 3.2rem 3rem}
.marginalia{border-left:1px solid rgba(194,163,90,.14);padding-left:1.4rem}
.marginalia p{font-size:.88rem;color:var(--dust)}
.plaque{display:inline-block;padding:.28rem .7rem;border:1px solid rgba(194,163,90,.3);
background:var(--panel-deep);color:var(--ink);font-family:Cinzel,serif;
font-size:.7rem;letter-spacing:.14em;text-transform:uppercase}
.colophon{padding:1.4rem 3.2rem;border-top:1px solid rgba(194,163,90,.18);
display:flex;justify-content:space-between;color:var(--dust);font-size:.74rem;
letter-spacing:.08em;background:var(--panel-deep)}
.tag{color:#7a7168;font-size:.72rem;letter-spacing:.2em;text-transform:uppercase;
text-align:center;margin:0 auto 1.2rem;max-width:1180px}
</style>
</head>
<body>
<div class="tag">Option A — the ledger is the frame · zero images</div>
<div class="book">
<div class="runninghead">
<span class="label">Shadows Over Westgate</span>
<nav><a href="#">The Court</a><a href="#">Entries</a><a href="#">Archive</a><a href="#">Petitions</a><a href="#">Enter</a></nav>
<span class="folio">fol. i</span>
</div>
<div class="frontispiece">
<div class="label">Being an account of the city and its debts</div>
<div class="fade-rule"></div>
<h1>Shadows Over Westgate</h1>
<div class="sub">A record kept against the dark</div>
<div class="fade-rule"></div>
<div class="seal"></div>
<p class="epigraph">Everyone in this city is compromised. The only question the ledger asks is by how much, and to whom.</p>
<div style="margin-top:1.6rem"><span class="plaque">Open the record</span></div>
</div>
<div class="leaf">
<div class="leaf-head"><h2 style="font-size:1.05rem;letter-spacing:.06em">Latest entries</h2><span class="folio">fol. ii — vii</span></div>
<div class="entry"><span class="t">The Ashgate Concession</span><span class="m">Ledgerkeeper</span><span class="n">41</span></div>
<div class="entry"><span class="t">On the matter of the second seal</span><span class="m">V. Marrow</span><span class="n">17</span></div>
<div class="entry"><span class="t">Debts owed to the Clockmakers' Guild</span><span class="m">Anonymous</span><span class="n">8</span></div>
<div class="entry"><span class="t">Petition: the widow at Candlewharf</span><span class="m">House Verrine</span><span class="n">63</span></div>
<div class="entry"><span class="t">Errata to the census of 1114</span><span class="m">Ledgerkeeper</span><span class="n">2</span></div>
</div>
<div class="two">
<div>
<h3 style="font-size:1rem;letter-spacing:.06em">From the archive</h3>
<div class="fade-rule" style="margin:.9rem 0 1.2rem;max-width:none"></div>
<p>The city keeps two books. One is public, ruled and countersigned, and it is a lie of omission. The other is this one.</p>
<p>Entries are made nightly. Corrections are made rarely, and never by the same hand twice.</p>
</div>
<aside class="marginalia">
<div class="label" style="font-size:.7rem">Standing</div>
<p style="margin-top:.8rem">The record is open. Fourteen hands are writing tonight.</p>
<div class="fade-rule" style="margin:1.2rem 0;max-width:none"></div>
<div class="label" style="font-size:.7rem">Seals in force</div>
<p style="margin-top:.8rem">Verrine · Marrow · the Guild</p>
</aside>
</div>
<div class="colophon"><span>Kept at Westgate</span><span>fol. vii of ccxi</span></div>
</div>
</body>
</html>
+91
View File
@@ -0,0 +1,91 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Westgate — the archive</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Cinzel:wght@600&family=Jost:wght@300;400;500&display=swap" rel="stylesheet">
<link rel="stylesheet" href="shell.css">
<style>
/* indoors: same shell, ornament turned down, ledger takes over */
/* One Rail: shell and content share the same left/right edge on every page.
Nothing is inset inside anything. Density is spacing and ornament only. */
:root{--fit:.35}
.crumb{display:flex;gap:.6rem;align-items:baseline;padding:1.2rem var(--rail) .4rem;
font-size:.8rem;color:var(--dust)}
.crumb a{text-decoration:none;color:var(--ink-muted)}
.crumb span{color:var(--pewter-deep)}
.room{display:grid;grid-template-columns:1fr 300px;gap:2rem;padding:.6rem var(--rail) 3rem;
background:var(--crypt)}
.bar{display:flex;justify-content:space-between;align-items:center;
padding:.5rem .2rem 1rem}
.bar h1{font-size:1.35rem;letter-spacing:.05em}
aside .box{padding-left:1.2rem;margin-bottom:1.6rem;position:relative}
aside .box::before{content:"";position:absolute;left:0;top:.2rem;bottom:.2rem;width:1px;
background:linear-gradient(180deg,rgba(140,143,151,.3),transparent)}
/* the page title sits on a fading rule, not a hard bar */
.bar{border-bottom:0}
aside p{font-size:.88rem;color:var(--dust);margin:.6rem 0 0}
.pager{display:flex;gap:.4rem;justify-content:flex-end;margin-top:1rem;
font-size:.8rem;color:var(--dust)}
.pager b{color:var(--gold);font-weight:400}
</style>
</head>
<body>
<div class="tag">Indoors — app density (--fit: .35)</div>
<div class="page">
<header class="lintel">
<a class="mark" href="index.html">Shadows Over Westgate</a>
<nav>
<a href="index.html">The City</a>
<a href="forum.html" aria-current="page">Forum</a>
<a href="forum.html">Archive</a>
<a href="forum.html">Enter</a>
</nav>
<div class="rivets"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div>
</header>
<div class="status"><span class="lamp"></span> The gates are open. Fourteen souls walk the city tonight.</div>
<div class="crumb"><a href="index.html">The City</a><span>·</span><a href="forum.html">The Archive</a><span>·</span><span>Entries of the Court</span></div>
<div class="room">
<main>
<div class="bar">
<h1>Entries of the Court</h1>
<a class="btn" href="#">New entry</a>
</div>
<div class="ledger framed">
<div class="row head"><span>Entry</span><span>Hand</span><span>Replies</span><span>Last</span></div>
<div class="row"><a class="t" href="#">The Ashgate Concession</a><span class="m">Ledgerkeeper</span><span class="n">41</span><span class="d">2h</span></div>
<div class="row"><a class="t" href="#">On the matter of the second seal</a><span class="m">V. Marrow</span><span class="n">17</span><span class="d">5h</span></div>
<div class="row"><a class="t" href="#">Debts owed to the Clockmakers' Guild</a><span class="m">Anonymous</span><span class="n">8</span><span class="d">9h</span></div>
<div class="row"><a class="t" href="#">Petition: the widow at Candlewharf</a><span class="m">House Verrine</span><span class="n">63</span><span class="d">1d</span></div>
<div class="row"><a class="t" href="#">Errata to the census of 1114</a><span class="m">Ledgerkeeper</span><span class="n">2</span><span class="d">1d</span></div>
<div class="row"><a class="t" href="#">Concerning the Foundry night shift</a><span class="m">Grell</span><span class="n">29</span><span class="d">2d</span></div>
<div class="row"><a class="t" href="#">A list of names, unsigned</a><span class="m">Anonymous</span><span class="n">104</span><span class="d">2d</span></div>
<div class="row"><a class="t" href="#">On lamp oil and its accounting</a><span class="m">Sable</span><span class="n">6</span><span class="d">3d</span></div>
<div class="row"><a class="t" href="#">The harbour tithe, revised</a><span class="m">House Verrine</span><span class="n">12</span><span class="d">4d</span></div>
<div class="row" style="border:0"><a class="t" href="#">Who kept the third key</a><span class="m">V. Marrow</span><span class="n">38</span><span class="d">6d</span></div>
</div>
<div class="pager"><b>1</b> · 2 · 3 · 4 · 211</div>
</main>
<aside>
<div class="box"><div class="label dull" style="font-size:.7rem">Tonight</div>
<p>Rain off the harbour. Two wards dark. The Foundry is still running.</p></div>
<div class="box"><div class="label dull" style="font-size:.7rem">Seals in force</div>
<p>Verrine · Marrow · the Guild</p></div>
<div class="box"><div class="label dull" style="font-size:.7rem">Newly arrived</div>
<p>Three petitioners at the Verrine gate.</p></div>
</aside>
</div>
<footer class="foundation"><span>Westgate</span><span>Est. 1114 · the record is kept</span></footer>
</div>
</body>
</html>
+105
View File
@@ -0,0 +1,105 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Westgate — outdoors</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Cinzel:wght@600&family=Jost:wght@300;400;500&display=swap" rel="stylesheet">
<link rel="stylesheet" href="shell.css">
<style>
/* showcase-only furniture: lives on the home page, nowhere else */
.horizon{position:relative;min-height:440px;display:flex;flex-direction:column;
justify-content:flex-end;padding:5rem var(--rail) 3rem;overflow:hidden;
background:
radial-gradient(70% 55% at 50% 100%, rgba(200,176,138,.16), transparent 70%),
radial-gradient(90% 70% at 50% 100%, rgba(53,30,40,.85), transparent 72%),
linear-gradient(180deg,#07060a 0%, #0d0b11 55%, #16121a 100%)}
.skyline{position:absolute;left:0;right:0;bottom:0;height:190px;display:flex;
align-items:flex-end;gap:6px;padding:0 1rem;opacity:.92}
.skyline b{display:block;background:#06050880;
border-top:1px solid rgba(140,143,151,.10);box-shadow:0 -1px 0 rgba(0,0,0,.9)}
/* One Rail: the hero sits on the same 3-column grid as the plaques below,
so its right edge lands on a shared grid line — a column, not an inset. */
.horizon .inner{position:relative;display:grid;
grid-template-columns:repeat(3,1fr);column-gap:1px}
.horizon .inner > *{grid-column:1 / span 2}
.horizon h1{font-size:3.2rem;letter-spacing:.03em;line-height:1.08}
.horizon p{color:var(--ink-muted);margin-top:1rem}
.cta{display:flex;gap:.9rem;margin-top:1.8rem}
/* plaques divided by rules that fade top and bottom, not a hard grid */
.band{display:grid;grid-template-columns:repeat(3,1fr)}
.plaque{background:linear-gradient(180deg,#191419,#120f14);
padding:1.6rem var(--rail);position:relative}
.plaque + .plaque::before{content:"";position:absolute;left:0;top:12%;bottom:12%;width:1px;
background:linear-gradient(180deg,transparent,rgba(194,163,90,.28),transparent)}
.plaque h3{font-size:1.05rem;letter-spacing:.05em;margin:.7rem 0 .5rem}
.plaque p{font-size:.9rem;color:var(--dust);margin:0}
.dispatches{padding:2.5rem var(--rail);background:var(--crypt);
border-top:0}
.dispatches .lead{display:flex;justify-content:space-between;align-items:baseline;
margin-bottom:.9rem}
.dispatches a.more{font-family:Cinzel,serif;font-size:.74rem;letter-spacing:.14em;
text-transform:uppercase;text-decoration:none}
</style>
</head>
<body>
<div class="tag">Outdoors — showcase density (--fit: 1)</div>
<div class="page">
<header class="lintel">
<a class="mark" href="index.html">Shadows Over Westgate</a>
<nav>
<a href="index.html" aria-current="page">The City</a>
<a href="forum.html">Forum</a>
<a href="forum.html">Archive</a>
<a href="forum.html">Enter</a>
</nav>
<div class="rivets"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div>
</header>
<div class="status"><span class="lamp"></span> The gates are open. Fourteen souls walk the city tonight.</div>
<section class="horizon">
<div class="skyline">
<b style="width:5%;height:52%"></b><b style="width:3%;height:74%"></b><b style="width:7%;height:38%"></b>
<b style="width:4%;height:88%"></b><b style="width:6%;height:46%"></b><b style="width:3%;height:96%"></b>
<b style="width:8%;height:34%"></b><b style="width:5%;height:66%"></b><b style="width:4%;height:44%"></b>
<b style="width:9%;height:28%"></b><b style="width:3%;height:80%"></b><b style="width:6%;height:40%"></b>
<b style="width:4%;height:58%"></b><b style="width:7%;height:32%"></b><b style="width:5%;height:70%"></b>
<b style="width:3%;height:50%"></b><b style="width:8%;height:36%"></b><b style="width:4%;height:62%"></b>
</div>
<div class="inner">
<div class="label">A gothic-fantasy roleplay city</div>
<h1>The lamps are lit.<br>No one is innocent.</h1>
<p>Renaissance stone, clockwork and lightning, and a court that has ruled from behind the shutters for four hundred years. You are already compromised. Decide what it bought you.</p>
<div class="cta">
<a class="btn" href="forum.html">Enter the city</a>
<a class="btn dull" href="forum.html">Read the archive</a>
</div>
</div>
</section>
<section class="band">
<div class="plaque"><div class="label dull">Decadence</div><h3>The Court</h3><p>Houses, favours, and debts that outlive the people who signed them.</p></div>
<div class="plaque"><div class="label dull">Decay</div><h3>The Wards</h3><p>Candlewharf, Ashgate, the Foundry. Gaslight where the money is, dark where it is not.</p></div>
<div class="plaque"><div class="label dull">Machinery</div><h3>The Guild</h3><p>Clockwork, steam, and the new lightning — sold to anyone who can pay the interest.</p></div>
</section>
<section class="dispatches">
<div class="lead">
<div class="label">Latest dispatches</div>
<a class="more" href="forum.html">All entries →</a>
</div>
<div class="fade-rule" style="margin-bottom:1rem"></div>
<div class="ledger framed">
<div class="row"><a class="t" href="forum.html">The Ashgate Concession</a><span class="m">Ledgerkeeper</span><span class="n">41</span><span class="d">2h</span></div>
<div class="row"><a class="t" href="forum.html">On the matter of the second seal</a><span class="m">V. Marrow</span><span class="n">17</span><span class="d">5h</span></div>
<div class="row" style="border:0"><a class="t" href="forum.html">Petition: the widow at Candlewharf</a><span class="m">House Verrine</span><span class="n">63</span><span class="d">1d</span></div>
</div>
</section>
<footer class="foundation"><span>Westgate</span><span>Est. 1114 · the record is kept</span></footer>
</div>
</body>
</html>
+108
View File
@@ -0,0 +1,108 @@
/* Throwaway prototype — Frame B shell, two metals, one shell / two densities.
Not for merge. Values here are candidates, not tokens. */
:root{
--gold:#c2a35a; --gilt:#a8893f; --gold-lit:#e0c878;
--plum-noir:#351e28; --blood:#8e3438; --wax:#a84a4e;
--crypt:#0f0d12; --grave:#09080b;
--panel:#18141d; --panel-deep:#110f15; --panel-raised:#201924;
--bone:#e6e0d6; --ash:#b9b2a6; --dust:#9a9086;
--ink:#d8c28a; --ink-muted:#a99d8f;
/* second metal — structural only */
--pewter:#8c8f97; --pewter-deep:#5a5d64;
--filament:#c8b08a;
/* the Threshold: one knob per density */
--fit:1; /* ornament weight: 1 outdoors, 0.35 indoors */
--page:1420px;
--rail:2rem; /* One Rail: the only horizontal edge on any page */
}
*{box-sizing:border-box}
body{margin:0;background:var(--grave);color:var(--ash);
font:400 1rem/1.6 Jost,system-ui,sans-serif}
a{color:var(--gold)}
h1,h2,h3{font-family:Cinzel,Georgia,serif;font-weight:600;color:var(--bone);margin:0;
text-shadow:0 1px 0 rgba(0,0,0,.9), 0 0 10px rgba(104,32,76,.16)}
.label{font-family:Cinzel,Georgia,serif;font-weight:600;font-size:.78rem;
letter-spacing:.16em;text-transform:uppercase;color:var(--gold)}
.label.dull{color:var(--pewter)}
.page{max-width:var(--page);margin:0 auto}
.fade-rule{height:1px;background:linear-gradient(90deg,transparent,var(--gilt),transparent)}
/* ---- lintel: identical on every page ---- */
.lintel{
display:flex;align-items:center;gap:2rem;padding:.85rem var(--rail);position:relative;
background:linear-gradient(180deg,#1b1a1f,#111015);
border-top:1px solid rgba(140,143,151,calc(.28 * var(--fit) + .06));
box-shadow:0 14px 30px rgba(0,0,0,.5);
}
/* the lintel's underside is a gilt rule that fades out, not a hard line */
.lintel::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
background:linear-gradient(90deg,transparent,rgba(194,163,90,.32) 12%,
rgba(194,163,90,.32) 88%,transparent)}
.rivets{position:absolute;inset:auto 0 6px 0;display:flex;justify-content:space-between;
padding:0 1rem;opacity:var(--fit)}
.rivets i{width:4px;height:4px;border-radius:50%;background:var(--pewter-deep);
box-shadow:inset 0 1px 0 rgba(255,255,255,.25)}
.mark{font-family:Cinzel,serif;color:var(--gold);letter-spacing:.18em;
text-transform:uppercase;font-size:.86rem;text-decoration:none}
.lintel nav{display:flex;gap:1.6rem;margin-left:auto}
.lintel nav a{color:var(--ink-muted);text-decoration:none;font-family:Cinzel,serif;
font-size:.78rem;letter-spacing:.14em;text-transform:uppercase}
.lintel nav a:hover{color:var(--gold-lit)}
.lintel nav a[aria-current]{color:var(--gold);border-bottom:1px solid var(--gilt)}
/* ---- status: a sentence, on every page ---- */
.status{display:flex;align-items:center;gap:.8rem;padding:.9rem var(--rail);
background:var(--panel-deep);font-size:.88rem;color:var(--ink-muted);
position:relative}
.status::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
background:linear-gradient(90deg,transparent,rgba(140,143,151,.24) 12%,
rgba(140,143,151,.24) 88%,transparent)}
.lamp{width:8px;height:8px;border-radius:50%;background:var(--filament);
box-shadow:0 0 10px 2px rgba(200,176,138,.5)}
/* ---- foundation: identical on every page ---- */
.foundation{padding:1.6rem var(--rail);background:#0a090c;position:relative;
display:flex;justify-content:space-between;color:var(--dust);
font-size:.74rem;letter-spacing:.1em}
.foundation::before{content:"";position:absolute;left:0;right:0;top:0;height:1px;
background:linear-gradient(90deg,transparent,rgba(194,163,90,.26) 12%,
rgba(194,163,90,.26) 88%,transparent)}
/* ---- buttons ---- */
.btn{display:inline-block;padding:.6rem 1.3rem;font-family:Cinzel,serif;font-size:.76rem;
letter-spacing:.16em;text-transform:uppercase;border:1px solid var(--gilt);
color:var(--ink);background:linear-gradient(180deg,#2a2214,#1a1510);text-decoration:none}
.btn.dull{border-color:rgba(140,143,151,.4);color:var(--pewter);
background:linear-gradient(180deg,#232529,#16171b)}
/* ---- gilded frame: a notched plate with corner marks, not a box ----
Edges fade rather than stop; corners are cut, then re-marked in gilt. */
/* No corner marks: an ornament inset from an edge agrees with nothing and
reads as misalignment. The plate is carried by material and fading rules. */
.framed{position:relative}
/* a rule that fades at both ends — the default separator */
.hair{height:1px;border:0;margin:0;
background:linear-gradient(90deg,transparent,rgba(194,163,90,.34) 18%,
rgba(194,163,90,.34) 82%,transparent)}
.hair.dull{background:linear-gradient(90deg,transparent,rgba(140,143,151,.3) 18%,
rgba(140,143,151,.3) 82%,transparent)}
/* ---- ledger interior: the archive material ---- */
.ledger{background:var(--panel);
box-shadow:inset 0 0 0 1px rgba(194,163,90,.10),
inset 0 1px 0 rgba(255,255,255,.022),
0 8px 22px rgba(0,0,0,.28)}
.ledger .row{display:grid;grid-template-columns:1fr 8rem 4rem 5rem;gap:1rem;
align-items:baseline;min-height:1.78rem;padding:.5rem 1.2rem;
border-bottom:1px solid rgba(194,163,90,.07)}
.ledger .row:hover{background:linear-gradient(90deg,rgba(53,30,40,.55),transparent)}
.ledger .t{color:var(--ink);font-family:Cinzel,serif;font-size:.95rem;text-decoration:none}
.ledger .m,.ledger .n,.ledger .d{font-size:.8rem;text-align:right;color:var(--dust)}
.ledger .n{color:var(--gold);font-variant-numeric:tabular-nums}
/* header row uses pewter — it structures, it is not touchable */
.ledger .head{background:var(--panel-deep);border-bottom:1px solid rgba(140,143,151,.2)}
.ledger .head span{font-family:Cinzel,serif;font-size:.7rem;letter-spacing:.14em;
text-transform:uppercase;color:var(--pewter)}
.tag{color:#7a7168;font-size:.72rem;letter-spacing:.2em;text-transform:uppercase;
text-align:center;padding:1rem 0 .4rem}