Every paper-ds-* skill loads this first.
Before the first write
- Call
get_basic_infowith the targetfileId. Every file-scoped response carriesfile.id. If it is not the file you meant, stop and correctfileId. A write to the wrong file cannot be undone. - Read
paper-ds.jsonand../paper-ds-manage/references/versioning.md. During first setup, use its in-progress connection record; do not recursively rerun setup. Outside setup, a missing record needspaper-ds-setup. - Call
get_font_family_infofor every family before writing text. A missing weight falls back silently and breaks every measurement after it. - Call
get_tokensand comparecontentHashwith the manifest. A different hash means tokens changed outside your session. Re-read before trusting names. Before overwriting artwork, checkpoint its real source, tokens, and any user's edits. Do not relabel a token-bound live frame as a frozen historical version.
Writing
- One visual group per
write_htmlcall. The user watches the canvas live, and small writes keep failures local. - Flex only. No
margin,display: grid,display: inlineor tables. - Font sizes in
px, never below 12. Letter spacing inem. Line height inpx. - Set
layer-nameon every structural element. Later runs find nodes by name. - Use tokens as
var(--name)everywhere Paper accepts them: color,padding,gap,border-radius,font-size,line-height,letter-spacing. Never write a value that exists as a token. - Read the ID of a new node from
createdNodes[0].idin the last content item of the response. The first content item is the file header and contains the file ID, so matching the first"id"in the response returns the wrong value. - Reuse with
x-paper-cloneorduplicate_nodes. Clones inherit tokens and structure, so they cannot drift. - Fix a defect with
update_stylesorset_text_content. Never delete and redraw for a small fix. - Call
finish_working_on_nodeswhen done, or the working indicator stays on the canvas.
Dark mode
Paper tokens hold one value, and a frame cannot override a variable for its children. So themes are separate tokens:
- Light roles:
--color-ground,--color-ink - Dark roles:
--color-dark-ground,--color-dark-ink
Pick a theme per frame and use only that theme's tokens inside it. Never mix. To show both themes, draw two frames.
Read themes in paper-ds.json before drawing:
["light", "dark"]: every option and review shows a light and a dark stage side by side.["dark"]or["light"]: one stage per option. The single theme's roles use the plain names (--color-ground), with nodark-set. Never draw a stage for a theme the product does not ship.
Sync from code with paper-ds-tokens, which maps the project's dark selector onto the dark- names.
Comment color
Reserve a distinct neon-pink comment role with comment-subtle for review semantics. Keep it documented in Foundations, not drawn as pins, comment cards, or findings on sheets. Do not use it for product status, actions, or decoration.
Sharing
Do not include private example-file URLs or IDs in public documentation, screenshots' captions, or generated examples. Use repo-local images for documentation. Share a user's working-file link only within their requested handoff, not as a reusable demo source.
Reading back
- A screenshot right after a write can be blank or stale. Call
get_tree_summaryon the node, then screenshot again. Never judge a write from a blank image. - Review each checkpoint in one line: spacing, type, contrast, alignment, artboard fit, repetition. Fix, then move on.
- Screenshot at scale 1. Use scale 2 only to read small text.
Text on the canvas
Paper's canvas is dark. Text on an unfilled artboard uses var(--color-canvas-text) and var(--color-canvas-muted). System ink is unreadable there. Text inside a filled artboard uses the system's roles.
Overarching notes (an overview) have no fill, border or card. create_artboard ignores backgroundColor: transparent and gives the artboard a white fill. After creating it, call update_styles with background: none, then check get_computed_styles for backgroundColor.
An overview is its own artboard, 760px wide, no padding, placed above the row of artboards at left: 0 with at least 80px clear below it. A full-width overview in the row looks like an empty sheet.
Padding set at creation sometimes cannot be changed later (paddingInline updates are ignored). If an artboard's padding is wrong, create a new artboard with the right padding, move_nodes the children into it, and delete the old one.
Placing artboards
- Set
leftandtopexplicitly. Lay artboards in a row, 80px apart, so none can overlap.create_artboardcan place a new artboard over an old one aftermove_nodes. - A
fit-contentartboard reports heightnullor?. Read its height from a screenshot, never from a guess. - Never set an artboard
topwithbottom: autoorheightto fix a child.find_nodesbyposition: absolutealso returns the artboard, and updating it pins its height. Select children by ID. move_nodeswithparentId: "root"lifts a frame to the page. The frame loses its width and height. Set both again at once.setTimeoutis undefined in codemode. Never wait with a timer. Callget_tree_summary, then screenshot again.- Row width is the sum of the actual stage/option widths, resolved DS gaps, and resolved DS padding. Never assume fixed padding. Place the next artboard after that width with a clear gap.
What Paper cannot do
Record each in the manifest divergences when the project's code depends on it.
color-mix()inside an SVG fill is flattened. Resolve it to a plain color first.- SVG noise filters do not render. Use a generated noise PNG at the same opacity and
paper-asset://. - A frame cannot switch themes (see Dark mode).
- Fonts load at launch. After installing one, the user must quit and reopen Paper.
paper-gen://generates images only when the user asked for images.