feat: eyebrow 14px and one small-text floor; fix a site-wide reflow defect; stamp TTL; §4 bars the struck universal

Pouya's five rulings of 2026-08-31, after 64bce10. One commit, because AGENTS.md
entry (aj) covers all five and the review fixes interleave across them —
recorded here rather than left to be inferred.

1. THE EYEBROW, 13 -> 14px, at the one token definition. `--text-eyebrow` is
deliberately NOT an alias of `--text-sm` despite sharing its value: the two move
for different reasons, and aliasing would mean a change to body-meta type
silently moving every eyebrow. Sweep by rendering, 22 pages x 2 widths, 801 mono
instances: 441 carry `.eyebrow`, 420 now at 14px, 21 held at 11px. Zero of 801
below 4.5:1.

Header check, which Pouya asked for explicitly: nothing header-side consumes the
token, `--header-h` is 81px, and the sticky header measures exactly 81.00px at
every width from 66rem up with the CTA on `.header-inner`'s content edge. Nothing
overflowed, so nothing was improvised.

2. /contact/'s LABELS RAISED, AND THE FLOOR CLAIM REWRITTEN BECAUSE THE RULING'S
PREMISE WAS FALSE. The ruling asked docs/02 to record the tagline as "the ONLY
sub-14px text on the site". It is not: the `--text-xs` 12px rung has ten
declaration sites and 130 elements rendering at 12px. So docs/02 records the
claim that IS verified — `--text-2xs` has one consumer in the repository — and
enumerates the 12px rung as a separate treatment. Writing a false claim into the
spec because the conclusion was handed down is the move the rules forbid.

A third block moved that the ruling did not name: /bio/'s ten <h2>s and its strap
were copies of five of `.eyebrow`'s six declarations at 11px — the same escape the
footer headings were. docs/02 justified holding them by the one-page PDF
constraint; measured, `@media print` sets both to 7pt, so the screen size never
reached the PDF and that was never the reason.

Consolidating them DID change the printed sheet, because the missing sixth
declaration was `font-weight`: 500 grew the PDF 89,496 -> 91,151 bytes. Print
therefore freezes 400, the committed PDF stays byte-identical (10 differing
bytes, all /CreationDate and /ModDate), and unifying is Pouya's call.

3. THE REFLOW DEFECT WAS SITE-WIDE AND /bio/ WAS NOT THE BINDING CAUSE.
`white-space: nowrap` on `SiteHeader .brand-name` held all 22 pages 63px over at
320px/root 32. Eight cause-specific fixes, no `overflow-x` anywhere; all eight
produce byte-identical geometry at root 16. `Pill` is marked in docs/02 as the
backstop it is — the real cause was `PracticeCard`'s rem-based padding, and with
it clamped "Construction" goes from 94x220 in six two-character lines to 158x85 in
two.

Three instrument findings now in docs/02, each of which hid a real defect:
`break-word` does not reduce min-content and `anywhere` does;
`getBoundingClientRect()` reports border boxes, so an element sweep cannot see
text spilling outside its own box; and `mobile: true` emulation expands the
layout viewport, so `scrollWidth - innerWidth` reads 0 while the reader still
scrolls sideways.

4. TTL STAMPED `ENABLED` in §7, with `DISABLED` at first verification recorded
rather than overwritten. Q60 narrowed to its second half and OPEN: no record has
been watched to vanish, and `ENABLED` proves the setting, not the behaviour.
R19's sweep found three stale copies outside §7; all now defer to it. R19 itself
was not edited — it points at §7 rather than carrying state, which is the
property that made it work.

5. §4 GAINS THE STRUCK-UNIVERSAL ROW, citing the committed ontario.ca extract and
cross-referenced to `check:claims`'s `struck-universal-q39`. It bars the claim in
BOTH directions: the commercial half is Pouya's attributed position, not a
verified fact. The row immediately caught two places asserting it flatly —
`SiteHeader.astro` and §9 Q33 — both now attributed. `check:claims` unmodified;
still frozen.

REVIEW: adversarial-reviewer, two rounds, 16 findings, ALL ACCEPTED, NONE
DECLINED. claims-auditor did not run (D20). Eight of round 2's ten were defects
in round 1's own fixes.

