The SVG parser reads neither, so fills came in black and strokes were dropped without a note. They are resolved before parsing: color(srgb|display-p3 ...) converted to the document's profile, color-mix(in srgb|oklab|oklch, ...) evaluated as CSS Color 5 defines it. Other spaces are approximated with a note; unreadable calls become a mid grey with a note. Bounded length, nesting and count.
The settings folder comes from craft-settings' rules: FIGCRAFT_CONFIG_DIR,
a `portable` file next to the executable (config/ beside it), then the
platform folder every earlier version used. The Windows portable zip ships
the marker, and a portable folder without preferences starts with a copy
of the platform folder's.
Direct3D 12 compiles with FXC and no device compiles wgpu's indirect-call
validation shaders, the two causes of "Parent device is lost" at start.
When the graphics still fail before the first frame, the app starts again
with the next of a fixed list of attempts (Windows: Vulkan, OpenGL; Linux
and FreeBSD: OpenGL; then lower requirements on the power-saving GPU), and
the last failure's message names what was tried.
Session::execute_as records the agent's presence: its name, the file, and the innermost layers its last edit changed or the selection it set, for 8 seconds after its last command. The app shows it as an avatar in the people row and an outline with a name tag on the canvas, in its own colour. Display only: no undo step, never saved, never synced to a live session.
While the interaction editor has an Open overlay action with Manual position open, the overlay frame shows dimmed and outlined where it opens, from the top-left of the layer that opens it. Dragging it sets the action's offset through proto.action.set in one gesture: the X/Y fields follow live and the drag is one undo step.
* M9: one name for comments and live sessions, shown in the Join dialog, kept in the browser, renamed live (#1380)
* M9: a reconnecting session's reset is its own helper (#1380)
* M9: a per-address budget for server admin requests, and join codes found by hash (#1075)
* M9: the server tests share one snapshot and address helper (#1075)
These scripts write no spaces between words, so a paragraph was one word
that only broke where it overflowed, mid-word (พัฒนาซอ|ฟต์แวร์).
breaks::word_breaks finds the word starts inside each run of them with
ICU4X's line segmenter (icu_segmenter 2.3, matching the icu_* crates in
the lock), and break_lines may break there when the next glyph starts a
new cluster. Where a run meets other text the UAX #14 subset decides as
before; a word wider than its box keeps #1400's emergency break.
Desktop uses the segmenter's dictionaries; the browser uses its LSTM
models (about 0.39 MB of wasm instead of 1.86 MB, which the 24 MiB web
gate can't take). ICU4X breaks between stray marks are filtered through
safe_emergency_break, so junk input never splits a cluster.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LvG6DyK6i9Nvvsp3tp77UP
* M4: a letter and its combining marks shape with one font (#1478)
* M4: the stacked-mark test checks positions only in fonts whose anchors stack them (#1478)
* M4: the cluster face rule is tested with stand-in faces, so it runs without system fonts (#1478)
* M4: the #1478 tests use stand-in faces only, so they run everywhere
Every message (the first and each reply) gets `mentions`: {name, known,
you} for each @mention, by the rule the thread view highlights with
(figcraft_doc::mentions, now shared with mention_ranges). Names resolve
against the file's people and you; unknown names are kept with
known: false; a@b.com mentions nobody.
The board canvas's background grid is now a preference (`board.grid`): dots
(the default), lines, graph paper (a strong line every 2-12 cells over fainter
ones, like Japanese section paper) or none, with spacing (4-512), mark size and
contrast. Preferences gets a Board grid section; right-clicking an empty board
offers Board grid settings. Zoomed out the grid still thins out (by halves, or
down to graph paper's strong lines), and dots no longer shrink to a single
pixel, so the grid stays visible at low zoom.
The renderer draws lines as well as dots, with a configurable strong-mark
rhythm; a crossing of two lines is blended once, in the stronger colour. A
hand-edited preferences file falls back to the default grid instead of losing
the other preferences.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FEkCVd8n1eC6xTHebmHMDR
A mask group's pixmaps cover only where its mask or content can paint within the view, rounded out to whole pixels, drawing the same pixels (a 40x40 mask on a 3000x2000 view: 96 MB -> 61.5 kB). Isolated layers share a 2 GiB per-thread budget; a layer past it is left out with a warning.
From the review of #1496: three background blurs stacked on each other across the band
boundaries draw the same in bands as in one piece (within anti-aliasing), so the bands'
overlap, the reach of the largest blur, is enough, as it is for the desktop's parallel bands;
pinned by a test. The docs and the `MAX_BANDS` comment no longer put the longest frame at "an
eighth of the render": a frame draws at least a band, a part of the render rather than the
whole, and the numbers measured for #1496 are cited instead.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* M2: components can't contain their own instances (#1084)
Edits that would make a component hold an instance of itself, directly, through other components or through another variant of its set, are refused with the loop named. Files holding such a loop open with one instance per loop detached and a note; a rebuild never expands an instance inside a copy of itself, so a loop merged in a live session stops growing.
* M2: a variant may hold a sibling variant's instance; only true loops are refused (#1084)
Each variant counts as its own component: refusals and open-time repairs apply only to a component leading back to itself through instances (an instance-swap value included), so files with nested sibling variants open unchanged. sync_instance_depth is split into match_layers and copy_layers.