Buttons

Summary

Buttons trigger actions or, when used as <a class="neura-button">, navigate to a destination. Five visual variants (standard, primary, link, subtle, compact) plus disabled, pressed, dropdown-trigger, and split-button compositions.

When to use

VariantUse it for
Primary
.neura-button-primary
The main action of a form or dialog. Use exactly one per surface.
Standard
.neura-button
Secondary actions and neutral controls.
Link
.neura-button-link
Actions that should look like a link but behave like a button (e.g. dialog Cancel).
Subtle
.neura-button-subtle
Visually quiet buttons, often icon-only, used in toolbars.
Compact
.neura-button-compact
Modifier for any variant; reduces height for tight rows.
Dropdown / split
.neura-dropdown2-trigger
Combine with any variant when the button opens a menu (see Dropdowns).

Examples

All variants rendered live: hover or tab to any button to verify focus and pressed states. The dropdown and split triggers open real menus; click outside or press Esc to close.

Variants

Compact

Disabled

Pressed (toggle state)

With icon

Button group

Dropdown button

Split button (with dropdown)

HTML

Standard button. Use <a> instead of <button> if the action is a navigation.

<button class="neura-button">Click me</button>
<a class="neura-button" href="/somewhere">Go</a>

Variants are added by appending a modifier class:

<button class="neura-button neura-button-primary">Save</button>
<button class="neura-button neura-button-link">Cancel</button>
<button class="neura-button neura-button-subtle">More</button>
<button class="neura-button neura-button-compact">Tiny</button>

Disabled: prefer the disabled attribute. aria-disabled="true" is honoured for non-form-submit cases.

<button class="neura-button" disabled>Disabled</button>
<button class="neura-button" aria-disabled="true">Disabled (a11y only)</button>

Toggle / pressed state: use aria-pressed.

<button class="neura-button" aria-pressed="true">Pressed</button>

Icon + text. The icon picks up currentColor from the button.

<button class="neura-button">
  <span class="neura-icon neura-icon-plus"></span>
  Add item
</button>

Icon-only: always include aria-label.

<button class="neura-button neura-button-subtle" aria-label="Edit">
  <span class="neura-icon neura-icon-pencil"></span>
</button>

Button group: wrap siblings in .neura-buttons to fuse their borders.

<div class="neura-buttons">
  <button class="neura-button">One</button>
  <button class="neura-button">Two</button>
  <button class="neura-button">Three</button>
</div>

Split button: primary action fused with a dropdown trigger.

<div class="neura-buttons">
  <button class="neura-button neura-button-split-main">Save</button>
  <button class="neura-button neura-button-split-more neura-dropdown2-trigger"
          aria-controls="split-menu"
          aria-label="More save options"></button>
</div>
<div id="split-menu" class="neura-dropdown2 neura-style-default" aria-hidden="true">
  <ul>
    <li><a href="#">Save</a></li>
    <li><a href="#">Save and close</a></li>
    <li><a href="#">Save as draft</a></li>
  </ul>
</div>

CSS classes

ClassEffect
.neura-buttonBase button styles. Required on every variant.
.neura-button-primaryBlue gradient + white text. Use for the dominant action.
.neura-button-linkRenders as a hyperlink: no background, blue text.
.neura-button-subtleBorderless until hover. Common for icon buttons in toolbars.
.neura-button-compactReduced vertical padding for tight rows. Combine with any variant.
.neura-buttonsWrapper that fuses the borders of adjacent buttons into a group. Inside a group, .neura-button-primary reverts to the standard look (link-colored text) so it doesn't break the cluster (matches AUI).
.neura-button-split-mainLeft half of a split button (primary action).
.neura-button-split-moreRight half of a split button (chevron-only dropdown trigger). Combine with .neura-dropdown2-trigger.
.neura-dropdown2-triggerAdds a CSS-drawn chevron arrow on the right edge. Use with aria-controls="…" pointing to the menu. Any redundant inner chevron span (.neura-icon-chevron-down) is hidden automatically.
.neura-dropdown2-trigger-arrowlessSuppresses the chevron on a dropdown trigger that should look like a plain button (AUI: aui-dropdown2-trigger-arrowless).

Adjacent sibling buttons space themselves automatically: .neura-button ~ .neura-button and .neura-buttons + .neura-buttons get a 10px start margin, so a simple row needs no wrapper.

Attributes & states

AttributeEffect
disabledNative disabled state: prevents click + form submission. Preferred.
aria-disabled="true"Visually disabled but still focusable. Use only when disabled is unsuitable.
aria-pressed="true"Toggle button in pressed state. Pair with click handler that flips the value.
.is-activeClass equivalent of the :active pressed look, for buttons that should render depressed programmatically. On .neura-button-split-more it also keeps the split divider in its hover state.
.activeSet automatically by Neura.dropdown2 on the trigger while its menu is open (brings the chevron to full opacity); no need to manage it yourself.

JavaScript

Buttons themselves are CSS-only; there is no Neura.button(...) API. Wire your own click handlers with addEventListener.

Plain click handler:

<button class="neura-button" id="save">Save</button>

<script>
  document.getElementById('save').addEventListener('click', () => {
    // your action here
    console.log('saved');
  });
</script>

Form submit: give the button type="submit" (the default inside a <form>) and listen on the form:

<form id="profile-form">
  <!-- fields -->
  <button class="neura-button neura-button-primary" type="submit">Save</button>
  <button class="neura-button neura-button-link" type="button" id="cancel">Cancel</button>
</form>

<script>
  document.getElementById('profile-form').addEventListener('submit', (e) => {
    e.preventDefault();
    // submit via fetch / XHR
  });
  document.getElementById('cancel').addEventListener('click', () => history.back());
</script>

Toggle button: flip aria-pressed on click so the CSS picks up the pressed state automatically:

<button class="neura-button" id="bold" aria-pressed="false">Bold</button>

<script>
  const btn = document.getElementById('bold');
  btn.addEventListener('click', () => {
    const pressed = btn.getAttribute('aria-pressed') === 'true';
    btn.setAttribute('aria-pressed', String(!pressed));
  });
</script>

Delegated handler: one listener for many buttons (useful when buttons are rendered dynamically):

document.querySelector('.toolbar').addEventListener('click', (e) => {
  const btn = e.target.closest('.neura-button[data-action]');
  if (!btn) return;
  const action = btn.dataset.action;
  // dispatch on `action`
});

When a button opens a menu, the JS surface lives on the dropdown - see Dropdowns for Neura.dropdown2(trigger).show()/hide()/toggle().

AUI compatibility

Every .aui-button* class works identically: the shim aliases them onto the .neura-button* rules via Sass @extend. Existing Velocity templates can use either prefix.

<!-- Both render identically: -->
<button class="aui-button aui-button-primary">Save</button>
<button class="neura-button neura-button-primary">Save</button>