@amsintegra/design-system 1.1.1 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +83 -0
- package/README.md +68 -137
- package/dist/index.cjs +2848 -1034
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1321 -457
- package/dist/index.d.ts +1321 -457
- package/dist/index.js +2630 -631
- package/dist/index.js.map +1 -1
- package/dist/styles.css +2 -0
- package/package.json +17 -27
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/theme/tokens.ts","../src/theme/theme.ts","../src/theme/useThemeMode.ts","../src/theme/AmsConfigProvider.tsx","../src/components/Button/Button.tsx","../src/components/Tag/Tag.tsx","../src/components/message/useAmsMessage.ts","../src/components/notification/useAmsNotification.ts","../src/components/Pagination/Pagination.tsx","../src/components/Card/Card.tsx","../src/components/ThemeToggle/ThemeToggle.tsx","../src/components/DataTable/DataTable.tsx","../src/hooks/useControllableState.ts","../src/components/ModalDialog/ModalDialog.tsx","../src/components/FilterSelect/FilterSelect.tsx","../src/components/FileUploadDragger/FileUploadDragger.tsx","../src/components/PageHeader/PageHeader.tsx","../src/components/DownloadButton/DownloadButton.tsx","../src/components/ConfirmModal/ConfirmModal.tsx"],"names":["antdTheme","Button","jsx","AntButton","forwardRef","Tag","AntTag","App","AntPagination","AntdCard","Switch","Skeleton","Table","useState","useCallback","useMemo","jsxs","Modal","Select","Upload","Fragment","Breadcrumb","DownloadButton","DownloadOutlined"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Design tokens — the single source of truth for the AMS Design System.\n *\n * Values are taken from the B2BMX Metronic theme:\n * b2bmx-web-metronic/src/_metronic/assets/sass/components/_variables.custom.scss\n * b2bmx-web-metronic/tailwind.config.js\n *\n * Two tiers:\n * - `primitives`: raw values, no semantic meaning.\n * - `semantic`: role aliases consumed by the antd theme (and Tailwind).\n */\n\n/** Raw Metronic brand values. */\nexport const primitives = {\n brandRed: '#A72432',\n brandRedActive: '#8B1D28', // darken 10%\n brandRedLight: '#f1faff',\n\n green: '#50cd89',\n greenActive: '#47be7d',\n greenLight: '#e8fff3',\n\n purple: '#7239ea',\n purpleActive: '#5014d0',\n purpleLight: '#f8f5ff',\n\n pink: '#f1416c',\n pinkActive: '#d9214e',\n pinkLight: '#fff5f8',\n\n yellow: '#ffc700',\n yellowActive: '#f1bc00',\n yellowLight: '#fff8dd',\n\n white: '#ffffff',\n\n gray: {\n 100: '#f9f9f9',\n 200: '#f4f4f4',\n 300: '#e1e3ea',\n 400: '#b5b5c3',\n 500: '#a1a5b7',\n 600: '#7e8299',\n 700: '#5e6278',\n 800: '#3f4254',\n 900: '#181c32',\n },\n\n background: {\n app: '#f5f8fa',\n body: '#ffffff',\n appDark: '#151521',\n bodyDark: '#1e1e2d',\n },\n\n dark: {\n base: '#181c32',\n bg: '#151521',\n header: '#1e1e2d',\n active: '#2a2a3c',\n separator: '#393945',\n // Dark-mode surfaces (from mf-container's antdTheme).\n inputBg: '#1b1b29',\n cardBg: '#1e1e2d',\n // Dark-mode gray scale — DISTINCT from the light `gray` scale (Metronic).\n gray: {\n 100: '#2b2b40',\n 200: '#323248',\n 300: '#3b3b64',\n 400: '#474761',\n 500: '#565674',\n 600: '#6d6d80',\n 700: '#92929f',\n 800: '#cdcdde',\n },\n },\n} as const;\n\n/** Radius scale (Metronic). Base radius is 4px. */\nexport const radius = {\n sm: 2,\n base: 4,\n md: 6,\n lg: 8,\n xl: 12,\n} as const;\n\n/** Typography (Metronic uses Inter with a compact 13px base). */\nexport const typography = {\n fontFamily: 'Inter, Helvetica, Arial, sans-serif',\n fontSizeBase: 13,\n weight: {\n light: 300,\n normal: 400,\n medium: 500,\n semibold: 600,\n bold: 700,\n },\n} as const;\n\n/** Control sizing (Metronic). */\nexport const sizing = {\n controlHeight: 32,\n buttonMinWidth: 110,\n} as const;\n\n/**\n * Semantic tokens — role aliases. These feed the antd `ThemeConfig`.\n * Components must consume semantic tokens, never primitives directly.\n */\nexport const semantic = {\n colorPrimary: primitives.brandRed,\n colorPrimaryActive: primitives.brandRedActive,\n colorSuccess: primitives.green,\n colorInfo: primitives.purple,\n colorError: primitives.pink,\n colorWarning: primitives.yellow,\n\n // Links. Metronic inherits link color from the (red) primary, which reads as\n // \"danger\" in dense UIs. The AMS default uses a neutral dark gray so links\n // don't look like errors; consumers can override `colorLink`/`colorLinkHover`\n // via AmsConfigProvider's `theme` prop (e.g. back to the brand red or blue).\n colorLink: primitives.gray[800],\n colorLinkHover: primitives.brandRed,\n colorLinkActive: primitives.brandRedActive,\n\n colorBgLayout: primitives.background.app,\n colorBgContainer: primitives.background.body,\n\n borderRadius: radius.base,\n fontFamily: typography.fontFamily,\n fontSize: typography.fontSizeBase,\n controlHeight: sizing.controlHeight,\n} as const;\n\nexport type ThemeMode = 'light' | 'dark';\n","import { theme as antdTheme } from 'antd';\nimport type { ThemeConfig } from 'antd';\nimport { primitives, semantic, type ThemeMode } from './tokens';\n\n/**\n * Tokens shared by light and dark modes (brand, links, radius, typography).\n * Backgrounds, text, and borders are mode-specific (see below).\n */\nconst sharedToken: ThemeConfig['token'] = {\n colorPrimary: semantic.colorPrimary,\n colorSuccess: semantic.colorSuccess,\n colorInfo: semantic.colorInfo,\n colorError: semantic.colorError,\n colorWarning: semantic.colorWarning,\n colorLink: semantic.colorLink,\n colorLinkHover: semantic.colorLinkHover,\n colorLinkActive: semantic.colorLinkActive,\n borderRadius: semantic.borderRadius,\n fontFamily: semantic.fontFamily,\n fontSize: semantic.fontSize,\n controlHeight: semantic.controlHeight,\n};\n\n/** Light-mode tokens. */\nconst lightToken: ThemeConfig['token'] = {\n ...sharedToken,\n colorBgLayout: semantic.colorBgLayout,\n colorBgContainer: semantic.colorBgContainer,\n colorBgElevated: primitives.background.body,\n colorText: primitives.gray[900],\n colorTextSecondary: primitives.gray[700],\n colorTextTertiary: primitives.gray[500],\n colorTextQuaternary: primitives.gray[400],\n colorBorder: primitives.gray[300],\n colorBorderSecondary: primitives.gray[200],\n};\n\n/**\n * Dark-mode tokens. Backgrounds/text/borders come from the Metronic dark\n * palette (mirrors mf-container's darkTheme). Brand colors stay identical.\n */\nconst darkToken: ThemeConfig['token'] = {\n ...sharedToken,\n colorBgLayout: primitives.background.appDark,\n colorBgContainer: primitives.background.bodyDark,\n colorBgElevated: primitives.background.bodyDark,\n colorText: '#ffffff',\n colorTextHeading: '#ffffff',\n colorTextSecondary: primitives.dark.gray[800],\n colorTextTertiary: primitives.dark.gray[700],\n colorTextQuaternary: primitives.dark.gray[600],\n colorBorder: primitives.dark.gray[300],\n colorBorderSecondary: primitives.dark.gray[200],\n boxShadow:\n '0 6px 16px 0 rgba(0, 0, 0, 0.48), 0 3px 6px -4px rgba(0, 0, 0, 0.36), 0 9px 28px 8px rgba(0, 0, 0, 0.15)',\n};\n\n/** Per-component overrides shared by both modes. */\nconst sharedComponents: ThemeConfig['components'] = {\n Button: { controlHeight: 32 },\n Tabs: {\n itemColor: primitives.gray[600],\n itemSelectedColor: semantic.colorPrimary,\n itemHoverColor: semantic.colorPrimary,\n },\n};\n\n/** Light per-component overrides. */\nconst lightComponents: ThemeConfig['components'] = {\n ...sharedComponents,\n Table: {\n headerBg: primitives.gray[100],\n headerColor: primitives.gray[800],\n borderColor: primitives.gray[300],\n cellPaddingBlock: 8,\n cellPaddingInline: 8,\n },\n};\n\n/** Dark per-component overrides (mirrors mf-container's dark component theme). */\nconst darkComponents: ThemeConfig['components'] = {\n ...sharedComponents,\n Table: {\n headerBg: primitives.dark.gray[200],\n headerColor: primitives.dark.gray[800],\n borderColor: primitives.dark.gray[400],\n rowHoverBg: primitives.dark.gray[200],\n cellPaddingBlock: 8,\n cellPaddingInline: 8,\n },\n Input: {\n colorBgContainer: primitives.dark.inputBg,\n colorBorder: primitives.dark.gray[400],\n colorText: '#ffffff',\n },\n Select: {\n colorBgContainer: primitives.dark.inputBg,\n colorBorder: primitives.dark.gray[400],\n colorText: '#ffffff',\n },\n DatePicker: {\n colorBgContainer: primitives.dark.inputBg,\n },\n Card: {\n colorBgContainer: primitives.dark.cardBg,\n colorBorderSecondary: primitives.dark.cardBg,\n },\n Modal: {\n contentBg: primitives.dark.gray[100],\n headerBg: primitives.dark.gray[100],\n },\n Drawer: {\n colorBgElevated: primitives.dark.gray[100],\n },\n Notification: {\n colorBgElevated: primitives.dark.gray[100],\n },\n Message: {\n contentBg: primitives.dark.gray[100],\n },\n Menu: {\n itemBg: primitives.background.bodyDark,\n itemHoverBg: primitives.dark.gray[100],\n itemSelectedBg: primitives.dark.active,\n itemSelectedColor: semantic.colorPrimary,\n itemActiveBg: primitives.dark.active,\n subMenuItemBg: primitives.background.bodyDark,\n },\n Dropdown: {\n colorBgElevated: primitives.background.bodyDark,\n controlItemBgHover: primitives.dark.gray[100],\n },\n};\n\n/**\n * Builds the antd theme for a given mode. Dark mode uses antd's\n * `darkAlgorithm`; brand tokens stay identical so the brand is consistent.\n */\nexport function buildTheme(mode: ThemeMode = 'light'): ThemeConfig {\n const isDark = mode === 'dark';\n return {\n algorithm: isDark ? antdTheme.darkAlgorithm : antdTheme.defaultAlgorithm,\n token: isDark ? darkToken : lightToken,\n components: isDark ? darkComponents : lightComponents,\n };\n}\n\n/** Default (light) AMS theme. */\nexport const amsTheme: ThemeConfig = buildTheme('light');\n\n/** Dark AMS theme. */\nexport const amsThemeDark: ThemeConfig = buildTheme('dark');\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport type { ThemeMode } from './tokens';\n\nconst STORAGE_KEY = 'ams-theme';\n\n/** Reads the initial mode: saved preference → OS preference → light. */\nexport function getInitialThemeMode(defaultMode: ThemeMode = 'light'): ThemeMode {\n if (typeof window === 'undefined') return defaultMode;\n const saved = window.localStorage.getItem(STORAGE_KEY);\n if (saved === 'light' || saved === 'dark') return saved;\n if (window.matchMedia?.('(prefers-color-scheme: dark)').matches) return 'dark';\n return defaultMode;\n}\n\n/** Reflects the mode on the DOM so CSS can react (mirrors mf-container). */\nexport function applyThemeModeToDOM(mode: ThemeMode): void {\n if (typeof document === 'undefined') return;\n document.documentElement.setAttribute('data-theme', mode);\n document.body?.setAttribute('data-theme', mode);\n}\n\nexport interface ThemeModeContextValue {\n mode: ThemeMode;\n setMode: (mode: ThemeMode) => void;\n toggle: () => void;\n isDark: boolean;\n}\n\nexport const ThemeModeContext = createContext<ThemeModeContextValue | null>(null);\n\n/**\n * Access the current color mode and switch it. Requires an ancestor\n * `AmsConfigProvider`. Use it to build a light/dark toggle:\n *\n * const { isDark, toggle } = useThemeMode();\n * <Switch checked={isDark} onChange={toggle} />\n */\nexport function useThemeMode(): ThemeModeContextValue {\n const ctx = useContext(ThemeModeContext);\n if (!ctx) {\n throw new Error('useThemeMode must be used within an AmsConfigProvider');\n }\n return ctx;\n}\n\n/**\n * Internal state manager for the color mode. When `controlledMode` is provided,\n * the provider is controlled (no persistence). Otherwise the mode is managed\n * here: persisted to localStorage and reflected on the DOM via `data-theme`.\n */\nexport function useThemeModeState(\n controlledMode: ThemeMode | undefined,\n defaultMode: ThemeMode,\n persist: boolean,\n): ThemeModeContextValue {\n const isControlled = controlledMode !== undefined;\n const [internalMode, setInternalMode] = useState<ThemeMode>(() =>\n isControlled ? controlledMode : persist ? getInitialThemeMode(defaultMode) : defaultMode,\n );\n\n const mode = isControlled ? controlledMode : internalMode;\n\n useEffect(() => {\n applyThemeModeToDOM(mode);\n }, [mode]);\n\n const setMode = useCallback(\n (next: ThemeMode) => {\n if (!isControlled) {\n setInternalMode(next);\n if (persist && typeof window !== 'undefined') {\n window.localStorage.setItem(STORAGE_KEY, next);\n }\n }\n },\n [isControlled, persist],\n );\n\n const toggle = useCallback(() => {\n setMode(mode === 'light' ? 'dark' : 'light');\n }, [mode, setMode]);\n\n return useMemo(\n () => ({ mode, setMode, toggle, isDark: mode === 'dark' }),\n [mode, setMode, toggle],\n );\n}\n","import { App, ConfigProvider } from 'antd';\nimport type { Locale } from 'antd/es/locale';\nimport type { ThemeConfig } from 'antd';\nimport type { PropsWithChildren, ReactNode } from 'react';\nimport { buildTheme } from './theme';\nimport type { ThemeMode } from './tokens';\nimport { ThemeModeContext, useThemeModeState } from './useThemeMode';\n\nexport interface AmsConfigProviderProps {\n /**\n * Controlled color mode. When provided, the provider does not manage or\n * persist the mode. Omit it to let the provider manage the mode itself\n * (persisted to localStorage, respects OS preference) — read/toggle it with\n * the `useThemeMode` hook.\n */\n mode?: ThemeMode;\n /** Initial mode when self-managed (uncontrolled). Defaults to `light`. */\n defaultMode?: ThemeMode;\n /** Persist the self-managed mode to localStorage. Defaults to `true`. */\n persistMode?: boolean;\n /**\n * antd locale (e.g. `esES`, `enUS`). The consuming app passes it;\n * the design system stays i18n-agnostic and ships no message catalog.\n */\n locale?: Locale;\n /**\n * Theme overrides merged on top of the AMS theme. Use it to customize tokens\n * per project without forking the DS, e.g. `{ token: { colorLink: '#1677ff' } }`.\n */\n theme?: ThemeConfig;\n children?: ReactNode;\n}\n\nfunction mergeTheme(base: ThemeConfig, override?: ThemeConfig): ThemeConfig {\n if (!override) return base;\n return {\n ...base,\n ...override,\n token: { ...base.token, ...override.token },\n components: { ...base.components, ...override.components },\n // A caller-provided algorithm wins; otherwise keep the mode's algorithm.\n algorithm: override.algorithm ?? base.algorithm,\n };\n}\n\n/**\n * Root provider for the AMS Design System.\n *\n * - Applies the AMS theme (light/dark) via antd's `ConfigProvider`.\n * - Renders antd's `App` for context-safe `message`/`notification`/`Modal`.\n * - Manages the color mode (controlled via `mode`, or self-managed with\n * localStorage persistence and OS-preference detection) and exposes it\n * through the `useThemeMode` hook.\n * - Accepts a `theme` override merged on top of the AMS theme.\n *\n * Render it once at the app root.\n */\nexport function AmsConfigProvider({\n mode,\n defaultMode = 'light',\n persistMode = true,\n locale,\n theme,\n children,\n}: PropsWithChildren<AmsConfigProviderProps>) {\n const themeMode = useThemeModeState(mode, defaultMode, persistMode);\n const resolvedTheme = mergeTheme(buildTheme(themeMode.mode), theme);\n\n return (\n <ThemeModeContext.Provider value={themeMode}>\n <ConfigProvider theme={resolvedTheme} locale={locale}>\n <App>{children}</App>\n </ConfigProvider>\n </ThemeModeContext.Provider>\n );\n}\n","import { Button as AntButton } from 'antd';\nimport type { ButtonProps as AntButtonProps } from 'antd';\nimport { forwardRef } from 'react';\n\nexport interface ButtonProps extends AntButtonProps {}\n\n/**\n * AMS Button — thin wrapper over antd `Button` that inherits the AMS theme.\n * Exposes the full antd Button API (type, danger, loading, icon, size, etc.)\n * and forwards the ref so it integrates with Form and tooltips.\n */\nexport const Button = forwardRef<HTMLButtonElement | HTMLAnchorElement, ButtonProps>(\n function Button(props, ref) {\n return <AntButton ref={ref} {...props} />;\n },\n);\n","import { Tag as AntTag } from 'antd';\nimport type { TagProps as AntTagProps } from 'antd';\nimport { forwardRef } from 'react';\nimport { semantic } from '../../theme/tokens';\n\n/** AMS semantic tag intents mapped to brand tokens. */\nexport type TagIntent = 'success' | 'error' | 'warning' | 'info' | 'primary';\n\nexport interface TagProps extends AntTagProps {\n /**\n * Semantic intent that resolves to an AMS brand color. Takes precedence over\n * antd's `color` when set. Formalizes the inline `#50cd89` / `#f1416c` colors\n * previously hardcoded in mf-boveda's DataTable.\n */\n intent?: TagIntent;\n}\n\nconst INTENT_COLOR: Record<TagIntent, string> = {\n success: semantic.colorSuccess,\n error: semantic.colorError,\n warning: semantic.colorWarning,\n info: semantic.colorInfo,\n primary: semantic.colorPrimary,\n};\n\n/**\n * AMS Tag — thin wrapper over antd `Tag` with an optional semantic `intent`\n * that maps to the brand palette. Falls back to the full antd Tag API.\n */\nexport const Tag = forwardRef<HTMLSpanElement, TagProps>(function Tag(\n { intent, color, ...rest },\n ref,\n) {\n const resolvedColor = intent ? INTENT_COLOR[intent] : color;\n return <AntTag ref={ref} color={resolvedColor} {...rest} />;\n});\n","import { App } from 'antd';\nimport type { MessageInstance } from 'antd/es/message/interface';\n\n/**\n * Context-safe access to antd's `message` API.\n *\n * In antd v5 the static `message.success(...)` calls do **not** read the\n * `ConfigProvider` theme and log a warning. The supported approach is to\n * consume the instance provided by antd's `App` context — which\n * `AmsConfigProvider` already renders at the root.\n *\n * Usage:\n * const message = useAmsMessage();\n * message.success('Saved');\n *\n * Requires an ancestor `AmsConfigProvider` (or antd `App`).\n */\nexport function useAmsMessage(): MessageInstance {\n return App.useApp().message;\n}\n","import { App } from 'antd';\nimport type { NotificationInstance } from 'antd/es/notification/interface';\n\n/**\n * Context-safe access to antd's `notification` API.\n *\n * Like `useAmsMessage`, this returns the instance from antd's `App` context so\n * notifications inherit the AMS theme and avoid the v5 static-method warning.\n * Requires an ancestor `AmsConfigProvider` (or antd `App`).\n *\n * Usage:\n * const notification = useAmsNotification();\n * notification.success({ message: 'Done', description: 'Saved.' });\n */\nexport function useAmsNotification(): NotificationInstance {\n return App.useApp().notification;\n}\n","import { Pagination as AntPagination } from 'antd';\nimport type { PaginationProps as AntPaginationProps } from 'antd';\nimport type { PaginationLocale } from 'antd/es/pagination/Pagination';\nimport type { ReactNode } from 'react';\n\n/**\n * Translatable text labels for the pagination control. The design system is\n * i18n-agnostic: the consuming app passes already-translated strings. Anything\n * omitted falls back to antd's `locale` (or English defaults).\n */\nexport interface PaginationLabels {\n /** Suffix in the page-size selector, e.g. \"/ página\". */\n itemsPerPage?: string;\n /** \"Ir a\" label of the quick jumper. */\n jumpTo?: string;\n /** Confirm button text of the quick jumper. */\n jumpToConfirm?: string;\n /** Accessible label for a page, e.g. \"Página\". */\n page?: string;\n /** Accessible label for the previous-page button. */\n prevPage?: string;\n /** Accessible label for the next-page button. */\n nextPage?: string;\n /** Label for the page-size selector, e.g. \"Tamaño de página\". */\n pageSize?: string;\n /**\n * Builds the total-records text (rendered before the pages).\n * Receives the total and the current [from, to] range.\n * e.g. (total) => `Total ${total} registros`. Takes precedence over `totalText`.\n */\n total?: (total: number, range: [number, number]) => ReactNode;\n /**\n * Declarative total text as separate translated words, matching how the\n * mf-boveda table builds it: `{prefix} {total} {suffix}` → \"Total 250 registros\".\n * Set `showRange` to render \"{prefix} {from}-{to} {suffix}\" instead.\n * Ignored when `total` (the function form) is provided.\n */\n totalText?: {\n /** Word(s) before the number, e.g. \"Total\". */\n prefix?: string;\n /** Word(s) after the number, e.g. \"registros\". */\n suffix?: string;\n /** Use the \"from-to\" range instead of just the total. Default false. */\n showRange?: boolean;\n };\n /** Visible text for the \"previous\" button (overrides the arrow). */\n previousText?: ReactNode;\n /** Visible text for the \"next\" button (overrides the arrow). */\n nextText?: ReactNode;\n}\n\nexport interface PaginationProps extends AntPaginationProps {\n /** Translatable text labels. */\n labels?: PaginationLabels;\n}\n\nfunction buildLocale(labels?: PaginationLabels): PaginationLocale | undefined {\n if (!labels) return undefined;\n const locale: PaginationLocale = {};\n if (labels.itemsPerPage !== undefined) locale.items_per_page = labels.itemsPerPage;\n if (labels.jumpTo !== undefined) locale.jump_to = labels.jumpTo;\n if (labels.jumpToConfirm !== undefined) locale.jump_to_confirm = labels.jumpToConfirm;\n if (labels.page !== undefined) locale.page = labels.page;\n if (labels.prevPage !== undefined) locale.prev_page = labels.prevPage;\n if (labels.nextPage !== undefined) locale.next_page = labels.nextPage;\n if (labels.pageSize !== undefined) locale.page_size = labels.pageSize;\n return Object.keys(locale).length > 0 ? locale : undefined;\n}\n\n/**\n * AMS Pagination — antd `Pagination` with translatable text via a single\n * `labels` prop (page, records/total, previous/next, items-per-page, jumper).\n * The rest of the antd Pagination API passes through. `showTotal` and\n * `itemRender` still work if you prefer to set them directly; explicit\n * `showTotal`/`itemRender`/`locale` props win over `labels`.\n */\nexport function Pagination({\n labels,\n showTotal,\n itemRender,\n locale,\n ...rest\n}: PaginationProps) {\n const mergedLocale = { ...buildLocale(labels), ...locale };\n\n const resolvedShowTotal: AntPaginationProps['showTotal'] =\n showTotal ??\n (labels?.total\n ? (total, range) => labels.total!(total, range)\n : labels?.totalText\n ? (total, range) => {\n const { prefix, suffix, showRange } = labels.totalText!;\n const middle = showRange ? `${range[0]}-${range[1]}` : String(total);\n return [prefix, middle, suffix].filter(Boolean).join(' ');\n }\n : undefined);\n\n const resolvedItemRender: AntPaginationProps['itemRender'] =\n itemRender ??\n (labels?.previousText || labels?.nextText\n ? (_page, type, element) => {\n if (type === 'prev' && labels?.previousText !== undefined) return labels.previousText;\n if (type === 'next' && labels?.nextText !== undefined) return labels.nextText;\n return element;\n }\n : undefined);\n\n return (\n <AntPagination\n {...rest}\n locale={Object.keys(mergedLocale).length > 0 ? mergedLocale : undefined}\n showTotal={resolvedShowTotal}\n itemRender={resolvedItemRender}\n />\n );\n}\n","import { Card as AntdCard } from 'antd';\nimport type { CardProps } from 'antd';\nimport type * as React from 'react';\n\n// antd v6 declares `Card` as an `interface` that EXTENDS a forwardRef function\n// type (`interface CardInterface extends typeof InternalCard { Grid; Meta }`).\n// Extending an interface over a function type discards its call/construct\n// signatures, so TypeScript rejects `<Card>` as a JSX element (TS2786 / TS2604)\n// in consumers (React 19 + moduleResolution: Bundler). Rebuilding the type with\n// an INTERSECTION preserves the call signature plus the subcomponents. This is a\n// type-only fix: the exported runtime value is the unchanged antd `Card`.\ntype CardComponent = React.ForwardRefExoticComponent<\n CardProps & React.RefAttributes<HTMLDivElement>\n> & {\n Grid: (typeof AntdCard)['Grid'];\n Meta: (typeof AntdCard)['Meta'];\n};\n\nexport const Card = AntdCard as unknown as CardComponent;\nexport type { CardProps } from 'antd';\n","import { Switch } from 'antd';\nimport type { SwitchProps } from 'antd';\nimport { BulbOutlined, BulbFilled } from '@ant-design/icons';\nimport { useThemeMode } from '../../theme/useThemeMode';\n\nexport interface ThemeToggleProps extends Omit<SwitchProps, 'checked' | 'onChange'> {}\n\n/**\n * AMS ThemeToggle — a ready-made light/dark switch wired to `useThemeMode`.\n * Requires an ancestor `AmsConfigProvider` that manages the mode\n * (i.e. rendered without a controlled `mode` prop).\n */\nexport function ThemeToggle(props: ThemeToggleProps) {\n const { isDark, toggle } = useThemeMode();\n return (\n <Switch\n checked={isDark}\n onChange={toggle}\n checkedChildren={<BulbFilled />}\n unCheckedChildren={<BulbOutlined />}\n {...props}\n />\n );\n}\n","import { Skeleton, Table } from 'antd';\nimport type { TableProps, TablePaginationConfig } from 'antd';\nimport type { PaginationLocale } from 'antd/es/pagination/Pagination';\nimport type { ReactNode } from 'react';\nimport { Tag } from '../Tag';\nimport type { PaginationLabels } from '../Pagination';\n\n/**\n * Labels for the DataTable. The design system is i18n-agnostic: the consuming\n * microfrontend passes translated strings from its own catalog. Sensible\n * English defaults are provided so the table renders without wiring.\n */\nexport interface DataTableLabels {\n emptyText?: string;\n sortAsc?: string;\n sortDesc?: string;\n cancelSort?: string;\n}\n\nfunction buildPaginationLocale(labels?: PaginationLabels): PaginationLocale | undefined {\n if (!labels) return undefined;\n const locale: PaginationLocale = {};\n if (labels.itemsPerPage !== undefined) locale.items_per_page = labels.itemsPerPage;\n if (labels.jumpTo !== undefined) locale.jump_to = labels.jumpTo;\n if (labels.jumpToConfirm !== undefined) locale.jump_to_confirm = labels.jumpToConfirm;\n if (labels.page !== undefined) locale.page = labels.page;\n if (labels.prevPage !== undefined) locale.prev_page = labels.prevPage;\n if (labels.nextPage !== undefined) locale.next_page = labels.nextPage;\n if (labels.pageSize !== undefined) locale.page_size = labels.pageSize;\n return Object.keys(locale).length > 0 ? locale : undefined;\n}\n\nconst DEFAULT_LABELS: Required<DataTableLabels> = {\n emptyText: 'No data',\n sortAsc: 'Sort ascending',\n sortDesc: 'Sort descending',\n cancelSort: 'Cancel sort',\n};\n\nexport interface DataTableProps<T extends object = Record<string, unknown>>\n extends Omit<TableProps<T>, 'title' | 'loading'> {\n /** Optional plain-text heading rendered above the table. */\n heading?: string;\n /** Extra content (buttons, filters) rendered above the table. */\n extra?: React.ReactNode;\n /** External loading state. Renders a skeleton placeholder while true. */\n loading?: boolean;\n /** Translated labels; falls back to English defaults. */\n labels?: DataTableLabels;\n /**\n * Translatable pagination text (total/records, previous/next, page-size,\n * jumper). Applied to the table's pagination — matches the mf-boveda pattern\n * of a \"{prefix} {total} {suffix}\" total and translated prev/next buttons.\n * Merged into `pagination`; anything set directly on `pagination`\n * (`showTotal`/`itemRender`/`locale`) wins.\n */\n paginationLabels?: PaginationLabels;\n /**\n * Opt-in: render numeric values in the first column as colored tags\n * (green when >= 0, red when < 0). Off by default — this replaces the\n * implicit column-0 behavior of the original mf-boveda DataTable, which\n * was surprising. Explicitly enable it per table when desired.\n */\n firstColumnNumericTag?: boolean;\n}\n\nfunction toNumericValue(value: unknown): number | null {\n if (value === null || value === undefined || value === '') return null;\n const num =\n typeof value === 'string' ? parseFloat(value.replace(/,/g, '')) : Number(value);\n return Number.isNaN(num) || !Number.isFinite(num) ? null : num;\n}\n\n/**\n * AMS DataTable — themed, opinionated wrapper over antd `Table`.\n *\n * Ports the reusable behavior from mf-boveda's DataTable:\n * - loading skeleton placeholder,\n * - `bordered` and horizontal `scroll: { x: 'max-content' }` defaults,\n * - i18n-agnostic labels via props,\n * - optional (opt-in) numeric tags on the first column.\n *\n * All other antd Table props pass through.\n */\nfunction buildTotalText(labels?: PaginationLabels): TablePaginationConfig['showTotal'] | undefined {\n if (!labels) return undefined;\n if (labels.total) return (total, range) => labels.total!(total, range);\n if (labels.totalText) {\n return (total, range) => {\n const { prefix, suffix, showRange } = labels.totalText!;\n const middle = showRange ? `${range[0]}-${range[1]}` : String(total);\n return [prefix, middle, suffix].filter(Boolean).join(' ');\n };\n }\n return undefined;\n}\n\nfunction buildItemRender(labels?: PaginationLabels): TablePaginationConfig['itemRender'] | undefined {\n if (!labels || (labels.previousText === undefined && labels.nextText === undefined)) {\n return undefined;\n }\n return (_page, type, element) => {\n if (type === 'prev' && labels.previousText !== undefined) return labels.previousText;\n if (type === 'next' && labels.nextText !== undefined) return labels.nextText;\n return element as ReactNode;\n };\n}\n\nexport function DataTable<T extends object = Record<string, unknown>>({\n heading,\n extra,\n loading = false,\n labels,\n paginationLabels,\n firstColumnNumericTag = false,\n columns,\n dataSource,\n scroll,\n bordered = true,\n pagination,\n className,\n ...rest\n}: DataTableProps<T>) {\n const mergedLabels = { ...DEFAULT_LABELS, ...labels };\n\n // Merge translatable pagination labels into the pagination config.\n // Explicit values on `pagination` win over the label-derived ones.\n const resolvedPagination =\n pagination === false || pagination === undefined\n ? pagination\n : (() => {\n const paginationLocale = buildPaginationLocale(paginationLabels);\n const totalFn = buildTotalText(paginationLabels);\n const itemRenderFn = buildItemRender(paginationLabels);\n return {\n ...(totalFn ? { showTotal: totalFn } : {}),\n ...(itemRenderFn ? { itemRender: itemRenderFn } : {}),\n ...(paginationLocale ? { locale: paginationLocale } : {}),\n ...pagination,\n };\n })();\n\n const resolvedColumns =\n firstColumnNumericTag && columns && columns.length > 0\n ? columns.map((col, index) => {\n if (index !== 0) return col;\n const originalRender = (\n col as { render?: (value: unknown, record: T, i: number) => React.ReactNode }\n ).render;\n return {\n ...col,\n render: (value: unknown, record: T, i: number) => {\n const content = originalRender\n ? originalRender(value, record, i)\n : (value as React.ReactNode);\n const numeric = toNumericValue(value);\n if (numeric === null) return content;\n return (\n <Tag\n intent={numeric < 0 ? 'error' : 'success'}\n style={{ minWidth: 72, textAlign: 'center' }}\n >\n {content}\n </Tag>\n );\n },\n };\n })\n : columns;\n\n const resolvedScroll = scroll ?? { x: 'max-content' };\n\n return (\n <div className={className}>\n {heading ? (\n <div style={{ marginBottom: 8 }}>\n <h3 style={{ margin: 0, fontWeight: 600 }}>{heading}</h3>\n </div>\n ) : null}\n {extra ? <div style={{ marginBottom: 8 }}>{extra}</div> : null}\n {loading ? (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>\n {Array.from({ length: 6 }).map((_, i) => (\n <Skeleton key={i} active paragraph={{ rows: 0 }} title={{ width: '100%' }} />\n ))}\n </div>\n ) : (\n <Table<T>\n columns={resolvedColumns}\n dataSource={dataSource}\n bordered={bordered}\n scroll={resolvedScroll}\n pagination={resolvedPagination}\n locale={{\n emptyText: mergedLabels.emptyText,\n triggerAsc: mergedLabels.sortAsc,\n triggerDesc: mergedLabels.sortDesc,\n cancelSort: mergedLabels.cancelSort,\n }}\n {...rest}\n />\n )}\n </div>\n );\n}\n","import { useCallback, useState } from 'react';\n\nexport interface UseControllableStateOptions<T> {\n /** Controlled value. When defined, the hook is in controlled mode. */\n value?: T;\n /** Initial value for uncontrolled mode. */\n defaultValue: T;\n /** Called on every change (both modes). */\n onChange?: (next: T) => void;\n}\n\n/**\n * Supports the controlled/uncontrolled pattern used across the design system\n * (mirrors mf-boveda's ReusableModal state handling). When `value` is provided\n * the component is controlled; otherwise internal state is used.\n */\nexport function useControllableState<T>({\n value,\n defaultValue,\n onChange,\n}: UseControllableStateOptions<T>): [T, (next: T) => void] {\n const isControlled = value !== undefined;\n const [internal, setInternal] = useState<T>(defaultValue);\n const current = isControlled ? (value as T) : internal;\n\n const setValue = useCallback(\n (next: T) => {\n if (!isControlled) {\n setInternal(next);\n }\n onChange?.(next);\n },\n [isControlled, onChange],\n );\n\n return [current, setValue];\n}\n","import { Modal } from 'antd';\nimport type { ModalProps } from 'antd';\nimport {\n isValidElement,\n cloneElement,\n useCallback,\n useMemo,\n type ReactNode,\n type MouseEvent,\n type KeyboardEvent,\n} from 'react';\nimport { useControllableState } from '../../hooks/useControllableState';\n\ntype TriggerRenderer = (open: () => void) => ReactNode;\n\nexport interface ModalDialogProps extends Omit<ModalProps, 'open' | 'children'> {\n /** Controlled open state. */\n open?: boolean;\n /** Initial open state in uncontrolled mode. */\n defaultOpen?: boolean;\n /** Node or render-prop that opens the modal when clicked. */\n trigger?: ReactNode | TriggerRenderer;\n /** Close automatically after `onOk` resolves. Default true. */\n closeOnOk?: boolean;\n /** Close automatically after `onCancel`. Default true. */\n closeOnCancel?: boolean;\n /** Notified whenever the open state changes (controlled or not). */\n onOpenChange?: (next: boolean) => void;\n children?: ReactNode;\n}\n\nfunction isPromise<T>(value: unknown): value is Promise<T> {\n return !!value && typeof (value as Promise<T>).then === 'function';\n}\n\n/**\n * AMS ModalDialog — a controllable modal composite.\n *\n * Ports mf-boveda's ReusableModal API:\n * - controlled (`open`) or uncontrolled (`defaultOpen`) state,\n * - a `trigger` node or render-prop that opens it,\n * - `closeOnOk` / `closeOnCancel` with async `onOk` support (waits for the\n * returned promise before closing).\n *\n * All other antd Modal props pass through.\n */\nexport function ModalDialog({\n trigger,\n children,\n open,\n defaultOpen = false,\n closeOnOk = true,\n closeOnCancel = true,\n onOk,\n onCancel,\n onOpenChange,\n ...modalProps\n}: ModalDialogProps) {\n const [isOpen, setOpen] = useControllableState<boolean>({\n value: open,\n defaultValue: defaultOpen,\n onChange: onOpenChange,\n });\n\n const handleOpen = useCallback(() => setOpen(true), [setOpen]);\n\n const handleCancel: ModalProps['onCancel'] = useCallback(\n (event: MouseEvent<HTMLButtonElement> | KeyboardEvent<HTMLElement>) => {\n onCancel?.(event);\n if (closeOnCancel) setOpen(false);\n },\n [onCancel, closeOnCancel, setOpen],\n );\n\n const handleOk: ModalProps['onOk'] = useCallback(\n async (event: MouseEvent<HTMLButtonElement>) => {\n const result = onOk?.(event);\n if (!closeOnOk) return;\n if (isPromise(result)) {\n try {\n await result;\n } finally {\n setOpen(false);\n }\n } else {\n setOpen(false);\n }\n },\n [onOk, closeOnOk, setOpen],\n );\n\n const triggerNode = useMemo(() => {\n if (!trigger) return null;\n if (typeof trigger === 'function') {\n return (trigger as TriggerRenderer)(handleOpen);\n }\n if (isValidElement(trigger)) {\n const el = trigger as React.ReactElement<{ onClick?: (e: MouseEvent<HTMLElement>) => void }>;\n const originalOnClick = el.props.onClick;\n return cloneElement(el, {\n onClick: (event: MouseEvent<HTMLElement>) => {\n originalOnClick?.(event);\n handleOpen();\n },\n });\n }\n return trigger;\n }, [trigger, handleOpen]);\n\n return (\n <>\n {triggerNode}\n <Modal open={isOpen} onOk={handleOk} onCancel={handleCancel} {...modalProps}>\n {children}\n </Modal>\n </>\n );\n}\n","import { Select } from 'antd';\nimport type { SelectProps } from 'antd';\nimport type { ReactNode } from 'react';\n\nexport interface FilterOption {\n value: string;\n label: ReactNode;\n disabled?: boolean;\n}\n\nexport interface FilterSelectProps\n extends Omit<SelectProps<string>, 'options' | 'filterOption'> {\n options: FilterOption[];\n /** Enable client-side search with accent-insensitive matching. */\n showSearch?: boolean;\n /** Override the default accent-insensitive filter. */\n filterOption?: SelectProps<string>['filterOption'];\n}\n\nconst normalize = (value?: string): string =>\n (value ?? '')\n .toString()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .toLowerCase();\n\nconst extractText = (node?: ReactNode): string => {\n if (node === null || node === undefined) return '';\n if (typeof node === 'string' || typeof node === 'number' || typeof node === 'boolean') {\n return String(node);\n }\n if (Array.isArray(node)) return node.map(extractText).join(' ');\n if (typeof node === 'object' && 'props' in (node as unknown as Record<string, unknown>)) {\n const props = (node as { props?: { children?: ReactNode } }).props;\n return extractText(props?.children);\n }\n return '';\n};\n\n/**\n * AMS FilterSelect — a Select preset for dashboard filters.\n *\n * Ports mf-boveda's FilterSelect: accent-insensitive search over both the\n * option label and value, full-width by default. i18n is the consumer's\n * responsibility (pass already-translated labels).\n */\nexport function FilterSelect({\n options,\n showSearch = false,\n filterOption,\n className,\n style,\n ...rest\n}: FilterSelectProps) {\n const defaultFilter: SelectProps<string>['filterOption'] = (input, option) => {\n if (!option) return false;\n const query = normalize(input);\n const label = normalize(extractText(option.label as ReactNode));\n const value = normalize(typeof option.value === 'string' ? option.value : '');\n return label.includes(query) || value.includes(query);\n };\n\n const resolvedFilter = showSearch && !filterOption ? defaultFilter : filterOption;\n\n return (\n <Select<string>\n options={options}\n showSearch={showSearch}\n filterOption={resolvedFilter}\n optionFilterProp=\"label\"\n className={className}\n style={{ width: '100%', ...style }}\n {...rest}\n />\n );\n}\n","import { Upload } from 'antd';\nimport type { UploadProps } from 'antd';\nimport { InboxOutlined } from '@ant-design/icons';\nimport { useMemo, type ReactNode } from 'react';\nimport { useAmsMessage } from '../message/useAmsMessage';\n\ntype UploadMessage = string | ((fileName: string) => string);\ntype UploadChangeInfo = Parameters<NonNullable<UploadProps['onChange']>>[0];\n\nexport interface FileUploadDraggerProps\n extends Omit<UploadProps, 'onChange'> {\n /** Success toast text or a builder receiving the file name. */\n successMessage?: UploadMessage;\n /** Error toast text or a builder receiving the file name. */\n errorMessage?: UploadMessage;\n /** Show success/error toasts on upload status changes. Default true. */\n showStatusMessages?: boolean;\n /** Prompt text shown inside the drop area (when no children given). */\n hintText?: ReactNode;\n onUploadSuccess?: (info: UploadChangeInfo) => void;\n onUploadError?: (info: UploadChangeInfo) => void;\n onChange?: UploadProps['onChange'];\n children?: ReactNode;\n}\n\nconst resolveMessage = (\n template: UploadMessage | undefined,\n fileName: string,\n fallback: string,\n): string => {\n if (!template) return fallback.replace('{file}', fileName);\n return typeof template === 'function' ? template(fileName) : template.replace('{file}', fileName);\n};\n\n/**\n * AMS FileUploadDragger — drag-and-drop uploader.\n *\n * Ports mf-boveda's FileUploadDragger with two DS improvements:\n * - toasts use the context-safe `useAmsMessage()` (no antd v5 static warning),\n * - all copy is passed via props (i18n stays in the consumer); no default\n * upload endpoint is baked in.\n */\nexport function FileUploadDragger({\n successMessage,\n errorMessage,\n showStatusMessages = true,\n hintText = 'Click or drag a file to this area to upload',\n onUploadSuccess,\n onUploadError,\n onChange: externalOnChange,\n children,\n ...uploadProps\n}: FileUploadDraggerProps) {\n const message = useAmsMessage();\n\n const mergedProps = useMemo<UploadProps>(\n () => ({\n ...uploadProps,\n onChange(info) {\n const { status, name: fileName } = info.file;\n if (showStatusMessages) {\n if (status === 'done') {\n message.success(resolveMessage(successMessage, fileName, `${fileName} uploaded successfully.`));\n onUploadSuccess?.(info);\n } else if (status === 'error') {\n message.error(resolveMessage(errorMessage, fileName, `${fileName} failed to upload.`));\n onUploadError?.(info);\n }\n }\n externalOnChange?.(info);\n },\n }),\n [uploadProps, showStatusMessages, message, successMessage, errorMessage, onUploadSuccess, onUploadError, externalOnChange],\n );\n\n return (\n <Upload.Dragger {...mergedProps}>\n {children ?? (\n <>\n <p className=\"ant-upload-drag-icon\">\n <InboxOutlined />\n </p>\n <p className=\"ant-upload-text\">{hintText}</p>\n </>\n )}\n </Upload.Dragger>\n );\n}\n","import { Breadcrumb } from 'antd';\nimport type { BreadcrumbProps } from 'antd';\nimport type { ReactNode } from 'react';\n\nexport interface BreadcrumbItem {\n title: ReactNode;\n href?: string;\n}\n\nexport interface PageHeaderProps {\n /** Page title. Rendered as an h1. */\n title: ReactNode;\n /** Breadcrumb trail. When omitted, no breadcrumb is shown. */\n breadcrumbs?: BreadcrumbItem[];\n /** Breadcrumb separator. Defaults to \">\". */\n separator?: ReactNode;\n /** Uppercase the title (matches the b2bmx convention). Default true. */\n uppercaseTitle?: boolean;\n /** Content aligned to the right of the title (actions). */\n extra?: ReactNode;\n className?: string;\n}\n\n/**\n * AMS PageHeader — page title with an optional breadcrumb.\n *\n * Consolidates mf-boveda's Header + Breadcrums. Decoupled from react-router\n * and the boveda domain: the consumer builds the breadcrumb items (already\n * translated) and passes them in.\n */\nexport function PageHeader({\n title,\n breadcrumbs,\n separator = '>',\n uppercaseTitle = true,\n extra,\n className,\n}: PageHeaderProps) {\n return (\n <div className={className} style={{ marginBottom: 32 }}>\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 16,\n }}\n >\n <h1\n style={{\n fontSize: 20,\n fontWeight: 700,\n margin: 0,\n textTransform: uppercaseTitle ? 'uppercase' : undefined,\n }}\n >\n {title}\n </h1>\n {extra ? <div>{extra}</div> : null}\n </div>\n {breadcrumbs && breadcrumbs.length > 0 ? (\n <Breadcrumb\n separator={separator}\n items={breadcrumbs as BreadcrumbProps['items']}\n style={{ fontSize: 13, marginTop: 8 }}\n />\n ) : null}\n </div>\n );\n}\n","import { DownloadOutlined } from '@ant-design/icons';\nimport { forwardRef } from 'react';\nimport { Button } from '../Button';\nimport type { ButtonProps } from '../Button';\n\nexport interface DownloadButtonProps extends ButtonProps {\n /** Button label. Defaults to \"CSV\". */\n label?: React.ReactNode;\n}\n\n/**\n * AMS DownloadButton — a Button preset for download actions.\n *\n * Ports mf-boveda's DownloadButton: primary type + download icon + label,\n * with the full Button API available. i18n via the `label`/`children` props.\n */\nexport const DownloadButton = forwardRef<\n HTMLButtonElement | HTMLAnchorElement,\n DownloadButtonProps\n>(function DownloadButton({ label = 'CSV', icon, type = 'primary', children, ...rest }, ref) {\n return (\n <Button ref={ref} type={type} icon={icon ?? <DownloadOutlined />} {...rest}>\n {children ?? label}\n </Button>\n );\n});\n","import type { ReactNode } from 'react';\nimport { ModalDialog } from '../ModalDialog';\nimport type { ModalDialogProps } from '../ModalDialog';\n\nexport interface ConfirmModalProps\n extends Omit<ModalDialogProps, 'children'> {\n /** Body message shown to the user. */\n message?: ReactNode;\n /** Mark the confirm action as destructive (red primary button). */\n danger?: boolean;\n children?: ReactNode;\n}\n\n/**\n * AMS ConfirmModal — a confirm/cancel dialog preset built on `ModalDialog`.\n *\n * Generalizes the mf-boveda cancel/confirm modals (CancelCfdiModal, etc.):\n * inherits controlled/uncontrolled state, trigger, and async `onOk` from\n * ModalDialog. Set `danger` for destructive actions. Copy via props (i18n).\n */\nexport function ConfirmModal({\n message,\n danger = false,\n okButtonProps,\n children,\n ...rest\n}: ConfirmModalProps) {\n return (\n <ModalDialog\n okButtonProps={{ danger, ...okButtonProps }}\n {...rest}\n >\n {children ?? (message ? <p>{message}</p> : null)}\n </ModalDialog>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/kit/lib/tema.ts","../src/kit/lib/LinkBase.tsx","../src/kit/lib/useNavegarListado.ts","../src/kit/lib/iconos.ts","../src/kit/lib/explicaciones.ts","../src/kit/lib/listado.ts","../src/kit/lib/formato.ts","../src/kit/lib/fecha.ts","../src/kit/lib/bytes.ts","../src/kit/ui/SpinnerMarca.tsx","../src/kit/ui/OverlayCargando.tsx","../src/kit/lib/useAccionConSpinner.tsx","../src/kit/lib/preferenciasTabla.ts","../src/kit/lib/useTablaPreferencias.ts","../src/kit/lib/posicionPopover.ts","../src/kit/ui/clases.ts","../src/kit/ui/PopoverHover.tsx","../src/kit/ui/InfoExplicacion.tsx","../src/kit/ui/Insignia.tsx","../src/kit/ui/Avisos.tsx","../src/kit/ui/BotonAccionAviso.tsx","../src/kit/ui/EnlaceNav.tsx","../src/kit/lib/panelPrefs.ts","../src/kit/ui/SidebarColapsable.tsx","../src/kit/lib/tablaMarco.ts","../src/kit/tabla/MarcoTabla.tsx","../src/kit/ui/CascaronApp.tsx","../src/kit/ui/Migas.tsx","../src/kit/ui/Dialogo.tsx","../src/kit/ui/PaginaListado.tsx","../src/kit/ui/ModalPanel.tsx","../src/kit/ui/Pestanas.tsx","../src/kit/ui/PantallaAcceso.tsx","../src/kit/ui/PantallaCargando.tsx","../src/kit/ui/FechaHoraLocal.tsx","../src/kit/ui/PaginaContenido.tsx","../src/kit/ui/PaginadorLocal.tsx","../src/kit/ui/PaginadorUrl.tsx","../src/kit/ui/BarraListado.tsx","../src/kit/ui/EncabezadoOrdenUrl.tsx","../src/kit/tabla/celdas.tsx","../src/kit/ui/TablaConfigurable.tsx","../src/kit/ui/CamposFiltro.tsx","../src/kit/ui/Metrica.tsx","../src/kit/tabla/AccionesFila.tsx"],"names":["LinkBase","createContext","useContext","partes","jsx","useState","useCallback","useEffect","jsxs","Fragment","useId","useRef","useLayoutEffect","col"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Tema (paleta + marca) por omision. Basado en `web/src/lib/tema.ts` de la plataforma SIN la llamada a su backend:\n * se conservan los NOMBRES de los tokens (`color_primario`, `badge_exito`...). Los valores por omision son la MARCA\n * AMS (rojo), que coinciden con el `:root` de `tokens.css` (deben mantenerse sincronizados). `variablesDeTema` es la\n * funcion de `app/layout.tsx` que inyecta la paleta como variables CSS en `<html style=...>`.\n *\n * Como una marca sobreescribe los tokens (3 formas, de mas a menos recomendada):\n * 1. Runtime: construye un `Tema` propio (de tu API/config) y pasa `variablesDeTema(tema)` al `style` de `<html>`.\n * 2. Estatica: un CSS de marca importado despues de globals.css con `:root { --tema-primario: #...; ... }`.\n * 3. Cambiar `TEMA_DEFAULT` y `:root` de globals.css a la vez (deben coincidir).\n * Nunca cambies colores dentro de un componente.\n */\nimport type { CSSProperties } from \"react\";\n\nexport type Tema = {\n logo_url: string | null;\n /** Icono de pestana (ruta o URL); sin valor rige el de la marca por omision. */\n favicon_url?: string | null;\n color_primario: string;\n color_primario_oscuro: string;\n /** Acento de marca (reflejo de la pantalla de acceso, spinner); sin valor rige el del tema por omision. */\n color_acento?: string;\n /**\n * Rojo de PELIGRO (acciones destructivas y texto de error). Reservado: cuando la marca es roja, el boton\n * primario va en neutro oscuro y este rojo queda solo para destructivos/error (ver docs/criterio-color-acciones.md).\n */\n color_peligro: string;\n color_fondo: string;\n color_texto: string;\n color_borde: string;\n badge_exito: string;\n badge_advertencia: string;\n badge_error: string;\n badge_neutro: string;\n};\n\nexport const NOMBRE_PRODUCTO_DEFAULT = \"Backoffice\";\n\n/**\n * Tema por omision = marca AMS (rojo). Mismos valores que el `:root` de `tokens.css` (deben coincidir).\n * El rojo es la identidad/acento; el boton primario va en neutro oscuro y el rojo queda reservado a peligro\n * (ver docs/criterio-color-acciones.md). Una marca distinta sobreescribe estos tokens via `variablesDeTema`.\n */\nexport const TEMA_DEFAULT: Tema = {\n logo_url: null,\n color_primario: \"#A72432\",\n color_primario_oscuro: \"#8B1D28\",\n color_acento: \"#C9414D\",\n color_peligro: \"#A72432\",\n color_fondo: \"#ffffff\",\n color_texto: \"#0b1f33\",\n color_borde: \"#e2e8f0\",\n badge_exito: \"#e6f4ea\",\n badge_advertencia: \"#fdf1de\",\n badge_error: \"#fbe9e9\",\n badge_neutro: \"#ececec\",\n};\n\n/**\n * Variables CSS del tema como `style` inline en el `<html>`. Sobreescriben los defaults de `globals.css`; con el tema por\n * omision son un no-op visual. (Extraido de `app/layout.tsx`.)\n */\nexport function variablesDeTema(tema: Tema): CSSProperties {\n return {\n ...(tema.color_acento ? { \"--tema-acento\": tema.color_acento } : {}),\n // El spinner de marca se pinta con el logo; sin logo rige el icono neutro de `globals.css`.\n ...(tema.logo_url ? { \"--tema-logo-spinner\": `url(\"${tema.logo_url}\")` } : {}),\n \"--tema-primario\": tema.color_primario,\n \"--tema-primario-oscuro\": tema.color_primario_oscuro,\n \"--tema-peligro\": tema.color_peligro,\n \"--tema-fondo\": tema.color_fondo,\n \"--tema-texto\": tema.color_texto,\n \"--tema-borde\": tema.color_borde,\n \"--tema-badge-exito\": tema.badge_exito,\n \"--tema-badge-advertencia\": tema.badge_advertencia,\n \"--tema-badge-error\": tema.badge_error,\n \"--tema-badge-neutro\": tema.badge_neutro,\n } as CSSProperties;\n}\n","\"use client\";\n\nimport {\n createContext,\n createElement,\n forwardRef,\n useContext,\n type AnchorHTMLAttributes,\n type ComponentType,\n type ReactNode,\n} from \"react\";\n\n/**\n * Framework-agnostic link.\n *\n * The kit used `next/link` directly, which a publishable library cannot depend on. Components now\n * render `LinkBase`, which by default is a plain `<a href>`. A consumer that wants client-side\n * routing (Next's <Link>, React Router's <Link>, etc.) injects their component once via\n * `LinkComponentProvider`; everything inside then routes through it, with no component API change.\n */\nexport type LinkBaseProps = {\n href: string;\n children: ReactNode;\n} & Omit<AnchorHTMLAttributes<HTMLAnchorElement>, \"href\">;\n\n/** Shape of an injected link component: anything that accepts `href` + anchor props. */\nexport type LinkComponent = ComponentType<LinkBaseProps>;\n\nconst LinkComponentContext = createContext<LinkComponent | null>(null);\n\nexport const LinkComponentProvider = LinkComponentContext.Provider;\n\nexport const LinkBase = forwardRef<HTMLAnchorElement, LinkBaseProps>(function LinkBase(\n { href, children, ...rest },\n ref,\n) {\n const Injected = useContext(LinkComponentContext);\n if (Injected) {\n // The injected component owns rendering (e.g. Next/React Router Link); forward everything.\n return createElement(Injected, { href, children, ...rest });\n }\n return (\n <a ref={ref} href={href} {...rest}>\n {children}\n </a>\n );\n});\n","\"use client\";\n\nimport { createContext, useContext } from \"react\";\n\n/**\n * Framework-agnostic listing navigation (option A of the migration).\n *\n * The kit originally read Next's router (usePathname/useRouter/useSearchParams). A publishable\n * library cannot depend on Next, so navigation is injected via React context instead: the consumer\n * wires `ListadoNavProvider` to whatever drives their URL/query state (Next's router, React Router,\n * or plain component state). The listing components (BarraListado, PaginadorUrl, EncabezadoOrdenUrl)\n * keep their public API unchanged — only the source of `ir`/`params`/`pendiente` moved to context.\n *\n * `cambios` semantics are preserved: apply the given key/value changes to the current query; a null\n * or empty value clears the key; any non-page change resets to page 1 (see hrefListado in listado.ts).\n */\nexport type CambiosListado = Record<string, string | null | undefined>;\n\nexport type ListadoNav = {\n /** Apply `cambios` to the current query. `scroll` hints the consumer to scroll to top (page changes). */\n ir: (cambios: CambiosListado, opciones?: { scroll?: boolean }) => void;\n /** True while a navigation is in flight, so controls can show a pending indicator. */\n pendiente: boolean;\n /** The current query string params (same shape as URLSearchParams). */\n params: URLSearchParams;\n};\n\nconst ListadoNavContext = createContext<ListadoNav | null>(null);\n\nexport const ListadoNavProvider = ListadoNavContext.Provider;\n\n/**\n * Read the listing navigation injected by the nearest `ListadoNavProvider`. Throws a clear error if\n * used outside a provider, so misuse fails loudly instead of silently doing nothing.\n */\nexport function useNavegarListado(): ListadoNav {\n const ctx = useContext(ListadoNavContext);\n if (!ctx) {\n throw new Error(\n \"useNavegarListado must be used within a <ListadoNavProvider>. Wrap your listing screen and \" +\n \"provide { ir, pendiente, params } connected to your router or local state.\",\n );\n }\n return ctx;\n}\n","/**\n * MAPA SEMANTICO CENTRAL DE ICONOGRAFIA (kit-ui-plataforma).\n *\n * Extraido de `web/src/lib/iconos.ts` de la plataforma: las constantes genericas (ICONO_NAV_*, ICONO_ALTA, ICONO_BAJA,\n * ICONO_FILTRO, ICONO_COLUMNAS, ICONO_ACCIONES_FILA, ICONOS_SEMAFORO...) se copiaron TAL CUAL (mismo nombre, mismo glifo de\n * Lucide). Se quitaron las propias del dominio de la plataforma original. Las constantes ICONO_COL_*, ICONO_KPI_*,\n * ICONO_AVISO/ERROR/OK/SEGURIDAD y ICONOS_ESTATUS son alias NEUTROS de conceptos que alli tienen nombre de dominio (mismos\n * glifos). Al final, \"EXTENSIONES DEL KIT\": conceptos del Backoffice que la plataforma no tiene; solo reutilizan glifos ya\n * importados aqui, nunca introducen una libreria nueva.\n *\n * REGLAS (obligatorias):\n * - Libreria UNICA: `lucide-react` (trazo de 2 px). Ninguna otra libreria de iconos, ningun emoji, ningun SVG suelto.\n * - Ninguna pantalla ni componente importa de `lucide-react` directamente: importa la constante `ICONO_*` de este\n * archivo. Un concepto nuevo se agrega AQUI una sola vez (y se documenta en references/iconos.md).\n * - Tamanos: `TAMANO_BADGE` (16) en contextos densos (insignias, tablas, titulos de tarjeta); `TAMANO_BOTON` (20) en\n * botones, menu lateral y titulo de pagina; el icono (i) es de 14. Iconos pequenos de apoyo: 12-13.\n * - Color: hereda `currentColor`; jamas un color fijo nuevo.\n * - Accesibilidad: decorativo -> `aria-hidden=\"true\"`; unico contenido de un control -> `aria-label` y `title`.\n * - Un icono por concepto: dos conceptos distintos no comparten glifo (p. ej. Dashboard=Activity, Salud=Gauge).\n */\nimport {\n Activity,\n AlertTriangle,\n ArrowDown,\n ArrowLeft,\n ArrowRight,\n ArrowUp,\n ArrowUpDown,\n Ban,\n BarChart3,\n Bell,\n BellOff,\n BellRing,\n BookOpen,\n Boxes,\n Briefcase,\n Building2,\n Calendar,\n CalendarClock,\n CalendarRange,\n Check,\n CheckCircle2,\n Circle,\n Clock,\n Coins,\n Columns3,\n Copy,\n Download,\n Ellipsis,\n Eye,\n EyeOff,\n FileSpreadsheet,\n FileText,\n Filter,\n FolderOpen,\n Gauge,\n GripVertical,\n Hash,\n History,\n Info,\n KeyRound,\n Layers,\n LayoutGrid,\n Link2,\n Loader2,\n Lock,\n LogIn,\n LogOut,\n type LucideIcon,\n Mail,\n MailPlus,\n Menu,\n Package,\n Palette,\n PanelLeftClose,\n PanelLeftOpen,\n PauseCircle,\n Pencil,\n PlayCircle,\n PlusCircle,\n RefreshCw,\n RotateCcw,\n Rows2,\n Rows4,\n Save,\n Search,\n SlidersHorizontal,\n ShieldAlert,\n ShieldCheck,\n Sparkles,\n Table2,\n Tag,\n Timer,\n Trash2,\n TrendingUp,\n User,\n UserPlus,\n UserX,\n Users,\n Wallet,\n X,\n XCircle,\n} from \"lucide-react\";\n\nexport const TAMANO_BADGE = 16;\nexport const TAMANO_BOTON = 20;\n\n/** Icono por defecto cuando un tipo/estatus no esta en el mapa: nunca un componente roto por un valor nuevo. */\nexport const ICONO_DEFAULT: LucideIcon = Circle;\n\n/** Tipo publico del icono (alias de `LucideIcon`) para tipar props sin importar de `lucide-react`. */\nexport type LucideIconType = LucideIcon;\n\n// ── Navegacion lateral (mismos iconos que el titulo de la pantalla destino) ────────────────────────────────────────\nexport const ICONO_NAV_DASHBOARD = Activity; // Dashboard / Inicio operativo\nexport const ICONO_NAV_SALUD = Gauge; // Salud del sistema (distinto de Dashboard)\nexport const ICONO_NAV_ANALITICA = BarChart3;\nexport const ICONO_NAV_ENTIDADES = Users;\nexport const ICONO_NAV_INVITACIONES = MailPlus;\nexport const ICONO_NAV_ETIQUETAS = Tag;\nexport const ICONO_NAV_JOBS = Briefcase;\nexport const ICONO_NAV_TEMA = Palette;\nexport const ICONO_NAV_CONFIGURACION = SlidersHorizontal;\nexport const ICONO_NAV_API_KEYS = KeyRound;\nexport const ICONO_NAV_BITACORA = History; // historial de cambios / auditoria\nexport const ICONO_NAV_NOTIFICACIONES = BellRing;\nexport const ICONO_NAV_MANUAL = BookOpen; // manual de usuario / documentacion\nexport const ICONO_NAV_CLIENTE = KeyRound;\nexport const ICONO_NAV_EXTRACCIONES = FileSpreadsheet;\n\n// ── Sesion ──────────────────────────────────────────────────────────────────────────────────────────────────────────\nexport const ICONO_CERRAR_SESION = LogOut;\nexport const ICONO_INICIAR_SESION = LogIn;\n\n// ── Chrome del menu lateral ─────────────────────────────────────────────────────────────────────────────────────────\nexport const ICONO_NAV_COLAPSAR = PanelLeftClose;\nexport const ICONO_NAV_EXPANDIR = PanelLeftOpen;\nexport const ICONO_NAV_MENU_MOVIL = Menu;\nexport const ICONO_CERRAR = X; // cerrar modal / panel / cajon\n\n// ── Acciones (icono ANTES del texto en todo boton) ──────────────────────────────────────────────────────────────────\nexport const ICONO_ALTA = PlusCircle; // \"Nuevo ...\" / crear\nexport const ICONO_GENERAR = Sparkles;\nexport const ICONO_GUARDAR = Save;\nexport const ICONO_EDITAR = Pencil;\nexport const ICONO_BAJA = Trash2; // eliminar / dar de baja (siempre con confirmacion)\nexport const ICONO_DESHABILITAR = UserX;\nexport const ICONO_INACTIVAR = PauseCircle;\nexport const ICONO_REACTIVAR_ETIQUETA = PlayCircle;\nexport const ICONO_REACTIVAR = RotateCcw;\nexport const ICONO_RESTABLECER = RotateCcw;\nexport const ICONO_REINTENTAR = RefreshCw;\nexport const ICONO_COPIAR = Copy;\nexport const ICONO_LINK = Link2;\nexport const ICONO_DESCARGAR = Download;\nexport const ICONO_EXPORTAR = FileSpreadsheet; // exportar a hoja de calculo\nexport const ICONO_EXPORTAR_CSV = Download;\nexport const ICONO_CONFIRMAR = CheckCircle2;\nexport const ICONO_VOLVER = ArrowLeft;\nexport const ICONO_VER_TODOS = ArrowRight;\nexport const ICONO_ROTAR_KEY = RotateCcw;\nexport const ICONO_REVOCAR_KEY = Ban;\nexport const ICONO_API_KEY = KeyRound;\nexport const ICONO_EMAIL = Mail;\nexport const ICONO_INVITACION_GENERICA = UserPlus;\nexport const ICONO_SEGURIDAD = ShieldCheck;\nexport const ICONO_CAMPANA = Bell;\nexport const ICONO_SILENCIAR = BellOff;\n\n// ── Filtros, busqueda, orden y paginacion ───────────────────────────────────────────────────────────────────────────\nexport const ICONO_FILTRO = Filter;\nexport const ICONO_BUSCAR = Search; // lupa dentro del campo de busqueda\nexport const ICONO_LIMPIAR = X; // limpiar el campo\nexport const ICONO_SELECCIONADO = Check;\nexport const ICONO_ORDENAR_ASC = ArrowUp;\nexport const ICONO_ORDENAR_DESC = ArrowDown;\nexport const ICONO_ORDENAR_NEUTRO = ArrowUpDown;\nexport const ICONO_PAGINA_ANTERIOR = ArrowLeft;\nexport const ICONO_PAGINA_SIGUIENTE = ArrowRight;\nexport const ICONO_VISTA_TABLA = Table2;\nexport const ICONO_VISTA_TARJETAS = LayoutGrid;\n\n// ── Tabla configurable / marco de tabla ─────────────────────────────────────────────────────────────────────────────\nexport const ICONO_ARRASTRAR_COLUMNA = GripVertical;\nexport const ICONO_COLUMNAS = Columns3;\nexport const ICONO_COLUMNA_VISIBLE = Eye;\nexport const ICONO_COLUMNA_OCULTA = EyeOff;\nexport const ICONO_ACCIONES_FILA = Ellipsis; // menu \"...\" (3 o mas acciones por fila)\nexport const ICONO_DENSIDAD_COMPACTA = Rows4;\nexport const ICONO_DENSIDAD_COMODA = Rows2;\n\n// ── Estado de carga / ayuda ─────────────────────────────────────────────────────────────────────────────────────────\nexport const ICONO_CARGANDO = Loader2; // siempre con `animate-spin motion-reduce:animate-none`\nexport const ICONO_INFO_EXPLICACION = Info; // el (i), 14 px, gris #9a9999\n\n// ── Columnas tipicas (icono antes del texto del encabezado) ─────────────────────────────────────────────────────────\nexport const ICONO_COL_CODIGO = Hash;\nexport const ICONO_COL_NOMBRE = Building2;\nexport const ICONO_COL_ESTADO = Activity;\nexport const ICONO_COL_MECANISMO = KeyRound;\nexport const ICONO_COL_TOTAL = Wallet;\nexport const ICONO_COL_FECHA = CalendarRange;\nexport const ICONO_COL_FECHA_HORA = CalendarClock;\nexport const ICONO_COL_ETIQUETA = Tag;\nexport const ICONO_COL_USUARIO = User;\nexport const ICONO_COL_DOCUMENTO = FileText;\nexport const ICONO_PERIODO = CalendarRange;\nexport const ICONO_VIGENCIA = Calendar;\nexport const ICONO_DURACION = Timer;\nexport const ICONO_UBICACION = FolderOpen;\n\n// ── Estatus: UN icono por estado (mapas) ────────────────────────────────────────────────────────────────────────────\n/** Estatus de proceso. Completado=CheckCircle2, en curso=Clock, pendiente=Circle, aviso=AlertTriangle, fallido=XCircle. */\nexport const ICONOS_ESTATUS: Record<string, LucideIcon> = {\n pendiente: Circle,\n procesando: Clock,\n hecha: CheckCircle2,\n gap: AlertTriangle,\n fallida: XCircle,\n};\n\nexport function iconoDeEstatus(estado: string): LucideIcon {\n return ICONOS_ESTATUS[estado] ?? ICONO_DEFAULT;\n}\n\n/** Semaforo: verde=CheckCircle2, ambar=AlertTriangle, rojo=XCircle (y siempre con texto, nunca solo color). */\nexport const ICONOS_SEMAFORO: Record<string, LucideIcon> = {\n verde: CheckCircle2,\n ambar: AlertTriangle,\n rojo: XCircle,\n};\nexport const ETIQUETAS_SEMAFORO: Record<string, string> = {\n verde: \"verde (en linea)\",\n ambar: \"ambar (advertencia)\",\n rojo: \"rojo (critico)\",\n};\nexport function iconoDeSemaforo(color: string): LucideIcon {\n return ICONOS_SEMAFORO[color] ?? Circle;\n}\nexport function etiquetaSemaforo(color: string): string {\n return ETIQUETAS_SEMAFORO[color] ?? color;\n}\n\nexport const ICONO_AVISO = AlertTriangle;\nexport const ICONO_ERROR = XCircle;\nexport const ICONO_OK = CheckCircle2;\n\n// ── Metricas / KPI (icono de 12-13 px junto a la etiqueta de la tarjeta) ───────────────────────────────────────────\nexport const ICONO_KPI_RITMO = TrendingUp;\nexport const ICONO_KPI_RENDIMIENTO = Gauge;\nexport const ICONO_KPI_CONTEO = Boxes;\nexport const ICONO_KPI_CREDENCIALES = KeyRound;\nexport const ICONO_KPI_ALERTA = ShieldAlert;\nexport const ICONO_KPI_CONSUMO = Coins;\nexport const ICONO_KPI_BLOQUEO = Lock;\n\n// ── EXTENSIONES DEL KIT (Backoffice): conceptos que la plataforma original no tiene ────────────────────────────────\n// Solo reutilizan glifos ya importados arriba. Si necesitas otro concepto: agregalo aqui, una sola vez.\nexport const ICONO_NAV_PLANES = Layers; // catalogo de planes\nexport const ICONO_NAV_PAQUETES = Package; // catalogo de paquetes (glifo nuevo: ninguno de los existentes encaja)\nexport const ICONO_NAV_ACCESOS = ShieldCheck; // gestion de accesos y roles\nexport const ICONO_NAV_USUARIOS = Users;\nexport const ICONO_LOGIN_MICROSOFT = LogIn; // boton \"Iniciar sesion con Microsoft 365\" (sin logos de terceros)\n","/**\n * Catalogo unico de explicaciones en sitio (el patron del icono (i)).\n *\n * LINEAMIENTO OBLIGATORIO: cada metrica, tarjeta, grafica, lista, encabezado de columna de tabla e insignia de estatus\n * de CUALQUIER pantalla referencia un id de este catalogo (nunca texto en linea) y responde siempre las mismas 4\n * preguntas: Que es, Como se calcula, De donde sale, Como leerlo. Cada texto se redacta leyendo el codigo que produce el\n * valor (no adivinando).\n *\n * Reglas de formato (verificables con `verificarCatalogo()` abajo): id `modulo.id` en minusculas `[a-z0-9_]`; cada\n * respuesta <= 320 caracteres; sin comillas dobles, barras invertidas ni saltos de linea; espanol neutro y profesional.\n *\n * Los ids `plataforma.*` los usan los componentes del kit (tabla, listado, rol): NO los borres ni los renombres.\n * Agrega los de tu producto con su propio prefijo (`planes.*`, `accesos.*`, `inicio.*`).\n */\n\nexport type Explicacion = {\n titulo: string;\n que_es: string;\n como_se_calcula: string;\n de_donde_sale: string;\n como_leerlo: string;\n};\n\nexport const EXPLICACIONES = {\n // ───────────────────────────── plataforma.* (usados por los componentes del kit) ─────────────────────────────\n \"plataforma.rol\": {\n titulo: \"Rol del usuario\",\n que_es: \"Tu nivel de acceso en este sistema, por ejemplo administrador, operador o consulta.\",\n como_se_calcula: \"Se resuelve al iniciar sesión según tu asignación; no se calcula.\",\n de_donde_sale: \"Asignación de rol del usuario en el directorio de acceso.\",\n como_leerlo: \"Determina qué módulos ves y qué acciones puedes ejecutar en cada tabla.\",\n },\n \"plataforma.listado_resultados\": {\n titulo: \"Resultados del listado\",\n que_es: \"Cuántas filas cumplen la búsqueda y los filtros actuales frente al total del listado.\",\n como_se_calcula: \"Se cuentan las filas cuyo texto contiene lo buscado, sin distinguir mayúsculas ni acentos, y que cumplen cada filtro. La tabla muestra una página de 25, 50 o 100 de ellas.\",\n de_donde_sale: \"Lista que ya trae la pantalla; la búsqueda, los filtros, el orden y la página viajan en la dirección (URL).\",\n como_leerlo: \"Si dice N en total no hay filtro activo. Copiar la dirección comparte la misma vista.\",\n },\n \"plataforma.tabla_columnas\": {\n titulo: \"Columnas de la tabla\",\n que_es: \"Lista para mostrar u ocultar las columnas de esta tabla que no están fijas. Las columnas de identidad y la de acciones siempre se ven.\",\n como_se_calcula: \"Cada casilla desmarcada oculta esa columna en pantalla; no cambia los datos, el orden, los filtros ni lo que se exporta.\",\n de_donde_sale: \"Preferencia guardada en este navegador, por tabla y por usuario. Restablecer la borra y vuelve a mostrar todas las columnas con la densidad cómoda.\",\n como_leerlo: \"Si falta una columna que esperabas, revisa esta lista. Con el almacenamiento del navegador bloqueado (modo privado) la elección dura solo mientras la página siga abierta.\",\n },\n \"plataforma.tabla_densidad\": {\n titulo: \"Densidad de la tabla\",\n que_es: \"Alto de las filas: compacta muestra más filas por pantalla; cómoda deja más aire entre ellas.\",\n como_se_calcula: \"Compacta reduce el relleno vertical de cada celda; no cambia el texto ni las columnas.\",\n de_donde_sale: \"Preferencia guardada en este navegador, por tabla y por usuario, junto con las columnas ocultas.\",\n como_leerlo: \"La tabla se desplaza dentro de su propio marco: la barra horizontal queda al pie de la pantalla, el encabezado arriba y las columnas de identidad y acciones fijas a los lados. Shift + rueda del ratón desplaza a lo ancho.\",\n },\n\n // ───────────────────────────── ejemplos del Backoffice (examples/) ─────────────────────────────\n \"inicio.planes_activos\": {\n titulo: \"Planes activos\",\n que_es: \"Número de planes del catálogo que hoy se pueden contratar.\",\n como_se_calcula: \"Conteo de planes con estado Activo; los borradores y los archivados no cuentan.\",\n de_donde_sale: \"Catálogo de planes del backoffice (ejemplo con datos ficticios).\",\n como_leerlo: \"Un plan archivado deja de contar aunque tenga clientes vigentes; esos clientes conservan su plan hasta renovar.\",\n },\n \"inicio.paquetes\": {\n titulo: \"Paquetes\",\n que_es: \"Número de paquetes de consumo definidos en el catálogo.\",\n como_se_calcula: \"Conteo de paquetes registrados, sin importar su estado.\",\n de_donde_sale: \"Catálogo de paquetes del backoffice (ejemplo con datos ficticios).\",\n como_leerlo: \"Un paquete puede estar asociado a varios planes; aquí se cuenta una sola vez.\",\n },\n \"inicio.accesos_vigentes\": {\n titulo: \"Accesos vigentes\",\n que_es: \"Usuarios con acceso al backoffice que no están suspendidos ni vencidos.\",\n como_se_calcula: \"Conteo de usuarios con estado Activo y fecha de vencimiento futura o sin vencimiento.\",\n de_donde_sale: \"Registro de accesos del backoffice (ejemplo con datos ficticios).\",\n como_leerlo: \"Un usuario con rol de solo consulta cuenta igual que uno administrador.\",\n },\n \"inicio.cobertura\": {\n titulo: \"Cobertura del catálogo\",\n que_es: \"Porcentaje de planes que ya tienen al menos un paquete asignado.\",\n como_se_calcula: \"Planes con al menos un paquete entre planes activos, por 100.\",\n de_donde_sale: \"Relación plan-paquete del catálogo (ejemplo con datos ficticios).\",\n como_leerlo: \"Menos de 100 % indica planes sin paquete: no se pueden vender hasta que se les asigne uno.\",\n },\n \"inicio.resumen_catalogo\": {\n titulo: \"Resumen del catálogo\",\n que_es: \"Planes agrupados por estado, con el total de paquetes que suman.\",\n como_se_calcula: \"Cada plan cae en un solo estado; los paquetes de una fila son la suma de los paquetes de sus planes.\",\n de_donde_sale: \"Catálogo de planes y paquetes del backoffice (ejemplo con datos ficticios).\",\n como_leerlo: \"Un paquete compartido por dos planes se cuenta una vez por cada plan.\",\n },\n \"planes.col_codigo\": {\n titulo: \"Código\",\n que_es: \"Identificador corto y estable del plan.\",\n como_se_calcula: \"Se captura al crear el plan; no se calcula ni se puede repetir.\",\n de_donde_sale: \"Catálogo de planes (ejemplo con datos ficticios).\",\n como_leerlo: \"Se usa en integraciones y reportes; el nombre comercial puede cambiar, el código no.\",\n },\n \"planes.col_nombre\": {\n titulo: \"Nombre\",\n que_es: \"Nombre comercial del plan tal como lo ve el cliente.\",\n como_se_calcula: \"Se captura al crear o editar el plan; no se calcula.\",\n de_donde_sale: \"Catálogo de planes (ejemplo con datos ficticios).\",\n como_leerlo: \"La búsqueda ignora mayúsculas y acentos.\",\n },\n \"planes.col_precio\": {\n titulo: \"Precio mensual\",\n que_es: \"Precio de lista del plan por mes, en pesos, sin impuestos.\",\n como_se_calcula: \"Se captura al crear o editar el plan; no se calcula.\",\n de_donde_sale: \"Catálogo de planes (ejemplo con datos ficticios).\",\n como_leerlo: \"Es precio de lista: un contrato puede tener un descuento que no se refleja aquí.\",\n },\n \"planes.col_estado\": {\n titulo: \"Estado del plan\",\n que_es: \"Situación del plan en el catálogo: Activo, Borrador o Archivado.\",\n como_se_calcula: \"Lo fija el administrador al publicar o archivar; no se calcula.\",\n de_donde_sale: \"Catálogo de planes (ejemplo con datos ficticios).\",\n como_leerlo: \"Solo los planes Activos se pueden contratar. Archivado conserva el historial pero no admite altas nuevas.\",\n },\n \"planes.col_actualizado\": {\n titulo: \"Actualizado\",\n que_es: \"Fecha y hora de la última modificación del plan, en tu hora local.\",\n como_se_calcula: \"Se registra en UTC al guardar cambios y el navegador la convierte a tu zona horaria.\",\n de_donde_sale: \"Bitácora de cambios del catálogo (ejemplo con datos ficticios).\",\n como_leerlo: \"Cambiar solo el estado también actualiza esta fecha.\",\n },\n \"planes.estado_activo\": {\n titulo: \"Activo\",\n que_es: \"El plan está publicado y se puede contratar.\",\n como_se_calcula: \"Estado asignado al publicar el plan.\",\n de_donde_sale: \"Catálogo de planes (ejemplo con datos ficticios).\",\n como_leerlo: \"Para retirarlo del catálogo, archívalo; no lo borres.\",\n },\n \"planes.estado_borrador\": {\n titulo: \"Borrador\",\n que_es: \"El plan se está preparando y aún no es visible para contratar.\",\n como_se_calcula: \"Estado inicial de todo plan nuevo.\",\n de_donde_sale: \"Catálogo de planes (ejemplo con datos ficticios).\",\n como_leerlo: \"Publica el plan cuando tenga precio y al menos un paquete.\",\n },\n \"planes.estado_archivado\": {\n titulo: \"Archivado\",\n que_es: \"El plan se retiró del catálogo; conserva su historial.\",\n como_se_calcula: \"Estado asignado al archivar un plan activo.\",\n de_donde_sale: \"Catálogo de planes (ejemplo con datos ficticios).\",\n como_leerlo: \"No admite altas nuevas; los clientes existentes conservan su plan hasta renovar.\",\n },\n} as const satisfies Record<string, Explicacion>;\n\nexport type ExplicacionId = keyof typeof EXPLICACIONES;\n\n/** Entrada del catalogo; un id desconocido (solo posible con un cast) falla de forma visible. */\nexport function explicacionDe(id: ExplicacionId): Explicacion {\n const entrada: Explicacion | undefined = (EXPLICACIONES as Record<string, Explicacion>)[id];\n if (!entrada) throw new Error(`Explicación desconocida: ${id}`);\n return entrada;\n}\n\n/** Devuelve la lista de violaciones de formato del catalogo (vacia = correcto). Util como prueba unitaria. */\nexport function verificarCatalogo(): string[] {\n const problemas: string[] = [];\n for (const [id, e] of Object.entries(EXPLICACIONES as Record<string, Explicacion>)) {\n if (!/^[a-z0-9_]+\\.[a-z0-9_]+$/.test(id)) problemas.push(`${id}: id invalido`);\n for (const [campo, texto] of Object.entries(e)) {\n if (texto.length > 320) problemas.push(`${id}.${campo}: mas de 320 caracteres`);\n if (/[\"\\\\\\n]/.test(texto)) problemas.push(`${id}.${campo}: comillas dobles, barra invertida o salto de linea`);\n }\n }\n return problemas;\n}\n","/**\n * Estado de un listado (busqueda, filtros, orden, pagina y tamano) que vive en la URL (change\n * `ux-listados-compactos`). Funciones puras: el Server Component de cada pantalla lee los `searchParams`, aplica\n * el listado sobre la lista ya traida de la API y pinta SOLO la pagina visible; la barra (`BarraListado`), el\n * paginador (`PaginadorUrl`) y los encabezados ordenables (`EncabezadoOrdenUrl`) solo reescriben la URL.\n *\n * Por que en el servidor de Next y no en el backend: cada lista esta acotada (decenas a cientos de filas) y la busqueda sin acentos obligaria a la API a un scan de todos\n * modos. Aqui el navegador recibe una sola pagina (25/50/100 filas) y el trabajo por fila (etiquetas, enlaces) se\n * hace solo para esa pagina.\n */\n\nexport const TAMANOS_LISTADO = [25, 50, 100] as const;\nexport const TAMANO_LISTADO_DEFAULT = 25;\n\nexport type Direccion = \"asc\" | \"desc\";\nexport type ParamsUrl = Record<string, string | string[] | undefined>;\n\nexport type EstadoListado = {\n q: string;\n pagina: number;\n tamano: number;\n orden: string;\n dir: Direccion;\n /** Solo los filtros declarados por la pantalla y con valor. */\n filtros: Record<string, string>;\n};\n\nexport type OpcionesListado = {\n /** Claves de filtro que la pantalla entiende (p. ej. `estado`, `mecanismo`). */\n filtros: readonly string[];\n /** Claves de orden validas. */\n ordenes: readonly string[];\n ordenDefault: string;\n dirDefault?: Direccion;\n};\n\nexport type DefListado<T> = {\n /** Texto en el que busca `q` (nombre, codigo, etc.). */\n texto: (item: T) => string;\n filtrar?: (item: T, filtros: Record<string, string>) => boolean;\n /** Valor por el que ordena cada clave de orden. `null`/`undefined`/`\"\"`/`NaN` = ausente (siempre al final). */\n valoresOrden: Record<string, (item: T) => string | number | null | undefined>;\n};\n\n/** Minusculas, sin acentos (NFD sin marcas combinantes) y espacios colapsados: \" PEÑA Ávila\" -> \"pena avila\". */\nexport function normalizarTexto(s: string): string {\n return s\n .normalize(\"NFD\")\n .replace(/[̀-ͯ]/g, \"\")\n .toLowerCase()\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nfunction primero(v: string | string[] | undefined): string {\n return (Array.isArray(v) ? v[0] : v) ?? \"\";\n}\n\nexport function leerListado(sp: ParamsUrl, opc: OpcionesListado): EstadoListado {\n const pagina = Number.parseInt(primero(sp.pagina), 10);\n const tamano = Number.parseInt(primero(sp.tamano), 10);\n const orden = primero(sp.orden);\n const dir = primero(sp.dir);\n const filtros: Record<string, string> = {};\n for (const clave of opc.filtros) {\n const valor = primero(sp[clave]).trim();\n if (valor) filtros[clave] = valor;\n }\n return {\n q: primero(sp.q).trim(),\n pagina: Number.isFinite(pagina) && pagina >= 1 ? pagina : 1,\n tamano: (TAMANOS_LISTADO as readonly number[]).includes(tamano) ? tamano : TAMANO_LISTADO_DEFAULT,\n orden: opc.ordenes.includes(orden) ? orden : opc.ordenDefault,\n dir: dir === \"asc\" || dir === \"desc\" ? dir : (opc.dirDefault ?? \"asc\"),\n filtros,\n };\n}\n\nfunction ausente(v: unknown): boolean {\n return v === undefined || v === null || v === \"\" || (typeof v === \"number\" && Number.isNaN(v));\n}\n\nexport function aplicarListado<T>(items: readonly T[], estado: EstadoListado, def: DefListado<T>) {\n const aguja = normalizarTexto(estado.q);\n const filtrados = items.filter(\n (it) =>\n (!aguja || normalizarTexto(def.texto(it)).includes(aguja)) &&\n (!def.filtrar || def.filtrar(it, estado.filtros)),\n );\n const valor = def.valoresOrden[estado.orden];\n if (valor) {\n const factor = estado.dir === \"asc\" ? 1 : -1;\n // Array.prototype.sort es estable: a igualdad conserva el orden de llegada.\n filtrados.sort((a, b) => {\n const va = valor(a);\n const vb = valor(b);\n if (ausente(va) && ausente(vb)) return 0;\n if (ausente(va)) return 1;\n if (ausente(vb)) return -1;\n if (typeof va === \"number\" && typeof vb === \"number\") return (va - vb) * factor;\n return String(va).localeCompare(String(vb), \"es\", { sensitivity: \"base\" }) * factor;\n });\n }\n const totalPaginas = Math.max(1, Math.ceil(filtrados.length / estado.tamano));\n const pagina = Math.min(estado.pagina, totalPaginas);\n const inicio = (pagina - 1) * estado.tamano;\n return {\n itemsPagina: filtrados.slice(inicio, inicio + estado.tamano),\n totalFiltrado: filtrados.length,\n total: items.length,\n pagina,\n totalPaginas,\n };\n}\n\n/**\n * URL con `cambios` aplicados sobre la query actual. Un valor vacio o `null` borra la clave. Cualquier cambio que\n * no sea de pagina regresa a la pagina 1 (borra `pagina`); `pagina=1` tambien se omite para que la URL quede limpia.\n */\nexport function hrefListado(\n ruta: string,\n actual: string | URLSearchParams,\n cambios: Record<string, string | null | undefined>,\n): string {\n const params = new URLSearchParams(actual);\n if (!(\"pagina\" in cambios)) params.delete(\"pagina\");\n for (const [clave, valor] of Object.entries(cambios)) {\n if (valor === null || valor === undefined || valor === \"\" || (clave === \"pagina\" && valor === \"1\")) {\n params.delete(clave);\n } else {\n params.set(clave, valor);\n }\n }\n const qs = params.toString();\n return qs ? `${ruta}?${qs}` : ruta;\n}\n","/**\n * Unico punto por el que las cifras del snapshot llegan a pantalla (decision D10 de `reporte-riesgo-crediticio`).\n *\n * Reglas: las cifras son CADENAS decimales ya redondeadas por el backend; aqui solo se agrupan los miles y se acomoda el\n * signo y el punto decimal manipulando texto, jamas con `Number`, `parseFloat` ni `toFixed` (un float distinto entre el\n * HTML y el PDF cambiaria una cifra). Un dato ausente (`null`) se muestra como `NO_DISPONIBLE`, nunca como cero.\n * Este modulo no importa nada de `next/*` ni hace red: lo comparten el sitio y el empaquetado del PDF.\n */\n\nexport const NO_DISPONIBLE = \"—\";\n\nconst DECIMAL = /^(-?)(\\d+)(?:\\.(\\d+))?$/;\n\nfunction partes(texto: string): { signo: string; entero: string; fraccion: string } | null {\n const m = DECIMAL.exec(texto.trim());\n return m ? { signo: m[1], entero: m[2], fraccion: m[3] ?? \"\" } : null;\n}\n\nconst miles = (entero: string) => entero.replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");\n\n/** Dinero en pesos: `1234.50` -> `$1,234.50` (los decimales son los que trae la cadena). */\nexport function formatoMxn(valor: string | null | undefined): string {\n if (valor == null) return NO_DISPONIBLE;\n const p = partes(valor);\n if (!p) return valor;\n return `${p.signo}$${miles(p.entero)}${p.fraccion ? `.${p.fraccion}` : \"\"}`;\n}\n\n/** Decimal generico (pendientes, promedios): agrupa los miles y respeta los decimales de la cadena. */\nexport function formatoNumero(valor: string | null | undefined): string {\n if (valor == null) return NO_DISPONIBLE;\n const p = partes(valor);\n if (!p) return valor;\n return `${p.signo}${miles(p.entero)}${p.fraccion ? `.${p.fraccion}` : \"\"}`;\n}\n\nexport function formatoEntero(valor: number | null | undefined): string {\n if (valor == null) return NO_DISPONIBLE;\n return formatoNumero(String(Math.trunc(valor)));\n}\n\n/** Razon (`0.1234`) como porcentaje (`12.34 %`): se corre el punto dos lugares en el texto, sin aritmetica. */\nexport function formatoPct(razon: string | null | undefined): string {\n if (razon == null) return NO_DISPONIBLE;\n const p = partes(razon);\n if (!p) return razon;\n const fraccion = p.fraccion.padEnd(4, \"0\");\n const entero = (p.entero + fraccion.slice(0, 2)).replace(/^0+(?=\\d)/, \"\");\n const resto = fraccion.slice(2);\n const decimales = resto.length > 2 ? resto : resto.padEnd(2, \"0\");\n return `${p.signo}${miles(entero)}.${decimales} %`;\n}\n\nexport function formatoDias(valor: string | null | undefined): string {\n return valor == null ? NO_DISPONIBLE : `${formatoNumero(valor)} días`;\n}\n\n/** `AAAA-MM-DD` -> `AAAA/MM/DD` (formato unico de fecha de la plataforma). */\nexport function formatoFecha(iso: string | null | undefined): string {\n if (!iso) return NO_DISPONIBLE;\n return iso.slice(0, 10).replace(/-/g, \"/\");\n}\n\nexport function formatoMes(mes: string | null | undefined): string {\n return mes ? mes.slice(0, 7).replace(/-/g, \"/\") : NO_DISPONIBLE;\n}\n","/**\n * Formato unico de fecha/hora para TODO el sistema (pedido explicito del usuario:\n * \"todos los periodos y fechas usemos formato yyyy/MM/dd HH:mm:ss\"), SIEMPRE en hora\n * LOCAL del navegador (pedido del usuario: \"en la base guardamos UTC pero en el view\n * debe ser hora local\").\n *\n * La API entrega fechas en DOS familias, que se distinguen por el sufijo de zona:\n * - CON sufijo UTC (`Z` o `+00:00`): timestamps del sistema escritos con\n * `now_utc().isoformat()` -> `...+00:00` (creado_en, terminado_en, `ts` de bitacora,\n * downloaded_at, etc.). Son instantes ABSOLUTOS en UTC y DEBEN convertirse a local.\n * - SIN sufijo (naive `YYYY-MM-DDTHH:MM:SS`): fechas de negocio (documento/portal)\n * (`fecha_emision`, `fecha_timbrado`, `start`/`end` de ventana, `date_from/to`) que\n * ya vienen en la hora que reporto la fuente -- NO se re-convierten (no tienen un\n * offset conocido; reinterpretarlas correria la hora sin base).\n *\n * En ambos casos la salida es `yyyy/MM/dd HH:mm:ss`. `date_from/to` puede venir como\n * `YYYY-MM-DD` puro (sin hora) -> se muestra la fecha a medianoche, sin conversion.\n */\nexport function formatearFechaHora(iso: string | null | undefined): string {\n if (!iso) return \"—\";\n\n const tieneZona = /(Z|[+-]\\d{2}:?\\d{2})$/.test(iso);\n\n // Con sufijo de zona (UTC): es un instante absoluto -> convertir a hora LOCAL del\n // navegador usando Date + partes locales.\n if (tieneZona && /T/.test(iso)) {\n const d = new Date(iso);\n if (!Number.isNaN(d.getTime())) {\n const p = (n: number) => String(n).padStart(2, \"0\");\n return (\n `${d.getFullYear()}/${p(d.getMonth() + 1)}/${p(d.getDate())} ` +\n `${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`\n );\n }\n }\n\n // Naive (sin zona) o `YYYY-MM-DD`: se formatea tal cual, sin conversion.\n const conHora = /T/.test(iso) ? iso : `${iso}T00:00:00`;\n const m = conHora.match(/^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})/);\n if (!m) return iso;\n const [, anio, mes, dia, hora, min, seg] = m;\n return `${anio}/${mes}/${dia} ${hora}:${min}:${seg}`;\n}\n\n/**\n * Como `formatearFechaHora`, pero un instante CON zona se muestra en America/Mexico_City (no en la\n * zona del proceso). Para componentes de servidor, donde \"hora local\" seria la del servidor (UTC).\n * Las fechas naive (fecha de negocio) o `YYYY-MM-DD` se muestran tal cual, igual que en la otra.\n */\nexport function formatearFechaHoraCDMX(iso: string | null | undefined): string {\n if (!iso) return \"—\";\n if (/(Z|[+-]\\d{2}:?\\d{2})$/.test(iso) && /T/.test(iso)) {\n const d = new Date(iso);\n if (!Number.isNaN(d.getTime())) {\n const partes = Object.fromEntries(\n new Intl.DateTimeFormat(\"en-CA\", {\n timeZone: \"America/Mexico_City\",\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n hourCycle: \"h23\",\n })\n .formatToParts(d)\n .map((x) => [x.type, x.value]),\n );\n return `${partes.year}/${partes.month}/${partes.day} ${partes.hour}:${partes.minute}:${partes.second}`;\n }\n }\n return formatearFechaHora(iso);\n}\n\n/** Formatea un rango `[desde, hasta]` con el mismo formato, unido por un guion largo. */\nexport function formatearRangoFechaHora(\n desde: string | null | undefined,\n hasta: string | null | undefined,\n): string {\n return `${formatearFechaHora(desde)} — ${formatearFechaHora(hasta)}`;\n}\n","/**\n * Tamano legible de un archivo (base 1024) para la estimacion y las partes ZIP de una\n * extraccion. Solo formatea: nunca recalcula nada.\n */\nexport function formatearBytes(n: number | null | undefined): string {\n if (n === null || n === undefined || !Number.isFinite(n) || n < 0) return \"—\";\n if (n < 1024) return `${n} B`;\n const unidades = [\"KB\", \"MB\", \"GB\", \"TB\"];\n let valor = n / 1024;\n let i = 0;\n while (valor >= 1024 && i < unidades.length - 1) {\n valor /= 1024;\n i += 1;\n }\n return `${valor.toFixed(1)} ${unidades[i]}`;\n}\n","\"use client\";\n\n/**\n * Spinner de marca: el logo de la instalacion que se \"llena\" de color de abajo hacia arriba, en\n * bucle (cambio `ux-spinner-marca`). Pedido explicito del usuario: entre\n * cambios de pantalla y en cada accion que consume un servicio, mostrar \"un spinner con el logo\n * llenandose de manera gradual\".\n *\n * COMO FUNCIONA (solucion de raiz, sin GIF ni libreria): se pinta la MISMA imagen del logo dos\n * veces superpuestas:\n * 1. una capa base tenue (el logo \"vacio\", en gris muy claro),\n * 2. una capa de color de marca recortada con `mask` a la forma del logo (`mask-image` = la\n * imagen), cuya ALTURA visible sube de 0% a 100% con una animacion CSS en bucle.\n * Asi el color solo aparece DENTRO de la silueta del logo y da el efecto de llenado gradual.\n * Respeta `prefers-reduced-motion` (si el usuario lo pide, no anima: muestra el logo lleno y\n * estatico, accesible).\n *\n * La imagen sale de la variable CSS `--tema-logo-spinner` (la fija el layout raiz con el logo del\n * producto o tenant); sin ella rige el icono de la marca por omision (`globals.css`). `tamano` en px (ancho);\n * la altura se deriva del aspect ratio del logo (~120x52).\n */\nexport function SpinnerMarca({\n tamano = 120,\n etiqueta = \"Cargando...\",\n}: {\n tamano?: number;\n etiqueta?: string;\n}) {\n const alto = Math.round((tamano * 52) / 120);\n return (\n <div\n className=\"inline-flex flex-col items-center gap-2\"\n role=\"status\"\n aria-live=\"polite\"\n aria-label={etiqueta}\n >\n <div className=\"spinner-marca\" style={{ width: tamano, height: alto }}>\n {/* Capa base: el logo \"vacio\" (tenue). */}\n <span className=\"spinner-marca__base\" aria-hidden=\"true\" />\n {/* Capa de relleno: color de marca recortado a la forma del logo, sube en bucle. */}\n <span className=\"spinner-marca__fill\" aria-hidden=\"true\" />\n </div>\n <span className=\"text-xs text-[#807f7f]\">{etiqueta}</span>\n </div>\n );\n}\n","\"use client\";\n\nimport { SpinnerMarca } from \"./SpinnerMarca\";\n\n/**\n * Overlay de carga para ACCIONES (cambio `ux-spinner-marca`). Pedido del usuario: en cada\n * accion que dispara al hacer click y consume un servicio, mostrar el spinner de marca\n * llenandose. A diferencia de `loading.tsx` (navegacion entre pantallas), este cubre las\n * mutaciones dentro de una pantalla (crear job, reintentar, exportar...). Se monta encima\n * del contenido con un velo semitransparente y BLOQUEA la interaccion mientras `visible`.\n *\n * Uso: `{enviando && <OverlayCargando etiqueta=\"Creando job...\" />}`.\n */\nexport function OverlayCargando({\n etiqueta = \"Procesando...\",\n visible = true,\n}: {\n etiqueta?: string;\n visible?: boolean;\n}) {\n if (!visible) return null;\n return (\n <div\n className=\"fixed inset-0 z-[60] flex items-center justify-center bg-white/70 backdrop-blur-[1px]\"\n role=\"alertdialog\"\n aria-busy=\"true\"\n aria-label={etiqueta}\n >\n <SpinnerMarca tamano={140} etiqueta={etiqueta} />\n </div>\n );\n}\n","\"use client\";\n\nimport { useCallback, useState } from \"react\";\n\nimport { OverlayCargando } from \"@/kit/ui/OverlayCargando\";\n\n/**\n * Helper central para el lineamiento \"toda accion dispara el spinner de marca\"\n * (lineamiento \"toda accion dispara el spinner de marca\"). Envuelve una funcion async y expone:\n * - `ejecutando`: true mientras la accion corre (para deshabilitar el boton).\n * - `ejecutar(fn, etiqueta?)`: corre `fn`, muestra el overlay de marca y lo cierra al\n * terminar (aunque `fn` lance).\n * - `Overlay`: componente listo para montar; pinta el `OverlayCargando` solo mientras\n * `ejecutando`. Asi cualquier accion obtiene el feedback homologado con una linea.\n *\n * Uso:\n * const { ejecutando, ejecutar, Overlay } = useAccionConSpinner();\n * <button disabled={ejecutando} onClick={() => ejecutar(guardar, \"Guardando...\")}>Guardar</button>\n * <Overlay />\n */\nexport function useAccionConSpinner() {\n const [ejecutando, setEjecutando] = useState(false);\n const [etiqueta, setEtiqueta] = useState<string>(\"Procesando...\");\n\n const ejecutar = useCallback(\n async <T,>(fn: () => Promise<T>, etiquetaAccion = \"Procesando...\"): Promise<T | undefined> => {\n setEtiqueta(etiquetaAccion);\n setEjecutando(true);\n try {\n return await fn();\n } finally {\n setEjecutando(false);\n }\n },\n [],\n );\n\n const Overlay = useCallback(\n () => <OverlayCargando visible={ejecutando} etiqueta={etiqueta} />,\n [ejecutando, etiqueta],\n );\n\n return { ejecutando, ejecutar, Overlay };\n}\n","/**\n * Preferencias de tabla persistentes (lineamiento del sistema): el usuario puede\n * reordenar y redimensionar columnas, y esas preferencias sobreviven al cierre del\n * navegador.\n *\n * MECANISMO: `localStorage`, NO cookies. Son preferencias de UI puramente del cliente\n * (la API no las necesita); mandarlas en cookies las enviaria en cada request sin\n * razon y con limite de ~4KB. `localStorage` persiste indefinidamente, es del lado\n * cliente y da ~5MB. Tradeoff aceptado: es por navegador/dispositivo (no se sincroniza\n * entre equipos); si en el futuro se quiere cross-device, se migra a una tabla de\n * preferencias por usuario en la API conservando esta misma interfaz.\n *\n * La CLAVE va VERSIONADA por tabla (ej. \"planes.tabla.prefs.v1\"): si cambian las columnas\n * de forma incompatible, se sube la version y las preferencias viejas se ignoran solas.\n * `ordenarColumnas` ademas es tolerante: columnas nuevas (no guardadas) aparecen al\n * final, y columnas guardadas que ya no existen se ignoran -- nunca se pierde una\n * columna ni se rompe por preferencias viejas.\n *\n * Este modulo es la logica PURA (serializacion + reordenamiento), sin React, para poder\n * probarla sin montar componentes. El hook de React que la usa vive aparte.\n */\n\nexport type PreferenciasTabla = {\n /** Orden de las columnas por id. Vacio = usar el orden default de la tabla. */\n orden: string[];\n /** Ancho en px por id de columna. Ausente = ancho automatico/default. */\n anchos: Record<string, number>;\n /** Ids de columnas ocultas. */\n ocultas: string[];\n};\n\nconst VACIAS: PreferenciasTabla = { orden: [], anchos: {}, ocultas: [] };\n\nfunction esNavegador(): boolean {\n return typeof window !== \"undefined\" && typeof window.localStorage !== \"undefined\";\n}\n\n/** Lee las preferencias de una tabla. Nunca lanza: ante ausencia o JSON corrupto,\n * devuelve preferencias vacias (la tabla usa sus defaults). */\nexport function cargarPreferencias(clave: string): PreferenciasTabla {\n if (!esNavegador()) return { ...VACIAS };\n const crudo = window.localStorage.getItem(clave);\n if (!crudo) return { ...VACIAS };\n try {\n const p = JSON.parse(crudo) as Partial<PreferenciasTabla>;\n return {\n orden: Array.isArray(p.orden) ? p.orden : [],\n anchos: p.anchos && typeof p.anchos === \"object\" ? p.anchos : {},\n ocultas: Array.isArray(p.ocultas) ? p.ocultas : [],\n };\n } catch {\n return { ...VACIAS };\n }\n}\n\n/** Persiste las preferencias de una tabla. No-op fuera del navegador (SSR). */\nexport function guardarPreferencias(clave: string, prefs: PreferenciasTabla): void {\n if (!esNavegador()) return;\n try {\n window.localStorage.setItem(clave, JSON.stringify(prefs));\n } catch {\n // localStorage lleno o deshabilitado (modo privado): la preferencia no se guarda,\n // pero la app sigue funcionando con el estado en memoria de la sesion actual.\n }\n}\n\n/** Borra las preferencias de una tabla (boton \"Restablecer columnas\"). */\nexport function borrarPreferencias(clave: string): void {\n if (!esNavegador()) return;\n window.localStorage.removeItem(clave);\n}\n\n/**\n * Aplica el orden guardado a la lista de ids default de la tabla:\n * 1. primero las columnas del orden guardado que aun existen, en ese orden;\n * 2. luego las columnas default que no estaban en el orden guardado (columnas nuevas),\n * conservando su posicion relativa default.\n * Asi ni se pierden columnas nuevas ni se rompe por ids viejos.\n */\nexport function ordenarColumnas(idsDefault: string[], ordenGuardado: string[]): string[] {\n if (ordenGuardado.length === 0) return [...idsDefault];\n const disponibles = new Set(idsDefault);\n const delGuardado = ordenGuardado.filter((id) => disponibles.has(id));\n const yaColocadas = new Set(delGuardado);\n const nuevas = idsDefault.filter((id) => !yaColocadas.has(id));\n return [...delGuardado, ...nuevas];\n}\n\n/** Reordena `ids` moviendo el elemento de `desde` a `hasta`. Indices fuera de rango\n * devuelven la lista intacta. */\nexport function moverColumna(ids: string[], desde: number, hasta: number): string[] {\n if (\n desde < 0 || desde >= ids.length ||\n hasta < 0 || hasta >= ids.length ||\n desde === hasta\n ) {\n return [...ids];\n }\n const copia = [...ids];\n const [movido] = copia.splice(desde, 1);\n copia.splice(hasta, 0, movido);\n return copia;\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useState } from \"react\";\n\nimport {\n borrarPreferencias,\n cargarPreferencias,\n guardarPreferencias,\n moverColumna,\n ordenarColumnas,\n type PreferenciasTabla,\n} from \"./preferenciasTabla\";\n\n/**\n * Hook de React sobre `preferenciasTabla`: mantiene el orden, los anchos y las columnas\n * ocultas de UNA tabla, persistidos en localStorage bajo `clave`, y expone acciones para\n * reordenar/redimensionar/ocultar/restablecer.\n *\n * `idsDefault` es el orden natural de las columnas de la tabla (por id). El hook resuelve\n * el orden efectivo combinando lo guardado con los defaults (columnas nuevas al final,\n * ids viejos ignorados) via `ordenarColumnas`.\n *\n * SSR-safe: en el primer render (servidor y cliente) usa los defaults; tras montar, lee\n * localStorage y re-renderiza. Asi no hay desajuste de hidratacion.\n */\nexport function useTablaPreferencias(clave: string, idsDefault: string[]) {\n const [prefs, setPrefs] = useState<PreferenciasTabla>({ orden: [], anchos: {}, ocultas: [] });\n\n // Cargar al montar (solo en cliente; en SSR localStorage no existe).\n useEffect(() => {\n setPrefs(cargarPreferencias(clave));\n }, [clave]);\n\n const persistir = useCallback(\n (nuevas: PreferenciasTabla) => {\n setPrefs(nuevas);\n guardarPreferencias(clave, nuevas);\n },\n [clave],\n );\n\n // Orden efectivo de ids (guardado + defaults nuevos), sin las ocultas.\n const idsOrdenados = ordenarColumnas(idsDefault, prefs.orden);\n const ocultas = new Set(prefs.ocultas);\n const idsVisibles = idsOrdenados.filter((id) => !ocultas.has(id));\n\n const mover = useCallback(\n (desde: number, hasta: number) => {\n // Los indices vienen sobre la lista de ids ordenados COMPLETA (incluye ocultas\n // fuera de vista? no: el reorder opera sobre lo que se ve). Recalculamos sobre\n // idsOrdenados para persistir un orden completo y estable.\n const base = ordenarColumnas(idsDefault, prefs.orden);\n const nuevoOrden = moverColumna(base, desde, hasta);\n persistir({ ...prefs, orden: nuevoOrden });\n },\n [idsDefault, prefs, persistir],\n );\n\n const redimensionar = useCallback(\n (id: string, ancho: number) => {\n const w = Math.max(60, Math.round(ancho)); // ancho minimo 60px\n persistir({ ...prefs, anchos: { ...prefs.anchos, [id]: w } });\n },\n [prefs, persistir],\n );\n\n const alternarVisible = useCallback(\n (id: string) => {\n const set = new Set(prefs.ocultas);\n if (set.has(id)) set.delete(id);\n else set.add(id);\n persistir({ ...prefs, ocultas: [...set] });\n },\n [prefs, persistir],\n );\n\n const restablecer = useCallback(() => {\n borrarPreferencias(clave);\n setPrefs({ orden: [], anchos: {}, ocultas: [] });\n }, [clave]);\n\n return {\n /** Ids en el orden efectivo, SIN las ocultas — para pintar la tabla. */\n idsVisibles,\n /** Ids en el orden efectivo, incluyendo ocultas — para el menu de mostrar/ocultar. */\n idsOrdenados,\n /** Set de ids ocultos. */\n ocultas,\n /** Ancho persistido de una columna, o undefined si no se ha redimensionado. */\n anchoDe: (id: string): number | undefined => prefs.anchos[id],\n mover,\n redimensionar,\n alternarVisible,\n restablecer,\n };\n}\n","/**\n * Calculo puro de la posicion de un popover `fixed` dentro del viewport. Separado del\n * componente para poder probarlo sin layout real (jsdom no mide).\n */\nexport type RectLike = {\n left: number;\n top: number;\n right: number;\n bottom: number;\n width: number;\n height: number;\n};\n\nexport type EntradaPosicion = {\n trigger: RectLike;\n /** Tamano medido del contenido (ya acotado a `anchoMax` si aplica). */\n contenido: { ancho: number; alto: number };\n viewport: { ancho: number; alto: number };\n margen?: number;\n separacion?: number;\n /** Ancho maximo deseado (default 360). */\n anchoPreferido?: number;\n};\n\nexport type PosicionPopover = {\n top: number;\n left: number;\n /** Alto maximo para scroll interno. */\n maxHeight: number;\n /** Ancho maximo: min(preferido, viewport - 2*margen). */\n anchoMax: number;\n};\n\nexport function calcularPosicionPopover({\n trigger,\n contenido,\n viewport,\n margen = 8,\n separacion = 4,\n anchoPreferido = 360,\n}: EntradaPosicion): PosicionPopover {\n const anchoMax = Math.min(anchoPreferido, viewport.ancho - 2 * margen);\n const ancho = Math.min(contenido.ancho, anchoMax);\n\n // Horizontal: alineado al disparador, acotado al viewport (equivale a alinear el borde\n // derecho cuando el disparador esta cerca del borde derecho).\n const left = Math.max(margen, Math.min(trigger.left, viewport.ancho - ancho - margen));\n\n // Vertical: debajo si cabe; si no, arriba si hay mas espacio arriba.\n const espacioAbajo = viewport.alto - trigger.bottom - separacion - margen;\n const espacioArriba = trigger.top - separacion - margen;\n const abajo = contenido.alto <= espacioAbajo || espacioAbajo >= espacioArriba;\n const disponible = Math.max(0, abajo ? espacioAbajo : espacioArriba);\n const alto = Math.min(contenido.alto, disponible);\n const top = abajo ? trigger.bottom + separacion : trigger.top - separacion - alto;\n\n return { top, left, maxHeight: disponible, anchoMax };\n}\n","/**\n * Clases Tailwind CANONICAS de botones, campos y avisos. La plataforma las escribe en linea en cada pantalla; aqui estan\n * agrupadas VERBATIM (docs/sistema-diseno-ui.md 7.1, 7.2 y 7.9 del proyecto original, y las clases mas repetidas en su\n * codigo) para que no se reinventen. Uso: `<button className={CLASE_BOTON_PRIMARIO}>`.\n * Regla: una sola accion primaria por vista o modal. Destructivo: siempre con confirmacion previa.\n */\n\n/**\n * Primario estandar (36 px de alto): accion principal de una vista o modal.\n * Relleno NEUTRO OSCURO (var(--tema-texto)), NO el rojo de marca: el rojo queda reservado a peligro\n * (ver docs/criterio-color-acciones.md). El rojo de marca aparece como acento (titulos, foco, seleccion).\n */\nexport const CLASE_BOTON_PRIMARIO =\n \"inline-flex items-center gap-1.5 rounded-md bg-[var(--tema-texto)] px-4 py-2 text-sm font-medium text-white transition hover:brightness-125 disabled:opacity-50\";\n/** Primario compacto (32 px): modales y barras de herramientas. Mismo criterio neutro oscuro. */\nexport const CLASE_BOTON_PRIMARIO_COMPACTO =\n \"inline-flex items-center gap-1.5 rounded-md bg-[var(--tema-texto)] px-3 py-1.5 text-sm font-medium text-white transition hover:brightness-125 disabled:opacity-50\";\n/** Secundario: cancelar, acciones de fila, paginador. */\nexport const CLASE_BOTON_SECUNDARIO =\n \"inline-flex items-center gap-1.5 rounded-md border border-[var(--tema-borde)] px-3 py-1.5 text-sm font-medium text-[#3c3c3b] transition hover:bg-[var(--tema-badge-neutro)] disabled:opacity-50\";\n/** Pequeno (28 px): barras de herramientas de tabla (mismo que el boton \"Columnas\"). */\nexport const CLASE_BOTON_PEQUENO =\n \"inline-flex items-center gap-1.5 rounded-md border border-[var(--tema-borde)] px-2.5 py-1.5 text-xs font-medium text-[#3c3c3b] transition hover:bg-[var(--tema-badge-neutro)] disabled:opacity-50\";\n/** Contorno primario: accion secundaria que debe destacar. */\nexport const CLASE_BOTON_CONTORNO =\n \"rounded-md border border-[var(--tema-primario)] px-3 py-1 text-xs font-medium text-[var(--tema-primario)] transition hover:bg-[#eaf2fb]\";\n/** Solo icono (cerrar, copiar, colapsar): exige `aria-label` y `title`. */\nexport const CLASE_BOTON_ICONO =\n \"rounded-md p-1 text-[#807f7f] transition hover:bg-[var(--tema-badge-neutro)]\";\n/** Destructivo (bajas): contorno en el rojo de peligro (tematizable); confirmar siempre antes de ejecutar. */\nexport const CLASE_BOTON_PELIGRO =\n \"inline-flex items-center gap-1.5 rounded-md border border-[var(--tema-peligro)] px-3 py-1.5 text-sm font-medium text-[var(--tema-peligro)] transition hover:bg-[var(--tema-badge-error)] disabled:opacity-50\";\n\n/** Input / select / textarea estandar. Compacto (filtros): `px-2 py-1.5`. */\nexport const CLASE_CAMPO =\n \"rounded-md border border-[var(--tema-borde)] bg-[var(--tema-fondo)] px-3 py-2 text-sm text-[#3c3c3b] focus:border-[var(--tema-primario)] focus:outline-none disabled:bg-[#f4f8fc] disabled:text-[#807f7f]\";\nexport const CLASE_CAMPO_COMPACTO =\n \"rounded-md border border-[var(--tema-borde)] bg-[var(--tema-fondo)] px-2 py-1.5 text-sm text-[#3c3c3b] focus:border-[var(--tema-primario)] focus:outline-none\";\n/** Etiqueta (label) de campo: encima del campo, separada 4 px (`flex flex-col gap-1`). */\nexport const CLASE_ETIQUETA_CAMPO = \"text-sm font-medium text-[#3c3c3b]\";\n/** Texto de ayuda bajo el campo. */\nexport const CLASE_AYUDA_CAMPO = \"text-xs text-[#807f7f]\";\n/** Error de un campo o del envio (con `role=\"alert\"`). */\nexport const CLASE_ERROR_CAMPO = \"text-sm text-[var(--tema-peligro)]\";\n/** Exito bajo el formulario (con `role=\"status\"`). */\nexport const CLASE_EXITO_CAMPO = \"text-sm text-[#1e7a34]\";\n\n/** Tarjeta / seccion: borde fino, sin sombra, sin fondo. */\nexport const CLASE_TARJETA = \"rounded-lg border border-[var(--tema-borde)] p-4\";\n/** Titulos. */\nexport const CLASE_TITULO_PAGINA = \"flex items-center gap-2 text-xl font-semibold text-[var(--tema-primario-oscuro)]\";\nexport const CLASE_TITULO_SECCION = \"text-sm font-semibold text-[var(--tema-primario-oscuro)]\";\nexport const CLASE_TEXTO_ATENUADO = \"text-sm text-[#807f7f]\";\n","\"use client\";\n\nimport { type ReactNode, useCallback, useEffect, useId, useLayoutEffect, useRef, useState } from \"react\";\n\nimport { calcularPosicionPopover, type PosicionPopover } from \"@/kit/lib/posicionPopover\";\n\n/**\n * Popover reusable que aparece al pasar el mouse (hover) o al enfocar con teclado (focus)\n * sobre su disparador, y se oculta al salir/desenfocar. Nace del widget del tag schedule,\n * pero es generico: cualquier control que quiera mostrar contenido rico al hover lo usa.\n *\n * Por que un componente y no el `title` nativo (unico patron previo en el sistema): el\n * `title` solo muestra texto plano de una linea, no permite contenido estructurado (tabla\n * de ejecuciones con iconos de estatus) ni es navegable. Este es accesible: el disparador\n * es un boton focusable, el contenido se asocia por `aria-describedby` y responde a\n * teclado (focus/blur), no solo a mouse.\n *\n * POSICIONAMIENTO `fixed` (no `absolute`): el widget vive dentro de tablas cuyo contenedor\n * tiene `overflow-hidden`/`overflow-x-auto`; un popover `absolute` quedaba RECORTADO por\n * ese overflow y no se veia. Con `fixed` + las coordenadas del disparador\n * (`getBoundingClientRect`) el contenido flota sobre todo, fuera del flujo recortado.\n *\n * VIEWPORT-AWARE: `fixed` en la esquina del disparador desbordaba el viewport cerca del\n * borde derecho/inferior (texto cortado e ilegible). Tras abrir se MIDE el contenido y\n * `calcularPosicionPopover` lo acota al viewport (desplaza a la izquierda, abre arriba si\n * no cabe abajo, limita ancho/alto con scroll interno). Se recalcula con scroll/resize y\n * Escape lo cierra.\n */\nexport function PopoverHover({\n etiqueta,\n disparador,\n children,\n}: {\n /** Nombre accesible del disparador (aria-label + tooltip nativo de respaldo). */\n etiqueta: string;\n /** Contenido visible del disparador (normalmente un icono). */\n disparador: ReactNode;\n /** Contenido del popover. */\n children: ReactNode;\n}) {\n const [abierto, setAbierto] = useState(false);\n const [pos, setPos] = useState<PosicionPopover | null>(null);\n const botonRef = useRef<HTMLButtonElement>(null);\n const contenidoRef = useRef<HTMLSpanElement>(null);\n const idContenido = useId();\n\n const reposicionar = useCallback(() => {\n const trigger = botonRef.current?.getBoundingClientRect();\n if (!trigger) return;\n const medida = contenidoRef.current?.getBoundingClientRect();\n setPos(\n calcularPosicionPopover({\n trigger,\n contenido: { ancho: medida?.width ?? 0, alto: medida?.height ?? 0 },\n viewport: { ancho: window.innerWidth, alto: window.innerHeight },\n }),\n );\n }, []);\n\n function abrir() {\n setAbierto(true);\n }\n\n // Medir tras montar el contenido (antes de pintar) y recalcular con scroll/resize.\n useLayoutEffect(() => {\n if (!abierto) {\n setPos(null);\n return;\n }\n reposicionar();\n window.addEventListener(\"scroll\", reposicionar, true);\n window.addEventListener(\"resize\", reposicionar);\n return () => {\n window.removeEventListener(\"scroll\", reposicionar, true);\n window.removeEventListener(\"resize\", reposicionar);\n };\n }, [abierto, reposicionar]);\n\n useEffect(() => {\n if (!abierto) return;\n function alTeclear(e: KeyboardEvent) {\n if (e.key === \"Escape\") setAbierto(false);\n }\n document.addEventListener(\"keydown\", alTeclear);\n return () => document.removeEventListener(\"keydown\", alTeclear);\n }, [abierto]);\n\n return (\n <span\n className=\"inline-flex\"\n onMouseEnter={abrir}\n onMouseLeave={() => setAbierto(false)}\n >\n <button\n ref={botonRef}\n type=\"button\"\n aria-label={etiqueta}\n title={etiqueta}\n aria-expanded={abierto}\n aria-describedby={abierto ? idContenido : undefined}\n onFocus={abrir}\n onBlur={() => setAbierto(false)}\n className=\"inline-flex items-center justify-center text-[#807f7f] transition hover:text-[var(--tema-primario)]\"\n >\n {disparador}\n </button>\n {abierto && (\n <span\n ref={contenidoRef}\n id={idContenido}\n role=\"tooltip\"\n style={{\n position: \"fixed\",\n top: pos?.top ?? 0,\n left: pos?.left ?? 0,\n // Antes de medir (pos null) se oculta para no parpadear en (0,0).\n visibility: pos ? \"visible\" : \"hidden\",\n maxWidth: pos?.anchoMax ?? \"min(360px, calc(100vw - 16px))\",\n maxHeight: pos?.maxHeight,\n overflowY: \"auto\",\n }}\n className=\"z-50 w-max rounded-md border border-[var(--tema-borde)] bg-white p-3 text-left shadow-lg\"\n >\n {children}\n </span>\n )}\n </span>\n );\n}\n","\"use client\";\n\nimport { type ExplicacionId, explicacionDe } from \"@/kit/lib/explicaciones\";\nimport { ICONO_INFO_EXPLICACION } from \"@/kit/lib/iconos\";\n\nimport { PopoverHover } from \"./PopoverHover\";\n\nconst PREGUNTAS = [\n [\"Qué es\", \"que_es\"],\n [\"Cómo se calcula\", \"como_se_calcula\"],\n [\"De dónde sale\", \"de_donde_sale\"],\n [\"Cómo leerlo\", \"como_leerlo\"],\n] as const;\n\n/**\n * Icono de ayuda (change `explicaciones-analitica-conceptos`): al pasar el mouse o enfocar con teclado abre un\n * popover con las 4 preguntas fijas (que es, como se calcula, de donde sale, como leerlo) del catalogo\n * `lib/explicaciones.ts`. Reusa `PopoverHover` (focusable, `aria-describedby`, posicion `fixed`).\n *\n * Sin desplazamiento de layout: el disparador es un icono de tamano fijo (14px) en un `span` en linea; el\n * contenido solo existe mientras esta abierto. Un id fuera del catalogo lanza (`explicacionDe`): preferible a\n * dejar una metrica sin explicacion en silencio. El `data-explicacion-id` lo leen las pruebas de cobertura.\n */\nexport function InfoExplicacion({ id }: { id: ExplicacionId }) {\n const e = explicacionDe(id);\n return (\n <span data-explicacion-id={id} className=\"inline-flex shrink-0 align-middle\">\n <PopoverHover\n etiqueta={`Explicación: ${e.titulo}`}\n disparador={<ICONO_INFO_EXPLICACION size={14} aria-hidden=\"true\" className=\"text-[#9a9999]\" />}\n >\n <span className=\"block max-w-[18rem] text-xs font-normal normal-case tracking-normal text-[#3c3c3b]\">\n <span className=\"block font-semibold text-[var(--tema-primario-oscuro)]\">{e.titulo}</span>\n {PREGUNTAS.map(([pregunta, campo]) => (\n <span key={campo} className=\"mt-1.5 block\">\n <span className=\"block font-medium text-[#565656]\">{pregunta}</span>\n <span className=\"block leading-snug\">{e[campo]}</span>\n </span>\n ))}\n </span>\n </PopoverHover>\n </span>\n );\n}\n","/**\n * Piezas basicas: Insignia (chip de estado), Tarjeta (seccion con titulo), Metrica (KPI simple) y ThInfo (encabezado de\n * columna con (i)). Copia de `components/factoraje/Insignia.tsx` de la plataforma original; unico cambio: `Insignia`\n * acepta `icono` opcional. REGLA DEL KIT: pasa SIEMPRE `info` (la explicacion (i)); es opcional solo por compatibilidad.\n */\nimport type { ReactNode } from \"react\";\n\nimport { InfoExplicacion } from \"@/kit/ui/InfoExplicacion\";\nimport type { ExplicacionId } from \"@/kit/lib/explicaciones\";\nimport type { LucideIconType } from \"@/kit/lib/iconos\";\n\nconst CLASES = {\n exito: \"bg-[var(--tema-badge-exito)] text-[#1e6b34]\",\n error: \"bg-[var(--tema-badge-error)] text-[var(--tema-peligro)]\",\n aviso: \"bg-[var(--tema-badge-advertencia)] text-[#8a5a00]\",\n neutro: \"bg-[var(--tema-badge-neutro)] text-[#565656]\",\n} as const;\n\nexport type Tono = keyof typeof CLASES;\n\nexport function Insignia({\n tono,\n children,\n info,\n icono: Icono,\n}: {\n tono: keyof typeof CLASES;\n children: ReactNode;\n /** Icono de 12 px antes del texto (KIT: patron de `BadgeEstado` de la plataforma; el color nunca es la unica senal). */\n icono?: LucideIconType;\n /** Explicacion en sitio de la insignia: el icono va justo despues del chip, nunca dentro de el. */\n info?: ExplicacionId;\n}) {\n return (\n <span className=\"inline-flex items-center gap-1 align-middle\">\n <span\n className={`${Icono ? \"inline-flex items-center gap-1\" : \"inline-block\"} rounded-full px-2 py-0.5 text-xs font-medium ${CLASES[tono]}`}\n >\n {Icono && <Icono size={12} aria-hidden=\"true\" />}\n {children}\n </span>\n {info && <InfoExplicacion id={info} />}\n </span>\n );\n}\n\nexport function Tarjeta({\n titulo,\n children,\n nota,\n info,\n}: {\n titulo: string;\n children: ReactNode;\n nota?: ReactNode;\n /** Explicacion en sitio del titulo (catalogo `lib/explicaciones.ts`). */\n info?: ExplicacionId;\n}) {\n return (\n <section className=\"rounded-lg border border-[var(--tema-borde)] p-5\">\n <div className=\"flex items-center gap-1.5\">\n <h2 className=\"text-sm font-semibold text-[var(--tema-primario-oscuro)]\">{titulo}</h2>\n {info && <InfoExplicacion id={info} />}\n </div>\n {nota && <p className=\"mt-1 text-xs text-[#807f7f]\">{nota}</p>}\n <div className=\"mt-3\">{children}</div>\n </section>\n );\n}\n\nexport function Metrica({\n etiqueta,\n valor,\n info,\n}: {\n etiqueta: string;\n valor: ReactNode;\n /** Explicacion en sitio de la metrica (catalogo `lib/explicaciones.ts`). */\n info?: ExplicacionId;\n}) {\n return (\n <div className=\"rounded-lg border border-[var(--tema-borde)] px-4 py-3\">\n <div className=\"flex items-center gap-1\">\n <p className=\"text-xs text-[#807f7f]\">{etiqueta}</p>\n {info && <InfoExplicacion id={info} />}\n </div>\n <p className=\"mt-1 text-lg font-semibold text-[var(--tema-primario-oscuro)]\">{valor}</p>\n </div>\n );\n}\n\n/** Encabezado de columna con su explicacion en sitio (el icono va junto al texto, alineado segun la columna). */\nexport function ThInfo({\n info,\n children,\n className,\n derecha,\n scope,\n atributos,\n}: {\n info: ExplicacionId;\n children: ReactNode;\n className?: string;\n derecha?: boolean;\n scope?: \"col\" | \"row\";\n /** Atributos de columna del marco de tablas: `fija(\"izq\", i)` o `col(id)` (`@/kit/tabla/celdas`). */\n atributos?: object;\n}) {\n return (\n <th scope={scope} {...atributos} className={className}>\n <span className={`inline-flex items-center gap-1 ${derecha ? \"justify-end\" : \"\"}`}>\n {children}\n <InfoExplicacion id={info} />\n </span>\n </th>\n );\n}\n","/**\n * Avisos en linea, estados vacios y barra de progreso. Clases VERBATIM de la plataforma (docs 7.8, 7.9, 8.2, 8.3).\n * La plataforma NO usa toasts: la retroalimentacion vive junto al control que la provoco (aviso en linea).\n */\nimport type { ReactNode } from \"react\";\n\nimport { InfoExplicacion } from \"@/kit/ui/InfoExplicacion\";\nimport type { ExplicacionId } from \"@/kit/lib/explicaciones\";\n\nconst TIPOS = {\n error: \"rounded-md bg-[var(--tema-badge-error)] px-3 py-2 text-sm text-[var(--tema-peligro)]\",\n advertencia: \"rounded-md bg-[var(--tema-badge-advertencia)] px-3 py-2 text-xs text-[#8a5a00]\",\n neutro: \"rounded-lg bg-[var(--tema-badge-neutro)] px-3 py-2 text-sm text-[#565656]\",\n exito: \"rounded-md bg-[var(--tema-badge-exito)] px-3 py-2 text-sm text-[#1e7a34]\",\n} as const;\n\n/** Aviso en linea: empieza con una frase en negrita (`titulo`) y sigue el detalle. `error` -> role=\"alert\"; el resto \"status\". */\nexport function Aviso({\n tipo,\n titulo,\n children,\n info,\n}: {\n tipo: keyof typeof TIPOS;\n titulo?: string;\n children?: ReactNode;\n info?: ExplicacionId;\n}) {\n return (\n <div role={tipo === \"error\" ? \"alert\" : \"status\"} className={TIPOS[tipo]}>\n {titulo && <strong className=\"font-semibold\">{titulo} </strong>}\n {children}\n {info && (\n <span className=\"ml-1 align-middle\">\n <InfoExplicacion id={info} />\n </span>\n )}\n </div>\n );\n}\n\n/** Vacio en bloque (borde punteado). Dentro de una tabla se usa una fila `td colSpan` con `EstadoVacioFila`. */\nexport function EstadoVacio({ children }: { children: ReactNode }) {\n return (\n <p className=\"rounded-lg border border-dashed border-[var(--tema-borde)] px-4 py-6 text-sm text-[#807f7f]\">{children}</p>\n );\n}\n\n/** Fila de \"Sin resultados\" para el `<tbody>` de una tabla. */\nexport function EstadoVacioFila({ columnas, children = \"Sin resultados\" }: { columnas: number; children?: ReactNode }) {\n return (\n <tr>\n <td colSpan={columnas} className=\"px-3 py-6 text-center text-sm text-[#807f7f]\">\n {children}\n </td>\n </tr>\n );\n}\n\n/** \"No disponible\": un calculo que no pudo hacerse. Dice por que; NUNCA pinta un cero. */\nexport function NoDisponible({ motivo, info }: { motivo: string; info: ExplicacionId }) {\n return (\n <div className=\"rounded-lg border border-dashed border-[var(--tema-borde)] px-4 py-3 text-sm text-[#565656]\">\n <p className=\"flex items-center gap-1 font-medium\">\n No disponible\n <InfoExplicacion id={info} />\n </p>\n <p className=\"mt-1 text-xs text-[#807f7f]\">{motivo}</p>\n </div>\n );\n}\n\n/** Barra de progreso (6 px de alto). */\nexport function BarraProgreso({ porcentaje, etiqueta }: { porcentaje: number; etiqueta: string }) {\n return (\n <div\n role=\"progressbar\"\n aria-label={etiqueta}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={porcentaje}\n className=\"h-1.5 w-full overflow-hidden rounded-full bg-[var(--tema-borde)]\"\n >\n <div className=\"h-full rounded-full bg-[var(--tema-primario)] transition-all\" style={{ width: `${porcentaje}%` }} />\n </div>\n );\n}\n","\"use client\";\n\nimport { useState } from \"react\";\n\nimport { InfoExplicacion } from \"./InfoExplicacion\";\nimport { SpinnerMarca } from \"./SpinnerMarca\";\n\nexport type AvisoAccion = { tipo: \"ok\" | \"error\"; texto: string };\n\ntype IdInfo = Parameters<typeof InfoExplicacion>[0][\"id\"];\n\n/**\n * Estado de una accion asincrona (patron unico: \"Reintentar\", \"Sincronizar\", etc.): `correr` la\n * ejecuta una vez, `ejecutando` deshabilita el disparador y `aviso` dice el resultado. Un error lanzado se dice con\n * `errorGenerico`; `onHecho` solo se llama si la accion termino bien (para refrescar lo que se ve). Change\n * separado del boton para que el disparador pueda vivir en el menu \"⋯\" de la fila (que\n * se cierra al elegir) mientras el spinner y el aviso se pintan en la fila.\n */\nexport function useAccionAviso({\n ejecutar,\n errorGenerico,\n onHecho,\n}: {\n ejecutar: () => Promise<AvisoAccion>;\n errorGenerico: string;\n onHecho?: () => void;\n}) {\n const [ejecutando, setEjecutando] = useState(false);\n const [aviso, setAviso] = useState<AvisoAccion | null>(null);\n\n async function correr() {\n setEjecutando(true);\n setAviso(null);\n let resultado: AvisoAccion;\n try {\n resultado = await ejecutar();\n } catch {\n resultado = { tipo: \"error\", texto: errorGenerico };\n }\n setAviso(resultado);\n setEjecutando(false);\n if (resultado.tipo === \"ok\") onHecho?.();\n }\n\n return { ejecutando, aviso, correr };\n}\n\n/** Spinner mientras la accion corre y el aviso del resultado (`status` si salio bien, `alert` si fallo). */\nexport function AvisoAccionEstado({\n ejecutando,\n aviso,\n etiquetaSpinner,\n}: {\n ejecutando: boolean;\n aviso: AvisoAccion | null;\n etiquetaSpinner: string;\n}) {\n return (\n <>\n {ejecutando && <SpinnerMarca tamano={32} etiqueta={etiquetaSpinner} />}\n {aviso && (\n <span\n role={aviso.tipo === \"ok\" ? \"status\" : \"alert\"}\n className={aviso.tipo === \"ok\" ? \"text-xs text-[var(--tema-primario-oscuro)]\" : \"text-xs text-[var(--tema-peligro)]\"}\n >\n {aviso.texto}\n </span>\n )}\n </>\n );\n}\n\n/**\n * Boton de accion con su (i), spinner y aviso del resultado. Deshabilitado mientras `ejecutar` corre.\n * Compone `useAccionAviso` + `AvisoAccionEstado`.\n */\nexport function BotonAccionAviso({\n etiqueta,\n etiquetaEjecutando,\n etiquetaSpinner,\n ariaLabel,\n info,\n errorGenerico,\n ejecutar,\n onHecho,\n}: {\n etiqueta: string;\n etiquetaEjecutando: string;\n etiquetaSpinner: string;\n ariaLabel: string;\n info: IdInfo;\n errorGenerico: string;\n ejecutar: () => Promise<AvisoAccion>;\n onHecho?: () => void;\n}) {\n const { ejecutando, aviso, correr } = useAccionAviso({ ejecutar, errorGenerico, onHecho });\n\n return (\n <span className=\"inline-flex flex-wrap items-center gap-1.5\">\n <button\n type=\"button\"\n onClick={correr}\n disabled={ejecutando}\n aria-label={ariaLabel}\n className=\"rounded-md border border-[var(--tema-borde)] px-2 py-0.5 text-xs font-medium text-[var(--tema-primario-oscuro)] transition hover:bg-[var(--tema-badge-neutro)] disabled:opacity-50\"\n >\n {ejecutando ? etiquetaEjecutando : etiqueta}\n </button>\n <InfoExplicacion id={info} />\n <AvisoAccionEstado ejecutando={ejecutando} aviso={aviso} etiquetaSpinner={etiquetaSpinner} />\n </span>\n );\n}\n","import type { ReactNode } from \"react\";\n\nimport { LinkBase } from \"@/kit/lib/LinkBase\";\n\n/**\n * Enlace del menu lateral. Server-compatible (sin estado): el colapso lo decide CSS via el\n * atributo `data-colapsado` del `<aside>` (`SidebarColapsable`, grupo `side`). Con el menu\n * colapsado (escritorio) solo se ve el icono; `aria-label` y `title` conservan el nombre\n * accesible y el tooltip nativo.\n */\nexport function EnlaceNav({\n href,\n icono,\n etiqueta,\n}: {\n href: string;\n icono: ReactNode;\n etiqueta: string;\n}) {\n return (\n <LinkBase\n href={href}\n aria-label={etiqueta}\n title={etiqueta}\n className=\"pulsable flex items-center gap-2.5 rounded-md px-2 py-2 transition hover:bg-[var(--tema-badge-neutro)] hover:text-[var(--tema-primario)] md:group-data-[colapsado=true]/side:justify-center\"\n >\n {icono}\n <span className=\"md:group-data-[colapsado=true]/side:hidden\">{etiqueta}</span>\n </LinkBase>\n );\n}\n\n/** Seccion del menu: el titulo se oculta (queda un separador) cuando el menu esta colapsado. */\nexport function SeccionNav({ titulo, children }: { titulo?: string; children: ReactNode }) {\n return (\n <div className=\"flex flex-col gap-1\">\n {titulo && (\n <span className=\"px-2 pb-1 text-[10px] font-semibold uppercase tracking-wider text-[#9a9a9a] md:group-data-[colapsado=true]/side:hidden\">\n {titulo}\n </span>\n )}\n {children}\n </div>\n );\n}\n","/**\n * Preferencias de UI por navegador (tamano/modo de paneles). `localStorage` puede lanzar\n * (ventana privada, datos bloqueados): toda lectura/escritura va en try/catch y la UI\n * funciona igual sin persistencia.\n */\nexport function leerPref<T>(clave: string, porDefecto: T): T {\n try {\n const crudo = window.localStorage.getItem(clave);\n return crudo === null ? porDefecto : (JSON.parse(crudo) as T);\n } catch {\n return porDefecto;\n }\n}\n\nexport function guardarPref(clave: string, valor: unknown): void {\n try {\n window.localStorage.setItem(clave, JSON.stringify(valor));\n } catch {\n // Sin persistencia: no es critico.\n }\n}\n\n/** Acota `valor` a [min, max]; si max < min prevalece min. */\nexport function limitar(valor: number, min: number, max: number): number {\n return Math.max(min, Math.min(valor, max));\n}\n","\"use client\";\n\nimport { type ReactNode, useEffect, useState } from \"react\";\n\nimport {\n ICONO_CERRAR,\n ICONO_NAV_COLAPSAR,\n ICONO_NAV_EXPANDIR,\n ICONO_NAV_MENU_MOVIL,\n TAMANO_BOTON,\n} from \"@/kit/lib/iconos\";\nimport { guardarPref, leerPref } from \"@/kit/lib/panelPrefs\";\n\nconst CLAVE = \"sidebar:colapsado\";\n\n/**\n * Cambio `web-paneles-ajustables` — menu lateral colapsable.\n *\n * Escritorio (`md`+): boton para colapsar a un rail de solo iconos (w-14); la preferencia\n * persiste en localStorage. Movil (<`md`): el menu es un cajon fuera de pantalla con boton\n * hamburguesa, fondo que lo cierra, Escape y cierre al elegir un enlace (antes ocupaba\n * 15rem fijos del viewport).\n *\n * El estado se expone como `data-colapsado` en el `<aside>` (grupo `side`): los enlaces del\n * Server Component (`EnlaceNav`) reaccionan por CSS, sin convertirse en cliente. El render\n * inicial es expandido (igual que el SSR) y el valor guardado se aplica tras montar.\n * Convive con el asistente anclado: este rail solo cambia SU ancho; el area de contenido es\n * `flex-1` y el asistente reserva su espacio aparte con `--asistente-ancho`.\n */\nexport function SidebarColapsable({\n cabecera,\n pie,\n children,\n}: {\n cabecera: ReactNode;\n pie: ReactNode;\n children: ReactNode;\n}) {\n const [colapsado, setColapsado] = useState(false);\n const [abiertoMovil, setAbiertoMovil] = useState(false);\n\n useEffect(() => {\n setColapsado(leerPref<boolean>(CLAVE, false) === true);\n }, []);\n\n useEffect(() => {\n if (!abiertoMovil) return;\n const alTeclear = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") setAbiertoMovil(false);\n };\n document.addEventListener(\"keydown\", alTeclear);\n return () => document.removeEventListener(\"keydown\", alTeclear);\n }, [abiertoMovil]);\n\n function alternar() {\n const nuevo = !colapsado;\n setColapsado(nuevo);\n guardarPref(CLAVE, nuevo);\n }\n\n return (\n <>\n <button\n type=\"button\"\n onClick={() => setAbiertoMovil(true)}\n aria-label=\"Abrir menú\"\n title=\"Abrir menú\"\n className=\"fixed left-3 top-3 z-30 flex h-9 w-9 items-center justify-center rounded-md border border-[var(--tema-borde)] bg-[var(--tema-fondo)] text-[#565656] shadow-sm md:hidden\"\n >\n <ICONO_NAV_MENU_MOVIL size={TAMANO_BOTON} aria-hidden=\"true\" />\n </button>\n\n {abiertoMovil && (\n <button\n type=\"button\"\n aria-label=\"Cerrar menú\"\n onClick={() => setAbiertoMovil(false)}\n className=\"fixed inset-0 z-30 bg-black/40 md:hidden\"\n />\n )}\n\n <aside\n data-colapsado={colapsado ? \"true\" : \"false\"}\n data-abierto-movil={abiertoMovil ? \"true\" : \"false\"}\n onClick={(e) => {\n // Elegir un destino cierra el cajon movil.\n if ((e.target as HTMLElement).closest(\"a\")) setAbiertoMovil(false);\n }}\n className={`group/side fixed inset-y-0 left-0 z-40 flex w-60 shrink-0 flex-col border-r border-[var(--tema-borde)] bg-[var(--tema-fondo)] transition-transform md:sticky md:top-0 md:h-screen md:translate-x-0 md:transition-[width] md:data-[colapsado=true]:w-14 ${\n abiertoMovil ? \"translate-x-0\" : \"-translate-x-full\"\n }`}\n >\n <div className=\"flex flex-col gap-2 border-b border-[var(--tema-borde)] px-4 py-4 md:group-data-[colapsado=true]/side:items-center md:group-data-[colapsado=true]/side:px-1\">\n <div className=\"md:group-data-[colapsado=true]/side:hidden\">{cabecera}</div>\n <button\n type=\"button\"\n onClick={alternar}\n aria-label={colapsado ? \"Expandir menú\" : \"Contraer menú\"}\n title={colapsado ? \"Expandir menú\" : \"Contraer menú\"}\n aria-expanded={!colapsado}\n className=\"hidden w-fit items-center rounded-md p-1 text-[#807f7f] transition hover:bg-[var(--tema-badge-neutro)] hover:text-[var(--tema-primario)] md:flex\"\n >\n {colapsado ? (\n <ICONO_NAV_EXPANDIR size={TAMANO_BOTON} aria-hidden=\"true\" />\n ) : (\n <ICONO_NAV_COLAPSAR size={TAMANO_BOTON} aria-hidden=\"true\" />\n )}\n </button>\n <button\n type=\"button\"\n onClick={() => setAbiertoMovil(false)}\n aria-label=\"Cerrar menú lateral\"\n className=\"absolute right-2 top-2 rounded-md p-1 text-[#807f7f] md:hidden\"\n >\n <ICONO_CERRAR size={TAMANO_BOTON} aria-hidden=\"true\" />\n </button>\n </div>\n\n <nav className=\"flex flex-1 flex-col gap-6 overflow-y-auto px-3 py-4 text-sm font-medium text-[#565656] md:group-data-[colapsado=true]/side:px-1.5\">\n {children}\n </nav>\n\n <div className=\"border-t border-[var(--tema-borde)] px-4 py-3 md:group-data-[colapsado=true]/side:px-1\">\n {pie}\n </div>\n </aside>\n </>\n );\n}\n","/**\n * Logica pura del marco de tablas (change `tablas-columnas-fijas`): claves y preferencias por tabla y por usuario\n * (columnas ocultas + densidad), CSS de columnas ocultas y offsets de las columnas fijas. Sin React, para probarla\n * sin montar componentes. El componente vive en `components/tabla/MarcoTabla.tsx`.\n *\n * MECANISMO: `localStorage` (preferencia de UI puramente del cliente, igual que `preferenciasTabla.ts`). La clave va\n * versionada y lleva un hash corto del usuario (nunca el id crudo): dos usuarios del mismo navegador no comparten\n * preferencias. Toda lectura/escritura va en try/catch: con almacenamiento bloqueado la tabla funciona con el estado\n * en memoria.\n */\n\nexport type Densidad = \"compacta\" | \"comoda\";\n\nexport type PrefsMarco = {\n /** Ids (`data-col`) de las columnas ocultas por el usuario. */\n ocultas: string[];\n densidad: Densidad;\n};\n\nexport const PREFS_MARCO_DEFAULT: PrefsMarco = { ocultas: [], densidad: \"comoda\" };\n\n/** Ids de columna permitidos: se usan dentro de un selector CSS, asi que solo caracteres seguros. */\nconst ID_SEGURO = /^[A-Za-z0-9_-]+$/;\n\n/** Hash FNV-1a de 32 bits en base 36: estable, corto y sin exponer el id del usuario en el almacenamiento. */\nfunction hashCorto(texto: string): string {\n let h = 0x811c9dc5;\n for (let i = 0; i < texto.length; i++) {\n h ^= texto.charCodeAt(i);\n h = Math.imul(h, 0x01000193) >>> 0;\n }\n return h.toString(36);\n}\n\n/** Clave de `localStorage` de una tabla para un usuario (`anon` sin sesion). */\nexport function claveMarco(tabla: string, usuario?: string | null): string {\n return `tabla.marco.v1.${tabla}.${usuario ? hashCorto(usuario) : \"anon\"}`;\n}\n\n/** Lee las preferencias. Nunca lanza: ausencia, JSON corrupto o almacenamiento bloqueado -> defaults. */\nexport function cargarPrefsMarco(clave: string): PrefsMarco {\n try {\n if (typeof window === \"undefined\") return { ...PREFS_MARCO_DEFAULT };\n const crudo = window.localStorage.getItem(clave);\n if (!crudo) return { ...PREFS_MARCO_DEFAULT };\n const p = JSON.parse(crudo) as Partial<PrefsMarco>;\n return {\n ocultas: Array.isArray(p.ocultas) ? p.ocultas.filter((x): x is string => typeof x === \"string\") : [],\n densidad: p.densidad === \"compacta\" ? \"compacta\" : \"comoda\",\n };\n } catch {\n return { ...PREFS_MARCO_DEFAULT };\n }\n}\n\n/** Persiste las preferencias. Errores (cuota, modo privado, SSR) se ignoran. */\nexport function guardarPrefsMarco(clave: string, prefs: PrefsMarco): void {\n try {\n window.localStorage.setItem(clave, JSON.stringify(prefs));\n } catch {\n // Sin almacenamiento: la preferencia vive solo en memoria durante la sesion.\n }\n}\n\n/** Borra las preferencias (boton \"Restablecer\"). */\nexport function borrarPrefsMarco(clave: string): void {\n try {\n window.localStorage.removeItem(clave);\n } catch {\n // Igual que arriba.\n }\n}\n\n/** Regla CSS que oculta las columnas `ocultas` SOLO dentro de la tabla `alcance` (atributo `data-marco-tabla`). */\nexport function cssColumnasOcultas(alcance: string, ocultas: string[]): string {\n const seguras = ocultas.filter((id) => ID_SEGURO.test(id));\n if (seguras.length === 0) return \"\";\n const selectores = seguras.map((id) => `[data-marco-tabla=\"${alcance}\"] [data-col=\"${id}\"]`);\n return `${selectores.join(\",\")}{display:none}`;\n}\n\n/** Offset `left` de cada columna fija (suma de los anchos anteriores) y el ancho total fijo. */\nexport function offsetsAcumulados(anchos: number[]): { offsets: number[]; total: number } {\n const offsets: number[] = [];\n let total = 0;\n for (const ancho of anchos) {\n offsets.push(total);\n total += ancho;\n }\n return { offsets, total };\n}\n","\"use client\";\n\nimport {\n createContext,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\n\nimport {\n ICONO_COLUMNAS,\n ICONO_DENSIDAD_COMODA,\n ICONO_DENSIDAD_COMPACTA,\n ICONO_RESTABLECER,\n TAMANO_BADGE,\n} from \"@/kit/lib/iconos\";\nimport {\n borrarPrefsMarco,\n cargarPrefsMarco,\n claveMarco,\n cssColumnasOcultas,\n type Densidad,\n guardarPrefsMarco,\n offsetsAcumulados,\n PREFS_MARCO_DEFAULT,\n type PrefsMarco,\n} from \"@/kit/lib/tablaMarco\";\n\nimport { InfoExplicacion } from \"@/kit/ui/InfoExplicacion\";\n\n/**\n * Marco compartido de TODAS las tablas de datos (change `tablas-columnas-fijas`, lineamiento\n * `docs/lineamientos-ui.md` \"Tablas: columnas fijas y desplazamiento acotado\").\n *\n * Envuelve el `<table>` de cada pantalla (no lo reescribe) y aporta:\n * - contenedor de desplazamiento con encabezado fijo arriba, en dos ajustes (change `listados-ajuste-viewport`):\n * `ajuste=\"pagina\"` en las pantallas de listado (dentro de `PaginaListado`): el marco ocupa el alto restante de la\n * pagina, la pagina NO se desplaza y solo el cuerpo de la tabla lo hace; `ajuste=\"acotado\"` (default) en paginas que si\n * se desplazan (tableros, informes, formularios): alto maximo acotado a la ventana;\n * - pie (`pie`) dentro del marco para el paginador: siempre visible bajo la tabla;\n * - columnas de identidad fijas a la izquierda (`fija(\"izq\", i)`) y de acciones a la derecha (`fija(\"der\")`), con sombra\n * cuando hay contenido desplazado debajo; en movil solo queda fija la columna primaria;\n * - menu \"Columnas\" para ocultar columnas no fijas (`col(id)`) y densidad compacta/comoda, persistidos por tabla y por\n * usuario en localStorage;\n * - Shift+rueda desplaza a lo ancho y el foco de teclado trae la celda a la vista.\n *\n * Los estilos (sticky, offsets, sombras, densidad, impresion) viven en `app/globals.css` bajo `[data-marco-tabla]`.\n * Las exportaciones (PDF/HTML del informe) envuelven su arbol en `<TablaPlana>` y el marco se reduce al contenedor `overflow-x-auto print:overflow-visible` original.\n */\n\n/** Contexto de exportacion: con `true`, `MarcoTabla` pinta solo el contenedor original de la tabla (sin marco, controles ni sticky). */\nconst ContextoTablaPlana = createContext(false);\n\n/** Envuelve un arbol que se exporta (PDF/HTML): sus tablas conservan el layout original. */\nexport function TablaPlana({ children }: { children: ReactNode }) {\n return <ContextoTablaPlana.Provider value>{children}</ContextoTablaPlana.Provider>;\n}\n\n/** Usuario de la sesion (id estable) para separar las preferencias por usuario. Lo provee el layout raiz. */\nconst ContextoUsuarioTablas = createContext<string | null>(null);\n\nexport function UsuarioTablas({ usuario, children }: { usuario?: string | null; children: ReactNode }) {\n return <ContextoUsuarioTablas.Provider value={usuario ?? null}>{children}</ContextoUsuarioTablas.Provider>;\n}\n\nexport type ColumnaOcultable = { id: string; etiqueta: string };\n\n/**\n * `pagina`: la tabla es el contenido principal de una pantalla de listado (`PaginaListado`) y toma el alto restante.\n * `acotado`: la tabla vive dentro de una pagina que se desplaza; su alto maximo se acota (`--marco-alto`, default 70dvh).\n */\nexport type AjusteMarco = \"pagina\" | \"acotado\";\n\nconst CLASE_BOTON =\n \"inline-flex items-center gap-1.5 rounded-md border border-[var(--tema-borde)] px-2 py-1 text-xs font-medium text-[#3c3c3b] transition hover:bg-[var(--tema-badge-neutro)]\";\n\nexport function MarcoTabla({\n clave,\n etiqueta,\n columnas,\n barra,\n alto,\n ajuste = \"acotado\",\n pie,\n controles = true,\n className = \"\",\n clasePlana = \"overflow-x-auto print:overflow-visible\",\n children,\n}: {\n /** Id estable de la tabla (persistencia): `modulo.tabla`. */\n clave: string;\n /** Nombre accesible de la region desplazable. */\n etiqueta: string;\n /** Columnas que el usuario puede ocultar (las que llevan `col(id)`). Sin ellas no hay menu \"Columnas\". */\n columnas?: ColumnaOcultable[];\n /** Controles propios de la tabla que van en la misma barra (a la izquierda). */\n barra?: ReactNode;\n /** Alto maximo del marco en el ajuste `acotado` (CSS). Default `70dvh`, nunca menos de 18rem. */\n alto?: string;\n /** `pagina` en pantallas de listado (la pagina no se desplaza, solo el cuerpo); `acotado` (default) en el resto. */\n ajuste?: AjusteMarco;\n /** Pie del marco (paginador): fila `shrink-0` bajo la region desplazable, siempre visible. */\n pie?: ReactNode;\n /** `false` oculta la barra (densidad/columnas) en tablas minimas; el marco y las columnas fijas se mantienen. */\n controles?: boolean;\n className?: string;\n /** Clases del contenedor bajo `TablaPlana` (exportaciones): las que tenia la tabla antes del marco, para no alterar su layout. */\n clasePlana?: string;\n children: ReactNode;\n}) {\n const plana = useContext(ContextoTablaPlana);\n // Exportaciones: el mismo contenedor que tenian las tablas del informe antes del marco (layout identico al original).\n if (plana)\n return pie ? (\n <>\n <div className={clasePlana}>{children}</div>\n {pie}\n </>\n ) : (\n <div className={clasePlana}>{children}</div>\n );\n return (\n <MarcoActivo\n clave={clave}\n etiqueta={etiqueta}\n columnas={columnas}\n barra={barra}\n alto={alto}\n ajuste={ajuste}\n pie={pie}\n controles={controles}\n className={className}\n >\n {children}\n </MarcoActivo>\n );\n}\n\nfunction MarcoActivo({\n clave,\n etiqueta,\n columnas,\n barra,\n alto,\n ajuste,\n pie,\n controles,\n className,\n children,\n}: {\n clave: string;\n etiqueta: string;\n columnas?: ColumnaOcultable[];\n barra?: ReactNode;\n alto?: string;\n ajuste: AjusteMarco;\n pie?: ReactNode;\n controles: boolean;\n className: string;\n children: ReactNode;\n}) {\n const usuario = useContext(ContextoUsuarioTablas);\n const claveLs = claveMarco(clave, usuario);\n const alcance = useId();\n const scroll = useRef<HTMLDivElement>(null);\n const [prefs, setPrefs] = useState<PrefsMarco>(PREFS_MARCO_DEFAULT);\n const [menu, setMenu] = useState(false);\n const zonaMenu = useRef<HTMLDivElement>(null);\n\n // Preferencias: defaults en el primer render (SSR e hidratacion iguales), luego lo guardado.\n useEffect(() => {\n setPrefs(cargarPrefsMarco(claveLs));\n }, [claveLs]);\n\n const persistir = useCallback(\n (nuevas: PrefsMarco) => {\n setPrefs(nuevas);\n guardarPrefsMarco(claveLs, nuevas);\n },\n [claveLs],\n );\n\n const ocultasValidas = prefs.ocultas.filter((id) => columnas?.some((c) => c.id === id));\n const css = cssColumnasOcultas(alcance, ocultasValidas);\n\n // Sombras: hay contenido debajo de las fijas izquierdas (scrollLeft > 0) o de la de acciones (falta por la derecha).\n const actualizarSombras = useCallback(() => {\n const el = scroll.current;\n if (!el) return;\n const izq = el.scrollLeft > 0;\n const der = el.scrollLeft + el.clientWidth < el.scrollWidth - 1;\n el.toggleAttribute(\"data-sombra-izq\", izq);\n el.toggleAttribute(\"data-sombra-der\", der);\n }, []);\n\n // Offsets de las columnas fijas izquierdas, medidos del encabezado (cada render y al cambiar de tamano). Se escriben\n // como variables CSS directo en el DOM: no hay estado, no hay renders extra.\n useLayoutEffect(() => {\n const el = scroll.current;\n if (!el) return;\n const medir = () => {\n const fila = el.querySelector(\"thead tr\");\n const izq = fila ? Array.from(fila.querySelectorAll<HTMLElement>(':scope > [data-fija=\"izq\"]')) : [];\n const { offsets, total } = offsetsAcumulados(izq.map((c) => c.offsetWidth));\n offsets.forEach((o, i) => el.style.setProperty(`--fija-izq-${i}`, `${o}px`));\n el.style.setProperty(\"--fija-izq-total\", `${total}px`);\n el.setAttribute(\"data-fijas-izq\", String(izq.length));\n const der = fila?.querySelector<HTMLElement>(':scope > [data-fija=\"der\"]');\n el.style.setProperty(\"--fija-der-total\", `${der?.offsetWidth ?? 0}px`);\n actualizarSombras();\n };\n medir();\n if (typeof ResizeObserver === \"undefined\") return;\n const obs = new ResizeObserver(medir);\n obs.observe(el);\n const tabla = el.querySelector(\"table\");\n if (tabla) obs.observe(tabla);\n return () => obs.disconnect();\n });\n\n // Shift+rueda -> desplazamiento horizontal (listener nativo no pasivo: React registra `wheel` como pasivo).\n useEffect(() => {\n const el = scroll.current;\n if (!el) return;\n const alGirar = (e: WheelEvent) => {\n if (!e.shiftKey || e.deltaY === 0 || Math.abs(e.deltaX) > 0) return;\n if (el.scrollWidth <= el.clientWidth) return;\n el.scrollLeft += e.deltaY;\n e.preventDefault();\n actualizarSombras();\n };\n el.addEventListener(\"wheel\", alGirar, { passive: false });\n return () => el.removeEventListener(\"wheel\", alGirar);\n }, [actualizarSombras]);\n\n // Menu de columnas: Escape o clic fuera lo cierran.\n useEffect(() => {\n if (!menu) return;\n const tecla = (e: KeyboardEvent) => e.key === \"Escape\" && setMenu(false);\n const fuera = (e: MouseEvent) => {\n if (zonaMenu.current && !zonaMenu.current.contains(e.target as Node)) setMenu(false);\n };\n document.addEventListener(\"keydown\", tecla);\n document.addEventListener(\"mousedown\", fuera);\n return () => {\n document.removeEventListener(\"keydown\", tecla);\n document.removeEventListener(\"mousedown\", fuera);\n };\n }, [menu]);\n\n function alternarColumna(id: string) {\n const ocultas = prefs.ocultas.includes(id) ? prefs.ocultas.filter((x) => x !== id) : [...prefs.ocultas, id];\n persistir({ ...prefs, ocultas });\n }\n\n function fijarDensidad(densidad: Densidad) {\n persistir({ ...prefs, densidad });\n }\n\n function restablecer() {\n setPrefs({ ...PREFS_MARCO_DEFAULT });\n borrarPrefsMarco(claveLs);\n }\n\n const hayColumnas = Boolean(columnas && columnas.length > 0);\n\n return (\n <div\n data-marco-ajuste={ajuste}\n className={`flex min-w-0 flex-col gap-2 ${ajuste === \"pagina\" ? \"min-h-0 flex-1\" : \"\"} ${className}`}\n >\n {css && <style>{css}</style>}\n {(controles || barra) && (\n <div className=\"flex shrink-0 flex-wrap items-center gap-2\" data-marco-barra=\"\">\n {barra && <div className=\"mr-auto flex flex-wrap items-center gap-2\">{barra}</div>}\n {controles && (\n <div className=\"ml-auto flex items-center gap-2\">\n {hayColumnas && (\n <div className=\"relative\" ref={zonaMenu}>\n <button\n type=\"button\"\n onClick={() => setMenu((v) => !v)}\n aria-expanded={menu}\n aria-haspopup=\"true\"\n title=\"Mostrar u ocultar columnas\"\n className={CLASE_BOTON}\n >\n <ICONO_COLUMNAS size={TAMANO_BADGE} aria-hidden=\"true\" />\n Columnas\n {ocultasValidas.length > 0 && (\n <span className=\"rounded bg-[var(--tema-badge-neutro)] px-1 tabular-nums\">-{ocultasValidas.length}</span>\n )}\n </button>\n {menu && (\n <div className=\"absolute right-0 top-full z-30 mt-1 w-60 rounded-md border border-[var(--tema-borde)] bg-[var(--tema-fondo)] p-2 shadow-lg\">\n <div role=\"group\" aria-label=\"Columnas visibles\">\n <p className=\"flex items-center gap-1 px-1 pb-1 text-[10px] font-semibold uppercase tracking-wide text-[#9a9a9a]\">\n Columnas visibles\n </p>\n {columnas!.map((c) => {\n const idInput = `${alcance}-${c.id}`;\n return (\n <label\n key={c.id}\n htmlFor={idInput}\n className=\"flex cursor-pointer items-center gap-2 rounded px-1.5 py-1 text-sm text-[#3c3c3b] hover:bg-[var(--tema-badge-neutro)]\"\n >\n <input\n id={idInput}\n type=\"checkbox\"\n checked={!prefs.ocultas.includes(c.id)}\n onChange={() => alternarColumna(c.id)}\n />\n {c.etiqueta}\n </label>\n );\n })}\n </div>\n <button\n type=\"button\"\n onClick={restablecer}\n className=\"mt-2 inline-flex w-full items-center justify-center gap-1.5 rounded border border-[var(--tema-borde)] px-2 py-1 text-xs text-[#3c3c3b] hover:bg-[var(--tema-badge-neutro)]\"\n >\n <ICONO_RESTABLECER size={TAMANO_BADGE} aria-hidden=\"true\" />\n Restablecer\n </button>\n </div>\n )}\n </div>\n )}\n {hayColumnas && <InfoExplicacion id=\"plataforma.tabla_columnas\" />}\n <div className=\"inline-flex items-center overflow-hidden rounded-md border border-[var(--tema-borde)]\" role=\"group\" aria-label=\"Densidad de filas\">\n <BotonDensidad actual={prefs.densidad} valor=\"compacta\" onClick={fijarDensidad} />\n <BotonDensidad actual={prefs.densidad} valor=\"comoda\" onClick={fijarDensidad} />\n </div>\n <InfoExplicacion id=\"plataforma.tabla_densidad\" />\n </div>\n )}\n </div>\n )}\n <div\n ref={scroll}\n role=\"region\"\n aria-label={etiqueta}\n tabIndex={0}\n data-marco-tabla={alcance}\n data-densidad={prefs.densidad}\n onScroll={actualizarSombras}\n onFocus={(e) => {\n // El foco de teclado en una celda o control la trae a la vista; `scroll-padding` (CSS) evita que quede bajo\n // las columnas fijas.\n if (e.target === e.currentTarget) return;\n const celda = (e.target as HTMLElement).closest(\"td,th\");\n celda?.scrollIntoView?.({ block: \"nearest\", inline: \"nearest\" });\n }}\n data-ajuste={ajuste}\n style={alto ? ({ \"--marco-alto\": alto } as React.CSSProperties) : undefined}\n className={`marco-tabla-scroll rounded-lg border border-[var(--tema-borde)] ${ajuste === \"pagina\" ? \"min-h-28\" : \"\"}`}\n >\n {children}\n </div>\n {pie && (\n // Al cambiar de pagina (o de tamano) el cuerpo vuelve arriba: la pagina ya no se desplaza, la tabla si.\n <div\n className=\"shrink-0\"\n data-marco-pie=\"\"\n onClick={(e) => {\n if ((e.target as HTMLElement).closest(\"button\")) scroll.current?.scrollTo?.({ top: 0 });\n }}\n >\n {pie}\n </div>\n )}\n </div>\n );\n}\n\nfunction BotonDensidad({\n actual,\n valor,\n onClick,\n}: {\n actual: Densidad;\n valor: Densidad;\n onClick: (d: Densidad) => void;\n}) {\n const Icono = valor === \"compacta\" ? ICONO_DENSIDAD_COMPACTA : ICONO_DENSIDAD_COMODA;\n const nombre = valor === \"compacta\" ? \"Densidad compacta\" : \"Densidad cómoda\";\n const activo = actual === valor;\n return (\n <button\n type=\"button\"\n aria-pressed={activo}\n aria-label={nombre}\n title={nombre}\n onClick={() => onClick(valor)}\n className={`px-2 py-1 transition ${activo ? \"bg-[var(--tema-primario)] text-white\" : \"text-[#565656] hover:bg-[var(--tema-badge-neutro)]\"}`}\n >\n <Icono size={TAMANO_BADGE} aria-hidden=\"true\" />\n </button>\n );\n}\n","/**\n * CASCARON DE LA APLICACION (layout shell). Es el marcado de `web/src/app/layout.tsx` de la plataforma, extraido a un\n * componente presentacional SIN datos de dominio: dos columnas -> `<aside>` colapsable (cabecera con logo/nombre, grupos\n * de navegacion con titulo overline, pie con usuario + rol + cerrar sesion) + area de contenido `flex-1`.\n *\n * Estructura exacta (no la cambies):\n * <div class=\"flex min-h-full\">\n * <SidebarColapsable cabecera pie> grupos <SeccionNav titulo> -> <EnlaceNav icono etiqueta href/> </SidebarColapsable>\n * <div data-area-contenido class=\"flex min-h-screen min-w-0 flex-1 flex-col overflow-x-clip pt-14 md:pt-0\"> children </div>\n * </div>\n *\n * NO hay barra superior (topbar): usuario, rol y cerrar sesion viven en el PIE del sidebar. NO hay boton de tema: la\n * aplicacion es siempre clara (ver references/modo-oscuro.md).\n * Uso en `src/app/layout.tsx`: `<body ...><CascaronApp ...>{children}</CascaronApp></body>`. Sin sesion (login), NO uses el\n * cascaron: renderiza la pantalla de acceso a pantalla completa.\n */\nimport type { ReactNode } from \"react\";\n\nimport { LinkBase } from \"@/kit/lib/LinkBase\";\nimport { ICONO_CERRAR_SESION, TAMANO_BOTON, type LucideIconType } from \"@/kit/lib/iconos\";\nimport { EnlaceNav, SeccionNav } from \"@/kit/ui/EnlaceNav\";\nimport { InfoExplicacion } from \"@/kit/ui/InfoExplicacion\";\nimport { SidebarColapsable } from \"@/kit/ui/SidebarColapsable\";\nimport { UsuarioTablas } from \"@/kit/tabla/MarcoTabla\";\n\nexport type GrupoNavegacion = {\n /** Titulo overline del grupo (\"Operacion\", \"Administracion\"...). Sin titulo = grupo sin encabezado. */\n titulo?: string;\n enlaces: { href: string; etiqueta: string; icono: LucideIconType }[];\n};\n\nexport function CascaronApp({\n producto,\n hrefInicio = \"/\",\n logo,\n usuario,\n hrefCerrarSesion = \"/auth/logout\",\n grupos,\n pieExtra,\n children,\n}: {\n /** Nombre del producto (14 px, 600, color primario) bajo el logo. */\n producto: string;\n hrefInicio?: string;\n /** Logo opcional (ya dimensionado). Sin logo se muestra solo el nombre. */\n logo?: { src: string; alt: string; ancho: number; alto: number };\n usuario: { nombre: string; rol?: string; idEstable?: string };\n hrefCerrarSesion?: string;\n grupos: GrupoNavegacion[];\n /** Controles extra del pie (p. ej. la campana de notificaciones), a la izquierda del usuario. */\n pieExtra?: ReactNode;\n children: ReactNode;\n}) {\n return (\n <UsuarioTablas usuario={usuario.idEstable}>\n <div className=\"flex min-h-full\">\n <SidebarColapsable\n cabecera={\n <div className=\"flex flex-col gap-2\">\n <LinkBase href={hrefInicio} className=\"flex shrink-0 items-center gap-2\">\n {logo && (\n // eslint-disable-next-line @next/next/no-img-element\n <img src={logo.src} alt={logo.alt} width={logo.ancho} height={logo.alto} />\n )}\n </LinkBase>\n <span className=\"text-sm font-semibold text-[var(--tema-primario)]\">{producto}</span>\n </div>\n }\n pie={\n <div className=\"flex items-center gap-2 md:group-data-[colapsado=true]/side:flex-col\">\n {pieExtra}\n <span className=\"flex min-w-0 flex-1 flex-col leading-tight md:group-data-[colapsado=true]/side:hidden\">\n <span className=\"truncate text-[11px] font-medium text-[#3c3c3b]\" title={usuario.nombre}>\n {usuario.nombre}\n </span>\n {usuario.rol && (\n <span className=\"mt-0.5 inline-flex items-center gap-1\">\n <span\n className=\"w-fit rounded-full bg-[var(--tema-badge-neutro)] px-1.5 py-0.5 text-[10px] font-medium text-[#565656]\"\n title={`Rol: ${usuario.rol}`}\n >\n {usuario.rol}\n </span>\n <InfoExplicacion id=\"plataforma.rol\" />\n </span>\n )}\n </span>\n <a\n href={hrefCerrarSesion}\n title=\"Cerrar sesión\"\n aria-label=\"Cerrar sesión\"\n className=\"flex shrink-0 items-center transition hover:text-[var(--tema-primario)]\"\n >\n <ICONO_CERRAR_SESION size={TAMANO_BOTON} aria-hidden=\"true\" />\n </a>\n </div>\n }\n >\n {grupos.map((g, i) => (\n <SeccionNav key={g.titulo ?? i} titulo={g.titulo}>\n {g.enlaces.map(({ href, etiqueta, icono: Icono }) => (\n <EnlaceNav key={href} href={href} etiqueta={etiqueta} icono={<Icono size={TAMANO_BOTON} aria-hidden=\"true\" />} />\n ))}\n </SeccionNav>\n ))}\n </SidebarColapsable>\n\n {/* `data-area-contenido`: con una pantalla de listado dentro (`PaginaListado`), esta columna toma exactamente el alto\n de la ventana (globals.css) y la pagina no se desplaza: solo el cuerpo de la tabla lo hace. */}\n <div\n data-area-contenido=\"\"\n className=\"flex min-h-screen min-w-0 flex-1 flex-col overflow-x-clip pt-14 transition-[padding] md:pt-0 md:pr-[var(--asistente-ancho,0px)]\"\n >\n {children}\n </div>\n </div>\n </UsuarioTablas>\n );\n}\n","/**\n * Migas / navegacion secundaria. Extraido de `factoraje/MigasFactoraje.tsx` y `factoraje/SubNavFactoraje.tsx` de la\n * plataforma (unicos dos patrones de navegacion secundaria que existen): migas de una linea con enlace \"← Volver\" y\n * sub-navegacion en \"pildoras\" entre vistas hermanas. No hay barra superior ni migas globales: usa estos dos.\n * Generalizado solo en los textos/rutas (props); las clases son las originales.\n */\nimport { LinkBase } from \"@/kit/lib/LinkBase\";\n\n/** Migas: \"← Volver\" (enlace primario subrayado) / valor actual (mono si es un codigo). */\nexport function Migas({\n hrefVolver,\n etiquetaVolver,\n actual,\n actualMono = false,\n}: {\n hrefVolver: string;\n /** Texto del enlace, p. ej. \"Planes\". Se pinta como \"← Planes\". */\n etiquetaVolver: string;\n actual: string;\n actualMono?: boolean;\n}) {\n return (\n <nav aria-label=\"Ruta\" className=\"mb-3 flex flex-wrap items-center gap-2 text-xs text-[#807f7f]\">\n <LinkBase href={hrefVolver} className=\"text-[var(--tema-primario)] underline\">\n ← {etiquetaVolver}\n </LinkBase>\n <span aria-hidden=\"true\">/</span>\n <span className={actualMono ? \"font-mono\" : undefined}>{actual}</span>\n </nav>\n );\n}\n\n/** Sub-navegacion entre vistas hermanas de una misma entidad (pildoras con borde; la activa lleva `aria-current`). */\nexport function SubNav({\n etiqueta,\n secciones,\n activa,\n}: {\n etiqueta: string;\n secciones: readonly { id: string; texto: string; href: string }[];\n activa: string;\n}) {\n return (\n <nav aria-label={etiqueta} className=\"mt-4 flex flex-wrap gap-2 text-sm\">\n {secciones.map((s) => (\n <LinkBase\n key={s.id}\n href={s.href}\n aria-current={s.id === activa ? \"page\" : undefined}\n className={`pulsable rounded-md border px-3 py-1 ${\n s.id === activa\n ? \"border-[var(--tema-primario)] bg-[var(--tema-badge-neutro)] font-semibold\"\n : \"border-[var(--tema-borde)] hover:bg-[var(--tema-badge-neutro)]\"\n }`}\n >\n {s.texto}\n </LinkBase>\n ))}\n </nav>\n );\n}\n","\"use client\";\n\nimport { type ReactNode, useEffect, useId, useRef, useState } from \"react\";\n\nimport { ICONO_CERRAR, TAMANO_BADGE } from \"@/kit/lib/iconos\";\n\nconst BOTON = {\n // Primario = relleno neutro oscuro (no el rojo de marca); el rojo queda reservado a peligro.\n primario:\n \"inline-flex items-center gap-1.5 rounded-md bg-[var(--tema-texto)] px-3 py-1.5 text-sm font-medium text-white transition hover:brightness-125 disabled:opacity-50\",\n secundario:\n \"inline-flex items-center gap-1.5 rounded-md border border-[var(--tema-borde)] px-3 py-1.5 text-sm font-medium text-[#3c3c3b] transition hover:bg-[var(--tema-badge-neutro)] disabled:opacity-50\",\n} as const;\n\n/**\n * Boton que abre un dialogo modal con un formulario (change `ux-listados-compactos`): saca de la vista los\n * formularios de alta que ocupaban la pantalla antes del listado. Sigue el sistema de diseno 7.11: `role=\"dialog\"`,\n * `aria-modal`, titulo asociado, foco al primer campo al abrir, `Escape`, boton Cerrar y clic en el fondo cierran,\n * y el foco vuelve al boton que lo abrio. El contenido (el formulario) se monta solo mientras esta abierto.\n */\nexport function AccionConDialogo({\n etiqueta,\n titulo,\n icono,\n variante = \"secundario\",\n children,\n}: {\n etiqueta: string;\n titulo: string;\n icono?: ReactNode;\n variante?: keyof typeof BOTON;\n children: ReactNode;\n}) {\n const [abierto, setAbierto] = useState(false);\n const disparador = useRef<HTMLButtonElement>(null);\n const panel = useRef<HTMLDivElement>(null);\n const tituloId = useId();\n\n useEffect(() => {\n if (!abierto) return;\n // microtask: el contenido ya esta montado cuando se busca el primer campo.\n queueMicrotask(() => {\n const campo = panel.current?.querySelector<HTMLElement>(\"input, select, textarea\");\n campo?.focus();\n });\n }, [abierto]);\n\n function cerrar() {\n setAbierto(false);\n disparador.current?.focus();\n }\n\n return (\n <>\n <button ref={disparador} type=\"button\" onClick={() => setAbierto(true)} className={BOTON[variante]}>\n {icono}\n {etiqueta}\n </button>\n {abierto && (\n <div\n data-testid=\"dialogo-fondo\"\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4\"\n onClick={cerrar}\n >\n <div\n ref={panel}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={tituloId}\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => {\n if (e.key === \"Escape\") {\n e.stopPropagation();\n cerrar();\n }\n }}\n className=\"max-h-[90vh] w-full max-w-md overflow-y-auto rounded-xl border border-[var(--tema-borde)] bg-[var(--tema-fondo)] p-6 shadow-xl\"\n >\n <div className=\"flex items-start justify-between gap-3\">\n <h2 id={tituloId} className=\"flex items-center gap-2 text-base font-semibold text-[var(--tema-primario-oscuro)]\">\n {icono}\n {titulo}\n </h2>\n <button\n type=\"button\"\n onClick={cerrar}\n aria-label=\"Cerrar\"\n title=\"Cerrar\"\n className=\"rounded-md p-1 text-[#807f7f] transition hover:bg-[var(--tema-badge-neutro)]\"\n >\n <ICONO_CERRAR size={TAMANO_BADGE} aria-hidden=\"true\" />\n </button>\n </div>\n <div className=\"mt-4\">{children}</div>\n </div>\n </div>\n )}\n </>\n );\n}\n","import type { ReactNode } from \"react\";\n\n/**\n * Pantalla de listado que cabe en la ventana (change `listados-ajuste-viewport`, lineamiento `docs/lineamientos-ui.md`\n * \"Tablas\"): la pagina NO se desplaza; solo el cuerpo de la tabla lo hace y el paginador y la barra horizontal quedan\n * siempre visibles al pie.\n *\n * Como funciona (layout, sin numeros magicos): la columna de contenido del layout raiz toma el alto de la ventana cuando\n * contiene un `[data-pagina-listado]` (`globals.css`); esta pagina es una columna flex `flex-1 min-h-0`, la cabecera y\n * las barras no se encogen, y la tabla (`MarcoTabla ajuste=\"pagina\"`) toma el alto restante. Cada envoltorio entre la\n * pagina y el marco lleva `CLASE_REGION_LISTADO` para no romper la cadena `min-h-0`.\n *\n * Sin `\"use client\"`: la usan paginas Server Component.\n */\n\n/** Clases de un envoltorio entre `PaginaListado` y `MarcoTabla ajuste=\"pagina\"` (pasa el alto restante hacia la tabla). */\nexport const CLASE_REGION_LISTADO = \"flex min-h-0 flex-1 flex-col\";\n\nexport function PaginaListado({\n titulo,\n icono,\n descripcion,\n acciones,\n className = \"\",\n children,\n}: {\n titulo: ReactNode;\n /** Icono de 20 px antes del titulo (opcional). */\n icono?: ReactNode;\n /** Una linea junto al titulo; si no cabe se recorta con elipsis y el texto completo queda en el tooltip. */\n descripcion?: string;\n /** Botones o enlaces de la pantalla (a la derecha de la cabecera). */\n acciones?: ReactNode;\n className?: string;\n children: ReactNode;\n}) {\n return (\n <main data-pagina-listado=\"\" className={`flex min-h-0 w-full flex-1 flex-col gap-3 px-6 py-4 ${className}`}>\n <header className=\"flex shrink-0 flex-wrap items-center gap-x-3 gap-y-1\">\n <h1 className=\"flex shrink-0 items-center gap-2 text-xl font-semibold text-[var(--tema-primario-oscuro)]\">\n {icono}\n {titulo}\n </h1>\n {descripcion && (\n <p className=\"min-w-[12rem] flex-1 truncate text-sm text-[#807f7f]\" title={descripcion}>\n {descripcion}\n </p>\n )}\n {acciones && <div className=\"ml-auto flex shrink-0 flex-wrap items-center gap-2\">{acciones}</div>}\n </header>\n {children}\n </main>\n );\n}\n","\"use client\";\n\nimport { type ReactNode, useEffect, useRef } from \"react\";\n\nimport { ICONO_CERRAR, TAMANO_BADGE } from \"@/kit/lib/iconos\";\n\nimport { CLASE_REGION_LISTADO } from \"./PaginaListado\";\n\n/**\n * Modal de detalle con tabla (change `listados-ajuste-viewport`, lineamiento `docs/lineamientos-ui.md` \"Tablas\"): el\n * dialogo nunca crece mas alla de la ventana (`max-h-[90dvh]`, ancho `min(96vw, ...)`); la cabecera y el resumen no se\n * encogen y la tabla (`MarcoTabla ajuste=\"pagina\"` dentro de `children`) toma el alto restante, asi que solo ella se\n * desplaza en ambos ejes con su encabezado y columnas fijas. Antes cada modal crecia con su tabla y se cortaba el pie y\n * las columnas de la derecha.\n *\n * `role=\"dialog\"` + `aria-modal`, titulo asociado (`tituloId`), foco al dialogo al abrir; `Escape`, el boton Cerrar y\n * el clic en el fondo cierran.\n */\nexport function ModalPanel({\n titulo,\n tituloId,\n acciones,\n onCerrar,\n etiquetaCerrar = \"Cerrar\",\n ancho = \"max-w-[min(96vw,100rem)]\",\n children,\n}: {\n /** Contenido del `<h2>` (texto, codigo, explicacion en sitio). */\n titulo: ReactNode;\n tituloId: string;\n /** Botones junto al de cerrar (p. ej. \"Descargar CSV\"). */\n acciones?: ReactNode;\n onCerrar: () => void;\n etiquetaCerrar?: string;\n /** Clase de ancho maximo (Tailwind). */\n ancho?: string;\n children: ReactNode;\n}) {\n const dialogo = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n dialogo.current?.focus();\n }, []);\n\n return (\n <div data-testid=\"modal-fondo\" className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4\" onClick={onCerrar}>\n <div\n ref={dialogo}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={tituloId}\n tabIndex={-1}\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => {\n if (e.key === \"Escape\") {\n e.stopPropagation();\n onCerrar();\n }\n }}\n className={`flex max-h-[90dvh] w-full ${ancho} flex-col gap-3 rounded-xl border border-[var(--tema-borde)] bg-[var(--tema-fondo)] p-4 shadow-xl outline-none`}\n >\n <div data-modal-cabecera=\"\" className=\"flex shrink-0 items-start justify-between gap-3\">\n <h2 id={tituloId} className=\"flex min-w-0 items-center gap-1.5 text-base font-semibold text-[var(--tema-primario-oscuro)]\">\n {titulo}\n </h2>\n <div className=\"flex shrink-0 items-center gap-2\">\n {acciones}\n <button\n type=\"button\"\n onClick={onCerrar}\n aria-label={etiquetaCerrar}\n title={etiquetaCerrar}\n className=\"rounded-md p-1 text-[#807f7f] transition hover:bg-[var(--tema-badge-neutro)]\"\n >\n <ICONO_CERRAR size={TAMANO_BADGE} aria-hidden=\"true\" />\n </button>\n </div>\n </div>\n <div data-modal-cuerpo=\"\" className={`${CLASE_REGION_LISTADO} gap-3`}>\n {children}\n </div>\n </div>\n </div>\n );\n}\n","\"use client\";\n\n/**\n * Pestanas (segmented control). Extraido de `riesgo-credito/secciones/SeccionScoreCombinado.tsx` (clases y atributos\n * ARIA originales: tablist/tab/tabpanel, tabindex itinerante, flechas para cambiar). Misma apariencia: grupo gris\n * `rounded-lg p-1`, pestana activa blanca con `shadow-sm`.\n */\nimport { type KeyboardEvent, type ReactNode, useId, useState } from \"react\";\n\nexport function Pestanas({\n etiqueta,\n pestanas,\n inicial,\n extra,\n}: {\n etiqueta: string;\n pestanas: { id: string; texto: string; contenido: ReactNode }[];\n inicial?: string;\n /** Normalmente el (i) de las pestanas, alineado al centro del grupo. */\n extra?: ReactNode;\n}) {\n const base = useId();\n const [activa, setActiva] = useState(inicial ?? pestanas[0]?.id);\n const ids = pestanas.map((p) => p.id);\n\n const teclado = (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key !== \"ArrowRight\" && e.key !== \"ArrowLeft\") return;\n e.preventDefault();\n const i = ids.indexOf(activa ?? \"\");\n const siguiente = ids[(i + (e.key === \"ArrowRight\" ? 1 : ids.length - 1)) % ids.length];\n setActiva(siguiente);\n document.getElementById(`${base}-pestana-${siguiente}`)?.focus();\n };\n\n return (\n <div className=\"space-y-4\">\n <div role=\"tablist\" aria-label={etiqueta} className=\"inline-flex gap-1 rounded-lg bg-[var(--tema-badge-neutro)] p-1 print:hidden\">\n {pestanas.map((p) => (\n <button\n key={p.id}\n type=\"button\"\n role=\"tab\"\n id={`${base}-pestana-${p.id}`}\n aria-selected={activa === p.id}\n aria-controls={`${base}-panel-${p.id}`}\n tabIndex={activa === p.id ? 0 : -1}\n onClick={() => setActiva(p.id)}\n onKeyDown={teclado}\n className={`rounded-md px-3 py-1 text-xs font-medium ${activa === p.id ? \"bg-[var(--tema-fondo)] text-[var(--tema-primario-oscuro)] shadow-sm\" : \"text-[#565656] hover:text-[var(--tema-primario)]\"}`}\n >\n {p.texto}\n </button>\n ))}\n {extra && <span className=\"self-center pr-1\">{extra}</span>}\n </div>\n {pestanas.map((p) => (\n <div\n key={p.id}\n role=\"tabpanel\"\n id={`${base}-panel-${p.id}`}\n aria-labelledby={`${base}-pestana-${p.id}`}\n // Oculto con clase (no con el atributo `hidden`: el preflight de Tailwind lo fija con !important).\n className={`space-y-3 ${activa !== p.id ? \"hidden print:block\" : \"\"}`}\n >\n {p.contenido}\n </div>\n ))}\n </div>\n );\n}\n","/**\n * PANTALLA DE ACCESO (login). Mismo marcado que la landing publica de la plataforma (`app/page.tsx`, rama sin sesion):\n * `main.reflejo-fondo` centrado sobre `bg-[#f4f8fc]`, cabecera de marca, titulo `text-3xl/4xl`, texto `#565656`, boton primario\n * grande con icono de login y tarjetas de capacidades (`rounded-xl border bg-white p-5 shadow-sm`).\n * La plataforma original no tiene un recuadro de login propio (redirige al proveedor de identidad con un `<a href>`); aqui el\n * boton es un ENLACE al inicio de sesion del proveedor (Microsoft 365 / Entra ID), nunca un formulario con contrasena.\n * No uses logos de terceros: el texto del boton es \"Iniciar sesión con Microsoft 365\" y el icono es ICONO_LOGIN_MICROSOFT.\n */\nimport type { ReactNode } from \"react\";\n\nimport { ICONO_LOGIN_MICROSOFT, TAMANO_BOTON, type LucideIconType } from \"@/kit/lib/iconos\";\n\nexport type CapacidadAcceso = { icono: LucideIconType; titulo: string; descripcion: string };\n\nexport function PantallaAcceso({\n producto,\n titulo,\n descripcion,\n hrefLogin,\n etiquetaBoton = \"Iniciar sesión con Microsoft 365\",\n capacidades = [],\n logo,\n error,\n}: {\n producto: string;\n titulo: string;\n descripcion: string;\n hrefLogin: string;\n etiquetaBoton?: string;\n capacidades?: readonly CapacidadAcceso[];\n /** Logo opcional ya renderizado (p. ej. `<Image .../>`). */\n logo?: ReactNode;\n /** Mensaje de error de acceso (p. ej. \"Tu cuenta no tiene acceso\"). Se pinta con role=\"alert\". */\n error?: string;\n}) {\n return (\n <main className=\"reflejo-fondo flex min-h-screen flex-1 flex-col items-center justify-center gap-10 bg-[#f4f8fc] px-6 py-16\">\n <header className=\"flex items-center gap-2\">\n {logo}\n {logo && <span className=\"h-6 w-px bg-[var(--tema-borde)]\" />}\n <span className=\"text-base font-semibold text-[var(--tema-primario)]\">{producto}</span>\n </header>\n <div className=\"flex max-w-xl flex-col items-center gap-4 text-center\">\n <h1 className=\"text-3xl font-semibold text-[var(--tema-primario-oscuro)] sm:text-4xl\">{titulo}</h1>\n <p className=\"text-base text-[#565656]\">{descripcion}</p>\n {error && (\n <p role=\"alert\" className=\"rounded-md bg-[var(--tema-badge-error)] px-3 py-2 text-sm text-[var(--tema-peligro)]\">\n {error}\n </p>\n )}\n <a\n href={hrefLogin}\n className=\"mt-2 inline-flex items-center gap-2 rounded-md bg-[var(--tema-texto)] px-5 py-2.5 text-sm font-medium text-white transition hover:brightness-125\"\n >\n <ICONO_LOGIN_MICROSOFT size={TAMANO_BOTON} aria-hidden=\"true\" />\n {etiquetaBoton}\n </a>\n </div>\n\n {capacidades.length > 0 && (\n <div className=\"grid w-full max-w-4xl gap-4 sm:grid-cols-3\">\n {capacidades.map(({ icono: Icono, titulo: t, descripcion: d }) => (\n <div key={t} className=\"flex flex-col gap-2 rounded-xl border border-[var(--tema-borde)] bg-white p-5 text-left shadow-sm\">\n <span className=\"flex h-10 w-10 items-center justify-center rounded-lg bg-[var(--tema-badge-neutro)] text-[var(--tema-primario)]\">\n <Icono size={TAMANO_BOTON} aria-hidden=\"true\" />\n </span>\n <h2 className=\"text-sm font-semibold text-[var(--tema-texto)]\">{t}</h2>\n <p className=\"text-xs leading-relaxed text-[#565656]\">{d}</p>\n </div>\n ))}\n </div>\n )}\n </main>\n );\n}\n","import { SpinnerMarca } from \"./SpinnerMarca\";\n\n/**\n * Pantalla de carga a pagina completa (cambio `ux-spinner-marca`). Se usa como\n * `loading.tsx` de las rutas densas: Next.js la muestra AL INSTANTE mientras el Server\n * Component hace su fetch (SSR), en vez de dejar la pantalla congelada/en blanco -- que\n * es lo que hacia sentir el cambio de pantalla \"muy lento\" (pedido del usuario). No es\n * maquillaje: el fetch tarda lo mismo, pero el usuario ve feedback inmediato de marca en\n * lugar de una pantalla muerta, que es la causa real de la lentitud PERCIBIDA.\n */\nexport function PantallaCargando({ etiqueta = \"Cargando...\" }: { etiqueta?: string }) {\n return (\n <div className=\"flex min-h-[60vh] w-full flex-1 items-center justify-center\">\n <SpinnerMarca tamano={140} etiqueta={etiqueta} />\n </div>\n );\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nimport { formatearFechaHora } from \"@/kit/lib/fecha\";\n\n/**\n * Muestra un timestamp UTC en HORA LOCAL del navegador SIN romper la hidratacion\n * (cambio `fix-hydration-fecha`).\n *\n * EL PROBLEMA (React #418): `formatearFechaHora` convierte los timestamps con sufijo UTC\n * a hora local usando `new Date().getHours()` (metodos locales de Date). En el SERVIDOR\n * (SSR en Lambda) la hora local es UTC; en el CLIENTE es la del navegador (p.ej. CDMX,\n * UTC-6). Para el mismo instante el texto difiere -> \"text content does not match\n * server-rendered HTML\" -> React descarta el arbol hidratado y puede romper el render.\n *\n * LA SOLUCION DE RAIZ (sin renunciar a la hora local que pidio el usuario): en el PRIMER\n * render (SSR + primera pintura del cliente) se muestra el MISMO texto determinista para\n * ambos (formato ISO legible, sin conversion), y TRAS montar (`useEffect`, solo cliente)\n * se re-renderiza ya en hora local. Asi el HTML del server y el primer render del cliente\n * coinciden byte a byte (no hay mismatch), y el usuario termina viendo su hora local. No\n * es maquillaje: es el patron correcto de Next para valores dependientes del entorno del\n * cliente (timezone).\n */\nexport function FechaHoraLocal({ iso }: { iso: string | null | undefined }) {\n // SSR + primer render cliente: texto ESTABLE e identico (sin conversion a local).\n const [texto, setTexto] = useState<string>(() => _isoLegible(iso));\n\n useEffect(() => {\n // Ya en el cliente (post-hidratacion): ahora si, hora local del navegador.\n setTexto(formatearFechaHora(iso));\n }, [iso]);\n\n return <span suppressHydrationWarning>{texto}</span>;\n}\n\n/** Formato deterministico e IDENTICO en server y cliente: recorta el ISO a\n * `yyyy/MM/dd HH:mm:ss` sin convertir la zona. Se usa solo para el primer render; el\n * `useEffect` lo reemplaza por la hora local. */\nfunction _isoLegible(iso: string | null | undefined): string {\n if (!iso) return \"—\";\n const m = iso.match(/^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})/);\n if (!m) return iso;\n const [, anio, mes, dia, hora, min, seg] = m;\n return `${anio}/${mes}/${dia} ${hora}:${min}:${seg}`;\n}\n","/**\n * Pagina de contenido \"normal\" (no listado): formularios, tableros, lecturas. Extraido del patron que repiten las\n * pantallas de la plataforma (p. ej. `app/invitaciones/page.tsx`): `main w-full flex-1 px-6 py-10`, `h1` con icono de\n * 20 px, descripcion `mt-1 text-sm text-[#807f7f]` y contenido a `mt-6`. Para listados con tabla usa `PaginaListado`.\n * `ancho`: \"completo\" (tablas/tableros) o max-w-2xl/3xl/4xl centrado (formularios y lecturas).\n */\nimport type { ReactNode } from \"react\";\n\nconst ANCHOS = {\n completo: \"\",\n \"2xl\": \"mx-auto max-w-2xl\",\n \"3xl\": \"mx-auto max-w-3xl\",\n \"4xl\": \"mx-auto max-w-4xl\",\n} as const;\n\nexport function PaginaContenido({\n titulo,\n icono,\n descripcion,\n acciones,\n ancho = \"completo\",\n children,\n}: {\n titulo: ReactNode;\n /** Icono de 20 px (TAMANO_BOTON) antes del titulo. */\n icono?: ReactNode;\n descripcion?: ReactNode;\n /** Botones de la pantalla, alineados a la derecha del encabezado. */\n acciones?: ReactNode;\n ancho?: keyof typeof ANCHOS;\n children: ReactNode;\n}) {\n return (\n <main className={`w-full flex-1 px-6 py-10 ${ANCHOS[ancho]}`}>\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <h1 className=\"flex items-center gap-2 text-xl font-semibold text-[var(--tema-primario-oscuro)]\">\n {icono}\n {titulo}\n </h1>\n {acciones && <div className=\"flex flex-wrap items-center gap-2\">{acciones}</div>}\n </div>\n {descripcion && <p className=\"mt-1 text-sm text-[#807f7f]\">{descripcion}</p>}\n <div className=\"mt-6\">{children}</div>\n </main>\n );\n}\n","\"use client\";\n\nimport { useMemo, useState } from \"react\";\n\nimport {\n ICONO_PAGINA_ANTERIOR,\n ICONO_PAGINA_SIGUIENTE,\n TAMANO_BADGE,\n} from \"@/kit/lib/iconos\";\n\n/**\n * Paginación CLIENT-SIDE sobre una lista ya cargada. Para listas acotadas\n * (decenas–cientos de filas) sin cursor de servidor: paginarlas en el cliente es lo proporcional.\n * Mismo patrón visual que el resto de listados (Anterior/Siguiente + tamaño de página, con iconos).\n *\n * `usePaginacionLocal` corta la lista; `PaginadorLocal` son los controles. Van juntos\n * pero separados para poder probar el corte sin renderizar la UI.\n */\nexport function usePaginacionLocal<T>(items: T[], tamanoInicial = 10) {\n const [tamano, setTamano] = useState(tamanoInicial);\n const [paginaActual, setPaginaActual] = useState(1);\n\n const totalPaginas = Math.max(1, Math.ceil(items.length / tamano));\n // La página vigente nunca puede quedar fuera de rango (p.ej. si la lista encogió por\n // un filtro o un refresh de polling): se acota al leer, sin efectos.\n const pagina = Math.min(paginaActual, totalPaginas);\n\n const itemsPagina = useMemo(() => {\n const inicio = (pagina - 1) * tamano;\n return items.slice(inicio, inicio + tamano);\n }, [items, pagina, tamano]);\n\n return {\n itemsPagina,\n paginaActual: pagina,\n totalPaginas,\n tamano,\n totalItems: items.length,\n siguiente: () => setPaginaActual((p) => Math.min(p + 1, totalPaginas)),\n anterior: () => setPaginaActual((p) => Math.max(p - 1, 1)),\n cambiarTamano: (n: number) => {\n setTamano(n);\n setPaginaActual(1); // el corte cambió: volver al inicio\n },\n };\n}\n\nconst TAMANOS = [10, 25, 50, 100] as const;\n\nexport function PaginadorLocal({\n paginaActual,\n totalPaginas,\n totalItems,\n tamano,\n tamanos = TAMANOS,\n onAnterior,\n onSiguiente,\n onCambiarTamano,\n}: {\n paginaActual: number;\n totalPaginas: number;\n totalItems: number;\n tamano: number;\n /** Tamanos ofrecidos (por omision 10/25/50/100). Los listados por URL usan 25/50/100. */\n tamanos?: readonly number[];\n onAnterior: () => void;\n onSiguiente: () => void;\n /** Sin este callback no se pinta el selector de tamano (p. ej. cuando vive en `BarraListado`). */\n onCambiarTamano?: (n: number) => void;\n}) {\n // Con una sola página no hay nada que paginar: no se renderiza (grids chicos quedan\n // idénticos a como estaban).\n if (totalPaginas <= 1) return null;\n\n const desde = totalItems === 0 ? 0 : (paginaActual - 1) * tamano + 1;\n const hasta = Math.min(paginaActual * tamano, totalItems);\n\n return (\n <div className=\"mt-3 flex flex-wrap items-center justify-between gap-3\">\n <div className=\"flex items-center gap-2\">\n {onCambiarTamano && (\n <>\n <label className=\"text-xs font-medium text-[#807f7f]\">Por página</label>\n <select\n value={tamano}\n onChange={(e) => onCambiarTamano(Number(e.target.value))}\n aria-label=\"Filas por página\"\n className=\"rounded-md border border-[var(--tema-borde)] bg-[var(--tema-fondo)] px-2 py-1.5 text-sm focus:border-[var(--tema-primario)] focus:outline-none\"\n >\n {tamanos.map((n) => (\n <option key={n} value={n}>\n {n}\n </option>\n ))}\n </select>\n </>\n )}\n <span className=\"text-xs text-[#807f7f]\">\n {desde}–{hasta} de {totalItems}\n </span>\n </div>\n\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={onAnterior}\n disabled={paginaActual <= 1}\n aria-label=\"Página anterior\"\n className=\"inline-flex items-center gap-1 rounded-md border border-[var(--tema-borde)] px-3 py-1.5 text-sm font-medium text-[#3c3c3b] transition hover:bg-[var(--tema-badge-neutro)] disabled:opacity-50\"\n >\n <ICONO_PAGINA_ANTERIOR size={TAMANO_BADGE} aria-hidden=\"true\" />\n Anterior\n </button>\n <span className=\"text-xs text-[#807f7f]\">\n {paginaActual} / {totalPaginas}\n </span>\n <button\n type=\"button\"\n onClick={onSiguiente}\n disabled={paginaActual >= totalPaginas}\n aria-label=\"Página siguiente\"\n className=\"inline-flex items-center gap-1 rounded-md border border-[var(--tema-borde)] px-3 py-1.5 text-sm font-medium text-[#3c3c3b] transition hover:bg-[var(--tema-badge-neutro)] disabled:opacity-50\"\n >\n Siguiente\n <ICONO_PAGINA_SIGUIENTE size={TAMANO_BADGE} aria-hidden=\"true\" />\n </button>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { TAMANOS_LISTADO } from \"@/kit/lib/listado\";\nimport { ICONO_CARGANDO } from \"@/kit/lib/iconos\";\nimport { useNavegarListado } from \"@/kit/lib/useNavegarListado\";\n\nimport { PaginadorLocal } from \"./PaginadorLocal\";\n\n/**\n * Paginador de un listado cuyo estado vive en la URL (change `ux-listados-compactos`). Reusa los controles de\n * `PaginadorLocal` (mismo aspecto que los demas grids); solo cambia de donde sale la pagina: `?pagina=N`. El\n * tamano de pagina se elige en `BarraListado`, por eso aqui no se pinta su selector. Al cambiar de pagina se\n * regresa al inicio de la pantalla (`scroll: true`).\n */\nexport function PaginadorUrl({\n pagina,\n totalPaginas,\n totalItems,\n tamano,\n}: {\n pagina: number;\n totalPaginas: number;\n totalItems: number;\n tamano: number;\n}) {\n const { ir, pendiente } = useNavegarListado();\n if (totalPaginas <= 1) return null;\n return (\n <div className=\"relative\" aria-busy={pendiente || undefined}>\n <PaginadorLocal\n paginaActual={pagina}\n totalPaginas={totalPaginas}\n totalItems={totalItems}\n tamano={tamano}\n tamanos={TAMANOS_LISTADO}\n onAnterior={() => ir({ pagina: String(Math.max(1, pagina - 1)) }, { scroll: true })}\n onSiguiente={() => ir({ pagina: String(Math.min(totalPaginas, pagina + 1)) }, { scroll: true })}\n />\n {pendiente && (\n <span role=\"status\" className=\"absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 text-[var(--tema-primario)]\">\n <ICONO_CARGANDO size={14} className=\"animate-spin motion-reduce:animate-none\" aria-hidden=\"true\" />\n <span className=\"sr-only\">Cargando página...</span>\n </span>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { type ReactNode, useEffect, useId, useRef, useState } from \"react\";\n\nimport { ICONO_BUSCAR, ICONO_CARGANDO, ICONO_FILTRO, ICONO_LIMPIAR, TAMANO_BADGE } from \"@/kit/lib/iconos\";\nimport { TAMANO_LISTADO_DEFAULT, TAMANOS_LISTADO } from \"@/kit/lib/listado\";\nimport { useNavegarListado } from \"@/kit/lib/useNavegarListado\";\n\nimport { InfoExplicacion } from \"./InfoExplicacion\";\n\nexport type FiltroListado =\n | {\n tipo?: \"seleccion\";\n clave: string;\n etiqueta: string;\n /** La primera opcion suele ser \"Todos\" con `valor: \"\"` (sin filtro). */\n opciones: { valor: string; etiqueta: string }[];\n }\n | { tipo: \"numero\"; clave: string; etiqueta: string; min?: number; max?: number };\n\nconst DEBOUNCE_MS = 300;\nconst CAMPO =\n \"rounded-md border border-[var(--tema-borde)] bg-[var(--tema-fondo)] px-2 py-1.5 text-sm text-[#3c3c3b] focus:border-[var(--tema-primario)] focus:outline-none\";\n\n/**\n * Barra de un listado (change `ux-listados-compactos`): busqueda de texto, filtros de la pantalla,\n * tamano de pagina y conteo. Todo vive en la URL (`useNavegarListado`), asi que un enlace copiado reproduce la\n * misma vista; cualquier cambio regresa a la pagina 1.\n *\n * La busqueda espera 300 ms sin teclear (o `Enter`) y navega UNA vez. Vive en su propio `<form role=\"search\">`\n * con `preventDefault`: `Enter` aqui nunca envia otro formulario de la pantalla. `Escape` o el boton X limpian.\n * Los filtros de seleccion aplican al elegir; los numericos al salir del campo o con `Enter`.\n */\nexport function BarraListado({\n filtros,\n totalFiltrado,\n total,\n placeholder = \"Buscar...\",\n etiquetaBusqueda = \"Buscar\",\n extra,\n}: {\n filtros: FiltroListado[];\n totalFiltrado: number;\n total: number;\n placeholder?: string;\n /** Rotulo (label) del campo de busqueda. */\n etiquetaBusqueda?: string;\n /** Controles adicionales a la derecha (p. ej. alternar vista tabla/tarjetas). */\n extra?: ReactNode;\n}) {\n const { ir, pendiente, params } = useNavegarListado();\n const qUrl = params.get(\"q\") ?? \"\";\n const [texto, setTexto] = useState(qUrl);\n const [numeros, setNumeros] = useState<Record<string, string>>(() =>\n Object.fromEntries(filtros.filter((f) => f.tipo === \"numero\").map((f) => [f.clave, params.get(f.clave) ?? \"\"])),\n );\n const idBuscar = useId();\n const temporizador = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Si la URL cambia por fuera (atras/adelante, un enlace), el campo la refleja.\n useEffect(() => setTexto(qUrl), [qUrl]);\n useEffect(() => () => cancelar(), []);\n\n function cancelar() {\n if (temporizador.current) clearTimeout(temporizador.current);\n temporizador.current = null;\n }\n\n function aplicarBusqueda(valor: string) {\n cancelar();\n if (valor.trim() === qUrl.trim()) return;\n ir({ q: valor.trim() || null });\n }\n\n function alEscribir(valor: string) {\n setTexto(valor);\n cancelar();\n temporizador.current = setTimeout(() => aplicarBusqueda(valor), DEBOUNCE_MS);\n }\n\n function limpiar() {\n setTexto(\"\");\n aplicarBusqueda(\"\");\n }\n\n function aplicarNumero(clave: string) {\n const valor = (numeros[clave] ?? \"\").trim();\n if (valor === (params.get(clave) ?? \"\")) return;\n ir({ [clave]: valor || null });\n }\n\n function alEnviar(e: React.FormEvent<HTMLFormElement>) {\n e.preventDefault();\n e.stopPropagation();\n cancelar();\n const cambios: Record<string, string | null> = {};\n if (texto.trim() !== qUrl.trim()) cambios.q = texto.trim() || null;\n for (const [clave, valor] of Object.entries(numeros)) {\n if (valor.trim() !== (params.get(clave) ?? \"\")) cambios[clave] = valor.trim() || null;\n }\n if (Object.keys(cambios).length > 0) ir(cambios);\n }\n\n const tamano = params.get(\"tamano\") ?? String(TAMANO_LISTADO_DEFAULT);\n\n return (\n <form\n role=\"search\"\n onSubmit={alEnviar}\n className=\"flex flex-wrap items-end gap-x-3 gap-y-2 rounded-lg border border-[var(--tema-borde)] bg-[#f9fafb] px-3 py-2\"\n >\n <div className=\"flex min-w-[16rem] flex-1 flex-col gap-1\">\n <label htmlFor={idBuscar} className=\"text-xs font-medium text-[#565656]\">\n {etiquetaBusqueda}\n </label>\n <div className=\"relative\">\n <ICONO_BUSCAR\n size={14}\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute left-2 top-1/2 -translate-y-1/2 text-[#807f7f]\"\n />\n <input\n id={idBuscar}\n type=\"search\"\n value={texto}\n onChange={(e) => alEscribir(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Escape\" && texto) {\n e.preventDefault();\n limpiar();\n }\n }}\n placeholder={placeholder}\n autoComplete=\"off\"\n spellCheck={false}\n className={`${CAMPO} w-full pl-7 pr-8 [&::-webkit-search-cancel-button]:hidden`}\n />\n {texto && (\n <button\n type=\"button\"\n onClick={limpiar}\n aria-label=\"Limpiar búsqueda\"\n title=\"Limpiar búsqueda\"\n className=\"absolute right-1 top-1/2 -translate-y-1/2 rounded p-1 text-[#807f7f] transition hover:bg-[var(--tema-badge-neutro)]\"\n >\n <ICONO_LIMPIAR size={12} aria-hidden=\"true\" />\n </button>\n )}\n </div>\n </div>\n\n {filtros.length > 0 && (\n <ICONO_FILTRO size={TAMANO_BADGE} aria-hidden=\"true\" className=\"mb-2 hidden text-[#807f7f] sm:block\" />\n )}\n {filtros.map((f) => {\n const id = `${idBuscar}-${f.clave}`;\n return (\n <div key={f.clave} className=\"flex flex-col gap-1\">\n <label htmlFor={id} className=\"text-xs font-medium text-[#565656]\">\n {f.etiqueta}\n </label>\n {f.tipo === \"numero\" ? (\n <input\n id={id}\n type=\"number\"\n inputMode=\"numeric\"\n min={f.min}\n max={f.max}\n value={numeros[f.clave] ?? \"\"}\n onChange={(e) => setNumeros((n) => ({ ...n, [f.clave]: e.target.value }))}\n onBlur={() => aplicarNumero(f.clave)}\n className={`${CAMPO} w-24`}\n />\n ) : (\n <select\n id={id}\n value={params.get(f.clave) ?? \"\"}\n onChange={(e) => ir({ [f.clave]: e.target.value || null })}\n className={CAMPO}\n >\n {f.opciones.map((o) => (\n <option key={o.valor} value={o.valor}>\n {o.etiqueta}\n </option>\n ))}\n </select>\n )}\n </div>\n );\n })}\n\n <div className=\"flex flex-col gap-1\">\n <label htmlFor={`${idBuscar}-tamano`} className=\"text-xs font-medium text-[#565656]\">\n Por página\n </label>\n <select\n id={`${idBuscar}-tamano`}\n aria-label=\"Filas por página\"\n value={tamano}\n onChange={(e) => ir({ tamano: e.target.value === String(TAMANO_LISTADO_DEFAULT) ? null : e.target.value })}\n className={CAMPO}\n >\n {TAMANOS_LISTADO.map((n) => (\n <option key={n} value={n}>\n {n}\n </option>\n ))}\n </select>\n </div>\n\n <div className=\"ml-auto flex items-center gap-3 pb-1.5\">\n {pendiente ? (\n <span role=\"status\" className=\"inline-flex items-center gap-1 text-xs text-[#807f7f]\">\n <ICONO_CARGANDO size={12} aria-hidden=\"true\" className=\"animate-spin text-[var(--tema-primario)] motion-reduce:animate-none\" />\n Actualizando...\n </span>\n ) : (\n <span className=\"inline-flex items-center gap-1 text-xs text-[#807f7f]\" aria-live=\"polite\">\n {totalFiltrado === total ? `${total} en total` : `${totalFiltrado} de ${total}`}\n <InfoExplicacion id=\"plataforma.listado_resultados\" />\n </span>\n )}\n {extra}\n </div>\n </form>\n );\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\n\nimport type { ExplicacionId } from \"@/kit/lib/explicaciones\";\nimport { ICONO_ORDENAR_ASC, ICONO_ORDENAR_DESC, ICONO_ORDENAR_NEUTRO } from \"@/kit/lib/iconos\";\nimport type { Direccion } from \"@/kit/lib/listado\";\nimport { useNavegarListado } from \"@/kit/lib/useNavegarListado\";\n\nimport { InfoExplicacion } from \"./InfoExplicacion\";\n\n/**\n * Encabezado ordenable de un listado por URL (change `ux-listados-compactos`; sistema de diseno 7.3). El `th`\n * lleva `aria-sort`; el boton alterna asc -> desc -> orden por omision de la pantalla (borra `orden`/`dir`) y escribe `orden`/`dir` en la URL, asi\n * que ordena TODO el resultado filtrado (no solo la pagina visible). La explicacion (i) va fuera del boton.\n */\nexport function EncabezadoOrdenUrl({\n clave,\n etiqueta,\n icono,\n info,\n ordenActual,\n dirActual,\n alineado = \"left\",\n celda,\n}: {\n clave: string;\n etiqueta: string;\n icono?: ReactNode;\n info: ExplicacionId;\n ordenActual: string;\n dirActual: Direccion;\n alineado?: \"left\" | \"right\";\n /** Atributos del marco de tablas para el `th`: `{...fija(\"izq\", 0)}` o `{...col(\"id\")}` (change `tablas-columnas-fijas`). */\n celda?: Record<string, string | number | undefined>;\n}) {\n const { ir } = useNavegarListado();\n // La columna del orden por omision tambien se marca activa: el listado SI esta ordenado por ella.\n const activa = ordenActual === clave;\n const dir = activa ? dirActual : null;\n const Flecha = dir === \"asc\" ? ICONO_ORDENAR_ASC : dir === \"desc\" ? ICONO_ORDENAR_DESC : ICONO_ORDENAR_NEUTRO;\n const descripcion = dir === \"asc\" ? \"ascendente\" : dir === \"desc\" ? \"descendente\" : \"sin ordenar\";\n\n function alternar() {\n if (!activa) return ir({ orden: clave, dir: \"asc\" });\n if (dir === \"asc\") return ir({ orden: clave, dir: \"desc\" });\n return ir({ orden: null, dir: null });\n }\n\n return (\n <th\n {...celda}\n scope=\"col\"\n aria-sort={dir === \"asc\" ? \"ascending\" : dir === \"desc\" ? \"descending\" : \"none\"}\n className={`whitespace-nowrap px-3 py-2 font-medium ${alineado === \"right\" ? \"text-right\" : \"\"}`}\n >\n <span className={`inline-flex items-center gap-1 ${alineado === \"right\" ? \"justify-end\" : \"\"}`}>\n <button\n type=\"button\"\n onClick={alternar}\n title={`Ordenar por ${etiqueta}`}\n aria-label={`Ordenar por ${etiqueta} (orden actual: ${descripcion})`}\n className={`inline-flex items-center gap-1 transition hover:text-[var(--tema-primario)] ${\n activa ? \"text-[var(--tema-primario)]\" : \"\"\n }`}\n >\n {icono}\n {etiqueta}\n <Flecha size={12} aria-hidden=\"true\" className={activa ? \"\" : \"opacity-40\"} />\n </button>\n <InfoExplicacion id={info} />\n </span>\n </th>\n );\n}\n","/**\n * Atributos de celda del marco de tablas (change `tablas-columnas-fijas`). SIN \"use client\": las paginas Server\n * Component llaman `fija()` / `col()` y pintan `CeldaIdentidad` al armar su `<table>` (una funcion exportada desde un\n * modulo cliente no se puede llamar en el servidor). El comportamiento vive en `MarcoTabla.tsx` y `app/globals.css`.\n */\n\ntype AtributosFija = {\n \"data-fija\": \"izq\" | \"der\";\n \"data-fija-idx\"?: number;\n \"data-fija-primaria\"?: \"\";\n};\n\n/**\n * Marca una celda (`th` o `td`) como fija. `izq` lleva el indice de la columna fija (0, 1, 2, 3, en orden de izquierda a\n * derecha); la 0 es la columna primaria salvo `{ primaria: true }` en otra (p. ej. cuando la 0 es una casilla). La\n * primaria es la unica que sigue fija en pantallas angostas. Se aplica igual en el encabezado y en cada fila.\n */\nexport function fija(lado: \"izq\" | \"der\", idx = 0, opciones?: { primaria?: boolean }): AtributosFija {\n if (lado === \"der\") return { \"data-fija\": \"der\" };\n const primaria = opciones?.primaria ?? idx === 0;\n return primaria\n ? { \"data-fija\": \"izq\", \"data-fija-idx\": idx, \"data-fija-primaria\": \"\" }\n : { \"data-fija\": \"izq\", \"data-fija-idx\": idx };\n}\n\n/** Marca una celda como parte de la columna ocultable `id` (el mismo id que se declara en `columnas`). */\nexport function col(id: string): { \"data-col\": string } {\n return { \"data-col\": id };\n}\n\n/** Texto de identidad largo (razon social): una linea con elipsis y el texto completo como tooltip. */\nexport function CeldaIdentidad({ texto, className = \"\" }: { texto: string | null | undefined; className?: string }) {\n const valor = texto ?? \"\";\n return (\n <span title={valor} className={`block max-w-[16rem] truncate ${className}`}>\n {valor}\n </span>\n );\n}\n\n/**\n * Estilo unico de una accion de fila con icono + texto corto (enlace o boton), en linea o dentro del menu \"⋯\" de\n * `AccionesFila` (change `avance-rfc-acciones-compactas`; antes vivia solo en Analitica).\n */\nexport const CLASE_ACCION_FILA =\n \"inline-flex items-center gap-1 whitespace-nowrap rounded-md border border-[var(--tema-borde)] px-2.5 py-1 text-xs hover:bg-[var(--tema-badge-neutro)] disabled:opacity-50\";\n","\"use client\";\n\nimport { type ReactNode, useRef, useState } from \"react\";\n\nimport type { ExplicacionId } from \"@/kit/lib/explicaciones\";\nimport {\n ICONO_ARRASTRAR_COLUMNA,\n ICONO_COLUMNA_OCULTA,\n ICONO_COLUMNA_VISIBLE,\n ICONO_COLUMNAS,\n ICONO_ORDENAR_ASC,\n ICONO_ORDENAR_DESC,\n ICONO_ORDENAR_NEUTRO,\n ICONO_RESTABLECER,\n TAMANO_BADGE,\n} from \"@/kit/lib/iconos\";\nimport { useTablaPreferencias } from \"@/kit/lib/useTablaPreferencias\";\n\nimport { InfoExplicacion } from \"./InfoExplicacion\";\nimport { fija } from \"@/kit/tabla/celdas\";\nimport { type AjusteMarco, MarcoTabla } from \"@/kit/tabla/MarcoTabla\";\n\n/**\n * Columna de una tabla configurable. `id` es estable (se usa para persistir orden/ancho);\n * `encabezado` es el contenido del <th> (texto + icono); `celda` recibe la fila y devuelve\n * el contenido del <td>. `alineado` afecta th y td. `minAncho` en px (default 80).\n * `fijaAncho`: si true, la columna respeta su ancho (util para UUID que debe verse\n * completo); si false/omitido, crece con el contenido salvo que el usuario la redimensione.\n */\nexport type ColumnaConfig<T> = {\n id: string;\n encabezado: ReactNode;\n /** Version del encabezado para el menu de columnas (que vive dentro de un <button>): sin controles\n * interactivos anidados, como el icono de explicacion en sitio. Si se omite se usa `encabezado`. */\n encabezadoMenu?: ReactNode;\n /**\n * Explicacion en sitio de la columna (catalogo `lib/explicaciones.ts`). Se pinta FUERA del boton de orden\n * (sin controles anidados) y no aparece en el menu de columnas. Obligatoria por lineamiento\n * (docs/lineamientos-ui.md): la compuerta `cobertura-explicaciones.test.ts` la exige.\n */\n info?: ExplicacionId;\n celda: (fila: T) => ReactNode;\n alineado?: \"left\" | \"right\";\n /** Ancho inicial en px (antes de que el usuario redimensione). Default 160. */\n anchoDefault?: number;\n /**\n * Si true, el encabezado se vuelve un boton que ordena la PAGINA VISIBLE por esta\n * columna (client-side, sobre las filas ya cargadas). Es un orden POR PAGINA, no\n * global -- la aria-label lo declara explicitamente para no confundir con el orden\n * global por fecha (que va por URL, filtros por URL). Requiere\n * `valorOrden` para saber por que valor comparar.\n */\n ordenable?: boolean;\n /** Valor por el que ordenar cuando `ordenable`. String -> orden alfabetico\n * (localeCompare); number -> orden numerico. Ausente/undefined -> al final. */\n valorOrden?: (fila: T) => string | number | undefined;\n /** Etiqueta legible para la aria-label del boton de orden (ej. \"Monto\"). Si se\n * omite y `encabezado` es un string, se usa ese; si no, \"esta columna\". */\n etiquetaOrden?: string;\n};\n\n/** Estado de orden client-side por pagina: id de la columna + direccion. */\ntype OrdenPagina = { id: string; dir: \"asc\" | \"desc\" } | null;\n\n/** Ancho base de una columna que aun no se ha redimensionado. */\nconst ANCHO_BASE = 160;\n\n/**\n * Tabla con columnas REORDENABLES (arrastrar el encabezado), REDIMENSIONABLES (arrastrar\n * el borde derecho del encabezado) y con menu de mostrar/ocultar columnas. Las\n * preferencias persisten en localStorage por `clavePrefs` (ver preferenciasTabla.ts).\n * Lineamiento del sistema: cualquier tabla puede usar este componente.\n *\n * Drag & drop nativo (HTML5 draggable) y resize con eventos de mouse -- sin dependencias\n * externas. Accesible: el asa de arrastre tiene aria-label; el menu de columnas es de\n * checkboxes.\n *\n * Change `tablas-columnas-fijas`: se pinta dentro de `MarcoTabla` (desplazamiento acotado, encabezado fijo, densidad).\n * `columnaFija` (casilla) e `idsFijos` (identidad: codigo, nombre...) quedan fijas a la izquierda y no se pueden\n * arrastrar ni ocultar; `columnaAcciones` queda fija a la derecha.\n */\nexport function TablaConfigurable<T>({\n columnas,\n filas,\n claveFila,\n clavePrefs,\n columnaFija,\n columnaAcciones,\n idsFijos = [],\n etiqueta = \"Resultados\",\n mensajeVacio = \"Sin resultados.\",\n ajuste,\n pie,\n barraExtra,\n}: {\n columnas: ColumnaConfig<T>[];\n filas: T[];\n claveFila: (fila: T) => string;\n clavePrefs: string;\n /** Contenido opcional de una primera columna FIJA no reordenable (ej. checkbox). */\n columnaFija?: { encabezado?: ReactNode; celda: (fila: T) => ReactNode };\n /** Contenido opcional de una ultima columna FIJA no reordenable (ej. acciones). */\n columnaAcciones?: { encabezado?: ReactNode; celda: (fila: T) => ReactNode };\n /** Ids de columnas de identidad fijas a la izquierda (en este orden), despues de `columnaFija`. */\n idsFijos?: string[];\n /** Nombre accesible de la region desplazable. */\n etiqueta?: string;\n mensajeVacio?: ReactNode;\n /** Ajuste del marco: `pagina` en pantallas de listado (`PaginaListado`), `acotado` (default) en el resto. */\n ajuste?: AjusteMarco;\n /** Pie del marco (paginador), siempre visible bajo la tabla. */\n pie?: ReactNode;\n /** Controles de la pantalla que van en la misma barra de la tabla (p. ej. el indicador en vivo): ahorra una fila. */\n barraExtra?: ReactNode;\n}) {\n const fijos = idsFijos.filter((id) => columnas.some((c) => c.id === id));\n const idsDefault = columnas.map((c) => c.id).filter((id) => !fijos.includes(id));\n const { idsVisibles, idsOrdenados, ocultas, anchoDe, mover, redimensionar, alternarVisible, restablecer } =\n useTablaPreferencias(clavePrefs, idsDefault);\n\n const porId = new Map(columnas.map((c) => [c.id, c]));\n const [menuAbierto, setMenuAbierto] = useState(false);\n const [orden, setOrden] = useState<OrdenPagina>(null);\n const arrastrando = useRef<number | null>(null);\n\n /**\n * Orden client-side SOBRE LA PAGINA VISIBLE (las `filas` que ya llegaron). No pide\n * datos nuevos ni reordena el universo completo -- solo la pagina cargada. Cuando no\n * hay orden activo, respeta el orden en que vinieron las filas (sin copiar/mutar el\n * arreglo original).\n */\n const filasOrdenadas = (() => {\n if (!orden) return filas;\n const col = porId.get(orden.id);\n if (!col?.valorOrden) return filas;\n const factor = orden.dir === \"asc\" ? 1 : -1;\n return [...filas].sort((a, b) => {\n const va = col.valorOrden!(a);\n const vb = col.valorOrden!(b);\n // Los valores ausentes se van al final SIEMPRE (asc o desc), para que no ensucien\n // el orden util con placeholders.\n if (va === undefined || va === null || va === \"\") return 1;\n if (vb === undefined || vb === null || vb === \"\") return -1;\n if (typeof va === \"number\" && typeof vb === \"number\") {\n return (va - vb) * factor;\n }\n return String(va).localeCompare(String(vb), \"es\") * factor;\n });\n })();\n\n function alternarOrdenColumna(id: string) {\n setOrden((prev) => {\n if (prev?.id !== id) return { id, dir: \"asc\" };\n if (prev.dir === \"asc\") return { id, dir: \"desc\" };\n return null; // tercer clic: quita el orden y vuelve al orden original de la pagina\n });\n }\n\n const colSpanTotal =\n fijos.length + idsVisibles.length + (columnaFija ? 1 : 0) + (columnaAcciones ? 1 : 0);\n // Indice de la primera columna de identidad fija (la casilla, si existe, ocupa el 0).\n const baseFijos = columnaFija ? 1 : 0;\n const atributosFijo = (i: number) => fija(\"izq\", baseFijos + i, { primaria: i === 0 });\n const atributosCasilla = fija(\"izq\", 0, { primaria: fijos.length === 0 });\n\n // Ancho EFECTIVO de una columna: el persistido por el usuario, o el default de la\n // columna, o el base. Con `table-fixed` este ancho MANDA (a diferencia de table-auto,\n // que lo reparte por contenido e ignora los width).\n const anchoEfectivo = (id: string): number => {\n const persistido = anchoDe(id);\n if (persistido !== undefined) return persistido;\n return porId.get(id)?.anchoDefault ?? ANCHO_BASE;\n };\n\n // Ancho total de la tabla = columnas fija/acciones (anchos fijos) + suma de visibles.\n const ANCHO_FIJA = 44; // checkbox\n const ANCHO_ACCIONES = 96;\n const anchoTabla =\n (columnaFija ? ANCHO_FIJA : 0) +\n (columnaAcciones ? ANCHO_ACCIONES : 0) +\n [...fijos, ...idsVisibles].reduce((suma, id) => suma + anchoEfectivo(id), 0);\n\n // Encabezado de una columna: boton de orden por pagina (si aplica) + explicacion en sitio fuera del boton.\n const contenidoEncabezado = (col: ColumnaConfig<T>) => (\n <>\n {col.ordenable ? (\n <EncabezadoOrdenable\n columnaId={col.id}\n contenido={col.encabezado}\n etiqueta={col.etiquetaOrden ?? (typeof col.encabezado === \"string\" ? col.encabezado : \"esta columna\")}\n orden={orden}\n onAlternar={() => alternarOrdenColumna(col.id)}\n />\n ) : (\n col.encabezado\n )}\n {col.info && <InfoExplicacion id={col.info} />}\n </>\n );\n\n // Controles propios (columnas reordenables/redimensionables) en la barra del marco compartido.\n const barra = (\n <div className=\"relative flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => setMenuAbierto((v) => !v)}\n title=\"Mostrar u ocultar columnas\"\n aria-label=\"Mostrar u ocultar columnas\"\n className=\"inline-flex items-center gap-1.5 rounded-md border border-[var(--tema-borde)] px-2.5 py-1.5 text-xs font-medium text-[#3c3c3b] transition hover:bg-[var(--tema-badge-neutro)]\"\n >\n <ICONO_COLUMNAS size={TAMANO_BADGE} aria-hidden=\"true\" />\n Columnas\n </button>\n <InfoExplicacion id=\"plataforma.tabla_columnas\" />\n <button\n type=\"button\"\n onClick={restablecer}\n title=\"Restablecer orden y tamaño de columnas\"\n aria-label=\"Restablecer columnas\"\n className=\"inline-flex items-center gap-1.5 rounded-md border border-[var(--tema-borde)] px-2.5 py-1.5 text-xs font-medium text-[#3c3c3b] transition hover:bg-[var(--tema-badge-neutro)]\"\n >\n <ICONO_RESTABLECER size={TAMANO_BADGE} aria-hidden=\"true\" />\n Restablecer\n </button>\n\n {menuAbierto && (\n <div className=\"absolute left-0 top-full z-30 mt-1 w-56 rounded-md border border-[var(--tema-borde)] bg-[var(--tema-fondo)] p-2 shadow-lg\">\n <p className=\"flex items-center gap-1 px-1 pb-1 text-[10px] font-semibold uppercase tracking-wide text-[#9a9a9a]\">\n Columnas visibles\n </p>\n {idsOrdenados.map((id) => {\n const col = porId.get(id);\n if (!col) return null;\n const visible = !ocultas.has(id);\n const Icono = visible ? ICONO_COLUMNA_VISIBLE : ICONO_COLUMNA_OCULTA;\n return (\n <button\n key={id}\n type=\"button\"\n onClick={() => alternarVisible(id)}\n className=\"flex w-full items-center gap-2 rounded px-1.5 py-1 text-left text-sm text-[#3c3c3b] transition hover:bg-[var(--tema-badge-neutro)]\"\n >\n <Icono size={14} aria-hidden=\"true\" className={visible ? \"\" : \"opacity-40\"} />\n <span className={visible ? \"\" : \"opacity-50\"}>{col.encabezadoMenu ?? col.encabezado}</span>\n </button>\n );\n })}\n </div>\n )}\n {barraExtra}\n </div>\n );\n\n return (\n <MarcoTabla clave={clavePrefs} etiqueta={etiqueta} barra={barra} ajuste={ajuste} pie={pie}>\n\n {/* table-fixed + width explicito: asi el `width` de cada columna MANDA (con\n table-auto el navegador lo reparte por contenido e ignora los anchos, por eso\n \"no expandia\"). La tabla crece a lo ancho y el contenedor hace scroll-x. */}\n <table\n className=\"table-fixed divide-y divide-[var(--tema-borde)] text-sm\"\n style={{ width: anchoTabla, minWidth: \"100%\" }}\n >\n <colgroup>\n {columnaFija && <col style={{ width: ANCHO_FIJA }} />}\n {fijos.map((id) => (\n <col key={id} style={{ width: anchoEfectivo(id) }} />\n ))}\n {idsVisibles.map((id) => (\n <col key={id} style={{ width: anchoEfectivo(id) }} />\n ))}\n {columnaAcciones && <col style={{ width: ANCHO_ACCIONES }} />}\n </colgroup>\n <thead>\n <tr className=\"text-left text-xs font-medium text-[#807f7f]\">\n {columnaFija && (\n <th className=\"px-3 py-2\" {...atributosCasilla}>\n {columnaFija.encabezado ?? null}\n </th>\n )}\n {fijos.map((id, i) => {\n const col = porId.get(id)!;\n return (\n <th key={id} className=\"relative overflow-hidden px-3 py-2\" {...atributosFijo(i)}>\n <span className={`flex items-center gap-1 truncate ${col.alineado === \"right\" ? \"justify-end\" : \"\"}`}>\n {contenidoEncabezado(col)}\n </span>\n <ResizerColumna\n anchoActual={anchoEfectivo(id)}\n onFinRedimension={(nuevoAncho) => redimensionar(id, nuevoAncho)}\n />\n </th>\n );\n })}\n {idsVisibles.map((id) => {\n const col = porId.get(id);\n if (!col) return null;\n const idxOrden = idsOrdenados.indexOf(id);\n return (\n <th\n key={id}\n // El <th> NO es draggable (antes lo era y competia con el resize,\n // por eso \"no expandia\"). El reorden se activa SOLO desde el asa\n // (icono grip). El drop se acepta a nivel <th>.\n className=\"relative overflow-hidden px-3 py-2\"\n onDragOver={(e) => e.preventDefault()}\n onDrop={() => {\n if (arrastrando.current !== null && arrastrando.current !== idxOrden) {\n mover(arrastrando.current, idxOrden);\n }\n arrastrando.current = null;\n }}\n >\n <span\n className={`flex items-center gap-1 truncate ${\n col.alineado === \"right\" ? \"justify-end\" : \"\"\n }`}\n >\n {/* SOLO el asa es arrastrable -> reordenar es explicito y no pelea\n con el resizer del borde. */}\n <span\n draggable\n onDragStart={() => {\n arrastrando.current = idxOrden;\n }}\n onDragEnd={() => {\n arrastrando.current = null;\n }}\n aria-label=\"Arrastrar para reordenar la columna\"\n className=\"shrink-0 cursor-grab text-[#c4c4c4] hover:text-[var(--tema-primario)]\"\n >\n <ICONO_ARRASTRAR_COLUMNA size={12} aria-hidden=\"true\" />\n </span>\n {contenidoEncabezado(col)}\n </span>\n {/* Asa de redimension en el borde derecho. Parte del ancho actual y\n persiste al soltar. */}\n <ResizerColumna\n anchoActual={anchoEfectivo(id)}\n onFinRedimension={(nuevoAncho) => redimensionar(id, nuevoAncho)}\n />\n </th>\n );\n })}\n {columnaAcciones && (\n <th className=\"px-3 py-2\" {...fija(\"der\")}>\n {columnaAcciones.encabezado ?? null}\n </th>\n )}\n </tr>\n </thead>\n <tbody className=\"divide-y divide-[var(--tema-borde)]\">\n {filasOrdenadas.length === 0 ? (\n <tr>\n <td colSpan={colSpanTotal} className=\"px-3 py-6 text-center text-sm text-[#807f7f]\">\n {mensajeVacio}\n </td>\n </tr>\n ) : (\n filasOrdenadas.map((fila) => (\n <tr key={claveFila(fila)} className=\"text-[#3c3c3b]\">\n {columnaFija && (\n <td className=\"px-3 py-2\" {...atributosCasilla}>\n {columnaFija.celda(fila)}\n </td>\n )}\n {fijos.map((id, i) => {\n const col = porId.get(id)!;\n return (\n <td\n key={id}\n {...atributosFijo(i)}\n className={`overflow-hidden px-3 py-2 align-top ${\n col.alineado === \"right\" ? \"text-right tabular-nums\" : \"\"\n }`}\n >\n {col.celda(fila)}\n </td>\n );\n })}\n {idsVisibles.map((id) => {\n const col = porId.get(id);\n if (!col) return null;\n return (\n <td\n key={id}\n className={`overflow-hidden px-3 py-2 align-top ${\n col.alineado === \"right\" ? \"text-right tabular-nums\" : \"\"\n }`}\n >\n {col.celda(fila)}\n </td>\n );\n })}\n {columnaAcciones && (\n <td className=\"px-3 py-2\" {...fija(\"der\")}>\n {columnaAcciones.celda(fila)}\n </td>\n )}\n </tr>\n ))\n )}\n </tbody>\n </table>\n </MarcoTabla>\n );\n}\n\n/**\n * Encabezado de una columna ORDENABLE por pagina. Es un boton (accesible) cuya\n * aria-label DECLARA explicitamente que el orden es \"en esta pagina\" -- para que el\n * usuario no lo confunda con un orden global sobre todo el universo (ese solo existe\n * para fecha de emision, via URL). Muestra la flecha asc/desc segun el estado, o el\n * icono neutro cuando esta columna no es la ordenada.\n */\nfunction EncabezadoOrdenable({\n columnaId,\n contenido,\n etiqueta,\n orden,\n onAlternar,\n}: {\n columnaId: string;\n contenido: ReactNode;\n etiqueta: string;\n orden: OrdenPagina;\n onAlternar: () => void;\n}) {\n const activa = orden?.id === columnaId;\n const dir = activa ? orden!.dir : null;\n const Flecha =\n dir === \"asc\" ? ICONO_ORDENAR_ASC : dir === \"desc\" ? ICONO_ORDENAR_DESC : ICONO_ORDENAR_NEUTRO;\n const descripcionDir =\n dir === \"asc\" ? \"ascendente\" : dir === \"desc\" ? \"descendente\" : \"sin ordenar\";\n return (\n <button\n type=\"button\"\n onClick={onAlternar}\n title=\"Ordena solo la pagina visible (no todo el universo)\"\n aria-label={`Ordenar por ${etiqueta} en esta pagina (orden actual: ${descripcionDir})`}\n className={`inline-flex items-center gap-1 truncate font-medium transition hover:text-[var(--tema-primario)] ${\n activa ? \"text-[var(--tema-primario)]\" : \"\"\n }`}\n >\n {contenido}\n <Flecha size={12} aria-hidden=\"true\" className={activa ? \"\" : \"opacity-40\"} />\n </button>\n );\n}\n\n/** Asa de redimension: una franja fina en el borde derecho del <th>. Arrastrar con el\n * mouse llama `onResize(delta)` con el desplazamiento horizontal en px. */\n/**\n * Asa de redimension: franja en el borde derecho del <th>. Al presionar, guarda el\n * ancho de partida y la X inicial; en cada movimiento calcula el ancho ABSOLUTO\n * (anchoActual + desplazamiento) y lo reporta, de modo que el ancho manda de forma\n * fluida sin acumular error de closures. Persiste el ancho final al soltar.\n */\nfunction ResizerColumna({\n anchoActual,\n onFinRedimension,\n}: {\n anchoActual: number;\n onFinRedimension: (nuevoAncho: number) => void;\n}) {\n function onMouseDown(e: React.MouseEvent) {\n e.preventDefault();\n e.stopPropagation();\n const inicioX = e.clientX;\n const inicioAncho = anchoActual;\n let ultimoAncho = anchoActual;\n\n function onMove(ev: MouseEvent) {\n ultimoAncho = Math.max(60, inicioAncho + (ev.clientX - inicioX));\n onFinRedimension(ultimoAncho);\n }\n function onUp() {\n onFinRedimension(ultimoAncho);\n window.removeEventListener(\"mousemove\", onMove);\n window.removeEventListener(\"mouseup\", onUp);\n document.body.style.cursor = \"\";\n document.body.style.userSelect = \"\";\n }\n // Cursor y bloqueo de seleccion global mientras se arrastra (mejor UX).\n document.body.style.cursor = \"col-resize\";\n document.body.style.userSelect = \"none\";\n window.addEventListener(\"mousemove\", onMove);\n window.addEventListener(\"mouseup\", onUp);\n }\n\n return (\n <span\n role=\"separator\"\n aria-label=\"Redimensionar columna\"\n aria-orientation=\"vertical\"\n onMouseDown={onMouseDown}\n draggable={false}\n onDragStart={(e) => e.preventDefault()}\n // Franja mas ancha (w-2) y translucida a la derecha, con linea visible al hover\n // para que sea facil de agarrar.\n className=\"absolute right-0 top-0 z-10 h-full w-2 cursor-col-resize select-none border-r-2 border-transparent hover:border-[var(--tema-primario)]\"\n />\n );\n}\n","\"use client\";\n\nimport type { LucideIconType as LucideIcon } from \"@/kit/lib/iconos\";\n\nimport type { ExplicacionId } from \"@/kit/lib/explicaciones\";\nimport { TAMANO_BADGE } from \"@/kit/lib/iconos\";\n\nimport { InfoExplicacion } from \"./InfoExplicacion\";\n\n/**\n * Campos de filtro compartidos por todos los buscadores: mismo aspecto, mismas etiquetas con icono y `label` asociado. Son\n * NO controlados (`defaultValue`): el formulario lee los valores con `FormData` al enviar.\n */\n\n/** Etiqueta de encabezado (icono + texto) para las columnas de la tabla configurable.\n * Ya NO envuelve un <th> (eso lo pone TablaConfigurable): es solo el contenido. */\nexport function EtiquetaCol({\n icono: Icono,\n texto,\n info,\n}: {\n icono?: LucideIcon;\n texto: string;\n /** Explicacion en sitio del encabezado (catalogo `lib/explicaciones.ts`). */\n info?: ExplicacionId;\n}) {\n return (\n <span className=\"inline-flex items-center gap-1\">\n {Icono && <Icono size={TAMANO_BADGE} aria-hidden=\"true\" />}\n {texto}\n {info && <InfoExplicacion id={info} />}\n </span>\n );\n}\n\nexport function Campo({\n id,\n name,\n etiqueta,\n defaultValue,\n tipo = \"text\",\n icono: Icono,\n}: {\n id: string;\n name: string;\n etiqueta: string;\n defaultValue: string;\n tipo?: string;\n icono?: LucideIcon;\n}) {\n return (\n <div className=\"flex flex-col gap-1\">\n <label htmlFor={id} className=\"inline-flex items-center gap-1 text-xs font-medium text-[#3c3c3b]\">\n {Icono ? <Icono size={TAMANO_BADGE} aria-hidden=\"true\" /> : null}\n {etiqueta}\n </label>\n <input\n id={id}\n name={name}\n type={tipo}\n defaultValue={defaultValue}\n className=\"w-full rounded-md border border-[var(--tema-borde)] px-2 py-1.5 text-sm focus:border-[var(--tema-primario)] focus:outline-none\"\n />\n </div>\n );\n}\n\nexport function CampoSelect({\n id,\n name,\n etiqueta,\n defaultValue,\n opciones,\n icono: Icono,\n}: {\n id: string;\n name: string;\n etiqueta: string;\n defaultValue: string;\n opciones: { valor: string; etiqueta: string }[];\n icono?: LucideIcon;\n}) {\n return (\n <div className=\"flex flex-col gap-1\">\n <label htmlFor={id} className=\"inline-flex items-center gap-1 text-xs font-medium text-[#3c3c3b]\">\n {Icono ? <Icono size={TAMANO_BADGE} aria-hidden=\"true\" /> : null}\n {etiqueta}\n </label>\n <select\n id={id}\n name={name}\n defaultValue={defaultValue}\n className=\"w-full rounded-md border border-[var(--tema-borde)] bg-[var(--tema-fondo)] px-2 py-1.5 text-sm focus:border-[var(--tema-primario)] focus:outline-none\"\n >\n {opciones.map((o) => (\n <option key={o.valor} value={o.valor}>\n {o.etiqueta}\n </option>\n ))}\n </select>\n </div>\n );\n}\n","/**\n * KPI / metrica de la plataforma. Extraido TAL CUAL de `JobDetalleVivo.tsx` (Metrica, GrupoMetricas, IconoConEtiqueta):\n * es la tarjeta de KPI \"completa\" (icono de 12 px, valor, linea de contexto, barra de progreso y variante destacada).\n * Para la tarjeta simple (etiqueta + valor + nota) usa `Metrica` de `@/kit/ui/Insignia`.\n * `info` (explicacion (i)) es OBLIGATORIA en este kit.\n */\nimport type { ReactNode } from \"react\";\n\nimport type { ExplicacionId } from \"@/kit/lib/explicaciones\";\nimport type { LucideIconType } from \"@/kit/lib/iconos\";\nimport { InfoExplicacion } from \"@/kit/ui/InfoExplicacion\";\n\nexport function IconoConEtiqueta({ Icono, texto, info }: { Icono: LucideIconType; texto: ReactNode; info?: ExplicacionId }) {\n return (\n <span className=\"inline-flex items-center gap-1\">\n <Icono size={16} aria-hidden=\"true\" />\n {texto}\n {info && <InfoExplicacion id={info} />}\n </span>\n );\n}\n\nexport function MetricaKpi({\n etiqueta,\n valor,\n icono: Icono,\n destacada = false,\n sub,\n progreso,\n info,\n}: {\n etiqueta: string;\n valor: string | number;\n icono: LucideIconType;\n // `info`: explicacion en sitio de la metrica (catalogo `lib/explicaciones.ts`); obligatoria por lineamiento.\n info: ExplicacionId;\n // `destacada`: metrica clave del grupo. Se remarca con borde e icono en color primario y un valor mas grande.\n destacada?: boolean;\n // `sub`: linea pequena de contexto bajo el valor. Se omite si no aplica.\n sub?: string;\n // `progreso`: barra de avance (0-100) bajo el valor, con su etiqueta accesible.\n progreso?: { porcentaje: number; etiqueta: string };\n}) {\n const claseTarjeta = destacada\n ? \"rounded-lg border-2 border-[var(--tema-primario)] bg-[var(--tema-badge-neutro)] px-4 py-3\"\n : \"rounded-lg border border-[var(--tema-borde)] px-4 py-3\";\n const claseEtiqueta = destacada\n ? \"flex items-center gap-1 text-xs font-medium text-[var(--tema-primario)]\"\n : \"flex items-center gap-1 text-xs text-[#807f7f]\";\n const claseValor = destacada\n ? \"mt-1 text-2xl font-bold text-[var(--tema-primario-oscuro)]\"\n : \"mt-1 text-lg font-semibold text-[var(--tema-primario-oscuro)]\";\n return (\n <div className={claseTarjeta}>\n <p className={claseEtiqueta}>\n <Icono size={12} aria-hidden=\"true\" />\n {etiqueta}\n {info && <InfoExplicacion id={info} />}\n </p>\n <p className={claseValor}>{valor}</p>\n {sub ? <p className=\"mt-0.5 text-xs text-[#807f7f]\">{sub}</p> : null}\n {progreso ? (\n <div\n role=\"progressbar\"\n aria-label={progreso.etiqueta}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={progreso.porcentaje}\n className=\"mt-2 h-1.5 w-full overflow-hidden rounded-full bg-[var(--tema-borde)]\"\n >\n <div\n className=\"h-full rounded-full bg-[var(--tema-primario)] transition-all\"\n style={{ width: `${progreso.porcentaje}%` }}\n />\n </div>\n ) : null}\n </div>\n );\n}\n\n/** Subtitulo de un grupo de metricas, para que las cajitas se lean agrupadas por concepto en vez de un mar plano. */\nexport function GrupoMetricas({ titulo, icono: Icono, children }: {\n titulo: string;\n icono: LucideIconType;\n children: ReactNode;\n}) {\n return (\n <section className=\"mt-4\">\n <h3 className=\"flex items-center gap-1.5 text-xs font-semibold uppercase tracking-wide text-[#807f7f]\">\n <Icono size={13} aria-hidden=\"true\" />\n {titulo}\n </h3>\n <div className=\"mt-2 grid grid-cols-2 gap-3 sm:grid-cols-4\">{children}</div>\n </section>\n );\n}\n\n/** Rejilla de KPI de la plataforma (extraida de `riesgo-credito/piezas.tsx`): 1 col movil, 2 `sm`, 4 `lg`. */\nexport function RejillaMetricas({ children }: { children: ReactNode }) {\n return <div className=\"grid gap-3 sm:grid-cols-2 lg:grid-cols-4\">{children}</div>;\n}\n\n/** Rotulo de un bloque o grafica con su (i) (extraido de `riesgo-credito/piezas.tsx`). */\nexport function Rotulo({ texto, info }: { texto: string; info: ExplicacionId }) {\n return (\n <p className=\"flex items-center gap-1 text-xs font-medium text-[#565656]\">\n <span>{texto}</span>\n <InfoExplicacion id={info} />\n </p>\n );\n}\n","\"use client\";\n\nimport {\n Children,\n isValidElement,\n type ReactNode,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\n\nimport { InfoExplicacion } from \"@/kit/ui/InfoExplicacion\";\nimport { CLASE_ACCION_FILA } from \"@/kit/tabla/celdas\";\nimport { ICONO_ACCIONES_FILA, TAMANO_BADGE } from \"@/kit/lib/iconos\";\nimport type { LucideIconType as LucideIcon } from \"@/kit/lib/iconos\";\n\n/**\n * Celda compacta de acciones por fila (change `tablas-columnas-fijas`). Hasta 2 acciones se pintan en linea (botones de\n * icono con `title`/`aria-label`, o enlaces cortos); con mas de 2, un solo boton \"...\" abre un menu. El menu es\n * `position: fixed` y vive en un portal en `body` (calculado del boton) para no quedar recortado por el marco desplazable ni\n * debajo de otras celdas fijas. Escape, clic fuera o elegir una accion lo cierran; si la accion abre un dialogo\n * (`aria-modal`), el menu sigue montado hasta que el dialogo se cierra (desmontarlo cerraria el dialogo). Va dentro de la\n * celda fija derecha (`fija(\"der\")`).\n */\nexport function AccionesFila({\n etiqueta = \"Más acciones\",\n children,\n}: {\n etiqueta?: string;\n children: ReactNode;\n}) {\n const acciones = Children.toArray(children).filter(\n (c) => isValidElement(c) || (typeof c === \"string\" && c.trim() !== \"\")\n );\n const [abierto, setAbierto] = useState(false);\n const [pos, setPos] = useState<{ top: number; right: number }>({\n top: 0,\n right: 0,\n });\n const boton = useRef<HTMLButtonElement>(null);\n const menu = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!abierto) return;\n const tecla = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n setAbierto(false);\n boton.current?.focus();\n }\n };\n const fuera = (e: MouseEvent) => {\n const t = e.target as Node;\n if (!menu.current?.contains(t) && !boton.current?.contains(t))\n setAbierto(false);\n };\n // Un desplazamiento de la pagina o de la tabla mueve el boton: se cierra en vez de dejar el menu flotando en otro\n // lugar (salvo desplazamientos dentro del propio menu o de un dialogo abierto desde el).\n const desplazar = (e: Event) => {\n if (menu.current?.contains(e.target as Node) || hayDialogo()) return;\n setAbierto(false);\n };\n document.addEventListener(\"keydown\", tecla);\n document.addEventListener(\"mousedown\", fuera);\n window.addEventListener(\"scroll\", desplazar, true);\n return () => {\n document.removeEventListener(\"keydown\", tecla);\n document.removeEventListener(\"mousedown\", fuera);\n window.removeEventListener(\"scroll\", desplazar, true);\n };\n }, [abierto]);\n\n function hayDialogo(): boolean {\n return Boolean(menu.current?.querySelector('[aria-modal=\"true\"]'));\n }\n\n if (acciones.length <= 2) {\n return (\n <div className=\"flex items-center justify-end gap-1 whitespace-nowrap\">\n {acciones}\n </div>\n );\n }\n\n function alternar() {\n const r = boton.current?.getBoundingClientRect();\n if (r)\n setPos({\n top: r.bottom + 4,\n right: Math.max(8, window.innerWidth - r.right),\n });\n setAbierto((v) => !v);\n }\n\n return (\n <div className=\"flex justify-end\">\n <button\n ref={boton}\n type=\"button\"\n onClick={alternar}\n aria-label={etiqueta}\n title={etiqueta}\n aria-haspopup=\"menu\"\n aria-expanded={abierto}\n className=\"inline-flex items-center rounded-md border border-[var(--tema-borde)] p-1 text-[#565656] transition hover:bg-[var(--tema-badge-neutro)] hover:text-[var(--tema-primario)]\"\n >\n <ICONO_ACCIONES_FILA size={TAMANO_BADGE} aria-hidden=\"true\" />\n </button>\n {abierto &&\n createPortal(\n <div\n ref={menu}\n role=\"menu\"\n aria-label={etiqueta}\n style={{ top: pos.top, right: pos.right }}\n // Elegir una accion cierra el menu, salvo que haya abierto un dialogo (vive dentro del menu).\n onClickCapture={() =>\n setTimeout(() => {\n if (!hayDialogo()) setAbierto(false);\n }, 0)\n }\n className=\"fixed z-50 flex min-w-40 flex-col items-stretch gap-1 rounded-md border border-[var(--tema-borde)] bg-[var(--tema-fondo)] p-1.5 text-left shadow-lg [&>*]:justify-start\"\n >\n {acciones}\n </div>,\n document.body\n )}\n </div>\n );\n}\n\n/**\n * Accion de fila con icono + texto corto y, opcional, su (i) al lado (change `avance-rfc-acciones-compactas`). Sirve en\n * linea y dentro del menu \"⋯\" de `AccionesFila` con el mismo aspecto (`CLASE_ACCION_FILA`). `disabled` mientras la\n * accion corre; el spinner y el resultado los pinta la fila, porque el menu se cierra al elegir.\n */\nexport function BotonAccionFila({\n icono: Icono,\n etiqueta,\n ariaLabel,\n onClick,\n disabled = false,\n info,\n}: {\n icono: LucideIcon;\n etiqueta: string;\n ariaLabel?: string;\n onClick: () => void;\n disabled?: boolean;\n info?: Parameters<typeof InfoExplicacion>[0][\"id\"];\n}) {\n return (\n <span className=\"inline-flex items-center gap-1\">\n <button type=\"button\" onClick={onClick} disabled={disabled} aria-label={ariaLabel} className={CLASE_ACCION_FILA}>\n <Icono size={12} aria-hidden=\"true\" />\n {etiqueta}\n </button>\n {info && <InfoExplicacion id={info} />}\n </span>\n );\n}\n"]}
|