Round 1's blocking finding was a defect in my own record: I wrote that every
reflow residual was zero at "root 16 and root 32, 286 measurements". Two ways of
simulating 200% text are NOT equivalent, because media-query `rem` resolves
against the DEFAULT font size, not the root element's. Under the method docs/02
itself prescribes the site is 944px over on 21 pages and 508px on / at 1280, and
304px at 1920 — nav clipped mid-word, Practice/Fees/Contact and the CTA
off-screen, WCAG 1.4.4 with loss of functionality. My 286 excluded exactly the
widths where the defect lives.

NOT FIXED, DELIBERATELY: the cause is `flex-wrap: nowrap` on `.nav-list` above
66rem, a locked step-1 decision, and the standing instruction is to stop and
report rather than improvise a header change. It is now a blocking item on
docs/06's cutover checklist, ticked only by ruling on it — "not by re-measuring
it with the method that reports zero".

Round 2 also caught: a 63,743-byte figure that was the `cmp -l` differing-byte
count rather than the 1,655-byte size delta; a lost-navigation list naming
Med-Arb, which is not in the masthead at any width, while omitting Contact; the
tagline's justification left recorded at 13px, where one clause of it is false at
14px (20px of document overflow at 1216 with a seventh nav item); my own label
raise reintroducing a 38px element overflow at the width just ruled on; two
copies of the eyebrow treatment left at weight 400; three stale residual tables;
and the min-content explanation duplicated six times in src/.

VERIFIED, exit statuses read directly, never through a pipe: build 0 (22 pages),
check 0 (0 errors/0 warnings/0 hints), check:claims 0, og:proof 0, check:intake 0,
lint 0, minifier tripwire clean, TODO in dist 0 with a source sanity check.
Overflow: 374 measurements over 22 pages, every one zero, row counts asserted
before reading, with positive controls (119px at width 200, 319px at root 64).
Lighthouse 0, run three times with identical category scores: perf 99 on / and
100 elsewhere, a11y 100, best practices 100, SEO 100 on all indexable pages,
CLS 0.000. / sits at LCP 2.03s against a 2.0s budget, unchanged by this work.

