{"version":3,"file":"apgrid.css","mappings":"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","sources":["webpack://ap/./src/styles/_base.scss","webpack://ap/./src/styles/_tokens.scss","webpack://ap/./src/styles/_header.scss","webpack://ap/./src/styles/_cells.scss","webpack://ap/./src/styles/_frozen.scss","webpack://ap/./src/styles/_editors.scss","webpack://ap/./src/styles/_grouping.scss","webpack://ap/./src/styles/_overlays.scss","webpack://ap/./src/styles/_theme-dark.scss"],"sourcesContent":["// Root: emit the light tokens and the grid's own box model + scroll structure.\n@use 'tokens' as *;\n\n.apg {\n  @include tokens($light);\n\n  position: relative;\n  overflow: hidden;\n  font: var(--apg-font);\n  color: var(--apg-cell-fg);\n  background: var(--apg-cell-bg);\n  box-sizing: border-box;\n  user-select: none;\n  -webkit-user-select: none;\n\n  *,\n  *::before,\n  *::after {\n    box-sizing: border-box;\n  }\n}\n\n.apg-viewport {\n  position: absolute;\n  inset: 0;\n  overflow: auto;\n\n  // Slimmer, theme-aware scrollbars so the chrome doesn't fight the content.\n  scrollbar-width: thin;\n  scrollbar-color: var(--apg-scrollbar-thumb) transparent;\n\n  &::-webkit-scrollbar {\n    width: 11px;\n    height: 11px;\n  }\n\n  &::-webkit-scrollbar-thumb {\n    background: var(--apg-scrollbar-thumb);\n    border: 3px solid transparent;\n    border-radius: 8px;\n    background-clip: padding-box;\n  }\n\n  &::-webkit-scrollbar-thumb:hover {\n    background: var(--apg-border-strong);\n    background-clip: padding-box;\n  }\n}\n\n.apg-canvas {\n  position: relative;\n  display: grid;\n}\n\n// The body is a viewport-sized panel the compositor keeps pinned (like the\n// header), not a slice of a giant scrolling layer. Rows inside are translated by\n// the scroll offset, so content never sits millions of pixels down where a fast\n// drag would outrun rasterization and flash blank. The tall canvas above only\n// provides the scrollbar range.\n.apg-cells {\n  grid-area: 1 / 1;\n  align-self: start;\n  justify-self: start;\n  position: sticky;\n  top: 0;\n  z-index: 0;\n  overflow: hidden;\n}\n\n.apg-corner {\n  grid-area: 1 / 1;\n  align-self: start;\n  justify-self: start;\n  position: sticky;\n  top: 0;\n  left: 0;\n  z-index: 5;\n  background: var(--apg-header-bg);\n  border-right: var(--apg-border);\n  border-bottom: var(--apg-border);\n}\n\n// Focus: no default outline on click; a clear accent ring for keyboard users.\n.apg:focus {\n  outline: none;\n}\n\n.apg:focus-visible {\n  outline: 2px solid var(--apg-focus-ring);\n  outline-offset: -2px;\n}\n\n// Inline SVG icon wrapper. Size/color come from the element it's placed on.\n.apg-icon {\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  width: 16px;\n  height: 16px;\n  flex: none;\n  line-height: 0;\n\n  svg {\n    display: block;\n    width: 100%;\n    height: 100%;\n  }\n}\n","// =============================================================================\n// apgrid — design tokens\n// =============================================================================\n// Every visual value is a CSS custom property on `.apg`, so consumers retheme at\n// runtime by overriding a variable and the light/dark theme files just set\n// different defaults. Token NAMES are the public API and are kept stable\n// (`--apg-cell-bg`, `--apg-active-border`, …); only their default VALUES are\n// refreshed here. The Grid also writes `--apg-row-height`,\n// `--apg-header-height`, and `--apg-group-header-height` at runtime.\n\n@use 'sass:map';\n\n// ---- Light (default) palette ------------------------------------------------\n// A calm neutral surface with a single blue accent, soft hairline borders and\n// airy spacing — ag-Grid Quartz in spirit, with Wijmo's crisp header contrast.\n$light: (\n  // geometry\n  'row-height': 30px,\n  'header-height': 36px,\n  'group-header-height': 34px,\n  'col-width': 100px,\n  'cell-padding-x': 12px,\n  'radius': 6px,\n  'radius-sm': 4px,\n  // typography\n  'font-family': (\n      -apple-system,\n      BlinkMacSystemFont,\n      'Segoe UI',\n      Roboto,\n      Helvetica,\n      Arial,\n      sans-serif\n    ),\n  'font-size': 13px,\n  'line-height': 1.45,\n  // surfaces\n  'cell-bg': #ffffff,\n  'cell-bg-alt': #f7f9fc,\n  'cell-fg': #1f2933,\n  'surface-sunken': #eef1f6,\n  'fg-muted': #5a6675,\n  // borders\n  'border-color': #e3e7ef,\n  'border-strong': #cbd2dd,\n  // header\n  'header-bg': #f4f6fa,\n  'header-fg': #3d4757,\n  // accent + states  (`active-border` is the legacy accent token name)\n  'active-border': #2563eb,\n  'accent-contrast': #ffffff,\n  'selected-bg': rgba(37, 99, 235, 0.1),\n  'hover-bg': rgba(37, 99, 235, 0.055),\n  'focus-ring': rgba(37, 99, 235, 0.4),\n  // grouping\n  'group-bg': #eef2fb,\n  'group-bg-hover': #e4eaf7,\n  'panel-bg': #eef1f6,\n  'frozen-cell-bg': #eef4fc,\n  // chrome\n  'shadow-sm': (0 1px 2px rgba(15, 23, 42, 0.06)),\n  'shadow-md': (0 4px 12px rgba(15, 23, 42, 0.14)),\n  'shadow-lg': (0 10px 28px rgba(15, 23, 42, 0.2)),\n  'scrollbar-thumb': rgba(15, 23, 42, 0.18),\n  'control-hover': rgba(15, 23, 42, 0.06),\n  'checkbox-border': #9aa3af\n);\n\n// ---- Dark palette (value overrides only) ------------------------------------\n$dark: (\n  'cell-bg': #1b1f27,\n  'cell-bg-alt': #21262f,\n  'cell-fg': #e6e9ee,\n  'surface-sunken': #161a21,\n  'fg-muted': #9aa4b2,\n  'border-color': #2c333d,\n  'border-strong': #3a424e,\n  'header-bg': #232833,\n  'header-fg': #c2cad6,\n  'active-border': #4b8bff,\n  'accent-contrast': #0d1017,\n  'selected-bg': rgba(75, 139, 255, 0.22),\n  'hover-bg': rgba(75, 139, 255, 0.12),\n  'focus-ring': rgba(75, 139, 255, 0.55),\n  'group-bg': #262c37,\n  'group-bg-hover': #2d3540,\n  'panel-bg': #1f242d,\n  'frozen-cell-bg': #222834,\n  'shadow-sm': (\n    0 1px 2px rgba(0, 0, 0, 0.4),\n  ),\n  'shadow-md': (\n    0 4px 12px rgba(0, 0, 0, 0.5),\n  ),\n  'shadow-lg': (\n    0 12px 30px rgba(0, 0, 0, 0.6),\n  ),\n  'scrollbar-thumb': rgba(255, 255, 255, 0.22),\n  'control-hover': rgba(255, 255, 255, 0.08),\n  'checkbox-border': #5c6675,\n);\n\n// Emit a token map as `--apg-*` custom properties plus the composite vars\n// (border shorthand, cell padding, font) — the composites only when their\n// primitives are present, so a partial override map (e.g. $dark) stays clean.\n@mixin tokens($m) {\n  @each $name, $value in $m {\n    --apg-#{$name}: #{$value};\n  }\n  @if map.has-key($m, 'border-color') {\n    --apg-border: 1px solid var(--apg-border-color);\n  }\n  @if map.has-key($m, 'cell-padding-x') {\n    --apg-cell-padding: 0 var(--apg-cell-padding-x);\n  }\n  @if map.has-key($m, 'font-family') {\n    --apg-font: var(--apg-font-size) / var(--apg-line-height) var(--apg-font-family);\n  }\n}\n","// Column header, multi-level column groups, sort arrow, filter button.\n\n.apg-header-inner {\n  grid-area: 1 / 1;\n  align-self: start;\n  justify-self: start;\n  position: sticky;\n  top: 0;\n  z-index: 3;\n  background: var(--apg-header-bg);\n  border-bottom: var(--apg-border);\n}\n\n.apg-header-cell {\n  position: absolute;\n  top: 0;\n  height: 100%;\n  display: flex;\n  align-items: center;\n  padding: var(--apg-cell-padding);\n  font-weight: 600;\n  color: var(--apg-header-fg);\n  letter-spacing: 0.01em;\n  border-right: var(--apg-border);\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  cursor: default;\n  transition: background-color 0.12s ease;\n\n  &.apg-sortable {\n    cursor: pointer;\n\n    &:hover {\n      background: var(--apg-control-hover);\n    }\n  }\n}\n\n.apg-sort-arrow {\n  margin-left: 4px;\n  font-size: 0.7em;\n  color: var(--apg-active-border);\n}\n\n// ---- Multi-level column groups ---------------------------------------------\n// The group band sits above the leaf header, pinned to the top edge; the leaf\n// header is pushed down by its height.\n.apg-columngroup-inner {\n  grid-area: 1 / 1;\n  align-self: start;\n  justify-self: start;\n  position: sticky;\n  top: 0;\n  z-index: 4;\n  background: var(--apg-header-bg);\n  border-bottom: var(--apg-border);\n}\n\n.apg-columngroup-cell {\n  position: absolute;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  gap: 4px;\n  padding: var(--apg-cell-padding);\n  font-weight: 600;\n  color: var(--apg-header-fg);\n  border-right: var(--apg-border);\n  border-bottom: var(--apg-border);\n  // Subtle top-down tint gives grouped bands a touch of depth over the leaves.\n  background:\n    linear-gradient(to bottom, var(--apg-control-hover), transparent 70%), var(--apg-header-bg);\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n\n  // A shallow leaf's header rendered inside the band as one tall cell.\n  // fillHeaderCell gives it .apg-header-cell styling (left-aligned, sortable);\n  // the band just supplies the divider so it reads as a normal column header.\n  &.apg-columngroup-leaf {\n    border-right: var(--apg-border);\n    border-bottom: none;\n    background: var(--apg-header-bg);\n  }\n\n  &.apg-collapsible {\n    cursor: pointer;\n\n    &:hover {\n      background: var(--apg-group-bg-hover);\n    }\n  }\n}\n\n// Collapse/expand animation, opt-in via the `columnGroupAnimation` option (adds\n// `.apg-animated` to the host). Group header cells ease their geometry as\n// columns hide/show, mirroring Wijmo FlexGrid's `.animated` transition.\n.apg-animated .apg-columngroup-cell {\n  transition:\n    left 0.2s ease,\n    width 0.2s ease,\n    top 0.2s ease,\n    height 0.2s ease;\n}\n\n.apg-columngroup-chevron {\n  width: 14px;\n  height: 14px;\n  flex: none;\n  color: var(--apg-header-fg);\n  transition: transform 0.18s ease;\n\n  // Chevron points right when collapsed, down when expanded.\n  &.apg-columngroup-chevron-open {\n    transform: rotate(90deg);\n  }\n}\n\n.apg-columngroup-label {\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n// ---- Filter button on filterable headers -----------------------------------\n.apg-filter-btn {\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  width: 20px;\n  height: 20px;\n  margin-left: auto;\n  padding: 0;\n  border: none;\n  border-radius: var(--apg-radius-sm);\n  background: transparent;\n  color: var(--apg-header-fg);\n  opacity: 0.55;\n  cursor: pointer;\n  flex: none;\n  transition:\n    background-color 0.12s ease,\n    opacity 0.12s ease;\n\n  .apg-icon {\n    width: 13px;\n    height: 13px;\n  }\n\n  &:hover {\n    background: var(--apg-control-hover);\n    opacity: 1;\n  }\n\n  &.apg-filter-active {\n    color: var(--apg-active-border);\n    opacity: 1;\n  }\n}\n\n// ---- Row-number header column ----------------------------------------------\n.apg-rowheader-inner {\n  grid-area: 1 / 1;\n  align-self: start;\n  justify-self: start;\n  position: sticky;\n  top: 0;\n  left: 0;\n  z-index: 3;\n  overflow: hidden;\n  background: var(--apg-header-bg);\n  border-right: var(--apg-border);\n}\n\n.apg-rowheader-cell {\n  position: absolute;\n  left: 0;\n  top: 0;\n  width: 100%;\n  height: var(--apg-row-height);\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  font-size: 0.85em;\n  color: var(--apg-fg-muted);\n  border-bottom: var(--apg-border);\n  will-change: transform;\n}\n\n.apg-rowheader-group {\n  background: var(--apg-group-bg);\n}\n","// Data rows and cells: striping, hover, selection, merge layer, alignment,\n// boolean checkboxes, and the data-map dropdown affordance.\n\n.apg-row {\n  position: absolute;\n  left: 0;\n  top: 0;\n  width: 100%;\n  height: var(--apg-row-height);\n  background: var(--apg-cell-bg);\n  will-change: transform;\n  contain: layout style;\n\n  &.apg-row-alt {\n    background: var(--apg-cell-bg-alt);\n  }\n\n  &:hover {\n    background: var(--apg-hover-bg);\n  }\n}\n\n.apg-cell {\n  position: absolute;\n  top: 0;\n  height: 100%;\n  display: flex;\n  align-items: center;\n  padding: var(--apg-cell-padding);\n  border-right: var(--apg-border);\n  border-bottom: var(--apg-border);\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n\n  &.apg-cell-selected {\n    background: var(--apg-selected-bg);\n  }\n\n  &.apg-cell-active {\n    box-shadow: inset 0 0 0 2px var(--apg-active-border);\n    border-radius: 1px;\n  }\n}\n\n// Merge layer: spanning cells paint here, above the normal rows.\n.apg-merge-layer {\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: 1;\n}\n\n.apg-cell-merged {\n  background: var(--apg-cell-bg);\n  align-items: center;\n  border-left: var(--apg-border);\n  border-top: var(--apg-border);\n\n  &.apg-cell-selected {\n    background: var(--apg-selected-bg);\n  }\n}\n\n// Data-mapped, editable cells show a chevron at rest so they read as dropdowns.\n.apg-cell-dropdown {\n  padding-right: 20px;\n\n  &::after {\n    content: '';\n    position: absolute;\n    right: 8px;\n    top: 50%;\n    margin-top: -2px;\n    border-left: 4px solid transparent;\n    border-right: 4px solid transparent;\n    border-top: 5px solid var(--apg-header-fg);\n    opacity: 0.5;\n    pointer-events: none;\n  }\n}\n\n.apg-align-left {\n  justify-content: flex-start;\n}\n\n.apg-align-center {\n  justify-content: center;\n}\n\n.apg-align-right {\n  justify-content: flex-end;\n}\n\n.apg-cell-bool::before {\n  content: '';\n  width: 16px;\n  height: 16px;\n  border: 1.5px solid var(--apg-checkbox-border);\n  border-radius: var(--apg-radius-sm);\n  background: var(--apg-cell-bg);\n  transition:\n    border-color 0.12s ease,\n    background-color 0.12s ease;\n}\n\n.apg-cell-bool.apg-checked::before {\n  border-color: var(--apg-active-border);\n  background: var(--apg-active-border)\n    url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='white' stroke-width='2.5'><path d='M3 8.5l3.5 3.5L13 4.5'/></svg>\")\n    center / 12px no-repeat;\n}\n\n.apg-cell-template {\n  overflow: hidden;\n}\n\n// Drop marker shown while dragging a column to reorder.\n.apg-col-drop-marker {\n  position: absolute;\n  top: 0;\n  width: 2px;\n  height: 100%;\n  margin-left: -1px;\n  background: var(--apg-active-border);\n  pointer-events: none;\n  z-index: 5;\n}\n","// Pinned (frozen) bands. Each is a sticky panel the compositor keeps in place:\n// columns pin left, rows pin top, and the corner pins both. Opaque backgrounds\n// and a heavier boundary edge separate the frozen area from the scrolling body.\n\n.apg-frozen-cols,\n.apg-frozen-rows,\n.apg-frozen-corner,\n.apg-frozen-cols-header,\n.apg-frozen-rows-header {\n  grid-area: 1 / 1;\n  align-self: start;\n  justify-self: start;\n  position: sticky;\n  background: var(--apg-cell-bg);\n}\n\n.apg-frozen-cols {\n  z-index: 2;\n  overflow: hidden;\n  border-right: 2px solid var(--apg-border-strong);\n}\n\n.apg-frozen-rows {\n  z-index: 2;\n  border-bottom: 2px solid var(--apg-border-strong);\n}\n\n.apg-frozen-cols-header,\n.apg-frozen-rows-header {\n  z-index: 4;\n}\n\n.apg-frozen-corner {\n  z-index: 3;\n  border-right: 2px solid var(--apg-border-strong);\n  border-bottom: 2px solid var(--apg-border-strong);\n}\n\n.apg-frozen-cols-header {\n  top: 0;\n  background: var(--apg-header-bg);\n  border-right: 2px solid var(--apg-border-strong);\n  border-bottom: var(--apg-border);\n}\n\n.apg-frozen-rows-header {\n  left: 0;\n  background: var(--apg-header-bg);\n  border-right: var(--apg-border);\n  border-bottom: 2px solid var(--apg-border-strong);\n}\n\n.apg-frozen-cell-row {\n  position: absolute;\n  left: 0;\n  will-change: transform;\n\n  &.apg-row-alt {\n    background: var(--apg-cell-bg-alt);\n  }\n}\n\n// Styling hooks for pinned cells. Override these to distinguish frozen content\n// (`apg-frozen-cell` is on every pinned data cell; the region-specific classes\n// target just the columns band, rows band, or their corner).\n.apg-frozen-cell {\n  background: var(--apg-frozen-cell-bg);\n  font-weight: 500;\n\n  &.apg-cell-selected {\n    background: var(--apg-selected-bg);\n  }\n}\n\n.apg-frozen-corner-cell.apg-cell-selected {\n  background: var(--apg-selected-bg);\n}\n","// In-cell editors: text, data-map dropdown, radio, and the shared dropdown list.\n\n.apg-editor {\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: 10;\n  margin: 0;\n  border: 2px solid var(--apg-active-border);\n  border-radius: 2px;\n  padding: var(--apg-cell-padding);\n  font: inherit;\n  color: var(--apg-cell-fg);\n  background: var(--apg-cell-bg);\n  outline: none;\n  user-select: text;\n  -webkit-user-select: text;\n  will-change: transform;\n\n  &.apg-align-right {\n    text-align: right;\n  }\n\n  &.apg-align-center {\n    text-align: center;\n  }\n}\n\n.apg-editor-dropdown {\n  padding: 0;\n  border: none;\n  background: transparent;\n  overflow: visible;\n}\n\n.apg-dd-input {\n  box-sizing: border-box;\n  width: 100%;\n  height: 100%;\n  margin: 0;\n  border: 2px solid var(--apg-active-border);\n  border-radius: 2px;\n  padding: var(--apg-cell-padding);\n  padding-right: 22px;\n  font: inherit;\n  color: inherit;\n  background: var(--apg-cell-bg);\n  outline: none;\n}\n\n.apg-dd-arrow {\n  position: absolute;\n  right: 8px;\n  top: 50%;\n  width: 0;\n  height: 0;\n  margin-top: -2px;\n  border-left: 4px solid transparent;\n  border-right: 4px solid transparent;\n  border-top: 5px solid var(--apg-header-fg);\n  cursor: pointer;\n}\n\n// Shared dropdown list used by the in-cell dropdown editor (and reusable for\n// other editable dropdowns). Floats just below the input; flips up near the\n// bottom.\n.apg-dropdown {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  right: 0;\n  z-index: 20;\n  margin: 0;\n  padding: 4px 0;\n  max-height: 200px;\n  overflow-y: auto;\n  list-style: none;\n  background: var(--apg-cell-bg);\n  border: var(--apg-border);\n  border-radius: var(--apg-radius);\n  box-shadow: var(--apg-shadow-md);\n\n  &.apg-dropdown-up {\n    top: auto;\n    bottom: 100%;\n  }\n}\n\n.apg-dropdown-option {\n  padding: 5px 12px;\n  white-space: nowrap;\n  cursor: pointer;\n\n  &:hover,\n  &.apg-dropdown-active {\n    background: var(--apg-selected-bg);\n  }\n}\n\n// The radio editor floats below the cell as its own panel, so it overrides the\n// fixed cell height and box styling the base .apg-editor sets.\n.apg-editor-radio {\n  height: auto;\n  flex-direction: column;\n  align-items: flex-start;\n  gap: 2px;\n  max-height: 180px;\n  padding: 4px 6px;\n  overflow-y: auto;\n  border: 1px solid var(--apg-active-border);\n  border-radius: var(--apg-radius);\n  box-shadow: var(--apg-shadow-md);\n  cursor: default;\n}\n\n.apg-radio-option {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  white-space: nowrap;\n  cursor: pointer;\n\n  input {\n    margin: 0;\n  }\n}\n","// Row grouping: the grouping bar with its chips, and the in-body group-header\n// rows with their toggle, label, count badge, and per-column aggregates.\n\n// ---- Grouping bar -----------------------------------------------------------\n.apg-grouppanel {\n  position: absolute;\n  top: 0;\n  left: 0;\n  right: 0;\n  display: flex;\n  align-items: center;\n  gap: 8px;\n  padding: 0 12px;\n  background: var(--apg-panel-bg);\n  border-bottom: var(--apg-border);\n  overflow-x: auto;\n  overflow-y: hidden;\n  white-space: nowrap;\n  scrollbar-width: thin;\n\n  &::-webkit-scrollbar {\n    height: 6px;\n  }\n\n  &::-webkit-scrollbar-thumb {\n    background: var(--apg-scrollbar-thumb);\n    border-radius: 3px;\n  }\n\n  &.apg-grouppanel-over {\n    background: var(--apg-hover-bg);\n    box-shadow: inset 0 0 0 2px var(--apg-active-border);\n  }\n}\n\n.apg-grouppanel-icon {\n  color: var(--apg-header-fg);\n  opacity: 0.5;\n}\n\n.apg-group-placeholder {\n  color: var(--apg-fg-muted);\n  font-style: italic;\n  font-size: 0.92em;\n}\n\n.apg-group-chips {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n}\n\n// Chevron between chips reads as a hierarchy: A › B › C\n.apg-group-sep {\n  width: 12px;\n  height: 12px;\n  color: var(--apg-header-fg);\n  opacity: 0.4;\n}\n\n.apg-group-chip {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  height: 26px;\n  padding: 0 4px 0 6px;\n  background: var(--apg-cell-bg);\n  border: 1px solid var(--apg-border-color);\n  border-radius: var(--apg-radius);\n  color: var(--apg-cell-fg);\n  cursor: grab;\n  user-select: none;\n  box-shadow: var(--apg-shadow-sm);\n  transition:\n    border-color 0.12s ease,\n    box-shadow 0.12s ease;\n\n  &:hover {\n    border-color: var(--apg-active-border);\n    box-shadow: var(--apg-shadow-md);\n  }\n\n  &:active {\n    cursor: grabbing;\n  }\n}\n\n.apg-group-chip-grip {\n  width: 12px;\n  height: 14px;\n  color: var(--apg-header-fg);\n  opacity: 0.4;\n}\n\n.apg-group-chip-label {\n  font-weight: 500;\n  font-size: 0.9em;\n}\n\n.apg-group-chip-sort {\n  width: 12px;\n  height: 12px;\n  color: var(--apg-active-border);\n}\n\n.apg-group-chip-remove {\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  width: 18px;\n  height: 18px;\n  padding: 0;\n  border: none;\n  border-radius: var(--apg-radius-sm);\n  background: transparent;\n  color: var(--apg-header-fg);\n  opacity: 0.55;\n  cursor: pointer;\n\n  .apg-icon {\n    width: 12px;\n    height: 12px;\n  }\n\n  &:hover {\n    background: var(--apg-control-hover);\n    opacity: 1;\n  }\n}\n\n.apg-group-chip-marker {\n  width: 2px;\n  height: 20px;\n  align-self: center;\n  border-radius: 1px;\n  background: var(--apg-active-border);\n}\n\n// ---- In-body group-header rows ---------------------------------------------\n.apg-group-row {\n  background: var(--apg-group-bg);\n  border-bottom: var(--apg-border);\n  contain: none;\n\n  &:hover {\n    background: var(--apg-group-bg-hover);\n  }\n}\n\n.apg-group-label {\n  position: sticky;\n  left: 0;\n  z-index: 1;\n  display: inline-flex;\n  align-items: center;\n  gap: 8px;\n  height: 100%;\n  padding-right: 16px;\n  background: inherit;\n  white-space: nowrap;\n}\n\n.apg-group-toggle {\n  width: 16px;\n  height: 16px;\n  color: var(--apg-header-fg);\n  border-radius: var(--apg-radius-sm);\n  cursor: pointer;\n  transition: transform 0.15s ease;\n\n  &:hover {\n    background: var(--apg-control-hover);\n    color: var(--apg-cell-fg);\n  }\n\n  &.apg-group-toggle-open {\n    transform: rotate(90deg);\n  }\n}\n\n.apg-group-inner {\n  display: inline-flex;\n  align-items: baseline;\n  gap: 8px;\n}\n\n.apg-group-name {\n  font-weight: 600;\n  color: var(--apg-cell-fg);\n}\n\n.apg-group-count {\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  min-width: 20px;\n  height: 18px;\n  padding: 0 6px;\n  border-radius: 9px;\n  background: var(--apg-control-hover);\n  color: var(--apg-header-fg);\n  font-size: 0.78em;\n  font-weight: 600;\n}\n\n.apg-group-agg {\n  position: absolute;\n  top: 0;\n  height: 100%;\n  display: flex;\n  align-items: center;\n  padding: var(--apg-cell-padding);\n  font-weight: 600;\n  color: var(--apg-cell-fg);\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n","// Popups/overlays appended to <body>, outside the `.apg` scope, so the theme\n// variables aren't inherited. Re-emit the full token set on each overlay root so\n// they render correctly wherever they mount (and pick up dark mode via the\n// media query in the theme files).\n@use 'tokens' as *;\n\n.apg-drag-ghost,\n.apg-context-menu,\n.apg-filter-dialog {\n  @include tokens($light);\n}\n\n// Floating label that follows the cursor while a header is being dragged.\n.apg-drag-ghost {\n  position: fixed;\n  top: 0;\n  left: 0;\n  z-index: 1000;\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n  height: 26px;\n  padding: 0 10px;\n  background: var(--apg-cell-bg);\n  border: 1px solid var(--apg-border-color);\n  border-radius: var(--apg-radius);\n  box-shadow: var(--apg-shadow-lg);\n  color: var(--apg-cell-fg);\n  font: var(--apg-font);\n  font-weight: 500;\n  pointer-events: none;\n  opacity: 0.96;\n}\n\n.apg-drag-ghost-icon {\n  color: var(--apg-header-fg);\n  opacity: 0.7;\n}\n\n.apg-drag-ghost-active {\n  border-color: var(--apg-active-border);\n  background: var(--apg-hover-bg);\n\n  .apg-drag-ghost-icon {\n    color: var(--apg-active-border);\n    opacity: 1;\n  }\n}\n\n// Right-click menu (grouping bar actions).\n.apg-context-menu {\n  position: fixed;\n  z-index: 2000;\n  min-width: 184px;\n  padding: 5px;\n  background: var(--apg-cell-bg);\n  border: 1px solid var(--apg-border-color);\n  border-radius: 8px;\n  box-shadow: var(--apg-shadow-lg);\n  font: var(--apg-font);\n  color: var(--apg-cell-fg);\n}\n\n.apg-context-menu-item {\n  display: flex;\n  align-items: center;\n  gap: 10px;\n  width: 100%;\n  height: 30px;\n  padding: 0 10px;\n  border: none;\n  border-radius: 5px;\n  background: transparent;\n  color: inherit;\n  font: inherit;\n  text-align: left;\n  cursor: pointer;\n\n  &:hover:not(:disabled) {\n    background: var(--apg-hover-bg);\n  }\n\n  &:disabled {\n    opacity: 0.4;\n    cursor: default;\n  }\n}\n\n.apg-context-menu-icon {\n  width: 16px;\n  height: 16px;\n  flex: none;\n  color: var(--apg-header-fg);\n}\n\n.apg-context-menu-label {\n  flex: 1;\n}\n\n.apg-context-menu-sep {\n  height: 1px;\n  margin: 5px 8px;\n  background: var(--apg-border-color);\n}\n\n// Column filter popup.\n.apg-filter-dialog {\n  position: fixed;\n  z-index: 2000;\n  width: 240px;\n  padding: 10px;\n  background: var(--apg-cell-bg);\n  border: 1px solid var(--apg-border-color);\n  border-radius: 8px;\n  box-shadow: var(--apg-shadow-lg);\n  font: var(--apg-font);\n  color: var(--apg-cell-fg);\n}\n\n.apg-filter-sort {\n  display: flex;\n  flex-direction: column;\n  gap: 1px;\n  margin: -4px -4px 0;\n}\n\n.apg-filter-sort-btn {\n  display: flex;\n  align-items: center;\n  gap: 9px;\n  width: 100%;\n  height: 30px;\n  padding: 0 8px;\n  border: none;\n  border-radius: 5px;\n  background: transparent;\n  color: var(--apg-cell-fg);\n  font: inherit;\n  text-align: left;\n  cursor: pointer;\n\n  .apg-icon {\n    width: 14px;\n    height: 14px;\n    flex: none;\n    color: var(--apg-header-fg);\n  }\n\n  &:hover {\n    background: var(--apg-hover-bg);\n  }\n}\n\n.apg-filter-sort-active {\n  color: var(--apg-active-border);\n  font-weight: 600;\n\n  .apg-icon {\n    color: var(--apg-active-border);\n  }\n}\n\n.apg-filter-section {\n  display: flex;\n  gap: 6px;\n  margin-bottom: 8px;\n}\n\n.apg-filter-op {\n  flex: none;\n  width: 96px;\n}\n\n.apg-filter-value {\n  flex: 1;\n  min-width: 0;\n}\n\n.apg-filter-op,\n.apg-filter-value,\n.apg-filter-search {\n  height: 28px;\n  padding: 0 8px;\n  border: 1px solid var(--apg-border-color);\n  border-radius: 5px;\n  font: inherit;\n  color: inherit;\n  background: var(--apg-cell-bg);\n  box-sizing: border-box;\n\n  &:focus {\n    outline: none;\n    border-color: var(--apg-active-border);\n  }\n}\n\n.apg-filter-sep {\n  height: 1px;\n  margin: 8px -10px;\n  background: var(--apg-border-color);\n}\n\n.apg-filter-search {\n  width: 100%;\n  margin-bottom: 6px;\n}\n\n.apg-filter-selectall {\n  display: flex;\n  align-items: center;\n  gap: 8px;\n  padding: 4px 2px;\n  font-weight: 600;\n  cursor: pointer;\n}\n\n.apg-filter-list {\n  max-height: 180px;\n  overflow-y: auto;\n  margin: 2px 0 8px;\n  border: 1px solid var(--apg-border-color);\n  border-radius: 5px;\n}\n\n.apg-filter-item {\n  display: flex;\n  align-items: center;\n  gap: 8px;\n  padding: 4px 8px;\n  white-space: nowrap;\n  cursor: pointer;\n\n  &:hover {\n    background: var(--apg-hover-bg);\n  }\n\n  span {\n    overflow: hidden;\n    text-overflow: ellipsis;\n  }\n}\n\n.apg-filter-footer {\n  display: flex;\n  justify-content: flex-end;\n  gap: 8px;\n}\n\n.apg-filter-clear,\n.apg-filter-apply {\n  height: 30px;\n  padding: 0 14px;\n  border-radius: var(--apg-radius);\n  font: inherit;\n  cursor: pointer;\n}\n\n.apg-filter-clear {\n  border: 1px solid var(--apg-border-color);\n  background: var(--apg-cell-bg);\n  color: var(--apg-cell-fg);\n\n  &:hover {\n    border-color: var(--apg-active-border);\n  }\n}\n\n.apg-filter-apply {\n  border: 1px solid var(--apg-active-border);\n  background: var(--apg-active-border);\n  color: var(--apg-accent-contrast);\n\n  &:hover {\n    filter: brightness(1.05);\n  }\n}\n","// Dark theme. Opt in explicitly with the `apg-theme-dark` class — either on the\n// grid host / overlay root itself, or on any ancestor (so a page wrapper can\n// theme every grid inside it). Use `apg-theme-auto` to follow the OS via\n// prefers-color-scheme. Only token VALUES change — every rule in the other\n// partials reads the same custom properties, so nothing else needs a dark copy.\n@use 'tokens' as *;\n\n// Roots that carry tokens: the grid host and the body-mounted overlays.\n$roots: '.apg, .apg-drag-ghost, .apg-context-menu, .apg-filter-dialog';\n\n// On the root itself…\n#{$roots} {\n  &.apg-theme-dark {\n    @include tokens($dark);\n  }\n}\n\n// …or inherited from an ancestor container.\n.apg-theme-dark {\n  .apg,\n  .apg-drag-ghost,\n  .apg-context-menu,\n  .apg-filter-dialog {\n    @include tokens($dark);\n  }\n}\n\n@media (prefers-color-scheme: dark) {\n  #{$roots} {\n    &.apg-theme-auto {\n      @include tokens($dark);\n    }\n  }\n\n  .apg-theme-auto {\n    .apg,\n    .apg-drag-ghost,\n    .apg-context-menu,\n    .apg-filter-dialog {\n      @include tokens($dark);\n    }\n  }\n}\n"],"names":[],"sourceRoot":""}