

/* react-ui/blocks/Sidebar/animations/tooltip.css */

/**
 * Tooltip Transition Keyframes
 *
 * Sistema de animaciones CSS para transiciones de tooltip con:
 * - Items staggered enter/exit
 * - Grid-based height transitions
 * - 3D title rotations
 *
 * Performance: GPU-accelerated (transform + opacity only)
 */

/* ============================================================================
   ITEMS ANIMATIONS - Staggered Enter/Exit
   ============================================================================ */

@keyframes tooltip-item-enter {
  from {
    opacity: 0;
    transform: translateX(-8px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes tooltip-item-exit {
  from {
    opacity: 1;
    transform: translateX(0);
  }
  to {
    opacity: 0;
    transform: translateX(-4px);
  }
}

/**
 * Item States con CSS Custom Properties
 *
 * Uso: <div style="--animation-order: 0" data-state="entering">
 */
.sidebar-sublink[data-state="entering"] {
  animation: tooltip-item-enter 150ms cubic-bezier(0.4, 0, 0.2, 1);
  animation-delay: calc(var(--animation-order, 0) * 30ms + 150ms);
  animation-fill-mode: both;
}

.sidebar-sublink[data-state="leaving"] {
  animation: tooltip-item-exit 100ms cubic-bezier(0.4, 0, 0.6, 1);
  animation-delay: calc(var(--animation-order, 0) * 20ms);
  animation-fill-mode: both;
}

/* ============================================================================
   TITLE 3D ROTATIONS
   ============================================================================ */

/**
 * Title Rotate Up (direction-aware)
 * Usado cuando navegamos hacia arriba en el sidebar
 */
@keyframes tooltip-title-rotate-up {
  from {
    transform: rotateX(0deg);
    opacity: 1;
  }
  to {
    transform: rotateX(-90deg);
    opacity: 0;
  }
}

@keyframes tooltip-title-enter-from-below {
  from {
    transform: rotateX(90deg);
    opacity: 0;
  }
  to {
    transform: rotateX(0deg);
    opacity: 1;
  }
}

/**
 * Title Rotate Down (direction-aware)
 * Usado cuando navegamos hacia abajo en el sidebar
 */
@keyframes tooltip-title-rotate-down {
  from {
    transform: rotateX(0deg);
    opacity: 1;
  }
  to {
    transform: rotateX(90deg);
    opacity: 0;
  }
}

@keyframes tooltip-title-enter-from-above {
  from {
    transform: rotateX(-90deg);
    opacity: 0;
  }
  to {
    transform: rotateX(0deg);
    opacity: 1;
  }
}

/**
 * Title States
 */
.tooltip-title[data-direction="up"][data-state="leaving"] {
  animation: tooltip-title-rotate-up 250ms cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

.tooltip-title[data-direction="up"][data-state="entering"] {
  animation: tooltip-title-enter-from-below 250ms cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

.tooltip-title[data-direction="down"][data-state="leaving"] {
  animation: tooltip-title-rotate-down 250ms cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

.tooltip-title[data-direction="down"][data-state="entering"] {
  animation: tooltip-title-enter-from-above 250ms cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

/* ============================================================================
   3D CUBE FACES (Enfoque A: Multi-cara)
   ============================================================================ */

/**
 * Cubo 3D con 6 caras para títulos
 *
 * Estructura:
 * .title-scene (perspective)
 *   └─ .title-cube (preserve-3d)
 *       ├─ .title-face--front
 *       ├─ .title-face--back
 *       ├─ .title-face--top
 *       ├─ .title-face--bottom
 *       ├─ .title-face--left
 *       └─ .title-face--right
 */

.title-scene {
  perspective: 600px;
  position: relative;
  width: 100%;
  height: 2rem;
}

.title-cube {
  width: 100%;
  height: 100%;
  position: relative;
  transform-style: preserve-3d;
  transition: transform 250ms cubic-bezier(0.4, 0, 0.2, 1);
  /* Empujar hacia atrás para evitar blur en texto */
  transform: translateZ(-1rem);
}

.title-face {
  position: absolute;
  width: 100%;
  height: 100%;
  backface-visibility: hidden;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  padding: 0 1rem;
  font-weight: 500;
}

/* Posicionamiento de caras - Vertical rotation (rotateX) */
.title-face--front {
  transform: rotateX(0deg) translateZ(1rem);
}

.title-face--top {
  transform: rotateX(90deg) translateZ(1rem);
}

.title-face--bottom {
  transform: rotateX(-90deg) translateZ(1rem);
}

.title-face--back {
  transform: rotateX(180deg) translateZ(1rem);
}

/* Estados del cubo - Direction-aware */
.title-cube[data-face="front"] {
  transform: translateZ(-1rem) rotateX(0deg);
}

.title-cube[data-face="top"] {
  transform: translateZ(-1rem) rotateX(-90deg);
}

.title-cube[data-face="bottom"] {
  transform: translateZ(-1rem) rotateX(90deg);
}

.title-cube[data-face="back"] {
  transform: translateZ(-1rem) rotateX(180deg);
}

/* ============================================================================
   GRID HEIGHT TRANSITION (Grid Trick)
   ============================================================================ */

/**
 * Grid trick para height: auto transitions
 *
 * Técnica: grid-template-rows: 0fr → 1fr
 * Browser support: Chrome 107+, Firefox 117+, Safari 16.4+
 */

.tooltip-content-grid {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 200ms cubic-bezier(0.4, 0, 0.2, 1);
  transition-delay: 50ms; /* Empieza después del fade-out de items */
}

.tooltip-content-grid[data-state="open"] {
  grid-template-rows: 1fr;
}

.tooltip-content-inner {
  overflow: hidden;
  min-height: 0; /* Crítico para que grid trick funcione */
}

/* ============================================================================
   UTILITY CLASSES
   ============================================================================ */

/**
 * Contenedor con perspective para títulos crossfade
 */
.tooltip-title-perspective {
  perspective: 600px;
  position: relative;
  width: 100%;
  height: 2rem;
  overflow: hidden;
}

/**
 * Disable animations durante hover rápido (opcional)
 * Usar con cuidado: puede causar flickering
 */
.tooltip-no-animations * {
  animation: none !important;
  transition: none !important;
}

/* ============================================================================
   DEBUG HELPERS
   ============================================================================ */

/**
 * Visualización de estados en debug mode
 */
[data-tooltip-debug="true"] .sidebar-sublink[data-state]::before {
  content: attr(data-state);
  position: absolute;
  top: 0;
  right: 0;
  font-size: 8px;
  background: rgba(255, 0, 0, 0.8);
  color: white;
  padding: 2px 4px;
  border-radius: 2px;
  pointer-events: none;
  z-index: 1000;
}

[data-tooltip-debug="true"] .tooltip-title[data-direction]::after {
  content: "dir:" attr(data-direction);
  position: absolute;
  bottom: 0;
  left: 0;
  font-size: 8px;
  background: rgba(0, 0, 255, 0.8);
  color: white;
  padding: 2px 4px;
  border-radius: 2px;
  pointer-events: none;
  z-index: 1000;
}

/* ============================================================================
   PERFORMANCE OPTIMIZATIONS
   ============================================================================ */

/**
 * GPU acceleration hints
 */
.sidebar-sublink[data-state],
.tooltip-title[data-state],
.title-cube {
  will-change: transform, opacity;
}

/**
 * Contain layout/paint/style para mejor performance
 */
.tooltip-content-grid {
  contain: layout style paint;
}

/**
 * Reduce motion para accesibilidad
 */
@media (prefers-reduced-motion: reduce) {
  .sidebar-sublink[data-state],
  .tooltip-title[data-state],
  .title-cube,
  .tooltip-content-grid {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}



/* react-ui/blocks/Terminal/panel/TerminalFilterDropdown/terminal-filter-dropdown.module.css */

/**
 * TerminalFilterDropdown Styles.
 *
 * Uses CSS Anchor Positioning API for dropdown placement.
 * Button acts as anchor, dropdown is positioned relative to it
 * with automatic flip behavior at viewport edges.
 *
 * @module components/devenv/terminal/panel/terminal-filter-dropdown/styles
 */

/* Trigger button - acts as CSS anchor */
.triggerButton {
  anchor-name: --filter-dropdown-anchor;
}

/* Dropdown menu - anchored to trigger button */
.dropdownMenu {
  position-anchor: --filter-dropdown-anchor;
  position: fixed;

  /* Position below and left-aligned */
  left: anchor(left);
  top: anchor(bottom);
  margin-top: 4px;

  /* Flip to above if no room below */
  position-try-fallbacks: flip-block, flip-inline;

  min-width: 180px;
  z-index: 50;

  /* Hidden by default */
  display: none;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 0.15s ease-out, transform 0.15s ease-out;
  pointer-events: none;
}

.dropdownMenu[data-open="true"] {
  display: block;
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

/* Fallback for browsers without CSS Anchor Positioning */
@supports not (anchor-name: none) {
  .dropdownMenu {
    position: absolute;
    left: 0;
    top: calc(100% + 4px);
    z-index: 50;
  }

  .dropdownMenu[data-open="true"] {
    display: block;
  }
}



/* react-ui/blocks/Terminal/panel/TerminalSessionTabs/terminal-session-tabs.module.css */

/**
 * TerminalSessionTabs Dropdown Styles.
 *
 * Uses CSS Anchor Positioning API for the "add container" dropdown.
 * The + button acts as anchor, dropdown is positioned below it
 * with automatic flip behavior at viewport edges.
 *
 * @module components/devenv/terminal/panel/terminal-session-tabs/styles
 */

/* + button - acts as CSS anchor */
.addButton {
  anchor-name: --session-tabs-add-anchor;
}

/* Container dropdown - anchored to + button */
.containerDropdown {
  position-anchor: --session-tabs-add-anchor;
  position: fixed;

  /* Position below and left-aligned */
  left: anchor(left);
  top: anchor(bottom);
  margin-top: 4px;

  /* Flip to above if no room below */
  position-try-fallbacks: flip-block, flip-inline;

  min-width: 200px;
  z-index: 50;

  /* Hidden by default */
  display: none;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 0.15s ease-out, transform 0.15s ease-out;
  pointer-events: none;
}

.containerDropdown[data-open="true"] {
  display: block;
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

/* Fallback for browsers without CSS Anchor Positioning */
@supports not (anchor-name: none) {
  .containerDropdown {
    position: absolute;
    left: 0;
    top: calc(100% + 4px);
    z-index: 50;
  }

  .containerDropdown[data-open="true"] {
    display: block;
  }
}



/* react-ui/components/MorphingPopover/morphing-popover.module.css */

/* CSS Variables for anchor positioning */
.morphingPopoverContainer {
  position: relative;
  display: inline-block;
  --anchor-name: morphing-trigger;
  --target-width: 220px;
  --target-height: 120px;
  --transition-duration: 0.2s;
}

/* Trigger button styles */
.morphingTrigger {
  anchor-name: var(--anchor-name);
  width: 44px;
  aspect-ratio: 1;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 24px;
  cursor: pointer;
  border: none;
  background: transparent;
  transition: background-color 0.2s;
}

.morphingTrigger:hover {
  background-color: hsl(var(--muted) / 0.5);
}

/* Popover styles - anchored to trigger by default */
.morphingPopover {
  position-anchor: var(--anchor-name);
  left: anchor(left);
  top: anchor(top);
  width: anchor-size(width);
  min-height: 0;
  border-radius: 50%;
  overflow: hidden;
  padding: 0;
  height: anchor-size(height);
  transition-behavior: allow-discrete;
  transition-property: display, overlay, width, height, top,
    border-radius, left, position-anchor, transform, opacity;
  transition-duration: var(--transition-duration);
  transition-timing-function: ease-out;
  transform-origin: center center;
  opacity: 0;
}

/* When popover is open - expand to target size */
.morphingPopover:popover-open {
  position-anchor: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: var(--target-width);
  height: var(--target-height);
  border-radius: 12px;
  opacity: 1;
  border: 1px solid hsl(var(--border));
  background: hsl(var(--background));
  box-shadow: 0 10px 40px -10px hsl(var(--foreground) / 0.3);
}

/* Starting style for animation - browser support required */
@starting-style {
  .morphingPopover:popover-open {
    position-anchor: var(--anchor-name);
    left: anchor(left);
    top: anchor(top);
    transform: none;
    border-radius: 50%;
    width: anchor-size(width);
    height: anchor-size(height);
    opacity: 0;
  }
}

/* Fallback for browsers without anchor positioning */
@supports not (anchor-name: none) {
  .morphingPopover {
    position: fixed;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%) scale(0.8);
    opacity: 0;
    pointer-events: none;
  }

  .morphingPopover:popover-open {
    transform: translate(-50%, -50%) scale(1);
    opacity: 1;
    pointer-events: auto;
  }

  @starting-style {
    .morphingPopover:popover-open {
      transform: translate(-50%, -50%) scale(0.8);
      opacity: 0;
    }
  }
}

/* Variant: Morphing to a specific target element */
.morphingPopoverTargetContainer {
  position: relative;
  display: inline-block;
  --anchor-name: morphing-trigger;
  --target-anchor-name: morphing-target;
  --transition-duration: 0.2s;
}

.morphingPopoverTarget {
  position-anchor: var(--anchor-name);
  left: anchor(left);
  top: anchor(top);
  width: anchor-size(width);
  min-height: 0;
  border-radius: 50%;
  overflow: hidden;
  padding: 0;
  height: anchor-size(height);
  transition-behavior: allow-discrete;
  transition-property: display, overlay, width, height, top,
    border-radius, left, position-anchor, transform, opacity;
  transition-duration: var(--transition-duration);
  transition-timing-function: ease-out;
}

.morphingPopoverTarget:popover-open {
  position-anchor: var(--target-anchor-name);
  left: anchor(left);
  top: anchor(top);
  border-radius: 12px;
  min-width: 200px;
  min-height: 120px;
  border: 1px solid hsl(var(--border));
  background: hsl(var(--background));
  box-shadow: 0 10px 40px -10px hsl(var(--foreground) / 0.3);
  opacity: 1;
}

@starting-style {
  .morphingPopoverTarget:popover-open {
    position-anchor: var(--anchor-name);
    left: anchor(left);
    top: anchor(top);
    border-radius: 50%;
    width: anchor-size(width);
    height: anchor-size(height);
    opacity: 0;
  }
}



/* react-ui/primitives/DotMatrix/dot.css */

/* =============================================================================
 *  DotMatrix — progressive fill model.
 *
 *  Cells light up one at a time in `pattern` order, stay lit until the
 *  cycle resets, then repeat. Implementation uses ONE CSS animation per
 *  matrix that drives a registered custom property `--dm-phase` from
 *  0 → 1 (fill), holds it at 1 (hold), then snaps back to 0 (reset)
 *  for a rest period.
 *
 *  Each cell carries a `--dm-threshold` (its position in the fill
 *  sequence, 0..1) and computes its own `::before` opacity as a step
 *  across `phase - threshold`, multiplied by `--dm-edge-sharpness` so
 *  the edge can range from "instant snap" to "warm fade".
 *
 *  Perf shape: N matrices = N animations total (not N × cells). Cell
 *  opacity is computed at paint time by calc(); the compositor batches
 *  updates via the shared phase var. With `contain: layout style paint`
 *  each cell is isolated so work doesn't cascade.
 * ============================================================================= */

@property --dm-phase {
	syntax: '<number>';
	initial-value: 0;
	inherits: true;
}

.dm-root {
	display: grid;
	width: 100%;
	gap: var(--dm-gap, 5px);
	padding: var(--dm-pad, 0.25rem);
	border-radius: 0.5rem;
	background-color: transparent;

	/* Skip render work when the matrix is offscreen. */
	content-visibility: auto;
	contain-intrinsic-size: auto 200px;
	transform: translateZ(0);

	--dm-on: var(--foreground);
	--dm-off: color-mix(in oklch, var(--foreground) 12%, transparent);
	--dm-glow: color-mix(in oklch, var(--foreground) 50%, transparent);
}

/* ─── Cell: base OFF layer — neutral dim ──────────────────────────────── */

.dm-cell {
	position: relative;
	aspect-ratio: 1 / 1;
	min-width: 4px;
	min-height: 4px;
	border-radius: var(--dm-radius, 32%);
	background-color: color-mix(in oklch, var(--foreground) 10%, transparent);
	opacity: var(--dm-off-opacity, 0.45);
	transform: scale(var(--dm-off-scale, 0.9));
	contain: layout style paint;

	--dm-threshold: 0;
	--dm-stagger-delay: 0ms;
}

/* ─── Pseudo: ON layer — LED look, fades in as phase crosses threshold ─ */

.dm-cell::before {
	content: '';
	position: absolute;
	inset: 0;
	border-radius: inherit;
	background-color: var(--dm-on);
	background-image:
		radial-gradient(
			circle at 32% 26%,
			rgb(255 255 255 / 0.35) 0%,
			rgb(255 255 255 / 0.12) 18%,
			transparent 48%
		),
		radial-gradient(
			circle at 70% 78%,
			rgb(0 0 0 / 0.22) 0%,
			transparent 60%
		);
	box-shadow:
		inset 0 0 1px rgb(255 255 255 / 0.55),
		inset 0 0 0 1px color-mix(in oklch, var(--dm-on) 65%, transparent),
		inset 0 -1px 2px color-mix(in oklch, var(--dm-on) 40%, black 20%);
	opacity: 0;
	pointer-events: none;
}

.dm-root[data-variant='glow'] .dm-cell::before {
	box-shadow:
		inset 0 0 1px rgb(255 255 255 / 0.55),
		inset 0 0 0 1px color-mix(in oklch, var(--dm-on) 65%, transparent),
		inset 0 -1px 2px color-mix(in oklch, var(--dm-on) 40%, black 20%),
		0 0 2px var(--dm-glow),
		0 0 6px var(--dm-glow),
		0 0 12px color-mix(in oklch, var(--dm-glow) 55%, transparent);
}

/* ─── Running: phase animates on root, cells derive state from it ────── */

.dm-root[data-status='running'] {
	animation-name: var(--dm-anim-phase);
	animation-duration: var(--dm-cycle-total, 2600ms);
	animation-iteration-count: infinite;
	animation-timing-function: linear;
	animation-fill-mode: both;
}

/* Lit fraction for THIS cell — 0 when off, 1 when fully filled, ramped
 * near the threshold by `--dm-edge-sharpness`. Reused by both the pseudo
 * opacity (the LED glow) and the cell's scale (grows when lit). */
.dm-root[data-status='running'] .dm-cell {
	opacity: 1;
	transform: scale(
		calc(
			var(--dm-off-scale, 0.88) +
			(var(--dm-on-scale, 1) - var(--dm-off-scale, 0.88)) *
			clamp(
				0,
				(var(--dm-phase) - var(--dm-threshold)) *
					var(--dm-edge-sharpness, 50),
				1
			)
		)
	);
}

.dm-root[data-status='running'] .dm-cell::before {
	opacity: clamp(
		0,
		calc(
			(var(--dm-phase) - var(--dm-threshold)) *
			var(--dm-edge-sharpness, 50)
		),
		1
	);
}

/* ─── Accent cells ────────────────────────────────────────────────────── */

.dm-cell[data-accent='true'] {
	opacity: 1;
	transform: scale(1);
}

.dm-cell[data-accent='true']::before {
	background-color: var(--primary);
	background-image: none;
	box-shadow:
		inset 0 0 1px rgb(255 255 255 / 0.5),
		0 0 3px color-mix(in oklch, var(--primary) 70%, transparent),
		0 0 7px color-mix(in oklch, var(--primary) 50%, transparent);
	opacity: 1 !important;
}

/* ─── Lifecycle FINAL animations ──────────────────────────────────────── */

@keyframes dm-success-pop {
	0% {
		transform: scale(0.94);
		filter: brightness(0.7);
	}
	45% {
		transform: scale(1.18);
		filter: brightness(1.4);
	}
	100% {
		transform: scale(1);
		filter: brightness(1);
	}
}

@keyframes dm-fail-strobe {
	0% {
		transform: scale(1);
		filter: brightness(1);
	}
	22% {
		transform: scale(1.22);
		filter: brightness(1.55) saturate(1.4);
	}
	55% {
		transform: scale(0.92);
		filter: brightness(0.75);
	}
	100% {
		transform: scale(0.97);
		filter: brightness(1);
	}
}

@keyframes dm-cancelled-dim {
	0% {
		transform: scale(1);
		opacity: 1;
	}
	100% {
		transform: scale(0.9);
		opacity: 0.55;
	}
}

.dm-root[data-status='success'] {
	animation: none;
}
.dm-root[data-status='success'] .dm-cell {
	opacity: 1;
	transform: scale(1);
	animation: dm-success-pop 520ms cubic-bezier(0.2, 0, 0.2, 1) both;
	animation-delay: var(--dm-stagger-delay, 0ms);
}
.dm-root[data-status='success'] .dm-cell::before {
	opacity: 1;
}

.dm-root[data-status='failed'] {
	animation: none;
}
.dm-root[data-status='failed'] .dm-cell {
	opacity: 1;
	animation: dm-fail-strobe 560ms cubic-bezier(0.2, 0, 0.2, 1) both;
	animation-delay: var(--dm-stagger-delay, 0ms);
}
.dm-root[data-status='failed'] .dm-cell::before {
	background-color: var(--destructive);
	box-shadow:
		inset 0 0 1px rgb(255 255 255 / 0.5),
		inset 0 0 0 1px color-mix(in oklch, var(--destructive) 55%, transparent),
		inset 0 -1px 2px color-mix(in oklch, var(--destructive) 40%, black 20%);
	opacity: 1;
}
.dm-root[data-status='failed'][data-variant='glow'] .dm-cell::before {
	box-shadow:
		inset 0 0 1px rgb(255 255 255 / 0.55),
		inset 0 0 0 1px color-mix(in oklch, var(--destructive) 55%, transparent),
		inset 0 -1px 2px color-mix(in oklch, var(--destructive) 40%, black 20%),
		0 0 3px color-mix(in oklch, var(--destructive) 70%, transparent),
		0 0 9px color-mix(in oklch, var(--destructive) 55%, transparent);
}

.dm-root[data-status='cancelled'] {
	animation: none;
}
.dm-root[data-status='cancelled'] .dm-cell {
	background-color: color-mix(in oklch, var(--foreground) 22%, transparent);
	opacity: 0.65;
	animation: dm-cancelled-dim 380ms cubic-bezier(0.4, 0, 0.8, 0.6) both;
	animation-delay: var(--dm-stagger-delay, 0ms);
}
.dm-root[data-status='cancelled'] .dm-cell::before {
	opacity: 0;
}

.dm-root[data-status='idle'] {
	animation: none;
}
.dm-root[data-status='idle'] .dm-cell::before {
	opacity: 0;
}

/* ─── Theme-token palettes ────────────────────────────────────────────── */

.dm--foreground {
	--dm-on: var(--foreground);
	--dm-off: color-mix(in oklch, var(--foreground) 12%, transparent);
	--dm-glow: color-mix(in oklch, var(--foreground) 55%, transparent);
}

.dm--primary {
	--dm-on: var(--primary);
	--dm-off: color-mix(in oklch, var(--primary) 14%, transparent);
	--dm-glow: color-mix(in oklch, var(--primary) 65%, transparent);
}

.dm--destructive {
	--dm-on: var(--destructive);
	--dm-off: color-mix(in oklch, var(--destructive) 14%, transparent);
	--dm-glow: color-mix(in oklch, var(--destructive) 65%, transparent);
}

.dm--warning {
	--dm-on: var(--warning);
	--dm-off: color-mix(in oklch, var(--warning) 14%, transparent);
	--dm-glow: color-mix(in oklch, var(--warning) 65%, transparent);
}

/* ─── Named palettes (OKLCH for stability) ────────────────────────────── */

.dm--cyan {
	--dm-on: oklch(90% 0.2 195);
	--dm-off: oklch(40% 0.08 195 / 0.4);
	--dm-glow: oklch(80% 0.25 195 / 0.95);
}
.dm--magenta {
	--dm-on: oklch(85% 0.25 330);
	--dm-off: oklch(40% 0.08 330 / 0.4);
	--dm-glow: oklch(75% 0.3 330 / 0.95);
}
.dm--yellow {
	--dm-on: oklch(95% 0.2 90);
	--dm-off: oklch(50% 0.08 90 / 0.4);
	--dm-glow: oklch(90% 0.25 90 / 0.95);
}
.dm--green {
	--dm-on: oklch(90% 0.25 145);
	--dm-off: oklch(40% 0.08 145 / 0.4);
	--dm-glow: oklch(80% 0.3 145 / 0.95);
}
.dm--orange {
	--dm-on: oklch(85% 0.22 50);
	--dm-off: oklch(45% 0.08 50 / 0.4);
	--dm-glow: oklch(75% 0.28 50 / 0.95);
}
.dm--blue {
	--dm-on: oklch(80% 0.22 260);
	--dm-off: oklch(40% 0.08 260 / 0.4);
	--dm-glow: oklch(70% 0.28 260 / 0.95);
}
.dm--red {
	--dm-on: oklch(70% 0.25 25);
	--dm-off: oklch(40% 0.08 25 / 0.4);
	--dm-glow: oklch(60% 0.3 25 / 0.95);
}
.dm--purple {
	--dm-on: oklch(75% 0.22 300);
	--dm-off: oklch(40% 0.08 300 / 0.4);
	--dm-glow: oklch(65% 0.28 300 / 0.95);
}
.dm--teal {
	--dm-on: oklch(82% 0.18 175);
	--dm-off: oklch(40% 0.08 175 / 0.4);
	--dm-glow: oklch(72% 0.24 175 / 0.95);
}
.dm--pink {
	--dm-on: oklch(80% 0.2 350);
	--dm-off: oklch(45% 0.08 350 / 0.4);
	--dm-glow: oklch(70% 0.26 350 / 0.95);
}
.dm--lime {
	--dm-on: oklch(88% 0.22 120);
	--dm-off: oklch(45% 0.08 120 / 0.4);
	--dm-glow: oklch(80% 0.28 120 / 0.95);
}
.dm--white {
	--dm-on: oklch(98% 0 0);
	--dm-off: oklch(50% 0 0 / 0.3);
	--dm-glow: oklch(95% 0 0 / 0.85);
}

/* ─── Reduced motion — freeze animations ─────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
	.dm-root[data-status='running'],
	.dm-root[data-status='success'] .dm-cell,
	.dm-root[data-status='failed'] .dm-cell,
	.dm-root[data-status='cancelled'] .dm-cell {
		animation: none !important;
	}
	.dm-cell {
		transform: none;
	}
}



/* react-ui/primitives/GooeyMorphingSurface/gooey-morphing.css */

/* =============================================================================
 *  GooeyMorphingSurface — CSS layer for the SVG rect morph + HTML overlays.
 *
 *  Classes are prefixed `.gms-*` so they act as a manual scope (mks-ui's
 *  rolldown build produces empty default-exports for CSS modules, so we use
 *  plain CSS with explicit classnames referenced as string literals from
 *  the component).
 *
 *  Every tunable value comes from inline CSS custom props set by the React
 *  component at the root element. No hard-coded dimensions or timings here.
 *
 *  Technique recap: two <rect>s inside a <g filter="url(#gooey)">. Body rect
 *  is a geometric CLONE of the pill when closed, and morphs into the card
 *  geometry (x, y, width, height, rx, ry all interpolate) when open. The
 *  gaussian-blur + alpha-threshold filter bends the overlapping silhouettes
 *  into a single shape with a soft metaball throat.
 * ============================================================================= */

.gms-root {
	position: relative;
	display: inline-block;
}

.gms-shell {
	position: relative;
	width: var(--gms-card-w);
	height: var(--gms-pill-h);
	color: var(--gms-fill);
	transition: height var(--gms-duration) var(--gms-ease);
	/* Drop-shadow follows the fused silhouette. Chained filters = additive
	 * shadow layers for depth without a hard box-shadow. */
	filter: drop-shadow(0 16px 38px rgb(0 0 0 / 0.35))
		drop-shadow(0 4px 10px rgb(0 0 0 / 0.18));
}

.gms-shell[data-open='true'] {
	height: calc(var(--gms-pill-h) + var(--gms-card-h));
}

.gms-svg {
	position: absolute;
	top: 0;
	left: 50%;
	/* translateZ(0) keeps the filtered region on its own GPU layer so Safari
	 * re-renders the gooey filter smoothly while the body rect's geometry is
	 * animated via WAAPI (Sileo Safari formula). */
	transform: translateX(-50%) translateZ(0);
	contain: layout style;
	display: block;
	overflow: visible;
	pointer-events: none;
}

/* The body rect's x/y/width/height are driven by the Web Animations API
 * (rect.animate, see index.tsx) — NOT a CSS transition, which WebKit refuses
 * to interpolate on SVG geometry attributes. `will-change` is the only hint
 * left here. */
.gms-body-rect {
	will-change: x, y, width, height;
}

.gms-pill {
	position: absolute;
	top: 0;
	left: var(--gms-pill-x);
	width: var(--gms-pill-w);
	height: var(--gms-pill-h);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	color: var(--card-foreground);
	pointer-events: none;
	z-index: 2;
}

.gms-card {
	position: absolute;
	top: calc(var(--gms-pill-h) - var(--gms-overlap));
	left: 0;
	width: var(--gms-card-w);
	height: var(--gms-card-h);
	color: var(--card-foreground);
	opacity: 0;
	transform: translateY(4px);
	pointer-events: none;
	z-index: 2;
	overflow: hidden;
	border-radius: var(--gms-card-r);
	transition:
		opacity calc(var(--gms-duration) * 0.35) var(--gms-ease),
		transform calc(var(--gms-duration) * 0.35) var(--gms-ease);
}

.gms-shell[data-open='true'] .gms-card {
	opacity: 1;
	transform: translateY(0);
	pointer-events: auto;
	transition:
		opacity calc(var(--gms-duration) * 0.55) var(--gms-ease)
			calc(var(--gms-duration) * 0.45),
		transform calc(var(--gms-duration) * 0.55) var(--gms-ease)
			calc(var(--gms-duration) * 0.45);
}

@media (prefers-reduced-motion: reduce) {
	.gms-shell,
	.gms-body-rect,
	.gms-card {
		transition-duration: 0.01ms !important;
	}
}



/* react-ui/primitives/waapi/Morph/techniques/useViewTransitions.module.css */

/**
 * View Transitions API - Default transition styles.
 *
 * These styles apply to all view-transition pseudo-elements by default,
 * eliminating the need for dynamic style injection based on transition names.
 *
 * Usage: Apply `view-transition-name` via inline style or CSS variable:
 *   <div style={{ viewTransitionName: 'hero' }}>...</div>
 *
 * Or via CSS:
 *   .my-element { view-transition-name: hero; }
 */

/* Default animation for all view transitions */
::view-transition-old(*),
::view-transition-new(*) {
  animation-duration: 300ms;
  animation-timing-function: ease-out;
}



/* react-ui/ui/DynamicToggle/DynamicToggle.css */

/**
 * DynamicToggle v2 — CSS state transitions.
 *
 * Rules requiring :has(), container queries, clip-path, or pseudo-elements.
 * Layout, colors, sizing in Tailwind (DynamicToggle.styles.ts).
 *
 * @import '@mks2508/mks-ui/react/ui/DynamicToggle/DynamicToggle.module.css';
 */

/* ── Variables ── */
[data-slot="dt-root"] {
  --dt-dur: 0.22s;
  --dt-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --dt-fade: 0.45;
  --dt-indicator-dur: 0.3s;
  --dt-indicator-ease: cubic-bezier(0.4, 0, 0.2, 1);
}

/* ── Track: explicit row prevents h-full items from overflowing container ── */
[data-slot="dt-root"] [data-slot="dt-track"] {
  grid-template-rows: minmax(0, 1fr);
}

/* ── Top-level option spans 2 grid cols ── */
[data-slot="dt-root"] [data-slot="dt-track"] > label {
  grid-column: span 2;
}

/* ── Primary option text ── */
[data-slot="dt-root"] [data-slot="dt-track"]:has(> input:checked) > label {
  color: var(--accent-foreground);
  z-index: 2;
}
[data-slot="dt-root"] [data-slot="dt-track"]:not(:has(> input:checked)) > label {
  color: var(--foreground);
  opacity: var(--dt-fade);
}

/* ── Group: container queries ── */
[data-slot="dt-root"] [data-slot="dt-group"] {
  container-type: size;
  overflow: hidden;
}

/* ══════════════════════════════════════════════════════════
 * INDICATOR POSITIONING
 *
 * Modern: CSS Anchor Positioning — indicator follows active option
 * Fallback: translate-based positioning for older browsers
 * ══════════════════════════════════════════════════════════ */

/* ── Anchor-based indicator (requires full anchor API) ── */
@supports (anchor-scope: all) {
  /* Scope anchors per toggle instance */
  [data-slot="dt-root"]:not([data-indicator="translate"]) {
    anchor-scope: --dt-active;
  }

  /* Active option becomes the anchor via native :checked */
  [data-slot="dt-root"]:not([data-indicator="translate"]) [data-slot="dt-track"] > label:has(+ input:checked) {
    anchor-name: --dt-active;
  }
  [data-slot="dt-root"]:not([data-indicator="translate"]) [data-slot="dt-group"] > label:has(+ input:checked) {
    anchor-name: --dt-active;
  }

  /* Single unified indicator: morphs from full-width to half-width */
  [data-slot="dt-root"]:not([data-indicator="translate"]) [data-slot="dt-indicator"] {
    position-anchor: --dt-active;
    top: anchor(top);
    right: anchor(right);
    bottom: anchor(bottom);
    left: anchor(left);
    translate: none;
    width: auto;
    transition:
      top var(--dt-indicator-dur) var(--dt-indicator-ease),
      right var(--dt-indicator-dur) var(--dt-indicator-ease),
      bottom var(--dt-indicator-dur) var(--dt-indicator-ease),
      left var(--dt-indicator-dur) var(--dt-indicator-ease);
  }

  /* Hide the group indicator — unified indicator handles everything */
  [data-slot="dt-root"]:not([data-indicator="translate"]) [data-slot="dt-group-indicator"] {
    display: none;
  }
}

/* ── Inset-based fallback (older browsers) — same morph as anchor but hardcoded ── */
@supports not (anchor-scope: all) {
  /* Unified indicator: left/right transition morphs width + position */
  [data-slot="dt-root"] [data-slot="dt-indicator"] {
    left: 50%;
    right: 0;
    width: auto;
    translate: none;
    transition:
      left var(--dt-indicator-dur) var(--dt-indicator-ease),
      right var(--dt-indicator-dur) var(--dt-indicator-ease);
  }
  /* Top-level checked: indicator covers left half */
  [data-slot="dt-root"] [data-slot="dt-track"]:has(> input:checked) [data-slot="dt-indicator"] {
    left: 0;
    right: 50%;
  }
  /* Group option 1 checked: indicator at 3rd quarter */
  [data-slot="dt-root"] [data-slot="dt-group"]:has(input:nth-of-type(1):checked) ~ [data-slot="dt-indicator"],
  [data-slot="dt-root"] [data-slot="dt-track"]:has([data-slot="dt-group"] input:nth-of-type(1):checked) [data-slot="dt-indicator"] {
    left: 50%;
    right: 25%;
  }
  /* Group option 2 checked: indicator at 4th quarter */
  [data-slot="dt-root"] [data-slot="dt-group"]:has(input:nth-of-type(2):checked) ~ [data-slot="dt-indicator"],
  [data-slot="dt-root"] [data-slot="dt-track"]:has([data-slot="dt-group"] input:nth-of-type(2):checked) [data-slot="dt-indicator"] {
    left: 75%;
    right: 0;
  }
  /* Hide group indicator — unified indicator handles everything */
  [data-slot="dt-root"] [data-slot="dt-group-indicator"] {
    display: none;
  }
}

/* ── Force inset mode via data-indicator="translate" (works regardless of @supports) ── */
[data-slot="dt-root"][data-indicator="translate"] [data-slot="dt-indicator"] {
  left: 50%;
  right: 0;
  width: auto;
  translate: none;
  transition:
    left var(--dt-indicator-dur) var(--dt-indicator-ease),
    right var(--dt-indicator-dur) var(--dt-indicator-ease);
}
[data-slot="dt-root"][data-indicator="translate"] [data-slot="dt-track"]:has(> input:checked) [data-slot="dt-indicator"] {
  left: 0;
  right: 50%;
}
[data-slot="dt-root"][data-indicator="translate"] [data-slot="dt-track"]:has([data-slot="dt-group"] input:nth-of-type(1):checked) [data-slot="dt-indicator"] {
  left: 50%;
  right: 25%;
}
[data-slot="dt-root"][data-indicator="translate"] [data-slot="dt-track"]:has([data-slot="dt-group"] input:nth-of-type(2):checked) [data-slot="dt-indicator"] {
  left: 75%;
  right: 0;
}
[data-slot="dt-root"][data-indicator="translate"] [data-slot="dt-group-indicator"] {
  display: none;
}

/* ══════════════════════════════════════════════════════════
 * GROUP COLLAPSED STATE
 *
 * ::before = title text (via data-label attr)
 * ::after  = combined opts text (via data-opts attr)
 * <label>s = controlled by data-collapsed mode
 *
 * 3 modes: title | opts | title-opts (default)
 * ══════════════════════════════════════════════════════════ */

/* ── ::before — group title ── */
[data-slot="dt-group"]::before {
  content: attr(data-label);
  position: absolute;
  left: 50%;
  top: 50%;
  translate: -50% -80%;
  color: var(--foreground);
  font-size: inherit;
  font-weight: 500;
  z-index: 2;
  white-space: nowrap;
  pointer-events: none;
  transition:
    scale var(--dt-dur) var(--dt-ease),
    translate var(--dt-dur) var(--dt-ease),
    opacity var(--dt-dur) var(--dt-ease);
}

/* ── ::after — combined opts text ── */
[data-slot="dt-group"]::after {
  content: attr(data-opts);
  position: absolute;
  left: 50%;
  top: 50%;
  translate: -50% 20%;
  color: var(--muted-foreground);
  font-size: 0.85em;
  opacity: 0.6;
  z-index: 2;
  white-space: nowrap;
  pointer-events: none;
  transition: opacity var(--dt-dur) var(--dt-ease);
}
[data-slot="dt-group"]:not([data-opts])::after {
  content: none;
}

/* ── Group labels — transition props ── */
[data-slot="dt-root"] [data-slot="dt-group"] label {
  color: var(--muted-foreground);
  cursor: pointer;
  z-index: 2;
  transition:
    color var(--dt-dur) var(--dt-ease),
    opacity var(--dt-dur) var(--dt-ease),
    translate var(--dt-dur) var(--dt-ease);
}
[data-slot="dt-root"] [data-slot="dt-group"] label span {
  display: grid;
  place-items: center;
  height: 100%;
  width: 100%;
  border-radius: var(--dt-radius, 9999px);
  transition: scale var(--dt-dur) var(--dt-ease);
}

/* ── Collapsed mode: "title" — only ::before, labels slide+scale out ── */
[data-slot="dt-group"][data-collapsed="title"]::before {
  translate: -50% -50%;
}
[data-slot="dt-group"][data-collapsed="title"]::after {
  display: none;
}
[data-slot="dt-group"][data-collapsed="title"]:not(:has(input:checked)) label {
  opacity: 0;
  translate: 0 30%;
}
[data-slot="dt-group"][data-collapsed="title"]:not(:has(input:checked)) label span {
  scale: 0.5;
}

/* ── Collapsed mode: "opts" — only ::after, labels slide+scale out ── */
[data-slot="dt-group"][data-collapsed="opts"]::before {
  display: none;
}
[data-slot="dt-group"][data-collapsed="opts"]::after {
  translate: -50% -50%;
  font-size: inherit;
  opacity: 0.7;
}
[data-slot="dt-group"][data-collapsed="opts"]:not(:has(input:checked)) label {
  opacity: 0;
  translate: 0 30%;
}
[data-slot="dt-group"][data-collapsed="opts"]:not(:has(input:checked)) label span {
  scale: 0.5;
}

/* ── Collapsed mode: "title-opts" — WIP: disabled, falls back to "title" behavior ── */
/* TODO: title-opts needs a redesign — title (::before) and scaled labels overlap
   at all container sizes. The codepen original morph relied on specific dimensions
   that don't translate to the component's size variants. Needs a different approach
   (e.g., crossfade, flex layout, or JS-measured positions). */
[data-slot="dt-group"][data-collapsed="title-opts"]::after {
  content: none;
}
[data-slot="dt-group"][data-collapsed="title-opts"]::before {
  translate: -50% -50%;
}
[data-slot="dt-group"][data-collapsed="title-opts"]:not(:has(input:checked)) label {
  opacity: 0;
  translate: 0 30%;
}

/* ── When group expanded ── */
[data-slot="dt-group"]:has(input:checked)::before {
  translate: -50% -250%;
  scale: 0.85;
}
[data-slot="dt-group"]:has(input:checked)::after {
  opacity: 0;
}
[data-slot="dt-group"]:has(input:checked) label {
  opacity: 0.75;
  color: var(--muted-foreground);
  translate: 0 0;
}
[data-slot="dt-group"]:has(input:checked) label span {
  scale: 1;
}
[data-slot="dt-group"]:has(input:nth-of-type(1):checked) label:nth-of-type(1),
[data-slot="dt-group"]:has(input:nth-of-type(2):checked) label:nth-of-type(2) {
  color: var(--foreground);
  opacity: 1;
}

/* ══════════════════════════════════════════════════════════
 * GROUP LABEL / BUBBLE (above or below the pill)
 *
 * Positioned via CSS. In filter/path morph modes, rendered with GooeyCanvas.
 * In none mode, simple CSS-driven show/hide.
 * bubblePosition: top | bottom (no left/right in v2)
 * ══════════════════════════════════════════════════════════ */

[data-slot="dt-group-label"] {
  display: grid;
  grid-template-rows: 0fr;
  left: 20%;
  right: 20%;
  transition:
    grid-template-rows calc(var(--dt-dur) * 1.5) var(--dt-ease),
    opacity var(--dt-dur) var(--dt-ease);
  opacity: 0;
  background: var(--card);
  border: 1px solid var(--border);
  z-index: 3;
  transform: translateZ(0);
  -webkit-transform: translateZ(0);
}
[data-slot="dt-group-label"] > span {
  overflow: hidden;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 0.75em;
  height: calc(var(--dt-h, 38px) * 0.4);
  box-sizing: border-box;
}

/* Top position */
[data-slot="dt-group-label"][data-bubble-position="top"] {
  bottom: 100%;
  border-radius: calc(var(--dt-h, 38px) * 0.2) calc(var(--dt-h, 38px) * 0.2) 0 0;
  border-bottom: none;
  margin-bottom: -1px;
}

/* Bottom position */
[data-slot="dt-group-label"][data-bubble-position="bottom"] {
  top: 100%;
  border-radius: 0 0 calc(var(--dt-h, 38px) * 0.2) calc(var(--dt-h, 38px) * 0.2);
  border-top: none;
  margin-top: -1px;
}

/* When group active → group label grows (vertical: top/bottom) */
[data-slot="dt-root"]:not(:has([data-slot="dt-track"] > input:checked)) [data-slot="dt-group-label"][data-bubble-position="top"],
[data-slot="dt-root"]:not(:has([data-slot="dt-track"] > input:checked)) [data-slot="dt-group-label"][data-bubble-position="bottom"] {
  grid-template-rows: 1fr;
  opacity: 1;
}
[data-slot="dt-root"]:not(:has([data-slot="dt-track"] > input:checked)) [data-slot="dt-group-label"][data-bubble-position="top"] > span,
[data-slot="dt-root"]:not(:has([data-slot="dt-track"] > input:checked)) [data-slot="dt-group-label"][data-bubble-position="bottom"] > span {
  padding: 0.35em 0.75em;
}

/* ── Filter morph mode ── */
[data-slot="dt-root"][data-morph="filter"] [data-slot="dt-group-label"] {
  border: none;
}
[data-slot="dt-root"][data-morph="filter"] [data-slot="dt-track"] {
  position: relative;
  z-index: 1;
}

/* ── Filter morph: ::before hides on expand, gooey canvas handles junction ── */
[data-slot="dt-root"][data-morph="filter"] [data-slot="dt-group"]:has(input:checked)::before {
  opacity: 0;
  translate: -50% -80%;
  scale: 1;
}

/* ── Path morph mode ── */
[data-slot="dt-root"][data-morph="path"] [data-slot="dt-track"] {
  position: relative;
  z-index: 1;
}



/* react-ui/ui/GooeyButton/gooey.css */

/* =============================================================================
 *  GooeyButton — transparent hit area over the pill region.
 *
 *  The visual pill is drawn by the <GooeyMorphingSurface> primitive; this
 *  layer is a single button that captures clicks in both open and closed
 *  states without painting anything. All layout math comes from the
 *  primitive's CSS custom props (--gms-pill-w, --gms-pill-h).
 * ============================================================================= */

.gbtn-host {
	position: relative;
	display: inline-block;
}

.gbtn-trigger {
	position: absolute;
	top: 0;
	/* Follow the pill's computed X (which honours `pillOffsetX`) instead of
	 * centring the hit-area in the host. Centring worked only while
	 * `pillOffsetX === 0`; any non-zero offset drifted the visual pill away
	 * from the invisible trigger. See `GooeyButton/index.tsx` — the host
	 * exposes `--gms-pill-x` identical to the primitive's internal value. */
	left: var(--gms-pill-x);
	z-index: 3;
	width: var(--gms-pill-w);
	height: var(--gms-pill-h);
	padding: 0;
	margin: 0;
	border: 0;
	background: transparent;
	cursor: pointer;
	font: inherit;
	color: inherit;
	/* Pill-shaped focus ring. */
	border-radius: 9999px;
}

.gbtn-trigger:focus-visible {
	outline: 2px solid var(--ring, currentColor);
	outline-offset: 2px;
}

.gbtn-trigger:disabled {
	cursor: not-allowed;
	pointer-events: none;
}



/* react-ui/ui/Tabs/Tabs.css */

/**
 * Tabs CSS Anchor Positioning.
 *
 * Zero-JS position tracking for the sliding indicator using CSS Anchor API.
 * The indicator automatically follows the active tab via anchor positioning.
 */

/* Scope anchors per Tabs instance */
[data-slot="tabs-list"] {
  anchor-scope: --tabs-active;
}

/* Active tab becomes the anchor */
[data-slot="tabs-tab"][data-active] {
  anchor-name: --tabs-active;
}

/* Indicator follows the active anchor */
[data-slot="tabs-indicator"] {
  position-anchor: --tabs-active;
  left: anchor(left);
  right: anchor(right);
  transition:
    top 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94),
    left 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94),
    right 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94),
    bottom 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94),
    width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94),
    height 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

/* Respect reduced motion preference */
@media (prefers-reduced-motion: reduce) {
  [data-slot="tabs-indicator"] {
    transition-duration: 0ms;
  }
}

