Steps 7a through 10 as one authorised run. Nothing deployed (D11).
7a Lighthouse returns as `lighthouse@13.4.1` + `chrome-launcher`, NOT
`@lhci/cli`. AGENTS.md §7's advisory attribution was wrong: the carriers
were @lhci/cli's own `tmp` and @puppeteer/browsers' `extract-zip`, not
Lighthouse, which audits clean. A deliberate deviation from R11's literal
trigger, recorded with what it costs. Local gate; CI has no Chrome.
7b OG card generator (satori + sharp) discharges R15 — 20 typed cards plus
per-article cards; the portrait stays on / and /about/ by Q40. Insights
plumbing: ArticleCard, Prose, the index, the article route, articleGraph,
and /'s section 7. Card copy is constrained structurally because text in a
JPEG cannot be grepped by check:claims: every headline IS its page's <h1>,
enforced by `npm run og:proof`.
7c Five drafted launch articles, draft: true / reviewedByPouya: false. An
independent compliance audit returned 76 findings and 57 unsourced
assertions; all blocking and should-fix applied.
8 /contact/, the intake form, and backend/intake/ (undeployed). Plain HTML
POST to a same-origin /api/intake with a 303 redirect, so the form works
with zero JavaScript. docs/05 records three deliberate deviations.
9 /fees/ on Q59's ruling — overtime runs from the session cap, and the
reservation point ships adjacent to the rate. One-page PDF bio discharges
R16; /bio/ is its source, so the circulated artefact stays inside the
review apparatus.
10 /legal/privacy/ and /legal/terms/, written to the backend as built. Three
of the policy's statements are derived and cannot drift.
Also: /about/'s inverse credentials band (approved at step 6); Q59 closed;
R15 and R16 discharged; and a fix to shipped copy — /practice/energy/ asserted
the absence of a regulation the source extract says must not be asserted.
Review: adversarial-reviewer, two rounds (D20/D19). Round 1 returned 16
findings including two blocking — an invisible ghost button on /fees/ at
1.00:1 that Lighthouse scored 100, and a privacy policy that named one data
processor when there are two. All 16 acted on.
Lighthouse, 22 pages, mobile: performance 99-100, accessibility 100,
best practices 100, SEO 100 on every indexable page, CLS 0.000.
AGENTS.md entry (ah) has the detail, including four of my own verification
commands that were wrong and what each of them nearly caused.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Md3GndFqWPzK78xAoebsg5
99 lines
3.6 KiB
Plaintext
99 lines
3.6 KiB
Plaintext
---
|
|
/**
|
|
* `/contact/could-not-send/` — the failure half of the intake form's
|
|
* POST-redirect-GET. Build step 8.
|
|
*
|
|
* WHY THIS PAGE EXISTS AT ALL. The site ships zero JavaScript, so a static page
|
|
* cannot read `?error=` and render a message. The alternatives were: return an
|
|
* error body from the API (the visitor lands on the API hostname with none of
|
|
* the site around it), or say nothing (the visitor cannot tell whether the
|
|
* inquiry arrived, on a form about a live dispute). A named page is the only one
|
|
* of the three that leaves the reader knowing what happened.
|
|
*
|
|
* ⚠️ **IT DOES NOT LIST WHICH FIELD FAILED, AND THAT IS DELIBERATE ON TWO
|
|
* COUNTS.** The handler deliberately does not return the error list — an
|
|
* enumeration of the validation rules is a gift to whoever is probing them — and
|
|
* the browser's own `required` / `type="email"` / `maxlength` handling has
|
|
* already caught every case a person is likely to hit, inline and announced. A
|
|
* server-side rejection means the submission was not made by that markup.
|
|
*
|
|
* ⚠️ **NO APOLOGY AND NO GUESS AT THE CAUSE.** "Something went wrong on our end"
|
|
* is a claim about which end, and this page cannot know. It says what is true —
|
|
* the inquiry was not recorded — and gives a route that does not depend on the
|
|
* form working.
|
|
*
|
|
* `noindex`, and excluded from the sitemap in `astro.config.mjs`.
|
|
*/
|
|
import BaseLayout from '../../layouts/BaseLayout.astro';
|
|
import Button from '../../components/Button.astro';
|
|
import Eyebrow from '../../components/Eyebrow.astro';
|
|
import { getImage } from 'astro:assets';
|
|
import ogDefault from '../../assets/og-portrait.jpg';
|
|
import { pageGraph } from '../../data/schema';
|
|
import { CONTACT } from '../../data/site';
|
|
|
|
const ldImage = await getImage({
|
|
src: ogDefault,
|
|
format: 'jpeg',
|
|
width: 1200,
|
|
height: 630,
|
|
});
|
|
const graph = pageGraph(new URL(ldImage.src, Astro.site).href);
|
|
---
|
|
|
|
<BaseLayout
|
|
title="Inquiry Not Sent · Contact · Pouya Lajevardi · Toronto"
|
|
description="The inquiry was not recorded, so nothing has been received. Email the same details directly and they will be answered within two business days."
|
|
jsonLd={graph}
|
|
noindex
|
|
>
|
|
<section class="section hero">
|
|
<div class="wrap">
|
|
<Eyebrow dot>Not sent</Eyebrow>
|
|
<h1 class="display hero-h">That inquiry was not recorded.</h1>
|
|
<div class="prose">
|
|
<p class="statement">
|
|
Nothing has been received, so there is nothing waiting for a reply.
|
|
</p>
|
|
<p>
|
|
The quickest route is email. Send the same details — your name, your
|
|
role, the other parties, and a few sentences about the dispute — to <a
|
|
href={`mailto:${CONTACT.email}`}>{CONTACT.email}</a
|
|
>, and leave privileged detail out of it. {CONTACT.responseTime}
|
|
</p>
|
|
<p>
|
|
Or go back to the form and send it again. If it fails a second time,
|
|
email rather than trying a third.
|
|
</p>
|
|
</div>
|
|
<div class="cta">
|
|
<Button href="/contact/">Back to the form</Button>
|
|
<Button href={`mailto:${CONTACT.email}`} variant="ghost">
|
|
Email instead →
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</BaseLayout>
|
|
|
|
<style>
|
|
.hero {
|
|
padding-block: var(--space-9) var(--space-11);
|
|
}
|
|
.hero-h {
|
|
margin-block: var(--space-4) var(--space-5);
|
|
font-size: var(--text-5xl);
|
|
}
|
|
.statement {
|
|
font-size: var(--text-lg);
|
|
line-height: var(--leading-body);
|
|
color: var(--text);
|
|
}
|
|
.cta {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: var(--space-3) var(--space-4);
|
|
margin-block-start: var(--space-8);
|
|
}
|
|
</style>
|