Buttons
Real <button> elements styled with the .ds-btn family. Hover, active, and focus states use native pseudoclasses.
Variants
Primary for the main action; secondary for cancel/dismiss; ghost for inline edits; ghost-danger for destructive actions.
Solid color variants
Filled buttons with the same gradient + border + hard-offset shadow treatment as primary, drawn from status and marketing colors. Use sparingly — primary should still be the dominant action on most surfaces.
Ghost color hover
Default ghost is text-only. On hover, the button gains an outline that matches its text color and a transparent fill of that same color.
Sizes
States
Hover and active states use real CSS pseudoclasses — interact with the buttons to see them.
Reveal pattern
Use this pattern any time multiple CTAs appear in a list. Resting state: muted (looks secondary). Hover the parent — only one button blooms to primary. Reduces the number of CTAs drawing the user's attention at once.
Follow-up: a v-reveal-parent directive could ship later so consumers don't need to remember the class name on the wrapping element.
With icons
Lead with an icon when the action is concrete (download, print, send) and the label needs reinforcement. Production source for the download trio: src/components/resume-builder/DownloadResumeButton.vue. The wrapper collapses into direct DSBtn usage with a leading icon — no new component needed.
Focus toolbar
Inline editor controls that appear when the row gains focus and stay for 5 seconds after focus leaves — long enough for a click to a confirm dialog without the toolbar vanishing mid-click. The pattern is a directive (v-focus-toolbar) that toggles is-toolbar-active on the host. Pair with absolute-positioned descendant chips. Used by DSHighlightRow; reusable anywhere a row needs ephemeral row-level actions (move up/down, delete) without the chrome bloat of always-on controls.
Icon-only buttons
The .ds-icon-btn utility class shapes any DSBtn variant into a 1.875rem square with the icon centered. Pair with an aria-label so the action stays accessible. The dialog close button is the canonical use; the same class works for trash, more-menu, settings, and plus glyphs across the app.