/* ════════════════════════════════════════════════════════════════════════
   Components — buttons, forms, cards, badges, tables, modals, toast
   Matches Yozafy theme patterns (pill shapes, compact spacing, warm accents)
   ════════════════════════════════════════════════════════════════════════ */

/* Hide elements until Alpine.js has hydrated (prevents x-show flash) */
[x-cloak] { display: none !important; }

/* ── Utilities ─────────────────────────────────────────────────────────
   Small, semantic helpers that replace one-off inline styles.
   Keep this list TIGHT — if a class would only be used once,
   create a proper component class instead. */

/* Display */
.is-hidden       { display: none; }
.is-block        { display: block; }
.is-inline       { display: inline; }
.is-inline-flex  { display: inline-flex; }

/* Visually hidden but accessible to screen readers — standard a11y pattern.
   Use for column headers like "Actions" where the icon is self-explanatory
   visually but assistive tech still needs the label. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Flex helpers */
.flex            { display: flex; }
.flex--gap-2     { gap: var(--space-2); }
.flex--gap-4     { gap: var(--space-4); }
.flex--end       { justify-content: flex-end; }
.flex--between   { justify-content: space-between; align-items: center; }
.flex--center    { align-items: center; }
.flex--wrap      { flex-wrap: wrap; }
.flex-1          { flex: 1; min-width: 0; }
.w-fit           { width: fit-content; }

/* Margin (use space scale tokens) */
.mt-2 { margin-top: var(--space-2); }
.mt-3 { margin-top: var(--space-3); }
.mt-6 { margin-top: var(--space-6); }
.mb-1 { margin-bottom: var(--space-1); }
.mb-2 { margin-bottom: var(--space-2); }
.mb-3 { margin-bottom: var(--space-3); }
.mb-4 { margin-bottom: var(--space-4); }
.ml-2 { margin-left: var(--space-2); }
.m-0  { margin: 0; }

/* Text */
.text--xs        { font-size: var(--font-size-xs); }
.text--sm        { font-size: var(--font-size-sm); }
.text--muted     { color: var(--color-text-muted); }
.text--primary   { color: var(--color-primary); }
.text--dark      { color: var(--color-dark); }
.text--success   { color: var(--color-success); }
.text--bold      { font-weight: 600; }
.text--break     { word-break: break-all; }
.text--mono      { font-family: var(--font-family-mono); font-size: var(--font-size-xs); }
.text--center    { text-align: center; }
.text--left      { text-align: left; }
.text--right     { text-align: right; }

/* ── Buttons ──────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: 38px;
  padding: 0 var(--space-5);
  background: var(--color-bg);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-full);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-dark);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--t-hover), border-color var(--t-hover), color var(--t-hover), transform var(--t-hover), box-shadow var(--t-hover);
}

.btn:hover { border-color: var(--color-dark); }
.btn:active { transform: scale(0.97); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }

.btn--primary {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-white);
}
.btn--primary:hover {
  background: var(--color-primary-hover);
  border-color: var(--color-primary-hover);
  box-shadow: var(--shadow-primary);
}

.btn--outline { background: transparent; border-color: var(--color-primary); color: var(--color-primary); }
.btn--outline:hover { background: var(--color-primary-light); }

.btn--ghost { border-color: transparent; color: var(--color-text); }
.btn--ghost:hover { background: var(--color-bg-light); }

.btn--danger { background: var(--color-error); border-color: var(--color-error); color: var(--color-white); }
.btn--danger:hover { background: var(--color-error-hover); border-color: var(--color-error-hover); }

.btn--danger-outline { background: transparent; border-color: var(--color-error); color: var(--color-error); }
.btn--danger-outline:hover { background: var(--color-error-light); }

.btn--success { background: var(--color-success); border-color: var(--color-success); color: var(--color-white); }
.btn--success:hover { background: var(--color-success-hover); border-color: var(--color-success-hover); }

.btn--sm { height: 30px; padding: 0 var(--space-3); font-size: var(--font-size-xs); }
.btn--lg { height: 46px; padding: 0 var(--space-6); font-size: var(--font-size-base); }
.btn--full { width: 100%; }

/* Icon button (square circle, e.g. user menu, close) */
.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-full);
  color: var(--color-text-light);
  background: transparent;
  transition: background var(--t-hover), color var(--t-hover);
}
.icon-btn:hover { background: var(--color-bg-light); color: var(--color-dark); }
.icon-btn--sm { width: 28px; height: 28px; }

/* ── Forms ────────────────────────────────────────────────────────────── */
.field { display: flex; flex-direction: column; gap: var(--space-1); }

.field__label {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-dark);
}

.field__hint {
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
  margin-top: 2px;
}

.field__error {
  font-size: var(--font-size-xs);
  color: var(--color-error);
  font-weight: var(--font-weight-medium);
  margin-top: 2px;
}

.field__input,
.field__textarea,
.field__select {
  width: 100%;
  height: 42px;
  padding: 0 var(--space-4);
  background: var(--color-bg);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-full);
  font-size: var(--font-size-sm);
  font-family: var(--font-family);
  color: var(--color-dark);
  transition: border-color var(--t-hover), box-shadow var(--t-hover);
}

.field__input:focus,
.field__textarea:focus,
.field__select:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-primary-ring);
}

.field__textarea {
  height: auto;
  min-height: 100px;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-xl);
  resize: vertical;
  line-height: var(--line-height-normal);
}

