Commit Graph
60 Commits
Author SHA1 Message Date
thePR0M3TH3AN b980215f15 Add creator premium epoch refresh action 2026-07-04 16:39:42 -04:00
thePR0M3TH3AN 37d871431b Make premium claim windows manual close by default 2026-07-04 16:34:23 -04:00
thePR0M3TH3AN e0e7755cf5 Document Premium 2.0 purchase flow 2026-07-04 16:16:03 -04:00
thePR0M3TH3AN 92c41442dc Plan and scaffold Premium 2.0 purchase copies 2026-07-04 14:55:02 -04:00
thePR0M3TH3ANandClaude Opus 4.7 b6b00c09f1 docs: J4.c.3 status note + implementation status table
Reader Mode reuses renderBookDesignedPageToCanvas, which the J4.c.2
commit already updated to render threaded chapter text. So J4.c.3
is implicit — no code change needed beyond what J4.c.2 shipped.

Adds an 'Implementation status' table to the spec so anyone reading
the doc later can map phase labels to actual commits + see what
still pends.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-06-04 20:35:56 -04:00
thePR0M3TH3ANandClaude Opus 4.7 79c89101c4 docs: Phase J spec — Linked Content + threaded text frames
Drafts the next architectural arc for the Book Designer around two
ideas:

- Events are linked files. Generalizes the pin-vs-live toggle
  shipped for chapters to every external reference. A new
  book.links[] collection becomes the project's 'Links panel'
  (chapters, masters, pages, illustration sets, future asset kinds).
- Threaded text frames (InDesign-style). First-class text-frame
  layers on designed pages, threaded port-to-port; a thread
  declares a content source (a linked chapter event) and the
  pagination engine pours text through the frame chain.

The current 'reflow entries in book.pages' model collapses into
links[] + threads[] + auto-generated designed pages — a one-time
migration on load. Pagination engine, PDF export, Reader Mode,
Linked Designs resolver, and NIP-23 chapter events all survive.

Phasing J1..J6 captured in the spec + TODO. No code yet — this is
just the design doc and arc placement.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-06-04 15:36:45 -04:00
thePR0M3TH3ANandClaude Opus 4.7 f50d92043c docs: add BOOK_DESIGNER_TUTORIAL.md
Hands-on end-to-end walkthrough for the Book Designer feature —
setup, starting a book (templates / deck-import / scratch), Document
settings, masters + text-frame, Pages overview, designed-page editor,
chapter editor (full feature exercise: tables, task lists, footnotes,
xrefs, {toc}, {index}, ^[term]), cover view, visibility chip,
publishing order, resolver behaviour, Reader Mode, embed integration,
PDF export modal, tokens reference, edge cases to probe, and a
codebase map.

Companion to docs/BOOK_DESIGNER_FEATURE.md (the spec).

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-06-04 08:41:25 -04:00
thePR0M3TH3AN 2f5167054b docs(book): polish pass — schema consistency + MVP path + missing acceptance
Final spec polish after the markdown / NIP-23 revision.

Schema consistency:
- Manifest entries now carry a stable opaque `id` (generated at
  insert time). Used for anchoring designed pages around reflow
  segments — anchors reference `entryId` instead of fragile array
  positions or human-readable strings.
- Unified `masterRef` across designed and reflow entries (was
  `inheritsMasterRef` on designed, `masterRef` on reflow). Both
  default to `spec.defaultMasterRef` when null.
- Promoted `AnchorBlock`, `GatingBlock`, `TextStylesBlock`,
  `TypographyObject` to named definitions in the data-model block
  so the schema is documented once and referenced from prose.
