{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "table-filter",
  "title": "Table Filter",
  "description": "A CRM table filters and selects rows, then a bulk-action bar slides up.",
  "dependencies": ["remotion", "@remotion/google-fonts"],
  "registryDependencies": ["@remocn/gsh"],
  "files": [
    {
      "path": "registry/remocn/table-filter/index.tsx",
      "content": "\"use client\";\n\nimport { loadFont } from \"@remotion/google-fonts/Onest\";\nimport type React from \"react\";\nimport {\n  AbsoluteFill,\n  Easing,\n  interpolate,\n  spring,\n  useCurrentFrame,\n  useVideoConfig,\n} from \"remotion\";\nimport type { GradientParams } from \"@/lib/remocn/gsh/gradient-engine\";\nimport { GshGround } from \"@/lib/remocn/gsh/gsh-ground\";\nimport type { GshPresetId } from \"@/lib/remocn/gsh/presets\";\n\nconst { fontFamily } = loadFont(\"normal\", {\n  weights: [\"300\", \"400\"],\n  subsets: [\"latin\"],\n});\n\nexport interface TableRecord {\n  company: string;\n  domain: string;\n  stage: string;\n  /** Annual recurring revenue in dollars, used for sorting. */\n  arr: number;\n  owner: string;\n  lastInteraction: string;\n  /** Logo tile color. */\n  color: string;\n}\n\nexport interface TableFilterProps {\n  rows?: TableRecord[];\n  title?: string;\n  /** Attribute shown in the filter chip. */\n  filterAttribute?: string;\n  /** Stage value rows are filtered by. */\n  filterValue?: string;\n  /** How many of the remaining rows get selected for the bulk action. */\n  selectCount?: number;\n  bulkAction?: string;\n  workspace?: string;\n  theme?: \"light\" | \"dark\";\n  accent?: string;\n  speed?: number;\n  ground?: GshPresetId;\n  groundParams?: Partial<GradientParams>;\n}\n\nconst DEFAULT_ROWS: TableRecord[] = [\n  {\n    company: \"Kitebase\",\n    domain: \"kitebase.io\",\n    stage: \"Negotiation\",\n    arr: 1_400_000,\n    owner: \"Maya Chen\",\n    lastInteraction: \"2 hours ago\",\n    color: \"#3B82F6\",\n  },\n  {\n    company: \"Lumen\",\n    domain: \"lumen.app\",\n    stage: \"Closed-won\",\n    arr: 320_000,\n    owner: \"Leo Park\",\n    lastInteraction: \"Yesterday\",\n    color: \"#F59E0B\",\n  },\n  {\n    company: \"Fernway\",\n    domain: \"fernway.com\",\n    stage: \"Qualified\",\n    arr: 860_000,\n    owner: \"Priya Raman\",\n    lastInteraction: \"3 days ago\",\n    color: \"#10B981\",\n  },\n  {\n    company: \"Quarry\",\n    domain: \"quarry.dev\",\n    stage: \"Closed-won\",\n    arr: 2_100_000,\n    owner: \"Maya Chen\",\n    lastInteraction: \"4 hours ago\",\n    color: \"#18181B\",\n  },\n  {\n    company: \"Orbitly\",\n    domain: \"orbitly.co\",\n    stage: \"Lead\",\n    arr: 95_000,\n    owner: \"Sam Ortiz\",\n    lastInteraction: \"1 week ago\",\n    color: \"#8B5CF6\",\n  },\n  {\n    company: \"Halcyon\",\n    domain: \"halcyon.ai\",\n    stage: \"Negotiation\",\n    arr: 1_100_000,\n    owner: \"Leo Park\",\n    lastInteraction: \"Yesterday\",\n    color: \"#0EA5E9\",\n  },\n  {\n    company: \"Tessel\",\n    domain: \"tessel.so\",\n    stage: \"Closed-won\",\n    arr: 640_000,\n    owner: \"Priya Raman\",\n    lastInteraction: \"2 days ago\",\n    color: \"#EF4444\",\n  },\n  {\n    company: \"Brightloom\",\n    domain: \"brightloom.com\",\n    stage: \"Closed-lost\",\n    arr: 210_000,\n    owner: \"Sam Ortiz\",\n    lastInteraction: \"3 weeks ago\",\n    color: \"#EC4899\",\n  },\n  {\n    company: \"Cobalt Labs\",\n    domain: \"cobaltlabs.com\",\n    stage: \"Closed-won\",\n    arr: 1_200_000,\n    owner: \"Leo Park\",\n    lastInteraction: \"6 hours ago\",\n    color: \"#6366F1\",\n  },\n];\n\nconst STAGE_COLORS: Record<string, string> = {\n  Lead: \"#9A9AA2\",\n  Qualified: \"#4C7FD8\",\n  Negotiation: \"#D69A3A\",\n  \"Closed-won\": \"#3E9E64\",\n  \"Closed-lost\": \"#C9584A\",\n};\n\nconst WIN = { x: 150, y: 76, w: 980, h: 572 };\nconst SIDEBAR = 180;\nconst MX = WIN.x + SIDEBAR;\nconst ROW_H = 38;\nconst TOOL_Y = WIN.y + 88;\nconst HEAD_Y = TOOL_Y + 40;\nconst BODY_Y = HEAD_Y + 34;\nconst COLS = [\n  { key: \"check\", label: \"\", w: 40 },\n  { key: \"company\", label: \"Company\", w: 200 },\n  { key: \"stage\", label: \"Stage\", w: 150 },\n  { key: \"arr\", label: \"ARR\", w: 100 },\n  { key: \"owner\", label: \"Owner\", w: 160 },\n  { key: \"last\", label: \"Last activity\", w: 150 },\n];\nconst colLeft = (i: number) => COLS.slice(0, i).reduce((s, c) => s + c.w, 0);\nconst SORT_BTN = { x: MX + 12, w: 200 };\nconst FILTER_BTN = { x: SORT_BTN.x + SORT_BTN.w + 8, w: 76 };\nconst POP = { x: FILTER_BTN.x - 6, y: TOOL_Y + 38, w: 236 };\nconst BAR = { w: 500, h: 46, y: 560 };\n\nconst MOVE = Easing.bezier(0.65, 0, 0.35, 1);\nconst easeOut = Easing.bezier(0.32, 0.72, 0, 1);\nconst EXIT = Easing.bezier(0.55, 0, 1, 0.45);\nconst CAMERA = Easing.bezier(0.87, 0, 0.13, 1);\nconst HEAVY = { mass: 1, damping: 26, stiffness: 120 };\nconst CARD = { mass: 0.8, damping: 18, stiffness: 160 };\nconst CHIP = { mass: 0.5, damping: 12, stiffness: 200 };\nconst MORPH = { damping: 200 };\nconst tween = (f: number, a: number, b: number, easing = easeOut) =>\n  interpolate(f, [a, b], [0, 1], {\n    extrapolateLeft: \"clamp\",\n    extrapolateRight: \"clamp\",\n    easing,\n  });\nconst clamp = (v: number, lo: number, hi: number) =>\n  Math.min(hi, Math.max(lo, v));\nconst lerp = (a: number, b: number, t: number) => a + (b - a) * t;\nconst CL = { extrapolateLeft: \"clamp\", extrapolateRight: \"clamp\" } as const;\n\nfunction withAlpha(color: string, alpha: number) {\n  const hex = color.replace(\"#\", \"\");\n  const full = hex.length === 3 ? hex.replace(/(.)/g, \"$1$1\") : hex;\n  if (!/^[0-9a-fA-F]{6}$/.test(full)) return color;\n  const n = Number.parseInt(full, 16);\n  return `rgba(${(n >> 16) & 255}, ${(n >> 8) & 255}, ${n & 255}, ${alpha})`;\n}\n\nconst fmtArr = (n: number) =>\n  n >= 1_000_000\n    ? `$${(n / 1_000_000).toFixed(1).replace(/\\.0$/, \"\")}M`\n    : `$${Math.round(n / 1000)}K`;\n\ninterface Pt {\n  x: number;\n  y: number;\n}\ninterface Key extends Pt {\n  t: number;\n}\n\nfunction pathAt(keys: Key[], f: number): Pt {\n  if (f <= keys[0].t) return keys[0];\n  for (let i = 1; i < keys.length; i++) {\n    const a = keys[i - 1];\n    const b = keys[i];\n    if (f <= b.t) {\n      const p = MOVE(clamp((f - a.t) / Math.max(1, b.t - a.t), 0, 1));\n      const dx = b.x - a.x;\n      const dy = b.y - a.y;\n      const d = Math.hypot(dx, dy) || 1;\n      const arc = Math.sin(p * Math.PI) * Math.min(26, d * 0.1);\n      return {\n        x: lerp(a.x, b.x, p) + (-dy / d) * arc,\n        y: lerp(a.y, b.y, p) + (dx / d) * arc,\n      };\n    }\n  }\n  return keys[keys.length - 1];\n}\n\nfunction Cursor({ x, y, press }: { x: number; y: number; press: number }) {\n  return (\n    <svg\n      width={22}\n      height={26}\n      viewBox=\"0 0 20 24\"\n      style={{\n        position: \"absolute\",\n        left: x - 2,\n        top: y - 2,\n        transformOrigin: \"2px 2px\",\n        transform: `scale(${1 - 0.04 * press})`,\n        filter: \"drop-shadow(0 2px 3px rgba(0,0,0,0.28))\",\n        overflow: \"visible\",\n      }}\n    >\n      <path\n        d=\"M2 2 L2 19.5 L6.6 15.4 L9.8 22.4 L12.9 21 L9.8 14.2 L16 14.2 Z\"\n        fill=\"#FFFFFF\"\n        stroke=\"#16171A\"\n        strokeWidth={1.1}\n        strokeLinejoin=\"round\"\n      />\n    </svg>\n  );\n}\n\ninterface Pal {\n  stage: string;\n  win: string;\n  panel: string;\n  border: string;\n  line: string;\n  text: string;\n  muted: string;\n  faint: string;\n  hover: string;\n  pop: string;\n  dark: boolean;\n}\n\nfunction palette(theme: \"light\" | \"dark\"): Pal {\n  return theme === \"dark\"\n    ? {\n        stage: \"rgba(3,4,8,0.3)\",\n        win: \"#111113\",\n        panel: \"#141416\",\n        border: \"rgba(255,255,255,0.09)\",\n        line: \"rgba(255,255,255,0.065)\",\n        text: \"#EDEDEF\",\n        muted: \"#A4A5AB\",\n        faint: \"#7C7D84\",\n        hover: \"rgba(255,255,255,0.04)\",\n        pop: \"#1F1F23\",\n        dark: true,\n      }\n    : {\n        stage: \"rgba(244,243,240,0.28)\",\n        win: \"#FAFAFA\",\n        panel: \"#FFFFFF\",\n        border: \"rgba(17,19,24,0.1)\",\n        line: \"rgba(17,19,24,0.07)\",\n        text: \"#18181B\",\n        muted: \"#5F6168\",\n        faint: \"#8E9096\",\n        hover: \"rgba(17,19,24,0.025)\",\n        pop: \"#FFFFFF\",\n        dark: false,\n      };\n}\n\nconst ICONS = {\n  sort: \"M5 3v10M2.75 10.75 5 13l2.25-2.25M11 13V3M8.75 5.25 11 3l2.25 2.25\",\n  filter: \"M2.5 4.5h11M4.5 8h7M6.5 11.5h3\",\n  chevDown: \"M4.75 6.5 8 9.75l3.25-3.25\",\n  x: \"M4.75 4.75l6.5 6.5M11.25 4.75l-6.5 6.5\",\n  arrowDown: \"M8 3.25v9.5M4.5 9.25 8 12.75l3.5-3.5\",\n  send: \"M13.5 2.5 7 9M13.5 2.5 9.4 13.5 7 9 2.5 6.6z\",\n  bell: \"M4.25 11V7.25a3.75 3.75 0 0 1 7.5 0V11l1 1.25h-9.5zM6.6 13.75a1.5 1.5 0 0 0 2.8 0\",\n  task: \"M4.5 2.75h7a1.75 1.75 0 0 1 1.75 1.75v7a1.75 1.75 0 0 1-1.75 1.75h-7a1.75 1.75 0 0 1-1.75-1.75v-7A1.75 1.75 0 0 1 4.5 2.75zM5.75 8.1l1.6 1.6 3-3.2\",\n  note: \"M4.25 2.5h5L12 5.25v8.25H4.25zM9 2.5v3h3M6.25 8.5h3.5M6.25 11h2.5\",\n  mail: \"M3.25 3.75h9.5a.75.75 0 0 1 .75.75v7a.75.75 0 0 1-.75.75h-9.5a.75.75 0 0 1-.75-.75v-7a.75.75 0 0 1 .75-.75zM2.75 4.5 8 8.75l5.25-4.25\",\n  chart: \"M3 2.75v10.5h10.25M6 10.5V8.25M8.75 10.5v-5M11.5 10.5V7\",\n  zap: \"M8.75 2.25 3.75 9H8l-.75 4.75L12.25 7H8z\",\n  list: \"M6 4.5h7.25M6 8h7.25M6 11.5h7.25M2.9 4.5h.01M2.9 8h.01M2.9 11.5h.01\",\n  search:\n    \"M7.25 11.75a4.5 4.5 0 1 0 0-9 4.5 4.5 0 0 0 0 9zM13.25 13.25l-2.8-2.8\",\n  sliders:\n    \"M2.75 5h5.5M11.25 5h2M2.75 11h2M7.75 11h5.5M9.75 3.4v3.2M6.25 9.4v3.2\",\n  download: \"M8 2.75v7.5M4.75 7 8 10.25 11.25 7M3 13.25h10\",\n  trash: \"M3 4.5h10M6.25 4.5V3h3.5v1.5M4.5 4.5l.6 8.75h5.8l.6-8.75\",\n  plus: \"M8 3.5v9M3.5 8h9\",\n  building:\n    \"M3 13.25h10M4.25 13.25V3h5v10.25M9.25 6h2.5v7.25M6.25 5.5h1M6.25 8h1M6.25 10.5h1\",\n  user: \"M8 7.75a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5zM3.5 13.25c.6-2.2 2.4-3.4 4.5-3.4s3.9 1.2 4.5 3.4\",\n  deal: \"M2.75 5.25h10.5v7.5H2.75zM5.75 5.25v-1.5h4.5v1.5M2.75 8.75h10.5\",\n  grid: \"M3 3h4v4H3zM9 3h4v4H9zM3 9h4v4H3zM9 9h4v4H9z\",\n} as const;\ntype IconName = keyof typeof ICONS;\n\nfunction Icon({\n  name,\n  color,\n  size = 14,\n  width = 1.4,\n}: {\n  name: IconName;\n  color: string;\n  size?: number;\n  width?: number;\n}) {\n  return (\n    <svg\n      width={size}\n      height={size}\n      viewBox=\"0 0 16 16\"\n      style={{ flexShrink: 0, display: \"block\" }}\n    >\n      <path\n        d={ICONS[name]}\n        fill=\"none\"\n        stroke={color}\n        strokeWidth={name === \"list\" ? 1.6 : width}\n        strokeLinecap=\"round\"\n        strokeLinejoin=\"round\"\n      />\n    </svg>\n  );\n}\n\nfunction Checkbox({ p, accent, pal }: { p: number; accent: string; pal: Pal }) {\n  const c = clamp(p, 0, 1.3);\n  return (\n    <div\n      style={{\n        width: 14,\n        height: 14,\n        borderRadius: 4,\n        border: `1.2px solid ${c > 0.3 ? accent : pal.dark ? \"rgba(255,255,255,0.22)\" : \"rgba(17,19,24,0.2)\"}`,\n        background: c > 0 ? withAlpha(accent, clamp(c, 0, 1)) : \"transparent\",\n        boxSizing: \"border-box\",\n        display: \"flex\",\n        alignItems: \"center\",\n        justifyContent: \"center\",\n        transform: `scale(${1 + 0.08 * Math.sin(clamp(c, 0, 1) * Math.PI)})`,\n      }}\n    >\n      {c > 0 && (\n        <svg width={10} height={10} viewBox=\"0 0 10 10\">\n          <path\n            d=\"M2 5.2 L4.1 7.2 L8 3\"\n            fill=\"none\"\n            stroke=\"#fff\"\n            strokeWidth={1.6}\n            strokeLinecap=\"round\"\n            strokeLinejoin=\"round\"\n            pathLength={1}\n            strokeDasharray=\"1 1\"\n            strokeDashoffset={1 - clamp(c, 0, 1)}\n          />\n        </svg>\n      )}\n    </div>\n  );\n}\n\nfunction Avatar({\n  name,\n  pal,\n  size = 20,\n}: {\n  name: string;\n  pal: Pal;\n  size?: number;\n}) {\n  const initials = name\n    .split(\" \")\n    .map((s) => s[0])\n    .join(\"\")\n    .slice(0, 2);\n  return (\n    <div\n      style={{\n        width: size,\n        height: size,\n        borderRadius: 999,\n        background: pal.dark ? \"#2A2A2F\" : \"#ECEBE7\",\n        color: pal.muted,\n        fontSize: size * 0.44,\n        fontWeight: 400,\n        display: \"flex\",\n        alignItems: \"center\",\n        justifyContent: \"center\",\n        flexShrink: 0,\n      }}\n    >\n      {initials}\n    </div>\n  );\n}\n\nfunction StagePill({ stage, pal }: { stage: string; pal: Pal }) {\n  return (\n    <div\n      style={{\n        display: \"inline-flex\",\n        alignItems: \"center\",\n        gap: 6,\n        height: 24,\n        padding: \"0 9px\",\n        borderRadius: 6,\n        boxShadow: `inset 0 0 0 1px ${pal.border}`,\n        fontSize: 13.5,\n        color: pal.text,\n      }}\n    >\n      <div\n        style={{\n          width: 7,\n          height: 7,\n          borderRadius: 999,\n          background: STAGE_COLORS[stage] ?? pal.faint,\n        }}\n      />\n      {stage}\n    </div>\n  );\n}\n\nfunction Row({\n  r,\n  pal,\n  accent,\n  checked,\n  sel,\n}: {\n  r: TableRecord;\n  pal: Pal;\n  accent: string;\n  checked: number;\n  sel: number;\n}) {\n  const cell = (\n    i: number,\n    children: React.ReactNode,\n    style: React.CSSProperties = {},\n  ) => (\n    <div\n      style={{\n        position: \"absolute\",\n        left: colLeft(i),\n        width: COLS[i].w,\n        top: 0,\n        height: ROW_H,\n        display: \"flex\",\n        alignItems: \"center\",\n        padding: \"0 10px\",\n        boxSizing: \"border-box\",\n        fontSize: 14.5,\n        color: pal.text,\n        overflow: \"hidden\",\n        whiteSpace: \"nowrap\",\n        ...style,\n      }}\n    >\n      {children}\n    </div>\n  );\n  return (\n    <div\n      style={{\n        position: \"absolute\",\n        inset: 0,\n        background:\n          sel > 0\n            ? withAlpha(accent, (pal.dark ? 0.12 : 0.06) * sel)\n            : pal.panel,\n      }}\n    >\n      {cell(0, <Checkbox p={checked} accent={accent} pal={pal} />, {\n        justifyContent: \"center\",\n        padding: 0,\n      })}\n      {cell(\n        1,\n        <>\n          <div\n            style={{\n              width: 22,\n              height: 22,\n              borderRadius: 6,\n              background: withAlpha(r.color, pal.dark ? 0.22 : 0.12),\n              color: pal.dark ? \"#EDEDEF\" : r.color,\n              fontSize: 12,\n              fontWeight: 400,\n              display: \"flex\",\n              alignItems: \"center\",\n              justifyContent: \"center\",\n              marginRight: 10,\n              flexShrink: 0,\n            }}\n          >\n            {r.company[0]}\n          </div>\n          <span style={{ fontWeight: 400 }}>{r.company}</span>\n        </>,\n      )}\n      {cell(2, <StagePill stage={r.stage} pal={pal} />)}\n      {cell(\n        3,\n        <span style={{ fontVariantNumeric: \"tabular-nums\" }}>\n          {fmtArr(r.arr)}\n        </span>,\n        { justifyContent: \"flex-end\" },\n      )}\n      {cell(\n        4,\n        <>\n          <Avatar name={r.owner} pal={pal} />\n          <span style={{ marginLeft: 8 }}>{r.owner}</span>\n        </>,\n      )}\n      {cell(5, <span style={{ color: pal.muted }}>{r.lastInteraction}</span>)}\n      <div\n        style={{\n          position: \"absolute\",\n          left: 0,\n          right: 0,\n          bottom: 0,\n          height: 1,\n          background: pal.line,\n        }}\n      />\n    </div>\n  );\n}\n\nconst NAV: [string, IconName][] = [\n  [\"Notifications\", \"bell\"],\n  [\"Tasks\", \"task\"],\n  [\"Emails\", \"mail\"],\n  [\"Reports\", \"chart\"],\n];\nconst RECORDS: [string, IconName][] = [\n  [\"Companies\", \"building\"],\n  [\"People\", \"user\"],\n  [\"Deals\", \"deal\"],\n  [\"Workspaces\", \"grid\"],\n];\n\nfunction Sidebar({\n  pal,\n  workspace,\n  title,\n}: {\n  pal: Pal;\n  workspace: string;\n  title: string;\n}) {\n  const icon = (name: IconName) => <Icon name={name} color={pal.muted} />;\n  const row = (\n    label: string,\n    lead: React.ReactNode,\n    active = false,\n    trail?: React.ReactNode,\n  ) => (\n    <div\n      key={label}\n      style={{\n        height: 30,\n        display: \"flex\",\n        alignItems: \"center\",\n        gap: 9,\n        padding: \"0 8px\",\n        borderRadius: 6,\n        fontSize: 14,\n        color: active ? pal.text : pal.muted,\n        fontWeight: 400,\n        background: active\n          ? pal.dark\n            ? \"rgba(255,255,255,0.06)\"\n            : \"rgba(17,19,24,0.05)\"\n          : \"transparent\",\n      }}\n    >\n      {lead}\n      {label}\n      <div style={{ flex: 1 }} />\n      {trail}\n    </div>\n  );\n  return (\n    <div\n      style={{\n        width: SIDEBAR,\n        padding: \"12px 10px\",\n        boxSizing: \"border-box\",\n        borderRight: `1px solid ${pal.border}`,\n        height: \"100%\",\n      }}\n    >\n      <div\n        style={{\n          display: \"flex\",\n          alignItems: \"center\",\n          gap: 8,\n          height: 30,\n          padding: \"0 6px\",\n        }}\n      >\n        <div\n          style={{\n            width: 20,\n            height: 20,\n            borderRadius: 5,\n            background: pal.dark ? \"#ECECEE\" : \"#1C1D1F\",\n            color: pal.dark ? \"#121214\" : \"#fff\",\n            fontSize: 12,\n            fontWeight: 400,\n            display: \"flex\",\n            alignItems: \"center\",\n            justifyContent: \"center\",\n          }}\n        >\n          {workspace[0]}\n        </div>\n        <span style={{ fontSize: 14.5, fontWeight: 400, color: pal.text }}>\n          {workspace}\n        </span>\n        <Icon name=\"chevDown\" color={pal.faint} size={12} />\n      </div>\n      <div\n        style={{\n          marginTop: 8,\n          height: 30,\n          display: \"flex\",\n          alignItems: \"center\",\n          gap: 8,\n          padding: \"0 8px\",\n          borderRadius: 7,\n          boxShadow: `inset 0 0 0 1px ${pal.border}`,\n          background: pal.panel,\n          fontSize: 14,\n          color: pal.muted,\n        }}\n      >\n        <Icon name=\"search\" color={pal.muted} />\n        Search\n        <div style={{ flex: 1 }} />\n        <span\n          style={{\n            fontSize: 11,\n            lineHeight: \"16px\",\n            color: pal.muted,\n            boxShadow: `inset 0 0 0 1px ${pal.border}`,\n            borderRadius: 4,\n            padding: \"0 4px\",\n          }}\n        >\n          ⌘K\n        </span>\n      </div>\n      <div style={{ marginTop: 10 }}>\n        {NAV.map(([l, ic]) => row(l, icon(ic)))}\n      </div>\n      <div\n        style={{\n          fontSize: 12,\n          color: pal.muted,\n          padding: \"14px 8px 4px\",\n          fontWeight: 400,\n        }}\n      >\n        Records\n      </div>\n      {RECORDS.map(([l, ic]) =>\n        row(\n          l,\n          <Icon name={ic} color={l === title ? pal.text : pal.muted} />,\n          l === title,\n        ),\n      )}\n      <div\n        style={{\n          fontSize: 12,\n          color: pal.muted,\n          padding: \"14px 8px 4px\",\n          fontWeight: 400,\n        }}\n      >\n        Lists\n      </div>\n      {row(\"Enterprise\", icon(\"list\"))}\n      {row(\"Q4 expansion\", icon(\"list\"))}\n    </div>\n  );\n}\n\nexport function TableFilter({\n  rows = DEFAULT_ROWS,\n  title = \"Companies\",\n  filterAttribute = \"Stage\",\n  filterValue = \"Closed-won\",\n  selectCount = 3,\n  bulkAction = \"Add to sequence\",\n  workspace = \"remocn\",\n  theme = \"light\",\n  accent = \"#3B5BFD\",\n  speed = 1,\n  ground,\n  groundParams,\n}: TableFilterProps) {\n  const frame = useCurrentFrame() * speed;\n  const { width: W, height: H, fps } = useVideoConfig();\n  const u = Math.min(W / 1280, H / 720);\n  const pal = palette(theme);\n  const sp = (\n    f: number,\n    config: { mass?: number; damping: number; stiffness?: number } = CARD,\n    durationInFrames?: number,\n  ) => spring({ frame: f, fps, config, durationInFrames });\n\n  const matchIdx = rows\n    .map((r, i) => (r.stage === filterValue ? i : -1))\n    .filter((i) => i >= 0);\n  const sorted = [...matchIdx].sort((a, b) => rows[b].arr - rows[a].arr);\n  const nSel = Math.min(selectCount, sorted.length);\n  const stages = Object.keys(STAGE_COLORS).filter(\n    (s) => rows.some((r) => r.stage === s) || s === filterValue,\n  );\n  const optIdx = Math.max(0, stages.indexOf(filterValue));\n\n  const T = {\n    filterClick: 48,\n    optionClick: 72,\n    collapse: 78,\n    sortClick: 114,\n    flip: 117,\n    check: [144, 151, 158].slice(0, nSel),\n    actionHover: 180,\n  };\n  const FLIP_LEN = 11;\n  const barStart = T.check[0] ?? 999;\n\n  const filterPt = { x: FILTER_BTN.x + 42, y: TOOL_Y + 21 };\n  const optPt = { x: POP.x + 78, y: POP.y + 8 + 36 + 36 + optIdx * 30 + 16 };\n  const arrPt = { x: MX + colLeft(4) + 62, y: HEAD_Y + 19 };\n  const checkPt = (k: number) => ({ x: MX + 21, y: BODY_Y + k * ROW_H + 19 });\n  const barX = MX + (WIN.w - SIDEBAR) / 2 - BAR.w / 2;\n  const actionPt = { x: barX + 148 + 84, y: BAR.y + BAR.h / 2 + 3 };\n  const keys: Key[] = [\n    { t: 22, x: 1010, y: 500 },\n    { t: T.filterClick - 4, ...filterPt },\n    { t: T.filterClick + 6, ...filterPt },\n    { t: T.optionClick - 4, ...optPt },\n    { t: T.optionClick + 6, ...optPt },\n    { t: T.sortClick - 4, ...arrPt },\n    { t: T.sortClick + 10, ...arrPt },\n  ];\n  T.check.forEach((t, k) => {\n    keys.push({ t: t - 3, ...checkPt(k) }, { t: t + 2, ...checkPt(k) });\n  });\n  keys.push({ t: T.actionHover, ...actionPt });\n  const cur = pathAt(keys, frame);\n  const clicks = [\n    T.filterClick,\n    T.optionClick,\n    T.sortClick,\n    ...T.check,\n    T.actionHover + 8,\n  ];\n  const press = clamp(\n    Math.max(\n      0,\n      ...clicks.map(\n        (c) => sp(frame - (c - 2), CHIP) - sp(frame - (c + 2), CHIP),\n      ),\n    ),\n    0,\n    1,\n  );\n  const cursorIn = interpolate(frame, [20, 28], [0, 1], CL);\n\n  const enter = sp(frame, HEAVY);\n  const popOpen = sp(frame - (T.filterClick + 1), CARD);\n  const popClose = tween(frame, T.optionClick + 2, T.optionClick + 6, EXIT);\n  const pop = popOpen * (1 - popClose);\n  const chip = sp(frame - (T.optionClick + 4), CHIP);\n  const sortOn = frame >= T.sortClick + 1;\n  const sortArrow = tween(frame, T.sortClick + 1, T.sortClick + 7);\n  const filtered = frame >= T.collapse;\n  const countIn = tween(frame, T.collapse, T.collapse + 6);\n  const countVal = filtered ? matchIdx.length : rows.length;\n  const sumArr = (idx: number[]) =>\n    fmtArr(idx.reduce((s, i) => s + rows[i].arr, 0));\n  const arrSum = filtered ? sumArr(matchIdx) : sumArr(rows.map((_, i) => i));\n\n  let nonMatch = 0;\n  const fadeOut = rows.map((_, i) => {\n    if (matchIdx.includes(i)) return 0;\n    const at = T.collapse + nonMatch++ * 0.6;\n    return tween(frame, at, at + 4);\n  });\n  const collapse = rows.map((_, i) =>\n    matchIdx.includes(i) ? 0 : sp(frame - (T.collapse + 2), MORPH, 9),\n  );\n  const ys: number[] = [];\n  let acc = 0;\n  rows.forEach((_, i) => {\n    ys.push(acc);\n    acc += ROW_H * (1 - collapse[i]);\n  });\n  const flipT = sp(frame - T.flip, MORPH, FLIP_LEN + 3);\n  const flipArc = Math.sin(flipT * Math.PI);\n  const rowY = rows.map((_, i) => {\n    const s = sorted.indexOf(i);\n    return s < 0 ? ys[i] : lerp(ys[i], s * ROW_H, flipT);\n  });\n  const climb = rows.map((_, i) => {\n    const s = sorted.indexOf(i);\n    return s < 0 ? 0 : Math.sign(matchIdx.indexOf(i) - s);\n  });\n  const checks = rows.map((_, i) => {\n    const s = sorted.indexOf(i);\n    if (s < 0 || s >= nSel) return 0;\n    return tween(frame, T.check[s], T.check[s] + 6);\n  });\n  const selected = T.check.filter((t) => frame >= t + 1).length;\n  const bar = sp(frame - (barStart + 2), CARD);\n  const selIn = tween(\n    frame,\n    (T.check[selected - 1] ?? 0) + 1,\n    (T.check[selected - 1] ?? 0) + 6,\n  );\n  const actionHover = tween(frame, T.actionHover - 5, T.actionHover);\n  const tableBottom = BODY_Y + acc;\n  const sortW = lerp(SORT_BTN.w, 134, sortArrow);\n  const filterX = SORT_BTN.x + sortW + 8;\n\n  const camT = interpolate(\n    frame,\n    [T.collapse, T.check[0] ?? T.collapse + 60],\n    [0, 1],\n    { ...CL, easing: CAMERA },\n  );\n\n  const btn = (x: number, w: number, label: React.ReactNode, active = 0) => (\n    <div\n      style={{\n        position: \"absolute\",\n        left: x,\n        top: TOOL_Y + 6,\n        width: w,\n        height: 28,\n        borderRadius: 7,\n        boxShadow: `inset 0 0 0 1px ${active > 0 ? withAlpha(accent, 0.5 * active) : pal.border}`,\n        background:\n          active > 0\n            ? withAlpha(accent, (pal.dark ? 0.12 : 0.06) * active)\n            : pal.panel,\n        display: \"flex\",\n        alignItems: \"center\",\n        gap: 6,\n        padding: \"0 10px\",\n        boxSizing: \"border-box\",\n        fontSize: 14,\n        color: pal.muted,\n        whiteSpace: \"nowrap\",\n        overflow: \"hidden\",\n      }}\n    >\n      {label}\n    </div>\n  );\n\n  const tall = H > W;\n  const uu = tall ? (W * 0.96) / (WIN.w - SIDEBAR) : u;\n  const ox = tall ? W * 0.02 - MX * uu : (W - 1280 * u) / 2;\n  const oy = tall ? H * 0.6 - (WIN.y + WIN.h / 2) * uu : (H - 720 * u) / 2;\n  const readIn = interpolate(frame, [6, 20], [0, 1], {\n    ...CL,\n    easing: easeOut,\n  });\n\n  return (\n    <AbsoluteFill style={{ fontFamily, overflow: \"hidden\" }}>\n      <GshGround\n        preset={ground ?? (pal.dark ? \"velvet-hour\" : \"paper-crease\")}\n        params={groundParams}\n        timeOffset={pal.dark ? 5 : 2}\n        timeScale={0.3}\n      />\n      <AbsoluteFill style={{ background: pal.stage }} />\n      {tall ? (\n        <div\n          style={{\n            position: \"absolute\",\n            left: W * 0.08,\n            right: W * 0.08,\n            top: H * 0.08,\n            color: pal.text,\n            opacity: readIn,\n            transform: `translateY(${(1 - readIn) * 30}px)`,\n          }}\n        >\n          <div\n            style={{\n              fontSize: W * 0.22,\n              fontWeight: 300,\n              letterSpacing: \"-0.05em\",\n              lineHeight: 0.95,\n              fontVariantNumeric: \"tabular-nums\",\n              opacity: filtered ? 0.25 + 0.75 * countIn : 1,\n            }}\n          >\n            {arrSum}\n          </div>\n          <div\n            style={{\n              marginTop: W * 0.03,\n              fontSize: W * 0.045,\n              color: pal.muted,\n              fontVariantNumeric: \"tabular-nums\",\n            }}\n          >\n            {filtered\n              ? `in ${countVal} ${filterValue.toLowerCase()} ${title.toLowerCase()}`\n              : `across ${countVal} ${title.toLowerCase()}`}\n          </div>\n        </div>\n      ) : null}\n      <div\n        style={{\n          position: \"absolute\",\n          left: ox,\n          top: oy,\n          width: 1280,\n          height: 720,\n          transformOrigin: \"0 0\",\n          transform: `scale(${uu})`,\n        }}\n      >\n        <div\n          style={{\n            position: \"absolute\",\n            inset: 0,\n            transformOrigin: `${MX + 400}px ${HEAD_Y}px`,\n            transform: `scale(${1 + 0.07 * camT}) translateY(${(1 - enter) * 34}px)`,\n            opacity: clamp(enter * 1.6, 0, 1),\n          }}\n        >\n          <div\n            style={{\n              position: \"absolute\",\n              left: WIN.x,\n              top: WIN.y,\n              width: WIN.w,\n              height: WIN.h,\n              borderRadius: 14,\n              overflow: \"hidden\",\n              background: pal.win,\n              display: \"flex\",\n              boxShadow: pal.dark\n                ? \"0 0 0 1px rgba(255,255,255,0.09), inset 0 1px 0 rgba(255,255,255,0.05), 0 30px 80px -20px rgba(0,0,0,0.7)\"\n                : \"0 0 0 1px rgba(17,19,24,0.06), 0 2px 4px rgba(17,19,24,0.04), 0 30px 70px -24px rgba(17,19,24,0.28)\",\n            }}\n          >\n            <Sidebar pal={pal} workspace={workspace} title={title} />\n            <div\n              style={{ flex: 1, background: pal.panel, position: \"relative\" }}\n            >\n              <div\n                style={{\n                  height: 44,\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  gap: 9,\n                  padding: \"0 16px\",\n                  borderBottom: `1px solid ${pal.border}`,\n                }}\n              >\n                <Icon name=\"building\" color={pal.text} size={15} />\n                <span\n                  style={{ fontSize: 15, fontWeight: 400, color: pal.text }}\n                >\n                  {title}\n                </span>\n                <div style={{ flex: 1 }} />\n                <Avatar name=\"Maya Chen\" pal={pal} size={24} />\n              </div>\n              <div\n                style={{\n                  height: 44,\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  gap: 8,\n                  padding: \"0 12px\",\n                  borderBottom: `1px solid ${pal.border}`,\n                }}\n              >\n                <div\n                  style={{\n                    height: 28,\n                    display: \"flex\",\n                    alignItems: \"center\",\n                    gap: 7,\n                    padding: \"0 10px\",\n                    borderRadius: 7,\n                    boxShadow: `inset 0 0 0 1px ${pal.border}`,\n                    fontSize: 14,\n                    color: pal.text,\n                    fontWeight: 400,\n                  }}\n                >\n                  All {title.toLowerCase()}\n                  <Icon name=\"chevDown\" color={pal.muted} size={12} />\n                </div>\n                <div style={{ flex: 1 }} />\n                {(\n                  [\n                    [\"View settings\", \"sliders\"],\n                    [\"Import / Export\", \"download\"],\n                  ] as [string, IconName][]\n                ).map(([l, ic]) => (\n                  <div\n                    key={l}\n                    style={{\n                      height: 28,\n                      display: \"flex\",\n                      alignItems: \"center\",\n                      gap: 6,\n                      padding: \"0 10px 0 8px\",\n                      borderRadius: 7,\n                      boxShadow: `inset 0 0 0 1px ${pal.border}`,\n                      fontSize: 14,\n                      color: pal.text,\n                    }}\n                  >\n                    <Icon name={ic} color={pal.muted} />\n                    {l}\n                  </div>\n                ))}\n              </div>\n            </div>\n          </div>\n          {btn(\n            SORT_BTN.x,\n            sortW,\n            <>\n              <Icon name=\"sort\" color={pal.muted} />\n              <span>Sorted by</span>\n              <span style={{ color: pal.text, fontWeight: 400 }}>\n                {sortOn ? \"ARR\" : \"Last activity\"}\n              </span>\n            </>,\n            interpolate(\n              frame,\n              [\n                T.sortClick,\n                T.sortClick + 4,\n                T.sortClick + 26,\n                T.sortClick + 36,\n              ],\n              [0, 1, 1, 0],\n              CL,\n            ),\n          )}\n          {btn(\n            filterX,\n            FILTER_BTN.w,\n            <>\n              <Icon name=\"filter\" color={pal.muted} />\n              <span style={{ color: pal.text }}>Filter</span>\n            </>,\n            pop,\n          )}\n          {chip > 0.01 && (\n            <div\n              style={{\n                position: \"absolute\",\n                left: filterX + FILTER_BTN.w + 8,\n                top: TOOL_Y + 6,\n                height: 28,\n                display: \"flex\",\n                alignItems: \"center\",\n                gap: 6,\n                padding: \"0 6px 0 10px\",\n                borderRadius: 7,\n                background: withAlpha(accent, pal.dark ? 0.16 : 0.07),\n                boxShadow: `inset 0 0 0 1px ${withAlpha(accent, 0.32)}`,\n                fontSize: 14,\n                color: pal.text,\n                transformOrigin: \"0 50%\",\n                transform: `translateX(${(1 - chip) * -6}px) scale(${0.96 + 0.04 * chip})`,\n                opacity: chip,\n                whiteSpace: \"nowrap\",\n              }}\n            >\n              <span style={{ color: pal.muted }}>{filterAttribute}</span>\n              <span style={{ color: pal.faint }}>is</span>\n              <div\n                style={{\n                  width: 7,\n                  height: 7,\n                  borderRadius: 999,\n                  background: STAGE_COLORS[filterValue] ?? accent,\n                }}\n              />\n              <span style={{ fontWeight: 400 }}>{filterValue}</span>\n              <div style={{ marginLeft: 2 }}>\n                <Icon name=\"x\" color={pal.muted} size={13} />\n              </div>\n            </div>\n          )}\n          <div\n            style={{\n              position: \"absolute\",\n              left: MX,\n              top: HEAD_Y,\n              width: WIN.w - SIDEBAR,\n              height: 34,\n              borderTop: `1px solid ${pal.border}`,\n              borderBottom: `1px solid ${pal.border}`,\n              boxSizing: \"border-box\",\n              background: pal.panel,\n            }}\n          >\n            {COLS.map((c, i) => (\n              <div\n                key={c.key}\n                style={{\n                  position: \"absolute\",\n                  left: colLeft(i),\n                  width: c.w,\n                  top: 0,\n                  bottom: 0,\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  justifyContent: c.key === \"arr\" ? \"flex-end\" : \"flex-start\",\n                  gap: 6,\n                  padding: \"0 10px\",\n                  boxSizing: \"border-box\",\n                  fontSize: 14,\n                  color: c.key === \"arr\" && sortOn ? pal.text : pal.muted,\n                  fontWeight: 400,\n                  background:\n                    c.key === \"arr\" && sortOn\n                      ? withAlpha(accent, 0.06 * clamp(sortArrow, 0, 1))\n                      : \"transparent\",\n                }}\n              >\n                {i === 0 ? (\n                  <Checkbox p={0} accent={accent} pal={pal} />\n                ) : (\n                  c.label\n                )}\n                {c.key === \"arr\" && sortArrow > 0.01 && (\n                  <div\n                    style={{\n                      transform: `translateY(${(1 - sortArrow) * -4}px)`,\n                      opacity: sortArrow,\n                    }}\n                  >\n                    <Icon\n                      name=\"arrowDown\"\n                      color={accent}\n                      size={13}\n                      width={1.6}\n                    />\n                  </div>\n                )}\n              </div>\n            ))}\n          </div>\n          <div\n            style={{\n              position: \"absolute\",\n              left: MX,\n              top: BODY_Y,\n              width: WIN.w - SIDEBAR,\n              height: ROW_H * rows.length,\n              overflow: \"hidden\",\n            }}\n          >\n            {rows.map((r, i) => {\n              const a = sp(frame - (10 + i * 2.5), CARD);\n              const lift = climb[i] > 0 ? flipArc : 0;\n              const sink = climb[i] < 0 ? flipArc : 0;\n              return (\n                <div\n                  key={r.company}\n                  style={{\n                    position: \"absolute\",\n                    left: 0,\n                    right: 0,\n                    top: rowY[i] + (1 - a) * 12,\n                    height: ROW_H * (1 - collapse[i]),\n                    overflow: \"hidden\",\n                    opacity:\n                      clamp(a * 1.6, 0, 1) *\n                      (1 - fadeOut[i]) *\n                      (1 - 0.9 * sink),\n                    zIndex: lift > 0 ? 5 : 1,\n                    boxShadow:\n                      lift > 0\n                        ? `0 0 0 1px ${pal.line}, 0 ${6 * lift}px ${16 * lift}px rgba(0,0,0,${(pal.dark ? 0.4 : 0.08) * lift})`\n                        : \"none\",\n                  }}\n                >\n                  <Row\n                    r={r}\n                    pal={pal}\n                    accent={accent}\n                    checked={checks[i]}\n                    sel={checks[i]}\n                  />\n                </div>\n              );\n            })}\n          </div>\n          <div\n            style={{\n              position: \"absolute\",\n              left: MX,\n              top: tableBottom + (1 - enter) * 12,\n              width: WIN.w - SIDEBAR,\n              height: 36,\n              display: \"flex\",\n              alignItems: \"center\",\n              fontSize: 14,\n              color: pal.muted,\n              whiteSpace: \"nowrap\",\n            }}\n          >\n            {COLS.map((c, i) => {\n              if (i === 0) return null;\n              const value =\n                c.key === \"company\"\n                  ? String(countVal)\n                  : c.key === \"arr\"\n                    ? arrSum\n                    : null;\n              return (\n                <div\n                  key={c.key}\n                  style={{\n                    width: i === 1 ? COLS[0].w + c.w : c.w,\n                    display: \"flex\",\n                    justifyContent: \"flex-end\",\n                    alignItems: \"center\",\n                    gap: 5,\n                    paddingRight: 10,\n                    boxSizing: \"border-box\",\n                  }}\n                >\n                  {value ? (\n                    <>\n                      <span\n                        style={{\n                          color: pal.text,\n                          fontWeight: 400,\n                          fontVariantNumeric: \"tabular-nums\",\n                          opacity: filtered ? 0.3 + 0.7 * countIn : 1,\n                          transform: `translateY(${filtered ? (1 - countIn) * 3 : 0}px)`,\n                        }}\n                      >\n                        {value}\n                      </span>\n                      {c.key === \"company\" ? \"count\" : \"sum\"}\n                    </>\n                  ) : (\n                    <>\n                      <Icon name=\"plus\" color={pal.faint} size={12} />\n                      <span style={{ color: pal.faint }}>Add calculation</span>\n                    </>\n                  )}\n                </div>\n              );\n            })}\n          </div>\n          {pop > 0.01 && (\n            <div\n              style={{\n                position: \"absolute\",\n                left: POP.x,\n                top: POP.y,\n                width: POP.w,\n                padding: 6,\n                boxSizing: \"border-box\",\n                borderRadius: 10,\n                background: pal.pop,\n                boxShadow: pal.dark\n                  ? \"0 0 0 1px rgba(255,255,255,0.1), 0 16px 40px rgba(0,0,0,0.55)\"\n                  : \"0 0 0 1px rgba(17,19,24,0.08), 0 12px 32px -4px rgba(17,19,24,0.14), 0 2px 6px rgba(17,19,24,0.05)\",\n                transformOrigin: \"48px 0\",\n                transform: `scale(${0.96 + 0.04 * pop}) translateY(${(1 - pop) * -4}px)`,\n                opacity: clamp(pop * 1.4, 0, 1),\n                zIndex: 30,\n              }}\n            >\n              <div\n                style={{\n                  height: 30,\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  gap: 6,\n                  padding: \"0 8px\",\n                  fontSize: 14,\n                  color: pal.muted,\n                }}\n              >\n                Where{\" \"}\n                <span\n                  style={{\n                    color: pal.text,\n                    fontWeight: 400,\n                    padding: \"2px 6px\",\n                    borderRadius: 5,\n                    boxShadow: `inset 0 0 0 1px ${pal.border}`,\n                  }}\n                >\n                  {filterAttribute}\n                </span>{\" \"}\n                is\n              </div>\n              <div\n                style={{\n                  height: 30,\n                  margin: \"4px 0 2px\",\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  gap: 7,\n                  padding: \"0 8px\",\n                  borderRadius: 6,\n                  boxShadow: `inset 0 0 0 1px ${pal.border}`,\n                  fontSize: 14,\n                  color: pal.faint,\n                }}\n              >\n                <Icon name=\"search\" color={pal.faint} size={13} />\n                Search options…\n              </div>\n              {stages.map((s, i) => {\n                const hov =\n                  i === optIdx\n                    ? interpolate(\n                        frame,\n                        [T.optionClick - 8, T.optionClick - 3],\n                        [0, 1],\n                        CL,\n                      )\n                    : 0;\n                return (\n                  <div\n                    key={s}\n                    style={{\n                      height: 30,\n                      display: \"flex\",\n                      alignItems: \"center\",\n                      gap: 8,\n                      padding: \"0 8px\",\n                      borderRadius: 6,\n                      fontSize: 14,\n                      color: pal.text,\n                      background:\n                        hov > 0\n                          ? pal.dark\n                            ? `rgba(255,255,255,${0.07 * hov})`\n                            : `rgba(17,19,24,${0.05 * hov})`\n                          : \"transparent\",\n                    }}\n                  >\n                    <div\n                      style={{\n                        width: 7,\n                        height: 7,\n                        borderRadius: 999,\n                        background: STAGE_COLORS[s],\n                      }}\n                    />\n                    {s}\n                  </div>\n                );\n              })}\n            </div>\n          )}\n          {bar > 0.01 && (\n            <div\n              style={{\n                position: \"absolute\",\n                left: barX,\n                top: BAR.y + (1 - bar) * 24,\n                width: BAR.w,\n                height: BAR.h,\n                borderRadius: 12,\n                background: pal.dark ? \"#26262B\" : \"#1C1D21\",\n                boxShadow: pal.dark\n                  ? \"0 0 0 1px rgba(255,255,255,0.1), 0 16px 40px rgba(0,0,0,0.5)\"\n                  : \"0 0 0 1px rgba(10,12,18,0.9), 0 16px 36px -6px rgba(10,12,18,0.32), 0 4px 10px rgba(10,12,18,0.12)\",\n                transform: `scale(${0.97 + 0.03 * clamp(bar, 0, 1)})`,\n                display: \"flex\",\n                alignItems: \"center\",\n                padding: \"0 6px 0 14px\",\n                boxSizing: \"border-box\",\n                gap: 6,\n                opacity: clamp(bar * 1.8, 0, 1),\n                color: \"#F2F2F4\",\n                fontSize: 14,\n                zIndex: 25,\n              }}\n            >\n              <div\n                style={{\n                  width: 120,\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  gap: 8,\n                }}\n              >\n                <Checkbox p={1} accent={accent} pal={pal} />\n                <span\n                  style={{\n                    fontWeight: 400,\n                    fontVariantNumeric: \"tabular-nums\",\n                    display: \"inline-block\",\n                    minWidth: 9,\n                    opacity: selected > 1 ? 0.3 + 0.7 * selIn : 1,\n                    transform: `translateY(${selected > 1 ? (1 - selIn) * 3 : 0}px)`,\n                  }}\n                >\n                  {selected}\n                </span>\n                <span style={{ color: \"#B4B5BB\", marginLeft: -3 }}>\n                  selected\n                </span>\n              </div>\n              <div\n                style={{\n                  width: 1,\n                  height: 20,\n                  background: \"rgba(255,255,255,0.14)\",\n                }}\n              />\n              <div\n                style={{\n                  width: 168,\n                  whiteSpace: \"nowrap\",\n                  height: 32,\n                  borderRadius: 8,\n                  background: accent,\n                  display: \"flex\",\n                  alignItems: \"center\",\n                  justifyContent: \"center\",\n                  gap: 7,\n                  fontWeight: 400,\n                  color: \"#fff\",\n                  transform: `scale(${1 - 0.03 * press * actionHover})`,\n                  boxShadow: \"inset 0 1px 0 rgba(255,255,255,0.16)\",\n                  filter: `brightness(${1 + 0.08 * actionHover})`,\n                }}\n              >\n                <Icon name=\"send\" color=\"#fff\" size={13} width={1.5} />\n                {bulkAction}\n              </div>\n              {(\n                [\n                  [\"Export\", \"download\"],\n                  [\"Delete\", \"trash\"],\n                ] as [string, IconName][]\n              ).map(([l, ic]) => (\n                <div\n                  key={l}\n                  style={{\n                    height: 32,\n                    padding: \"0 8px\",\n                    display: \"flex\",\n                    alignItems: \"center\",\n                    gap: 6,\n                    color: l === \"Delete\" ? \"#FF8A8A\" : \"#D6D7DC\",\n                    borderRadius: 8,\n                  }}\n                >\n                  <Icon\n                    name={ic}\n                    color={l === \"Delete\" ? \"#FF8A8A\" : \"#A9AAB1\"}\n                    size={13}\n                  />\n                  {l}\n                </div>\n              ))}\n              <div style={{ flex: 1 }} />\n              <div style={{ paddingRight: 8 }}>\n                <Icon name=\"x\" color=\"#8D8E95\" />\n              </div>\n            </div>\n          )}\n          <div\n            style={{\n              position: \"absolute\",\n              left: 0,\n              top: 0,\n              opacity: cursorIn,\n              zIndex: 50,\n            }}\n          >\n            <Cursor x={cur.x} y={cur.y} press={press} />\n          </div>\n        </div>\n      </div>\n    </AbsoluteFill>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/remocn/table-filter.tsx"
    }
  ],
  "type": "registry:component"
}