/* Code-style textarea variant — used by the CSV import plugin so pasted
   data lines up in a fixed-width grid and long rows don't soft-wrap into
   confusing two-line entries. Used wherever a textarea takes structured,
   line-oriented text (CSV, JSON, .env, log dumps). */
.field__textarea--code {
  font-family: var(--font-family-mono);
  font-size:   var(--font-size-xs);
  white-space: pre;
  overflow-x:  auto;
}

.field__select { padding-right: var(--space-8); cursor: pointer; appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23999' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right var(--space-4) center; }

.field--has-error .field__input,
.field--has-error .field__textarea { border-color: var(--color-error); }

/* Inline checkbox + label combo. Used when a field is boolean (e.g.
   "Verified purchase" toggle in the import form). The orange accent
   matches the primary CTA color. */
.field__checkbox {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
  user-select: none;
  font-size: var(--font-size-sm);
  color: var(--color-text);
  padding: var(--space-2) 0;
}
.field__checkbox input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: var(--color-primary);
  cursor: pointer;
}

/* ── Cards ────────────────────────────────────────────────────────────── */
.card {
  background: var(--color-bg);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-sm);
}

.card__body { padding: var(--space-5); }
.card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--color-border-light);
}
.card__title {
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-semibold);
  color: var(--color-dark);
}
.card__subtitle {
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
  font-weight: var(--font-weight-normal);
}

/* ── Stats card (dashboard) ───────────────────────────────────────────── */
/* Calm by default — informational cards do NOT respond to hover. Premium
   dashboards (Mercury / Stripe / Linear) reserve interactivity cues for
   actually-interactive elements. A card that pretends to be clickable but
   isn't is visual noise. Only `<a class="stat-card">` (real links) get the
   hover lift — see `.stat-card[href]` below. */
.stat-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-5);
  background: var(--color-bg);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-sm);
}
/* Hover lift ONLY on actually-clickable cards (links). The attribute-
   selector form means we don't have to add a modifier class — any
   <a class="stat-card"> automatically gets the cue. */
a.stat-card,
.stat-card[href] {
  text-decoration: none;
  color: inherit;
  transition: transform var(--t-hover), box-shadow var(--t-hover);
}
a.stat-card:hover,
.stat-card[href]:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

.stat-card__label {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.stat-card__value {
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold);
  color: var(--color-dark);
  line-height: 1.1;
}

.stat-card__hint {
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
}

.stat-card--accent .stat-card__value { color: var(--color-primary); }
.stat-card--success .stat-card__value { color: var(--color-success); }
.stat-card--warning .stat-card__value { color: var(--color-warning); }
.stat-card--info    .stat-card__value { color: var(--color-text); }
.stat-card--pending .stat-card__value { color: var(--color-warning); }
/* Negative — used on Net / P&L cards when income < expenses. Pairs with
   --success (green) so the founder reads the bottom line in one glance:
   green = positive position, red = loss. Same approach Stripe / Mercury /
   QuickBooks dashboards use. */
.stat-card--negative .stat-card__value { color: var(--color-error); }

/* Compact modifier — tighter padding + smaller value font so multiple
   tiers of cards fit in the vertical real estate one row of large cards
   takes. Used for the two-tier /finance overview (Tier 1 = this month,
   Tier 2 = all-time cockpit). Padding and font sizes still reference
   the token scale so the compact card scales with the design system. */
.stat-card--compact {
  padding: var(--space-4);
  gap: var(--space-1);
}
.stat-card--compact .stat-card__value {
  font-size: var(--font-size-xl);
}

/* Hero modifier — the single most important card in a section. Bigger
   padding + display-sized value font + subtle gradient background tied
   to the financial sign (green wash for profit, red wash for loss, neutral
   for breakeven).

   The top group (label / value / hint) sits at natural gap; the breakdown
   footer (see .finance-overview__hero-breakdown) uses `margin-top: auto`
   to float itself to the card's bottom edge. This keeps the headline
   metric grouped tightly while still using the full card height when the
   row is driven taller by neighbouring cards.

   Used for the All-time Net card on the /finance overview's "Position"
   section. Pair with `.stat-card--success` / `.stat-card--negative` so
   one modifier set drives both the value color AND the surface wash. */
.stat-card--hero {
  padding: var(--space-6);
}
.stat-card--hero .stat-card__value {
  /* Same value-font scale as the base stat-card (--font-size-2xl). The
     hero's visual emphasis comes from its gradient surface, two-column
     layout (text + chart), and inline footer breakdown — NOT from making
     the number scream. A display-sized value on a card with this much
     surrounding context reads as shouty rather than premium. */
  font-size: var(--font-size-2xl);
}
.stat-card--hero.stat-card--success {
  background: linear-gradient(135deg, var(--color-success-light), var(--color-bg));
  border-color: var(--color-success-light);
}
.stat-card--hero.stat-card--negative {
  background: linear-gradient(135deg, var(--color-error-light), var(--color-bg));
  border-color: var(--color-error-light);
}

/* Secondary supporting line below the main hint (e.g. month-pace projection,
   lock-in description). Smaller + de-emphasised so the headline number reads
   first. `margin-top: auto` anchors it to the card's bottom edge so all four
   cards in a row stay visually aligned regardless of which have a sub line. */