The zsh `$VAR` word-split trap fired twice more and both times read as a clean
pass; caught only by asserting row counts first. Two of my own instruments were
wrong before they were right: a `grep -F '0.875rem'` state check that could never
match because Lightning CSS writes `.875rem`, and a probe whose inline
`!important` was outranked by a running CSS transition.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Md3GndFqWPzK78xAoebsg5
This commit is contained in:
Pouya Lajevardi
2026-08-31 15:44:13 -04:00
co-authored by Claude Opus 5
parent 64bce105f8
commit 0f7595b602
15 changed files with 534 additions and 120 deletions
+9 -4
View File
@@ -57,10 +57,12 @@ const { slots } = Astro.props;
measured-sounding comment that was false is this project's own named
failure mode.
`minmax(0, 1fr)` cannot overflow at any width or any root font size,
which also retires the `min(11rem, 100%)` guard this line briefly
`minmax(0, 1fr)` means the TRACK cannot overflow at any width or any root
font size, which retires the `min(11rem, 100%)` guard this line briefly
carried — that guard was fixing the overflow symptom of a floor that
should not have been there. */
should not have been there. ⚠️ **THE TRACK IS NOT THE CONTENT:** a label's
own words can overflow the track, and at a 200% default font size they
did. That is why `.credential-label` below carries `overflow-wrap`. */
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: var(--space-6) var(--space-5);
margin: 0;
@@ -102,7 +104,10 @@ const { slots } = Astro.props;
deliberately long (AGENTS.md Q37) — it wraps to two lines at every width
and must not be prevented from doing so. Do not add `white-space: nowrap`
here, and do not shorten the label to make the row tidier: the asymmetry
is the honest part. */
is the honest part. ⚠️ `overflow-wrap: anywhere` is LOAD-BEARING here, not
cosmetic — `anywhere`, not `break-word`: see `docs/02` §Reflow, instrument
finding 1. */
text-wrap: pretty;
overflow-wrap: anywhere;
}
</style>
+6 -1
View File
@@ -85,7 +85,12 @@ void _props;
200% default font size (root 32px) overflowed the document by 111px at
320px — WCAG 1.4.10 Reflow. Measured 2026-08-28; no pill on the site is
that long today, which is exactly why this is easy to delete and must not
be. `normal` costs nothing at default size. */
be. `normal` costs nothing at default size.
⚠️ `normal` ALONE IS NOT ENOUGH — a one-word pill cannot wrap at a space
that is not there. `anywhere`, not `break-word`, and this is the BACKSTOP
rather than the cause: `docs/02` §Reflow, instrument finding 1 and the
`Pill` row. */
white-space: normal;
overflow-wrap: anywhere;
}
</style>
+7 -1
View File
@@ -48,7 +48,13 @@ const H = `h${level}` as 'h2' | 'h3';
flex-direction: column;
align-items: flex-start;
gap: var(--space-4);
padding: var(--space-6);
/* CLAMPED, not a flat --space-6, for the reason `.feature` on `/` carries:
the space scale is rem-based, so `2rem` is 64 px a side at a 200% default
font size — 128 px of padding inside a ~224 px content box, which left
~96 px for the whole card column and was the real cause of a `Pill`
overflowing. The 10vw term holds it at 32 px on every viewport from 320 px
up and lets it collapse only when the rem is doubled. */
padding: clamp(var(--space-4), 10vw, var(--space-6));
background: var(--bg);
border: 1px solid var(--border);
border-block-start: 2px solid var(--rule);
+6
View File
@@ -171,8 +171,14 @@ const aboutLinks = [
border-block-end: 1px solid var(--rule);
}
/* `flex-wrap: wrap` is the reflow fix, chosen OVER `overflow-wrap: anywhere` on
the name: the name is a flex item at `min-width: auto` and cannot shrink
below "Lajevardi", and wrapping the flex line breaks no word where
`anywhere` would have hyphenated a person's name. No effect at any normal
size. `docs/02` §Reflow carries the measurement. */
.footer-brand {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--space-3);
min-block-size: 44px;
+26 -14
View File
@@ -158,10 +158,15 @@ const isHome = path === '/';
Pouya's name read as a held capability, and §4 then recorded Q.Arb as
merely commenced. Q33 answered that the same day, and the premise was
wrong twice over — §4 now records Q.Arb as HELD, and even before it did:
ADR designations are voluntary credentials, not licences, and COMMERCIAL
arbitral appointment in Ontario is not gated behind a designation — so the
constraint was always positional, never legal, and Pouya accepts sole,
party-appointed and co-arbitration work today. See §4 Offerings.
ADR designations are voluntary credentials rather than licences, and on
**Pouya's stated position, which §4 Offerings records attributed to him and
deliberately unstamped**, commercial arbitral appointment in Ontario is not
gated behind a designation — so the constraint was always positional rather
than legal, and he accepts sole, party-appointed and co-arbitration work
today. ⚠️ **STATED AS HIS POSITION, NOT AS FACT, AND THAT IS REQUIRED:** §4
Forbidden bars the class claim about arbitral gating **in both directions**,
and this repository does not conclude a proposition of law. See §4 Offerings
and the `struck-universal-q39` row.
SCOPED 2026-08-27 (Q39). This comment said "Anyone may be appointed an
arbitrator in Ontario", which Pouya checked and found FALSE as a universal:
@@ -199,24 +204,31 @@ const isHome = path === '/';
same words as the hero eyebrow (docs/01). */
.brand-tagline {
display: none;
/* HELD AT 11px, BELOW THE `.eyebrow` THIS ELEMENT CARRIES. Two reasons, both
measured 2026-08-31 at 13px. (1) `--header-h` is 81px and the header goes
to 83.4px — `global.css` drives `scroll-padding-top` from that token. (2)
With a seventh nav item the CTA lands past `.header-inner`'s content edge
by 42px at 1216, 18px at 1240 and 26px at 1280 and 1440 — it does not
resolve as the viewport widens. Insights is that item; `showInsights`
turns it on at two published articles. ⚠️ Document overflow is 0 in every
one of those cases: flex lets the CTA sit past the padding edge without
growing the document, so a page-level check cannot see this. */
/* HELD AT 11px, BELOW THE `.eyebrow` THIS ELEMENT CARRIES. Measured at the
LIVE token value, 14px, on 2026-08-31 — earlier figures here were taken at
13px and understated all three costs. (1) `--header-h` is 81px and the
header goes to 84.98px; `global.css` drives `scroll-padding-top` from that
token. (2) The CTA lands past `.header-inner`'s content edge — 1.3px at
1216 with the SIX nav items shipping today, and 67.8 / 43.8 / 51.8 / 51.8px
at 1216 / 1240 / 1280 / 1440 with a seventh. It does not resolve as the
viewport widens. Insights is that item; `showInsights` turns it on at two
published articles. (3) ⚠️ AND AT 14px IT DOES GROW THE DOCUMENT: 20px of
overflow at 1216 and 4px at 1280 with seven items. At 13px it did not,
which is why this comment used to say a page-level check could not see it.
At 11px all three are zero, with six items and with seven. */
font-size: var(--text-2xs);
white-space: nowrap;
}
/* ⚠️ NEVER `white-space: nowrap` HERE. It was, until 2026-08-31, and because the
masthead is on all 22 pages that one declaration was the site's binding
reflow defect at a 200% default font size. The name is two words and takes
two lines when it has to; at every normal size it never wraps. WCAG 1.4.4 /
1.4.10; `docs/02` §Reflow carries the measurement. */
.brand-name {
font-family: var(--font-serif);
font-size: var(--text-xl);
line-height: var(--leading-tight);
letter-spacing: var(--tracking-tight);
white-space: nowrap;
color: var(--text);
}
.brand:hover .brand-name {
+35 -21
View File
@@ -119,12 +119,12 @@ const PROCESSES = [
</div>
<h1 class="sheet-name">{SITE.name}</h1>
<p class="sheet-desigs">{CREDENTIALS.designations.join(' · ')}</p>
<p class="sheet-strap">{SITE.tagline}</p>
<p class="eyebrow sheet-strap">{SITE.tagline}</p>
</header>
<div class="sheet-grid">
<section class="block block-wide">
<h2>The practice</h2>
<h2 class="eyebrow">The practice</h2>
<p>
{
/* ⚠️ NO LEADING SCOPE. This sentence read "I act as a neutral in
@@ -152,26 +152,26 @@ const PROCESSES = [
</section>
<section class="block">
<h2>Designations</h2>
<h2 class="eyebrow">Designations</h2>
<ul role="list">
{CREDENTIALS.designations.map((d) => <li>{d}</li>)}
</ul>
<h2>Education</h2>
<h2 class="eyebrow">Education</h2>
<ul role="list">
{CREDENTIALS.education.map((d) => <li>{d}</li>)}
</ul>
<h2>Certifications</h2>
<h2 class="eyebrow">Certifications</h2>
<ul role="list">
{CREDENTIALS.certifications.map((d) => <li>{d}</li>)}
</ul>
</section>
<section class="block">
<h2>Memberships</h2>
<h2 class="eyebrow">Memberships</h2>
<ul role="list">
{CREDENTIALS.memberships.map((d) => <li>{d}</li>)}
</ul>
<h2>Languages</h2>
<h2 class="eyebrow">Languages</h2>
<ul role="list">
<li>
{CREDENTIALS.languages.join(' and ')}, without an interpreter
@@ -180,14 +180,14 @@ const PROCESSES = [
</section>
<section class="block">
<h2>Processes</h2>
<h2 class="eyebrow">Processes</h2>
<ul role="list">
{PROCESSES.map((p) => <li>{p}</li>)}
</ul>
</section>
<section class="block">
<h2>Subject matter</h2>
<h2 class="eyebrow">Subject matter</h2>
<ul role="list">
{PRACTICE_AREAS.map((area) => <li>{area.name}</li>)}
</ul>
@@ -197,7 +197,7 @@ const PROCESSES = [
</section>
<section class="block block-wide">
<h2>Rates</h2>
<h2 class="eyebrow">Rates</h2>
<ul role="list" class="rates-list">
<li>
Half day, up to {halfDay.hours} hours of session — {
@@ -228,7 +228,7 @@ const PROCESSES = [
</section>
<section class="block block-wide sheet-contact">
<h2>Contact</h2>
<h2 class="eyebrow">Contact</h2>
<p>
{CONTACT.email} · {CONTACT.phoneFallback} · {CONTACT.location}
<br />
@@ -271,13 +271,13 @@ const PROCESSES = [
letter-spacing: var(--tracking-wide);
color: var(--accent);
}
/* Type comes from the global `.eyebrow` class on the element; only the margin is
here. This rule and `.block h2` below were byte-for-byte copies of
`.eyebrow`'s declarations at `--text-2xs` — the same escape the footer's
column headings were. The print block below sets both to 7pt, so the screen
size never reached the PDF. */
.sheet-strap {
margin-block-start: var(--space-2);
font-family: var(--font-mono);
font-size: var(--text-2xs);
letter-spacing: var(--tracking-eyebrow);
text-transform: uppercase;
color: var(--text-meta);
}
.sheet-grid {
@@ -290,12 +290,8 @@ const PROCESSES = [
grid-column: 1 / -1;
}
/* See `.sheet-strap` above: type from `.eyebrow`, only the rule under it here. */
.block h2 {
font-family: var(--font-mono);
font-size: var(--text-2xs);
letter-spacing: var(--tracking-eyebrow);
text-transform: uppercase;
color: var(--text-meta);
padding-block-end: var(--space-2);
border-block-end: 1px solid var(--border);
}
@@ -320,8 +316,13 @@ const PROCESSES = [
.block p + p {
margin-block-start: var(--space-3);
}
/* `anywhere`, and the cause is ONE STRING: the last row prints the fee-card URL,
which has no break opportunity and sized this single-column grid track. The
URL has to stay — printed sheet, the reader cannot click it. `docs/02`
§Reflow, instrument finding 1. */
.rates-list {
max-inline-size: none;
overflow-wrap: anywhere;
}
.fine {
font-size: var(--text-xs);
@@ -367,6 +368,19 @@ const PROCESSES = [
.sheet-head {
padding-block-end: 8pt;
}
/* ⚠️ `font-weight` IS FROZEN AT 400, AND FROZEN RATHER THAN CHOSEN. These
elements carried no weight of their own before 2026-08-31 and rendered at
400; taking `.eyebrow` gave them its 500, which changed the PRINTED sheet —
a visual change to the artefact circulated with an appointment proposal,
from a ruling that was about SIZE. `docs/02` §Accessibility floor carries
the byte figures. So print keeps 400
and the committed PDF stays byte-identical; screen takes the 500 every other
eyebrow has. ⚠️ POUYA'S CALL WHETHER TO UNIFY: if he does, this declaration
goes and `npm run bio:pdf` must be re-run and re-committed. */
.block h2,
.sheet-strap {
font-weight: var(--weight-normal);
}
.block h2 {
font-size: 7pt;
padding-block-end: 3pt;
+22 -5
View File
@@ -323,18 +323,22 @@ const hintId = (name: string) => `${name}-hint`;
color: var(--text-secondary);
}
/* The direct-contact block. A `<dl>` because each row is genuinely a
term and its value, which is also what lets the labels stay legible at
small sizes without a heading level. */
/* The direct-contact block. A `<dl>` because each row is genuinely a term and
its value, which is what gives the labels their semantics without spending a
heading level on them. */
.direct {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(14rem, 100%), 1fr));
gap: var(--space-5);
margin-block-start: var(--space-8);
}
/* `--text-eyebrow`, not `--text-2xs`: these `<dt>`s are label text on the page
that collects inquiries, so they move with the `<label>`s below rather than
sitting a step behind them. Pouya's ruling, 2026-08-31. */
.direct dt {
font-family: var(--font-mono);
font-size: var(--text-2xs);
font-size: var(--text-eyebrow);
font-weight: var(--weight-medium);
letter-spacing: var(--tracking-eyebrow);
text-transform: uppercase;
color: var(--text-meta);
@@ -343,6 +347,10 @@ const hintId = (name: string) => `${name}-hint`;
margin-block-start: var(--space-2);
font-size: var(--text-base);
line-height: var(--leading-snug);
/* The email address has no break opportunity and overflowed at a 200% default
font size. It must stay selectable and correct, so it breaks rather than
being truncated. `docs/02` §Reflow carries the measurement. */
overflow-wrap: anywhere;
}
/* The no-retainer sentence, set larger than the paragraphs under it. On an
@@ -374,13 +382,22 @@ const hintId = (name: string) => `${name}-hint`;
gap: var(--space-2);
}
/* NOT the `.eyebrow` class, deliberately: `--text-secondary` (11.75:1) rather
than `.eyebrow`'s `--text-meta` (5.47:1), because a form label is operative
text. Everything else matches it, `font-weight` included — without that these
rendered at 400 under a `p.eyebrow` of the same size and colour.
`overflow-wrap` because at a 200% default font size "Firm or organisation"
ran 38px outside its own box at 320px: `docs/02` §Reflow, instrument
finding 2. */
label,
legend {
font-family: var(--font-mono);
font-size: var(--text-2xs);
font-size: var(--text-eyebrow);
font-weight: var(--weight-medium);
letter-spacing: var(--tracking-eyebrow);
text-transform: uppercase;
color: var(--text-secondary);
overflow-wrap: anywhere;
}
/* Maroon on cream is 12.29:1, so the asterisk is legible — but it is
`aria-hidden` and paired with a visually-hidden "(required)", because
+7
View File
@@ -687,6 +687,9 @@ const latest = (await getCollection('insights', ({ data }) => !data.draft))
runs four lines; `text-wrap: balance` (global.css) keeps them even. */
font-size: var(--text-6xl);
max-inline-size: 22ch;
/* `anywhere`, not `break-word` — one word here held the whole hero column
open. `docs/02` §Reflow, instrument finding 1. */
overflow-wrap: anywhere;
}
.hero-lede {
max-inline-size: var(--width-prose);
@@ -875,6 +878,10 @@ const latest = (await getCollection('insights', ({ data }) => !data.draft))
flex: 1 1 auto;
max-inline-size: 46ch;
color: var(--text-secondary);
/* `anywhere`, not the `break-word` `global.css` already gives this `<p>` —
one token held this card's grid track open. `docs/02` §Reflow, instrument
finding 1. */
overflow-wrap: anywhere;
}
.feature-arrow {
font-size: var(--text-xl);
+22 -18
View File
@@ -27,23 +27,25 @@
*
* ⚠️ **WHAT THIS PAGE DELIBERATELY DOES NOT CLAIM, AND THE OMISSIONS ARE THE
* POINT.** docs/05 specifies a customer-managed KMS key, point-in-time recovery,
* and DynamoDB TTL. `AGENTS.md` §7 verifies the table's name and region and
* **does not verify any of those three as enabled**. So:
* and DynamoDB TTL. `AGENTS.md` §7 is the register for whether each of the three
* is enabled, and **this comment does not restate what it says** — it did once,
* went stale within the day, and had to be pulled back (§12 R19). So:
*
* - "Encrypted at rest" IS stated, because DynamoDB encrypts every table at
* rest unconditionally — it is true whether or not the customer-managed key
* in docs/05 has been configured.
* - The customer-managed key and point-in-time recovery are NOT mentioned.
* Neither is a fact a reader needs, and neither is verified.
* - **Automatic deletion IS stated, and it is the one promise on this page
* that depends on a control nobody has verified.** The handler writes the
* `ttl` attribute, and ⚠️ **writing the attribute is not the mechanism** —
* TTL must be ENABLED on the table, and **§7 records whether it is.**
* docs/05's definition of done carries "TTL set and verified by test
* record" and `docs/06`'s cutover checklist names this page as what that
* item is protecting. **Both halves — `ENABLED` by command, and a test
* record confirmed deleted — before this page is public.** See the
* TODO(pouya) on the retention section below, and §9 Q60.
* - **Automatic deletion IS stated, and it asserts a MECHANISM rather than only
* a period** — the one promise here whose truth lives entirely outside this
* repository. The handler writes the `ttl` attribute, and ⚠️ **writing the
* attribute is not the mechanism**: TTL must also be enabled on the table,
* which §7 records — **and the setting being on still does not prove a
* record is ever deleted.** Only a record written with a near-future `ttl`
* and watched to vanish proves that. docs/05's definition of done carries
* "TTL set and verified by test record" and `docs/06`'s cutover checklist
* names this page as what that item protects. **Both halves before this page
* is public.** See the TODO(pouya) on the retention section below, and §9 Q60.
*
* ⚠️ **NO LICENSURE CLAIM AND NO ANSWER TO THE CAPACITY QUESTION.** A privacy
* policy is where "legal advice" phrasing arrives by convention. §4 records
@@ -209,13 +211,15 @@ const COLLECTED = INTAKE_FIELDS.map((field) => field.label);
<h2>How long it is kept</h2>
{
/* TODO(pouya): is DynamoDB TTL `ENABLED` on the intake table, and has a
test record been written with a near-future `ttl` and observed to
disappear? AGENTS.md §9 Q60. The sentence below asserts a mechanism,
not just a period — `describe-time-to-live` returned `DISABLED` on
2026-08-31 — and it must not go public until both halves are
confirmed. §7 records the status; do not answer this from the
handler code, which only writes the attribute. */
/* TODO(pouya): has a test record been written to the intake table with a
near-future `ttl` and OBSERVED TO DISAPPEAR? AGENTS.md §9 Q60. The
sentence below asserts a MECHANISM, not just a period, and the
setting being on does not prove the mechanism runs. The table
setting is confirmed — §7 holds that status and this comment does
not restate it, because it did restate it once and went stale within
the day (§12 R19). Do not answer this from the handler code, which
only writes the attribute. This page must not go public until a
deletion has actually been seen. */
}
<p>
<strong>{RETENTION_MONTHS} months from the date you send it</strong>,
+15 -7
View File
@@ -64,15 +64,23 @@
/* Fluid scale, 360px → 1600px viewport. Ratio widens toward the display
end (1.25 → 1.333) so headlines scale harder than body copy.
--text-2xs is the 11px floor for a COMPRESSED label — the header tagline
and the print sheet. It stopped being the eyebrow floor on 2026-08-31.
Added 2026-08-27: SiteHeader wrote `0.6875rem` as a literal, step-1
review finding #7. */
--text-2xs HAS EXACTLY ONE CONSUMER: the header tagline in SiteHeader, held
there for a measured layout reason recorded beside it. It is the smallest
type on the site and nothing else may use it without a measurement — the
three other places that did (the /contact/ labels, the /contact/ dl terms,
the /bio/ sheet) all moved to --text-eyebrow on 2026-08-31 because none of
them had a reason beyond having been written that way. Added 2026-08-27:
SiteHeader wrote `0.6875rem` as a literal, step-1 review finding #7. */
--text-2xs: 0.6875rem; /* 11 — label */
--text-xs: 0.75rem; /* 12 — legal */
/* Not a rung on the ladder above: 13px sits between xs and sm because
uppercase mono at 0.18em reads smaller than it measures. Pouya, 2026-08-31. */
--text-eyebrow: 0.8125rem; /* 13 — eyebrow */
/* THE SAME VALUE AS `--text-sm` BELOW, AND DELIBERATELY NOT AN ALIAS OF IT.
Uppercase mono at 0.18em reads smaller than it measures, so the eyebrow
needs the top of the small range rather than a rung of its own — but it and
body-meta type move for different reasons, and aliasing would mean a future
change to meta text silently moved every eyebrow on the site. Pouya raised
it 12 -> 13 -> 14 px on 2026-08-31; 13 px was still getting lost against the
display type. */
--text-eyebrow: 0.875rem; /* 14 — eyebrow */
--text-sm: 0.875rem; /* 14 — meta */
--text-base: 1rem; /* 16 — body */
--text-lg: clamp(1.0625rem, 0.99rem + 0.32vw, 1.1875rem); /* 17→19 */