- Page event `d`-tag pinned to a stable opaque id, not derived from
  the page title (titles change; d-tags shouldn't).
- Added uniqueness rules: a chapter or page event can appear in at
  most one manifest entry per book; every entry has a unique `id`.

New sections:
- **Chapter event example** (kind-30023 NIP-23 article) so the
  full event shape is documented alongside page / master / cover.
- **Schema + compatibility** — bump to SCHEMA_VERSION 6,
  additive on the project payload, with the documented fallback
  for older clients.
- **Privacy** — confirms PRIVATE_PUBLISHING works across all
  constituent events of a book.
- **Compatibility notes** — Linked Designs inside pages works
  via existing async resolver (worth a Phase B smoke test); all
  existing layer types render on book targets.
- **MVP launch path** — two reasonable launch targets:
  MVP-A (designed-only books, Phases A+B+D1+D2) and MVP-B
  (books with prose, MVP-A + C+C.5+E). Phases F/G/H/I are strict
  enhancements that don't block either MVP.

Tightened semantics:
- **Token substitution scope** explicitly limited to (a) text
  layers and (b) reflow-entry display fields. Markdown bodies of
  chapter events stay portable to other NIP-23 clients — no
  book-specific tokens leak in.
- PDF section: removed outdated "may flatten text to vector
  paths" notes — the font allowlist + per-export warning is now
  the committed approach. Reflowed prose and designed-page text
  emit as real PDF text uniformly.
- PDF outline / bookmarks moved out of "limitations" — they ship
  in Phase I built from `chapterTitle` and `{toc}` targets.

Cleaned Open Questions: removed answered items (TOC token is now
Phase I, Linked Designs interaction moved to Compatibility notes).

Added missing acceptance criteria for Phase F (templates +
deck-to-book import) and Phase I (CodeMirror + extended subset +
auto-TOC + cross-references).
2026-06-02 10:53:53 -04:00
thePR0M3TH3AN 7383b98cf9 docs(book): fold reflowable text + markdown + NIP-23 into the spec
Third revision pass adds reflowable prose as a first-class part of
the Book Designer, without giving up the fixed-layout design pages.

Architecture:
- Prose chapters live as NIP-23 long-form articles (kind-30023,
  markdown body). One source, two presentations: same article event
  is readable standalone on Habla.news AND laid out as designed
  pages inside a book on Artstr Studio.
- Book manifest's `pages` becomes a discriminated union:
  `{ type: 'design', ref }` for fixed-layout pages, and
  `{ type: 'reflow', textRef, masterRef, … }` for chapter segments
  that paginate dynamically.
- New `text-frame` layer kind, lives on masters. The pagination
  engine pours markdown tokens into copies of the master until the
  chapter is exhausted.
- New `spec.textStyles` block — a book-level stylesheet mapping
  each markdown element (h1-h6 / body / blockquote / code / list /
  link / hr) to typography (font, size, weight, leading, alignment,
  margins, plus keepWithNext / keepTogether flow controls).
- Anchored designed pages: designed entries on the manifest use
  `anchor.mode: 'before-chapter' | 'after-chapter'` so their
  semantic position survives reflow-driven page-count changes.

Tradeoff mitigations baked in:
- Pagination is fiddly → tight v1 markdown subset documented;
  pure-function engine for testability; "Preview pagination" before
  publish; overflow toasts for too-long words / wide code blocks.
- Text drift breaks pagination → chapters pin to a specific event
  id by default (safe for print); opt-in "Live" mode for
  always-latest with re-paginate notices showing page-count delta;
  anchor-based positioning for designed pages.
- PDF text fidelity → reflowed prose exports as real PDF text via
  pdf-lib font subsetting; font allowlist with vector-path
  fallback + per-export warning.
- Editor scope → plain textarea + live preview for v1; CodeMirror
  upgrade deferred to Phase I; WYSIWYG never in scope.

New tokens: `{chapter-title}`, `{chapter-number}` resolve per
chapter context (useful for running headers on masters).

Phases updated:
- Phase C grows `text-frame` layer kind (structural).
- New Phase C.5 — vendor `marked`, implement pagination engine,
  markdown editor pane, anchoring, pin/live tracking. Slots in
  before PDF export because PDF needs it.
- Phase D1 expanded to include chapter publish as kind-30023.
- Phase E updated for real PDF text on reflowed prose.
- New Phase I — extended markdown subset (tables, footnotes,
  auto-TOC via `{toc}`, cross-references) + CodeMirror editor.

Pages overview tile UX expanded: designed-page tiles show a
rendered thumbnail; reflow tiles show a stack-of-pages icon with
chapter title, master name, paginated page count, and a tiny
first-page preview.

Acceptance criteria for Phases C, C.5, D1, E updated to match.

TODO.md summary rewritten to reflect the new shape.
2026-06-02 10:47:42 -04:00
thePR0M3TH3AN 33ee2b7ec5 docs(book): rewrite spec around Nostr-native sidecar architecture
Apply twelve Nostr-driven revisions to the Book Designer spec:

1. **Sidecar architecture.** Pages, masters, and the cover spread
   are now separate addressable kind-30078 events
   (`casewrap-page`, role-discriminated). The book is a thin
   `casewrap-book` manifest that references them by
   `{ kind, pubkey, dTag }` — the same shape Linked Designs
   already speaks. Edit one page → that page event replaces; the
   manifest only changes when order / list / spec moves.
2. **Masters as Nostr objects.** Each master is its own event; one
   "Body pages" master can be referenced by many books and forked
   by other authors. Default master lives on the manifest spec.
3. **Cover as a sidecar event** with `role: 'cover-spread'` so it
   can iterate independently and be republished as standalone
   marketing art.
4. **Linked Designs is the precedent.** The resolver IIFE,
   progressive fetch, localStorage disk cache, batched relay
   queries, upstream-update notifications, and attribution chain
   all transfer verbatim. Call this out explicitly so we don't
   reinvent the wheel.
5. **Addressable refs everywhere.** Manifest entries use the
   existing `{ kind, pubkey, dTag }` form (convertible to naddr at
   the UI layer), not local UUIDs.
6. **Premium gating + tips.** New "Premium, tipping, gating"
   section covers whole-book paywall (gate the manifest),
   per-chapter paywall (gate individual page events via
   PREMIUM_DESIGNS), and NIP-57 zaps at any granularity.
7. **Reader Mode** added as Phase G — the Slide Decks' Presenter
   Mode counterpart, with progressive page fetch, TOC sidebar,
   page-flip nav, and inline zap-to-unlock.
8. **Embed integration.** EXTERNAL_EMBED learns `?book=<naddr>`
   for a flip-book iframe player; same transport + CSP rules.
9. **Per-page reactions / comments** work for free because each
   page is its own addressable event (NIP-25 + kind-1). One-liner
   in product goals + Reader Mode acceptance.
10. **`{page-count}` semantics pinned.** Defaults to *numbered*
    pages; new `{physical-page-count}` exposes the raw total.
    Plus `{book-author}` for the manifest pubkey.
11. **NIP-23 distinction.** Explicit non-goal — Book mode is
    fixed-layout design, not reflowable prose; for prose use
    NIP-23 long-form articles directly.
12. **Manifest schema.** Pages now carry
    `{ ref, label?, inheritsMasterRef, skipNumber, gating? }`;
    page-side fields that vary per-book (master, skipNumber,
    label) moved off the page event onto the manifest entry.

Phase D split into D1 (publish individual page / master / cover
events) and D2 (publish the manifest); new Phase G (Reader Mode +
embed); new Phase H (premium gating). Acceptance summary,
cross-surface reactivity, and risks updated to match.

TODO.md's Book Designer summary rewritten to reflect the
sidecar plan.
2026-06-02 10:36:40 -04:00
thePR0M3TH3AN 50eed8c017 docs: spec the Book Designer (unified cover + pages + PDF export)
New BOOK_DESIGNER_FEATURE.md drafts a top-level templateMode: 'book'
that orchestrates the existing cover designer, deck overview, and
custom-art canvas around a shared document spec (trim size, page
count, paper thickness, bleed). Spine width derives from page count
× paper thickness; the cover view goes read-only on the spine
column when in derived mode. Pages reuse the deck-sorter UI for
reordering; the per-page editor is the custom-art canvas bound to
a book-page:<id> target with prev / next page nav. Masters render
underneath each inheriting page and support {page-number} /
{page-count} / {book-title} token substitution.

PDF export ships in its own phase (E), backed by a vendored
pdf-lib (~80 KB). Single-file (cover + interior) and split (cover
PDF + interior PDF) output modes; bleed + crop-mark options;
v1 flattens text to vector for font-fidelity, with vector PDF
text as a follow-up.

Phased: A (spec + skeleton) → B (pages + editor) → C (masters) →
D (publish) → E (PDF export) → F (templates + deck-to-book
import). Non-goals: reflowable text, footnotes, automatic TOC,
CMYK / ICC, imposition, mixed page sizes in one book.

Linked from README's "Drafted-but-unbuilt" list and TODO.md.
2026-06-02 10:29:01 -04:00
thePR0M3TH3AN 5b0eec1a1a docs: log the Illustrator parity arc + follow-ups
PEN_TOOL_FEATURE.md gets a 2026-06-02 status block documenting
everything that landed on top of Phase D — Direct Selection split,
auto-add/auto-delete, click-vs-drag convert, Alt-click curved ↔
pointed, multi-anchor select / marquee / arrow nudge, drag-segment
bow, continue-endpoint, spacebar reposition, Alt mid-draw, handle
break, Cmd+J / Cmd+Alt+J, Path Actions side panel — plus the
adjacent design-tool features that shipped in the same arc
(Eyedropper, Align & distribute, Free Transform rotation,
Pathfinder, marquee box-select, dive-into-edit on dbl-click).

TODO.md gets a "Design-tool follow-ups" section listing the gaps:
Smart Guides, Gradients + shadows, Scissors / Outline text /
Command palette, Flip H / V (needs renderer scaleX/scaleY),
Pathfinder rotation support, pixel-art frame timeline.
2026-06-02 09:53:06 -04:00
thePR0M3TH3AN b825181356 Pen tool Phase D close-out: add/delete anchor, smooth/corner, bbox refit
Finished the deferred Phase D pieces from PEN_TOOL_FEATURE.md.

New affordances on the editable pen layer:

- Click a segment between anchors → inserts a new anchor at the
  click point via de Casteljau cubic split. Curve shape is
  preserved exactly: a's hOut, b's hIn, and the new mid-anchor's
  handles all derive from the split. Lines (no handles either
  side) get a plain midpoint anchor with no handles. The new
  anchor is selected and immediately drag-able.
- Right-click an anchor → delete it. Suppresses the browser
  context menu on the pen overlay always.
- Backspace / Delete with an anchor selected → delete it.
  Layer-delete still wins when no anchor is selected. The pen
  tool's selected-anchor sentinel `_penSelectedAnchor` is reset
  on tool change.
- Alt-click an anchor → toggle between `kind: 'corner'` (handles
  move independently) and `kind: 'smooth'` (handles stay mirrored
  across the anchor). Promoting to smooth re-derives the missing
  handle (or re-mirrors both if independent) so the curve
  actually becomes continuous. New nodes from pen click-drag
  default to smooth; new nodes from a single click are corners.
- Drag an anchor or handle past the original 0–100 viewBox →
  the layer's bounding rect auto-refits. New `refitPenLayerIfNeeded`
  computes the bbox over all nodes + handles, translates
  layer.x/y by the bbox offset (scaled to current w/h), updates
  layer.w/h, then remaps every node into the new 0–100 space.
  Path stays visually anchored to the canvas — no more clipping
  at the layer edge.

Anchor glyphs now distinguish kind: smooth = circle (existing
look), corner = square. The selected anchor renders with an amber
stroke (#f97316) so the Backspace-to-delete target is unmistakable.

Spec updated to mark Phase D complete and the deferred items
shipped. Rotated paths are still not node-editable in v1 (the
deferral remains).
2026-06-01 16:25:38 -04:00
thePR0M3TH3AN 007ad1d1e2 Cleanup: drop superseded specs + refresh README
Removed three superseded spec files now that the work they
described is either shipped (under newer specs) or formally
replaced:

  docs/ZAP_GATED_TEMPLATES_FEATURE.md
  docs/ZAPS_NWC_FEATURE.md
  docs/ZAP_GATED_PREMIUM_FEATURE.md

The history is preserved in git. The current canonical premium
plan is docs/PREMIUM_DESIGNS_FEATURE.md (which absorbed the
zap-gated+NWC infrastructure plus added the soft-gate KDF +
encrypted envelopes + purchase vault).

README's docs paragraph now lists every active spec by status —
shipped / partial / drafted — and adds the transparency-iframe
baseline stub that landed alongside the embed feature.
2026-06-01 16:11:35 -04:00
thePR0M3TH3AN c1ac849219 External embed spec: mark shipped + drop Phase 8
The embed feature is essentially complete — phases 0-6 are live
on main, Phase 7 hardening shipped alongside Phase 1. Updated
the spec to reflect that:

- Status block flipped from "Nothing in this spec is implemented
  yet" to "Shipped (2026-06-01)" with date.
- Every shipped phase gets a ✅ marker on its heading.
- Phase 7 (Hardening + headers) body rewritten to record what
  actually shipped (CSP frame-ancestors, SPA rewrites, error
  handling, sanitization reuse) plus what's still optional
  (?debug=1 surface, hard relay-count cap).
- Phase 8 (Polish) deliberately dropped — the previously-drafted
  Credits overlay, postMessage handshake, and explicit
  light/dark/auto theming weren't needed for the use cases the
  feature is actually solving. Replaced with a clear "dropped"
  note listing each item and why.
- Phase 9 (Future) reframed as the natural follow-up arcs if we
  revisit (oEmbed endpoint, render-to-image, OG images,
  lightweight embed.html bundle).

The Acceptance Criteria for Embed v1 stays valid as-is — every
bullet is true.
2026-06-01 15:58:05 -04:00
thePR0M3TH3AN 4d355f87d4 External embed: draft v2 spec
Updated rewrite of the earlier embed plan covering every Artstr
feature shipped since the original sketch:

- Linked sub-design resolution inside embeds (reuses
  linkedDesigns.prefetchBatch + resolveLinked + disk cache, full
  cycle/depth/byte safety).
- Premium boundary: watermarked preview + "Open in Artstr to
  unlock" CTA; no in-iframe zap.
- Private boundary: hard refuse with 🔒 placeholder; no decrypt
  attempts.
- Pixel-art animation playback (auto-play, fps override,
  prefers-reduced-motion respected).
- Deck slide picker — `?slide=N` deep-links; linked-deck layers
  carrying design.slideIndex project to a single-slide payload.
- Credits overlay (opt-in via `?credits=1`), mirroring the
  in-app Credits panel.
- PostMessage handshake for parent-page integration (deck
  control, fullscreen request, ready/error events).
- Layer-group handling falls out naturally — groups are flat
  layers with groupId; the existing renderers already paint them.
- Open Graph metadata on the embed route URL itself.
- Per-event + per-tree byte caps inherited from linked-designs.
- Phase plan + acceptance criteria + risks updated.

No code; this is the planning artifact. Implementation phases
0-9 are scoped inside the doc.
2026-05-31 22:46:16 -04:00
thePR0M3TH3AN f8cf8570f2 Linked Designs spec: tighten before implementation
Second-pass review surfaced eight issues worth pinning down before
we start coding. Each addressed in-place rather than as a TODO so
the implementation has a clear target:

1. §5.1 — Persisted vs in-memory fields. The host's serialized
   `content` was implicitly inflating with `fallbackPreview`,
   `lastResolvedAt`, `lastResolvedSize` from the initial schema.
   Now explicit: only `kind` / `ref` / `mode` / `pinnedEventId` /
   `pinnedSnapshot` persist; the rest are runtime-only and stripped
   at publish time. A linked layer footprint is ~110 bytes serialized.
2. §6.1 — Pinned + source deletion. New section covering the case
   where the source author kind-5-deletes a pinned event. Adds a
   `pinnedSnapshot` field that the renderer prefers-live-falls-back-
   to-snapshot, plus the existing `fallbackPreview` for visual-only
   fallback. Default = pin without snapshot, user opts in for
   permanence.
3. §8.1 — Sync vs async render decision. The renderer is synchronous
   today; this section explicitly picks "sync placeholder + async
   upgrade" over "block render" or "pre-fetch all". DOM tagging +
   abort-on-detach behaviour documented so the implementation
   doesn't end up re-deciding mid-build.
4. §8.2 — Autosave + cold start. localStorage restore loses in-memory
   resolver state, so on `restoreAutosave` we kick off the resolver
   for every linked layer in the background.
5. §10.3 — Embedded → linked attribution: corrected an inaccurate
   claim. Embedded layers don't carry source-author metadata, so
   "Publish + link" credits the CURRENT user, not whoever originally
   authored the embedded content. Action copy should warn explicitly.
6. §12.1 — Premium-link access check: clarified that the gate is the
   host viewer's purchase-vault entry (not technical decryption
   capability, since the soft-gate KDF is deterministic).
7. §13 — Added a per-tree cap (1 MB total resolved payload per host
   render) on top of the per-event cap. Depth-3 fan-out could
   theoretically multiply fetches; the tree cap stops a coordinated
   DOS at the host level.
8. §11.5 — Picking initial layer dimensions for a new linked layer
   (sync resolver lookup with a 1.5 s timeout, falls back to 16:9
   default). Plus a link-creation modal preview so the user can
   confirm what they're linking before commit.

Also tightened the Phase 1 acceptance criteria around serialized
size: explicit budgets for 10-link host events and verification that
in-memory fields are stripped at publish.
2026-05-31 16:38:26 -04:00
thePR0M3TH3AN 87dd9426c2 Draft Linked Designs spec
Spec for the next big arc: reference-based cross-design imports.
Adds a `kind: 'linked'` flavor of the existing design layer that
stores only a NIP-01 addressable-event coordinate
(30078:<pubkey>:<dTag>) and resolves to the latest source on
render. Sits alongside the existing embedded import path; user
picks at import time.

Key decisions baked in (per scoping conversation):

- Versioning: always-latest by default, with an opt-in "Pin to
  this version" toggle exposed per linked layer.
- Nesting: up to 3 levels deep with cycle detection + visible
  depth-exceeded placeholders.
- Encrypted: Phase 1 ships public-only; Phase 2 adds premium
  (renders if viewer's unlocked) and private (share-list aware).
- Attribution chain is first-class — host publish emits one
  ['p', '<contributor pubkey>', '<relay-hint>', 'design-contributor']
  tag per distinct linked-tree creator, plus an in-app Credits
  panel surfacing co-creators. Lets larger collaborative projects
  carry honest attribution natively.

Architectural shape:

- Resolver IIFE (linkedDesigns) with session cache, multi-relay
  union (mirrors _vaultRelayUnion), and a manual Refresh button
  to bypass cache.
- renderDesignObjectIntoElement gets a linked branch that calls
  the resolver before the existing render path.
- Layer-options panel exposes pin / refresh / unlink / replace.
- "Publish + link" action converts an embedded layer to a freshly-
  published source + linked reference (Phase 3 polish).
- Convert-back-to-embed action snapshots the current resolution.

Phased implementation:

- Phase 1: Public-only linking, schema, resolver, rendering, UI.
- Phase 2: Premium + private link resolution with access control.
- Phase 3: Disk cache, attribution `p`-tag emission, Credits panel,
  Publish + link workflow.

Acceptance criterion for Phase 1: a public cover design linked into
a public slide deck renders correctly; editing the source updates
the host's render on next refresh. 10-link host event stays under
typical relay size limits.

Outstanding open questions to revisit during implementation:

- Whether the depth limit should be 3 forever or configurable.
- Whether the 256 KB per-source payload cap is the right number.
- Whether to surface "last resolved" times in the layer name itself
  or only on hover.
2026-05-31 16:38:26 -04:00
thePR0M3TH3AN 5422f2c3e8 Draft PPTX chart-import spec
Spec for the next big arc: replacing the current chart-placeholder
behaviour (single image layer at PPTX_IMAGE_PLACEHOLDER_URL) with
native rendering — bars / wedges / lines as Artstr shape layers,
labels as text layers. Branch pptx-chart-spec.

Scope decisions baked in:

- Phase 1: clustered column + bar charts only. Bars as rect shape
  layers, category labels as text. Plot area derived via a fixed
  inset on the chart's graphicFrame bounding box (no
  c:manualLayout reading until Phase 4).
- Phase 2: pie / doughnut. Slice geometry emitted as kind:'path'
  with SVG arc d-attributes.
- Phase 3: line charts with optional markers.
- Phase 4: title / legend / data labels / value-axis ticks /
  gridlines.
- Phase 5: stacked + percent-stacked variants.
- Deferred to placeholder: scatter, bubble, area, radar, 3D,
  combo charts, trendlines, error bars, per-point overrides.

Architecture:

- New src/pptx-importer-charts.js with the per-type builders,
  loaded as an addendum to pptx-importer.js (or inlined — TBD
  during implementation; the dependency budget is small enough
  that a single file might be cleaner).
- convertGraphicFrame in pptx-importer.js gets a "try native
  before placeholder" branch: parse chart XML, dispatch on type,
  fall through to the existing placeholder + warning when the
  builder returns null.
- All chart data read from c:strCache / c:numCache. The embedded
  ppt/embeddings/*.xlsx workbook is ignored — caches are reliable
  in OOXML output and reading XLSX is its own rabbit hole.

Acceptance criteria for Phase 1: gallery_template_layout_set.pptx
slide 10 imports with 8 native bar layers (#5E735D + #B05A44
clustered across Q1-Q4) plus 4 category-label text layers,
matching what PowerPoint shows. Scatter / 3D / etc. still
placeholder cleanly without crash.
2026-05-30 08:57:12 -04:00
thePR0M3TH3AN 38894031bf Mark Phase 6 done in PPTX spec 2026-05-29 15:37:52 -04:00
thePR0M3TH3AN 1d0239f022 Mark Phase 5 done in PPTX spec 2026-05-29 15:26:55 -04:00
thePR0M3TH3AN d355c21792 Mark Phase 3 done in PPTX spec 2026-05-29 15:20:38 -04:00
thePR0M3TH3AN 8cf79f0fe0 Mark Phase 2 done in PPTX spec 2026-05-29 15:13:27 -04:00
thePR0M3TH3AN 5d86d9ced7 Mark Phase 4 done in PPTX spec 2026-05-29 15:01:13 -04:00
thePR0M3TH3AN 71e5370e36 Mark Phase 1 done in PPTX spec 2026-05-29 14:33:29 -04:00
thePR0M3TH3AN 24fb160e99 Mark Phase 0 done in PPTX spec; pausing for vault-fix work on main 2026-05-29 13:54:10 -04:00
thePR0M3TH3AN 467fbcf5e4 Draft PPTX import spec
Adds docs/PPTX_IMPORT_FEATURE.md as the canonical plan for the next
big arc: a phased editable .pptx importer that lands PowerPoint decks
as editable Artstr deck JSON.

Key decisions baked in:

- Images and unsupported objects (charts / SmartArt / tables / video)
  import as placeholder image layers pointing at a hardcoded URL
  (postimg.cc for now). Original PowerPoint media filenames carry
  over into the layer name so the user can correlate placeholders
  with their source deck.
- fflate (~10 KB) vendored as src/vendor/fflate.min.js. JSZip is too
  heavy for the single-file ethos.
- Importer code lives in src/pptx-importer.js as an IIFE that
  exposes window.ArtstrPptxImporter. The Import PPTX button
  dynamically injects both scripts on first click, so the main
  index.html bundle does not grow for the 90 % of users who never
  import a PPTX.
- Notes folded into Phase 2 alongside text (single extra relationship
  lookup, Presenter Mode already renders slide.notes).
- No Blossom / NIP-96 prereq, no base64 bloat, no publish-size guard.
  Imported decks are normal Artstr deck payloads with remote URLs.
- Import-only for this arc. PPTX export (Artstr -> .pptx) is a
  separate later arc with its own complexity.

TODO.md gets a Drafted-but-unbuilt entry pointing at the new spec.
2026-05-29 11:21:54 -04:00
thePR0M3TH3AN 3b47a314c0 Catch up TODO + README + spec banner on the premium-templates arc
Pre-merge docs sweep before zap-gated lands on main:

- TODO.md: move Premium out of "Drafted-but-unbuilt" into "Shipped
  (recent)" with a full summary of what landed (soft-gate, watermarked
  previews, NWC split-zap with 30% platform fee, purchase vault with
  auto-split, profile menu, login picker, Settings, mobile polish).
  Leave Phase 4 E2E + a few confirm()-modal replacements as a new
  "Premium-templates polish" section.
- docs/PREMIUM_DESIGNS_FEATURE.md: flip the status banner to
  "Shipped on zap-gated, merged into main 2026-05-29" and map each
  spec step (0-4) to where it lives in src/.
- README.md: add a Premium encrypted designs section; mention NWC,
  vault, login picker, profile dropdown, and Settings modal in the
  Nostr / Lightning sections; drop "NWC zaps / zap-gated templates"
  from the unbuilt list in the Files section.
2026-05-29 10:37:27 -04:00
thePR0M3TH3ANandClaude Opus 4.7 7da0c9d97c Adopt static soft-gate + buyer purchase vault spec as canonical premium model
In live testing, the tag-only gate shipped in Phases 0–3 turned out
to be too leaky: the design payload was published in plaintext, three
separate import paths (feed-card Use/Fork, preview-pane Use/Fork,
preview-pane Save JSON) bypassed the lock, and any non-Artstr client
could ignore the tag entirely. Adam pulled back the original detailed
spec he wrote earlier — the static soft-gate + buyer purchase vault
model — which solves the protection gap WITHOUT requiring a creator-
online bot (the route I was about to build).

Key idea: the AES key derives deterministically from
HKDF-SHA256(softGatePepperForEpoch(epoch), publicDesignSalt, info =
"artstr-softgate-v1" + epoch + creatorPubkey + premiumAddress +
schemaVersion). The pepper lives in the static client (obfuscated,
not secret). The client refuses to derive the key until valid kind-
9735 receipts confirm the split zap. Same key for every buyer; no
creator-online requirement; cross-device unlock via a NIP-44 self-
encrypted purchase vault (kind-30078, d=artstr:purchase-vault:v1).

Files:

  - docs/PREMIUM_DESIGNS_FEATURE.md (new, canonical) — the full
    soft-gate + split-zap + purchase-vault spec. Sections 1–17 are
    the original spec verbatim. Section 18 maps the shipped Phases
    0–3 to the spec's implementation-plan items (10.0–10.6) so the
    next contributor sees what's done. Section 19 lists the
    remaining work in build order: soft-gate crypto primitive →
    watermarked preview → premium publish event → premium consume
    → receipt fast-path by address → purchase vault → My Purchases
    UI → hardening + copy.

  - docs/ZAP_GATED_PREMIUM_FEATURE.md — banner now points at
    PREMIUM_DESIGNS_FEATURE.md as the canonical going-forward doc.
    The obsolete Phases 5/6 (DM-delivery key flow) I sketched
    earlier today are removed; the "Content model (CORRECTED)"
    section is trimmed and points at the new spec. The file is
    kept for Phases 0–3 history, the NWC/tip integration notes,
    and the threat model that still applies.

  - docs/ZAP_GATED_TEMPLATES_FEATURE.md and ZAPS_NWC_FEATURE.md
    keep their "superseded" banners pointing at
    ZAP_GATED_PREMIUM_FEATURE.md (which itself now points at
    PREMIUM_DESIGNS_FEATURE.md) — chain of provenance preserved.

  - TODO.md: drafted-but-unbuilt entry rewritten to describe the
    final shape (encrypted + vault + honest soft-gate framing) and
    point at the new spec; references the older docs for the
    shipped foundation.

No code changes yet — the spec adoption is the gate. Next commits
implement the soft-gate crypto primitive, the watermarked preview,
and the premium publish path.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-28 15:20:31 -04:00
thePR0M3TH3ANandClaude Opus 4.7 3e75b562a0 Tighten zap-gated spec after a review pass — 8 substantive gaps + polish
Critical additions:

  1. Relay fast-path. Zap receipts live on relays forever — querying
     for matching receipts on feed load means a cache-wiped user (or
     a new device) restores their unlocks for free. Also auto-detects
     a half-failed unlock that eventually settled.

  2. NIP-47 capability discovery via kind-13194. We subscribe to the
     wallet's info event on connect and verify pay_invoice is
     supported before allowing the user to proceed.

  3. Wallet-budget-exhausted handling. Special-case QUOTA_EXCEEDED /
     BUDGET_EXCEEDED so we say "raise your wallet's NWC budget" not
     a generic failure. Also surface this guidance in the CoinOS
     setup flow itself ("set a budget that comfortably covers the
     unlocks you expect").

  4. Preimage = proof of payment. Decouple unlock UX from kind-9735
     receipt arrival. The preimage hashes to the bolt11's payment
     hash; that's all we need to mark unlocked locally. Receipts
     become async verification.

  5. nwcLookupInvoice for double-spend protection. Before paying any
     leg on retry, check whether the wallet already settled it.
     Combined with PARTIAL_UNLOCK_KEY persistence (now storing bolt11
     + paymentHash, not just receipt id), this means cross-session
     retries never double-charge.

  6. LNURL minSendable checks. Block at publish time if the creator's
     LNURL won't accept their split share (with a corrective hint
     showing the minimum viable zap-min). Same defensive check on
     the platform side.

  7. Parallelize the dual-zap. Sign both zap requests in Promise.all,
     fetch both bolt11s in parallel, then pay sequentially with
     creator first. Roughly halves the user-facing latency.

  8. Partial-unlock persistence + banner. If the user closes the tab
     mid-unlock, on next visit a top-bar banner offers Resume or
     Discard for unfinished unlocks.

Polish:

  - Phase 0 bumped 2-3h → 3-5h (noble subset inlining is genuinely
    more work than that estimate).
  - NWC URI parser now handles multiple relay params, URL-encoded
    secrets, optional lud16 param.
  - "Wallet alias from get_info" instead of misleading "walletDomain".
  - CoinOS deep link to coinos.io/settings/connect.
  - Mobile copy-paste note.
  - Three new threat-model rows: platform-pubkey exposure (intentional),
    budget-exhausted-mid-flow (precise retry prompt), and forged-
    receipt fast-path (signature verification).
  - Two new open-questions: pay-above-min unlocks (creator-only
    bonus), currency display.
  - Phase 4 ship gate: "documented in commit message" since we push
    straight to main, no PR workflow.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-28 13:11:34 -04:00
thePR0M3TH3ANandClaude Opus 4.7 419d816212 Draft zap-gated + NWC + platform-split merged spec; supersede the two old drafts
The original ZAP_GATED_TEMPLATES_FEATURE.md said "no platform fee, no
backend" — that's exactly the opposite of what we actually want to
ship. ZAPS_NWC_FEATURE.md was scoped as a general tip upgrade,
listing splits as a "future enhancement." For our purposes the two
are a single arc, with NWC being the only thing that gives the
mandatory creator/platform split a tolerable UX.

ZAP_GATED_PREMIUM_FEATURE.md is the new canonical plan:
  - 5 phases (0 crypto bundle, 1 NWC, 2 platform-fee plumbing,
    3 zap-gated UI, 4 E2E + edge cases). ~16-23h total.
  - 30% platform fee, single-constant for easy adjustment later.
  - PLATFORM_NPUB hard-coded; lud16 resolved dynamically from the
    npub's kind-0 each session (so the lightning address can change
    later without a code update).
  - CoinOS recommended via a guided "Set up with CoinOS" path in
    the wallet-connection modal; generic "paste any NIP-47 URI"
    fallback for Alby Hub, Mutiny, Phoenix, Cashu.me, etc.
  - Idempotent retry of partial unlocks via localStorage receipt
    tracking — creator-leg pays first so a half-failed unlock at
    least pays the creator.
  - Explicit threat model + non-goals (no creator-only fallback,
    no refunds, no bolt11-QR fallback path).

The two old specs are marked superseded with a banner at the top so
historical context is preserved without future contributors getting
crossed wires. TODO.md drops them from the drafted-but-unbuilt list
and points to the merged doc; it also fixes the stale Private
Publishing entry — Phases 1 & 2 already shipped in 3e6e89e, only
Phases 3 & 4 remain.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-28 12:49:52 -04:00
thePR0M3TH3ANandClaude Opus 4.7 6a1352904e Docs: ship pixel-art Phases A–D, prune stale TODOs, update README
PIXEL_ART_FEATURE.md: rewrite Implementation status to reflect that
Phases A–D all shipped (embedded layer, standalone design, raster
export + editor extras, animation, image → pixelize), with the
backlog (WebP/APNG, Blossom offload, animated pixel layers driving
Stack actions) called out as deferred.

TODO.md: drop stale items now that they're resolved —

- Pixel Art (moved to a "Shipped (recent)" section pointing at the
  spec doc).
- Pixel editor layout expansion (subsumed by the collapsible
  sidebar — both the pixel editor and vector canvas can now use
  the full viewport width).
- Print / Save event ID wrapping (the `<dd>` already uses
  `overflow-wrap: anywhere; word-break: break-word`).
- TMDB auto-fill cleanup (the doc was already deleted).

The Color picker fixes item is kept but narrowed to the vector
tools — the pixel editor's in-app HSV picker shipped in Phase A.

README.md: add Pixel Art everywhere it's relevant —

- One-liner mention in the intro paragraph.
- New "Pixel art" Designer-tab layout entry alongside Slide / Disc
  design.
- `pixelart` layer type added to the Layers list.
- New dedicated "Pixel art" section before Editor canvas, covering
  tools / transforms / animation / export / import / undo /
  animated previews.
- Editor canvas section mentions the new sidebar collapse toggle.
- Schema section lists `pixelart` template mode and layer type,
  documents the `pixelArt` data-model shape, and notes that the
  inline GIF89a encoder lives in `index.html` (not a vendored dep).

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-26 10:54:10 -04:00
thePR0M3TH3AN 8a2c146408 added pixel art editor 2026-05-22 16:06:36 -04:00
thePR0M3TH3ANandClaude Opus 4.7 b24511ad80 Add Pixel Art Phase A1 — editable pixel layers
A new `pixelart` layer type: a palette-indexed, RLE-encoded grid stored
in the project JSON, rendered crisp (image-rendering: pixelated) across
the editor, preview-DOM renderers, and the export canvas.

A dedicated #pixelEditorView with pencil / eraser / fill / eyedropper
(drag-paint with line interpolation), a palette panel (pick / add
colours), grid toggle, mirror X/Y, zoom, and per-stroke in-editor undo.
Reachable via a tool-palette button (adds a 32x32 layer + opens the
editor) and an "Edit pixels" button / double-click on a pixel layer.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-22 15:30:43 -04:00
thePR0M3TH3ANandClaude Opus 4.7 3e6e89e16f Add private (encrypted) publishing — Phases 1 & 2
Phase 1 — publish a design encrypted, readable only by the author:
- Crypto helpers: encryptProjectEnvelope / decryptProjectEnvelope —
  AES-256-GCM over gzipped JSON, AES key NIP-44 key-wrapped to the
  author (NIP-04 fallback), via a nostrEncryptCapability() probe. All
  in-browser, no new dependencies.
- publishEncryptedDesign: a feed-invisible kind:30078 event — random
  persistent d-tag, only d / alt / encrypted tags, no casewrap tag.
- Publish-confirm modal gains a Public / Private control with the
  privacy warning and a capability gate; wired into the template and
  disc-design publish paths.
- My Designs decrypts the author's own private events and shows a
  lock badge; buildRowsFromEvents skips any stray encrypted event so it
  can never surface in the public feed.
- state.visibility / state.privateDTag — restored on load, cleared on
  Close project, autosaved.

Phase 2 — flip a published design's visibility in place:
- Owner-only Make Public / Make Private button on the preview page;
  republishDesignVisibility re-publishes under the same d-tag with the
  opposite wrapper (NIP-33 replace), behind a confirm that states the
  public-to-private caveat.

Spec status documented in docs/PRIVATE_PUBLISHING_FEATURE.md.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-22 13:48:59 -04:00
thePR0M3TH3ANandClaude Opus 4.7 5e44c9e2e4 Draft Pixel Art feature plan with event-size budgeting
Spec for a Nostr-native pixel-art editor: an editable `pixelart` layer
type (palette-indexed + RLE grid stored in JSON, raster as export-only),
a dedicated Pixel Editor canvas-area view, a standalone casewrap-pixelart
Designer-tab design importable into any design as a layer, PNG export,
and a phased path to animation frames + GIF.

Includes a Size limits section: relays cap event size (commonly 64 KB),
so publishing is gated on a measured event-size budget derived from the
relays' NIP-11 max_event_size (min across the user's set, 64 KB
fallback) — soft warning at ~50%, hard block at ~90%, with a live size
readout in the editor. Encoder stores the smaller of RLE / base64 to
bound the worst case; rough size table per grid dimension included.

Also index the spec in TODO.md under drafted-but-unbuilt features.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-22 07:29:14 -04:00
thePR0M3TH3ANandClaude Opus 4.7 39f0ed0eb0 Expand Artstr Stacks spec into a HyperCard behaviour model
Replace the thin single-action-per-layer model with real interactive
logic:

- Cards gain onEnter/onExit chains; layers gain an onClick chain. Each is
  an ordered action chain, not a single link.
- v1 action set: goto-card, go-back, open-url, show-layer, hide-layer,
  toggle-layer — reveals, secret panels, multi-step buttons, branching.
- New action-builder surface: a no-JSON panel with reorderable rows,
  id-based target pickers, and authoring warnings.
- Runtime tracks a per-card layer-visibility map (reset on re-entry) and
  executes chains; action overlay regions are focusable buttons.
- Safety: onEnter/onExit cannot navigate (no enter->goto->enter loops);
  chains capped and non-recursive; unknown action types ignored.
- Re-phased A (format) -> B (behaviour authoring) -> C (runtime) ->
  D (route) -> E (stack logic: variables/conditionals, future tier).

Interactivity stays a declarative, interpreted attribute of existing
layers — no new layer types, no HTML/JS, no eval.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-22 07:05:12 -04:00
thePR0M3TH3ANandClaude Opus 4.7 19ee00f14a Tighten Artstr Stacks spec after review pass
- Aspect-ratio changes now re-fit cards via the existing import-letterbox
  remap instead of stranding layers off-canvas; imports target the
  stack's aspect, not a hardcoded 16:9.
- Clarify how the shared deck renderer is fed for stacks (dims from
  stack, background from card) and startCard deletion fallback.
- Viewer: action regions are focusable buttons (Tab/Enter, screen
  readers); empty-space clicks are no-ops; goto-card keywords clamp at
  the ends; touch taps act as clicks; persist the edited card before
  launching; encrypted-stack locked state on the /p/ route.
- Fix the hit-testing risk note (rotation is exact; only clip-masked
  layers fall back to a bounding box) and add an accessibility row.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-21 22:40:41 -04:00
thePR0M3TH3ANandClaude Opus 4.7 22256182d2 Draft Artstr Stacks (interactive pages) feature plan
Spec for "HyperCard for Nostr" — fullscreen interactive card stacks built
as a focused extension of the Slide Deck: a new templateMode 'stack'
reusing the deck card-container engine, with a per-stack aspect ratio,
optional per-layer actions (goto-card / open-url), transparent hotspots,
and a fullscreen interactive viewer with click routing. Declarative
safe schema only — no HTML/JS. Phased A-D plus a /p/<naddr> viewer route.

Also index both PRIVATE_PUBLISHING_FEATURE.md and STACKS_FEATURE.md under
the drafted-but-unbuilt features in TODO.md.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-21 22:37:51 -04:00
thePR0M3TH3ANandClaude Opus 4.7 0870ccfa08 Draft private (encrypted) publishing feature plan
Spec for publishing any design to Nostr encrypted, readable only by the
author (Phase 1 "private to me"). Covers the AES-256-GCM + NIP-44/NIP-04
key-wrap envelope, leak-free tagging (no casewrap feed tag, random d-tag),
progressive decryption in My Designs, an explicit threat model, and a
Phase 0 validation spike. Phases 2-4 (public/private toggle, recipients,
NIP-59/Blossom) sketched as future work.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-21 22:31:21 -04:00
thePR0M3TH3ANandClaude Opus 4.7 9bf99f1abb Add Slide Decks & Presenter Mode (v1: Phases A–D)
Build a Nostr-native presentation system on top of the existing canvas
editor:

- Slide (templateMode 'slide') — a 16:9 Custom Art canvas with speaker
  notes; publishes/forks/loads as casewrap-slide.
- Deck Builder (templateMode 'deck') — a Template-tab container with an
  inline ordered slide list. Slide-sorter view: add blank, import from
  Nostr or file (non-16:9 imports letterboxed), duplicate, delete,
  drag-reorder, inline-rename; edit a slide in the canvas editor with
  write-back. Self-contained save/load/publish/fork as casewrap-deck;
  deck feed-card and publish previews show the first slide + count badge.
- Deck theme — deck-level font + background, render-time composition,
  per-slide ignoreDeckTheme opt-out.
- Presenter Mode — full-screen runtime: themed slide, notes, next
  thumbnail, counter; keyboard/click/on-screen nav; Presenter ⇄ Audience
  view toggle (slide-only full-screen with auto-hiding chrome). Launches
  from the deck tool palette and a deck's community-browser preview.

Supporting changes:
- New categories: slide ("Slide design") and slide-deck ("Slide deck");
  both use the free-form Custom tag field, not media identifiers.
- Swap the Template/Designer tab icons; 50% larger.
- Remove the IMDb/OMDb metadata import (button, handler, omdbApiKey);
  the imdbId field stays.
- Update README, SLIDE_DECK_FEATURE.md status, and TODO.md.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-21 22:10:06 -04:00
thePR0M3TH3ANandClaude Opus 4.7 06c5ab6768 Draft slide-deck & presenter-mode feature plan
- docs/SLIDE_DECK_FEATURE.md: phased spec for Slide Designer (16:9
  canvas + speaker notes), Deck Builder (embedded ordered slides,
  slide-sorter view, deck theme), and Presenter Mode (single-window
  v1, dual-window deferred to Phase E). Phases A-D with ship gates.
- Select tool icon changed to a rotated arrowhead so it reads as a
  cursor, not a play button (distinct from the planned Present icon).

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-21 14:30:59 -04:00
thePR0M3TH3ANandClaude Opus 4.7 ef7d4803f7 Text/Shape/Hand tools, Designer-tab restructure, rename to Artstr Studio
- New left-palette tools: Hand (pan), Shape (drag to draw a primitive),
  Text (click to place). Removed the redundant sidebar add-buttons.
- Pencil strokes now keep a constant on-screen thickness (pixel-space
  viewBox) instead of scaling with stroke length/aspect.
- Restructured tabs: "Disc Designer" -> "Designer", which now hosts a
  Layout panel with Custom Art (default) + Disc Design; Custom Art moved
  off the Template tab. Underlying appMode/save-format unchanged.
- Renamed the app from CaseWrap Studio to Artstr Studio (brand text only;
  Nostr tags and localStorage keys kept for compatibility); smaller
  one-line logo wordmark.
- README updated for the new tabs, tools, and keyboard shortcuts.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-20 15:30:46 -04:00
thePR0M3TH3ANandClaude Opus 4.7 16c1577af4 Pen & pencil tools, unified vector editing, sidebar polish
- Pen/pencil tools (Phases A-E): left tool palette, contextual options
  panel, freehand pencil strokes, Bézier pen paths, anchor/handle editing,
  per-layer hidden flag with eye toggle in the layer list.
- Unified vector editing: the pen panel edits any selected shape's
  fill/stroke; a "Make editable path" action converts primitives and
  single-path SVGs into editable pen paths (SVG d-string parser + arcs).
- Stroke no longer clips at the shape's bounding box (overflow:visible).
- Toolbars anchored outside the scroll area so they stay locked on screen.
- Keyboard shortcuts: Delete, arrow-nudge, [/], Ctrl+D, Ctrl+C/X/V.
- Collapsible sidebar panels, collapsed by default (Layout stays open);
  selecting a layer auto-opens the Layers panel.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-20 10:32:28 -04:00
thePR0M3TH3ANandClaude Opus 4.7 ee0052847e Draft pen & pencil tool feature plan
docs/PEN_TOOL_FEATURE.md: pen and pencil tools that author
shape.kind:'path' layers rather than a new raster type, so drawn
paths inherit the existing fill / gradient / stroke / clip / opacity
/ transform / undo / export / Nostr plumbing for free.

Decisions locked with the project owner:
- Pencil strokes are raw polylines, no smoothing (early-web look).
- Only pen paths are node-editable; pencil paths are not.
- A closed pen path auto-fills with a solid accent color on close.
- Pen + pencil work in Disc Designer mode too — the overlay attaches
  to #designerDiscWrap and coordinate capture branches on
  isDesignerLayer, mirroring startLayerDrag.

Plan: a state.editorTool tool-mode system (select / pen / pencil), a
left floating tool palette and a right contextual options toolbar
matching the zoom-toolbar styling, a pointer-capturing pen overlay,
shape.pen.nodes metadata for re-editable pen paths, and a new
layer.hidden flag for mask-source shapes. Five phases: A tool-mode +
toolbars, B pencil, C pen create, D pen node editing, E visibility
flag + mask polish.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-19 22:20:45 -04:00
thePR0M3TH3ANandClaude Opus 4.7 162da4b9e4 QR code layers, combined-wrap panel, profile-close fix, TODO
QR code layer (Phase A):
- New `qr` layer type. Add QR button alongside Image / Text / Color /
  Shape in every layer panel. Spawns 1:1 with a placeholder URL.
- Controls: data textarea, error-correction level (L/M/Q/H), quiet
  zone, module + background colors, transparent-background toggle.
- Renders as crisp SVG on the editor and all five preview surfaces
  (dark modules merged into one path); canvas/PDF/JPEG export draws
  it cell-by-cell. Round-trips through JSON and Nostr publish/fork;
  old clients skip the unknown type. Works with drag / resize /
  rotate / opacity / aspect-lock / clip / clipboard / undo-redo.

Combined-wrap layer panel:
- In cover mode with Artwork mode "One combined wrap image", the
  layer panel collapses the separate Back / Spine / Front panels
  into a single "Cover trim area" panel — the wrap is one open
  canvas, so the sub-regions aren't meaningful. The combined panel
  still lists any pre-existing back/spine/front layers via a
  matchKeys set so they aren't orphaned from the UI.

Profile modal close fix:
- closeProfilePage used history.back(), which navigated the browser
  out of the app entirely when the profile was cold-loaded from a
  shared /u/<npub> link (that entry being first in the tab's
  history). Switched to history.replaceState to "/" — cleans the
  URL in place without navigating or firing popstate. Matches how
  closeNostrPreview already handles the /share/ URL.

Docs:
- Add TODO.md tracking deferred work: QR Phase B/C, IMDb-import
  removal, profile-page polish, edit-flow polish, and the unbuilt
  badges / collections / zap-gated / NWC-zaps features.
- Remove docs/UNDO_REDO_FEATURE.md and docs/QR_CODE_LAYER_FEATURE.md
  (shipped) and docs/TMDB_AUTOFILL_FEATURE.md (declined).
- README: document QR layers, undo/redo, fit-to-view + zoom toolbar,
  and the off-canvas veil; refresh the schema and docs references.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-19 22:09:15 -04:00
thePR0M3TH3ANandClaude Opus 4.7 412f932b9f Harden undo/redo feature plan for current scope
Rewrite docs/UNDO_REDO_FEATURE.md to match what the codebase actually
contains today. Explicit snapshotted-vs-not field list covering
savedMetaByMode, customArt canvas, editing-in-place context, the full
layer schema with shape/fill/stroke/clip sub-objects, and discMeta /
spine labels. Trigger list organized by category (layer lifecycle,
geometry, paint, SVG per-element, clip, mode/structural, artwork
loads, metadata, custom-art canvas) with debounce windows per field
type. Switches storage from localStorage to memory-only for v1 to
avoid quota issues with our richer state. Adds an _isRestoring guard,
focused-input bypass for the keyboard shortcut, and 11 acceptance
criteria covering cross-mode meta swap, edit-in-place, clipboard
interaction, and the stack cap. Four implementation slices.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-19 15:12:39 -04:00
thePR0M3TH3ANandClaude Opus 4.7 a02c562a9f Custom Art metadata simplification, JPEG mask fix, README rewrite
Custom Art project metadata:
- Hide the "Add Media Identifiers" panel when in Custom Art mode —
  IMDb / UPC / TheTVDB / MusicBrainz don't fit wallpaper / banner /
  logo work.
- Show a single optional Custom tag field in its place. Stored as
  state.meta.customTag, round-trips through save/load, and emits to
  Nostr as both an NIP-73-style 'i custom:<tag>' identifier and a
  topical 't <tag>' tag (lowercased, hyphenated, capped at 64 chars).
- Hide the IMDb import button + hint in Custom Art mode.
- Auto-select the "Custom art" category the first time the user
  enters customart mode without one set.

JPEG export mask fix:
- body.export-print > *:not(#exportPrintContainer) { display: none }
  was hiding the global SVG <defs> container that holds <clipPath>
  definitions for layer masks. With the defs invisible, every
  clip-path: url(#…) reference resolved to nothing during print,
  so the PDF that the JPEG flow re-rasterizes had unclipped layers.
  Carve #globalClipDefs out of the exclusion selector and force
  it to zero-size + overflow:hidden so it stays in the DOM but
  takes no space. Direct "Print / Save PDF" was unaffected because
  it doesn't use the export-print mode.

README rewrite:
- Brings the README in line with what the app actually does today:
  Custom Art mode, vector shape primitives + gradients + strokes +
  custom SVG upload with per-element editor, clipping/masking,
  layer clipboard, profile pages at /u/:npub, Lightning tips with
  WebLN auto-pay + NIP-57 zap tracking + Zapped tab, edit-in-place
  via NIP-33 replaceable semantics, the publish-confirm modal, the
  current schema version (5 / min 4), and the vendored qrcode lib.

Remove docs/VECTOR_SHAPES_FEATURE.md — the feature shipped.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-19 14:37:36 -04:00
thePR0M3TH3ANandClaude Opus 4.7 c5a04423ad Draft vector shapes feature, prune shipped feature docs
VECTOR_SHAPES_FEATURE.md plans a new shape layer type that subsumes
primitives (rect / rounded-rect / circle / ellipse / polygon / star /
line / custom SVG path) under a single discriminated kind, plus
solid / linear-gradient / radial-gradient fills, strokes, and clip
support that any layer type can use. JSON storage is purely additive,
backwards compatible with existing payloads, and forward compatible
for unknown shape kinds. Phased delivery: A primitives + solid fill,
B gradients, C strokes, D custom paths, E masking.

Pruned docs for features that have already shipped in this codebase:

- COLOR_AND_FONT_LAYERS_FEATURE.md — color layers + font picker
- CUSTOM_ART_MODE_FEATURE.md — custom-art template mode
- EDIT_DESIGN_FEATURE.md — replaceable-event edit-in-place
- LIGHTNING_ZAPS_FEATURE.md — LNURL-pay tip flow
- PROFILE_PAGES_FEATURE.md — /u/:npub profile pages
- STREAMING_RELAY_SYNC_FEATURE.md — progressive feed loading
- TEMPLATE_FORKING_FEATURE.md — Fork off! flow
- TRUST_AND_BLOCK_FEATURE.md — block / mute-sync / trust tiers / report
- WOT_SOFT_MODERATION_FEATURE.md — hop-1 mute/report blur
- ZAP_TRACKING_FEATURE.md — NIP-57 zap requests and receipt sums

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-18 18:47:22 -04:00
thePR0M3TH3ANandClaude Opus 4.7 b707b42909 Draft edit-published-designs feature plan
Uses NIP-33 parameterized-replaceable semantics: republishing kind-30078
with the same d-tag from the same pubkey supersedes the old event on
compliant relays. No NIP-09 deletion required for the replace itself.

Plan covers state/banner (Phase A), publish-flow rewire (Phase B),
owner-only Edit buttons on My Designs, profile, and preview (Phase C),
and polish (Phase D). Surfaces the honest tradeoff that reactions and
zap receipts orphan to the old event id, while naddr share links keep
working since they're d-tag based.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-18 14:48:27 -04:00