.stat-card__sub {
  display: block;
  margin-top: auto;
  padding-top: var(--space-2);
  border-top: 1px solid var(--color-border-light);
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
  line-height: 1.5;
}

/* Anchor-styled stat-card (clickable variant — Pending bills, etc.) */
a.stat-card {
  text-decoration: none;
  color: inherit;
  display: flex;
  flex-direction: column;
}
a.stat-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }

/* ── Badges ───────────────────────────────────────────────────────────── */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 22px;
  padding: 0 var(--space-2);
  border-radius: var(--radius-full);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
}

.badge--primary { background: var(--color-primary-light); color: var(--color-primary-dark); }
.badge--success { background: var(--color-success-light); color: var(--color-success-dark); }
.badge--warning { background: var(--color-warning-light); color: var(--color-warning-dark); }
.badge--error   { background: var(--color-error-light);   color: var(--color-error-dark); }
.badge--muted   { background: var(--color-bg-light);      color: var(--color-text); }
.badge--dark    { background: var(--color-dark);          color: var(--color-white); }

/* Size modifier — used as a status indicator beside page-header buttons */
.badge--lg {
  height: 38px;
  padding: 0 var(--space-4);
  font-size: var(--font-size-sm);
}

/* ── Tables ───────────────────────────────────────────────────────────── */
.table-wrap {
  background: var(--color-bg);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-xl);
  /* NOTE: no `overflow: hidden` — that would clip the row-actions dropdown
     when it floats outside the row. The rounded corners still look correct
     because the table inside doesn't paint backgrounds out to the edges. */
}

.table {
  width: 100%;
  border-collapse: collapse;
}

.table th,
.table td {
  padding: var(--space-3) var(--space-4);
  text-align: left;
  font-size: var(--font-size-sm);
  vertical-align: middle;
}

.table th {
  background: var(--color-bg-light);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-muted);
  font-size: var(--font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--color-border-light);
}

.table tbody tr { border-bottom: 1px solid var(--color-border-light); transition: background var(--t-hover); }
.table tbody tr:last-child { border-bottom: 0; }
.table tbody tr:hover { background: var(--color-bg-warm); }

/* Round corner cells so backgrounds (TH fill, hovered last row) match the
   wrapper's rounded border now that .table-wrap doesn't clip overflow. */
.table thead tr:first-child th:first-child { border-top-left-radius:    calc(var(--radius-xl) - 1px); }
.table thead tr:first-child th:last-child  { border-top-right-radius:   calc(var(--radius-xl) - 1px); }
.table tbody tr:last-child  td:first-child { border-bottom-left-radius:  calc(var(--radius-xl) - 1px); }
.table tbody tr:last-child  td:last-child  { border-bottom-right-radius: calc(var(--radius-xl) - 1px); }

.table td.col-actions { text-align: right; white-space: nowrap; }

/* ── Stars (for ratings) ─────────────────────────────────────────────── */
.stars { display: inline-flex; gap: 1px; }
.stars .star--filled { color: var(--rev-star-color); }
.stars .star--empty  { color: var(--rev-star-empty); }

/* ── Toast (HTMX action feedback) ─────────────────────────────────────── */
.toast-container {
  position: fixed;
  top: var(--space-4);
  right: var(--space-4);
  z-index: 9999;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  pointer-events: none;
}

.toast {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 280px;
  max-width: 420px;
  padding: var(--space-3) var(--space-4);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--color-primary);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-dark);
  pointer-events: auto;
  animation: toast-in var(--t-enter);
}

.toast--success { border-left-color: var(--color-success); }
.toast--error   { border-left-color: var(--color-error); }
.toast--warning { border-left-color: var(--color-warning); }

@keyframes toast-in {
  from { opacity: 0; transform: translateX(20px); }
  to   { opacity: 1; transform: translateX(0); }
}

/* ── Empty state ──────────────────────────────────────────────────────── */
.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  padding: var(--space-10) var(--space-6);
  text-align: center;
  color: var(--color-text-muted);
}
.empty__icon { color: var(--color-text-muted); opacity: 0.4; }
.empty__title { font-size: var(--font-size-base); font-weight: var(--font-weight-semibold); color: var(--color-dark); }
.empty__text { font-size: var(--font-size-sm); }

/* ── Modal ────────────────────────────────────────────────────────────── */
.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal-backdrop);
  background: var(--color-modal-overlay);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-6);
  animation: modal-backdrop-in var(--t-enter);
}

.modal {
  background: var(--color-bg);
  border-radius: var(--radius-xl);
  max-width: 480px;
  width: 100%;
  box-shadow: var(--shadow-xl);
  z-index: var(--z-modal);
  animation: modal-in var(--t-enter);
  overflow: hidden;
}

.modal--lg { max-width: 720px; }
.modal--sm { max-width: 360px; }

.modal__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-5) var(--space-6);
  border-bottom: 1px solid var(--color-border-light);
}

.modal__title {
  font-size: var(--font-size-lg);
  font-weight: var(--font-weight-bold);
  color: var(--color-dark);
  margin: 0;
}

.modal__body {
  padding: var(--space-5) var(--space-6);
  font-size: var(--font-size-sm);
  line-height: var(--line-height-normal);
  color: var(--color-text);
  max-height: calc(85vh - 160px);
  overflow-y: auto;
}

