Arranging: boxes on everything, handwriting movable, the Eraser's preview, a Circle shape, pixel-exact cues

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
ackandClaude Fable 5.1 committed 2026-10-14 20:38:29 +02:00
1 parent 03907da8c9
commit 24a6a2595b
10 files changed
+690 -126

No files matched your search

+51 -32
View File
@@ -5,6 +5,22 @@
--panel: #f6f6f7;
--desk: #e4e4e7;
--accent: #1f4fd8;
/* The two colours of arranging (Andy, 2026-10-14): the blue of the
boxes and corners the Arrange tool lays on everything it can move,
and the green of the one being moved or resized, by Arrange or by a
hold with any tool, until the pointer lifts. The hover cue on an
implied rectangle (free text, a text rectangle, a Hide) is the same
blue today but has its own name, so that trying another arrange
blue leaves it alone: it is the only sign of the rectangle's extent. */
--arrange_blue: #1e88e5;
--held_green: #2e7d32;
--hover_blue: #1e88e5;
/* The line of the Arrange cue and of the grip, the same width for both
(Andy, 2026-10-14: the thinner blue line had read as standing closer
to the ink than the green, the gap being the same). */
--cue_line: 2px;
/* The eraser's cue: what a press would erase (Andy, 2026-10-14). */
--erase_red: #e53935;
font-family: system-ui, sans-serif;
font-size: 15px;
color: var(--ink);
@@ -334,18 +350,23 @@ h2 {
background: var(--desk);
}
/* The cue around an image being moved or scaled by hand: green, with a
square at the corner being dragged. */
.image_grip {
/* The grip around whatever is being moved or resized (an image, a Hide,
a text block, a shape), by a hold or by Arrange: green, its four
corners (none on free text, which has no corners to resize by), and
the corner being dragged larger. Under Arrange it takes
the place of the thing's blue cue, which is left out while held. */
.grip {
position: absolute;
z-index: 3;
box-sizing: border-box;
border: 2px solid #2e7d32;
border: var(--cue_line) solid var(--held_green);
pointer-events: none;
--handle-color: #2e7d32;
--handle-color: var(--held_green);
--moving_handle: 14px;
}
/* The four corners of a held object, and the corner being dragged, larger. */
/* The four corners of a held object or an Arrange cue; a moving corner
is larger (the one dragged, or all four when the thing is moved). */
.handle {
position: absolute;
width: 10px;
@@ -358,45 +379,43 @@ h2 {
.handle.sw { left: 0; top: 100%; }
.handle.se { left: 100%; top: 100%; }
.image_grip.corner::after {
/* The corner being dragged is larger; and while the whole thing is moved
all four corners are, since all four are moving (Andy, 2026-10-14). */
.grip.corner::after {
content: "";
position: absolute;
left: var(--corner-x);
top: var(--corner-y);
width: 16px;
height: 16px;
width: var(--moving_handle);
height: var(--moving_handle);
transform: translate(-50%, -50%);
background: #2e7d32;
background: var(--held_green);
}
.grip.moving .handle { width: var(--moving_handle); height: var(--moving_handle); }
/* The Arrange tool's cues: blue corners and an outline on every image,
whose edges may not show (text rectangles and Hides carry blue corners
at all times since 2026-10-14, drawn on the canvases); and the same
corners on free text under a hovering pointer (.hover_cue). */
/* The Arrange tool's cues (Andy, 2026-10-14): a blue box with blue
corner squares on everything a press can move or resize, images,
Hides, one's own text and shapes alike; free text, which has no width
to resize, gets the box without the corners. */
.arrange_cues { position: absolute; inset: 0; pointer-events: none; z-index: 3; }
.arrange_cue {
position: absolute;
box-sizing: border-box;
pointer-events: none;
--handle-color: #1e88e5;
border: var(--cue_line) solid var(--arrange_blue);
--handle-color: var(--arrange_blue);
}
.arrange_cue.image { border: 1px solid #1e88e5; }
/* The hover cue's corners are L marks like those the canvases draw on
text rectangles and Hides, not the Arrange tool's squares, so that
"blue corners" look the same everywhere; renderer.js sets the mark's
length and line width for the zoom. */
.hover_cue { position: absolute; box-sizing: border-box; pointer-events: none; z-index: 3; --handle-color: #1e88e5; }
.hover_cue .handle {
width: var(--mark);
height: var(--mark);
transform: none;
background: none;
border: 0 solid var(--handle-color);
}
.hover_cue .handle.nw { left: 0; top: 0; border-width: var(--mark_line) 0 0 var(--mark_line); }
.hover_cue .handle.ne { left: auto; right: 0; top: 0; border-width: var(--mark_line) var(--mark_line) 0 0; }
.hover_cue .handle.sw { left: 0; top: auto; bottom: 0; border-width: 0 0 var(--mark_line) var(--mark_line); }
.hover_cue .handle.se { left: auto; right: 0; top: auto; bottom: 0; border-width: 0 var(--mark_line) var(--mark_line) 0; }
.arrange_cue.no_corners .handle, .grip.no_corners .handle { display: none; }
/* The eraser's cues: a red box around each element a press where the
pointer hovers would erase, whole, as the eraser works. */
.erase_cues { position: absolute; inset: 0; pointer-events: none; z-index: 3; }
.erase_cue { position: absolute; box-sizing: border-box; pointer-events: none; border: var(--cue_line) solid var(--erase_red); }
/* The hover cue on an implied rectangle (Andy, 2026-10-14, evening): a
text rectangle and a Hide are outlined, free text shows its top and
left edges only, so the two kinds of text are told apart. renderer.js
sets the line width for the zoom. */
.hover_cue { position: absolute; box-sizing: border-box; pointer-events: none; z-index: 3; border: var(--mark_line) solid var(--hover_blue); }
.hover_cue.free { border-width: var(--mark_line) 0 0 var(--mark_line); }
.page {
position: relative;