<style>
/* Role-based button system, signed off 2026-07-23. Colours are hardcoded here
rather than driven by CSS custom properties because no shared tokens.css exists
yet (see the sync note in public/css/styleguide.css); update both places by hand
if these values change again. Hover treatment: only Primary has a signed-off
hover-darken hex (#521f5a). Go, Secondary and Danger use a computed brightness/
tint shift as an interim treatment pending their own hover sign-off. */
.tsg-btn {
font-family: 'Satoshi', sans-serif;
font-weight: 500;
font-size: 0.875rem;
line-height: 1;
border-radius: 8px;
border: 1px solid transparent;
padding: 10px 18px;
cursor: pointer;
display: inline-flex;
align-items: center;
justify-content: center;
text-decoration: none;
transition: background-color 200ms ease, filter 200ms ease;
}
.tsg-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.tsg-btn--primary {
background: #672c72;
color: #fff;
}
.tsg-btn--primary:hover:not(:disabled) {
background: #521f5a;
}
.tsg-btn--go {
background: #178055;
color: #fff;
}
.tsg-btn--go:hover:not(:disabled) {
filter: brightness(0.92);
}
.tsg-btn--secondary {
background: #c2410c;
color: #fff;
}
.tsg-btn--secondary:hover:not(:disabled) {
filter: brightness(0.92);
}
.tsg-btn--danger {
background: #fff;
color: #a61b1b;
border-color: #a61b1b;
padding-left: 0;
overflow: hidden;
}
.tsg-btn--danger:hover:not(:disabled) {
background: #fdf2f2;
}
.tsg-btn__tape {
display: inline-block;
align-self: stretch;
width: 14px;
flex-shrink: 0;
margin-right: 12px;
background-image: repeating-linear-gradient(45deg, #f5c400 0 6px, #1a1a1a 6px 12px);
border-top-left-radius: 8px;
border-bottom-left-radius: 8px;
}
</style>
<button class="tsg-btn tsg-btn--go">Generate now</button>
<div style="margin-top:0.5rem;font-size:0.6875rem;color:var(--paragraph);font-family:'Satoshi',sans-serif;max-width:320px;">Dark pair: #2bc485 on #0a2a1d.</div>
<style>
/* Role-based button system, signed off 2026-07-23. Colours are hardcoded here
rather than driven by CSS custom properties because no shared tokens.css exists
yet (see the sync note in public/css/styleguide.css); update both places by hand
if these values change again. Hover treatment: only Primary has a signed-off
hover-darken hex (#521f5a). Go, Secondary and Danger use a computed brightness/
tint shift as an interim treatment pending their own hover sign-off. */
.tsg-btn {
font-family: 'Satoshi', sans-serif;
font-weight: 500;
font-size: 0.875rem;
line-height: 1;
border-radius: 8px;
border: 1px solid transparent;
padding: 10px 18px;
cursor: pointer;
display: inline-flex;
align-items: center;
justify-content: center;
text-decoration: none;
transition: background-color 200ms ease, filter 200ms ease;
}
.tsg-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.tsg-btn--primary { background: #672c72; color: #fff; }
.tsg-btn--primary:hover:not(:disabled) { background: #521f5a; }
.tsg-btn--go { background: #178055; color: #fff; }
.tsg-btn--go:hover:not(:disabled) { filter: brightness(0.92); }
.tsg-btn--secondary { background: #c2410c; color: #fff; }
.tsg-btn--secondary:hover:not(:disabled) { filter: brightness(0.92); }
.tsg-btn--danger {
background: #fff;
color: #a61b1b;
border-color: #a61b1b;
padding-left: 0;
overflow: hidden;
}
.tsg-btn--danger:hover:not(:disabled) { background: #fdf2f2; }
.tsg-btn__tape {
display: inline-block;
align-self: stretch;
width: 14px;
flex-shrink: 0;
margin-right: 12px;
background-image: repeating-linear-gradient(45deg, #f5c400 0 6px, #1a1a1a 6px 12px);
border-top-left-radius: 8px;
border-bottom-left-radius: 8px;
}
</style>
{{#if isDanger}}
<button class="tsg-btn tsg-btn--{{role}}" {{#if disabled}}disabled{{/if}}>
<span class="tsg-btn__tape" aria-hidden="true"></span>{{label}}
</button>
{{else}}
<button class="tsg-btn tsg-btn--{{role}}" {{#if disabled}}disabled{{/if}}>{{label}}</button>
{{/if}}
{{#if darkNote}}
<div style="margin-top:0.5rem;font-size:0.6875rem;color:var(--paragraph);font-family:'Satoshi',sans-serif;max-width:320px;">{{darkNote}}</div>
{{/if}}
{
"label": "Generate now",
"role": "go",
"isDanger": false,
"disabled": false,
"darkNote": "Dark pair: #2bc485 on #0a2a1d."
}
Role-based button system, signed off 2026-07-23 (docs/styling-review-2026-07/decision-doc.md). Four roles, each carrying a light-mode and a dark-mode colour pair. Dark mode is not shipped in the app yet, so only the light-mode pair renders below; the dark pair is noted under each button for when dark mode lands.
#672c72 / #fff, hover #521f5a), the default action. Dark-mode pair is not finalised yet; candidate is #c983d1 on #220e25.#178055 / #fff light, #2bc485 / #0a2a1d dark), a full-auto action that does something on the user’s behalf immediately (e.g. one-click generate), not just a navigation.#c2410c / #fff light, #f26419 / #2a0f04 dark), an alternative or lower-emphasis flow. Not the same colour as the general brand secondary orange (--secondary-color) used for links and accents elsewhere; that stays #F26419.#a61b1b text and border. Dark: #351b1b fill, #ef5350 border, #ffb4b4 text, same tab. The solid #c62828 / #ef5350 danger tokens remain in use for confirm-dialog fills and destructive text elsewhere; the tape tab is specifically the button treatment.Superseded: the previous purple-primary / orange-secondary / light-mark / light-skip / red-remove scheme (btn-primary, btn-primary btn-secondary, btn-primary btn-light btn-mark, btn-primary btn-light btn-skip, btn-fill btn-remove) is retired in favour of the four roles above. Other components in this guide (e.g. Modal) still reference the old classes pending their own migration pass.
Appears in: Throughout the app, tool pages, modals (Do Next, upgrade prompts), script pages, settings, Social Bio editor, and any form submission.