.modal__actions {
  display: flex;
  gap: var(--space-2);
  justify-content: flex-end;
  padding: var(--space-4) var(--space-6);
  background: var(--color-bg-light);
  border-top: 1px solid var(--color-border-light);
}

@keyframes modal-backdrop-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes modal-in {
  from { opacity: 0; transform: translateY(10px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* ── Dropdown ─────────────────────────────────────────────────────────── */
.dropdown {
  position: relative;
  display: inline-block;
}

.dropdown__menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: var(--z-dropdown);
  min-width: 200px;
  background: var(--color-bg);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--space-1);
  transform-origin: top right;
  animation: dropdown-spring-in var(--t-spring);
}

/* Variants for menu opening direction (when row near bottom or near left edge) */
.dropdown__menu--up   { top: auto; bottom: calc(100% + 6px); transform-origin: bottom right; }
.dropdown__menu--left { right: auto; left: 0; transform-origin: top left; }
.dropdown__menu--up.dropdown__menu--left { transform-origin: bottom left; }

.dropdown__item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  font-size: var(--font-size-sm);
  color: var(--color-text);
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: background var(--t-hover), color var(--t-hover);
  width: 100%;
  background: transparent;
  border: 0;
  text-align: left;
  font-family: inherit;
}

.dropdown__item:hover,
.dropdown__item:focus-visible {
  background: var(--color-bg-light);
  color: var(--color-dark);
  outline: none;
}

.dropdown__item--danger { color: var(--color-error); }
.dropdown__item--danger:hover,
.dropdown__item--danger:focus-visible { background: var(--color-error-light); color: var(--color-error); }

.dropdown__item .icon { flex-shrink: 0; opacity: 0.7; }
.dropdown__item:hover .icon { opacity: 1; }

.dropdown__divider {
  height: 1px;
  background: var(--color-border-light);
  margin: var(--space-1) 0;
}

@keyframes dropdown-spring-in {
  0%   { opacity: 0; transform: scale(0.92) translateY(-6px); }
  60%  { opacity: 1; transform: scale(1.02) translateY(1px); }
  100% { opacity: 1; transform: scale(1) translateY(0); }
}

/* ── Product picker (Shopify-product typeahead for import forms) ─────── */
.product-picker {
  position: relative;
  display: block;
}

.product-picker__dropdown {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  z-index: var(--z-dropdown);
  background: var(--color-bg);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--space-1);
  max-height: 320px;
  overflow-y: auto;
  transform-origin: top center;
  animation: dropdown-spring-in var(--t-spring);
}

.product-picker__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-2) var(--space-3);
  background: transparent;
  border: 0;
  border-radius: var(--radius-md);
  cursor: pointer;
  font-family: inherit;
  font-size: var(--font-size-sm);
  color: var(--color-text);
  text-align: left;
  transition: background var(--t-hover);
}

.product-picker__item:hover,
.product-picker__item:focus-visible {
  background: var(--color-bg-light);
  color: var(--color-dark);
  outline: none;
}

.product-picker__thumb {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-md);
  object-fit: cover;
  background: var(--color-bg-light);
}

.product-picker__info {
  display: flex;
  flex-direction: column;
  min-width: 0;            /* enables ellipsis on children */
  gap: 1px;
}

.product-picker__title {
  font-weight: var(--font-weight-medium);
  color: var(--color-dark);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.product-picker__meta {
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.product-picker__loading,
.product-picker__empty,
.product-picker__error {
  padding: var(--space-3);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  text-align: center;
}

.product-picker__error { color: var(--color-error); }

/* ── Row actions (inline primary action + three-dots dropdown) ────────── */
.row-actions {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  justify-content: flex-end;
}

.row-actions__trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 0;
  background: transparent;
  color: var(--color-text-muted);
  cursor: pointer;
  transition:
    background var(--t-hover),
    color var(--t-hover),
    box-shadow var(--t-hover),
    transform var(--t-spring);
}

.row-actions__trigger:hover {
  background: var(--color-bg-light);
  color: var(--color-dark);
}

.row-actions__trigger:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--color-primary-ring-strong);
}

.row-actions__trigger[aria-expanded="true"] {
  background: var(--color-bg-light);
  color: var(--color-primary);
  transform: scale(1.08);
}

/* ── Notification bell + dropdown panel ────────────────────────────────
   Used by views/partials/notification-bell.ejs.
   Architecture in DESIGN-STANDARDS §4 "Notification system". */
.notif {
  position: relative;
  display: inline-block;
}

.notif__trigger {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 0;
  background: transparent;
  color: var(--color-text-light);
  cursor: pointer;
  transition: background var(--t-hover), color var(--t-hover);
}
.notif__trigger:hover,
.notif__trigger[aria-expanded="true"] {
  background: var(--color-bg-light);
  color: var(--color-dark);
}
.notif__trigger:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--color-primary-light);
}

.notif__badge {
  /* Float slightly outside the circular bell so the badge has breathing room
     against the page background instead of being cramped inside the button.
     Standard pattern used by Gmail, Slack, GitHub. */
  position: absolute;
  top: -2px;
  right: -2px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: var(--radius-full);
  background: var(--color-error);
  color: var(--color-white);
  font-size: 10px;
  font-weight: var(--font-weight-bold);
  line-height: 14px;       /* visual centering inside 18px box with 2px border */
  text-align: center;
  border: 2px solid var(--color-bg);
  box-sizing: border-box;
  /* Reuses the existing dropdown-spring keyframe so new badges pop in */
  animation: dropdown-spring-in var(--t-spring);
}

