offplan · online
Plan · admin-panel

Admin Panel Redesign — brandbook v2 canon pass + onboarding stub

Approvedplanadmin-panel
Created
2026-05-11

Goal

Replace docs/mockups/admin-panel-v8.html (3 163-line monolith, dark theme + gold accent + table-wrap layout) with a multi-file mockup set at design-system/admin/ that anchors strictly to brandbook v2 canon, restructured into 15 screens (1 onboarding + 1 overview + 11 v8 project-editor sections + 1 Team + 1 Activity log) with shared CSS. Mockup becomes the canonical visual reference for the future React-build admin track (analogous to how design-system/sales/02-exterior.html anchors the sales-app-react work).

Success Criteria

See frontmatter. The two-minute check: open design-system/admin/index.html, click through all 15 screens, no gold/glass/saturated-status anywhere, role badge present in topbar of every authenticated screen, trial banner visible until upgraded, brandbook v2 token table reconciled (a manual grep of the mockup CSS for #B8955A, --gold, glass-, rgba(255,255,255,0.5 returns zero hits).

Approach (chosen)

Pure visual reskin v8 + onboarding stub (Approach A from Step 3 interview).

Multi-file HTML mockup set under design-system/admin/ mirroring the design-system/sales/ precedent — one HTML file per screen, three shared CSS files (_shell.css, _components.css, colors_and_type.css), and a small asset folder for the Phosphor icon sprite + wordmark SVG.

Visual register: strict brandbook v2 canon. The colors_and_type.css is forked from design-system/bundle/project/colors_and_type.css with every gold-leftover token (--gold, --gold-light, --gold-dim, --gold-border, --skel-accent hex-equal-to-gold) deleted and replaced by VV Moss #6A7061 derivatives. Status palette uses oxidised tokens (--status-available #5C7A4A / --status-reserved #B58440 / --status-sold #8A4438) — not the saturated traffic-light from admin-panel-atelier.html. No glass-* tokens or backdrop-filter: blur() surfaces.

IA-rethink scope (per Step 1 interview pick "Редизайн + переосмысление IA"):

What this plan does NOT cover (explicitly out of scope, scoped to a follow- on workstream that closes CONV-35 designer task-list):

These surfaces are referenced from the shell (e.g. the upgrade CTA links to a modal stub) but not designed in this plan. They land in a follow-on admin-panel-trial-ux workstream after this plan ratifies the visual register.

Inputs (canonical)

  1. design-system/bundle/project/colors_and_type.css — token source of truth. Fork into design-system/admin/colors_and_type.css, strip gold leftovers, keep Moss + oxidised status + Skeleton White + Warm Stone.
  2. design-system/bundle/project/reference/brandbook-v2.html — canonical component anatomy + token table. Authoritative when atelier-mockup diverges.
  3. design-system/bundle/project/preview/*.html — 7 working previews (colors / typography / components / spacing-shadow-radius / sales- presentation / admin-panel / brandbook) — copy-paste-friendly token usage examples.
  4. docs/mockups/admin-panel-v8.html — IA + section list reference (11 project-editor sections to preserve). NOT a visual reference (dark theme, gold accent → drift).
  5. docs/mockups/admin-panel-atelier.html — layout/density inspiration only (sidebar pattern, project switcher chip, header structure). NOT a visual reference (gold + glass → drift per ADR 0015).
  6. docs/mockups/admin-quick-build-atelier-standalone.html — onboarding flow inspiration for 01-onboarding.html. NOT extended directly (opaque Babel-bundled blob); read it as a design reference.
  7. plans/permission-and-tenancy-model.md (ratified v4.18) — role list: Owner / Admin / Sales Manager / Content Editor / Sales Agent + Free Guest org tier. Admin-panel link = next to avatar in sales-app top bar (Phase 1.3.12). Roles drive Team screen + lock-icon logic.
  8. plans/onboarding-trial-mode.md (ratified CONV-35 2026-05-11) — tier names: Starter / Pro (Trial default 14d) / Enterprise. 3 seats during trial. Subdomain {slug}.offplan.online, custom domain T2+. Trial banner copy + counters source.
  9. docs/decisions/0004-audit-log-retention.md (v2 CONV-34) — 12mo active + 7yr archive (pseudonymised) + append-only + monthly hash-chain seal. Drives Activity log columns + filter UI.
  10. docs/decisions/0002-iconset-phosphor.md — Phosphor as canonical iconset. Assemble subset SVG sprite.

Inputs (NOT canonical — explicitly skipped)

Out of scope

Implementation Steps

Phase 1 — Foundation (shared CSS + assets + landing)

Tasks:

  1. Fork design-system/bundle/project/colors_and_type.css to `design- system/admin/colors_and_type.css. Strip every --gold* token, --skel- accent, --glass-*. Reaffirm: --moss, --moss-soft, --moss-bg`, --status-available, --status-reserved, --status-sold + -bg variants, Skeleton White surfaces, Warm Stone surfaces, all type tokens, tracking tokens, radius tokens, shadow tokens, motion tokens.
  2. Create design-system/admin/_shell.css — shell layout primitives:
    • .shell (CSS grid: sidebar 280px + main 1fr)
    • .shell__sidebar (Warm Stone, fixed-width, Phosphor icons + label rows)
    • .shell__topbar (Skeleton White, 64px height, breadcrumb + actions)
    • .shell__trial-banner (above topbar, thin band, Moss-soft surface, tier label + counters + Upgrade CTA)
    • .shell__content (Warm Stone, 32px padding, max-width 1240px)
    • .shell__section-header (h1 + eyebrow + actions cluster)
  3. Create design-system/admin/_components.css — reusable bits:
    • .btn-primary / .btn-secondary / .btn-ghost / .btn-danger
    • .input / .input--with-icon / .textarea / .select
    • .table / .table__row / .table__cell / .table--editable
    • .tabs / .tab--active
    • .chip / .chip--filter / .chip--filter-active
    • .status-pill (consumes --status-* tokens only; no hex literals)
    • .panel (Card + header + body + footer; no glass effect)
    • .modal-stub (Skeleton White overlay; opacity-anchored, no blur)
    • .banner / .banner--info / .banner--warning / .banner--success
    • .role-badge (small pill carrying role name, surfaced in topbar)
    • .lock-icon (Phosphor lock-simple 14px, inline next to disabled action)
  4. Assemble Phosphor SVG sprite at design-system/admin/assets/icons.svg. Subset: ~30 icons — house, building, image, map-pin, layers, sliders, list, plus, pencil, trash, lock-simple, user-circle, users, gear, signpost, shield, clock-counter-clockwise (for activity log), file-text, image-square, palette, currency-dollar, chart-line, sign-in, sign-out, plus more as discovered during build. Pull from Phosphor 2.x regular weight, 24×24 viewbox.
  5. Copy wordmark from design-system/sales/assets/brand/wordmark.svg to design-system/admin/assets/brand/wordmark.svg (canon mark, already used sales-side).
  6. Create design-system/admin/index.html — review menu page with thumb grid + name + screen number for each of the 15 screens. Used by Roma+Ilya for screen-by-screen walkthrough. Tiny page, ~60 lines.

Verification:

Eval pack:

Field Value
Artefact design-system/admin/colors_and_type.css + _shell.css + _components.css + assets folder + index.html
2-min check Open index.html — 15 thumb slots visible; open colors_and_type.css — visible tokens are Moss + oxidised status + Skeleton White / Warm Stone; no gold tokens present.
Agent self-check All three grep checks pass (AU English, drift, console-errors). Phase-gate handoff: Gate-passed: phase-1.

Phase 2 — Onboarding + overview (the two new screens)

Tasks:

  1. 01-onboarding.html — first-registration Trial signup flow imitation. Modelled after admin-quick-build-atelier-standalone.html (Trial signup entry mode). Structure:
    • Hero strip: wordmark + "Get your white-label sales platform · 14 days, no card required" (Trial T2 Pro default per Sub-plan 2 Pick #1 B4)
    • Step 1 — workspace details: Organisation name + subdomain slug live preview {slug}.offplan.online + Organisation type chips (Studio / Agency / Developer / Other) per permission-and-tenancy-model Block A.
    • Step 2 — admin contact: name + email + (optional) phone
    • Step 3 — first-project bootstrap: name + project type + skip-for-now link
    • Step 4 — confirmation: "Workspace ready · Trial active for 14 days" + CTA "Open admin panel →" (links to 02-overview.html)
    • No real form submission — pure visual. Buttons are anchor tags.
  2. 02-overview.html — post-login workspace landing. Structure:
    • Shell with sidebar (Phosphor house Overview, Phosphor building per project, Phosphor users Team, Phosphor clock-counter-clockwise Activity log, Phosphor gear Settings, Phosphor sign-out Sign out at bottom).
    • Trial banner at top: "Trial · Pro · 11 days left · 1 project of unlimited · 3 of 3 seats · Add card to keep your team" + Upgrade CTA → links to modal-stub.
    • Topbar: breadcrumb (Workspace) + role-badge (default state: Owner) + avatar.
    • KPI row: 4 cards — Projects (count + open), Saved presentations (count + delta), Active visitors (count + last 7d), Team seats (used / cap).
    • Projects list: cards 3-up, per project: cover image (Skeleton White placeholder if none) + name + slug + status pill + last-edited date + Open → CTA links to 03-theme.html (the first editor section per v8).
    • Empty state: when no projects, large Skeleton White card "No projects yet — Add your first" + Phosphor plus icon + CTA.

Verification:

Eval pack:

Field Value
Artefact 01-onboarding.html + 02-overview.html walkable in browser.
2-min check Sergei opens 01, fills imaginary org details (UI only — no submit), clicks Open admin panel → lands on 02 → sees trial banner + KPI row + project cards (placeholder Riviera fixture).
Agent self-check Drift + AU greps pass. Phosphor icons render (no missing-glyph squares). Phase-gate handoff: Gate-passed: phase-2.

Phase 3 — Project-editor sections (the 11 reskins from v8)

Tasks:

For each of the 11 v8 sections, read the v8 HTML to capture the section's data model + form fields, then re-author in canon CSS. Order — same as v8's "workflow bar" (Theme → Features → Labels → Buildings → Galleries → Location → Levels → Amenity → Units → Plans → Plates), one HTML per screen.

  1. 03-theme.html — Project theme: accent colour token swatch grid (deep-blue / moss / oxblood / charcoal — per project, not org-level), wordmark upload, hero font scale slider, dark/light preview toggle.
  2. 04-features.html — Feature flags table: Floor Plates / Floor Plans / Galleries / 360 panoramas / Amenities / Saved units etc. — each toggle on / off with description + dependency hints. Per v8's 706-line Features screen.
  3. 05-labels.html — Labels & terminology overrides: "Building" → "Tower" / "Apartment" → "Residence" / etc. Per-project i18n stub (English only in Stage 1).
  4. 06-buildings.html — Building list: name + level count + units count + status. Per-building drawer: floors + amenities + assets.
  5. 07-galleries.html — Gallery groups: cover + count + reorder + drag- drop hint. Skeleton White card grid.
  6. 08-location.html — Map: Skeleton White placeholder + lat/long inputs + POI list (cafés / schools / transit) + map style (Skeleton White / dark mode disabled per canon).
  7. 09-levels.html — Levels per building: floor index + plate assignment + ceiling height + plate count. Per v8.
  8. 10-amenities.html — Amenities list: name + icon (Phosphor) + tier (resident / public) + photo gallery. Per v8.
  9. 11-units.html — Unit list table: code + level + layout + beds + baths sample.
    • aspect + status pill + price (canon JetBrains Mono). Per v8's 23-unit
  10. 12-plans.html — Floor plan layouts: thumbnail + name + bed count + floors-using-this + edit pencil. Per v8.
  11. 13-plates.html — Floorplates: plan view + layout grid + assigned units. Per v8's 21-plate sample.

Every section's shell + topbar comes from _shell.css; every form/table/chip/ pill comes from _components.css. NO inline styles permitted in feature sections (token-as-truth rule per L-1 brandbook product-pattern layer).

Verification:

Eval pack:

Field Value
Artefact 11 HTML files in design-system/admin/03-…html13-…html walkable.
2-min check Roma + Ilya walk the editor flow: 02 → 03 → 04 → … → 13, no dead-ends, no broken styles, visual register matches brandbook v2 components.html.
Agent self-check All 3 greps × 11 files. Per-screen tab/back-nav works. Phase-gate handoff: Gate-passed: phase-3.

Phase 4 — Team + Activity log (RBAC-specific new screens)

Tasks:

  1. 14-team.html — Team management screen.
    • Topbar: breadcrumb (Workspace › Team) + Add member CTA.
    • Member table: avatar + name + email + role chip + last-active + actions (edit / remove). 5 sample rows covering each role.
    • Role legend below table — 5 roles (Owner / Admin / Sales Manager / Content Editor / Sales Agent) with one-line permission summary each, per ratified permission-and-tenancy-model.md Block B matrix.
    • Empty seat indicator: trial-mode shows "0 of 3 free seats used" if trial, "X of N seats used" if paid; "Upgrade to add more seats" CTA when at cap.
    • Pending invitations panel below table: email + role + sent-at + revoke.
    • Free Guest section: tenants with guest membership in your projects — name + their Org + their role with you + project link.
  2. 15-activity.html — Activity (audit) log, per Phase 1.3 §2.4 + ADR 0004 v2.
    • Topbar: breadcrumb (Workspace › Activity) + filter chips (date range, actor, action type, target type).
    • Timeline view: reverse-chrono. Each entry: timestamp (JetBrains Mono) + actor avatar + role chip + action verb + target (with link) + diff summary if applicable.
    • Sample entries (10–15): project created, unit status changed, member invited, member removed, theme accent updated, plan published, etc.
    • "12 months retained, then archived (pseudonymised) · 7-year horizon" tag in topbar — surfaces ADR 0004 v2 retention policy to the operator.
    • Export CSV button (visual only — no real export).

Verification:

Eval pack:

Field Value
Artefact 14-team.html + 15-activity.html walkable.
2-min check Roma walks Team → adds imaginary invitation → sees pending row → walks Activity → filters by actor → sees entry. URL ?as=ce shows lock icons on Remove member rows.
Agent self-check Drift + AU + Phosphor. Role-chip parity vs Phase 3 sections. Phase-gate handoff: Gate-passed: phase-4.

Phase 5 — Reconciliation + sign-off

Tasks:

  1. Cross-screen consistency pass — open all 15 HTML side-by-side; verify identical sidebar, identical topbar, identical trial banner, identical button library, identical chip library, identical status-pill across all screens. File diffs of any inconsistency, apply patches.
  2. Visual register reconciliation against brandbook v2 — open `design- system/bundle/project/reference/brandbook-v2.html` side-by-side with each screen; verify token usage (every colour, every type ramp, every shadow, every radius). Catalogue any deliberate deviation in a `design-system/ admin/REGISTER-NOTES.md` (e.g. "trial banner uses Moss-soft fill not in brandbook palette — intentional, callout reason").
  3. Sergei walks the full journey solo (success criteria pre-check) — 01 → 02 → 03 → … → 13 → 14 → 15 → back to 02. Notes any dead-end, broken nav, broken style. Patches applied.
  4. Open question round — anything unresolved (e.g. "should role badge show abbreviation or full name on mobile-narrow viewport?") parked in design-system/admin/OPEN-QUESTIONS.md for later sub-plan or follow-on workstream.
  5. Sign-off with Roma + Ilya — screen-by-screen walkthrough, capture feedback. Two outcomes: (a) approved → workstream admin-panel-redesign marked done, follow-on admin-panel-trial-ux opens; (b) revisions required → back to Phase 3/4 for patch pass before re-walk.

Verification:

Eval pack:

Field Value
Artefact All 15 HTML files + 3 CSS files + assets + 2 notes files. design-system/admin/index.html walkable end-to-end.
2-min check Sergei loads index.html, clicks every thumb, walks every screen, none broken. Roma + Ilya sign-off captured.
Agent self-check Full drift + AU + Phosphor sweep × 15 screens passes. REGISTER-NOTES.md lists every deliberate deviation with reason. Phase-gate handoff: Gate-passed: phase-5 + demo URL recorded.

Files to Create / Modify

Phase 1 — Foundation

Phase 2 — Onboarding + Overview

Phase 3 — Project-editor sections

Phase 4 — Team + Activity

Phase 5 — Reconciliation

Files explicitly NOT touched

Dependencies

Testing & Verification

Workstreams

Name Priority Depends On Tags Tasks
admin-panel-foundation P0 ux, architecture, tooling Phase 1 (CSS + assets + index)
admin-panel-onboarding-overview P0 admin-panel-foundation ux, architecture Phase 2 (01 + 02)
admin-panel-project-editor P0 admin-panel-onboarding-overview ux, architecture, domain Phase 3 (03–13, 11 sections)
admin-panel-rbac-audit P0 admin-panel-project-editor ux, security, architecture Phase 4 (14 + 15)
admin-panel-sign-off P0 admin-panel-rbac-audit ux, tooling Phase 5 (reconciliation + sign-off)

Five sequential P0 workstreams. Each completable in 1–2 sessions (Phase 3 is the largest — possibly 3 sessions given 11 sections, but each section is ~200-300 lines of HTML/CSS so an experienced pass should land 3-4 per session).

Risks & Edge Cases

Risk Severity Mitigation
Forking colors_and_type.css and missing a subtle token (e.g. spacing scale) drifts admin from sales tokens MEDIUM Phase 1 task 1 explicitly enumerates kept-tokens; verify post-fork by diff'ing canon tokens in admin vs sales colors_and_type.css
Phosphor sprite balloons (every icon → 30+ KB) LOW Subset to ~30 icons in Phase 1 task 4; assemble as single sprite with <symbol> blocks; gzip-friendly
v8 data-model leakage — section content captured wrongly because v8's dark-theme HTML obscures structure MEDIUM For each Phase 3 section: read v8 source first, list fields/columns, draft the canon version against that explicit list (not eyeballed)
Trial banner copy drifts from Sub-plan 2's authoritative copy MEDIUM Pin trial-banner copy to exact strings from plans/onboarding-trial-mode.md Pick #1 + #4; if copy changes upstream, REGISTER-NOTES tracks it
Role-badge / lock-icon affordance design drifts from how the real React build will implement RBAC LOW This mockup is the design spec for the React build — mockup defines, React conforms. RBAC matrix from ratified permission-and-tenancy-model is authoritative
Mockup gets stale as ratified plans evolve MEDIUM Section content tagged with source plan (e.g. <!-- spec: onboarding-trial-mode.md Pick #1 --> HTML comments) so future you can grep and update
Sergei's atelier-track muscle memory creeps gold accent back in mid-build LOW Drift grep is run per-phase as hard gate; CI-style enforcement
Roma reviews and wants atelier-style mood after all (per Phase 5 sign-off) LOW Sign-off includes "(a) approved or (b) revisions required" branch — revision path documented
brandbook v2 itself revises mid-build (separate brand-language-and-identity plan is in flight) MEDIUM Tokens forked at start of Phase 1; if brand workstream lands a new token mid-build, sync via REGISTER-NOTES diff; do not chase brand-workstream changes intra-phase
Phosphor icon set might miss a needed glyph (e.g. specific architectural symbol) LOW Phase 1 task 4 lists the subset; if a glyph missing, swap to Phosphor closest match or assemble custom SVG in assets/custom-icons/
01-onboarding.html Trial signup field set differs from Sub-plan 2's authoritative onboarding form (Stripe + KYC fields etc.) MEDIUM Cross-check 01-onboarding.html field list against Sub-plan 2 Step 2 (signup form fields); REGISTER-NOTES if intentionally simpler for mockup
Activity log columns + filters don't match what ADR 0004 v2 authoritatively logs MEDIUM Cross-check 15-activity.html columns against ADR 0004 §Logged events list; REGISTER-NOTES if intentionally subset for mockup
File path design-system/admin/ collides with future React design-system/admin-app/ LOW Acceptable — different directory names; mockup-side is admin, React-side will be admin-app (mirroring sales / sales-app split)

From Learnings DB

Evaluation

Each phase has its own eval pack inline above (Artefact / 2-min check / Agent self-check). The plan-level evaluation is the success criteria in frontmatter — verifiable by Sergei walking the full demo at the end of Phase 5 + Roma + Ilya sign-off.


Business Review SPEC-AMEND v1.1 (CONV-36, 2026-05-11)

Five concern agents (Customers / Brand / Customer Success / Engineering / Security & Privacy) reviewed this plan in parallel post-Step-4 and returned 51 findings (16 HIGH + 22 MED + 13 LOW). HIGH findings are applied to the plan body as amendments below; MED + LOW are catalogued. Scenarios traced: (S1) Sergei solo walkthrough → sign-off, (S2) Roma+Ilya screen-by-screen review, (S3) future React-build developer reads mockup as spec, (S4) Trial customer Day 1 navigates onboarding → first project bootstrap, (S5) Sales Agent attempts to filter Activity log by other Agent's actions, (S6) trial customer post-T+30 lands on locked admin panel.

HIGH findings — applied inline as Implementation amendments

# Source Finding Amendment
H1 Customers Role names (Sales Manager / Sales Agent) are agency-language; 4-8-person studios think "boss / 3D artists / project manager". Studios will mis-assign or default everyone to Owner/Admin. Phase 4 task 1 (14-team.html): add role-tooltip with studio-native examples per role (e.g. "Content Editor = your 3D artist updating renders; Sales Manager = your account manager handling developer-clients"). Tooltip text captured in REGISTER-NOTES.md for tone-of-voice review.
H2 Customers Free Guest org tier (developer-clients invited by studio) has no defined landing view. Studios won't invite developer-clients into a confusing surface. NEW Phase 2 task — 02b-overview-guest.html (16th screen): single-project landing, no trial banner, no Team / Activity log sections, restricted sidebar (Phosphor building + project name + Saved + Gallery only). Surfaces "Guest access · invited by {host}" chip.
H3 Customers 11 v8 editor sections in one sidebar paralyses new studios (Labels & Terms / Plates are advanced). "This looks complicated" → churn before first project ships. Phase 1 task 2 (_shell.css): sidebar groups → "Essentials" (Theme / Buildings / Galleries / Units) + collapsed "Advanced" group (Features / Labels / Levels / Amenity / Plans / Plates / Location). Default state on first visit = Advanced collapsed.
H4 Brand Drift grep regex misses dominant glass pattern. Atelier uses rgba(255,255,255,0.30–0.45) (15+ instances) + whitespace variants + --warn: #B8955A (gold under different name). Hard gate lets most drift through. Verification section update: drift grep → `grep -REn 'rgba\(\s255\s,\s255\s,\s255\s,\s*0?\.[0-9]+\)\ backdrop-filter\ -webkit-backdrop-filter\ Cormorant\ Garamond\ --gold\ --navy\ --warn' design-system/admin/` returns 0. Hard gate.
H5 Brand 08-location.html map needs canonical --proj-map-water/--proj-map-land/--proj-map-park/--proj-map-road/--proj-map-pin tokens (bundle L281–286). Plan said "Skeleton White placeholder" — ad-hoc map colours would contradict brand contract. Phase 3 task 6 (08-location.html): map preview pins a data-project="cote" sample (or house-default) and consumes --proj-map-* tokens exclusively.
H6 Brand Forking colors_and_type.css creates a second source of truth that brand workstream cannot revise by editing the bundle. Phase 1 task 1 amendment: admin uses @import url('../bundle/project/colors_and_type.css'); then a sibling _admin-overrides.css with only deletions of gold/glass leftovers via inverted --gold: unset; style. Brand workstream owner co-signs the override file at Phase 1 close.
H7 CS Trial banner copy in plan is a third variant vs Sub-plan 2 Pick #3 header-banner («TRIAL — N days left») and Pick #14 countdown (« Trial ends in N days · Add card to continue → »). Mockup will create "email said 7 days, banner says 11" support tickets. Phase 2 task 2 (02-overview.html): trial-banner copy pinned verbatim to Pick #3 + Pick #14 strings. HTML comment <!-- spec: onboarding-trial-mode.md Pick #3 + #14 --> next to banner markup. Risk row 4 promoted to ratified copy lock.
H8 CS Out-of-scope trial-UX modals leave a design window where trial customers post-T+30 hit "Object Builder doesn't work" with no surface. Every "where's my data" call routes to CS without anything to screenshot. Phase 1 task 3 amendment (_components.css): .modal-stub ships with generic post-trial copy "Your Trial ended. Contact [email protected] to reactivate or upgrade →" + Phosphor clock-counter-clockwise icon. CS can screenshot for support docs immediately. Full modal designs land in follow-on admin-panel-trial-ux workstream.
H9 CS 15-activity.html columns (timestamp / actor / role / verb / target / diff) miss target_user_id, pii_class, deletion_journal stages, and Stripe subscription.deleted/chargeback events. Chargeback / "who deleted my data" investigations have no filter pivot. Phase 4 task 2 amendment: activity log filter chips → date range, actor, target user / Org, action type, billing-event subgroup (subscription / dispute / deletion_journal stage). Sample entries (10–15) include ≥1 chargeback freeze + ≥1 deletion_journal stage transition + ≥1 customer.subscription.deleted event.
H10 Engineering Token-name divergence sales-mockup (--moss) ↔ sales-app Tailwind v4 (--color-moss). Mockup-to-React port repeats the rename. Phase 1 task 1 amendment: every admin token prefixed --color-* / --font-* / --tracking-* / --radius-* / --shadow-* / --ease-* / --duration-* to match Tailwind v4 @theme inline convention. Bundle import remapped via override file (see H6). Mapping table in REGISTER-NOTES.md.
H11 Engineering No CSS namespace strategy for future monorepo collision (admin + sales tokens, .btn-primary, .shell, .panel identical names). Phase 1 task 2 amendment: wrap admin shell in [data-app="admin"] scope; mockup index.html body sets data-app="admin". All shell/component classes scoped under this attribute. Mirrors sales-app's [data-project] cascade pattern.
H12 Engineering ?as=ce URL param is undefined behaviour in static HTML (no JS) — either need a tiny script or 5× HTML duplicates per screen. Plan picks neither. NEW Phase 1 task — assets/role-switch.js (~20 lines): reads location.search, sets body[data-role="<role>"], components style via body[data-role="ce"] .lock-icon { display: inline; }. Loaded by every screen via <script src="assets/role-switch.js" defer>.
H13 Security ?as=ce is a client-side role-impersonation primitive. If React build mirrors this pattern without server-side auth, it becomes an auth-bypass (?as=owner escalation). assets/role-switch.js header comment + REGISTER-NOTES entry: "MOCKUP-ONLY. React role-preview MUST be server-issued ephemeral token, Owner+Admin only (cf. View-as-Agent §4.6). Never URL-parse role client-side in production."
H14 Security View-as-Agent admin debug tool (§4.6 of permission-and-tenancy-model) is absent from the mockup. ADR 0004 v2 classifies it as personal_content PII; React build would invent both UI + audit-entry shape. Phase 4 task 1 amendment (14-team.html): add View-as-Agent entry point (Owner-only action on Sales Agent rows). Phase 4 task 2 amendment (15-activity.html): sample entry showing View-as-Agent invocation with pii_class=personal_content badge + read-only-mode indicator + auto-revoke timestamp.
H15 Security Activity log filter design has no role-scoping rule. Sales Agent could filter by other Agents' actor IDs → lateral lead-activity disclosure. Phase 4 task 2 amendment: activity-log filter scoping legend: Sales Agents see only own actions; Sales Manager sees own team's; Content Editor sees own + content-section actions; Owner / Admin see all. Legend rendered on 15-activity.html so React build conforms.
H16 Security Pseudonymisation surface (post-12mo→7yr boundary per ADR 0004 v2) has no UX treatment. actor avatar + role chip pattern breaks when actor_user_id becomes HMAC hash. Phase 4 task 2 amendment: ≥1 sample pseudonymised entry in 15-activity.html with canonical treatment: empty avatar slot → Phosphor user-circle outline + "Archived actor · {role retained} · hash truncated" + tooltip linking to retention policy.

MED findings — documented for follow-on

# Source Finding Disposition
M1 Customers Subdomain slug live preview is friction-prone — studios pick branded names then can't change. Phase 2 task 1 sub-add: auto-suggest from Org name + "change later in Settings" inline hint (no commitment to actual change-flow design — that's onboarding-trial-mode scope).
M2 Customers Trial banner copy "to keep your team" is loss-aversion + 5 facts in one strip is dense. Resolved by H7 (verbatim from Sub-plan 2). MED finding subsumed.
M3 Customers "Open admin panel" CTA in sales-app topbar lacks visual spec. Phase 2 task 2 sub-add: HTML comment in 02-overview.html recommends labelled chip "Admin" + Phosphor gear, not avatar-menu-only. Sales-app implementation is out of scope; recommendation only.
M4 Customers Onboarding Step 3 skip-for-now → empty 02-overview state with generic "No projects yet" copy. Phase 2 task 2 sub-add: empty state references prior context — "Skipped project setup? Start with a guided 5-minute walkthrough" + link to 01-onboarding (re-entry path).
M5 Brand Onboarding + banner copy not tagged [copy:provisional]. Phase 1 + 2: every voice-bearing string carries <!-- [copy:provisional] --> HTML comment for brand-language-and-identity tone-of-voice pass.
M6 Brand 03-theme.html proposes oxblood as project-accent — collapses --status-sold semantic. Phase 3 task 1 amendment: project-accent picker excludes any --status-* hex; pulls from existing [data-project="cote/velvet/redwall"] palettes or a curated 6-stop Stone+Moss ramp.
M7 Brand Role-badge palette unspecified. Phase 1 task 3 sub-add: 5-stop role-badge token set from Stone + Moss scale (no new hues). Recorded in REGISTER-NOTES.md.
M8 Brand Wordmark is 3-asset contract (light / mark / on-dark); plan copies only 1. Phase 1 task 5: copy all three variants (wordmark.svg, wordmark-mark.svg, wordmark-on-dark.svg); on-dark used in sidebar dark surfaces if any.
M9 Brand Motion tokens unmentioned for modals / banner / drawers / tabs. Phase 1 task 3 sub-add: _components.css brief requires var(--duration-*) + var(--ease-*) for every transition: declaration. Phase 5 grep: any transition not consuming these vars flagged.
M10 CS Free Guest section in 14-team.html has no in-product explainer. Phase 4 task 1 sub-add: inline help-popover next to Free Guest header — one-line definition + link to (future) docs page.
M11 CS Phase 5 OPEN-QUESTIONS.md doesn't commit to CS-relevant gaps. Phase 5 task 4 amendment: must include post-T+30 freeze branded page (sales-app side) + pseudonymised CSV export policy + role-badge collapse on narrow viewport as OPEN-QUESTIONS items.
M12 CS Activity log retention tag is operator-facing terse. Phase 4 task 2 sub-add: info-icon next to retention tag → stub /docs/audit-retention URL.
M13 Engineering Phosphor sprite → React (@phosphor-icons/react) mapping not stated. REGISTER-NOTES.md entry: React build switches to @phosphor-icons/react; pin Phosphor 2.x for glyph parity.
M14 Engineering No @import strategy for shared CSS. Phase 1 task 1 sub-add: single admin.css entry that @imports the override file + bundle import (per H6); every HTML links admin.css only.
M15 Engineering Accessibility entirely absent. New Risks row added (see Risks section, A11Y row). Phase 5 task 1 amendment: a11y sweep using axe-core CLI run over all 15 files; semantic-HTML grep (<nav>, <main>, <aside>, aria-current on active sidebar item, role-badge ARIA, focus trap on .modal-stub).
M16 Engineering Mobile deferred but launch principle says self-serve. Phase 1 task 2 sub-add: _shell.css grid uses clamp() / container queries so 1440 desktop degrades to 1024 + 768 readable (not pixel-perfect — visual integrity only). Mobile React build = explicit follow-on.
M17 Engineering Token-only-via-var lint not promoted to hard gate. Phase 5 verification: grep -REn '#[0-9A-Fa-f]\{3,8\}' design-system/admin/_shell.css design-system/admin/_components.css returns 0. Hard gate. (HTML files allowed hex for inline images/placeholders only — exempt.)
M18 Security Privacy Policy link missing from shell + onboarding consent. Phase 1 task 2 sub-add: shell footer carries Privacy · Terms · Cookies link row on every authenticated screen. Phase 2 task 1 sub-add: 01-onboarding.html Step 4 has consent checkbox + privacy-policy link.
M19 Security Lock-icon = "show but disable" antipattern for destructive actions on other users. Phase 4 task 1 + Phase 3 sections amendment: destructive actions outside role scope hidden entirely (no lock-icon); lock-icon reserved for non-sensitive write actions where upgrade-path discoverability is valuable. _components.css comment captures the hide-vs-lock decision tree.
M20 Security Pending invitations panel exposes colleague emails + role pre-hire to Sales Agents. Phase 4 task 1 amendment: pending-invitations panel gated Owner / Admin (full view), Sales Manager (own-team invites), Content Editor / Sales Agent (hidden).
M21 Security Trial banner counters expose org commercial data (seats / projects) to Sales Agents + Free Guests. Phase 1 task 2 amendment: .shell__trial-banner accepts a data-banner-scope="owner-admin" attribute. Owner/Admin → full counters; Sales Manager / Content Editor / Sales Agent → tier label + days-left only; Free Guest → "Guest access" chip, no banner.
M22 Security Post-trial lock empty-state contract — server-side strip not opacity overlay. Phase 1 task 3 sub-add: _components.css comment for .modal-stub post-trial state documents "in React: server-side strip content payload, do NOT use opacity/blur overlays". Mockup encodes empty payload directly.

LOW findings — deferred to OPEN-QUESTIONS.md (Phase 5)

# Source Note
L1 Customers "Developer" self-signup org-type chip wrong (developers come via invite only) — drop from chips.
L2 Customers Activity log retention copy ("pseudonymised / 7-year horizon") legalese for customers — soften to "We keep 12 months of detailed history; older entries summarised. Export anytime."
L3 Brand Phosphor weight (regular) provisional pending brand-language icon decision.
L4 Brand Photographic register silent — use Stone-tinted placeholder shapes only; defer photo policy to brand workstream.
L5 Brand Persistent trial banner breaks "Moss one-per-view" — either lower to --moss-bg 10% wash or accept admin-chrome exception in REGISTER-NOTES.
L6 CS 01-onboarding.html Step 2 missing billing-address country field (Stripe automatic_tax requirement). Add as mandatory field.
L7 CS Trial banner stale-state for Stripe webhook lag — data-banner-state="stale" variant in _shell.css.
L8 Engineering Mockup-to-React component mapping table (.btn-primary<Button variant="primary">, etc.) appendix.
L9 Engineering ADR 0015 update: mockup directory stays canon, NOT deleted when React build lands (sales precedent).
L10 Engineering scripts/build-phosphor-sprite.sh — tiny shell script documenting source URLs, idempotent re-run.
L11 Security Role-badge collapse to initials on narrow viewport (screen-share sensitivity).
L12 Security CSV export must respect pii_class redaction matrix + Owner-only + self-audit-logged when implemented for real.
L13 Security Subdomain slug typing reveals tenant existence — real availability check must be rate-limited + return ambiguous "unavailable" without distinguishing reserved/taken.

Files added by SPEC-AMEND v1.1

Workstream amendments

Consolidation

Replaces

Dedup check

Touch radius


Business Review SPEC-AMEND v1.2 (CONV-37, 2026-05-11)

User feedback mid-build (Phase 2 in flight): the original 01-onboarding.html 4-step wizard pattern is methodical but loses the "wow moment" of the atelier Quick Build flow (split-screen builder with live sales-presentation preview). Real SaaS onboarding precedents (Notion / Linear / Webflow) offer a fork right after signup: fast path / methodical path / skip. Apply the same to Phase 2.

Phase 2 IA change

# Screen Was Is
00 00-welcome.html NEW. Post-signup fork screen. Hero «How do you want to start?» + 3 cards: (a) Quick Build → 01-quick-build.html; (b) Set up your organisation → 01-onboarding.html; (c) Skip to admin → 02-overview.html.
01 01-onboarding.html First-registration 4-step wizard UNCHANGED. Reached via card #2 «Set up your organisation» on 00-welcome.
01 (sibling) 01-quick-build.html NEW. Split-screen Object Builder modelled after atelier mockup. Left column (~580px): wordmark + Trial chip + eyebrow «OBJECT BUILDER · QUICK BUILD» + h1 «Name your project» + project name + subdomain w/ availability check + 3 required uploads (Exterior / Floor Plans / Gallery, numbered i/ii/iii) + SAVE & CONTINUE primary + SKIP ghost. Right column (flex-1): «LIVE PREVIEW · cote-residence.offplan.online» strip + Desktop/Tablet/Mobile toggle + sales-presentation preview frame using [data-project="cote"] + .project-themed cascade to demonstrate per-project brand-contract — sage-leaning marine accent, hero with project name + price + meta. Bottom dock: «Floor Plans · awaiting upload» + «Gallery · 0 of 12 images uploaded» (mirroring the upload-state of the left column).
02 02-overview.html Workspace landing UNCHANGED. Reached via card #3 «Skip» on 00-welcome OR after completing 01-onboarding OR after Save&Continue on 01-quick-build.

Reasoning

Files added by v1.2

Workstream amendments

Verification (per v1.2)