canonrs-server 0.1.0

CanonRS server-side rendering support
/* ═══════════════════════════════════════════════════════════════
   BUTTON — Family C Forms tokens compliant
   State via data-rs-state — zero pseudo-class state selectors
   ═══════════════════════════════════════════════════════════════ */

/* BASE */
[data-rs-button] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--button-gap);

  height: var(--button-height);
  padding: var(--button-padding-y) var(--button-padding-x);

  font-family: var(--font-family-sans);
  font-weight: var(--font-weight-medium);
  font-size: var(--font-size-md);
  line-height: var(--line-height-normal);

  border-radius: var(--button-radius);
  border: var(--border-thin) solid transparent;

  cursor: pointer;
  user-select: none;
  text-decoration: none;
  white-space: nowrap;

  transition:
    background-color var(--motion-duration-fast) var(--motion-ease-standard),
    color var(--motion-duration-fast) var(--motion-ease-standard),
    border-color var(--motion-duration-fast) var(--motion-ease-standard),
    box-shadow var(--motion-duration-fast) var(--motion-ease-standard),
    opacity var(--motion-duration-fast) var(--motion-ease-standard);
}

/* ── SIZES ──────────────────────────────────────────────────── */
[data-rs-button][data-rs-size="xs"] {
  height: var(--button-xs-height);
  padding: var(--button-xs-padding-y) var(--button-xs-padding-x);
  font-size: var(--button-xs-font-size);
}

[data-rs-button][data-rs-size="sm"] {
  height: var(--button-sm-height);
  padding: var(--button-sm-padding-y) var(--button-sm-padding-x);
  font-size: var(--button-sm-font-size);
}

[data-rs-button][data-rs-size="lg"] {
  height: var(--button-lg-height);
  padding: var(--button-lg-padding-y) var(--button-lg-padding-x);
  font-size: var(--button-lg-font-size);
}

[data-rs-button][data-rs-size="xl"] {
  height: var(--button-xl-height);
  padding: var(--button-xl-padding-y) var(--button-xl-padding-x);
  font-size: var(--button-xl-font-size);
}

[data-rs-button][data-rs-size="icon"] {
  width: var(--button-height);
  padding: 0;
}

/* ── CORE VARIANTS ──────────────────────────────────────────── */
[data-rs-button][data-rs-variant="primary"],
[data-rs-button][data-rs-variant="solid"] {
  background: var(--button-primary-bg);
  color: var(--button-primary-fg);
  border-color: var(--button-primary-bg);
}

[data-rs-button][data-rs-variant="secondary"] {
  background: var(--button-secondary-bg);
  color: var(--button-secondary-fg);
  border-color: var(--button-secondary-border);
}

[data-rs-button][data-rs-variant="outline"] {
  background: var(--button-outline-bg);
  color: var(--button-outline-fg);
  border-color: var(--button-outline-border);
}

[data-rs-button][data-rs-variant="ghost"] {
  background: var(--button-ghost-bg);
  color: var(--button-ghost-fg);
  border-color: transparent;
}

[data-rs-button][data-rs-variant="link"] {
  background: var(--button-link-bg);
  color: var(--button-link-fg);
  border-color: transparent;
  text-decoration: underline;
  text-decoration-thickness: var(--button-link-underline-thickness);
  text-underline-offset: var(--button-link-underline-offset);
  font-weight: var(--font-weight-semibold);
  height: auto;
  padding: 0;
}

/* ── SEMANTIC VARIANTS ──────────────────────────────────────── */
[data-rs-button][data-rs-variant="destructive"] {
  background: var(--button-danger-bg);
  color: var(--button-danger-fg);
  border-color: var(--button-danger-bg);
}

[data-rs-button][data-rs-variant="success"] {
  background: var(--button-success-bg);
  color: var(--button-success-fg);
  border-color: var(--button-success-bg);
}

[data-rs-button][data-rs-variant="warning"] {
  background: var(--button-warning-bg);
  color: var(--button-warning-fg);
  border-color: var(--button-warning-bg);
}

[data-rs-button][data-rs-variant="info"] {
  background: var(--button-info-bg);
  color: var(--button-info-fg);
  border-color: var(--button-info-bg);
}

/* ── NEUTRAL VARIANTS ───────────────────────────────────────── */
[data-rs-button][data-rs-variant="default"] {
  background: var(--button-default-bg);
  color: var(--button-default-fg);
  border-color: var(--button-default-border);
}

[data-rs-button][data-rs-variant="subtle"] {
  background: var(--button-subtle-bg);
  color: var(--button-subtle-fg);
  border-color: transparent;
}

[data-rs-button][data-rs-variant="muted"] {
  background: var(--button-muted-bg);
  color: var(--button-muted-fg);
  border-color: transparent;
}

/* ── STATES via data-rs-state ───────────────────────────────── */
[data-rs-button][data-rs-state~="hover"]:not([data-rs-state~="disabled"]):not([data-rs-variant="ghost"]):not([data-rs-variant="link"]) {
  opacity: var(--opacity-hover);
}

[data-rs-button][data-rs-variant="ghost"][data-rs-state~="hover"]:not([data-rs-state~="disabled"]) {
  background: var(--button-ghost-bg-hover);
  opacity: 1;
}

[data-rs-button][data-rs-variant="link"][data-rs-state~="hover"]:not([data-rs-state~="disabled"]) {
  opacity: 1;
  text-decoration-thickness: var(--button-link-underline-thickness-hover);
  filter: brightness(0.92);
}

[data-rs-button][data-rs-state~="active"]:not([data-rs-state~="disabled"]) {
  opacity: var(--opacity-active);
  transform: var(--button-active-transform);
  transition:
    transform var(--motion-duration-fast) var(--motion-ease-standard),
    opacity var(--motion-duration-fast) var(--motion-ease-standard);
}

[data-rs-button][data-rs-state~="disabled"] {
  opacity: var(--opacity-disabled);
  cursor: not-allowed;
  pointer-events: none;
}

[data-rs-button][data-rs-state~="focus"]:focus-visible,
[data-rs-button]:focus-visible {
  outline: none;
  box-shadow: var(--button-focus-ring-shadow);
}

[data-rs-button][data-rs-state~="focus"]:not(:focus-visible):not([data-rs-validation]) {
  box-shadow: none;
}

/* ── VALIDATION ─────────────────────────────────────────────── */
[data-rs-button][data-rs-validation="error"] {
  box-shadow: var(--validation-error-shadow);
}

[data-rs-button][data-rs-validation="warning"] {
  box-shadow: var(--validation-warning-shadow);
}

[data-rs-button][data-rs-validation="success"] {
  box-shadow: var(--validation-success-shadow);
}