.notif__panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: var(--z-dropdown);
  width: 360px;
  max-height: 480px;
  overflow-y: auto;
  background: var(--color-bg);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  animation: dropdown-spring-in var(--t-spring);
  transform-origin: top right;
}

.notif__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border-light);
  position: sticky;
  top: 0;
  background: var(--color-bg);
  z-index: 1;
}

.notif__title {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-dark);
  margin: 0;
}

.notif__header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.notif__header-btn {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  color: var(--color-primary);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  transition: color var(--t-hover);
}
.notif__header-btn:hover { color: var(--color-primary-hover); }
.notif__header-btn--danger { color: var(--color-error); }
.notif__header-btn--danger:hover { color: var(--color-error-hover); }

.notif__empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--space-8) var(--space-6);
  color: var(--color-text-muted);
  gap: var(--space-2);
}
.notif__empty-text {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  margin: 0;
}

.notif__list {
  display: flex;
  flex-direction: column;
}

.notif__item {
  position: relative;
  display: flex;
  align-items: stretch;
  border-bottom: 1px solid var(--color-border-light);
  background: transparent;
  /* HTMX swap animation: fade + slide + collapse when the row is being removed */
  max-height: 200px;
  overflow: hidden;
  transition: max-height var(--t-spring), opacity var(--t-hover), transform var(--t-hover), background var(--t-hover);
}
.notif__item:last-child { border-bottom: 0; }
.notif__item:hover,
.notif__item:focus-within {
  background: var(--color-bg-light);
}
.notif__item--unread { background: var(--color-primary-light); }
.notif__item--unread:hover,
.notif__item--unread:focus-within {
  background: var(--color-primary-light);
}

/* htmx-swapping is added by HTMX during the swap:200ms window before DOM removal */
.notif__item.htmx-swapping {
  opacity: 0;
  transform: translateX(24px);
  max-height: 0;
}

.notif__item-link {
  flex: 1;
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  text-decoration: none;
  color: inherit;
  min-width: 0;
}
.notif__item-link:focus-visible { outline: none; }

.notif__item-delete {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  background: transparent;
  border: 0;
  color: var(--color-text-muted);
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--t-hover), color var(--t-hover), background var(--t-hover);
}
.notif__item:hover .notif__item-delete,
.notif__item:focus-within .notif__item-delete {
  opacity: 1;
}
.notif__item-delete:hover {
  color: var(--color-error);
  background: var(--color-error-light, var(--color-bg-light));
}
/* Touch devices: always show the trash so it stays reachable without hover */
@media (hover: none) {
  .notif__item-delete { opacity: 1; }
}

.notif__item-icon {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--color-bg-light);
  color: var(--color-text-muted);
}
.notif__item--unread .notif__item-icon {
  background: var(--color-primary);
  color: var(--color-white);
}

.notif__item-body {
  flex: 1;
  min-width: 0;
}
.notif__item-title {
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  color: var(--color-dark);
  margin: 0 0 2px;
  line-height: var(--line-height-snug);
}
.notif__item-text {
  font-size: var(--font-size-xs);
  color: var(--color-text);
  margin: 0 0 2px;
  line-height: var(--line-height-normal);
  /* Clamp to 2 lines */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.notif__item-time {
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
  margin: 0;
}

.notif__item-dot {
  flex-shrink: 0;
  align-self: center;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-primary);
}

.notif__loading {
  padding: var(--space-6);
  text-align: center;
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

/* Sticky footer link in the dropdown — sends user to the full /notifications page */
.notif__footer-link {
  position: sticky;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-primary);
  text-decoration: none;
  background: var(--color-bg);
  border-top: 1px solid var(--color-border-light);
  transition: background var(--t-hover), color var(--t-hover);
}
.notif__footer-link:hover {
  background: var(--color-bg-light);
  color: var(--color-primary-hover);
}

/* Mobile: full-width panel on narrow screens */
@media (max-width: 480px) {
  .notif__panel {
    width: calc(100vw - var(--space-4));
    right: calc(-1 * var(--space-2));
  }
}

/* ── Tooltip ──────────────────────────────────────────────────────────── */
.tooltip-anchor {
  position: relative;
  display: inline-flex;
}

.tooltip {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  z-index: var(--z-tooltip);
  padding: var(--space-1) var(--space-2);
  background: var(--color-dark);
  color: var(--color-white);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  border-radius: var(--radius-md);
  white-space: nowrap;
  pointer-events: none;
  animation: tooltip-in var(--t-hover);
}

.tooltip::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 4px solid transparent;
  border-top-color: var(--color-dark);
}

