638 Commits

Author SHA1 Message Date
Eva Marco
980ed0a719
♻️ Use DS icon buttons to close the subscription dialogs (#12539)
* ♻️ Use DS icon buttons to close the subscription dialogs

The close buttons of the five subscription dialogs (plan management,
success, Nitrate subscription, contact sales and manual cancel) were
raw buttons with no name. They become ghost DS icon buttons named
"Close"; the class that places them in the corner goes on the tooltip
wrapper, so they stay where they were and only show the DS hover.

The plans page link-style buttons stay raw: they have no DS equivalent.
A visual test covers the plans page and the plan management dialog.

AI-assisted-by: claude-opus-5-5

* ♻️ Move settings subscription styles closer to the DS

The settings subscription stylesheet inlines the deprecated
button-style mixin and %button-icon placeholder, resolves its legacy
color aliases and font weight, uses logical properties and the DS
typography module without a namespace. The rules on icon svgs that have
no class keep a comment; two that match nothing (the dropdown arrow svg
and .radio-btns) are commented out with a TODO.

refactor/ stays only for the modal placeholders (%modal-*), which move
with the modals refactor. No visual change.

AI-assisted-by: claude-opus-5-5

* 🔥 Remove unused styles from the settings subscription

The SCSS refactor of the settings subscription left rules commented out
with a TODO because the module does not use them, or because they target
an svg inside a DS icon that is the svg itself. CSS modules scope the
classes to this module and no other source uses them, so they go:
.icon-dropdown svg, .radio-btns, .radio-btns label. No visual change.

AI-assisted-by: claude-opus-5-5

* ♻️ Give the subscription icons classes and drop unused props

Review fixes for the subscription styles:

- The plan icon span sets the letter color with color, not stroke on a
  bare svg, and drops fill, stroke-width and color: transparent, which
  do nothing on a span.
- The plan icon border uses $b-2 (was 1.75px), so it is 0.25px thicker.
- The letter gets its own class for its 2.25px stroke. With the default
  stroke it looks too thin next to the border.
- The open link and editors arrow icons get a cta-icon class instead of
  the bare svg selector, and take the button color. The arrow used an
  icon-dropdown class with no rule.

AI-assisted-by: claude-opus-5-5

* ♻️ Use the DS stroke width and color in the subscription icons

The plan letter and the member icons keep the DS stroke width (the plan
letter line gets thinner), the member icons set their color instead of
the stroke, and the props copied from the button icon placeholder go.
The success dialog logo gets its own class instead of a bare svg
selector.

AI-assisted-by: claude-opus-5-5
2026-10-28 12:11:06 +01:00
Eva Marco
1109e38852
♻️ Use DS icons in the dashboard lists and placeholders (#12536)
* ♻️ Use DS icons in the dashboard lists and placeholders

The trash project options button becomes a ghost DS icon button, as in
the projects list, and says whether its menu is open. The search
placeholders, the empty project "create new file" button, the comments
placeholder and the legacy import library tag use the DS icons. The
legacy search icon had no fill rule, so its lens was filled black; the
DS one is not.

Two fixtures make the trash testable: a deleted project, and deleted
files due in 2100 (the existing ones expired in 2024, so the trash
dropped them). A visual test covers the trash row, the empty project
button, the project rename field and the comments placeholder.

AI-assisted-by: claude-opus-5-5

* 🐛 Remove the hidden close control from the dashboard rename field

The rename field of dashboard projects and files had a close control
next to the input that never showed: its legacy icon is drawn with a
stroke, but the styles only set a fill. It could not be reached with
the keyboard or a screen reader, and a click on it did what leaving
the field does: the blur saves the name first, and its handler saved
it too. It only left a pointer cursor over an empty spot. Enter, Escape
and leaving the field keep working as before. No visual change.

AI-assisted-by: claude-opus-5-5

* ♻️ Move dashboard trash, comments and rename styles to the DS

The trash, comments panel and rename field stylesheets resolve their
legacy color aliases, sizes, font sizes, mixins and the menu shadow to
DS tokens and values, and use logical properties. The comments panel
and the rename field no longer import refactor/; the trash keeps only
the shared dashboard header styles (common-dashboard), used by ten
dashboard modules.

Four selectors that the modules do not use are commented out with a
TODO. The comments dropdown z-index (4) has no DS token and keeps a
TODO. No visual change.

AI-assisted-by: claude-opus-5-5

* 🔥 Remove unused styles from the dashboard trash and comments

The SCSS refactor of the dashboard trash and comments left rules
commented out with a TODO because the module does not use them, or
because they target an svg inside a DS icon that is the svg itself. CSS
modules scope the classes to this module and no other source uses them,
so they go: .thread-group, .comments-icon-small, .add-file-btn,
.add-icon. No visual change.

AI-assisted-by: claude-opus-5-5

* 🐛 Use px2rem for the unread dot size in dashboard comments

The unread dot used $sz-8, which the DS sizes do not define, so the
integration bundle build failed. It now uses px2rem(8), the same 8px.

AI-assisted-by: claude-opus-5-5

* ♻️ Use DS typography and z-index in the dashboard comments

Review fixes for the dashboard lists styles:

- The comments dropdown title uses the headline-small typography. It
  was 11px regular, so it is now 12px medium (larger and bolder).
- The comments dropdown uses --z-index-dropdown instead of a raw 4.
- The rename field selector is the class alone; the input type is not
  needed to win over the input defaults (0px change).

The visual test now also captures the whole comments dropdown, so the
title change shows.

AI-assisted-by: claude-opus-5-5

* 🔥 Remove dead rules from the dashboard comments styles

The comments dropdown has no separators, so its hr rule matched
nothing, and the comments icon set the default stroke width. No visual
change.

AI-assisted-by: claude-opus-5-5
2026-10-28 12:10:47 +01:00
Eva Marco
4d416bd3f2
♻️ Use DS icons and buttons in the settings sidebar and email modal (#12541)
* ♻️ Use DS icons and buttons in the settings sidebar and email modal

- The settings sidebar back arrow and "Contact us" icon use the DS
  icons. The arrow keeps its place; the small DS icon draws 12px inside
  a 16px box, so the feedback icon sits 2px to the right and its margin
  shrinks to keep the label in place.
- The change email modal close button becomes a ghost DS icon button
  named "Close"; the class that places it goes on the tooltip wrapper.

The form submit buttons of the settings pages stay: they are the shared
forms submit button. A visual test covers the settings sidebar and the
change email modal.

AI-assisted-by: claude-opus-5-5

* ♻️ Move settings sidebar and email modal styles to the DS

The settings sidebar no longer imports refactor/: its legacy mixins,
sizes and color aliases resolve to DS values and tokens, with logical
properties. Its z-index (1) has no DS token and keeps a TODO.

The change email modal does the same and keeps refactor/ only for the
modal placeholders (%modal-*), which move with the modals refactor. Its
legacy uppercase title becomes the DS headline-small typography, which
differs only in its size (12px instead of 11px): the modal grows 2px.
Two unused selectors are commented out with a TODO.

AI-assisted-by: claude-opus-5-5

* 🔥 Remove unused styles from the change email modal

The SCSS refactor of the change email modal left rules commented out
with a TODO because the module does not use them, or because they target
an svg inside a DS icon that is the svg itself. CSS modules scope the
classes to this module and no other source uses them, so they go:
.select-title, .cancel-button. No visual change.

AI-assisted-by: claude-opus-5-5

* ♻️ Tidy the settings sidebar and change email styles

The sidebar uses --z-index-panels instead of auto, the change email
submit button gets its own class instead of a bare button selector, and
the sidebar icons keep the DS stroke width (only the feedback icon line
gets thinner).

AI-assisted-by: claude-opus-5-5
2026-10-28 10:39:35 +01:00
Eva Marco
b1018c77b7
♻️ Use DS icons in the legacy context notification (#12542)
* ♻️ Use DS icons in the legacy context notification

The legacy context notification (still used by the global context
notifications, the fonts page, the team, change email, delete account
and export modals) draws its level icon with the DS icons instead of
the deprecated icon set, colored through the color property. The icons
are the same drawings, so nothing changes on screen.

The component stays: the DS context notification has no links, which
the global context notifications use. A visual test covers the info and
warning levels and a warning with html content.

AI-assisted-by: claude-opus-5-5

* ♻️ Move the legacy context notification styles to the DS

The legacy context notification no longer imports refactor/: its sizes,
spacing, borders and alert color aliases resolve to DS tokens, with
logical properties. The legacy body-small typography becomes the DS
one, which differs only in its line height (1.3 instead of 1.4): one
line notifications do not change, and multi-line ones are about 1.5px
shorter per extra line. The unused .default level is commented out with
a TODO.

AI-assisted-by: claude-opus-5-5

* 🔥 Remove unused styles from the legacy context notification

The SCSS refactor of the legacy context notification left rules
commented out with a TODO because the module does not use them, or
because they target an svg inside a DS icon that is the svg itself. CSS
modules scope the classes to this module and no other source uses them,
so they go: .default. No visual change.

AI-assisted-by: claude-opus-5-5
2026-10-28 10:39:20 +01:00
Eva Marco
08228324db
♻️ Use DS icons in the dashboard templates section (#12535)
The arrow and add icons of the dashboard libraries and templates
section use the DS icons and get their color from the color property.
The collapse button says whether the section is expanded, and the left
scroll button, which had no name, is now named "Previous".

The scroll buttons stay raw: they are round 36px buttons with no DS
equivalent. The template cards are anchors without href; they go to the
anchors backlog. A new fixture lists eight builtin templates, and a
visual test covers the cards, a card hover, the scroll buttons and the
collapsed title. No visual change.

AI-assisted-by: claude-opus-5-5
2026-10-28 09:21:00 +01:00
Eva Marco
c05b2e2ead
♻️ Use DS buttons and icons in the share link modal (#12562)
* ♻️ Use DS buttons and icons in the share link modal

- The close button becomes a ghost DS icon button named "Close"; the
  class that places it goes on the tooltip wrapper.
- "Get link", "Destroy link" and the confirmation buttons were raw
  inputs; they become DS primary, destructive and secondary buttons.
- The copy link button stays a raw segment of the link field; its icon
  becomes the DS clipboard icon, a bit larger than the legacy drawing.
- "Manage permissions" stays a link-style toggle; its arrow becomes the
  DS icon (the rotation still shows the state) and it says whether the
  permissions are expanded.

The page checkboxes and the permission selects stay for their own
groups. A new create share link fixture and a visual test cover the
modal before and after getting a link, with the permissions expanded,
and the destroy confirmation.

AI-assisted-by: claude-opus-5-5

* ♻️ Move share link modal styles closer to the DS

The share link stylesheet resolves its legacy sizes, spacing, mixins,
z-index and color aliases to DS values and tokens, with logical
properties. The copy button inlines %button-secondary with local color
variables, so it looks the same at rest, on hover, on focus and while
pressed; the visual test now also covers its hover.

The legacy typographies become the DS ones, each differing in one
detail: the title and "Manage permissions" use headline-small (12px
instead of 11px) and the texts body-small (line height 1.3 instead of
1.4), so the modal changes height by about 1px. refactor/ stays only
for the modal container, the link input and the page checkboxes.

AI-assisted-by: claude-opus-5-5

* ♻️ Use a DS icon button for the share link copy button

The copy button next to the link was a raw button with the secondary
button styles inlined in share_link.scss. It is now a secondary
icon-button* named "Copy link", so the .copy-button block goes away
(review feedback).

Visible changes: the DS secondary look (grey icon at rest, no lighter
background on hover) and a 32px wide button instead of 28px, so the
link text ends 4px earlier.

AI-assisted-by: claude-opus-5-5
2026-10-28 09:20:41 +01:00
Eva Marco
ac52c41903
♻️ Use DS icons in the comments panel filter (#12561)
* ♻️ Use DS icons in the comments panel filter

The comments panel filter (workspace and viewer sidebar) draws its
trigger arrow and menu ticks with the DS icons, as the viewer comments
filter does. The trigger button says whether its menu is open
(aria-expanded, aria-haspopup). The menu items stay: they move with the
menus group.

The dropdown item placeholder styles any svg inside a span with a 12px
box and a stroke color, so the tick icon class sets its 16px box and
currentColor stroke. Nothing changes on screen. A visual test covers
the trigger and the open menu.

AI-assisted-by: claude-opus-5-5

* ♻️ Move comments panel styles closer to the DS

The comments panel stylesheet resolves its legacy sizes, spacing,
mixins and color aliases to DS values and tokens, with logical
properties, and inlines the asset element placeholder of the filter
trigger. refactor/ stays only for the dropdown placeholders, which move
with the menus group.

The legacy body-small typography becomes the DS one, which differs only
in its line height (1.3 instead of 1.4): the menu labels sit 1px
higher. The trigger looks the same at rest and on hover; the visual
test now also covers the hover.

AI-assisted-by: claude-opus-5-5
2026-10-28 09:20:22 +01:00
Eva Marco
f6f9df9a1a
♻️ Use DS icons in the layer row buttons (#12477)
* ♻️ Use DS icons in the layer row buttons

The expand, visibility and lock buttons of the layer rows drew their
icons with the deprecated icon set (arrow, shown, hide, unlock, lock).
Use the DS icon instead. The buttons stay raw: they are segments of the
layer row, with backgrounds that follow the row state.

The icons get a class each, so their colors move from svg rules to
those classes, and they keep the old stroke weight. The DS icon draws
12px inside a 16px box:

- The expand button start padding goes from 8px to 6px, so the arrow
  stays in place.
- The visibility and lock buttons leave 12px for the icon, so their
  icons do not shrink (flex-shrink: 0) and stay centered, uncut.

The rows look the same as before, pixel for pixel. Add a visual test
with a selected, hidden and blocked layer and a hovered row.

AI-assisted-by: claude-opus-5-5

* ♻️ Move the layer name styles off the deprecated styles

The layer name and its rename input used the deprecated body-small
typography, mixins, spacing and token aliases. They now use the DS
body-small typography, sizes, borders and px2rem(), and the layer row
color aliases resolve to their DS tokens, in layer_item.scss too.

The DS body-small has a 1.3 line-height instead of 1.4, so the layer
names sit 1px higher. The name color is one local variable for every
state; the rename input sets it too, since it also has .element-name.
A visual test now covers the rename input.

AI-assisted-by: claude-opus-5-5
2026-10-27 16:01:53 +01:00
Eva Marco
c26a67a8dd
♻️ Use a DS button for previous in the onboarding questions (#12550)
* ♻️ Use a DS button for previous in the onboarding questions

The "Previous" button of the onboarding questions becomes a DS
secondary button; it was a raw button with the deprecated modal cancel
styles. It is a bit narrower and its label uses the DS typography.

"Next" stays: it is the shared forms submit button. The "Other" option
icon stays too: it belongs to the forms image radio buttons, which move
with the radio buttons group. A visual test covers the step 2 buttons
at rest and with "Previous" hovered.

AI-assisted-by: claude-opus-5-5

* ♻️ Move onboarding questions styles closer to the DS

The onboarding questions stylesheet resolves its legacy modal color
aliases to DS tokens, uses logical properties and the DS typography
module without a namespace. refactor/ stays only for the modal
placeholders (%modal-*), which move with the modals refactor. No visual
change (checked on steps 1 and 2; only the shuffled options differ
between runs).

AI-assisted-by: claude-opus-5-5
2026-10-27 14:07:42 +01:00
Eva Marco
29e79edc66
♻️ Use DS buttons and icons in the dashboard team pages (#12531)
* ♻️ Use DS buttons and icons in the dashboard team pages

The team pages (members, invitations, webhooks and settings) and their
modals move off the deprecated icons and raw buttons:

- The member and webhook row menus become ghost DS icon buttons named
  "Options", with aria-expanded.
- The member and invitation role selectors become buttons with
  aria-haspopup and aria-expanded, and use the DS arrow icon. They were
  divs; one carried a role and an id repeated on every row.
- The four modal close buttons become ghost DS icon buttons named
  "Close"; the class that places them goes on the tooltip wrapper.
- "Create webhook" becomes a DS primary button.
- The webhook status, team image and settings icons use the DS icons.

The invitation checkbox tick stays until the checkbox migration. A
visual test covers the role and row menus, the resend and webhook
modals and the team image overlay.

AI-assisted-by: claude-opus-5-5

* ♻️ Move dashboard team styles to logical properties and DS tokens

The remaining legacy color aliases resolve to their DS tokens, physical
offsets and margins become logical properties, and the DS typography
module is used without a namespace. Four selectors that team.cljs does
not use are commented out with a TODO.

refactor/ stays only for component-family placeholders: %input-checkbox
and %checkbox-icon (checkboxes) and %modal-* (modals). The shared
dashboard header styles (common-dashboard) are used by ten dashboard
modules and move in their own change. No visual change.

AI-assisted-by: claude-opus-5-5

* 🐛 Open the team row menus below their button

The member and webhook row menus were placed from the bottom of their
cell with a fixed offset, so their position depended on the menu
height and the button height. The two-item webhook menu covered its
button, the member menu covered the lower part of it, and the taller DS
icon button moved both 3px down. They now open 4px below the button.

AI-assisted-by: claude-opus-5-5

* 🔥 Remove unused styles from the dashboard team pages

The SCSS refactor left four rules commented out with a TODO because
team.cljs does not use them. CSS modules scope the classes to this
module and no other source uses them, so they go: .dashboard-top-cta,
.error-notification, .empty-invitations-buttons and
.invitations-dropdown. No visual change.

AI-assisted-by: claude-opus-5-5

* 🐛 Find the member role selector as a button in the dashboard test

The "Bug 9443" test looked for the member role selector as a combobox.
The selector is now a button with aria-haspopup, so the test failed in
CI. It now looks for a button named "Admin", and checks that the owner
has no such button.

AI-assisted-by: claude-opus-5-5
2026-10-27 12:19:47 +01:00
Eva Marco
112e6dedd7
♻️ Use DS icons in the copy button (#12558)
* ♻️ Use DS icons in the copy button

The shared copy button (Inspect attribute rows and code blocks, share
link, integrations) draws its clipboard and tick icons with the DS
icons at the small size, colored through the color property. The
button itself stays: it wraps whole rows. The icons are the same
drawings, so nothing changes on screen.

A visual test covers an Inspect computed attribute row and the code
block copy button, at rest, on hover and after copying.

AI-assisted-by: claude-opus-5-5

* ♻️ Move copy button styles off the deprecated styles

The copy button stylesheet no longer imports refactor/: the
button-style, flex-center and copy-wrapper-base mixins are inlined with
DS values, the tertiary button and icon color aliases resolve to their
DS tokens, and physical properties become logical ones. No visual
change (whole viewer visual spec compared; the code tab syntax
highlighting loads late on a cold first run, with either stylesheet).

AI-assisted-by: claude-opus-5-5
2026-10-27 11:41:36 +01:00
Eva Marco
8800ff4bc9
♻️ Use DS buttons and icons in the assets tab (#12559)
* ♻️ Use DS buttons and icons in the assets tab

- "Add library" and "Manage library" become DS primary and secondary
  buttons, full width with the label centered; they keep their test id.
- The filter button stays a raw segment of the search bar; its legacy
  icon becomes the DS filter icon. Its opened state comes before the
  focus and hover rules, as the legacy placeholder did, so the focus
  border still shows.
- The create/rename group modal gets a ghost DS icon button named
  "Close", placed on the tooltip wrapper, and DS cancel (secondary) and
  create/rename (primary) buttons instead of raw inputs.

A visual test covers the add and manage library buttons, the filter at
rest, on hover and opened, and the create group modal.

AI-assisted-by: claude-opus-5-5

* ♻️ Move assets tab styles off the deprecated styles

assets.scss no longer imports refactor/: its mixins, sizes, spacing and
input / button icon color aliases resolve to DS values and tokens, with
logical properties. The unused .sections-container, .section-item and
.section-btn rules are deleted (the filter menu is the shared context
menu).

assets/groups.scss does the same and keeps refactor/ only for the modal
placeholders (%modal-*) and %input-with-label. Its legacy uppercase
title becomes the DS headline-small typography, which differs only in
its size (12px instead of 11px): the group modal grows 2px.

AI-assisted-by: claude-opus-5-5
2026-10-27 11:41:23 +01:00
Eva Marco
33d304c0af
♻️ Use DS icons in the dashboard sidebar (#12534)
* ♻️ Use DS icons in the dashboard sidebar

The search, clear search, pinned projects placeholder and logout icons
of the dashboard sidebar use the DS icons, and they get their color
from the color property. The two search buttons had untranslated test
names as their labels ("dashboard-search"); they are now named "Search"
and "Clear search". The pin keeps its place: the DS small icon draws
12px inside a 16px box, so its margins shrink by 2px.

New key: dashboard.clear-search (en, es). The dashboard page object
looks the search button up by its new name. A visual test covers the
search box with and without a term, the pinned projects placeholder and
the profile menu.

AI-assisted-by: claude-opus-5-5

* ♻️ Move dashboard sidebar styles off the deprecated styles

Legacy color aliases resolve to their DS tokens, deprecated mixins,
sizes and font variables are inlined with DS values, physical
properties become logical ones and the DS typography module is used
without a namespace. An invalid max-width with two values, which the
browser ignored, is gone.

Two rules that match nothing are commented out with a TODO: the profile
menu arrow svg rule (the arrow is the DS icon svg itself) and the
upgrade plan section, which sidebar.cljs does not use.

refactor/ stays only for the profile menu placeholders (%menu-dropdown,
%menu-item-base) and the shared dashboard header styles
(common-dashboard). No visual change.

AI-assisted-by: claude-opus-5-5

* 🔥 Remove unused styles from the dashboard sidebar

The SCSS refactor of the dashboard sidebar left rules commented out with
a TODO because the module does not use them, or because they target an
svg inside a DS icon that is the svg itself. CSS modules scope the
classes to this module and no other source uses them, so they go:
.profile-dropdown-item .open-arrow svg, .upgrade-plan-section,
.penpot-free, .no-limits, .power-up. No visual change.

AI-assisted-by: claude-opus-5-5
2026-10-27 11:41:19 +01:00
Eva Marco
afd838ea5b
♻️ Use DS buttons in the dashboard team modals (#12537)
* ♻️ Use DS buttons in the dashboard team modals

The close buttons of the create/rename team modal, the team permission
notice and the two "before you leave" modals become ghost DS icon
buttons named "Close"; the class that places them goes on the tooltip
wrapper. The cancel and "promote and leave" inputs of the leave modals
become DS buttons: secondary, and destructive once a member is picked
(primary and disabled before).

Two fixtures make the leave and reassign modal testable (the logged-in
user owns the second team, which has another member). A visual test
covers the create team modal and the leave and reassign modal.

AI-assisted-by: claude-opus-5-5

* ♻️ Move dashboard team modal styles closer to the DS

The change owner and team form stylesheets resolve their legacy color
aliases, spacing and typography mixins to DS tokens and use the DS
typography module without a namespace. The legacy uppercase title
becomes the DS headline-small typography, which differs only in its
size (12px instead of 11px): the "before you leave" title grows 1px and
the modal 2px. Unused selectors are commented out with a TODO.

refactor/ stays only for the modal placeholders (%modal-*), which move
with the modals refactor, and the input placeholders.

AI-assisted-by: claude-opus-5-5

* 🔥 Remove unused styles from the dashboard team modals

The SCSS refactor of the dashboard team modals left rules commented out
with a TODO because the module does not use them, or because they target
an svg inside a DS icon that is the svg itself. CSS modules scope the
classes to this module and no other source uses them, so they go:
.input-wrapper, .cancel-button, &.danger. No visual change.

AI-assisted-by: claude-opus-5-5
2026-10-27 10:58:13 +01:00
Eva Marco
19fc9ebce8
♻️ Use DS icons in the viewer flows and interactions menus (#12520)
* ♻️ Use DS icons in the viewer flows and interactions menus

The flows and interactions triggers in the viewer header were divs with
a click handler, and their menus lived inside them. They are now
buttons with aria-expanded and aria-haspopup, and each menu sits next
to its button in a wrapper, since a button cannot hold the menu
entries. The play, arrow and tick icons use DS icons. The menu entries
stay as they are.

A visual test covers the interactions menu closed and open; the test
files have no flows, and the flows trigger shares its styles.

AI-assisted-by: claude-opus-5-5

* ♻️ Move viewer interactions styles off the deprecated styles

Spacing, sizes, borders, typographies and color aliases move to DS
tokens and logical properties. The DS icons take their color from the
text and no longer shrink, so the old icon placeholders go away. The
DS body-small line-height is more compact, so the trigger labels sit
1px higher. The refactor/ import stays only for the shared menu
placeholders.

AI-assisted-by: claude-opus-5-5
2026-10-27 10:47:07 +01:00
Eva Marco
9854f8e54f
♻️ Move dashboard subscription styles off the deprecated styles (#12538)
* ♻️ Move dashboard subscription styles off the deprecated styles

The subscription stylesheet inlines the deprecated button-style and
flex-center mixins, resolves its legacy color aliases and sizes to DS
tokens, uses logical properties and the DS typography module without a
namespace. Three rules that match nothing (the arrow svg, .cta-link and
.open-arrow) are commented out with a TODO.

The subscription controls need no DS change: the plan card, the current
plan card and the manage subscription link have no DS equivalent, and
they use no legacy icons. refactor/ stays only for the power up menu
item placeholder and the shared dashboard header styles.

A visual test covers the sidebar plan card (closed and open), the team
settings plan and the members seats warnings. No visual change.

AI-assisted-by: claude-opus-5-5

* 🔥 Remove unused styles from the dashboard subscription

The SCSS refactor of the dashboard subscription left rules commented out
with a TODO because the module does not use them, or because they target
an svg inside a DS icon that is the svg itself. CSS modules scope the
classes to this module and no other source uses them, so they go:
.icon-dropdown svg, .cta-link, .open-arrow. No visual change.

AI-assisted-by: claude-opus-5-5
2026-10-27 10:23:55 +01:00
Eva Marco
411f661bdb
♻️ Use DS buttons in the delete shared libraries modal (#12554)
* ♻️ Use DS buttons in the delete shared libraries modal

The delete shared libraries modal (unpublish a library, delete a shared
file or project) gets a ghost DS icon button named "Close", placed on
the tooltip wrapper, and DS buttons for cancel (secondary) and accept
(destructive for the danger style, primary otherwise) instead of raw
inputs. The buttons are narrower and the accept button takes the DS
destructive red.

A new empty library references fixture and a visual test cover the
unpublish library modal from the workspace main menu.

AI-assisted-by: claude-opus-5-5

* ♻️ Move delete shared libraries modal styles closer to the DS

The delete shared libraries stylesheet resolves its legacy modal color
aliases to DS tokens, uses a logical property and the DS typography
module without a namespace. refactor/ stays only for the modal
placeholders (%modal-*), which move with the modals refactor. Two
unused selectors are commented out with a TODO. No visual change.

AI-assisted-by: claude-opus-5-5

* 🔥 Remove unused styles from the delete shared libraries modal

The SCSS refactor of the delete shared libraries modal left rules
commented out with a TODO because the module does not use them, or
because they target an svg inside a DS icon that is the svg itself. CSS
modules scope the classes to this module and no other source uses them,
so they go: &.transparent, .list-wrapper. No visual change.

AI-assisted-by: claude-opus-5-5
2026-10-27 10:20:11 +01:00
Eva Marco
f07452e36b
♻️ Use DS buttons and icons in the inspect code tab (#12521)
* ♻️ Use DS buttons and icons in the inspect code tab

"Copy all code" becomes a DS secondary button, and the expand panel
buttons ghost DS icon buttons labelled "Expand panel" (new key, en and
es). The collapse toggles of the CSS and markup blocks stay raw
buttons, since they sit in a 12px column; their arrow uses DS icons and
they get a name and aria-expanded. The copy buttons belong to the
shared copy button and move with it.

A visual test covers the code tab buttons, expanded and collapsed.

AI-assisted-by: claude-opus-5-5

* ♻️ Move inspect code tab styles off the deprecated styles

Spacing, sizes, borders, typographies and color aliases move to DS
tokens and logical properties. The 11px uppercase titles become the
12px DS headline-small, the only difference. The code typography keeps
its values with a TODO: the DS code-font names "Roboto Mono", while
the app loads "robotomono". The full-width "Copy all code" DS button
centers its label explicitly. The refactor/ import stays only for the
copy buttons, styled here until the shared copy button moves to the DS.

AI-assisted-by: claude-opus-5-5
2026-10-26 17:55:54 +01:00
Eva Marco
96b62f6475
♻️ Use DS buttons in the delete account modal (#12540)
* ♻️ Use DS buttons in the delete account modal

The close button of the delete account modal becomes a ghost DS icon
button named "Close"; the class that places it goes on the tooltip
wrapper. The cancel and delete buttons become DS secondary and
destructive buttons, so their labels no longer wrap and the delete
button takes the DS destructive red. The delete button keeps its test
id.

A visual test covers the modal at rest and with the close and delete
buttons hovered.

AI-assisted-by: claude-opus-5-5

* ♻️ Move delete account modal styles closer to the DS

The delete account stylesheet resolves its legacy sizes, spacing,
mixins and color aliases to DS tokens and uses logical properties and
the DS typography module without a namespace. The legacy uppercase
title becomes the DS headline-small typography, which differs only in
its size (12px instead of 11px), so the title and the content below sit
1px lower. The organization counts used a fixed dark-theme gray; they
now use the themed DS secondary foreground. Two unused selectors are
commented out with a TODO.

refactor/ stays only for the modal placeholders (%modal-*), which move
with the modals refactor.

AI-assisted-by: claude-opus-5-5

* 🔥 Remove unused styles from the delete account modal

The SCSS refactor of the delete account modal left rules commented out
with a TODO because the module does not use them, or because they target
an svg inside a DS icon that is the svg itself. CSS modules scope the
classes to this module and no other source uses them, so they go:
.fields-row, .select-title. No visual change.

AI-assisted-by: claude-opus-5-5
2026-10-26 17:17:46 +01:00
Eva Marco
376ecda94e
♻️ Move viewport top bar styles off the deprecated styles (#12488)
* ♻️ Move viewport top bar styles off the deprecated styles

The viewport top bars (view only bar of the inspect tab, path edition
bar) already use DS buttons. Move top_bar.scss to DS sizes, borders,
spacing tokens and logical properties, resolve the panel and shadow
color aliases, and drop the refactor import. The unused done-btn class,
the last user of the deprecated button placeholders here, goes away.
The two z-index values have no DS token, so they stay with a TODO.

Add a visual test of the view only bar; it looks the same as before,
pixel for pixel.

AI-assisted-by: claude-opus-5-5

* ♻️ Use the body-small typography in the viewport top bar title

The title only set a 12px font size, which body-small already has.
Use the DS typography instead of the inline size and its TODO. The
view only bar looks the same, pixel for pixel.

AI-assisted-by: claude-opus-5-5
2026-10-26 15:53:05 +01:00
Filip Sajdak
576bf4ed3d
✨ Close search and shortcuts panels with Escape (#12374)
* ✨ Close search and shortcuts panels with Escape

The workspace search and shortcuts panels could only be dismissed with
the mouse, which interrupts keyboard-first workflows.

A new use-escape-to-close hook gives each panel an on-key-down handler
that closes it on Escape while the user is working in it: the latest
pointer press or focus change must have landed inside the panel, or the
panel must hold focus when it opens (a panel that autofocuses its search
box, such as Shortcuts, is closed by the first Escape). Focus left
behind in a panel after the user moved on to the canvas does not count,
so Escape keeps its usual meaning there.

The handler never stops the event. The global Escape shortcut still
runs and finishes in-progress operations such as path drawing; an
earlier version stopped propagation and left a half-drawn path that
failed shape validation on the next commit.

In the search panel an open filters menu takes the first Escape and
the panel closes on the second.

The history panel needs no handler: Escape already closes it through
the :interrupt it emits.

Closes #9540

AI-assisted-by: claude-opus-5-5
AI-assisted-by: claude-sonnet-5-5
Signed-off-by: Filip Sajdak <filip.sajdak@siili.com>

* 📎 Add e2e test for closing panels with Escape

Cover the Escape handling added for the layers search and shortcuts
panels with four Playwright cases on the mocked workspace:

- Escape closes the layers search panel.
- With the search filters menu open, the first Escape closes only the
  menu and the second closes the panel.
- Escape closes the shortcuts panel right after it opens with `?`. The
  panel autofocuses its search box, so the first Escape must close it
  instead of only blurring the box.
- A path drawn while focus sits in the shortcuts panel is finished by
  Escape, which proves the panel does not swallow the global shortcut.

The first three cases fail on develop. The shortcuts case also fails
when the hook does not seed its tracker from the focused element.

AI-assisted-by: claude-sonnet-5-5
Signed-off-by: Filip Sajdak <filip.sajdak@siili.com>

* 🐛 Close History with Escape when opened by shortcut or menu

Only the header button opened History through initialize-history, which
removes the :document-history flag on the next :interrupt. The
Ctrl/Cmd+Alt+H shortcut and the "Version history" menu item toggled the
flag directly, so the global Escape left the panel open. Both now emit
initialize-history, like the header, and keep their own event origin.

Two e2e cases cover the shortcut and the menu; both fail without this
change.

AI-assisted-by: claude-sonnet-5-5
Signed-off-by: Filip Sajdak <filip.sajdak@siili.com>

* ♻️ Apply review suggestions to Escape-to-close

Use dom/child? instead of .contains in the Escape hook and drop the
redundant nil checks. Drive the path test through clickAt so its clicks
wait for the path tool. Add a negative Search case: Escape reaches the
panel after the last click landed on the viewport, and the panel stays
open. That case fails when the containment check is removed.

AI-assisted-by: claude-sonnet-5-5
Signed-off-by: Filip Sajdak <filip.sajdak@siili.com>

---------

Signed-off-by: Filip Sajdak <filip.sajdak@siili.com>
2026-10-26 14:42:43 +01:00
Eva Marco
e24e9dc747
♻️ Use DS buttons and icons in the viewer header (#12523)
* ♻️ Use DS buttons and icons in the viewer header

The section buttons, full screen and edit become ghost DS icon buttons
(the last two were spans), with aria-pressed where they toggle. Share
and "Log in or sign up" become DS buttons. The zoom widget becomes a
button that toggles its menu, like the workspace one, with DS zoom
buttons inside. The breadcrumb and the current board name become
buttons with aria-expanded, and the page menu moves next to its
button. The arrow and tick icons use DS icons. The logo stays: it is
brand art.

A visual test covers the header in two sections and both menus.

AI-assisted-by: claude-opus-5-5

* ♻️ Move viewer header styles off the deprecated styles

Spacing, sizes, borders, typographies and color aliases move to DS
tokens and logical properties, and the button placeholders go away.
The section buttons column goes from a fixed 92px to auto, since the
three 32px DS buttons no longer fit; the 1fr side columns keep it
centered. The zoom widget follows the workspace header one. The 11px
project name becomes the 12px DS headline-small. The global .selected
rule also highlighted the current page in the page menu: that row
keeps its highlight through its own rule. The refactor/ import stays
only for the shared menu placeholders; the options z-index (10) has no
DS token and keeps a TODO.

AI-assisted-by: claude-opus-5-5
2026-10-26 14:39:06 +01:00
Eva Marco
48a5875a71
♻️ Use DS icon buttons in the viewer board navigation (#12527)
* ♻️ Use DS icon buttons in the viewer board navigation

The previous, next and first board buttons of the viewer become
secondary DS icon buttons with the DS arrow and reload icons. They keep
their size and the viewer background at rest; on hover they take the DS
secondary look. The first board button had no accessible name; it is
now labelled. The position classes move to the tooltip wrappers, so the
fullscreen and comments sidebar offsets still apply.

New key: viewer.go-to-first-board (en, es). A visual test covers the
buttons at rest and on hover.

AI-assisted-by: claude-opus-5-5

* ♻️ Move viewer styles off the deprecated styles

Spacing, sizes, borders, typographies and color aliases move to DS
tokens and logical properties, and the file no longer imports
refactor/. The section scrollbar uses the DS custom-scrollbar mixin; the
text selection and placeholder styles that %new-scrollbar gave to the
comments layer stay, with DS tokens of the same value. An invalid
padding-right with four values, which the browser ignored, is gone.

The DS body-small typography differs from the old one only in a more
compact line-height, so the board counter sits 1px higher. The z-index
values (10, 2) have no DS token and keep a TODO. The .viewer-header,
.not-fixed, .fixed and .frame-children rules are not used by this module
and are commented out with a TODO.

AI-assisted-by: claude-opus-5-5

* 🔥 Remove unused styles from the viewer

The SCSS refactor of the viewer left rules commented out with a TODO
because the module does not use them, or because they target an svg
inside a DS icon that is the svg itself. CSS modules scope the classes
to this module and no other source uses them, so they go:
.viewer-header, .not-fixed, .fixed, .frame-children g. No visual change.

AI-assisted-by: claude-opus-5-5
2026-10-26 12:48:43 +01:00
Eva Marco
a5fd2df1f0
♻️ Make the grid track direction icon and the swap groups buttons (#12476)
* ♻️ Make the grid track direction icon a button

The direction icon at the start of each grid track value field selected
that column or row from a div with a click handler: no button role, no
name and no keyboard access. Make it a button labeled "Select column" or
"Select row", keeping its class and handler, and reset the browser
border so it looks the same. It stays a raw button: it is a segment of
the track field, not a DS button.

Add the workspace.layout-grid.editor.select-column and select-row keys
(en, es).

AI-assisted-by: claude-opus-5-5

* ♻️ Make the component swap panel groups buttons

The groups of the component swap panel opened from a div with a click
handler: no button role and no keyboard access. Make each group a
button, keeping its class, title and handler, and reset the browser
button styles so it looks the same. Its name is the visible group name.

Add a visual test with a fixture whose components sit in two groups, so
the swap panel lists them.

AI-assisted-by: claude-opus-5-5
2026-10-26 11:38:33 +01:00
Eva Marco
bac62a27bf
♻️ Use DS icons in the viewer comments filter (#12519)
* ♻️ Use DS icons in the viewer comments filter

The "Comments" filter trigger in the viewer header was a div with a
click handler, and its menu lived inside it. It is now a button with
aria-expanded and aria-haspopup, and the menu sits next to it in a
wrapper, since a button cannot hold the menu entries. The arrow and the
ticks use DS icons. The menu entries stay as they are.

A visual test covers the filter closed and open.

AI-assisted-by: claude-opus-5-5

* ♻️ Move viewer comments styles off the deprecated styles

Spacing, sizes, borders, typographies and color aliases move to DS
tokens and logical properties. The DS icons take their color from the
text and no longer shrink, so the old icon placeholders go away. The
DS body-small line-height is more compact, so "Comments" sits 1px
higher. The refactor/ import stays only for the shared menu
placeholders. The z-index values (1 and 10) have no DS token and keep a
TODO.

AI-assisted-by: claude-opus-5-5
2026-10-26 11:36:46 +01:00
Eva Marco
ef17aea39e
♻️ Use DS icon buttons in the viewer thumbnails panel (#12518)
* ♻️ Use DS icon buttons in the viewer thumbnails panel

The expand, close and scroll buttons of the viewer thumbnails panel
become ghost DS icon buttons. They had no accessible name; they are now
labelled, and the expand button says whether the panel is expanded. The
rotated legacy arrow gives way to the DS arrow icons. The thumbnails
stay raw buttons, since they are list items.

New keys: labels.expand and viewer.thumbnails.scroll-left/right (en,
es). A visual test covers the panel collapsed, on hover and expanded.

AI-assisted-by: claude-opus-5-5

* ♻️ Move viewer thumbnails panel styles off the deprecated styles

Spacing, sizes, borders, typographies and color aliases move to DS
tokens and logical properties, and the file no longer imports
refactor/. The scroll buttons keep their 60px height through
--button-height and still show only on hover; their tooltip wrappers
take the grid cells. The DS body-small typography differs from the old
one only in a more compact line-height, so the counter and the board
names sit 1px higher. The panel z-index (10) has no DS token and keeps
a TODO.

AI-assisted-by: claude-opus-5-5
2026-10-26 10:33:11 +01:00
Eva Marco
9911f82087
♻️ Use a DS icon in the grid editor track options button (#12486)
* ♻️ Use a DS icon in the grid editor track options button

The options button of each grid track on the canvas drew a deprecated
icon and had no accessible name. Use the DS menu icon and label the
button "Track options". The button stays raw: it lives on the canvas,
where the track editor keeps a fixed screen size at any zoom.

The DS icon has a fixed 16px size, so its class scales it down with the
zoom (transform: scale(1 / zoom)), as the old svg rule did with its
width. It looks the same, but for a few antialiasing pixels.

Add the workspace.layout-grid.editor.track-options key (en, es) and a
visual test of a track at two zoom levels.

AI-assisted-by: claude-opus-5-5

* ♻️ Move grid editor styles off the deprecated styles

Move grid_layout_editor.scss to DS sizes, borders, spacing tokens,
colors and logical properties, and drop the refactor import. The canvas
sizes keep their division by the zoom. The grid editor color aliases
resolve to their DS tokens, and the unused close-btn class, the last
user of the deprecated button placeholders here, goes away.

The track editor and the editing bar look the same as before.

AI-assisted-by: claude-opus-5-5
2026-10-26 10:32:06 +01:00
Eva Marco
7ff8df6ffb
♻️ Name the grid track expand buttons and make the annotation toggle a button (#12489)
* ♻️ Name the grid track expand buttons

The menu button that expands the columns or rows of a grid layout had no
accessible name. Label it "Columns" or "Rows" and expose its state with
aria-expanded. The track title next to it also toggles on click; it
stays a div, as a larger pointer target for the same action, so the
keyboard does not stop twice on it.

Add the workspace.layout-grid.editor.columns and rows keys (en, es).

AI-assisted-by: claude-opus-5-5

* ♻️ Make the annotation title toggle a button

The annotation title of a component toggled from a div with a click
handler, and it holds the edit, delete, save and discard buttons, so it
cannot become a single button. Move the toggle to a button with the
arrow and the "Annotation" name, with aria-expanded, that takes the
whole free width of the title. While editing or creating, the title
stays text and no longer collapses the annotation on click, as its
cursor already suggested.

Extend the annotation visual test with the collapsed state; it looks the
same as before, pixel for pixel.

AI-assisted-by: claude-opus-5-5
2026-10-26 10:31:51 +01:00
Eva Marco
ac08e38c1a
♻️ Use DS buttons and icons in the export assets modal (#12517)
* ♻️ Use DS buttons and icons in the export assets modal

The export modal close button becomes a ghost DS icon button and the
progress toast close button an action one, which fits its 24px grid
column; both are labelled "Close". Cancel and Export become DS buttons.
The checkbox ticks and the toast icons use DS icons. The selection rows
stay raw buttons, since they are list rows, and so does the link-styled
retry/cancel button of the toast.

The export frames e2e spec now finds the Export button by role, and a
visual test covers the modal with all, some and no rows selected.

AI-assisted-by: claude-opus-5-5

* ♻️ Make the export progress ring a button

The export progress ring in the header opens the export details, but it
was a div with a click handler. It is now a button named after the
export status, with aria-expanded, and keeps its look.

AI-assisted-by: claude-opus-5-5

* ♻️ Move export assets modal styles off the deprecated styles

Spacing, sizes, borders, typographies and color aliases move to DS
tokens and logical properties, and the button placeholders go away.
The classes left without use are removed: the old modal buttons, the
old close icon, and the file export entries, which live in files.scss.

The refactor/ import stays only for the shared modal and checkbox
placeholders, which move to the DS with the modals and the checkboxes.
The checkbox placeholder shrinks a ticked icon to 12px, which pushed
the DS tick off center: the tick keeps its 16px box now, and does not
shrink inside the 14px flex box either.

AI-assisted-by: claude-opus-5-5
2026-10-26 10:31:34 +01:00
Eva Marco
29b00f8535
♻️ Use DS icons in the text palette and its menu (#12452)
* ♻️ Use DS icons in the text palette and its menu

The scroll arrows of the text palette and the tick of the selected
palette in its menu used deprecated icons; use the DS arrow and tick
icons instead. The arrows are full-height scroll buttons with a fade, not
DS button sizes, so they stay raw buttons.

Add a visual test that opens a file with 16 local typographies, so the
arrows show, and captures the palette at rest, with the pointer over the
right arrow, after scrolling and with its menu open. Its fixture is the
library fixture with more typographies.

AI-assisted-by: claude-opus-5-5

* ♻️ Move text palette styles off the deprecated styles

Inline the button, flex and ellipsis mixins, move spacing, sizes and
borders to DS tokens and logical properties, and resolve the color
aliases to their DS tokens. The arrow, item and menu colors that change
on hover, disable or selection go through local variables, and the new
icons take them through currentColor instead of svg selectors. The three
typography lines share their ellipsis rule. The .disabled ::after rule
of the left arrow never matched and goes away; :disabled::after already
covers it.

The items, the empty message and the menu use the DS body-small
typography, whose line-height is 1.3 instead of 1.4. The arrows keep
their z-index, now commented, and the menu its legacy context menu one.

text_palette.scss and text_palette_ctx_menu.scss no longer import
refactor/.

AI-assisted-by: claude-opus-5-5

* 🐛 Show the text palette scroll arrows at rest

The enabled scroll arrows of the text palette had no color at rest, so
they only showed on hover, while the color palette arrows show in the
secondary color. Give them the same rest color.

AI-assisted-by: claude-opus-5-5
2026-10-26 10:31:14 +01:00
Eva Marco
904f456c61
♻️ Use DS icons in the color palette and its menu (#12444)
* ♻️ Use DS icons in the color palette and its menu

The scroll arrows of the color palette and the tick of the selected
palette in its menu used deprecated icons; use the DS arrow and tick
icons instead. The arrows are full-height scroll buttons with a fade, not
DS button sizes, so they stay raw buttons. The color cells are swatches
and stay as they are.

Add a visual test that opens a file with 24 local colors, so the arrows
show, and captures the palette before and after scrolling and with its
menu open. Its fixture is the library fixture with more colors.

AI-assisted-by: claude-opus-5-5

* ♻️ Move color palette styles off the deprecated styles

Inline the button, flex and ellipsis mixins, move spacing, sizes and
borders to DS tokens and logical properties, and resolve the color
aliases to their DS tokens. The arrow and menu item colors that change
on hover, disable or selection go through local variables, and the new
icons take them through currentColor instead of svg selectors.

The empty palette message and the menu items use the DS body-small
typography, whose line-height is 1.3 instead of 1.4. The arrows keep
their z-index, now commented: the left arrow comes before the
positioned color list, so without it the colors would cover its fade.
The menu keeps its legacy context menu z-index, also commented.

color_palette.scss and color_palette_ctx_menu.scss no longer import
refactor/.

AI-assisted-by: claude-opus-5-5
2026-10-26 10:27:13 +01:00
Eva Marco
6acb360f4a
♻️ Use DS icons and an icon button in the undo history panel (#12472)
* ♻️ Use DS icons and an icon button in the undo history panel

The undo history panel (History > Actions) drew its entry type icons
with the deprecated icon set, and the arrow that shows the details of an
entry was a div with a click handler: no button role, no keyboard
access and no accessible name.

- The entry type icons use the DS icon (drop-icon is i/drop in the DS).
- The arrow becomes a DS action icon button labeled "Show details", with
  aria-expanded for its state. It keeps its data attribute, its classes
  and its click handler, and it also shows on keyboard focus.

The DS icon draws 12px inside a 16px box, so the entry icon gets a
negative margin, and the button wrapper a negative end margin: icon,
arrow and text stay where they were. The arrow turns through its own
class instead of an svg rule.

Add the workspace.undo.entry.show-details key (en, es) and a visual test
that draws a rectangle, opens the actions list and expands the entry.

AI-assisted-by: claude-opus-5-5

* ♻️ Move undo history panel styles off the deprecated styles

Move history.scss to DS tokens, sizes, borders and logical properties,
and drop the refactor import. The entry color aliases become local
variables of the entry, set by its disabled and hover states, and the
arrow opacity goes through one as well.

AI-assisted-by: claude-opus-5-5

* 💄 Place the undo history icon and arrow without negative margins

Drop the -2px margin of the entry icon and the -6px end margin of the
details button wrapper. Keep text and arrow in place with token spacing
instead: the text after the 16px icon box starts with --sp-xs instead
of --sp-s, and the entry end padding is --sp-xxs, since the 24px button
leaves 6px around its 12px arrow. The icon now sits 2px to the right,
centered in its box.

AI-assisted-by: claude-opus-5-5
2026-10-21 15:59:31 +02:00
Eva Marco
d6e850e917
♻️ Use DS icon buttons for the bottom palette toggles (#12443)
* ♻️ Use DS icon buttons for the bottom palette toggles

The color palette and typographies toggles of the bottom palette were raw
buttons with deprecated icons. Replace them with DS ghost icon buttons
with small icons, as before, that show the open palette through
aria-pressed. The layout flags are keywords, so they are coerced to a
boolean for aria-pressed. Their title moves to the label, shown in the DS
tooltip with the shortcut.

The palette actions button spans the palette height, not a DS button
size, so it stays raw; only its deprecated icon moves to the DS icon.

Add a visual test that compares the palette with each toggle selected
with no tolerance.

AI-assisted-by: claude-opus-5-5

* ♻️ Move bottom palette styles off the deprecated styles

The palette toggles are DS icon buttons, so their placeholders go away.
The actions button keeps the tertiary button look through local state
variables, and its icon takes the color from the button. Spacing, sizes,
borders, opacity and the color aliases move to DS tokens and logical
properties, except right and width of the palette, which are the
transitioned properties. The grid template is split into areas, rows and
columns, since Sass reads its slash as a division with a size variable.

The z-index values came from the legacy global scale. The resize area,
the toggles and the actions button had their own (4, 2 and 2), plus 0
overrides while collapsed, but they sit in separate grid areas and the
palette content does not reach them: removing them changes no pixel with
the text or color palette, the actions menu open, the 80px size, or the
palette collapsed and hidden. Only the palette's own z-index stays, with
a comment: it keeps the palette above the viewport overlays (z-index 1),
and drops to their level while collapsed.

The help button styles are not used in palette.cljs, but the external
chat widget injected into the palette wrapper may use them, so they stay,
inlined on DS tokens.

palette.scss no longer imports refactor/.

AI-assisted-by: claude-opus-5-5

* ♻️ Use a DS icon button for the bottom palette actions

The palette actions button (⋮) stayed a raw button because it spans the
palette height, not a DS button size. The DS icon button takes its
height from --button-height, so a class now stretches it to the palette
and the hand-made colors and states go away. It uses the ghost variant,
like the palette toggles next to it.

The button had no accessible name and did not say that it opens a menu:
it now has the "Palette options" label (new en and es keys) with its
tooltip, aria-expanded and aria-haspopup. The class given to its icon
did not exist in palette.scss and is gone.

Only the button corners change in the palette screenshots: the raw
button painted its own rounded background, the ghost button is
transparent at rest.

AI-assisted-by: claude-opus-5-5
2026-10-21 14:35:12 +02:00
Eva Marco
1d54d170cf
♻️ Move layers panel styles off the deprecated button styles (#12478)
The layers panel already uses DS icons and buttons; its two raw buttons
(the layer filter pill and the focus mode title) stay raw, since they are
custom widgets. Their styles still used the deprecated %button-tag
placeholder and color aliases.

- Inline %button-tag in the filter pill: border, cursor, centering, and
  its focus and pressed states through local variables. Its hover rule
  set the icons to the color they already had, so it goes away.
- Resolve the icon, title, pill and menu color aliases to DS tokens. The
  filter menu item texts are the same color in every state, so only the
  background changes, through a local variable.

The refactor import stays for the shared %menu-dropdown placeholder.
Add a visual test of the focus mode title, a filter pill and the filter
menu; the panel looks the same as before, pixel for pixel.

AI-assisted-by: claude-opus-5-5
2026-10-21 14:11:15 +02:00
Eva Marco
5259b4b2d5
♻️ Use DS buttons in the workspace right header (#12454)
* ♻️ Use DS buttons in the workspace right header

The comments and history buttons were raw buttons with deprecated icons;
they become DS ghost icon buttons that show their state through
aria-pressed, with the unread dot as a child of the comments button. The
view mode link had a click handler and no href; it becomes a DS icon
button too, so it gets a button role and keyboard activation. Their
tooltips open below and to the left, at the top right corner of the
screen. The zoom menu's Reset is a DS ghost button.

The share link stays raw with its deprecated icon until the DS has a
share icon; it now uses its own class instead of the view mode one.

Add a visual test that captures the header at rest, with comments
active, and with the zoom menu open.

AI-assisted-by: claude-opus-5-5

* ♻️ Move workspace right header styles off the deprecated styles

The comments, history and view mode buttons are DS icon buttons, so their
placeholders go away; the comments class only holds the unread dot. The
zoom widget color goes through a local variable, and spacing, sizes,
borders and the color aliases move to DS tokens and logical properties.

Delete the save status rules: the status widget moved to the left header
in #5773 and nothing here uses them anymore.

refactor/ stays only for the shared menu placeholders and for the
tertiary button and icon placeholders of the share link.

AI-assisted-by: claude-opus-5-5

* 🐛 Give the action icon button a color while pressed or active

The action variant of the DS icon button set the active background but
not the active foreground, so it kept the base value, initial. A custom
property set to initial is invalid at computed time, so the icon took
the color of its container while the button was pressed (:active) or
toggled on (aria-pressed): yellow in the workspace header, for example.

Use the accent color, as the ghost and secondary variants do.

AI-assisted-by: claude-opus-5-5

* 💄 Use the action variant for the right header icon buttons

The comments, history and view mode buttons had no background at rest,
on hover or while active. The DS action variant keeps that: no
background at rest and on hover, accent icon on hover. It is 24px
instead of the ghost 32px, and shows a small background while comments
or history is on.

The unread dot moves to 4px from the button corner, so it stays over the
top right corner of the icon in the smaller button.

AI-assisted-by: claude-opus-5-5

* 💄 Drop the background of a pressed action icon button

A toggled-on action icon button (aria-pressed) showed the quaternary
background next to the accent icon. Keep only the accent icon, as the
workspace header buttons looked before the DS migration. The background
stays for the click feedback (:active).

Only the right header comments and history buttons use the action
variant with aria-pressed today.

AI-assisted-by: claude-opus-5-5

* 💄 Widen the gap between the right header actions

The action icon buttons are 24px wide, smaller than the old ones, so
the comments, history and view mode buttons sat closer together than
before the DS migration. Raise the header gap from --sp-s to --sp-m to
keep the old spacing between the icons without resizing the buttons.
The separator absorbs the extra space, so the header width stays the
same.

AI-assisted-by: claude-opus-5-5

* ♻️ Make the right header zoom widget a button

The zoom percentage of the right header opened its menu from a div with
a click handler: no button role and no keyboard access. Make it a
button with aria-expanded, keeping its classes, title and handler; its
visible percentage is its accessible name. Reset the browser padding of
the button so the percentage stays in place.

AI-assisted-by: claude-opus-5-5

* ✨ Toggle the zoom dropdown from the zoom widget

Clicking the zoom widget while its dropdown was open left it open: the
handler always set the open state, and it stops the click before the
dropdown sees it. The widget now toggles the dropdown, as its
aria-expanded already suggests. Closing from outside or with Escape
works as before.

AI-assisted-by: claude-opus-5-5
2026-10-21 14:10:34 +02:00
Eva Marco
5dbf0731e5
♻️ Use DS buttons and icons in the plugins dialogs (#12470)
* ♻️ Use DS buttons and icons in the plugins dialogs

The plugins manager and the permissions, permissions update and try-out
dialogs used raw buttons, input elements styled as buttons and
deprecated icons. Replace them with the DS components:

- The four close buttons become ghost icon buttons labeled "Close", shown
  in their DS tooltip. The class that places them in the corner goes on
  the tooltip wrapper, so the tooltip anchors to the button.
- Install, and the cancel and accept buttons of the three dialogs, become
  DS primary and secondary buttons.
- The empty list puzzle and the external link icons use the DS icon.

The permission icons (oauth-*) stay: they are brand art.

Add a visual test with fixtures for a team with the plugins feature and
a profile with one installed plugin. It shows the empty manager, the
manager with a plugin and the permissions dialog.

AI-assisted-by: claude-opus-5-5

* ♻️ Move plugins dialog styles off the deprecated styles

Remove the styles the DS buttons and icons no longer need (close-icon,
primary-button, cancel-button, search-icon and the svg rules of the
migrated icons) and move the rest of plugins.scss to DS tokens, DS
typographies and logical properties.

- The close button wrapper keeps only its position; the deprecated
  tertiary button style was landing on the tooltip wrapper.
- The full-width cancel and accept buttons center their label again: the
  DS button does not center it when it grows.
- The external link icon gets a class instead of an svg rule.
- The deprecated body-small used line-height 1.4 and the DS one 1.3, so
  the permissions dialog is a few pixels shorter.

The refactor import stays for the modal placeholders until the modals
move to the DS modal.

AI-assisted-by: claude-opus-5-5
2026-10-21 13:11:04 +02:00
Eva Marco
858d5dad9c
♻️ Use DS buttons in the debug shape panel (#12484)
* ♻️ Use DS buttons in the debug shape panel

The object and tree dump buttons of the debug shape panel were raw
buttons with the browser default look. Use DS secondary buttons. The
DS buttons are taller, so the title row centers the shape name.

Add a visual test that turns on the shape-panel debug option and shows
the title row of the selected shape.

AI-assisted-by: claude-opus-5-5

* ♻️ Move debug shape panel styles off the deprecated styles

Move debug_shape_info.scss to DS spacing tokens, borders and logical
properties, resolve the panel background alias, and drop the refactor
import. The two font sizes match no DS typography, so they stay with a
TODO, and the unused shape-info-title class is commented out for a
manual check. The panel looks the same as with the previous commit.

AI-assisted-by: claude-opus-5-5

* 🐛 Let the debugging tools options scroll

The debugging tools panel lists 32 options in the left sidebar, whose
content area hides what overflows. On a short window the last options
were cut off with no way to reach them. Make the options list fill the
space under the title and scroll on its own.

AI-assisted-by: claude-opus-5-5

* ♻️ Move debugging tools panel styles to DS tokens

Move debug.scss spacing, size and the panel background alias to DS
tokens and logical properties. The refactor import stays only for the
checkbox placeholders, until the checkboxes move to the DS. The panel
looks the same as before.

AI-assisted-by: claude-opus-5-5
2026-10-21 12:32:09 +02:00
Eva Marco
47d7ad2de1
♻️ Explain layout_container's deprecated import and format visual spec (#12449)
* ♻️ Explain why layout_container.scss keeps the deprecated import

The TODO at the top said to remove the refactor/ import once the buttons
were replaced, and sat above the DS imports instead of that one. The
buttons are now DS buttons (#12428, #12431), but the import is still
needed by the numeric inputs (%input-element, %disabled-input) and by the
two raw track header buttons, which keep the secondary and tertiary
placeholders. Replace the TODO with a comment on the import that says so.

AI-assisted-by: claude-opus-5-5

* 📎 Format the workspace visual spec with Prettier

Three expectations added in #12423, #12428 and #12431 broke a call chain
in a way Prettier rewrites. check-fmt:js did not catch it: its
playwright/**/*.js glob is expanded by the shell without globstar, so it
does not reach visual-specs/.

AI-assisted-by: claude-opus-5-5
2026-10-20 09:19:17 +02:00
Eva Marco
9904e50889
♻️ Use DS icon buttons in the component options (#12394)
* ♻️ Use a DS icon button for the component pill menu

Replace the raw three dots button of the component pill with the DS
secondary icon button. It had no label, so it reuses the "Options" one,
shown in the DS tooltip above and to the left (it sits at the right edge
of the sidebar), and aria-pressed while the menu is open instead of the
selected class.

Its class drops the button placeholders and only keeps the pill segment
shape: full height and square corners on the left. The tooltip wrapper
fills the segment too.

Add a visual test that selects a component copy so the pill shows.

AI-assisted-by: claude-opus-5-5

* ♻️ Use DS icon buttons for the component annotation actions

The save/create, discard, edit and delete actions of a component
annotation were divs with a click handler: no keyboard focus and no button
role. Replace them with DS ghost icon buttons. Their title moves to the
label, shown in the DS tooltip above and to the left, and save is disabled
while the text is blank, which it already ignored.

The class that hides them until the title is hovered, or while editing or
creating, now goes on the tooltip wrapper. The green and red hover colors
and the fixed size go away with the DS look. While editing or creating,
the actions get a small padding so their hover background does not touch
the annotation border; the title row grows from 32 to 36px there.

Add a visual test that creates an annotation on a main component and
shows both sets of actions.

AI-assisted-by: claude-opus-5-5

* 💄 Open component options tooltips above and to the left

The variants help, create variant, add property and remove property icon
buttons sit at the right edge of the sidebar: open their tooltips above
and to the left, like the other actions of the component options.

AI-assisted-by: claude-opus-5-5

* ♻️ Move component options styles off the deprecated styles

Inline the dropdown placeholders of the component pill menu with DS
tokens and a local variable for the item colors that change on hover, and
give the item label its own class instead of styling the span. Resolve
the annotation title border alias to its DS token and delete the unused
.component-title-actions rule.

The item label uses the DS body-small typography; its line-height is 1.3
instead of 1.4, with no visible change since the item centers it.

component.scss no longer imports refactor/.

AI-assisted-by: claude-opus-5-5
2026-10-20 09:18:49 +02:00
Eva Marco
7e5e589744
♻️ Use a DS icon button for the guide defaults menu (#12391)
* ♻️ Use a DS icon button for the guide defaults menu

Replace the raw three dots button that opens the use default / set as
default menu of a guide with the DS ghost icon button. It had no label, so
it gets a new "Guide defaults" one, shown in the DS tooltip, and
aria-pressed while the menu is open instead of the selected class.

The add, show/hide and remove guide buttons, and the new one, sit at the
right edge of the sidebar: open their tooltips above and to the left.

The advanced options toggle stays a raw button: it is one segment of the
guide type control and an icon button would break that shape.

Add a visual test that adds a guide to a board and opens its advanced
options.

AI-assisted-by: claude-opus-5-5

* ♻️ Remove guide defaults button styles

The three dots guide defaults button is a DS icon button now: delete the
.show-more-options rule, its state variables and its svg rule. The rest of
frame_grid.scss already uses DS tokens.

AI-assisted-by: claude-opus-5-5
2026-10-20 09:18:24 +02:00
Andrey Antukh
fffc3ee222 Merge remote-tracking branch 'origin/staging' into develop 2026-10-19 22:18:27 +02:00
Eva Marco
cdb7dc2977
♻️ Use a DS button for edit grid in the grid cell options (#12385)
* ♻️ Use a DS button for edit grid in the grid cell options

Replace the raw "Edit grid" button of the grid cell options with the DS
secondary button. Drop its alt attribute, which is not valid on a button;
the label already names it.

The column and row icons label the numeric inputs, so they move with the
numeric inputs migration.

Add a visual test that selects a cell in grid edit mode so the options
show.

AI-assisted-by: claude-opus-5-5

* ♻️ Move grid cell options styles to DS tokens

The edit grid button is a DS button now, so its button placeholder and
typography mixin go away; the class only stretches it and centers its
label. Merge the two .grid-cell-menu-container rules, inline the flex
mixins, and move spacing, borders and color aliases to DS tokens and
logical properties.

Use the DS body-small typography in the inputs; its line-height is 1.3
instead of 1.4.

The refactor/ import stays only for %input-element and %button-icon, used
by the inputs and their legacy icons, which move with the numeric inputs
migration.

AI-assisted-by: claude-opus-5-5
2026-10-19 17:05:22 +02:00
Eva Marco
1c70b0ce2d
♻️ Use the DS icon in the workspace left header (#12432)
* ♻️ Use the DS icon in the workspace left header

The shared library badge of the left header used a deprecated icon; use
the DS library icon instead.

Drop the deprecated icons inside the save status dot. They rendered as
500px SVGs with no stroke, so they never showed: the dot is only its
background color, and its title keeps the status text. The Penpot logo is
brand art and stays.

Add a visual test that opens a shared file and shows the header with the
badge, then the saved status after drawing a shape.

AI-assisted-by: claude-opus-5-5

* ♻️ Move workspace left header styles off the deprecated styles

Inline the flex and ellipsis mixins, move spacing, sizes and borders to
DS tokens and logical properties, and resolve the color aliases to their
DS tokens. The status dot takes its color from a local variable. The
badge icon gets its color through a class instead of an svg selector.

The project name uses the DS headline-small typography: 12px instead of
11px. The file name matches title-small exactly.

Left with a TODO: the rename input font size and z-index have no DS
match, and the pending status orange (#f5a91b) has no DS color.

left_header.scss no longer imports refactor/.

AI-assisted-by: claude-opus-5-5

* ♻️ Resolve the TODOs left in the workspace left header styles

The status dot used the legacy warning orange #f5a91b, which drifted from
the DS one when both replaced #fe4811 a few days apart in early 2025. Use
the DS --color-accent-warning (#fe9c07), the orange of every other DS
warning, so the dot looks a little more orange while saving.

The rename input had z-index 20, which did nothing: the input is neither
positioned nor a flex or grid item. Remove it.

The rename input only set its font size and got the rest from the global
reset; it now uses the DS title-small typography, like the file name. Its
line-height goes from normal to 1.2, so it grows from 16 to 16.8px.

AI-assisted-by: claude-opus-5-5
2026-10-19 15:52:48 +02:00
Eva Marco
e4da0527fc
♻️ Use DS buttons and icons in the grid layout options (#12431)
* ♻️ Use DS buttons and icons in the grid layout options

The "Edit grid" button of a grid layout and the "Exit" button of the grid
editor were raw buttons with the deprecated secondary style. Replace them
with DS secondary buttons; their text and actions stay the same. Drop the
"alt" attribute of "Edit grid": it is not valid on a button.

The expand and add buttons of the column and row headers are 52px parts of
a custom header, not DS buttons, so they stay raw; only their deprecated
icons move to the DS icon, as does the direction icon of each track.

Add a visual test that shows the grid layout options and the grid editor
with the column tracks expanded.

AI-assisted-by: claude-opus-5-5

* ♻️ Remove deprecated button styles from the grid layout options

"Edit grid" and "Exit" are now DS buttons, so their secondary placeholder
and typography go away; the classes only place them in the grid and center
their label. The track header and direction icons drop the deprecated icon
placeholder and get their colors through classes. The header buttons keep
their secondary and tertiary placeholders, since they stay raw.

AI-assisted-by: claude-opus-5-5
2026-10-19 15:49:14 +02:00
Eva Marco
3d6823eacd
♻️ Use DS icon buttons for the flex wrap and padding mode (#12428)
* ♻️ Use DS icon buttons for the flex wrap and padding mode

The wrap button of a flex layout and the button that shows the four
padding sides (flex and grid layouts) were raw buttons with deprecated
icons. Replace them with DS ghost icon buttons that show their state
through aria-pressed, with the tooltip above and to the left since they
sit at the right edge of the sidebar.

The wrap label is now always "Wrap": its title switched to "No wrap"
while pressed, which conflicts with the pressed state.

Add a visual test that selects a flex board and shows both buttons at
rest and pressed.

AI-assisted-by: claude-opus-5-5

* ♻️ Remove deprecated wrap and padding toggle styles

The wrap and padding mode buttons are now DS icon buttons, so their
tertiary button, icon and selected placeholders go away. The tooltip
wrappers take the same grid cells the buttons had.

AI-assisted-by: claude-opus-5-5
2026-10-19 15:48:59 +02:00
Eva Marco
398678e54c
♻️ Use a DS icon button for the layout element margin mode (#12423)
* ♻️ Use a DS icon button for the layout element margin mode

The button that switches a flex or grid element between simple and
multiple margins was a raw button with a deprecated icon. Replace it with
a DS ghost icon button that shows the multiple state through aria-pressed.
Its title moves to the label, shown in the DS tooltip above and to the
left since the button sits at the right edge of the sidebar. The grid
column class goes on the tooltip wrapper.

The legacy margin icons label the numeric inputs and stay for the numeric
inputs group; the radio buttons are out of scope.

Add a visual test that selects a flex element and shows both margin modes.

AI-assisted-by: claude-opus-5-5

* ♻️ Remove deprecated button styles from layout element options

The margin mode button is now a DS icon button, so its tertiary button,
icon and selected placeholders and the deprecated 32px height go away.
The class only places the tooltip wrapper in the third grid column.

The refactor/ import stays for %input-element, still used by the legacy
numeric inputs.

AI-assisted-by: claude-opus-5-5
2026-10-19 15:48:43 +02:00
Eva Marco
c345c7cbaa
♻️ Use a DS icon button to remove imported SVG attributes (#12382)
* ♻️ Use a DS icon button to remove imported SVG attributes

Replace the raw remove button of each imported SVG attribute with the DS
ghost icon button and the DS remove icon. The button had no title, so it
gets a new "Remove attribute" label, which the DS tooltip shows. Drop the
wrapper div that only held the button.

Add a visual test that selects a group imported from SVG so the section
shows.

AI-assisted-by: claude-opus-5-5

* ♻️ Move imported SVG attributes styles to DS tokens

The remove button is a DS icon button now, so .attr-actions and
.attr-action-btn with their button placeholders go away. Inline the flex
and ellipsis mixins, move spacing to DS tokens and logical properties,
sizes to px2rem and the title color alias to its DS token.

Use the DS body-small typography; its line-height is 1.3 instead of 1.4.
Drop the line clamp rules of the attribute name: its later display:
inline-block already overrode the -webkit-box they need.

The refactor/ import stays only for %input-element on the value input,
which moves with the inputs migration.

AI-assisted-by: claude-opus-5-5
2026-10-19 15:35:44 +02:00
Belén Albeza
c99980327f
🐛 Resize fit-content flex boards while typing in v3 text editor (#12330)
* 🐛 Resize fit-content flex boards while typing in v3 text editor

Typing in an auto-width text did not resize its fit-content layout
parent until the editor closed. The v3 editor now previews the live
text size in the layout on each keystroke, also when the text sits
in a group.

* 🐛 Preview text layout when typing with a pending caret style

Both v3 editor commit paths share v3-update-editor-content.

* 🐛 Skip the layout preview for absolute texts

Absolute layout items do not affect their board.

* ⚡ Preview text layout only when the text size changes

Each preview propagates modifiers, so skip unchanged sizes.

* 🐛 Leave interactive render mode when the v3 editor closes

Finalize only ends it when it applies geometry.
2026-10-19 15:06:56 +02:00
Eva Marco
18ca25518e
♻️ Use a DS icon button to close the nudge amount modal (#12439)
* ♻️ Use a DS icon button to close the nudge amount modal

The close button of the nudge amount modal (main menu, Preferences) was a
raw button with a deprecated icon and no accessible name. Replace it with
a DS ghost icon button labeled "Close", shown in its DS tooltip. The class
that places it in the corner goes on the tooltip wrapper, so the tooltip
anchors to the button. The numeric inputs stay for the inputs group.

Add a visual test that opens the modal from the main menu.

AI-assisted-by: claude-opus-5-5

* ♻️ Move nudge modal styles off the deprecated styles

The close button is a DS icon button, so its placeholder goes away; it is
now 32px wide instead of 28px, and sits 4px from the edge instead of 6px
so the icon stays in the same place. Spacing, sizes and the color aliases
move to DS tokens and logical properties, the flex mixin is inlined, and
the label rule targets its class instead of the label element.

The title matches the DS headline-medium typography exactly. The content
and labels use body-large and the wrapper body-small, whose line-heights
differ by 0.1 from the legacy ones; the labels keep their 1.5 override,
so nothing visible changes.

refactor/ stays only for the shared modal and labeled input placeholders.

AI-assisted-by: claude-opus-5-5
2026-10-19 14:28:03 +02:00
Eva Marco
f4f581ab74
🐛 Fix export scale dropdown clipped in Inspect (#12351)
* 🐛 Fix export scale dropdown clipped in Inspect

The export selects in the Inspect tab used a dropdown class that always
opened them upwards, overriding the select's own up/down choice. On
elements with few properties the export section sits near the top of
the panel, so the scale list (now eight options) went past the top of
the scroll area and hid 0.5x. Keep only the dropdown width and let the
select pick the direction.

Closes #12346

AI-assisted-by: claude-opus-5-5

* ♻️ Move Inspect exports styles to DS tokens

Replace the deprecated spacing and size variables, the flex mixins, the
color aliases and the typography mixins with DS tokens, and use logical
properties. The typographies switch to the closest DS ones: body-small
for the suffix input (line-height 1.3 instead of 1.4) and headline-small
for the export button (12px instead of 11px). The @extend placeholders
still come from refactor/ and are left for a later migration.

AI-assisted-by: claude-opus-5-5

* ♻️ Use DS buttons in Inspect exports

Replace the add, remove and export buttons in the Inspect exports section
with the DS icon-button and button, as the workspace export section does.
Delete their now unused styles and the sizes import; the export button
class only stretches the button and centers its label.

AI-assisted-by: claude-opus-5-5

* 🐛 Fix add export button lookup in the Inspect exports e2e test

The add export button in Inspect is a DS icon button now and lost its
.add-export class, so the test timed out waiting for it. Find it by its
role and accessible name instead.

AI-assisted-by: claude-opus-5-5
2026-10-19 10:50:32 +02:00