1/* Button — multi-class API
  2 *
  3 * Compose:
  4 *   <button class="btn btn-primary">           default size, primary
  5 *   <button class="btn btn-sm btn-outline">    small outline
  6 *   <button class="btn btn-icon btn-ghost">    square icon-only ghost
  7 *   <button class="btn btn-lg btn-icon btn-danger">
  8 *
  9 * Axes are orthogonal:
 10 *   • size:  default | btn-sm | btn-lg
 11 *   • shape: (rect)  | btn-icon (square)
 12 *   • color: btn-{primary,secondary,outline,ghost,link,success,warning,danger,info}
 13 *
 14 * Sizes/shapes are nested under `.admin-btn` so compound selectors win the
 15 * specificity battle against the base rule's `:has(>svg)` adjustment
 16 * — that's why size/icon overrides live inside the .admin-btn block.
 17 *
 18 * Color variants live as standalone rules so they're orthogonal to
 19 * size and trivially extended.
 20 *
 21 * Status buttons (success/warning/danger/info) render at 70% bg in dark
 22 * mode so the saturated hue mixes into a softer tone — the foreground
 23 * tokens already give plenty of contrast at full opacity. Tweak the
 24 * `/70` and `/60` modifiers to taste.
 25 */
 26@layer components {
 27  .admin-btn {
 28    @apply focus-control inline-flex items-center justify-center whitespace-nowrap text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none cursor-pointer;
 29    border-radius: var(--radius-button);
 30    /* default size */
 31    @apply gap-2 h-9 px-4 py-2;
 32    &:has(>svg) { @apply px-3; }
 33
 34    &.admin-btn-sm {
 35      @apply gap-1.5 h-8 px-3 py-0;
 36      &:has(>svg) { @apply px-2.5; }
 37    }
 38    &.admin-btn-lg {
 39      @apply h-10 px-6 py-2;
 40      &:has(>svg) { @apply px-4; }
 41    }
 42
 43    &.admin-btn-icon       { @apply size-9 p-0; }
 44    &.admin-btn-sm.admin-btn-icon { @apply size-8; }
 45    &.admin-btn-lg.admin-btn-icon { @apply size-10; }
 46  }
 47
 48  .admin-btn-primary {
 49    @apply bg-admin-primary text-admin-primary-foreground shadow-xs hover:bg-admin-primary/90;
 50    &[aria-pressed='true'] { @apply bg-admin-primary/90; }
 51  }
 52  .admin-btn-secondary {
 53    @apply bg-admin-secondary text-admin-secondary-foreground shadow-xs;
 54    &:hover,
 55    &[aria-pressed='true'] { @apply bg-admin-secondary/80; }
 56  }
 57  .admin-btn-outline {
 58    @apply border bg-transparent shadow-xs;
 59    &:hover,
 60    &[aria-pressed='true'] { @apply bg-admin-accent text-admin-accent-foreground dark:bg-admin-accent/50; }
 61  }
 62  .admin-btn-ghost {
 63    &:hover,
 64    &[aria-pressed='true'] { @apply bg-admin-accent text-admin-accent-foreground dark:bg-admin-accent/50; }
 65  }
 66  .admin-btn-link {
 67    @apply text-admin-primary underline-offset-4;
 68    &:hover,
 69    &[aria-pressed='true'] { @apply hover:underline; }
 70  }
 71  .admin-btn-success {
 72    @apply bg-admin-success text-admin-success-foreground shadow-xs focus-visible:ring-admin-success/20 dark:focus-visible:ring-admin-success/40 dark:bg-admin-success/70;
 73    &:hover,
 74    &[aria-pressed='true'] { @apply bg-admin-success/90 dark:bg-admin-success/60; }
 75  }
 76  .admin-btn-warning {
 77    @apply bg-admin-warning text-admin-warning-foreground shadow-xs focus-visible:ring-admin-warning/20 dark:focus-visible:ring-admin-warning/40 dark:bg-admin-warning/70;
 78    &:hover,
 79    &[aria-pressed='true'] { @apply bg-admin-warning/90 dark:bg-admin-warning/60; }
 80  }
 81  .admin-btn-danger {
 82    @apply bg-admin-danger text-admin-danger-foreground shadow-xs focus-visible:ring-admin-danger/20 dark:focus-visible:ring-admin-danger/40 dark:bg-admin-danger/70;
 83    &:hover,
 84    &[aria-pressed='true'] { @apply bg-admin-danger/90 dark:bg-admin-danger/60; }
 85  }
 86  .admin-btn-info {
 87    @apply bg-admin-info text-admin-info-foreground shadow-xs focus-visible:ring-admin-info/20 dark:focus-visible:ring-admin-info/40 dark:bg-admin-info/70;
 88    &:hover,
 89    &[aria-pressed='true'] { @apply bg-admin-info/90 dark:bg-admin-info/60; }
 90  }
 91}
 92
 93/* Button Group */
 94@layer components {
 95  .admin-button-group {
 96    @apply inline-flex w-fit items-stretch;
 97    /* isolate */
 98
 99    > *:focus-visible,
100    > :is(.admin-dropdown-menu, .admin-popover, .admin-select) > button:focus-visible {
101      @apply relative z-10;
102    }
103
104    > hr[role='separator'] {
105      @apply w-0 h-auto self-stretch border border-admin-input shrink-0 m-0;
106    }
107
108    &:not([data-orientation='vertical']) {
109      > *:not(:first-child),
110      > :is(.admin-dropdown-menu, .admin-popover, .admin-select):not(:first-child) > button {
111        @apply rounded-l-none border-l-0;
112      }
113      > *:not(:last-child),
114      > :is(.admin-dropdown-menu, .admin-popover, .admin-select):not(:last-child) > button {
115        @apply rounded-r-none;
116      }
117    }
118    &[data-orientation='vertical'] {
119      @apply flex-col;
120
121      > hr[role='separator'] {
122        @apply w-auto h-px;
123      }
124
125      > *:not(:first-child),
126      > :is(.admin-dropdown-menu, .admin-popover, .admin-select):not(:first-child) > button {
127        @apply rounded-t-none border-t-0;
128      }
129      > *:not(:last-child),
130      > :is(.admin-dropdown-menu, .admin-popover, .admin-select):not(:last-child) > button {
131        @apply rounded-b-none;
132      }
133    }
134  }
135}