@keyframes tooltip-in {
  from { opacity: 0; transform: translateX(-50%) translateY(2px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}

/* ── Alert (persistent inline banners) ────────────────────────────────── */
.alert {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-lg);
  border-left: 4px solid;
  font-size: var(--font-size-sm);
  line-height: var(--line-height-normal);
}

.alert__icon { flex-shrink: 0; margin-top: 2px; }
.alert__body { flex: 1; }
.alert__title { font-weight: var(--font-weight-semibold); margin-bottom: 2px; }

.alert--info {
  background: var(--color-info-light);
  border-left-color: var(--color-info);
  color: var(--color-dark);
}
.alert--info .alert__icon { color: var(--color-info); }

.alert--success {
  background: var(--color-success-light);
  border-left-color: var(--color-success);
  color: var(--color-dark);
}
.alert--success .alert__icon { color: var(--color-success); }

.alert--warning {
  background: var(--color-warning-light);
  border-left-color: var(--color-warning);
  color: var(--color-dark);
}
.alert--warning .alert__icon { color: var(--color-warning); }

.alert--error {
  background: var(--color-error-light);
  border-left-color: var(--color-error);
  color: var(--color-dark);
}
.alert--error .alert__icon { color: var(--color-error); }

/* ── Avatar ───────────────────────────────────────────────────────────── */
.avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-full);
  background: var(--color-primary);
  color: var(--color-white);
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-xs);
  flex-shrink: 0;
  overflow: hidden;
}

.avatar img { width: 100%; height: 100%; object-fit: cover; }

.avatar--sm { width: 24px; height: 24px; font-size: 10px; }
.avatar--lg { width: 48px; height: 48px; font-size: var(--font-size-sm); }
.avatar--xl { width: 64px; height: 64px; font-size: var(--font-size-lg); }

/* ── Form sections (used in Form template) ───────────────────────────── */
.form-section {
  border: none;
  padding: 0;
  margin: 0 0 var(--space-6) 0;
}

.form-section:last-child { margin-bottom: 0; }

.form-section__title {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-dark);
  margin-bottom: var(--space-2);
}

.form-section__hint {
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
  margin-bottom: var(--space-4);
}

.form-section__fields {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.card__footer {
  display: flex;
  gap: var(--space-2);
  justify-content: flex-end;
  padding: var(--space-4) var(--space-5);
  background: var(--color-bg-light);
  border-top: 1px solid var(--color-border-light);
}

/* ── Filter chips ─────────────────────────────────────────────────────── */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 30px;
  padding: 0 var(--space-3);
  background: var(--color-bg-light);
  border: 1.5px solid var(--color-border-light);
  border-radius: var(--radius-full);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  color: var(--color-text);
  cursor: pointer;
  transition: all var(--t-hover);
  white-space: nowrap;
}
.chip:hover,
.chip.is-active {
  background: var(--color-primary-light);
  border-color: var(--color-primary);
  color: var(--color-primary);
}

/* Count pill inside filter chips: "All (24)" — the parenthesized count */
.chip__count { opacity: 0.6; margin-left: 4px; }

/* ── Sparkline (inline trend chart) ───────────────────────────────────── */
/* Reusable inline chart with premium interactive polish — used in finance
   overview hero, future analytics widgets, or anywhere a "where the line
   goes" mini-view fits. Markup in views/partials/sparkline.ejs.

   Three feature layers, all opt-in via partial props:
     1. Smooth curves + gradient fill + animated draw-in (always)
     2. Gridlines + per-point dots (showGridlines / showDots)
     3. Hover crosshair + tooltip per column (hoverTooltips array)

   No client JS for any of these — the hover system uses CSS `:hover` on
   each column cell, with the crosshair and tooltip as cell children. */

.sparkline-wrapper {
  position: relative;
  width: 100%;
  /* Reset font-style noise that might bleed in from parent — tooltips
     style themselves explicitly. */
  line-height: 1;
}
.sparkline {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible; /* end-dot can extend slightly outside viewBox */
}
.sparkline__line {
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 400;
  stroke-dashoffset: 400;
  animation: sparkline-draw 1.2s ease-out forwards;
}
.sparkline__area {
  opacity: 0;
  animation: sparkline-fade 1.2s ease-out 0.2s forwards;
}
.sparkline__end-dot {
  transform-origin: center;
  transform-box: fill-box;
  opacity: 0;
  animation: sparkline-pop 0.3s cubic-bezier(0.34, 1.56, 0.64, 1) 1.1s forwards;
}
.sparkline__data-dot {
  transform-origin: center;
  transform-box: fill-box;
  opacity: 0;
  animation: sparkline-fade 0.3s ease-out 1.2s forwards;
}
.sparkline__empty {
  opacity: 0.6;
}
@keyframes sparkline-draw { to { stroke-dashoffset: 0; } }
@keyframes sparkline-fade { to { opacity: 1; } }
@keyframes sparkline-pop  { to { opacity: 1; transform: scale(1); } from { opacity: 0; transform: scale(0); } }
@media (prefers-reduced-motion: reduce) {
  .sparkline__line,
  .sparkline__area,
  .sparkline__end-dot,
  .sparkline__data-dot { animation: none; opacity: 1; stroke-dashoffset: 0; transform: scale(1); }
}

/* ── Hover overlay — CSS-only crosshair + tooltip per column ─────────── */
/* The overlay sits on top of the SVG, divided into N equal cells (one per
   data point column). Each cell hover shows its own crosshair line +
   tooltip card. Built on top of the existing chart so works with any
   multi-series sparkline that passes a `hoverTooltips` array. */

.sparkline-hover {
  position: absolute;
  inset: 0;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
}
.sparkline-hover__cell {
  position: relative;
  cursor: crosshair;
}

/* Crosshair — thin dotted vertical line centered in each cell. Hidden by
   default, fades in on cell hover. Repeating-gradient gives the dotted
   look without an SVG dependency. */
.sparkline-hover__crosshair {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 1px;
  transform: translateX(-50%);
  background-image: repeating-linear-gradient(
    to bottom,
    var(--color-border) 0 3px,
    transparent 3px 6px
  );
  opacity: 0;
  transition: opacity 0.15s ease-out;
  pointer-events: none;
}

/* Tooltip — floating card above the data point. Hidden by default, fades
   in and slides up on cell hover. Uses dark surface for the premium
   contrast against the gradient-tinted hero card behind. */
.sparkline-hover__tooltip {
  position: absolute;
  bottom: calc(100% + var(--space-2));
  left: 50%;
  transform: translateX(-50%) translateY(4px);
  background: var(--color-dark);
  color: var(--color-bg);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  font-size: var(--font-size-xs);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease-out, transform 0.15s ease-out;
  z-index: 2;
}
.sparkline-hover__tooltip-title {
  font-weight: var(--font-weight-semibold);
  margin-bottom: var(--space-1);
}
.sparkline-hover__tooltip-line {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-variant-numeric: tabular-nums;
}
.sparkline-hover__tooltip-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
}
.sparkline-hover__tooltip-dot--error   { background: var(--color-error); }
.sparkline-hover__tooltip-dot--success { background: var(--color-success); }
.sparkline-hover__tooltip-dot--warning { background: var(--color-warning); }
.sparkline-hover__tooltip-dot--primary { background: var(--color-primary); }
.sparkline-hover__tooltip-label {
  color: var(--color-border-light);
}
.sparkline-hover__tooltip-value {
  margin-left: auto;
  font-weight: var(--font-weight-semibold);
}

/* The hover trigger — show crosshair + tooltip when the cell is hovered. */
.sparkline-hover__cell:hover .sparkline-hover__crosshair,
.sparkline-hover__cell:hover .sparkline-hover__tooltip {
  opacity: 1;
}
.sparkline-hover__cell:hover .sparkline-hover__tooltip {
  transform: translateX(-50%) translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  .sparkline-hover__crosshair,
  .sparkline-hover__tooltip { transition: none; }
}

/* Compact sort select used inside the toolbar — pairs with .chip visually */
.toolbar__sort {
  height: 30px;
  padding: 0 var(--space-3);
}

/* ── Bookmarklet setup page ──────────────────────────────────────────────
   The "drag this to your bookmarks bar" install zone + the supported-platform
   list. Used by /reviews/import/bookmarklet (views/pages/reviews/import-bookmarklet.ejs).
*/

.bookmarklet-install {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-5);
  background: var(--color-bg-warm);
  border: 1px dashed var(--color-primary);
  border-radius: var(--radius-lg);
}

/* The draggable button itself — styled to look like a "real" pill-button so
   users recognize it as something to grab. The href is a `javascript:` URL,
   which we intercept with an onclick alert to nudge them to drag, not click. */
.bookmarklet-install__chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0 var(--space-5);
  height: 38px;
  background: var(--color-primary);
  color: var(--color-white);
  border-radius: var(--radius-full);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  text-decoration: none;
  cursor: grab;
  user-select: none;
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--t-hover), transform var(--t-hover);
}
.bookmarklet-install__chip:hover {
  box-shadow: var(--shadow-primary);
  transform: translateY(-1px);
}
.bookmarklet-install__chip:active { cursor: grabbing; }

.bookmarklet-install__hint {
  font-size: var(--font-size-sm);
  color: var(--color-text-light);
  margin: 0;
}

/* Supported platforms list — clean two-line rows.
   .item--planned dims rows that aren't yet implemented. */
.bookmarklet-platforms {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.bookmarklet-platforms__item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--space-3) var(--space-4);
  background: var(--color-bg-light);
  border-radius: var(--radius-md);
  border-left: 3px solid var(--color-primary);
}
.bookmarklet-platforms__item--planned {
  border-left-color: var(--color-border);
  opacity: 0.6;
}
.bookmarklet-platforms__name {
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-dark);
}
.bookmarklet-platforms__detail {
  font-size: var(--font-size-sm);
  color: var(--color-text-light);
}

/* ─────────────────────────────────────────────────────────────────────
   Bulk actions — REUSABLE pattern for any data table
   ─────────────────────────────────────────────────────────────────────
   Used by /reviews list and any future table that needs multi-select +
   batch operations. Pattern:
     • Each row has <input type="checkbox" class="row-check" data-id="...">
     • Header has    <input type="checkbox" class="row-check-all">
     • Page wraps the table in x-data="bulkActions({...})"
     • Page includes partials/bulk-actions.ejs near the bottom

   The bar is fixed at the bottom of the viewport and slides up when at
   least one row is selected. It floats above the page content with the
   sticky-region z-index.
*/

.bulk-actions {
  position: fixed;
  bottom: var(--space-4);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  box-shadow: var(--shadow-lg);
  z-index: 200;                 /* above content, below modals */
  font-size: var(--font-size-sm);
  /* Locked min-width prevents the centered bar from visually drifting as
     the count text changes between singular/plural ("1 review selected"
     vs "12 reviews selected") — the bar stays the same width, so its
     translateX(-50%) lands at the same pixel every time. */
  min-width: 340px;
  max-width: calc(100vw - 32px);
  flex-wrap: wrap;
  justify-content: center;
}
/* Visibility is handled by x-show (display: none | flex). The existing
   [x-cloak] { display: none !important } rule in this file hides the bar
   before Alpine has processed it on initial page load. */

.bulk-actions__count {
  font-weight: var(--font-weight-semibold);
  color: var(--color-dark);
  padding: 0 var(--space-2);
  white-space: nowrap;
}

.bulk-actions__divider {
  width: 1px;
  height: 20px;
  background: var(--color-border);
  flex-shrink: 0;
}

.bulk-actions__buttons {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

/* Row checkbox column — narrow + centered.
   Header AND body rows share the same column class for alignment.
   Note: tables using `table-layout: fixed` should set this width explicitly
   in their nth-child rules too (see .reviews-table in pages.css for example). */
.col-check {
  width: 40px;
  text-align: center;
  padding-left: var(--space-2);
  padding-right: var(--space-1);
}
.row-check,
.row-check-all {
  cursor: pointer;
  accent-color: var(--color-primary);
  width: 16px;
  height: 16px;
  margin: 0;
  vertical-align: middle;
}

/* Highlight the row when its checkbox is checked — easy visual feedback */
.table tbody tr.is-selected {
  background: var(--color-bg-warm);
}

/* Confirmation modal scoped class — uses .modal infrastructure but keeps
   bulk-action language consistent across pages. */
.bulk-confirm__title {
  margin-bottom: var(--space-2);
}
.bulk-confirm__body {
  font-size: var(--font-size-sm);
  color: var(--color-text);
  margin-bottom: var(--space-4);
  line-height: 1.5;
}
.bulk-confirm__warning {
  padding: var(--space-3);
  background: var(--color-warning-light);
  border-left: 3px solid var(--color-warning);
  border-radius: var(--radius-md);
  font-size: var(--font-size-sm);
  margin-bottom: var(--space-4);
}

/* ── Toggle — reusable slider for boolean state ───────────────────────────
   Generic on/off slider for settings, opt-ins, auto-renew flags, etc.
   Renders a hidden <input type="checkbox"> with a styled track + thumb.
   Drop the partial views/partials/toggle.ejs anywhere — pair with HTMX
   for server-side state, or keep as a plain form input for client-side.
   See DESIGN-STANDARDS §4.19 for the contract.
*/
.toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
  user-select: none;
}
.toggle__input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.toggle__track {
  position: relative;
  display: inline-block;
  width: var(--toggle-track-w);
  height: var(--toggle-track-h);
  background: var(--color-border);
  border-radius: 999px;
  transition: background 150ms ease;
  flex-shrink: 0;
}
.toggle__thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  background: var(--color-bg);
  border-radius: 50%;
  transition: transform 150ms ease;
  box-shadow: var(--shadow-sm);
}
.toggle__input:checked + .toggle__track {
  background: var(--color-success);
}
.toggle__input:checked + .toggle__track .toggle__thumb {
  transform: translateX(16px);
}
.toggle__input:focus-visible + .toggle__track {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}
.toggle__input:disabled + .toggle__track {
  opacity: 0.5;
  cursor: not-allowed;
}
.toggle__label {
  font-size: var(--font-size-sm);
  color: var(--color-text-light);
  font-weight: 500;
}

/* Size variants */
.toggle--sm .toggle__track { width: 28px; height: 16px; }
.toggle--sm .toggle__thumb { width: 12px; height: 12px; }
.toggle--sm .toggle__input:checked + .toggle__track .toggle__thumb { transform: translateX(12px); }

.toggle--lg .toggle__track { width: 44px; height: 24px; }
.toggle--lg .toggle__thumb { width: 20px; height: 20px; }
.toggle--lg .toggle__input:checked + .toggle__track .toggle__thumb { transform: translateX(20px); }

/* ── Tooltip — global drop-in for native title="" ──────────────────────────
   Usage: <button data-tooltip="Delete this entry">…</button>
   Default position is above the element with a small caret. No JS required.
   Pointer-events: none means the tooltip never blocks clicks on its anchor.
   Optional position override: data-tooltip-position="bottom" (default "top"). */
[data-tooltip] {
  position: relative;
}
[data-tooltip]::after,
[data-tooltip]::before {
  position: absolute;
  opacity: 0;
  pointer-events: none;
  transition: opacity 120ms ease, transform 120ms ease;
  z-index: var(--z-tooltip);
}
[data-tooltip]::after {
  content: attr(data-tooltip);
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translate(-50%, 4px);
  padding: 4px 8px;
  background: var(--color-dark);
  color: var(--color-bg);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  border-radius: var(--radius-md);
  white-space: nowrap;
  max-width: 240px;
  letter-spacing: 0.01em;
}
[data-tooltip]::before {
  content: '';
  bottom: calc(100% + 4px);
  left: 50%;
  transform: translate(-50%, 4px);
  border: 4px solid transparent;
  border-top-color: var(--color-dark);
}
[data-tooltip]:hover::after,
[data-tooltip]:hover::before,
[data-tooltip]:focus-visible::after,
[data-tooltip]:focus-visible::before {
  opacity: 1;
  transform: translate(-50%, 0);
}

/* Position variant: tooltip below the anchor (caret flips). */
[data-tooltip-position="bottom"]::after {
  bottom: auto;
  top: calc(100% + 8px);
}
[data-tooltip-position="bottom"]::before {
  bottom: auto;
  top: calc(100% + 4px);
  border-top-color: transparent;
  border-bottom-color: var(--color-dark);
}

