@kaufmann-lab/ui 0.1.9 → 0.1.11
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/fesm2022/kaufmann-lab-ui.mjs +1842 -438
- package/fesm2022/kaufmann-lab-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/src/tokens/base.css +22 -0
- package/types/kaufmann-lab-ui.d.ts +617 -139
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kaufmann-lab-ui.mjs","sources":["../../../projects/ui/src/lib/icon/icons/activity.ts","../../../projects/ui/src/lib/icon/icons/alert-circle.ts","../../../projects/ui/src/lib/icon/icons/alert-octagon.ts","../../../projects/ui/src/lib/icon/icons/alert-triangle.ts","../../../projects/ui/src/lib/icon/icons/award.ts","../../../projects/ui/src/lib/icon/icons/bar-chart.ts","../../../projects/ui/src/lib/icon/icons/bell.ts","../../../projects/ui/src/lib/icon/icons/bus.ts","../../../projects/ui/src/lib/icon/icons/calculator.ts","../../../projects/ui/src/lib/icon/icons/calendar.ts","../../../projects/ui/src/lib/icon/icons/car.ts","../../../projects/ui/src/lib/icon/icons/cart.ts","../../../projects/ui/src/lib/icon/icons/check.ts","../../../projects/ui/src/lib/icon/icons/check-circle.ts","../../../projects/ui/src/lib/icon/icons/check-square.ts","../../../projects/ui/src/lib/icon/icons/chevron-down.ts","../../../projects/ui/src/lib/icon/icons/chevron-left.ts","../../../projects/ui/src/lib/icon/icons/chevron-left-bar.ts","../../../projects/ui/src/lib/icon/icons/chevron-right.ts","../../../projects/ui/src/lib/icon/icons/clipboard.ts","../../../projects/ui/src/lib/icon/icons/clock.ts","../../../projects/ui/src/lib/icon/icons/credit-card.ts","../../../projects/ui/src/lib/icon/icons/download.ts","../../../projects/ui/src/lib/icon/icons/edit.ts","../../../projects/ui/src/lib/icon/icons/external-link.ts","../../../projects/ui/src/lib/icon/icons/eye.ts","../../../projects/ui/src/lib/icon/icons/eye-off.ts","../../../projects/ui/src/lib/icon/icons/file.ts","../../../projects/ui/src/lib/icon/icons/filter.ts","../../../projects/ui/src/lib/icon/icons/gauge.ts","../../../projects/ui/src/lib/icon/icons/gift.ts","../../../projects/ui/src/lib/icon/icons/grid.ts","../../../projects/ui/src/lib/icon/icons/history.ts","../../../projects/ui/src/lib/icon/icons/inbox.ts","../../../projects/ui/src/lib/icon/icons/layers.ts","../../../projects/ui/src/lib/icon/icons/list.ts","../../../projects/ui/src/lib/icon/icons/map.ts","../../../projects/ui/src/lib/icon/icons/map-pin.ts","../../../projects/ui/src/lib/icon/icons/menu.ts","../../../projects/ui/src/lib/icon/icons/mic.ts","../../../projects/ui/src/lib/icon/icons/mic-off.ts","../../../projects/ui/src/lib/icon/icons/more-vertical.ts","../../../projects/ui/src/lib/icon/icons/pause.ts","../../../projects/ui/src/lib/icon/icons/phone.ts","../../../projects/ui/src/lib/icon/icons/play.ts","../../../projects/ui/src/lib/icon/icons/plus.ts","../../../projects/ui/src/lib/icon/icons/search.ts","../../../projects/ui/src/lib/icon/icons/settings.ts","../../../projects/ui/src/lib/icon/icons/shield-check.ts","../../../projects/ui/src/lib/icon/icons/sort.ts","../../../projects/ui/src/lib/icon/icons/star.ts","../../../projects/ui/src/lib/icon/icons/ticket.ts","../../../projects/ui/src/lib/icon/icons/tool.ts","../../../projects/ui/src/lib/icon/icons/trash.ts","../../../projects/ui/src/lib/icon/icons/truck.ts","../../../projects/ui/src/lib/icon/icons/upload-cloud.ts","../../../projects/ui/src/lib/icon/icons/user.ts","../../../projects/ui/src/lib/icon/icons/user-search.ts","../../../projects/ui/src/lib/icon/icons/video.ts","../../../projects/ui/src/lib/icon/icons/x.ts","../../../projects/ui/src/lib/icon/icons/index.ts","../../../projects/ui/src/lib/icon/icon-sprite.ts","../../../projects/ui/src/lib/icon/Icon.ts","../../../projects/ui/src/lib/action-tile/ActionTile.ts","../../../projects/ui/src/lib/admin-badge/AdminBadge.ts","../../../projects/ui/src/lib/spinner/Spinner.ts","../../../projects/ui/src/lib/button/button.ts","../../../projects/ui/src/lib/alert/Alert.ts","../../../projects/ui/src/lib/avatar/Avatar.ts","../../../projects/ui/src/lib/badge/Badge.ts","../../../projects/ui/src/lib/breadcrumb/Breadcrumb.ts","../../../projects/ui/src/lib/card/Card.ts","../../../projects/ui/src/lib/carousel/Carousel.ts","../../../projects/ui/src/lib/checkbox/Checkbox.ts","../../../projects/ui/src/lib/chip/Chip.ts","../../../projects/ui/src/lib/divider/Divider.ts","../../../projects/ui/src/lib/field-label/FieldLabel.ts","../../../projects/ui/src/lib/select/Select.ts","../../../projects/ui/src/lib/company-selector/CompanySelector.ts","../../../projects/ui/src/lib/content-slot/ContentSlot.ts","../../../projects/ui/src/lib/empty-state/EmptyState.ts","../../../projects/ui/src/lib/skeleton/Skeleton.ts","../../../projects/ui/src/lib/content-state/ContentState.ts","../../../projects/ui/src/lib/data-table/DataTable.ts","../../../projects/ui/src/lib/dropdown/Dropdown.ts","../../../projects/ui/src/lib/feature-card/FeatureCard.ts","../../../projects/ui/src/lib/field/Field.ts","../../../projects/ui/src/lib/filter-chips/FilterChips.ts","../../../projects/ui/src/lib/folder-tabs/FolderTabs.ts","../../../projects/ui/src/lib/input/Input.ts","../../../projects/ui/src/lib/link/Link.ts","../../../projects/ui/src/lib/metric-card/MetricCard.ts","../../../projects/ui/src/lib/modal/Modal.ts","../../../projects/ui/src/lib/multi-select/MultiSelect.ts","../../../projects/ui/src/lib/page-header/PageHeader.ts","../../../projects/ui/src/lib/pagination/Pagination.ts","../../../projects/ui/src/lib/panel/Panel.ts","../../../projects/ui/src/lib/portal-header/PortalHeader.ts","../../../projects/ui/src/lib/reserve-block/ReserveBlock.ts","../../../projects/ui/src/lib/section-header/SectionHeader.ts","../../../projects/ui/src/lib/segmented/Segmented.ts","../../../projects/ui/src/lib/stat-tile/StatTile.ts","../../../projects/ui/src/lib/status-pill/StatusPill.ts","../../../projects/ui/src/lib/tabs/Tabs.ts","../../../projects/ui/src/lib/text/Text.ts","../../../projects/ui/src/lib/toast/Toast.ts","../../../projects/ui/src/lib/vehicle-header/VehicleHeader.ts","../../../projects/ui/src/lib/view-toggle/ViewToggle.ts","../../../projects/ui/src/public-api.ts","../../../projects/ui/src/kaufmann-lab-ui.ts"],"sourcesContent":["import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"activity\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const activity: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"alert-circle\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const alertCircle: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" x2=\"12\" y1=\"8\" y2=\"12\" />\n <line x1=\"12\" x2=\"12.01\" y1=\"16\" y2=\"16\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"alert-octagon\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const alertOctagon: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M12 16h.01\" />\n <path d=\"M12 8v4\" />\n <path d=\"M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"alert-triangle\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const alertTriangle: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"award\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const award: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"m15.477 12.89 1.515 8.526a.5.5 0 0 1-.81.47l-3.58-2.687a1 1 0 0 0-1.197 0l-3.586 2.686a.5.5 0 0 1-.81-.469l1.514-8.526\" />\n <circle cx=\"12\" cy=\"8\" r=\"6\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"bar-chart\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const barChart: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M5 21v-6\" />\n <path d=\"M12 21V9\" />\n <path d=\"M19 21V3\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"bell\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const bell: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M10.268 21a2 2 0 0 0 3.464 0\" />\n <path d=\"M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"bus\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const bus: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M8 6v6\" />\n <path d=\"M15 6v6\" />\n <path d=\"M2 12h19.6\" />\n <path d=\"M18 18h3s.5-1.7.8-2.8c.1-.4.2-.8.2-1.2 0-.4-.1-.8-.2-1.2l-1.4-5C20.1 6.8 19.1 6 18 6H4a2 2 0 0 0-2 2v10h3\" />\n <circle cx=\"7\" cy=\"18\" r=\"2\" />\n <path d=\"M9 18h5\" />\n <circle cx=\"16\" cy=\"18\" r=\"2\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"calculator\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const calculator: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <rect width=\"16\" height=\"20\" x=\"4\" y=\"2\" rx=\"2\" />\n <line x1=\"8\" x2=\"16\" y1=\"6\" y2=\"6\" />\n <line x1=\"16\" x2=\"16\" y1=\"14\" y2=\"18\" />\n <path d=\"M16 10h.01\" />\n <path d=\"M12 10h.01\" />\n <path d=\"M8 10h.01\" />\n <path d=\"M12 14h.01\" />\n <path d=\"M8 14h.01\" />\n <path d=\"M12 18h.01\" />\n <path d=\"M8 18h.01\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"calendar\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const calendar: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M8 2v3\" />\n <path d=\"M16 2v3\" />\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" />\n <path d=\"M3 9h18\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"car\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const car: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M19 17h2c.6 0 1-.4 1-1v-3c0-.9-.7-1.7-1.5-1.9C18.7 10.6 16 10 16 10s-1.3-1.4-2.2-2.3c-.5-.4-1.1-.7-1.8-.7H5c-.6 0-1.1.4-1.4.9l-1.4 2.9A3.7 3.7 0 0 0 2 12v4c0 .6.4 1 1 1h2\" />\n <circle cx=\"7\" cy=\"17\" r=\"2\" />\n <path d=\"M9 17h6\" />\n <circle cx=\"17\" cy=\"17\" r=\"2\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"cart\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const cart: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <circle cx=\"8\" cy=\"21\" r=\"1\" />\n <circle cx=\"19\" cy=\"21\" r=\"1\" />\n <path d=\"M2.05 2.05h2l2.66 12.42a2 2 0 0 0 2 1.58h9.78a2 2 0 0 0 1.95-1.57l1.65-7.43H5.12\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"check\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const check: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M20 6 9 17l-5-5\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"check-circle\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const checkCircle: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M21.801 10A10 10 0 1 1 17 3.335\" />\n <path d=\"m9 11 3 3L22 4\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"check-square\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const checkSquare: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"m9 12 2 2 4-4\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"chevron-down\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const chevronDown: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"m6 9 6 6 6-6\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"chevron-left\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const chevronLeft: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"m15 18-6-6 6-6\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"chevron-left-bar\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const chevronLeftBar: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"M9 3v18\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"chevron-right\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const chevronRight: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"m9 18 6-6-6-6\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"clipboard\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const clipboard: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <rect width=\"8\" height=\"4\" x=\"8\" y=\"2\" rx=\"1\" ry=\"1\" />\n <path d=\"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"clock\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const clock: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 6v6l4 2\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"credit-card\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const creditCard: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <rect width=\"20\" height=\"14\" x=\"2\" y=\"5\" rx=\"2\" />\n <line x1=\"2\" x2=\"22\" y1=\"10\" y2=\"10\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"download\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const download: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M12 15V3\" />\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <path d=\"m7 10 5 5 5-5\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"edit\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const edit: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z\" />\n <path d=\"m15 5 4 4\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"external-link\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const externalLink: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M15 3h6v6\" />\n <path d=\"M10 14 21 3\" />\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"eye\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const eye: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"eye-off\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const eyeOff: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49\" />\n <path d=\"M14.084 14.158a3 3 0 0 1-4.242-4.242\" />\n <path d=\"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143\" />\n <path d=\"m2 2 20 20\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"file\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const file: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\" />\n <path d=\"M14 2v5a1 1 0 0 0 1 1h5\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"filter\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const filter: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"gauge\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const gauge: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"m12 14 4-4\" />\n <path d=\"M3.34 19a10 10 0 1 1 17.32 0\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"gift\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const gift: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M12 7v14\" />\n <path d=\"M20 11v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-8\" />\n <path d=\"M7.5 7a1 1 0 0 1 0-5A4.8 8 0 0 1 12 7a4.8 8 0 0 1 4.5-5 1 1 0 0 1 0 5\" />\n <rect x=\"3\" y=\"7\" width=\"18\" height=\"4\" rx=\"1\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"grid\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const grid: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"M3 9h18\" />\n <path d=\"M3 15h18\" />\n <path d=\"M9 3v18\" />\n <path d=\"M15 3v18\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"history\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const history: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\" />\n <path d=\"M3 3v5h5\" />\n <path d=\"M12 7v5l4 2\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"inbox\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const inbox: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <polyline points=\"22 12 16 12 14 15 10 15 8 12 2 12\" />\n <path d=\"M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"layers\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const layers: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z\" />\n <path d=\"M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12\" />\n <path d=\"M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"list\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const list: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M3 5h.01\" />\n <path d=\"M3 12h.01\" />\n <path d=\"M3 19h.01\" />\n <path d=\"M8 5h13\" />\n <path d=\"M8 12h13\" />\n <path d=\"M8 19h13\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"map\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const map: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M14.106 5.553a2 2 0 0 0 1.788 0l3.659-1.83A1 1 0 0 1 21 4.619v12.764a1 1 0 0 1-.553.894l-4.553 2.277a2 2 0 0 1-1.788 0l-4.212-2.106a2 2 0 0 0-1.788 0l-3.659 1.83A1 1 0 0 1 3 19.381V6.618a1 1 0 0 1 .553-.894l4.553-2.277a2 2 0 0 1 1.788 0z\" />\n <path d=\"M15 5.764v15\" />\n <path d=\"M9 3.236v15\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"map-pin\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const mapPin: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0\" />\n <circle cx=\"12\" cy=\"10\" r=\"3\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"menu\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const menu: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M4 5h16\" />\n <path d=\"M4 12h16\" />\n <path d=\"M4 19h16\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"mic\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const mic: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M12 19v3\" />\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\" />\n <rect x=\"9\" y=\"2\" width=\"6\" height=\"13\" rx=\"3\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"mic-off\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const micOff: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M12 19v3\" />\n <path d=\"M15 9.34V5a3 3 0 0 0-5.68-1.33\" />\n <path d=\"M16.95 16.95A7 7 0 0 1 5 12v-2\" />\n <path d=\"M18.89 13.23A7 7 0 0 0 19 12v-2\" />\n <path d=\"m2 2 20 20\" />\n <path d=\"M9 9v3a3 3 0 0 0 5.12 2.12\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"more-vertical\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const moreVertical: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\n <circle cx=\"12\" cy=\"5\" r=\"1\" />\n <circle cx=\"12\" cy=\"19\" r=\"1\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"pause\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const pause: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <rect x=\"14\" y=\"3\" width=\"5\" height=\"18\" rx=\"1\" />\n <rect x=\"5\" y=\"3\" width=\"5\" height=\"18\" rx=\"1\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"phone\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const phone: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M13.832 16.568a1 1 0 0 0 1.213-.303l.355-.465A2 2 0 0 1 17 15h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2A18 18 0 0 1 2 4a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-.8 1.6l-.468.351a1 1 0 0 0-.292 1.233 14 14 0 0 0 6.392 6.384\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"play\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const play: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"plus\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const plus: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M5 12h14\" />\n <path d=\"M12 5v14\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"search\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const search: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"m21 21-4.34-4.34\" />\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"settings\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const settings: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"shield-check\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const shieldCheck: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z\" />\n <path d=\"m9 12 2 2 4-4\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"sort\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const sort: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"m21 16-4 4-4-4\" />\n <path d=\"M17 20V4\" />\n <path d=\"m3 8 4-4 4 4\" />\n <path d=\"M7 4v16\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"star\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const star: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"ticket\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const ticket: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z\" />\n <path d=\"M13 5v2\" />\n <path d=\"M13 17v2\" />\n <path d=\"M13 11v2\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"tool\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const tool: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"trash\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const trash: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\" />\n <path d=\"M3 6h18\" />\n <path d=\"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"truck\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const truck: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M14 18V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v11a1 1 0 0 0 1 1h2\" />\n <path d=\"M15 18H9\" />\n <path d=\"M19 18h2a1 1 0 0 0 1-1v-3.65a1 1 0 0 0-.22-.624l-3.48-4.35A1 1 0 0 0 17.52 8H14\" />\n <circle cx=\"17\" cy=\"18\" r=\"2\" />\n <circle cx=\"7\" cy=\"18\" r=\"2\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"upload-cloud\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const uploadCloud: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M12 13v8\" />\n <path d=\"M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242\" />\n <path d=\"m8 17 4-4 4 4\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"user\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const user: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2\" />\n <circle cx=\"12\" cy=\"7\" r=\"4\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"user-search\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const userSearch: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <circle cx=\"10\" cy=\"7\" r=\"4\" />\n <path d=\"M10.3 15H7a4 4 0 0 0-4 4v2\" />\n <circle cx=\"17\" cy=\"17\" r=\"3\" />\n <path d=\"m21 21-1.9-1.9\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"video\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const video: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.87a.5.5 0 0 0-.752-.432L16 10.5\" />\n <rect x=\"2\" y=\"6\" width=\"14\" height=\"12\" rx=\"2\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"x\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const x: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\nimport type { IconName } from '../icon-name';\nimport { activity } from './activity';\nimport { alertCircle } from './alert-circle';\nimport { alertOctagon } from './alert-octagon';\nimport { alertTriangle } from './alert-triangle';\nimport { award } from './award';\nimport { barChart } from './bar-chart';\nimport { bell } from './bell';\nimport { bus } from './bus';\nimport { calculator } from './calculator';\nimport { calendar } from './calendar';\nimport { car } from './car';\nimport { cart } from './cart';\nimport { check } from './check';\nimport { checkCircle } from './check-circle';\nimport { checkSquare } from './check-square';\nimport { chevronDown } from './chevron-down';\nimport { chevronLeft } from './chevron-left';\nimport { chevronLeftBar } from './chevron-left-bar';\nimport { chevronRight } from './chevron-right';\nimport { clipboard } from './clipboard';\nimport { clock } from './clock';\nimport { creditCard } from './credit-card';\nimport { download } from './download';\nimport { edit } from './edit';\nimport { externalLink } from './external-link';\nimport { eye } from './eye';\nimport { eyeOff } from './eye-off';\nimport { file } from './file';\nimport { filter } from './filter';\nimport { gauge } from './gauge';\nimport { gift } from './gift';\nimport { grid } from './grid';\nimport { history } from './history';\nimport { inbox } from './inbox';\nimport { layers } from './layers';\nimport { list } from './list';\nimport { map } from './map';\nimport { mapPin } from './map-pin';\nimport { menu } from './menu';\nimport { mic } from './mic';\nimport { micOff } from './mic-off';\nimport { moreVertical } from './more-vertical';\nimport { pause } from './pause';\nimport { phone } from './phone';\nimport { play } from './play';\nimport { plus } from './plus';\nimport { search } from './search';\nimport { settings } from './settings';\nimport { shieldCheck } from './shield-check';\nimport { sort } from './sort';\nimport { star } from './star';\nimport { ticket } from './ticket';\nimport { tool } from './tool';\nimport { trash } from './trash';\nimport { truck } from './truck';\nimport { uploadCloud } from './upload-cloud';\nimport { user } from './user';\nimport { userSearch } from './user-search';\nimport { video } from './video';\nimport { x } from './x';\n\n/**\n * Registro tipado de todos los símbolos de ícono. `Record<IconName,\n * IconDefinition>` obliga al compilador a exigir una entrada por cada\n * nombre de `IconName` — agregar un nombre acá sin su archivo en\n * `icons/`, o viceversa, es un error de TypeScript, no un ícono roto\n * en runtime (que era el riesgo real del sprite como string único).\n *\n * Agregar un ícono nuevo es: crear `icons/nombre-del-icono.ts` (copiar\n * el patrón de cualquier archivo vecino), agregarlo a `IconName` en\n * `icon-name.ts`, e importarlo/registrarlo acá.\n */\nexport const ICON_DEFINITIONS: Record<IconName, IconDefinition> = {\n activity: activity,\n 'alert-circle': alertCircle,\n 'alert-octagon': alertOctagon,\n 'alert-triangle': alertTriangle,\n award: award,\n 'bar-chart': barChart,\n bell: bell,\n bus: bus,\n calculator: calculator,\n calendar: calendar,\n car: car,\n cart: cart,\n check: check,\n 'check-circle': checkCircle,\n 'check-square': checkSquare,\n 'chevron-down': chevronDown,\n 'chevron-left': chevronLeft,\n 'chevron-left-bar': chevronLeftBar,\n 'chevron-right': chevronRight,\n clipboard: clipboard,\n clock: clock,\n 'credit-card': creditCard,\n download: download,\n edit: edit,\n 'external-link': externalLink,\n eye: eye,\n 'eye-off': eyeOff,\n file: file,\n filter: filter,\n gauge: gauge,\n gift: gift,\n grid: grid,\n history: history,\n inbox: inbox,\n layers: layers,\n list: list,\n map: map,\n 'map-pin': mapPin,\n menu: menu,\n mic: mic,\n 'mic-off': micOff,\n 'more-vertical': moreVertical,\n pause: pause,\n phone: phone,\n play: play,\n plus: plus,\n search: search,\n settings: settings,\n 'shield-check': shieldCheck,\n sort: sort,\n star: star,\n ticket: ticket,\n tool: tool,\n trash: trash,\n truck: truck,\n 'upload-cloud': uploadCloud,\n user: user,\n 'user-search': userSearch,\n video: video,\n x: x,\n};\n","import { ICON_DEFINITIONS } from './icons';\n\n/**\n * Sprite SVG con los 60 íconos de trazo del design system (página 5:\n * \"Set de 59 iconos de trazo (1.9px, grilla 24×24)\", más `eye-off` como\n * extensión propia). Cada ícono es un `<symbol>` con su nombre real de la\n * spec como id (`kf-icon-check`, `kf-icon-alert-triangle`, etc.) — `Icon`\n * lo referencia con `<use>`.\n *\n * Los paths vienen de Lucide (https://lucide.dev, licencia ISC), la\n * librería de iconos de trazo cuyo set de nombres coincide exactamente con\n * el que pide el design system (chevron-right, alert-triangle, bar-chart…).\n * Se embeben acá en vez de agregar `lucide` como dependencia del paquete\n * para no sumar peso/versión externa a algo que consumen todos los\n * frontends del ecosistema — son símbolos estáticos, no lógica que\n * necesite actualizarse seguido.\n *\n * Mapeo de 4 nombres de la spec que no existen tal cual en Lucide (renombres\n * entre versiones de esa librería, o conceptos vecinos):\n * tool -> wrench\n * sort -> arrow-up-down (control de orden bidireccional simple)\n * cart -> shopping-cart\n * chevron-left-bar -> panel-left (icono de \"colapsar panel lateral\")\n *\n * El sprite ya no es un string único de mano: se construye acá a partir de\n * `ICON_DEFINITIONS` (ver `icons/index.ts`), el registro tipado donde cada\n * ícono vive en su propio archivo bajo `icons/`. Esto es responsabilidad de\n * ensamblado pura — los datos de cada glyph viven en otro lado.\n *\n * Se inyecta UNA sola vez en el DOM (ver `Icon`), sin importar cuántos\n * `<kf-icon>` distintos haya en la página — todos referencian el mismo\n * sprite vía `<use href=\"#kf-icon-...\">`.\n */\nexport const KF_ICON_SPRITE = buildIconSprite();\n\nfunction buildIconSprite(): string {\n const symbols = Object.entries(ICON_DEFINITIONS)\n .map(\n ([name, { viewBox, markup }]) =>\n `<symbol id=\"kf-icon-${name}\" viewBox=\"${viewBox}\">${markup}</symbol>`,\n )\n .join('\\n ');\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" style=\"display: none\">\n ${symbols}\n</svg>`;\n}\n","import { DOCUMENT } from '@angular/common';\nimport { Component, computed, effect, inject, input } from '@angular/core';\nimport { KF_ICON_SPRITE } from './icon-sprite';\nimport type { IconName } from './icon-name';\n\nexport type { IconName };\n\nexport type IconSize = 'sm' | 'md' | 'lg';\n\n/** Marca el sprite ya inyectado, para no depender de una bandera de módulo\n * — una bandera compartida entre instancias de test (o entre múltiples\n * `TestBed` en la misma suite) daría falsos negativos: el primer test que\n * corre \"gasta\" la bandera y todos los siguientes creerían que el sprite\n * nunca se inyecta. Comprobar el propio DOM es la fuente de verdad real. */\nconst SPRITE_ROOT_ID = 'kf-icon-sprite-root';\n\n/**\n * Ícono de trazo del design system — 60 glyphs (59 de la página 5 + `eye-off`), grilla 24×24,\n * grosor de trazo 1.9px. Referencia un sprite SVG embebido (ver\n * `icon-sprite.ts`) vía `<use>`, así que no hay peso de red adicional por\n * cada instancia: el sprite se inyecta al DOM una única vez, la primera\n * vez que se renderiza cualquier `<kf-icon>` de toda la aplicación.\n *\n * El tamaño se controla con `size` (página 6: \"el tamaño se controla con la\n * prop size\"): `sm` (16px), `md` (20px, default) o `lg` (24px). El color\n * sigue siempre `currentColor` — se hereda del texto del elemento\n * contenedor, nunca se fija en el propio ícono.\n *\n * <kf-icon name=\"alert-triangle\" size=\"sm\" />\n * <kf-button icon=\"calendar\">Reservar hora</kf-button> <!-- ver Button -->\n */\n@Component({\n selector: 'kf-icon',\n template: `\n <svg [attr.aria-hidden]=\"true\" focusable=\"false\">\n <use [attr.href]=\"'#kf-icon-' + name()\" />\n </svg>\n `,\n styles: `\n :host {\n display: inline-flex;\n flex: none;\n line-height: 0;\n }\n svg {\n width: var(--kf-icon-size, 20px);\n height: var(--kf-icon-size, 20px);\n fill: none;\n stroke: currentColor;\n stroke-width: 1.9;\n stroke-linecap: round;\n stroke-linejoin: round;\n }\n `,\n host: {\n '[style.--kf-icon-size]': 'pixelSize()',\n },\n})\nexport class Icon {\n readonly name = input.required<IconName>();\n readonly size = input<IconSize>('md');\n\n private readonly document = inject(DOCUMENT);\n\n protected readonly pixelSize = computed(() => {\n const bySize: Record<IconSize, string> = { sm: '16px', md: '20px', lg: '24px' };\n return bySize[this.size()];\n });\n\n constructor() {\n effect(() => {\n if (this.document.getElementById(SPRITE_ROOT_ID)) {\n return;\n }\n const container = this.document.createElement('div');\n container.innerHTML = KF_ICON_SPRITE;\n const sprite = container.firstElementChild;\n if (sprite) {\n sprite.id = SPRITE_ROOT_ID;\n this.document.body.prepend(sprite);\n }\n });\n }\n}\n","import { Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Dos variantes del mismo concepto — acceso rápido a una sección (página\n * 35): \"Tile de acceso destacado\" (`variant=\"tile\"`, default) es un bloque\n * centrado con ícono grande arriba y título abajo, pensado para una\n * cuadrícula de accesos (ej. \"Todos los certificados\"). \"Fila de documento\"\n * (`variant=\"row\"`) es horizontal, con ícono a la izquierda y\n * título+descripción a la derecha, pensada para listas verticales dentro de\n * un `kf-panel` (ej. \"Pagos\" / \"Revisa tu estado de cuenta y realiza pagos.\").\n *\n * <kf-action-tile icon=\"shield-check\" title=\"Todos los certificados\" />\n * <kf-action-tile variant=\"row\" icon=\"download\" title=\"Pagos\"\n * description=\"Revisa tu estado de cuenta y realiza pagos.\" />\n */\n@Component({\n selector: 'kf-action-tile',\n imports: [Icon],\n template: `\n <span class=\"kf-action-tile__icon\">\n <kf-icon [name]=\"icon()\" [size]=\"variant() === 'row' ? 'md' : 'lg'\" />\n </span>\n <span class=\"kf-action-tile__text\">\n <span class=\"kf-action-tile__title\">{{ title() }}</span>\n @if (description()) {\n <span class=\"kf-action-tile__description\">{{ description() }}</span>\n }\n </span>\n `,\n styles: `\n :host {\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-white);\n cursor: pointer;\n transition:\n border-color 0.14s,\n box-shadow 0.14s;\n }\n :host(:hover) {\n border-color: var(--kf-color-border-strong);\n box-shadow: var(--kf-shadow-xs);\n }\n :host(.kf-action-tile--tile) {\n flex-direction: column;\n text-align: center;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-lg);\n }\n .kf-action-tile__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-primary-soft);\n color: var(--kf-color-primary);\n }\n :host(.kf-action-tile--row) .kf-action-tile__icon {\n width: 2.25rem;\n height: 2.25rem;\n background: var(--kf-color-secondary-soft);\n color: var(--kf-color-secondary);\n }\n :host(.kf-action-tile--tile) .kf-action-tile__icon {\n width: 2.75rem;\n height: 2.75rem;\n }\n .kf-action-tile__text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n }\n .kf-action-tile__title {\n font-family: var(--kf-font-title);\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-action-tile__description {\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n }\n `,\n host: {\n '[class.kf-action-tile--tile]': \"variant() === 'tile'\",\n '[class.kf-action-tile--row]': \"variant() === 'row'\",\n },\n})\nexport class ActionTile {\n readonly variant = input<'tile' | 'row'>('tile');\n readonly icon = input.required<IconName>();\n readonly title = input.required<string>();\n readonly description = input<string>();\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\nimport { Icon } from '../icon/Icon';\n\n/**\n * Marca la barra superior como chrome exclusivo de administradores (página\n * 18) — acento ámbar para diferenciar contexto privilegiado del resto del\n * portal. Dos variantes: etiqueta aislada (pill), o `inline` para usarse\n * dentro de la franja de `kf-portal-header` (fondo oscuro, texto ámbar).\n *\n * <kf-admin-badge />\n * <kf-admin-badge inline />\n */\n@Component({\n selector: 'kf-admin-badge',\n imports: [Icon],\n template: `\n <kf-icon name=\"shield-check\" size=\"sm\" />\n <span>Vista administrador</span>\n `,\n styles: `\n :host {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-warning-soft);\n border: 1px solid var(--kf-color-warning);\n color: var(--kf-color-warning-strong);\n font-size: 0.75rem;\n font-weight: 700;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n line-height: 1;\n }\n :host(.kf-admin-badge--inline) {\n background: transparent;\n border-color: rgba(226, 185, 59, 0.5);\n color: var(--kf-color-warning);\n }\n `,\n host: {\n '[class.kf-admin-badge--inline]': 'inline()',\n },\n})\nexport class AdminBadge {\n /** Para usarse dentro de una superficie oscura (ej. la franja de `kf-portal-header`). */\n readonly inline = input(false, { transform: booleanAttribute });\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\n\nexport type SpinnerSize = 'sm' | 'md' | 'lg';\n\n/**\n * Indicador de carga indeterminado: inline, dentro de un botón, o como único\n * contenido de una sección mientras llega la data.\n *\n * Cuando se conoce la forma del contenido que viene, preferir `kf-skeleton`\n * (dibuja la silueta). El spinner es para \"algo está pasando\" sin forma\n * conocida — guardar, enviar, reintentar.\n *\n * Lleva `role=\"status\"`, así que el lector de pantalla anuncia el `label`\n * cuando aparece. Sin `label` cae en un texto accesible por defecto.\n *\n * <kf-spinner />\n * <kf-spinner size=\"sm\" label=\"Cargando…\" />\n * <kf-spinner onDark />\n */\n@Component({\n selector: 'kf-spinner',\n template: `\n <span class=\"kf-spinner\" [class.kf-spinner--on-dark]=\"onDark()\" role=\"status\">\n <span class=\"kf-spinner__ring\" [class]=\"'kf-spinner__ring--' + size()\"></span>\n @if (label()) {\n <span class=\"kf-spinner__label\">{{ label() }}</span>\n } @else {\n <span class=\"kf-spinner__sr\">Cargando</span>\n }\n </span>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-spinner {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-sm);\n font-family: var(--kf-font-body);\n }\n .kf-spinner__ring {\n display: inline-block;\n flex: none;\n border-radius: var(--kf-radius-pill);\n border: 2px solid var(--kf-color-border);\n border-top-color: var(--kf-color-primary);\n animation: kf-spinner-turn 0.7s linear infinite;\n }\n .kf-spinner__ring--sm {\n width: 16px;\n height: 16px;\n }\n .kf-spinner__ring--md {\n width: 24px;\n height: 24px;\n border-width: 3px;\n }\n .kf-spinner__ring--lg {\n width: 32px;\n height: 32px;\n border-width: 3px;\n }\n .kf-spinner__label {\n font-size: 0.875rem;\n color: var(--kf-color-text-muted);\n }\n /* Sobre superficies oscuras (carousel, feature card, barra de admin). */\n .kf-spinner--on-dark .kf-spinner__ring {\n border-color: rgba(255, 255, 255, 0.28);\n border-top-color: var(--kf-color-white);\n }\n .kf-spinner--on-dark .kf-spinner__label {\n color: var(--kf-color-white);\n }\n @keyframes kf-spinner-turn {\n to {\n transform: rotate(360deg);\n }\n }\n .kf-spinner__sr {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n }\n @media (prefers-reduced-motion: reduce) {\n .kf-spinner__ring {\n animation-duration: 2s;\n }\n }\n `,\n})\nexport class Spinner {\n readonly size = input<SpinnerSize>('md');\n /** Texto al lado del anillo. Vacío deja solo el anillo (y el texto para lectores). */\n readonly label = input('');\n /** Invierte los colores para fondos oscuros. */\n readonly onDark = input(false, { transform: booleanAttribute });\n}\n","import { booleanAttribute, Component, computed, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\nimport { Spinner } from '../spinner/Spinner';\n\n/**\n * Wraps a native `<button>`, so keyboard handling, focus and form submission\n * keep working. The cost of the wrapper is forwarding `disabled` and `type` by\n * hand: as attributes on a custom element they have no native effect.\n *\n * Five variants (page 9 of the design system): `primary` (main action, blue),\n * `secondary` (service actions, orange), `ghost` (low-emphasis, no fill),\n * `outline` (medium-emphasis, bordered) and `danger` (destructive\n * confirmations — red, see the Confirmation Modal pattern on page 30). Three\n * sizes (`sm`/`md`/`lg`). `icon` renders a leading glyph (`kf-icon`) before\n * the projected label; `block` stretches the button to the full width of its\n * container.\n *\n * `(click)` is not forwarded — it bubbles from the inner button to the host.\n *\n * `loading` replaces the projected content with `kf-spinner` and forces\n * `disabled` — for the common \"Ingresando…\"/\"Enviando…\" submit pattern,\n * which before this prop existed as plain text swaps with no visual\n * indicator (see `web-portal-latam-frontend`'s login submit buttons).\n *\n * <kf-button (click)=\"save()\">Save</kf-button>\n * <kf-button variant=\"ghost\" disabled>Cancel</kf-button>\n * <kf-button variant=\"danger\" (click)=\"remove()\">Delete</kf-button>\n * <kf-button size=\"sm\" icon=\"calendar\" block>Reservar hora</kf-button>\n * <kf-button type=\"submit\" [loading]=\"submitting()\">Ingresar</kf-button>\n */\n@Component({\n selector: 'kf-button',\n imports: [Icon, Spinner],\n template: `\n <button\n [type]=\"type()\"\n [disabled]=\"disabled() || loading()\"\n [class.kf-button--secondary]=\"variant() === 'secondary'\"\n [class.kf-button--ghost]=\"variant() === 'ghost'\"\n [class.kf-button--outline]=\"variant() === 'outline'\"\n [class.kf-button--danger]=\"variant() === 'danger'\"\n [class.kf-button--sm]=\"size() === 'sm'\"\n [class.kf-button--lg]=\"size() === 'lg'\"\n >\n @if (loading()) {\n <kf-spinner size=\"sm\" [onDark]=\"hasSolidFill()\" />\n } @else {\n @if (icon(); as iconName) {\n <kf-icon\n class=\"kf-button__icon\"\n [name]=\"iconName\"\n [size]=\"size() === 'lg' ? 'md' : 'sm'\"\n />\n }\n <ng-content />\n }\n </button>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n :host([block]) {\n display: block;\n }\n button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--kf-space-xs);\n width: 100%;\n font: inherit;\n font-weight: 600;\n padding: var(--kf-space-sm) var(--kf-space-md);\n border: 1px solid var(--kf-color-primary);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-primary);\n color: var(--kf-color-white);\n cursor: pointer;\n transition:\n background 0.14s,\n border-color 0.14s,\n color 0.14s;\n }\n button:hover:not(:disabled) {\n background: var(--kf-color-primary-hover);\n border-color: var(--kf-color-primary-hover);\n }\n button:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n /* Secondary — naranja, para acciones de servicio (agendar, mantención). */\n button.kf-button--secondary {\n border-color: var(--kf-color-secondary);\n background: var(--kf-color-secondary);\n }\n button.kf-button--secondary:hover:not(:disabled) {\n background: var(--kf-color-secondary-hover);\n border-color: var(--kf-color-secondary-hover);\n }\n\n /* Ghost — sin relleno, para acciones secundarias junto a un primary. */\n button.kf-button--ghost {\n background: transparent;\n border-color: transparent;\n color: var(--kf-color-primary);\n }\n button.kf-button--ghost:hover:not(:disabled) {\n background: var(--kf-color-primary-soft);\n }\n\n /* Outline — énfasis medio: borde visible, sin relleno (ej. \"Llamar\" en Vehicle Header). */\n button.kf-button--outline {\n background: transparent;\n border-color: var(--kf-color-border-strong);\n color: var(--kf-color-text);\n }\n button.kf-button--outline:hover:not(:disabled) {\n background: var(--kf-color-surface);\n border-color: var(--kf-color-text-muted);\n }\n\n /* Danger — rojo, para confirmaciones destructivas (cancelar, eliminar). */\n button.kf-button--danger {\n border-color: var(--kf-color-error);\n background: var(--kf-color-error);\n }\n button.kf-button--danger:hover:not(:disabled) {\n background: var(--kf-color-error-hover);\n border-color: var(--kf-color-error-hover);\n }\n\n /* Tamaños — el tamaño por defecto (md) usa el padding base de arriba. */\n button.kf-button--sm {\n padding: 6px var(--kf-space-sm);\n font-size: 0.85rem;\n }\n button.kf-button--lg {\n padding: var(--kf-space-sm) var(--kf-space-lg);\n font-size: 1.05rem;\n }\n `,\n host: {\n '[attr.block]': \"block() ? '' : null\",\n },\n})\nexport class Button {\n readonly variant = input<'primary' | 'secondary' | 'ghost' | 'outline' | 'danger'>('primary');\n readonly size = input<'sm' | 'md' | 'lg'>('md');\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Matches the native default: submits when inside a `<form>`. */\n readonly type = input<'button' | 'submit' | 'reset'>('submit');\n /** Leading icon, rendered via `kf-icon` before the projected label. */\n readonly icon = input<IconName>();\n /** Stretches the button to the full width of its container. */\n readonly block = input(false, { transform: booleanAttribute });\n /** Replaces the projected content with `kf-spinner` and forces `disabled`. */\n readonly loading = input(false, { transform: booleanAttribute });\n\n /** `ghost`/`outline` have no solid background — the default spinner ring already reads fine there. */\n protected readonly hasSolidFill = computed(() => {\n const variant = this.variant();\n return variant !== 'ghost' && variant !== 'outline';\n });\n}\n","import { booleanAttribute, Component, computed, input, model } from '@angular/core';\n\nexport type AlertTone = 'info' | 'ok' | 'warn' | 'error';\n\n/**\n * Banner contextual que vive dentro del flujo: validaciones, avisos de\n * vencimiento, confirmaciones. Persiste hasta que se descarta o hasta que la\n * condición que lo causó desaparece — para feedback efímero está el toast.\n *\n * `open` es two-way: el botón de cerrar lo pone en `false` y el componente\n * deja de renderizar. El consumidor puede volver a abrirlo poniéndolo en\n * `true` (ej. cuando la validación falla otra vez).\n *\n * ponytail: los glifos van inline en vez de venir de un componente Icon —\n * son 4 paths fijos, uno por tono, y no existe todavía `kf-icon` en la\n * librería. Cuando exista, se reemplaza este `@switch` por `<kf-icon>`.\n *\n * <kf-alert tone=\"warn\" title=\"SOAT por vencer\">Vence el 15/08.</kf-alert>\n * <kf-alert tone=\"ok\" [(open)]=\"saved\" dismissible>Pago registrado.</kf-alert>\n */\n@Component({\n selector: 'kf-alert',\n template: `\n @if (open()) {\n <div class=\"kf-alert\" [class]=\"'kf-alert--' + tone()\" [attr.role]=\"ariaRole()\">\n <svg class=\"kf-alert__icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\n @switch (tone()) {\n @case ('ok') {\n <path d=\"M21 12a9 9 0 1 1-4.2-7.6\" />\n <path d=\"M9 11.5l3 3 8.5-8.5\" />\n }\n @case ('warn') {\n <path d=\"M12 4l9 16H3z\" />\n <path d=\"M12 10v4\" />\n <path d=\"M12 17.5h.01\" />\n }\n @case ('error') {\n <path d=\"M8 3h8l5 5v8l-5 5H8l-5-5V8z\" />\n <path d=\"M12 8v4\" />\n <path d=\"M12 16h.01\" />\n }\n @default {\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"M12 8v4\" />\n <path d=\"M12 16h.01\" />\n }\n }\n </svg>\n <div class=\"kf-alert__body\">\n @if (title()) {\n <p class=\"kf-alert__title\">{{ title() }}</p>\n }\n <div class=\"kf-alert__message\"><ng-content /></div>\n </div>\n @if (dismissible()) {\n <button\n type=\"button\"\n class=\"kf-alert__close\"\n aria-label=\"Cerrar aviso\"\n (click)=\"open.set(false)\"\n >\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M6 6l12 12M18 6L6 18\" />\n </svg>\n </button>\n }\n </div>\n }\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-alert {\n display: flex;\n align-items: flex-start;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-sm) var(--kf-space-md);\n border: 1px solid transparent;\n border-radius: var(--kf-radius-sm);\n font-size: 0.9rem;\n }\n .kf-alert--info {\n background: var(--kf-color-info-soft);\n border-color: var(--kf-color-info);\n color: var(--kf-color-info-strong);\n }\n .kf-alert--ok {\n background: var(--kf-color-success-soft);\n border-color: var(--kf-color-success);\n color: var(--kf-color-success-strong);\n }\n .kf-alert--warn {\n background: var(--kf-color-warning-soft);\n border-color: var(--kf-color-warning);\n color: var(--kf-color-warning-strong);\n }\n .kf-alert--error {\n background: var(--kf-color-error-soft);\n border-color: var(--kf-color-error);\n color: var(--kf-color-error-strong);\n }\n .kf-alert__icon,\n .kf-alert__close svg {\n flex: none;\n width: 1.15em;\n height: 1.15em;\n fill: none;\n stroke: currentColor;\n stroke-width: 1.9;\n stroke-linecap: round;\n stroke-linejoin: round;\n }\n .kf-alert__body {\n flex: 1;\n min-width: 0;\n }\n .kf-alert__title {\n margin: 0;\n font-family: var(--kf-font-title);\n font-weight: 700;\n }\n .kf-alert__message {\n color: inherit;\n }\n .kf-alert__close {\n flex: none;\n display: inline-flex;\n padding: 2px;\n border: none;\n background: transparent;\n color: inherit;\n border-radius: var(--kf-radius-xs);\n cursor: pointer;\n opacity: 0.7;\n }\n .kf-alert__close:hover {\n opacity: 1;\n }\n .kf-alert__close:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n `,\n})\nexport class Alert {\n readonly tone = input<AlertTone>('info');\n /** Línea en negrita arriba del mensaje. Vacío deja solo el contenido proyectado. */\n readonly title = input('');\n readonly dismissible = input(false, { transform: booleanAttribute });\n /** Visibilidad, two-way: `[(open)]=\"hasError\"`. */\n readonly open = model(true);\n\n /**\n * `alert` interrumpe al lector de pantalla; se reserva para error/warn.\n * Los avisos informativos se anuncian sin cortar lo que se esté leyendo.\n */\n protected readonly ariaRole = computed(() =>\n this.tone() === 'error' || this.tone() === 'warn' ? 'alert' : 'status',\n );\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport { booleanAttribute, Component, computed, input } from '@angular/core';\n\n/**\n * Avatar de usuario: muestra una foto (`src`) o, si no hay foto, las\n * iniciales (`initials`) sobre un fondo con gradiente de marca. `round`\n * controla la forma: circular (por defecto) o cuadrada con radio.\n *\n * Con `pill`, el avatar se envuelve en una pastilla azul con un chevron a la\n * derecha — la \"pill de usuario (header)\" de la página 18 del design system,\n * usada en la barra de sesión del Portal Header.\n *\n * <kf-avatar initials=\"JD\" />\n * <kf-avatar src=\"https://…/foto.jpg\" [round]=\"false\" />\n * <kf-avatar initials=\"TS\" pill />\n *\n * Pendiente: si en el futuro se agrega un ícono de fallback (persona\n * genérica) para cuando no hay ni `src` ni `initials`, depende del\n * componente Icon / sprite SVG que todavía no existe en esta librería.\n */\n@Component({\n selector: 'kf-avatar',\n imports: [NgTemplateOutlet],\n template: `\n <ng-template #avatarCircle>\n <span class=\"kf-avatar\" [class.kf-avatar--square]=\"!round()\">\n @if (src()) {\n <img class=\"kf-avatar__image\" [src]=\"src()\" [alt]=\"initials() || ''\" />\n } @else {\n <span class=\"kf-avatar__initials\">{{ displayInitials() }}</span>\n }\n </span>\n </ng-template>\n\n @if (pill()) {\n <span class=\"kf-avatar-pill\">\n <ng-container [ngTemplateOutlet]=\"avatarCircle\" />\n <span class=\"kf-avatar-pill__caret\" aria-hidden=\"true\"></span>\n </span>\n } @else {\n <ng-container [ngTemplateOutlet]=\"avatarCircle\" />\n }\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-avatar {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n inline-size: 40px;\n block-size: 40px;\n overflow: hidden;\n border-radius: var(--kf-radius-pill);\n background: linear-gradient(135deg, var(--kf-color-primary), var(--kf-color-primary-active));\n color: var(--kf-color-white);\n font: inherit;\n font-size: 0.875rem;\n font-weight: 600;\n line-height: 1;\n user-select: none;\n flex: none;\n }\n .kf-avatar--square {\n border-radius: var(--kf-radius-sm);\n }\n .kf-avatar__image {\n inline-size: 100%;\n block-size: 100%;\n object-fit: cover;\n }\n .kf-avatar__initials {\n text-transform: uppercase;\n }\n\n /* Pill de usuario (header) — envuelve el avatar en una pastilla azul con chevron. */\n .kf-avatar-pill {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: 4px var(--kf-space-sm) 4px 4px;\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-primary);\n cursor: pointer;\n }\n .kf-avatar-pill .kf-avatar {\n inline-size: 32px;\n block-size: 32px;\n background: rgba(255, 255, 255, 0.18);\n }\n .kf-avatar-pill__caret {\n flex: none;\n width: 8px;\n height: 8px;\n border-right: 2px solid var(--kf-color-white);\n border-bottom: 2px solid var(--kf-color-white);\n transform: rotate(45deg);\n margin-top: -4px;\n }\n `,\n})\nexport class Avatar {\n readonly initials = input<string>();\n readonly src = input<string>();\n readonly round = input(true);\n /** Envuelve el avatar en la pastilla de sesión del header, con chevron. */\n readonly pill = input(false, { transform: booleanAttribute });\n\n /** Limita a 2 caracteres para que quepan cómodos dentro del círculo. */\n readonly displayInitials = computed(() => (this.initials() ?? '').slice(0, 2));\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\n\n/**\n * Pill chica de fondo suave (soft) para un conteo, tag o estado liviano\n * puntual (no un proceso en vivo — para eso existe `kf-status-pill`, que usa\n * borde en vez de relleno). El color de fondo/texto/punto depende de `tone`.\n *\n * El PDF (página 10) fija seis tonos con fondo soft y texto del tono fuerte\n * — nunca fondo saturado con texto blanco, que es más apto para un botón\n * que para una etiqueta de lectura rápida en una lista densa.\n *\n * <kf-badge tone=\"ok\" dot>Al día</kf-badge>\n * <kf-badge tone=\"error\">3</kf-badge>\n *\n * Mapeo de `tone` a los seis conceptos de la página 10 y sus tokens\n * semánticos en projects/ui/src/tokens/base.css:\n * neutral -> Neutral (border/text-muted), info -> Información (info-soft/-strong),\n * ok -> Activo (success-soft/-strong), warn -> Pendiente (warning-soft/-strong),\n * error -> Vencido (error-soft/-strong), service -> Servicio (secondary-soft,\n * no existe un `-strong` para secondary todavía — usa el color base).\n */\n@Component({\n selector: 'kf-badge',\n template: `\n <span class=\"kf-badge\" [class]=\"'kf-badge--' + tone()\">\n @if (dot()) {\n <span class=\"kf-badge__dot\"></span>\n }\n <ng-content />\n </span>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-badge {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border-radius: var(--kf-radius-pill);\n font: inherit;\n font-size: 0.75rem;\n font-weight: 600;\n line-height: 1;\n white-space: nowrap;\n background: var(--kf-color-border);\n color: var(--kf-color-text-muted);\n }\n .kf-badge__dot {\n inline-size: 6px;\n block-size: 6px;\n border-radius: var(--kf-radius-pill);\n flex: none;\n background: currentColor;\n }\n .kf-badge--neutral {\n background: var(--kf-color-border);\n color: var(--kf-color-text-muted);\n }\n .kf-badge--ok {\n background: var(--kf-color-success-soft);\n color: var(--kf-color-success-strong);\n }\n .kf-badge--warn {\n background: var(--kf-color-warning-soft);\n color: var(--kf-color-warning-strong);\n }\n .kf-badge--error {\n background: var(--kf-color-error-soft);\n color: var(--kf-color-error-strong);\n }\n .kf-badge--info {\n background: var(--kf-color-info-soft);\n color: var(--kf-color-info-strong);\n }\n .kf-badge--service {\n background: var(--kf-color-secondary-soft);\n color: var(--kf-color-secondary-strong);\n }\n `,\n})\nexport class Badge {\n readonly tone = input<'neutral' | 'ok' | 'warn' | 'error' | 'info' | 'service'>('neutral');\n readonly dot = input(false, { transform: booleanAttribute });\n}\n","import { Component, computed, input, output } from '@angular/core';\n\nexport interface BreadcrumbItem {\n label: string;\n /** Destino del link. Sin `href` el nivel se rinde como texto plano. */\n href?: string;\n}\n\n/**\n * Ruta de navegación de las vistas internas. El último nivel es la página\n * actual: nunca es link y lleva `aria-current=\"page\"`, aunque traiga `href`.\n *\n * Se rinde como `<nav><ol>` — es una lista ordenada de ancestros, y eso es lo\n * que los lectores de pantalla anuncian (\"navegación, lista de 3 elementos\").\n *\n * Para apps con router: escuchar `itemClick` y llamar\n * `event.preventDefault()` antes de `router.navigate(...)`. El `href` se\n * mantiene igual para que click-medio, \"abrir en pestaña nueva\" y el hover\n * de la barra de estado sigan funcionando.\n *\n * <kf-breadcrumb [items]=\"[{ label: 'Inicio', href: '/' }, { label: 'Mis vehículos' }]\" />\n */\n@Component({\n selector: 'kf-breadcrumb',\n template: `\n <nav class=\"kf-breadcrumb\" aria-label=\"Ruta de navegación\">\n <ol class=\"kf-breadcrumb__list\">\n @for (item of items(); track $index; let i = $index) {\n <li class=\"kf-breadcrumb__item\">\n @if (i > 0) {\n <svg\n class=\"kf-breadcrumb__separator\"\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path d=\"M9 6l6 6-6 6\" />\n </svg>\n }\n @if (item.href && i !== lastIndex()) {\n <a\n class=\"kf-breadcrumb__link\"\n [href]=\"item.href\"\n (click)=\"itemClick.emit({ item, index: i, event: $event })\"\n >\n {{ item.label }}\n </a>\n } @else {\n <span\n class=\"kf-breadcrumb__current\"\n [attr.aria-current]=\"i === lastIndex() ? 'page' : null\"\n >\n {{ item.label }}\n </span>\n }\n </li>\n }\n </ol>\n </nav>\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n font-size: 0.875rem;\n }\n .kf-breadcrumb__list {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--kf-space-xs);\n margin: 0;\n padding: 0;\n list-style: none;\n }\n .kf-breadcrumb__item {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n min-width: 0;\n }\n .kf-breadcrumb__separator {\n flex: none;\n width: 1em;\n height: 1em;\n fill: none;\n stroke: var(--kf-color-border-strong);\n stroke-width: 1.9;\n stroke-linecap: round;\n stroke-linejoin: round;\n }\n .kf-breadcrumb__link {\n color: var(--kf-color-primary);\n text-decoration: none;\n border-radius: var(--kf-radius-xs);\n transition: color 0.14s;\n }\n .kf-breadcrumb__link:hover {\n text-decoration: underline;\n }\n .kf-breadcrumb__link:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-breadcrumb__current {\n color: var(--kf-color-text-muted);\n overflow-wrap: anywhere;\n }\n `,\n})\nexport class Breadcrumb {\n readonly items = input.required<BreadcrumbItem[]>();\n\n /**\n * Click en un nivel con `href`. Incluye el `MouseEvent` para que un\n * consumidor con router pueda cortar la navegación nativa.\n *\n * ponytail: no dependemos de `@angular/router` acá — sería un peer dep\n * nuevo en la librería para lo que el consumidor resuelve en una línea.\n */\n readonly itemClick = output<{ item: BreadcrumbItem; index: number; event: MouseEvent }>();\n\n protected readonly lastIndex = computed(() => this.items().length - 1);\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\n\n/**\n * Contenedor base con esquinas redondeadas y sombra sutil — la base visual\n * de paneles, tarjetas de métrica, tablas y bloques de contenido de todo el\n * portal (ver página 14 del design system).\n *\n * Piensa este componente como el \"cimiento\": no impone estructura interna\n * más allá de dos slots opcionales alrededor del contenido libre —\n * `[media]` para una imagen/ícono destacado arriba, y `[actions]` para una\n * fila de botones al pie, separada por una línea. El contenido por defecto\n * (sin selector) queda en el medio, sin ningún layout forzado, para que\n * cualquier composición (una métrica, una lista, un formulario) pueda vivir\n * dentro sin pelear con estilos propios del `Card`.\n *\n * <kf-card>Contenido simple</kf-card>\n * <kf-card flush>Sin sombra — para superficies ya delimitadas por otra card</kf-card>\n * <kf-card>\n * <img kf-card-media src=\"...\" alt=\"\" />\n * <h3>Título</h3>\n * <p>Descripción</p>\n * <div kf-card-actions>\n * <kf-button variant=\"ghost\">Cancelar</kf-button>\n * <kf-button>Guardar</kf-button>\n * </div>\n * </kf-card>\n */\n@Component({\n selector: 'kf-card',\n template: `\n <ng-content select=\"[kf-card-media]\" />\n <div class=\"kf-card__body\">\n <ng-content />\n </div>\n <ng-content select=\"[kf-card-actions]\" />\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n box-shadow: var(--kf-shadow-xs);\n overflow: hidden;\n }\n :host.kf-card--flush {\n box-shadow: none;\n }\n .kf-card__body {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-md);\n flex: 1 1 auto;\n }\n ::ng-deep [kf-card-media] {\n display: block;\n inline-size: 100%;\n block-size: auto;\n object-fit: cover;\n }\n ::ng-deep [kf-card-actions] {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-sm) var(--kf-space-md);\n border-top: 1px solid var(--kf-color-border);\n }\n `,\n host: {\n '[class.kf-card--flush]': 'flush()',\n },\n})\nexport class Card {\n /** Quita la sombra — para cards anidadas dentro de otra superficie ya elevada. */\n readonly flush = input(false, { transform: booleanAttribute });\n}\n","import {\n AfterContentInit,\n Component,\n DestroyRef,\n contentChildren,\n inject,\n input,\n numberAttribute,\n output,\n signal,\n} from '@angular/core';\nimport { Icon } from '../icon/Icon';\n\n/**\n * Slide individual de un `kf-carousel`. Es un contenedor mínimo: solo existe\n * para que el carrusel pueda detectar, vía `contentChildren`, cuántos slides\n * se proyectaron y en qué orden — el contenido real es responsabilidad total\n * de quien lo consume.\n *\n * <kf-carousel-slide>...</kf-carousel-slide>\n */\n@Component({\n selector: 'kf-carousel-slide',\n template: `<ng-content />`,\n styles: `\n :host {\n display: block;\n flex: 0 0 100%;\n width: 100%;\n height: 100%;\n }\n `,\n})\nexport class CarouselSlide {}\n\n/**\n * Carrusel de slides con flechas, dots y autoplay opcional.\n *\n * La spec original de React recibe `slides` como un array de nodos React.\n * En Angular eso no tiene equivalente directo: en vez de forzar un array de\n * datos crudos, cada slide se proyecta como contenido declarativo mediante\n * un `kf-carousel-slide` hijo, y el carrusel los detecta con\n * `contentChildren(CarouselSlide)`. Esto evita depender de un renderer de\n * nodos y deja que cada slide use plantillas Angular normales (bindings,\n * `@if`, `@for`, etc.) tal como se espera en este ecosistema.\n *\n * <kf-carousel [autoplay]=\"true\" [interval]=\"4000\" (indexChange)=\"onIndex($event)\">\n * <kf-carousel-slide>...</kf-carousel-slide>\n * <kf-carousel-slide>...</kf-carousel-slide>\n * </kf-carousel>\n */\n@Component({\n selector: 'kf-carousel',\n imports: [Icon],\n template: `\n <div\n class=\"kf-carousel\"\n (mouseenter)=\"pauseAutoplay()\"\n (mouseleave)=\"resumeAutoplay()\"\n (focusin)=\"pauseAutoplay()\"\n (focusout)=\"resumeAutoplay()\"\n >\n <div class=\"kf-carousel__viewport\">\n <div\n class=\"kf-carousel__track\"\n [style.transform]=\"'translateX(-' + activeIndex() * 100 + '%)'\"\n >\n <ng-content />\n </div>\n </div>\n\n @if (slides().length > 1) {\n <div class=\"kf-carousel__controls\">\n <div class=\"kf-carousel__dots\" role=\"tablist\">\n @for (slide of slides(); track slide; let i = $index) {\n <button\n type=\"button\"\n role=\"tab\"\n class=\"kf-carousel__dot\"\n [class.kf-carousel__dot--active]=\"i === activeIndex()\"\n [attr.aria-selected]=\"i === activeIndex()\"\n [attr.aria-label]=\"'Ir al slide ' + (i + 1)\"\n (click)=\"goTo(i)\"\n ></button>\n }\n </div>\n <button\n type=\"button\"\n class=\"kf-carousel__arrow\"\n aria-label=\"Slide anterior\"\n (click)=\"previous()\"\n >\n <kf-icon name=\"chevron-left\" size=\"sm\" />\n </button>\n <button\n type=\"button\"\n class=\"kf-carousel__arrow\"\n aria-label=\"Slide siguiente\"\n (click)=\"next()\"\n >\n <kf-icon name=\"chevron-right\" size=\"sm\" />\n </button>\n </div>\n }\n </div>\n `,\n styles: `\n :host {\n display: block;\n height: 100%;\n font-family: var(--kf-font-body);\n }\n .kf-carousel {\n position: relative;\n height: 100%;\n }\n .kf-carousel__viewport {\n height: 100%;\n overflow: hidden;\n border-radius: var(--kf-radius-md);\n }\n .kf-carousel__track {\n display: flex;\n height: 100%;\n transition: transform 0.32s ease;\n }\n .kf-carousel__controls {\n position: absolute;\n z-index: 2;\n right: var(--kf-space-sm);\n bottom: var(--kf-space-sm);\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n }\n .kf-carousel__arrow {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 1.75rem;\n height: 1.75rem;\n border: 1px solid rgb(255 255 255 / 22%);\n border-radius: var(--kf-radius-pill);\n background: rgb(255 255 255 / 12%);\n /* kf-icon usa currentColor — el SVG hereda este blanco sin más CSS. */\n color: #fff;\n cursor: pointer;\n transition: background 0.14s;\n }\n .kf-carousel__arrow:hover {\n background: rgb(255 255 255 / 24%);\n }\n .kf-carousel__arrow:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px rgb(255 255 255 / 60%);\n }\n .kf-carousel__dots {\n display: flex;\n gap: var(--kf-space-xs);\n }\n .kf-carousel__dot {\n width: 7px;\n height: 7px;\n padding: 0;\n border: none;\n border-radius: var(--kf-radius-pill);\n background: rgb(255 255 255 / 35%);\n cursor: pointer;\n transition:\n background 0.14s,\n width 0.14s;\n }\n .kf-carousel__dot:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px rgb(255 255 255 / 60%);\n }\n .kf-carousel__dot--active {\n width: 1.125rem;\n border-radius: var(--kf-radius-xs);\n background: #fff;\n }\n `,\n})\nexport class Carousel implements AfterContentInit {\n readonly autoplay = input(false);\n readonly interval = input(5000, { transform: numberAttribute });\n readonly indexChange = output<number>();\n\n readonly slides = contentChildren(CarouselSlide);\n\n private readonly activeIndexSignal = signal(0);\n readonly activeIndex = this.activeIndexSignal.asReadonly();\n\n private readonly destroyRef = inject(DestroyRef);\n private timer: ReturnType<typeof setInterval> | null = null;\n private autoplayPaused = false;\n\n ngAfterContentInit(): void {\n this.startAutoplay();\n this.destroyRef.onDestroy(() => this.stopAutoplay());\n }\n\n next(): void {\n const total = this.slides().length;\n if (total === 0) {\n return;\n }\n this.goTo((this.activeIndexSignal() + 1) % total);\n }\n\n previous(): void {\n const total = this.slides().length;\n if (total === 0) {\n return;\n }\n this.goTo((this.activeIndexSignal() - 1 + total) % total);\n }\n\n goTo(index: number): void {\n if (index === this.activeIndexSignal()) {\n return;\n }\n this.activeIndexSignal.set(index);\n this.indexChange.emit(index);\n }\n\n pauseAutoplay(): void {\n this.autoplayPaused = true;\n }\n\n resumeAutoplay(): void {\n this.autoplayPaused = false;\n }\n\n private startAutoplay(): void {\n if (!this.autoplay() || this.slides().length <= 1) {\n return;\n }\n this.timer = setInterval(() => {\n if (!this.autoplayPaused) {\n this.next();\n }\n }, this.interval());\n }\n\n private stopAutoplay(): void {\n if (this.timer !== null) {\n clearInterval(this.timer);\n this.timer = null;\n }\n }\n}\n","import {\n booleanAttribute,\n Component,\n effect,\n ElementRef,\n forwardRef,\n input,\n output,\n viewChild,\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\n/**\n * Checkbox accesible con soporte de estado \"indeterminate\".\n *\n * `indeterminate` no existe como atributo HTML: el navegador solo lo expone\n * como propiedad del elemento nativo, así que se aplica a mano sobre el\n * `<input>` interno vía `viewChild` + `effect` cada vez que cambia el input.\n *\n * Implementa `ControlValueAccessor` para poder usarse con `formControlName` /\n * `ngModel` igual que un checkbox nativo. En ese modo, `writeValue` controla\n * el DOM directamente y el input `checked` (pensado para binding manual sin\n * forms) queda en su valor por defecto — igual que `disabled` combina el\n * input signal con `setDisabledState` en el resto de la librería.\n *\n * `invalid` pinta el recuadro en rojo y setea `aria-invalid` en el `<input>`\n * nativo — mismo mecanismo que `Input.invalid`, para el caso típico de un\n * checkbox obligatorio (ej. \"Acepto términos y condiciones\") sin marcar.\n *\n * <kf-checkbox label=\"Aceptar términos\" [(checked)]=\"accepted\" />\n * <kf-checkbox label=\"Seleccionar todo\" [indeterminate]=\"isPartial()\" />\n * <kf-checkbox label=\"Notificaciones\" formControlName=\"notifications\" />\n * <kf-checkbox label=\"Acepto los términos y condiciones\" [invalid]=\"submitted() && !accepted()\" />\n */\n@Component({\n selector: 'kf-checkbox',\n template: `\n <label class=\"kf-checkbox\" [class.kf-checkbox--disabled]=\"disabled()\">\n <input\n #inputRef\n type=\"checkbox\"\n [checked]=\"checked()\"\n [disabled]=\"disabled()\"\n [attr.aria-invalid]=\"invalid() ? true : null\"\n (change)=\"onChange($event)\"\n (blur)=\"onTouched()\"\n />\n <span class=\"kf-checkbox__box\" [class.kf-checkbox__box--invalid]=\"invalid()\"></span>\n @if (label()) {\n <span class=\"kf-checkbox__label\">{{ label() }}</span>\n }\n </label>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-checkbox {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-sm);\n cursor: pointer;\n font: inherit;\n font-family: var(--kf-font-body);\n color: var(--kf-color-text);\n }\n .kf-checkbox--disabled {\n cursor: not-allowed;\n color: var(--kf-color-text-muted);\n }\n .kf-checkbox input {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n .kf-checkbox__box {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--kf-space-md);\n height: var(--kf-space-md);\n border: 1px solid var(--kf-color-border-strong);\n border-radius: var(--kf-radius-xs);\n background: var(--kf-color-white);\n transition:\n background 0.14s,\n border-color 0.14s;\n }\n .kf-checkbox input:checked + .kf-checkbox__box,\n .kf-checkbox input:indeterminate + .kf-checkbox__box {\n background: var(--kf-color-primary);\n border-color: var(--kf-color-primary);\n }\n .kf-checkbox input:checked + .kf-checkbox__box::after {\n content: '';\n width: 4px;\n height: 8px;\n border: solid var(--kf-color-white);\n border-width: 0 2px 2px 0;\n transform: rotate(45deg) translate(-1px, -1px);\n }\n .kf-checkbox input:indeterminate + .kf-checkbox__box::after {\n content: '';\n width: 8px;\n height: 2px;\n background: var(--kf-color-white);\n border-radius: var(--kf-radius-xs);\n }\n .kf-checkbox input:focus-visible + .kf-checkbox__box {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-checkbox__box--invalid {\n border-color: var(--kf-color-error);\n }\n .kf-checkbox--disabled .kf-checkbox__box {\n opacity: 0.5;\n }\n .kf-checkbox__label {\n user-select: none;\n }\n `,\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => Checkbox),\n multi: true,\n },\n ],\n})\nexport class Checkbox implements ControlValueAccessor {\n readonly label = input<string>();\n readonly checked = input(false, { transform: booleanAttribute });\n readonly disabled = input(false, { transform: booleanAttribute });\n readonly indeterminate = input(false, { transform: booleanAttribute });\n /** Recuadro en rojo + aria-invalid — ej. checkbox obligatorio sin marcar. */\n readonly invalid = input(false, { transform: booleanAttribute });\n\n readonly checkedChange = output<boolean>();\n\n private readonly inputRef = viewChild.required<ElementRef<HTMLInputElement>>('inputRef');\n\n /** Callbacks registrados por Forms; no-op hasta que registerOnChange/Touched las reemplacen. */\n private onChangeFn: (value: boolean) => void = () => {};\n private onTouchedFn: () => void = () => {};\n\n constructor() {\n // El estado \"indeterminate\" no tiene atributo HTML: hay que empujarlo\n // como propiedad DOM cada vez que cambia el input, incluyendo el\n // valor inicial del primer render.\n effect(() => {\n this.inputRef().nativeElement.indeterminate = this.indeterminate();\n });\n }\n\n onChange(event: Event): void {\n const value = (event.target as HTMLInputElement).checked;\n this.checkedChange.emit(value);\n this.onChangeFn(value);\n }\n\n onTouched(): void {\n this.onTouchedFn();\n }\n\n writeValue(value: boolean): void {\n this.inputRef().nativeElement.checked = !!value;\n }\n\n registerOnChange(fn: (value: boolean) => void): void {\n this.onChangeFn = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouchedFn = fn;\n }\n\n setDisabledState?(isDisabled: boolean): void {\n this.inputRef().nativeElement.disabled = isDisabled;\n }\n}\n","import { Component, input } from '@angular/core';\n\n/**\n * Chip de fondo suave con un punto líder que indica estado. Pensado\n * principalmente para celdas de tabla (estado de fila), pero utilizable\n * en cualquier lugar donde se necesite una etiqueta de estado compacta.\n *\n * <kf-chip tone=\"warn\">Pendiente</kf-chip>\n * <kf-chip tone=\"ok\">Aprobado</kf-chip>\n *\n * Nota: la spec original define la unión de tonos como \"ok\" | \"warn\" |\n * \"error\" | \"neutral\". Internamente se mapean a los tokens semánticos de\n * projects/ui/src/tokens/base.css: ok -> success, warn -> warning,\n * error -> error, neutral -> surface/border/text-muted (no existe un\n * token \"neutral\" dedicado en base.css, así que se arma con los tokens\n * de superficie/borde/texto-muted más cercanos).\n */\n@Component({\n selector: 'kf-chip',\n template: `\n <span\n class=\"kf-chip__dot\"\n [class.kf-chip__dot--ok]=\"tone() === 'ok'\"\n [class.kf-chip__dot--warn]=\"tone() === 'warn'\"\n [class.kf-chip__dot--error]=\"tone() === 'error'\"\n [class.kf-chip__dot--neutral]=\"tone() === 'neutral'\"\n ></span>\n <span class=\"kf-chip__label\"><ng-content /></span>\n `,\n styles: `\n :host {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border-radius: var(--kf-radius-pill);\n border: 1px solid transparent;\n font: inherit;\n font-size: 0.875em;\n line-height: 1;\n color: var(--kf-color-text);\n background: var(--kf-color-surface);\n border-color: var(--kf-color-border);\n white-space: nowrap;\n }\n :host(.kf-chip--ok) {\n background: var(--kf-color-success-soft);\n border-color: var(--kf-color-success-soft);\n color: var(--kf-color-text);\n }\n :host(.kf-chip--warn) {\n background: var(--kf-color-warning-soft);\n border-color: var(--kf-color-warning-soft);\n color: var(--kf-color-text);\n }\n :host(.kf-chip--error) {\n background: var(--kf-color-error-soft);\n border-color: var(--kf-color-error-soft);\n color: var(--kf-color-text);\n }\n :host(.kf-chip--neutral) {\n background: var(--kf-color-surface);\n border-color: var(--kf-color-border);\n color: var(--kf-color-text);\n }\n .kf-chip__dot {\n inline-size: 0.5em;\n block-size: 0.5em;\n border-radius: var(--kf-radius-pill);\n flex: none;\n background: var(--kf-color-text-muted);\n }\n .kf-chip__label {\n display: inline-block;\n }\n .kf-chip__dot--ok {\n background: var(--kf-color-success);\n }\n .kf-chip__dot--warn {\n background: var(--kf-color-warning);\n }\n .kf-chip__dot--error {\n background: var(--kf-color-error);\n }\n .kf-chip__dot--neutral {\n background: var(--kf-color-text-muted);\n }\n `,\n host: {\n '[class.kf-chip--ok]': \"tone() === 'ok'\",\n '[class.kf-chip--warn]': \"tone() === 'warn'\",\n '[class.kf-chip--error]': \"tone() === 'error'\",\n '[class.kf-chip--neutral]': \"tone() === 'neutral'\",\n },\n})\nexport class Chip {\n readonly tone = input<'ok' | 'warn' | 'error' | 'neutral'>('neutral');\n}\n","import { Component, input } from '@angular/core';\n\nexport type DividerOrientation = 'horizontal' | 'vertical';\n\n/**\n * Separador visual simple entre bloques de contenido. `orientation`\n * controla si es una línea horizontal (para separar secciones apiladas) o\n * vertical (para separar elementos en una fila, ej. acciones en una toolbar,\n * o las columnas de metadata en `kf-company-selector`).\n *\n * En `vertical`, el divisor necesita una altura del contexto donde vive —\n * `:host { align-self: stretch }` lo hace ocupar la altura del contenedor\n * flex/grid padre sin que el consumidor tenga que fijarla a mano. `flex:\n * none` evita que el propio divisor se achique a 0 dentro de ese contenedor\n * flex cuando hay contenido hermano compitiendo por espacio.\n *\n * <kf-divider />\n * <kf-divider orientation=\"vertical\" />\n */\n@Component({\n selector: 'kf-divider',\n template: '',\n styles: `\n :host {\n display: block;\n flex: none;\n border: none;\n background: var(--kf-color-border);\n }\n :host,\n :host([orientation='horizontal']) {\n width: 100%;\n height: 1px;\n }\n :host([orientation='vertical']) {\n align-self: stretch;\n width: 1px;\n height: auto;\n }\n `,\n host: {\n role: 'separator',\n '[attr.orientation]': 'orientation()',\n '[attr.aria-orientation]': 'orientation()',\n },\n})\nexport class Divider {\n readonly orientation = input<DividerOrientation>('horizontal');\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\n\n/**\n * Label superior compartido por todos los campos de formulario del design\n * system (páginas 11-12: Text Field, Select, Multiselect) — uppercase,\n * chico, gris, con letter-spacing amplio. El PDF fija un único tratamiento\n * (\"PATENTE O VIN\", \"SUCURSAL\", \"SUCURSALES\" usan exactamente el mismo\n * estilo), así que este componente es la única fuente de verdad: antes vivía\n * copiado por separado en `Input`, `Select`, `SelectMenu` y `MultiSelect`,\n * y dos de esas copias ya habían divergido del estilo real del PDF.\n *\n * No reemplaza al `<label>` nativo — lo envuelve, para no perder la\n * asociación de accesibilidad `for`/`id` con el control real.\n *\n * `required` agrega un asterisco visual en el tono de error, separado del\n * texto por un espacio y marcado `aria-hidden` — el estado obligatorio real\n * para lectores de pantalla lo comunica el propio control (`aria-required`\n * / `required` en el `<input>`/`<select>` asociado), no este label.\n *\n * <kf-field-label [for]=\"inputId\">Patente o VIN</kf-field-label>\n * <kf-field-label [for]=\"inputId\" required>Correo electrónico</kf-field-label>\n */\n@Component({\n selector: 'kf-field-label',\n template: `\n <label class=\"kf-field-label\" [for]=\"for()\">\n <ng-content />\n @if (required()) {\n <span class=\"kf-field-label__required\" aria-hidden=\"true\">*</span>\n }\n </label>\n `,\n styles: `\n :host {\n display: contents;\n }\n .kf-field-label {\n font-family: var(--kf-font-title);\n font-size: 0.75rem;\n font-weight: 600;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--kf-color-text-muted);\n }\n .kf-field-label__required {\n color: var(--kf-color-error);\n margin-inline-start: 2px;\n }\n `,\n})\nexport class FieldLabel {\n /** `id` del control asociado — se refleja como `for` en el `<label>` interno. */\n readonly for = input<string>();\n /** Muestra un asterisco visual indicando que el campo es obligatorio. */\n readonly required = input(false, { transform: booleanAttribute });\n}\n","import { Overlay, type OverlayRef } from '@angular/cdk/overlay';\nimport { TemplatePortal } from '@angular/cdk/portal';\nimport {\n Component,\n DestroyRef,\n ElementRef,\n HostListener,\n TemplateRef,\n ViewContainerRef,\n booleanAttribute,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { FieldLabel } from '../field-label/FieldLabel';\n\n/** Normalized shape used internally once `options` (string[] or object[]) is resolved. */\ninterface SelectOption {\n value: string;\n label: string;\n}\n\nlet nextId = 0;\n\n/**\n * Dropdown de selección simple con panel propio — NUNCA usa el `<select>`\n * nativo del navegador. Un `<select>` real siempre delega el popup de\n * opciones al sistema operativo, y ningún CSS puede controlar cómo se ve\n * ese popup.\n *\n * Hasta la `0.1.5` existía además `kf-select-menu`, un segundo componente\n * prácticamente idéntico (mismo trigger, mismo panel, mismo CSS) que solo\n * se diferenciaba en aceptar `options` únicamente como `{ value, label }[]`\n * (sin el atajo `string[]` que `Select` ya tenía). Se fusionaron en este\n * componente en la `0.2.0` — mantener dos componentes con la misma\n * interacción y el mismo aspecto visual, cuya única diferencia real era la\n * forma de un input, no se sostenía como dos piezas separadas del catálogo.\n *\n * El panel flotante se conecta al trigger vía `@angular/cdk/overlay` — el\n * mismo mecanismo que `Dropdown` (ver `../dropdown/Dropdown.ts`).\n *\n * <kf-select label=\"Sede\" [options]=\"['Lima', 'Arequipa', 'Trujillo']\" placeholder=\"Selecciona…\" />\n * <kf-select [options]=\"[{ value: 'pe', label: 'Perú' }]\" (valueChange)=\"onCountry($event)\" />\n *\n * Pendiente: el prop `icon` de otros componentes del design system requiere\n * un componente Icon / sprite SVG que esta librería todavía no tiene — este\n * componente no usa iconos, así que no aplica acá.\n */\n@Component({\n selector: 'kf-select',\n imports: [FieldLabel],\n template: `\n @if (label()) {\n <kf-field-label [for]=\"triggerId\">{{ label() }}</kf-field-label>\n }\n <button\n #trigger\n type=\"button\"\n [id]=\"triggerId\"\n class=\"kf-select__trigger\"\n [class.kf-select__trigger--disabled]=\"disabled()\"\n [disabled]=\"disabled()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-controls]=\"isOpen() ? listboxId : null\"\n (click)=\"toggle()\"\n >\n <span class=\"kf-select__value\" [class.kf-select__value--placeholder]=\"!selectedOption()\">\n {{ selectedOption()?.label ?? placeholder() }}\n </span>\n <span\n class=\"kf-select__caret\"\n [class.kf-select__caret--open]=\"isOpen()\"\n aria-hidden=\"true\"\n ></span>\n </button>\n <ng-template #panelTemplate>\n <ul\n class=\"kf-select__panel\"\n [id]=\"listboxId\"\n role=\"listbox\"\n [attr.aria-labelledby]=\"triggerId\"\n >\n @for (option of normalizedOptions(); track option.value) {\n <li\n class=\"kf-select__option\"\n [class.kf-select__option--selected]=\"option.value === value()\"\n role=\"option\"\n tabindex=\"0\"\n [attr.aria-selected]=\"option.value === value()\"\n (click)=\"select(option)\"\n (keydown.enter)=\"select(option)\"\n (keydown.space)=\"$event.preventDefault(); select(option)\"\n >\n {{ option.label }}\n </li>\n } @empty {\n <li class=\"kf-select__empty\">Sin opciones disponibles</li>\n }\n </ul>\n </ng-template>\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n /*\n * Ancho FIJO, no min-width: un :host en flex sin ancho propio se\n * ajusta al contenido de su hijo en cada render — con min-width sí se\n * evita que se achique con una opción de label corto, pero seguía\n * pudiendo CRECER de más con una opción de label largo, desalineando\n * varios kf-select en fila dentro del mismo formulario (ej. \"Sede\" /\n * \"País\" / \"Divisiones\" ya no miden lo mismo entre sí). El texto que\n * no entra se corta con el text-overflow: ellipsis que\n * .kf-select__value ya tenía preparado — antes nunca se activaba\n * porque el host crecía en vez de cortar el texto.\n */\n width: 240px;\n font-family: var(--kf-font-body);\n }\n .kf-select__trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-sm);\n width: 100%;\n font: inherit;\n color: var(--kf-color-text);\n padding: var(--kf-space-sm) var(--kf-space-md);\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n cursor: pointer;\n transition:\n border-color 0.14s,\n box-shadow 0.14s;\n }\n .kf-select__trigger:hover:not(:disabled) {\n border-color: var(--kf-color-border-strong);\n }\n .kf-select__trigger:focus-visible {\n outline: none;\n border-color: var(--kf-color-primary);\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-select__trigger--disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .kf-select__value {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .kf-select__value--placeholder {\n color: var(--kf-color-text-muted);\n }\n .kf-select__caret {\n flex-shrink: 0;\n width: 8px;\n height: 8px;\n border-right: 2px solid var(--kf-color-text-muted);\n border-bottom: 2px solid var(--kf-color-text-muted);\n transform: rotate(45deg);\n transition: transform 0.14s;\n margin-top: -4px;\n }\n .kf-select__caret--open {\n transform: rotate(-135deg);\n margin-top: 4px;\n }\n .kf-select__panel {\n box-sizing: border-box;\n width: 100%;\n margin: 0;\n padding: var(--kf-space-xs) 0;\n list-style: none;\n max-height: 240px;\n overflow-y: auto;\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n box-shadow: var(--kf-shadow-md);\n }\n .kf-select__option {\n padding: var(--kf-space-sm) var(--kf-space-md);\n color: var(--kf-color-text);\n cursor: pointer;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .kf-select__option:hover {\n background: var(--kf-color-primary-soft);\n }\n .kf-select__option--selected {\n background: var(--kf-color-primary-soft);\n color: var(--kf-color-primary);\n font-weight: 600;\n }\n .kf-select__empty {\n padding: var(--kf-space-sm) var(--kf-space-md);\n color: var(--kf-color-text-muted);\n }\n `,\n})\nexport class Select {\n readonly label = input<string>();\n readonly options = input.required<string[] | SelectOption[]>();\n readonly value = input<string>();\n readonly placeholder = input<string>('Seleccionar');\n readonly disabled = input(false, { transform: booleanAttribute });\n\n readonly valueChange = output<string>();\n\n private readonly instanceId = `kf-select-${nextId++}`;\n readonly triggerId = `${this.instanceId}-trigger`;\n readonly listboxId = `${this.instanceId}-listbox`;\n\n readonly isOpen = signal(false);\n\n /** Resolves the union (`string[] | { value; label }[]`) into a single shape for the template. */\n readonly normalizedOptions = computed<SelectOption[]>(() =>\n this.options().map((option) =>\n typeof option === 'string' ? { value: option, label: option } : option,\n ),\n );\n\n readonly selectedOption = computed(() =>\n this.normalizedOptions().find((option) => option.value === this.value()),\n );\n\n private readonly triggerRef = viewChild.required<ElementRef<HTMLButtonElement>>('trigger');\n private readonly panelTemplate = viewChild.required<TemplateRef<unknown>>('panelTemplate');\n\n private readonly overlayService = inject(Overlay);\n private readonly viewContainerRef = inject(ViewContainerRef);\n private readonly destroyRef = inject(DestroyRef);\n\n private overlayRef: OverlayRef | null = null;\n\n constructor() {\n effect(() => {\n if (this.isOpen()) {\n this.attach();\n } else {\n this.detach();\n }\n });\n\n this.destroyRef.onDestroy(() => this.overlayRef?.dispose());\n }\n\n /**\n * Respaldo de `overlayRef.keydownEvents()`: ese observable del CDK solo ve\n * teclas presionadas con el foco DENTRO del pane del overlay. Si el foco\n * sigue en el trigger (o en cualquier otro lado de la página) mientras el\n * panel está abierto, `keydownEvents()` nunca dispara.\n */\n @HostListener('document:keydown.escape')\n onDocumentEscape(): void {\n this.isOpen.set(false);\n }\n\n toggle(): void {\n if (this.disabled()) {\n return;\n }\n this.isOpen.update((open) => !open);\n }\n\n select(option: SelectOption): void {\n this.isOpen.set(false);\n if (option.value !== this.value()) {\n this.valueChange.emit(option.value);\n }\n }\n\n private attach(): void {\n if (this.overlayRef?.hasAttached()) {\n return;\n }\n\n const overlayRef = this.getOrCreateOverlayRef();\n // Se remide el ancho del trigger en cada apertura, no solo la primera —\n // ver la misma nota en SelectMenu: cachear el ancho en la creación del\n // overlay lo deja desincronizado si el trigger cambia de tamaño entre\n // una apertura y la siguiente.\n overlayRef.updateSize({ width: this.triggerRef().nativeElement.getBoundingClientRect().width });\n\n const portal = new TemplatePortal(this.panelTemplate(), this.viewContainerRef);\n overlayRef.attach(portal);\n\n overlayRef.outsidePointerEvents().subscribe(() => this.isOpen.set(false));\n overlayRef.keydownEvents().subscribe((event) => {\n if (event.key === 'Escape') {\n this.isOpen.set(false);\n }\n });\n }\n\n private detach(): void {\n this.overlayRef?.detach();\n }\n\n private getOrCreateOverlayRef(): OverlayRef {\n if (this.overlayRef) {\n return this.overlayRef;\n }\n\n const positionStrategy = this.overlayService\n .position()\n .flexibleConnectedTo(this.triggerRef())\n .withPositions([\n { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 4 },\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -4 },\n { originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top', offsetY: 4 },\n { originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', offsetY: -4 },\n ])\n .withViewportMargin(8)\n .withPush(true);\n\n this.overlayRef = this.overlayService.create({\n positionStrategy,\n scrollStrategy: this.overlayService.scrollStrategies.reposition(),\n width: this.triggerRef().nativeElement.getBoundingClientRect().width,\n maxWidth: '90vw',\n });\n\n return this.overlayRef;\n }\n}\n","import { Component, input, output } from '@angular/core';\nimport { Divider } from '../divider/Divider';\nimport { Select } from '../select/Select';\n\n/** Metadato clave mostrado junto al selector (RUC, identificación, sucursal). */\nexport interface CompanySelectorMeta {\n label: string;\n value: string;\n}\n\n/**\n * Conmutador de empresa activa con metadatos clave (página 32) — encabeza\n * la pantalla de inicio del portal. Compone `kf-select` para el propio\n * selector (mismo panel propio, sin `<select>` nativo) y proyecta hasta 3\n * pares label/valor (RUC, Identificación, Sucursal en el ejemplo del PDF).\n *\n * <kf-company-selector\n * label=\"Selecciona empresa\"\n * [companies]=\"['TRANSPORTES DEL SUR S.A.C.', 'ANDES MAQ LTDA.']\"\n * [value]=\"activeCompany()\"\n * (valueChange)=\"activeCompany.set($event)\"\n * [meta]=\"[\n * { label: 'RUC', value: '20448712359' },\n * { label: 'Identificación', value: '0004002232' },\n * { label: 'Sucursal', value: 'Sucursal Norte' },\n * ]\"\n * />\n */\n@Component({\n selector: 'kf-company-selector',\n imports: [Divider, Select],\n template: `\n <kf-select\n class=\"kf-company-selector__select\"\n [label]=\"label()\"\n [options]=\"companies()\"\n [value]=\"value()\"\n (valueChange)=\"valueChange.emit($event)\"\n />\n @if (meta().length) {\n <div class=\"kf-company-selector__meta\">\n @for (item of meta(); track item.label; let last = $last) {\n <div class=\"kf-company-selector__meta-item\">\n <span class=\"kf-company-selector__meta-label\">{{ item.label }}</span>\n <span class=\"kf-company-selector__meta-value\">{{ item.value }}</span>\n </div>\n @if (!last) {\n <kf-divider orientation=\"vertical\" />\n }\n }\n </div>\n }\n `,\n styles: `\n :host {\n display: flex;\n align-items: center;\n gap: var(--kf-space-lg);\n flex-wrap: wrap;\n padding: var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n background: var(--kf-color-white);\n font-family: var(--kf-font-body);\n }\n .kf-company-selector__select {\n flex: 1 1 260px;\n min-width: 0;\n }\n .kf-company-selector__meta {\n display: flex;\n gap: var(--kf-space-lg);\n flex-wrap: wrap;\n }\n .kf-company-selector__meta-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n .kf-company-selector__meta-label {\n font-family: var(--kf-font-title);\n font-size: 0.72rem;\n font-weight: 600;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--kf-color-text-muted);\n }\n .kf-company-selector__meta-value {\n font-family: var(--kf-font-mono);\n font-size: 0.875rem;\n color: var(--kf-color-ink);\n }\n `,\n})\nexport class CompanySelector {\n readonly label = input('Selecciona empresa');\n readonly companies = input.required<string[]>();\n readonly value = input<string>();\n readonly meta = input<CompanySelectorMeta[]>([]);\n\n readonly valueChange = output<string>();\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Marcador genérico para contenido aún por definir (página 38) — comunica\n * \"contenido disponible para uso\" sin parecer un error, a diferencia de\n * `kf-empty-state` (que comunica ausencia real de datos del usuario).\n * Pensado para secciones del portal que un negocio todavía no completó.\n *\n * `compact` reduce el tamaño de la imagen placeholder y omite el badge de\n * pie (segunda variante de la página 38, sin la etiqueta \"Contenido\n * disponible para uso\" al final).\n *\n * <kf-content-slot title=\"Contenido disponible\"\n * description=\"Espacio reservado para contenido de Divemotor Perú. Disponible para uso.\" />\n * <kf-content-slot compact icon=\"star\" title=\"Contenido disponible\"\n * description=\"Espacio reservado para contenido de Divemotor Perú.\" />\n */\n@Component({\n selector: 'kf-content-slot',\n imports: [Icon],\n template: `\n <div class=\"kf-content-slot__media\">\n <kf-icon [name]=\"icon()\" [size]=\"compact() ? 'md' : 'lg'\" />\n </div>\n <span class=\"kf-content-slot__title\">{{ title() }}</span>\n @if (description()) {\n <p class=\"kf-content-slot__description\">{{ description() }}</p>\n }\n @if (!compact()) {\n <span class=\"kf-content-slot__footer\">Contenido disponible para uso</span>\n }\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-white);\n font-family: var(--kf-font-body);\n }\n .kf-content-slot__media {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 96px;\n margin-bottom: var(--kf-space-xs);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-surface);\n color: var(--kf-color-border-strong);\n }\n :host(.kf-content-slot--compact) .kf-content-slot__media {\n height: 56px;\n }\n .kf-content-slot__title {\n font-family: var(--kf-font-title);\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-content-slot__description {\n margin: 0;\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n }\n .kf-content-slot__footer {\n align-self: flex-start;\n margin-top: var(--kf-space-xs);\n padding: 2px var(--kf-space-sm);\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-surface);\n color: var(--kf-color-text-muted);\n font-size: 0.72rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n }\n `,\n host: {\n '[class.kf-content-slot--compact]': 'compact()',\n },\n})\nexport class ContentSlot {\n readonly title = input('Contenido disponible');\n readonly description = input<string>();\n readonly icon = input<IconName>('layers');\n readonly compact = input(false, { transform: booleanAttribute });\n}\n","import { Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Placeholder para una sección sin contenido. Dos tonos, con anatomía\n * distinta (páginas 27-28 del design system, que los trata como piezas\n * separadas — \"Error State\" no es una variante de color de \"Empty State\",\n * es un estado semánticamente distinto):\n *\n * - `neutral` (default): \"cero resultados\" — cuadro con borde punteado\n * discreto, para listas vacías o búsquedas sin coincidencias. No es un\n * error, es la ausencia normal de datos.\n * - `error`: fallo real de carga — sin borde punteado, con un ícono de\n * alerta más prominente y texto en el tono de error. Pensado para usarse\n * junto a un botón \"Reintentar\" en el slot por defecto.\n *\n * <kf-empty-state>No se encontraron resultados.</kf-empty-state>\n * <kf-empty-state icon=\"search\">Sin coincidencias para tu búsqueda.</kf-empty-state>\n * <kf-empty-state tone=\"error\" icon=\"alert-triangle\">\n * No pudimos cargar tus vehículos\n * <kf-button (click)=\"retry()\">Reintentar</kf-button>\n * </kf-empty-state>\n */\n@Component({\n selector: 'kf-empty-state',\n imports: [Icon],\n template: `\n @if (icon(); as iconName) {\n <span class=\"kf-empty-state__icon\">\n <kf-icon [name]=\"iconName\" [size]=\"tone() === 'error' ? 'lg' : 'md'\" />\n </span>\n }\n <div class=\"kf-empty-state__content\">\n <ng-content />\n </div>\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-xl);\n border: 1px dashed var(--kf-color-border-strong);\n border-radius: var(--kf-radius-md);\n background: var(--kf-color-surface);\n color: var(--kf-color-text-muted);\n font: inherit;\n text-align: center;\n }\n :host(.kf-empty-state--error) {\n border: none;\n background: var(--kf-color-error-soft);\n }\n .kf-empty-state__content {\n color: var(--kf-color-text-muted);\n font-family: var(--kf-font-body);\n }\n :host(.kf-empty-state--error) .kf-empty-state__content {\n color: var(--kf-color-error-strong);\n }\n `,\n host: {\n '[class.kf-empty-state--error]': \"tone() === 'error'\",\n },\n})\nexport class EmptyState {\n readonly icon = input<IconName | undefined>(undefined);\n /** `neutral` (default): cero resultados. `error`: fallo real de carga. */\n readonly tone = input<'neutral' | 'error'>('neutral');\n}\n","import { Component, input } from '@angular/core';\n\n/** Forma del placeholder. */\nexport type SkeletonVariant = 'text' | 'circle' | 'rect';\n\n/**\n * Bloque placeholder con shimmer para contenido que todavía carga: una línea\n * de texto, un avatar o un área de card/imagen, según `variant`.\n *\n * Es decorativo (`aria-hidden`): quien lo usa debería marcar el contenedor con\n * `aria-busy=\"true\"` mientras carga, así el lector de pantalla anuncia el\n * estado una vez en vez de leer N placeholders vacíos.\n *\n * `circle` usa `aspect-ratio`, así que alcanza con darle `width`.\n *\n * <kf-skeleton />\n * <kf-skeleton variant=\"circle\" width=\"40px\" />\n * <kf-skeleton variant=\"rect\" width=\"100%\" height=\"120px\" />\n */\n@Component({\n selector: 'kf-skeleton',\n template: `\n <span\n class=\"kf-skeleton\"\n [class]=\"'kf-skeleton--' + variant()\"\n aria-hidden=\"true\"\n [style.width]=\"width()\"\n [style.height]=\"height() || null\"\n ></span>\n `,\n styles: `\n :host {\n display: block;\n }\n .kf-skeleton {\n display: block;\n background: linear-gradient(\n 90deg,\n var(--kf-color-border) 25%,\n var(--kf-color-surface) 37%,\n var(--kf-color-border) 63%\n );\n background-size: 400% 100%;\n animation: kf-skeleton-shimmer 1.4s ease infinite;\n }\n .kf-skeleton--text {\n height: 14px;\n border-radius: var(--kf-radius-xs);\n }\n .kf-skeleton--rect {\n height: 80px;\n border-radius: var(--kf-radius-sm);\n }\n .kf-skeleton--circle {\n aspect-ratio: 1 / 1;\n border-radius: var(--kf-radius-pill);\n }\n @keyframes kf-skeleton-shimmer {\n from {\n background-position: 100% 0;\n }\n to {\n background-position: 0 0;\n }\n }\n @media (prefers-reduced-motion: reduce) {\n .kf-skeleton {\n animation: none;\n background: var(--kf-color-border);\n }\n }\n `,\n})\nexport class Skeleton {\n readonly variant = input<SkeletonVariant>('text');\n /** Ancho CSS. Default `'100%'`. */\n readonly width = input('100%');\n /** Alto CSS. Vacío deja el alto/aspect-ratio propio de la variante. */\n readonly height = input('');\n}\n","import { Component, input } from '@angular/core';\nimport { EmptyState } from '../empty-state/EmptyState';\nimport { Skeleton } from '../skeleton/Skeleton';\nimport { Spinner } from '../spinner/Spinner';\n\n/** En qué estado está la sección. */\nexport type ContentStateKind = 'ready' | 'loading' | 'empty' | 'error';\n\n/** Cómo se dibuja `loading`. Default `'skeleton'`. */\nexport type ContentStateLoad = 'skeleton' | 'spinner';\n\n/**\n * Wrapper de los cuatro estados que toda sección tiene: cargando, con datos,\n * vacía y con error. Un componente en vez de tres `@if` sueltos, porque es\n * siempre el mismo slot el que va rotando entre los cuatro.\n *\n * Con `state=\"ready\"` proyecta el contenido real y desaparece; en los otros\n * tres dibuja el placeholder correspondiente y el contenido no se instancia.\n * No inventa visuales propios: `loading` usa `kf-skeleton` (o `kf-spinner` con\n * `load=\"spinner\"`), y `empty`/`error` usan `kf-empty-state`.\n *\n * Las acciones (reintentar, crear) van en el slot `actions` — se ignoran\n * mientras carga, porque no hay nada que reintentar todavía.\n *\n * <kf-content-state [state]=\"state()\" title=\"No pudimos cargar tus vehículos\"\n * subtitle=\"Revisá tu conexión e intentá de nuevo.\">\n * <kf-button actions (click)=\"retry()\">Reintentar</kf-button>\n * <kf-data-table [columns]=\"cols\" [rows]=\"rows()\" />\n * </kf-content-state>\n */\n@Component({\n selector: 'kf-content-state',\n imports: [EmptyState, Skeleton, Spinner],\n template: `\n @switch (state()) {\n @case ('ready') {\n <ng-content />\n }\n @case ('loading') {\n <div class=\"kf-content-state__loading\" aria-busy=\"true\">\n @if (load() === 'spinner') {\n <kf-spinner [label]=\"loadingLabel()\" />\n } @else {\n <kf-skeleton />\n <kf-skeleton width=\"80%\" />\n <kf-skeleton width=\"60%\" />\n }\n </div>\n }\n @default {\n <kf-empty-state [tone]=\"state() === 'error' ? 'error' : 'neutral'\">\n @if (title()) {\n <p class=\"kf-content-state__title\">{{ title() }}</p>\n }\n @if (subtitle()) {\n <p class=\"kf-content-state__subtitle\">{{ subtitle() }}</p>\n }\n <div class=\"kf-content-state__actions\"><ng-content select=\"[actions]\" /></div>\n </kf-empty-state>\n }\n }\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-content-state__loading {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-sm);\n }\n .kf-content-state__title {\n margin: 0;\n font-family: var(--kf-font-title);\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-content-state__subtitle {\n margin: 0;\n color: var(--kf-color-text-muted);\n }\n .kf-content-state__actions:empty {\n display: none;\n }\n .kf-content-state__actions {\n display: flex;\n flex-wrap: wrap;\n justify-content: center;\n gap: var(--kf-space-sm);\n margin-top: var(--kf-space-sm);\n }\n `,\n})\nexport class ContentState {\n readonly state = input.required<ContentStateKind>();\n /** Forma del estado de carga: silueta (default) o spinner. */\n readonly load = input<ContentStateLoad>('skeleton');\n /** Título de `empty`/`error`. Ignorado mientras carga. */\n readonly title = input('');\n readonly subtitle = input('');\n /** Texto al lado del spinner cuando `load=\"spinner\"`. */\n readonly loadingLabel = input('Cargando…');\n}\n","import { Component, computed, input, output, signal, TemplateRef } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\n\n/**\n * Zona que ocupa la columna en la vista de cards. La vista de tabla ignora\n * esto (salvo `media`, que igual se rinde como thumbnail en vez de imprimir\n * la URL):\n * - `media`: thumbnail a la izquierda del encabezado; el valor de la celda se\n * usa como `src` salvo que la columna traiga su `cellTemplates`.\n * - `title`: título del encabezado (ej. la patente/unidad).\n * - `status`: chip/estado al lado del título.\n * - `field` (default): par label/valor en el cuerpo.\n * - `action`: va al pie, separado del cuerpo por una línea.\n */\nexport type DataTableCardRole = 'media' | 'title' | 'status' | 'field' | 'action';\n\nexport interface DataTableColumn {\n key: string;\n label: string;\n right?: boolean;\n className?: string;\n cardRole?: DataTableCardRole;\n}\n\n/** Vistas disponibles cuando `cardable` está activo. */\nexport type DataTableView = 'table' | 'cards';\n\n/**\n * Tabla estandarizada con soporte opcional de toggle tabla/cards.\n *\n * El \"render\" custom por columna de la spec original (una función que\n * devuelve JSX) se resuelve acá de dos formas, de la más simple a la más\n * flexible:\n * - `render`: función `(row) => string` para el caso típico de mostrar un\n * valor derivado/formateado de la fila como texto plano.\n * - `cellTemplates`: mapa `key -> TemplateRef` para cuando un consumidor\n * necesita marcado real dentro de una celda (badges, links, botones). Se\n * proyecta con `ngTemplateOutlet` y recibe `{ $implicit: row, index }`.\n * Se eligió esta combinación en vez de content-projection por columna\n * (ng-content con selector) porque las columnas son dinámicas (vienen de\n * `columns()`), y `ngTemplateOutlet` es el mecanismo estándar de Angular\n * para \"insertar esta plantilla por cada fila de este array\".\n *\n * En la vista de cards, `cardRole` por columna reparte el contenido en zonas\n * — encabezado (thumbnail + título + estado), cuerpo (pares label/valor) y\n * pie separado por una línea para las acciones. Sin `cardRole`, todas las\n * columnas caen en el cuerpo, igual que antes.\n *\n * El modo `cards` no depende de un componente ViewToggle separado: expone\n * un control de segmentos mínimo inline (mismo patrón visual que\n * kf-segmented) para no acoplarse a un componente que otro agente puede\n * estar construyendo en paralelo — ver nota en el resumen de la tarea.\n *\n * <kf-data-table [columns]=\"columns\" [rows]=\"rows\" (rowClick)=\"onRowClick($event)\">\n * <kf-empty-state empty>No hay resultados para mostrar.</kf-empty-state>\n * </kf-data-table>\n *\n * <kf-data-table [columns]=\"columns\" [rows]=\"rows\" [cardable]=\"true\" defaultView=\"cards\" />\n *\n * El slot `[footer]` (página 15: \"slot de pie para paginación\") va siempre\n * al final, en ambas vistas, separado por una línea — pensado para proyectar\n * `<kf-pagination>`, que sigue siendo un componente independiente.\n *\n * <kf-data-table [columns]=\"columns\" [rows]=\"rows\">\n * <kf-pagination footer [page]=\"page()\" [total]=\"total()\" (pageChange)=\"page.set($event)\" />\n * </kf-data-table>\n */\n@Component({\n selector: 'kf-data-table',\n imports: [NgTemplateOutlet],\n template: `\n <div class=\"kf-data-table\" [class.kf-data-table--flush]=\"flush()\">\n @if (cardable()) {\n <div class=\"kf-data-table__toolbar\">\n <div class=\"kf-data-table__view-toggle\" role=\"group\" aria-label=\"Cambiar vista\">\n <button\n type=\"button\"\n class=\"kf-data-table__view-option\"\n [class.kf-data-table__view-option--active]=\"view() === 'table'\"\n [attr.aria-pressed]=\"view() === 'table'\"\n (click)=\"setView('table')\"\n >\n Tabla\n </button>\n <button\n type=\"button\"\n class=\"kf-data-table__view-option\"\n [class.kf-data-table__view-option--active]=\"view() === 'cards'\"\n [attr.aria-pressed]=\"view() === 'cards'\"\n (click)=\"setView('cards')\"\n >\n Tarjetas\n </button>\n </div>\n </div>\n }\n\n @if (rows().length === 0) {\n <div class=\"kf-data-table__empty\">\n <ng-content select=\"[empty]\" />\n </div>\n } @else if (view() === 'table') {\n <div class=\"kf-data-table__scroll\">\n <table class=\"kf-data-table__table\">\n <thead>\n <tr>\n @for (column of columns(); track column.key) {\n <th [class]=\"column.className\" [class.kf-data-table__cell--right]=\"column.right\">\n {{ column.label }}\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of rows(); track trackRow(row, $index); let i = $index) {\n <tr\n class=\"kf-data-table__row\"\n tabindex=\"0\"\n (click)=\"onRowClick(row, i)\"\n (keydown.enter)=\"onRowClick(row, i)\"\n >\n @for (column of columns(); track column.key) {\n <td\n [class]=\"column.className\"\n [class.kf-data-table__cell--right]=\"column.right\"\n >\n @if (cellTemplates()?.[column.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else if (column.cardRole === 'media') {\n <img class=\"kf-data-table__thumb\" [src]=\"cellValue(row, column)\" alt=\"\" />\n } @else {\n {{ cellValue(row, column) }}\n }\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n } @else {\n <div class=\"kf-data-table__cards\">\n @for (row of rows(); track trackRow(row, $index); let i = $index) {\n <div\n class=\"kf-data-table__card\"\n [class.kf-data-table__card--interactive]=\"cardInteractive()\"\n [attr.role]=\"cardInteractive() ? 'button' : null\"\n [attr.tabindex]=\"cardInteractive() ? 0 : null\"\n (click)=\"cardInteractive() && onRowClick(row, i)\"\n (keydown.enter)=\"cardInteractive() && onRowClick(row, i)\"\n >\n @if (cardMediaColumn() || cardTitleColumn() || cardStatusColumns().length) {\n <div class=\"kf-data-table__card-header\">\n @if (cardMediaColumn(); as media) {\n <div class=\"kf-data-table__card-media\">\n @if (cellTemplates()?.[media.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else {\n <img [src]=\"cellValue(row, media)\" alt=\"\" />\n }\n </div>\n }\n <div class=\"kf-data-table__card-heading\">\n @if (cardTitleColumn(); as title) {\n <span class=\"kf-data-table__card-title\">\n @if (cellTemplates()?.[title.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else {\n {{ cellValue(row, title) }}\n }\n </span>\n }\n @if (cardStatusColumns().length) {\n <span class=\"kf-data-table__card-statuses\">\n @for (column of cardStatusColumns(); track column.key) {\n @if (cellTemplates()?.[column.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else {\n {{ cellValue(row, column) }}\n }\n }\n </span>\n }\n </div>\n </div>\n }\n\n @if (cardFieldColumns().length) {\n <div class=\"kf-data-table__card-fields\">\n @for (column of cardFieldColumns(); track column.key) {\n <div class=\"kf-data-table__card-field\">\n <span class=\"kf-data-table__card-label\">{{ column.label }}</span>\n <span class=\"kf-data-table__card-value\">\n @if (cellTemplates()?.[column.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else {\n {{ cellValue(row, column) }}\n }\n </span>\n </div>\n }\n </div>\n }\n\n @if (cardActionColumns().length) {\n <div class=\"kf-data-table__card-actions\">\n @for (column of cardActionColumns(); track column.key) {\n @if (cellTemplates()?.[column.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else {\n {{ cellValue(row, column) }}\n }\n }\n </div>\n }\n </div>\n }\n </div>\n }\n\n @if (rows().length > 0) {\n <div class=\"kf-data-table__footer\">\n <ng-content select=\"[footer]\" />\n </div>\n }\n </div>\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-data-table {\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n box-shadow: var(--kf-shadow-sm);\n overflow: hidden;\n }\n .kf-data-table--flush {\n border: none;\n box-shadow: none;\n border-radius: 0;\n }\n .kf-data-table__toolbar {\n display: flex;\n justify-content: flex-end;\n padding: var(--kf-space-sm) var(--kf-space-md);\n border-bottom: 1px solid var(--kf-color-border);\n }\n .kf-data-table__view-toggle {\n display: inline-flex;\n gap: 2px;\n padding: 2px;\n background: var(--kf-color-surface);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n }\n .kf-data-table__view-option {\n font: inherit;\n font-size: 0.875em;\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border: none;\n background: transparent;\n color: var(--kf-color-text-muted);\n border-radius: var(--kf-radius-xs);\n cursor: pointer;\n transition:\n background 0.14s,\n color 0.14s;\n }\n .kf-data-table__view-option:hover:not(.kf-data-table__view-option--active) {\n color: var(--kf-color-text);\n }\n .kf-data-table__view-option--active {\n background: var(--kf-color-white);\n color: var(--kf-color-ink);\n box-shadow: var(--kf-shadow-xs);\n }\n .kf-data-table__view-option:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n\n .kf-data-table__scroll {\n overflow-x: auto;\n }\n .kf-data-table__table {\n width: 100%;\n border-collapse: collapse;\n text-align: left;\n }\n .kf-data-table__table th,\n .kf-data-table__table td {\n padding: var(--kf-space-sm) var(--kf-space-md);\n border-bottom: 1px solid var(--kf-color-border);\n white-space: nowrap;\n }\n .kf-data-table__table th {\n font-family: var(--kf-font-title);\n font-size: 0.8125em;\n text-transform: uppercase;\n letter-spacing: 0.02em;\n color: var(--kf-color-text-muted);\n background: var(--kf-color-surface);\n }\n .kf-data-table__table td {\n color: var(--kf-color-text);\n }\n .kf-data-table__table tbody tr:last-child td {\n border-bottom: none;\n }\n .kf-data-table__row {\n cursor: pointer;\n transition: background 0.14s;\n }\n .kf-data-table__row:hover {\n background: var(--kf-color-primary-soft);\n }\n .kf-data-table__cell--right {\n text-align: right;\n }\n\n .kf-data-table__empty {\n padding: var(--kf-space-md);\n }\n\n .kf-data-table__footer {\n padding: var(--kf-space-sm) var(--kf-space-md);\n border-top: 1px solid var(--kf-color-border);\n }\n .kf-data-table__footer:empty {\n display: none;\n }\n\n .kf-data-table__cards {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));\n gap: var(--kf-space-md);\n padding: var(--kf-space-md);\n }\n .kf-data-table__card {\n display: flex;\n flex-direction: column;\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n overflow: hidden;\n transition:\n border-color 0.14s,\n box-shadow 0.14s;\n }\n .kf-data-table__card--interactive {\n cursor: pointer;\n }\n .kf-data-table__card:hover {\n border-color: var(--kf-color-border-strong);\n box-shadow: var(--kf-shadow-xs);\n }\n .kf-data-table__card--interactive:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n\n .kf-data-table__card-header {\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-md);\n }\n .kf-data-table__card-media {\n flex: none;\n }\n .kf-data-table__card-media img,\n .kf-data-table__thumb {\n display: block;\n width: 48px;\n height: 48px;\n border-radius: var(--kf-radius-xs);\n object-fit: cover;\n background: var(--kf-color-surface);\n }\n .kf-data-table__card-heading {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n min-width: 0;\n }\n .kf-data-table__card-title {\n font-family: var(--kf-font-title);\n font-weight: 600;\n color: var(--kf-color-ink);\n overflow-wrap: anywhere;\n }\n .kf-data-table__card-statuses,\n .kf-data-table__card-actions {\n display: flex;\n flex-wrap: wrap;\n gap: var(--kf-space-xs);\n }\n\n .kf-data-table__card-fields {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-md);\n }\n /* El encabezado ya aportó el padding de arriba. */\n .kf-data-table__card-header + .kf-data-table__card-fields {\n padding-top: 0;\n }\n .kf-data-table__card-field {\n display: flex;\n justify-content: space-between;\n gap: var(--kf-space-sm);\n }\n .kf-data-table__card-actions {\n justify-content: flex-end;\n margin-top: auto;\n padding: var(--kf-space-sm) var(--kf-space-md);\n border-top: 1px solid var(--kf-color-border);\n background: var(--kf-color-surface);\n }\n\n .kf-data-table__thumb {\n width: 32px;\n height: 32px;\n }\n .kf-data-table__card-label {\n font-family: var(--kf-font-title);\n font-size: 0.8125em;\n text-transform: uppercase;\n letter-spacing: 0.02em;\n color: var(--kf-color-text-muted);\n }\n .kf-data-table__card-value {\n color: var(--kf-color-text);\n text-align: right;\n }\n `,\n})\nexport class DataTable<T = unknown> {\n readonly columns = input.required<DataTableColumn[]>();\n readonly rows = input.required<T[]>();\n /** Default: índice de la fila dentro de `rows`. */\n readonly rowKey = input<(row: T, index: number) => string | number>();\n /** Sin borde/sombra de card — para tablas anidadas dentro de otra card. */\n readonly flush = input(false);\n /** Habilita el toggle de vista tabla/cards. */\n readonly cardable = input(false);\n readonly defaultView = input<DataTableView>('table');\n /**\n * Formateo simple de celda como texto: `(row) => string`. Para marcado\n * real (badges, links, botones) usar `cellTemplates`.\n */\n readonly render = input<(row: T) => string>();\n /** Mapa `columnKey -> TemplateRef` para celdas con contenido custom. */\n readonly cellTemplates = input<\n Record<string, TemplateRef<{ $implicit: T; index: number }>> | undefined\n >();\n\n readonly rowClick = output<{ row: T; index: number }>();\n\n private readonly internalView = signal<DataTableView | null>(null);\n\n /** Vista activa: la elegida por el usuario, o `defaultView` si no tocó el toggle. */\n readonly view = computed<DataTableView>(() => this.internalView() ?? this.defaultView());\n\n /** Primera columna de cada rol único; el resto se ignora en el encabezado. */\n readonly cardMediaColumn = computed(() => this.columns().find((c) => c.cardRole === 'media'));\n readonly cardTitleColumn = computed(() => this.columns().find((c) => c.cardRole === 'title'));\n readonly cardStatusColumns = computed(() =>\n this.columns().filter((c) => c.cardRole === 'status'),\n );\n readonly cardActionColumns = computed(() =>\n this.columns().filter((c) => c.cardRole === 'action'),\n );\n readonly cardFieldColumns = computed(() =>\n this.columns().filter((c) => !c.cardRole || c.cardRole === 'field'),\n );\n\n /**\n * La card entera es clickeable solo si no tiene acciones propias: un\n * `role=\"button\"` con botones adentro es inválido y deja el foco ambiguo.\n * Con columnas `action`, la interacción la manejan esos botones.\n */\n readonly cardInteractive = computed(() => this.cardActionColumns().length === 0);\n\n setView(next: DataTableView): void {\n this.internalView.set(next);\n }\n\n trackRow(row: T, index: number): string | number {\n const keyFn = this.rowKey();\n return keyFn ? keyFn(row, index) : index;\n }\n\n cellValue(row: T, column: DataTableColumn): string {\n const renderFn = this.render();\n if (renderFn) {\n return renderFn(row);\n }\n const value = (row as Record<string, unknown>)[column.key];\n return value === null || value === undefined ? '' : String(value);\n }\n\n onRowClick(row: T, index: number): void {\n this.rowClick.emit({ row, index });\n }\n}\n","import { Overlay, type OverlayRef } from '@angular/cdk/overlay';\nimport { TemplatePortal } from '@angular/cdk/portal';\nimport {\n Component,\n DestroyRef,\n ElementRef,\n HostListener,\n TemplateRef,\n ViewContainerRef,\n contentChild,\n effect,\n inject,\n input,\n model,\n viewChild,\n} from '@angular/core';\n\nexport type DropdownItemTone = 'neutral' | 'error';\n\n/**\n * Ítem de acción dentro de un `kf-dropdown-panel`. Es un `<button>` nativo\n * por dentro (no un `<a>`): las acciones de un menú de este tipo disparan\n * comportamiento en la pantalla actual (cerrar sesión, ejecutar un\n * comando), no navegan a otra URL.\n *\n * <kf-dropdown-item (click)=\"onLogout()\" tone=\"error\">Cerrar sesión</kf-dropdown-item>\n */\n@Component({\n selector: 'kf-dropdown-item',\n template: `\n <button\n type=\"button\"\n class=\"kf-dropdown-item\"\n [class.kf-dropdown-item--error]=\"tone() === 'error'\"\n role=\"menuitem\"\n >\n <ng-content />\n </button>\n `,\n styles: `\n :host {\n display: block;\n }\n .kf-dropdown-item {\n display: block;\n width: 100%;\n padding: var(--kf-space-sm) var(--kf-space-md);\n border: none;\n background: transparent;\n font: inherit;\n text-align: left;\n color: var(--kf-color-text);\n cursor: pointer;\n }\n .kf-dropdown-item:hover {\n background: var(--kf-color-surface);\n }\n .kf-dropdown-item:focus-visible {\n outline: none;\n box-shadow: inset var(--kf-shadow-focus);\n }\n .kf-dropdown-item--error {\n color: var(--kf-color-error-strong);\n }\n .kf-dropdown-item--error:hover {\n background: var(--kf-color-error-soft);\n }\n `,\n})\nexport class DropdownItem {\n readonly tone = input<DropdownItemTone>('neutral');\n}\n\n/**\n * Contenido del panel flotante de un `kf-dropdown`. Es solo una plantilla\n * (`<ng-template>` por dentro, capturada vía `TemplateRef`) — `Dropdown` la\n * conecta al overlay real cuando `open` pasa a `true`, no la renderiza en su\n * propio lugar del DOM. Esto es lo que permite que el panel aparezca pegado\n * al host de `Dropdown` sin importar dónde esté ese host en la página.\n *\n * <kf-dropdown [(open)]=\"menuOpen\">\n * <kf-dropdown-panel>\n * <kf-dropdown-item (click)=\"onLogout()\">Cerrar sesión</kf-dropdown-item>\n * </kf-dropdown-panel>\n * </kf-dropdown>\n */\n@Component({\n selector: 'kf-dropdown-panel',\n template: `\n <ng-template>\n <div class=\"kf-dropdown-panel\">\n <div class=\"kf-dropdown-panel__inner\" role=\"menu\">\n <ng-content />\n </div>\n </div>\n </ng-template>\n `,\n styles: `\n /*\n * Dos capas a propósito: \\`overflow: hidden\\` y \\`box-shadow\\` en el MISMO\n * elemento hacen que el navegador recorte la propia sombra en las\n * esquinas donde el \\`border-radius\\` curva hacia adentro (se veía como\n * un borde/sombra \"cortada\" en una esquina). El borde/radio/sombra viven\n * en \\`.kf-dropdown-panel\\` (sin overflow), el recorte de contenido\n * (necesario para que el hover de los items no se salga de las esquinas\n * redondeadas) vive en \\`.kf-dropdown-panel__inner\\`.\n */\n .kf-dropdown-panel {\n min-width: 220px;\n max-width: 100%;\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n box-shadow: var(--kf-shadow-lg);\n font-family: var(--kf-font-body);\n animation: kf-dropdown-panel-enter 0.14s ease-out;\n }\n .kf-dropdown-panel__inner {\n padding: var(--kf-space-xs) 0;\n overflow: hidden;\n border-radius: inherit;\n }\n @media (prefers-reduced-motion: reduce) {\n .kf-dropdown-panel {\n animation: none;\n }\n }\n @keyframes kf-dropdown-panel-enter {\n from {\n opacity: 0;\n transform: translateY(-4px) scale(0.98);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n }\n `,\n})\nexport class DropdownPanel {\n readonly templateRef = viewChild.required(TemplateRef);\n}\n\n/**\n * Menú de acciones flotante, conectado a un elemento disparador vía\n * `@angular/cdk/overlay` — la misma pieza que usa Angular Material para\n * `mat-menu`/`mat-select`. Resuelve el patrón que antes se reimplementaba a\n * mano en cada consumidor (ver el session-menu de `web-portal-latam-frontend`,\n * ~80 líneas de HTML/TS/SCSS para toggle + click-afuera + Escape + animación\n * de entrada, acopladas a una clase interna no pública de `PortalHeader`).\n *\n * Se apoya en el CDK en vez de un `position: absolute` casero (como sí hace\n * `SelectMenu`, que puede permitírselo porque su trigger vive siempre dentro\n * del propio componente) porque acá el disparador real puede vivir en OTRO\n * componente por completo — ej. el avatar dentro de `kf-portal-header` — y\n * el panel tiene que aparecer pegado a ESE elemento sin importar dónde el\n * consumidor ubique al `Dropdown` en su HTML. El Overlay CDK calcula esa\n * posición (con fallback si no entra en pantalla) en vez de que cada\n * consumidor lo recalcule a mano.\n *\n * `open` es two-way, igual que `Alert`/`Modal`: el consumidor decide qué\n * dispara la apertura (puede ser un `(click)` en un botón propio, o un\n * evento de otro componente como `PortalHeader.sessionClick`) — `Dropdown`\n * en sí no renderiza ningún trigger, su propio host es el punto de anclaje\n * visual del panel.\n *\n * <kf-dropdown [(open)]=\"menuOpen\">\n * <kf-dropdown-panel>\n * <div class=\"mi-header\">Sesión iniciada como {{ email() }}</div>\n * <kf-dropdown-item (click)=\"onLogout()\" tone=\"error\">Cerrar sesión</kf-dropdown-item>\n * </kf-dropdown-panel>\n * </kf-dropdown>\n */\n@Component({\n selector: 'kf-dropdown',\n template: `<ng-content />`,\n styles: `\n :host {\n display: inline-block;\n }\n `,\n})\nexport class Dropdown {\n /** Visibilidad del panel, two-way: `[(open)]=\"menuOpen\"`. */\n readonly open = model(false);\n\n /**\n * Elemento al que se conecta el overlay, si es distinto del propio host\n * de `Dropdown`. Sin esto, `Dropdown` asume que ÉL MISMO es visualmente\n * el disparador (caso normal: el consumidor arma su propio botón como\n * contenido, y `Dropdown` envuelve ese contenido). Cuando el disparador\n * real vive dentro de OTRO componente que no se puede envolver sin\n * ensanchar el área de click a algo más grande que el botón (ej. el\n * avatar de sesión dentro de `PortalHeader`, que convive con logo y\n * navegación en el mismo host), `anchor` permite apuntar el overlay a la\n * referencia real de ese componente en vez de al host vacío de\n * `Dropdown`.\n *\n * <kf-dropdown [(open)]=\"menuOpen\" [anchor]=\"headerRef()\">\n */\n readonly anchor = input<ElementRef<HTMLElement>>();\n\n private readonly panel = contentChild(DropdownPanel);\n\n private readonly overlayService = inject(Overlay);\n private readonly host = inject(ElementRef<HTMLElement>);\n private readonly viewContainerRef = inject(ViewContainerRef);\n private readonly destroyRef = inject(DestroyRef);\n\n private overlayRef: OverlayRef | null = null;\n\n constructor() {\n effect(() => {\n if (this.open()) {\n this.attach();\n } else {\n this.detach();\n }\n });\n\n this.destroyRef.onDestroy(() => this.overlayRef?.dispose());\n }\n\n /**\n * Respaldo de `overlayRef.keydownEvents()`: ese observable del CDK solo\n * ve teclas presionadas con el foco DENTRO del pane del overlay. Si el\n * usuario abre el menú y presiona Escape con el foco en otro lado de la\n * página (caso común — el foco puede seguir en el botón disparador, que\n * vive fuera del overlay), `keydownEvents()` nunca dispara. Este listener\n * a nivel de documento cubre ese caso; el de `keydownEvents()` sigue\n * activo para cuando el foco sí está dentro del panel.\n */\n @HostListener('document:keydown.escape')\n onDocumentEscape(): void {\n this.open.set(false);\n }\n\n private attach(): void {\n const panel = this.panel();\n if (!panel || this.overlayRef?.hasAttached()) {\n return;\n }\n\n const overlayRef = this.getOrCreateOverlayRef();\n const portal = new TemplatePortal(panel.templateRef(), this.viewContainerRef);\n overlayRef.attach(portal);\n\n overlayRef.outsidePointerEvents().subscribe(() => this.open.set(false));\n overlayRef.keydownEvents().subscribe((event) => {\n if (event.key === 'Escape') {\n this.open.set(false);\n }\n });\n }\n\n private detach(): void {\n this.overlayRef?.detach();\n }\n\n private getOrCreateOverlayRef(): OverlayRef {\n if (this.overlayRef) {\n return this.overlayRef;\n }\n\n const positionStrategy = this.overlayService\n .position()\n .flexibleConnectedTo(this.anchor() ?? this.host)\n // 4 posiciones, no 2: además de abajo/arriba (alineado al borde\n // derecho del anchor, el caso común), agrega el mismo par alineado al\n // borde IZQUIERDO. Con solo el par \"end\" — como estaba antes — un\n // trigger cerca del borde derecho de la pantalla no tenía ningún\n // fallback horizontal: el panel se salía del viewport en vez de\n // reacomodarse hacia la izquierda. El CDK prueba cada posición en\n // orden y usa la primera que entra completa en el viewport.\n .withPositions([\n { originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top', offsetY: 4 },\n { originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', offsetY: -4 },\n { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 4 },\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -4 },\n ])\n // Margen de seguridad contra los bordes del viewport — sin esto, el\n // CDK puede considerar una posición \"válida\" aunque quede pegada al\n // borde con 0px de aire.\n .withViewportMargin(8)\n // Si ninguna de las 4 posiciones entra completa (viewport muy\n // angosto), la última se ajusta con push en vez de desbordarse fuera\n // de pantalla sin control.\n .withPush(true);\n\n this.overlayRef = this.overlayService.create({\n positionStrategy,\n scrollStrategy: this.overlayService.scrollStrategies.reposition(),\n // Sin esto, el panel puede quedar más angosto que su propio\n // `min-width` en pantallas chicas si el CDK decide recortar — fija un\n // techo razonable en vez de dejarlo crecer sin límite ni encogerse\n // por debajo de lo legible.\n maxWidth: '90vw',\n });\n\n return this.overlayRef;\n }\n}\n","import { Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Bloque promocional sobre fondo oscuro de marca (página 37) — campañas,\n * accesos directos o el portal de autoatención. Usa `--kf-color-tertiary-deep`\n * como base del degradado, el mismo azul profundo que el slide destacado de\n * `kf-carousel` y la barra de `kf-portal-header`.\n *\n * <kf-feature-card badge=\"Autoatención\" badgeIcon=\"tool\" title=\"Portal de Autoatención\"\n * description=\"Con tu patente o VIN accede a soluciones para tu vehículo: mantenciones, repuestos y conectividad en un solo lugar.\"\n * actionLabel=\"Ir al portal\" actionHref=\"/autoatencion\" />\n */\n@Component({\n selector: 'kf-feature-card',\n imports: [Icon],\n template: `\n @if (badge()) {\n <span class=\"kf-feature-card__badge\">\n @if (badgeIcon(); as iconName) {\n <kf-icon [name]=\"iconName\" size=\"sm\" />\n }\n {{ badge() }}\n </span>\n }\n <span class=\"kf-feature-card__title\">{{ title() }}</span>\n @if (description()) {\n <p class=\"kf-feature-card__description\">{{ description() }}</p>\n }\n @if (actionLabel()) {\n <a class=\"kf-feature-card__action\" [href]=\"actionHref() || '#'\">\n <kf-icon name=\"chevron-right\" size=\"sm\" />\n {{ actionLabel() }}\n </a>\n }\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-lg);\n border-radius: var(--kf-radius-md);\n background: linear-gradient(\n 135deg,\n var(--kf-color-primary-active) 0%,\n var(--kf-color-tertiary-deep) 100%\n );\n color: var(--kf-color-white);\n font-family: var(--kf-font-body);\n }\n .kf-feature-card__badge {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border-radius: var(--kf-radius-pill);\n background: rgba(255, 255, 255, 0.12);\n border: 1px solid rgba(255, 255, 255, 0.24);\n font-size: 0.72rem;\n font-weight: 700;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n }\n .kf-feature-card__title {\n font-family: var(--kf-font-title);\n font-size: 1.375rem;\n font-weight: 700;\n line-height: 1.2;\n }\n .kf-feature-card__description {\n margin: 0;\n max-width: 48ch;\n color: rgba(255, 255, 255, 0.8);\n font-size: 0.9375rem;\n }\n .kf-feature-card__action {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n margin-top: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-md);\n border-radius: var(--kf-radius-sm);\n background: rgba(255, 255, 255, 0.14);\n color: var(--kf-color-white);\n font-size: 0.875rem;\n font-weight: 600;\n text-decoration: none;\n transition: background 0.14s;\n }\n .kf-feature-card__action:hover {\n background: rgba(255, 255, 255, 0.22);\n }\n `,\n})\nexport class FeatureCard {\n readonly badge = input<string>();\n readonly badgeIcon = input<IconName>();\n readonly title = input.required<string>();\n readonly description = input<string>();\n readonly actionLabel = input<string>();\n readonly actionHref = input<string>();\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Chip de solo-lectura inline (label/valor) dentro de una caja bordeada.\n * Se usa en barras de filtro y filas de resumen para mostrar información,\n * NO para entrada de datos — para eso existe `Input`.\n *\n * El valor admite dos formas, igual que en el design system de referencia:\n * - `value` (string): caso simple, ej. `[value]=\"'Jul 2026'\"`.\n * - contenido proyectado (`<ng-content>`): cuando se necesita algo más rico\n * que un string (un badge, texto con formato, etc.).\n * `value` tiene prioridad cuando está definido; si no se pasa `value`, se\n * renderiza el contenido proyectado y, si tampoco hay contenido, `placeholder`.\n *\n * <kf-field icon=\"calendar\" label=\"Periodo\" value=\"Jul 2026\" [select]=\"true\" />\n * <kf-field label=\"Sucursal\"><strong>Casa Central</strong></kf-field>\n */\n@Component({\n selector: 'kf-field',\n imports: [Icon],\n template: `\n @if (icon(); as iconName) {\n <kf-icon class=\"kf-field__icon\" [name]=\"iconName\" size=\"sm\" />\n }\n @if (label()) {\n <span class=\"kf-field__label\">{{ label() }}</span>\n }\n <span class=\"kf-field__value\">\n @if (value()) {\n {{ value() }}\n } @else {\n <ng-content></ng-content>\n @if (isPlaceholderVisible()) {\n <span class=\"kf-field__placeholder\">{{ placeholder() }}</span>\n }\n }\n </span>\n @if (select()) {\n <kf-icon class=\"kf-field__chevron\" name=\"chevron-down\" size=\"sm\" />\n }\n `,\n styles: `\n :host {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-surface);\n font: inherit;\n font-family: var(--kf-font-body);\n color: var(--kf-color-text);\n line-height: 1.2;\n }\n :host(.kf-field--select) {\n cursor: pointer;\n }\n :host(.kf-field--select:hover) {\n border-color: var(--kf-color-border-strong);\n }\n .kf-field__icon {\n color: var(--kf-color-text-muted);\n }\n .kf-field__label {\n color: var(--kf-color-text-muted);\n white-space: nowrap;\n }\n .kf-field__value {\n font-weight: 500;\n color: var(--kf-color-ink);\n white-space: nowrap;\n }\n .kf-field__placeholder {\n color: var(--kf-color-text-muted);\n font-weight: 400;\n }\n .kf-field__chevron {\n color: var(--kf-color-text-muted);\n }\n `,\n host: {\n '[class.kf-field--select]': 'select()',\n '[attr.style]': 'style() || null',\n },\n})\nexport class Field {\n readonly label = input<string>();\n readonly value = input<string>();\n readonly icon = input<IconName>();\n readonly placeholder = input<string>();\n readonly select = input(false, { transform: booleanAttribute });\n /** Estilos inline opcionales aplicados directamente al host. */\n readonly style = input<string>();\n\n /**\n * El placeholder solo tiene sentido cuando no hay `value` ni contenido\n * proyectado. Angular no expone de forma simple si `<ng-content>` recibió\n * hijos reales, así que la regla adoptada es puramente declarativa: se\n * muestra el placeholder cuando hay texto de placeholder y no hay `value`\n * (ver comentario de clase sobre la prioridad value > proyectado > placeholder).\n */\n protected isPlaceholderVisible(): boolean {\n return !this.value() && !!this.placeholder();\n }\n}\n","import { Component, computed, input, output } from '@angular/core';\n\n/** Forma normalizada interna de cada opción, ya resuelta a value/label. */\ninterface FilterChipOption {\n value: string;\n label: string;\n}\n\n/**\n * Fila de chips tipo \"pill\" para filtros de una sola selección.\n *\n * Cada opción puede pasarse como string simple (se usa como value y label\n * a la vez) o como objeto { value, label } cuando el texto mostrado difiere\n * del valor interno.\n *\n * El chip activo se resalta con el color \"ink\" oscuro (--kf-color-ink), no\n * con el color primario de marca: así lo define el sistema de diseño de\n * referencia para este componente en particular.\n *\n * <kf-filter-chips [options]=\"['Todos', 'Activos', 'Archivados']\"\n * [value]=\"filtro\"\n * (valueChange)=\"filtro = $event\" />\n *\n * <kf-filter-chips [options]=\"[{ value: 'all', label: 'Todos' }]\"\n * [value]=\"filtro\"\n * (valueChange)=\"filtro = $event\" />\n */\n@Component({\n selector: 'kf-filter-chips',\n template: `\n <div class=\"kf-filter-chips\" role=\"group\">\n @for (option of normalizedOptions(); track option.value) {\n <button\n type=\"button\"\n class=\"kf-filter-chips__chip\"\n [class.kf-filter-chips__chip--active]=\"option.value === value()\"\n [attr.aria-pressed]=\"option.value === value()\"\n (click)=\"select(option.value)\"\n >\n {{ option.label }}\n </button>\n }\n </div>\n `,\n styles: `\n :host {\n display: block;\n }\n .kf-filter-chips {\n display: flex;\n flex-wrap: wrap;\n gap: var(--kf-space-xs);\n }\n .kf-filter-chips__chip {\n font: inherit;\n padding: var(--kf-space-xs) var(--kf-space-md);\n border-radius: var(--kf-radius-pill);\n border: 1px solid var(--kf-color-border);\n background: var(--kf-color-surface);\n color: var(--kf-color-text);\n cursor: pointer;\n transition:\n background 0.14s,\n border-color 0.14s,\n color 0.14s;\n }\n .kf-filter-chips__chip:hover:not(.kf-filter-chips__chip--active) {\n border-color: var(--kf-color-border-strong);\n }\n .kf-filter-chips__chip:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-filter-chips__chip--active {\n background: var(--kf-color-ink);\n border-color: var(--kf-color-ink);\n color: var(--kf-color-white);\n }\n `,\n})\nexport class FilterChips {\n readonly options = input.required<(string | { value: string; label: string })[]>();\n readonly value = input<string>('');\n\n readonly valueChange = output<string>();\n\n /** Normaliza cada opción string/objeto a la forma { value, label }. */\n readonly normalizedOptions = computed<FilterChipOption[]>(() =>\n this.options().map((option) =>\n typeof option === 'string' ? { value: option, label: option } : option,\n ),\n );\n\n select(value: string): void {\n if (value === this.value()) {\n return;\n }\n this.valueChange.emit(value);\n }\n}\n","import { Component, Directive, computed, contentChild, input, output } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\nexport interface FolderTabOption {\n value: string;\n label: string;\n icon?: IconName;\n}\n\n/**\n * Marca el contenido que `kf-folder-tabs` debe proyectar dentro de su\n * panel. Sin lógica propia — existe solo como token de tipo para que\n * `contentChild(FolderTabsPanel)` pueda detectar si el consumidor proyectó\n * algo (mismo mecanismo que `kf-dropdown` usa con `contentChild(DropdownPanel)`;\n * acá no hace falta un componente completo, alcanza con una directiva de\n * atributo porque el panel no necesita comportamiento propio, solo marcar\n * su presencia).\n *\n * <div kf-folder-tabs-panel>...</div>\n */\n@Directive({ selector: '[kf-folder-tabs-panel]' })\nexport class FolderTabsPanel {}\n\n/**\n * Tabs con forma de \"carpeta\": el borde superior queda redondeado y el borde\n * inferior de la pestaña activa se funde visualmente con el panel de\n * contenido que va debajo (misma superficie, sin línea divisoria).\n *\n * Al cambiar de pestaña, la que se activa se \"abre\": gira sobre su borde\n * inferior (hinge 3D) y sube con un pequeño rebote. Es CSS solo: la clase\n * `--active` se mueve de un botón a otro, y eso vuelve a disparar el keyframe\n * sin tocar JS.\n *\n * El panel de contenido es un `<ng-content>` OPCIONAL — si el consumidor no\n * proyecta nada, `kf-folder-tabs` renderiza solo la fila de pestañas (mismo\n * comportamiento que antes de que existiera este slot, detectado con\n * `contentChild()` sin `.required`, igual patrón que usa `kf-dropdown` para\n * saber si hay un `kf-dropdown-panel` proyectado). Si SÍ proyecta contenido,\n * se envuelve en un panel con la esquina superior-izquierda recta (nace ahí\n * la primera pestaña, siempre pegada al borde izquierdo de la fila — un\n * radio ahí competiría visualmente con el propio borde redondeado de esa\n * pestaña) y las otras tres redondeadas. El `border-bottom` de 2px de la\n * pestaña activa (ver `.kf-folder-tabs__tab--active` más abajo) es la señal\n * visual de conexión con el panel para CUALQUIER pestaña activa, sin\n * necesitar mover ni medir nada.\n *\n * El borde izquierdo de toda la fila (y por lo tanto de la esquina recta\n * del panel) depende de que ninguna pestaña se corra al cambiar de estado\n * — ver `transform-origin: bottom left` en `.kf-folder-tabs__tab`: con el\n * origen centrado (como estaba antes), el `scale()` de la pestaña inactiva\n * encogía el borde izquierdo unos px, y ese corrimiento sub-pixel es lo que\n * hacía que este mismo diseño (esquina fija) se viera \"roto\" cuando la\n * pestaña activa no era la primera. Con el origen anclado a la izquierda,\n * el corrimiento desaparece y la esquina fija vuelve a ser una solución\n * válida y simple — sin necesitar medir la pestaña activa por JS.\n *\n * Antes de este slot, el patrón era que el consumidor pusiera su propia\n * card como HERMANO de `kf-folder-tabs` y anulara a mano el radio superior\n * completo (`border-top-left-radius: 0`, `border-top-right-radius: 0` — ver\n * el caso original de `web-portal-latam-frontend`). Encapsular esto acá\n * evita que cada consumidor repita esas reglas a mano.\n *\n * <kf-folder-tabs [options]=\"tabs\" [value]=\"active\" (valueChange)=\"active = $event\">\n * <div kf-folder-tabs-panel>contenido de la pestaña activa</div>\n * </kf-folder-tabs>\n *\n * <!-- o, sin contenido, como antes: -->\n * <kf-folder-tabs [options]=\"tabs\" [value]=\"active\" (valueChange)=\"active = $event\" />\n */\n@Component({\n selector: 'kf-folder-tabs',\n imports: [Icon],\n template: `\n <div class=\"kf-folder-tabs\" role=\"tablist\">\n @for (option of options(); track option.value) {\n <button\n type=\"button\"\n role=\"tab\"\n class=\"kf-folder-tabs__tab\"\n [class.kf-folder-tabs__tab--active]=\"option.value === value()\"\n [attr.aria-selected]=\"option.value === value()\"\n [attr.tabindex]=\"option.value === value() ? 0 : -1\"\n [id]=\"'kf-folder-tab-' + option.value\"\n [attr.aria-controls]=\"'kf-folder-panel-' + option.value\"\n (click)=\"select(option.value)\"\n (keydown)=\"onKeydown($event, option.value)\"\n >\n @if (option.icon; as iconName) {\n <kf-icon class=\"kf-folder-tabs__icon\" [name]=\"iconName\" size=\"sm\" />\n }\n <span class=\"kf-folder-tabs__label\">{{ option.label }}</span>\n </button>\n }\n </div>\n\n <div class=\"kf-folder-tabs__panel\" [class.kf-folder-tabs__panel--empty]=\"!hasPanel()\">\n <ng-content select=\"[kf-folder-tabs-panel]\" />\n </div>\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-folder-tabs {\n display: flex;\n align-items: flex-end;\n gap: var(--kf-space-xs);\n /* Da profundidad al hinge: las pestañas giran sobre su borde inferior. */\n perspective: 900px;\n }\n .kf-folder-tabs__tab {\n position: relative;\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n font: inherit;\n font-size: 0.9rem;\n color: var(--kf-color-text-muted);\n background: var(--kf-color-surface);\n border: 1px solid var(--kf-color-border);\n border-bottom-color: var(--kf-color-border-strong);\n border-radius: var(--kf-radius-sm) var(--kf-radius-sm) 0 0;\n padding: var(--kf-space-sm) var(--kf-space-md);\n cursor: pointer;\n /* bottom left, no bottom center: con el origen centrado, el\n scale() de abajo encoge/agranda la pestaña desde su centro\n horizontal — el borde IZQUIERDO se corre unos px cada vez que\n una pestaña cambia de activa a inactiva (o viceversa), lo que\n desalinea la fila entera contra el panel de abajo (se percibe\n como si la tab \"se rompiera\"). Con el origen a la izquierda, el\n crecimiento/encogimiento siempre pasa hacia la derecha: el borde\n izquierdo de cada pestaña — y por lo tanto el de toda la fila —\n nunca se mueve. */\n transform-origin: bottom left;\n /* Inactiva: hundida en la pila, un pelo más chica. */\n transform: translateY(5px) scale(0.985);\n transition:\n background 0.14s,\n color 0.14s,\n border-color 0.14s,\n transform 0.22s cubic-bezier(0.32, 0.72, 0, 1);\n }\n .kf-folder-tabs__tab:hover:not(.kf-folder-tabs__tab--active) {\n color: var(--kf-color-text);\n background: var(--kf-color-white);\n transform: translateY(2px) scale(0.99);\n }\n .kf-folder-tabs__tab:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n z-index: 1;\n }\n .kf-folder-tabs__tab--active {\n z-index: 1;\n color: var(--kf-color-primary);\n font-weight: 700;\n background: var(--kf-color-white);\n border-color: var(--kf-color-border);\n /* Marca el color del tema abajo (página 19 del design system) — no se\n funde con el panel: el borde queda visible y grueso, mismo trato\n que el subrayado de kf-tabs. */\n border-bottom: 2px solid var(--kf-color-primary);\n /* Sombra hacia arriba: la pestaña quedó por delante del resto. */\n box-shadow: 0 -6px 14px -10px rgba(16, 24, 40, 0.4);\n transform: translateY(1px);\n animation: kf-folder-tabs-pull 0.34s cubic-bezier(0.22, 1.2, 0.36, 1) both;\n }\n @keyframes kf-folder-tabs-pull {\n /*\n * Rotación y rebote reducidos a propósito: la versión original\n * (rotateX(-24deg), overshoot a scale(1.02)) se sentía excesiva en\n * un patrón de uso frecuente como cambiar de tab — la gente lo hace\n * seguido y rápido, así que un exceso de movimiento cansa más que\n * \"da personalidad\". Se mantiene el espíritu de \"carpeta que se\n * abre\" (rotateX + lift), con menos intensidad.\n */\n 0% {\n transform: translateY(7px) rotateX(-10deg) scale(0.97);\n }\n /*\n * El rebote (overshoot) se resuelve DENTRO del rango final, no por\n * encima: antes este paso intermedio llegaba a translateY(-2px) —\n * más arriba que la posición de reposo (translateY(1px)) — y esos\n * 3px de más dejaban un hueco visible contra el panel de abajo (que\n * no se mueve) durante la fracción de segundo del rebote. Ahora el\n * mínimo del rebote es translateY(1px), igual que el reposo: la\n * pestaña nunca sube más allá de donde termina.\n */\n 60% {\n transform: translateY(1px) rotateX(2deg) scale(1.01);\n }\n 100% {\n transform: translateY(1px) rotateX(0) scale(1);\n }\n }\n @media (prefers-reduced-motion: reduce) {\n .kf-folder-tabs__tab,\n .kf-folder-tabs__tab--active {\n animation: none;\n transition:\n background 0.14s,\n color 0.14s,\n border-color 0.14s;\n }\n }\n\n /*\n * Panel opcional (kf-folder-tabs-panel proyectado). Vacío cuando el\n * consumidor no proyecta nada — display: contents para que no ocupe\n * espacio ni imponga su propio box en ese caso, dejando a\n * kf-folder-tabs comportarse exactamente como antes de este slot\n * (solo la fila de pestañas).\n */\n .kf-folder-tabs__panel--empty {\n display: contents;\n }\n .kf-folder-tabs__panel:not(.kf-folder-tabs__panel--empty) {\n background: var(--kf-color-white);\n /*\n * Bordes declarados por lado (en vez de la shorthand border) — dos\n * shorthands consecutivos que tocan la misma propiedad terminaban\n * pisándose mal al compilarse (el border quedaba vacío en el CSS\n * final). Declarar cada lado explícito evita el conflicto.\n */\n border-right: 1px solid var(--kf-color-border);\n border-bottom: 1px solid var(--kf-color-border);\n border-left: 1px solid var(--kf-color-border);\n border-top: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n /*\n * Solo la esquina superior-izquierda queda recta: es donde nace la\n * primera pestaña, y un radio ahí competiría visualmente con el\n * propio borde redondeado de esa pestaña. Va DESPUÉS del shorthand\n * de arriba a propósito — el shorthand fija las 4 esquinas, y esta\n * declaración más específica pisa solo la superior-izquierda.\n */\n border-top-left-radius: 0;\n /* Sin box-shadow a propósito: el borde de 1px solo es el mismo que\n usa cualquier kf-card sin sombra propia — consistente con el\n resto de la librería. */\n /* El contenido proyectado (ej. una kf-card rectangular, sin su\n propio border-radius) se desbordaba por encima de las esquinas\n redondeadas del panel — mismo motivo por el que Card usa\n overflow: hidden en su propio :host. */\n overflow: hidden;\n }\n `,\n})\nexport class FolderTabs {\n readonly options = input.required<FolderTabOption[]>();\n readonly value = input.required<string>();\n readonly valueChange = output<string>();\n\n /**\n * Detecta si el consumidor proyectó contenido marcado con\n * `kf-folder-tabs-panel` — sin `.required`, así que es `undefined`\n * cuando no hay nada proyectado (mismo patrón que usa `kf-dropdown` con\n * `contentChild(DropdownPanel)` para saber si hay un panel que\n * attachear). `hasPanel()` decide si el wrapper del panel participa del\n * layout (`display: contents` si no).\n */\n private readonly projectedPanel = contentChild(FolderTabsPanel);\n protected readonly hasPanel = computed(() => this.projectedPanel() !== undefined);\n\n select(value: string): void {\n if (value === this.value()) {\n return;\n }\n this.valueChange.emit(value);\n }\n\n /** Navegación estándar de ARIA tabs: flechas mueven el foco y activan la pestaña. */\n onKeydown(event: KeyboardEvent, currentValue: string): void {\n const items = this.options();\n const currentIndex = items.findIndex((option) => option.value === currentValue);\n\n let nextIndex: number;\n switch (event.key) {\n case 'ArrowRight':\n nextIndex = (currentIndex + 1) % items.length;\n break;\n case 'ArrowLeft':\n nextIndex = (currentIndex - 1 + items.length) % items.length;\n break;\n case 'Home':\n nextIndex = 0;\n break;\n case 'End':\n nextIndex = items.length - 1;\n break;\n default:\n return;\n }\n\n event.preventDefault();\n const nextOption = items[nextIndex];\n this.select(nextOption.value);\n\n const host = (event.currentTarget as HTMLElement).parentElement;\n const nextId = `kf-folder-tab-${nextOption.value}`;\n const nextButton = Array.from(host?.querySelectorAll<HTMLButtonElement>('button') ?? []).find(\n (button) => button.id === nextId,\n );\n nextButton?.focus();\n }\n}\n","import {\n AfterViewInit,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n forwardRef,\n input,\n signal,\n viewChild,\n} from '@angular/core';\nimport { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { FieldLabel } from '../field-label/FieldLabel';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Input de formulario apilado: label arriba (en mayúsculas vía CSS), campo con\n * fondo gris que pasa a blanco con anillo de foco azul al enfocar.\n *\n * Implementa ControlValueAccessor, así que funciona con [(ngModel)] y con\n * Reactive Forms (formControl / formControlName), no es solo un wrapper visual.\n *\n * <kf-input label=\"Placa\" icon=\"car\" placeholder=\"ABC-123\" hint=\"Formato: 3 letras + 3 números\" />\n * <input kf-input formControlName=\"email\" type=\"email\" />\n *\n * `invalid` + `errorMessage` cubren el estado de error: con `invalid` el\n * borde pasa a rojo (`--kf-color-error`) y se setea `aria-invalid=\"true\"` en\n * el `<input>` nativo; `errorMessage` reemplaza el `hint` neutro por un\n * mensaje en rojo con `role=\"alert\"`, para que un lector de pantalla lo\n * anuncie apenas aparece (a diferencia de `hint`, que es solo informativo y\n * nunca interrumpe). Si se pasan ambos, `errorMessage` tiene prioridad\n * visual sobre `hint` — no tiene sentido mostrar los dos a la vez.\n *\n * <kf-input label=\"Correo\" formControlName=\"email\"\n * [invalid]=\"email.invalid && email.touched\"\n * [errorMessage]=\"email.touched && email.hasError('required') ? 'Ingresa tu correo.' : undefined\" />\n *\n * `toggleable` solo tiene efecto cuando `type=\"password\"`: agrega un botón\n * de ojo al final del campo que alterna la visibilidad del valor tipeado\n * (cambia el `type` real del `<input>` nativo entre `password` y `text`,\n * nunca expone el valor en el DOM de otra forma). El botón es `type=\"button\"`\n * — nunca dispara submit del form contenedor — y anuncia su acción con\n * `aria-label` dinámico y `aria-pressed`, ya que es un toggle, no un botón\n * de una sola acción.\n *\n * <kf-input type=\"password\" label=\"Contraseña\" toggleable formControlName=\"password\" />\n */\n@Component({\n selector: 'kf-input',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [FormsModule, FieldLabel, Icon],\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => Input),\n multi: true,\n },\n ],\n template: `\n @if (label()) {\n <kf-field-label [for]=\"inputId\" [required]=\"required()\">{{ label() }}</kf-field-label>\n }\n <div\n class=\"kf-input__field\"\n [class.kf-input__field--disabled]=\"isDisabled()\"\n [class.kf-input__field--focused]=\"focused()\"\n [class.kf-input__field--invalid]=\"invalid()\"\n >\n @if (icon(); as iconName) {\n <kf-icon class=\"kf-input__icon\" [name]=\"iconName\" size=\"sm\" />\n }\n <input\n #nativeInput\n [id]=\"inputId\"\n class=\"kf-input__control\"\n [type]=\"effectiveType()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-describedby]=\"errorMessage() ? errorId : hint() ? hintId : null\"\n [attr.aria-invalid]=\"invalid() ? true : null\"\n [value]=\"value()\"\n (input)=\"onInput(nativeInput.value)\"\n (blur)=\"onBlur()\"\n (focus)=\"focused.set(true)\"\n />\n @if (showPasswordToggle()) {\n <button\n type=\"button\"\n class=\"kf-input__toggle\"\n [attr.aria-label]=\"passwordVisible() ? 'Ocultar contraseña' : 'Mostrar contraseña'\"\n [attr.aria-pressed]=\"passwordVisible()\"\n (click)=\"onTogglePasswordVisibility()\"\n >\n <kf-icon [name]=\"passwordVisible() ? 'eye-off' : 'eye'\" size=\"sm\" />\n </button>\n } @else if (suffix()) {\n <span class=\"kf-input__suffix\">{{ suffix() }}</span>\n }\n </div>\n @if (errorMessage(); as message) {\n <span class=\"kf-input__error\" [id]=\"errorId\" role=\"alert\">{{ message }}</span>\n } @else if (hint()) {\n <span class=\"kf-input__hint\" [id]=\"hintId\">{{ hint() }}</span>\n }\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n font-family: var(--kf-font-body);\n }\n .kf-input__field {\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n padding: 0 var(--kf-space-sm);\n background: var(--kf-color-surface);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n transition:\n background 0.14s,\n border-color 0.14s,\n box-shadow 0.14s;\n }\n .kf-input__field--focused {\n background: var(--kf-color-white);\n border-color: var(--kf-color-primary);\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-input__field--invalid {\n border-color: var(--kf-color-error);\n }\n .kf-input__field--invalid.kf-input__field--focused {\n box-shadow: 0 0 0 3px rgba(235, 87, 87, 0.22);\n }\n .kf-input__field--disabled {\n opacity: 0.5;\n }\n .kf-input__icon {\n color: var(--kf-color-text-muted);\n }\n .kf-input__field--invalid .kf-input__icon {\n color: var(--kf-color-error);\n }\n .kf-input__control {\n flex: 1;\n min-width: 0;\n border: none;\n outline: none;\n background: transparent;\n font: inherit;\n color: var(--kf-color-text);\n padding: var(--kf-space-sm) 0;\n }\n .kf-input__control::placeholder {\n color: var(--kf-color-text-muted);\n }\n .kf-input__control:disabled {\n cursor: not-allowed;\n }\n .kf-input__suffix {\n flex: none;\n color: var(--kf-color-text-muted);\n font-size: 0.875rem;\n }\n .kf-input__toggle {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n padding: var(--kf-space-xs);\n margin: 0 calc(var(--kf-space-xs) * -1);\n color: var(--kf-color-text-muted);\n cursor: pointer;\n border-radius: var(--kf-radius-xs);\n transition: color 0.14s;\n }\n .kf-input__toggle:hover {\n color: var(--kf-color-text);\n }\n .kf-input__toggle:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-input__hint {\n font-size: 0.75rem;\n color: var(--kf-color-text-muted);\n }\n .kf-input__error {\n display: flex;\n align-items: center;\n gap: var(--kf-space-xs);\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--kf-color-error-strong);\n }\n `,\n})\nexport class Input implements ControlValueAccessor, AfterViewInit {\n private static nextId = 0;\n\n private readonly nativeInput = viewChild.required<ElementRef<HTMLInputElement>>('nativeInput');\n\n readonly label = input<string>();\n /** Marca el label con un asterisco visual — no aplica `required` al `<input>` nativo por sí solo. */\n readonly required = input(false, { transform: booleanAttribute });\n /** Ícono líder, renderizado vía `kf-icon`. */\n readonly icon = input<IconName>();\n readonly suffix = input<string>();\n readonly hint = input<string>();\n /** Borde y aria-invalid en rojo. Ver `errorMessage` para el mensaje asociado. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /** Mensaje de error con `role=\"alert\"` — reemplaza a `hint` mientras esté presente. */\n readonly errorMessage = input<string>();\n readonly disabled = input(false, { transform: booleanAttribute });\n readonly type = input<string>('text');\n readonly placeholder = input<string>('');\n /** Agrega el botón de mostrar/ocultar — sin efecto si `type` no es `\"password\"`. */\n readonly toggleable = input(false, { transform: booleanAttribute });\n\n protected readonly inputId = `kf-input-${Input.nextId++}`;\n protected readonly hintId = `${this.inputId}-hint`;\n protected readonly errorId = `${this.inputId}-error`;\n\n protected readonly value = signal('');\n protected readonly focused = signal(false);\n /** Deshabilitado por Reactive Forms (formControl.disable()). */\n private readonly disabledByForm = signal(false);\n /** Disabled real: por input() directo o por el FormControl asociado. */\n protected readonly isDisabled = computed(() => this.disabled() || this.disabledByForm());\n\n /** Estado interno del toggle — irrelevante si `showPasswordToggle()` es false. */\n protected readonly passwordVisible = signal(false);\n /** El botón solo tiene sentido si el campo realmente es de contraseña. */\n protected readonly showPasswordToggle = computed(\n () => this.toggleable() && this.type() === 'password',\n );\n /**\n * `type` real que recibe el `<input>` nativo: igual a `type()` salvo\n * cuando el toggle está activo y visible, donde pasa a `text` para\n * mostrar el valor en claro sin cambiar `type()` en sí (evita que un\n * consumidor que lee `type()` desde afuera vea un valor inconsistente).\n */\n protected readonly effectiveType = computed(() =>\n this.showPasswordToggle() && this.passwordVisible() ? 'text' : this.type(),\n );\n\n private onChange: (value: string) => void = () => {};\n private onTouched: () => void = () => {};\n\n ngAfterViewInit(): void {\n // El binding declarativo [value]=\"value()\" no siempre re-sincroniza la\n // propiedad DOM del <input> cuando el valor llega por writeValue() antes\n // de que la vista termine de inicializarse — se refuerza escribiendo la\n // propiedad DOM directamente para que el primer valor de un formulario\n // ya cargado (ngModel/formControl con valor inicial) se refleje siempre.\n this.nativeInput().nativeElement.value = this.value();\n }\n\n writeValue(value: string): void {\n const nextValue = value ?? '';\n this.value.set(nextValue);\n // Mismo motivo que en ngAfterViewInit: escritura directa a la propiedad\n // DOM además del binding declarativo, para que cambios de valor\n // posteriores (ej. patchValue de un FormControl) siempre lleguen al\n // input nativo sin depender del timing de detección de cambios.\n const el = this.nativeInput?.();\n if (el) {\n el.nativeElement.value = nextValue;\n }\n }\n\n registerOnChange(fn: (value: string) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.disabledByForm.set(isDisabled);\n }\n\n protected onInput(rawValue: string): void {\n this.value.set(rawValue);\n this.onChange(rawValue);\n }\n\n protected onBlur(): void {\n this.focused.set(false);\n this.onTouched();\n }\n\n /**\n * Alterna la visibilidad del valor. No dispara `onBlur`/pierde el foco:\n * el botón vive dentro del mismo `.kf-input__field`, así que un click acá\n * no debe tratarse como si el usuario hubiese abandonado el campo.\n */\n protected onTogglePasswordVisibility(): void {\n this.passwordVisible.update((visible) => !visible);\n }\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\n\nexport type LinkVariant = 'default' | 'muted';\n\n/**\n * Acción de bajo énfasis con apariencia de texto — \"¿Olvidaste tu\n * contraseña?\", \"Volver a iniciar sesión\". Antes de este componente,\n * `web-portal-latam-frontend` reimplementaba esto dos veces (`.login__forgot`\n * como `<a href=\"#\">` con `preventDefault()`, `.login__back` como\n * `<button>`), cada una con su propio `:focus-visible` copiado literal.\n *\n * Es siempre un `<button type=\"button\">` por dentro, nunca un `<a>`: ninguno\n * de los dos casos reales navega a otra URL, ambos disparan una acción en la\n * misma pantalla (cambiar de vista, someter un flujo). Si en el futuro un\n * consumidor necesita navegación real con href, esa es una discusión de API\n * distinta (`kf-link` con `[routerLink]`/`href`), no se fuerza acá sin caso\n * de uso confirmado.\n *\n * `variant=\"default\"` (color primario, subrayado en hover) es para la\n * acción de mayor jerarquía relativa de la pantalla (ej. \"¿Olvidaste tu\n * contraseña?\"); `variant=\"muted\"` (gris que pasa a primario en hover) es\n * para acciones de retroceso/salida (ej. \"← Volver a iniciar sesión\").\n *\n * <kf-link (click)=\"onForgotPassword()\">¿Olvidaste tu contraseña?</kf-link>\n * <kf-link variant=\"muted\" (click)=\"onBack()\">← Volver a iniciar sesión</kf-link>\n */\n@Component({\n selector: 'kf-link',\n template: `\n <button\n type=\"button\"\n class=\"kf-link\"\n [class.kf-link--muted]=\"variant() === 'muted'\"\n [disabled]=\"disabled()\"\n >\n <ng-content />\n </button>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-link {\n padding: 0;\n border: none;\n background: transparent;\n font: inherit;\n font-weight: 500;\n color: var(--kf-color-primary);\n text-decoration: none;\n cursor: pointer;\n }\n .kf-link:hover:not(:disabled) {\n text-decoration: underline;\n }\n .kf-link:focus-visible {\n outline: 2px solid var(--kf-color-primary);\n outline-offset: 2px;\n border-radius: var(--kf-radius-xs);\n }\n .kf-link:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .kf-link--muted {\n color: var(--kf-color-text-muted);\n }\n .kf-link--muted:hover:not(:disabled) {\n color: var(--kf-color-primary);\n text-decoration: none;\n }\n `,\n})\nexport class Link {\n readonly variant = input<LinkVariant>('default');\n readonly disabled = input(false, { transform: booleanAttribute });\n}\n","import { Component, input } from '@angular/core';\nimport { Card } from '../card/Card';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Card de estadística/KPI: label, valor grande, ícono opcional en la esquina\n * superior derecha, badge de esquina opcional (pegado al valor) y una nota\n * al pie. Pensada para tableros de resumen (ej. \"11 Tickets abiertos\").\n *\n * Compone sobre `kf-card` en vez de duplicar su estilo de contenedor — así\n * el look de \"card\" (radio, sombra, borde) tiene una única fuente de verdad\n * en toda la librería, tal como pide el design system (página 14: \"Card...\n * es la base de paneles, tarjetas de métrica, tablas...\").\n *\n * <kf-metric-card label=\"Tickets abiertos\" value=\"11\" icon=\"ticket\" foot=\"+2 hoy\" />\n * <kf-metric-card label=\"Tasa de resolución\" value=\"94%\" badge=\"+2%\" value-color=\"var(--kf-color-success)\" />\n */\n@Component({\n selector: 'kf-metric-card',\n imports: [Card, Icon],\n template: `\n <kf-card>\n <div class=\"kf-metric-card__head\">\n <span class=\"kf-metric-card__label\">{{ label() }}</span>\n @if (icon(); as iconName) {\n <span class=\"kf-metric-card__icon\">\n <kf-icon [name]=\"iconName\" size=\"sm\" />\n </span>\n }\n </div>\n <div class=\"kf-metric-card__value-row\">\n <div class=\"kf-metric-card__value\" [style.color]=\"valueColor()\">\n {{ value() }}\n @if (unit()) {\n <span class=\"kf-metric-card__unit\">{{ unit() }}</span>\n }\n </div>\n @if (badge()) {\n <span class=\"kf-metric-card__badge\">{{ badge() }}</span>\n }\n </div>\n @if (foot()) {\n <div class=\"kf-metric-card__foot\">{{ foot() }}</div>\n }\n </kf-card>\n `,\n styles: `\n :host {\n display: block;\n }\n .kf-metric-card__head {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: var(--kf-space-xs);\n }\n .kf-metric-card__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 1.75rem;\n height: 1.75rem;\n flex: none;\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-primary-soft);\n color: var(--kf-color-primary);\n }\n .kf-metric-card__label {\n font-size: 0.72rem;\n font-weight: 700;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n color: var(--kf-color-text-muted);\n }\n .kf-metric-card__value-row {\n display: flex;\n align-items: center;\n gap: var(--kf-space-xs);\n }\n .kf-metric-card__value {\n font-family: var(--kf-font-title);\n font-weight: 700;\n font-size: 1.6rem;\n line-height: 1.1;\n color: var(--kf-color-ink);\n }\n .kf-metric-card__unit {\n font-size: 0.85rem;\n font-weight: 500;\n color: var(--kf-color-text-muted);\n margin-left: var(--kf-space-xs);\n }\n .kf-metric-card__badge {\n font-size: 0.72rem;\n font-weight: 700;\n padding: 2px var(--kf-space-xs);\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-success-soft);\n color: var(--kf-color-success-strong);\n }\n .kf-metric-card__foot {\n font-size: 0.78rem;\n color: var(--kf-color-text-muted);\n }\n `,\n})\nexport class MetricCard {\n readonly label = input.required<string>();\n readonly value = input.required<string | number>();\n readonly unit = input<string>();\n /** Ícono en la esquina superior derecha, renderizado vía `kf-icon`. */\n readonly icon = input<IconName>();\n readonly foot = input<string>();\n /** Tinte opcional para el valor grande (ej. un color semántico de estado). */\n readonly valueColor = input<string>();\n /** Badge de esquina opcional, pegado al valor (ej. \"+2%\"). */\n readonly badge = input<string>();\n}\n","import { DOCUMENT } from '@angular/common';\nimport {\n booleanAttribute,\n Component,\n DestroyRef,\n ElementRef,\n HostListener,\n afterRenderEffect,\n inject,\n input,\n model,\n viewChild,\n} from '@angular/core';\n\nlet modalId = 0;\n\n/**\n * Diálogo centrado sobre un backdrop: confirmaciones destructivas, formularios\n * cortos, decisiones que bloquean el flujo.\n *\n * Se apoya en el `<dialog>` nativo (`showModal()`), así que el atrapado de\n * foco, el backdrop, el orden en el top-layer y el cierre con `Escape` los\n * resuelve el navegador — no hay trampa de foco escrita a mano acá. Lo único\n * que se agrega es el lock de scroll del body, que `<dialog>` no hace.\n *\n * `open` es two-way. Con `dismissible` en `false` (ej. mientras una acción\n * destructiva está en vuelo) se cancelan `Escape` y el clic en el backdrop:\n * solo cierra el consumidor poniendo `open` en `false`.\n *\n * Las acciones van en el slot `footer`.\n *\n * <kf-modal [(open)]=\"confirmOpen\" title=\"Eliminar unidad\">\n * <p>Esta acción no se puede deshacer.</p>\n * <div footer>\n * <kf-button variant=\"ghost\" (click)=\"confirmOpen.set(false)\">Cancelar</kf-button>\n * <kf-button (click)=\"remove()\">Eliminar</kf-button>\n * </div>\n * </kf-modal>\n */\n@Component({\n selector: 'kf-modal',\n template: `\n <dialog\n #dialog\n class=\"kf-modal\"\n [attr.aria-labelledby]=\"title() ? titleId : null\"\n (cancel)=\"onCancel($event)\"\n (close)=\"open.set(false)\"\n >\n @if (open()) {\n <div class=\"kf-modal__panel\">\n <div class=\"kf-modal__head\">\n @if (title()) {\n <h2 class=\"kf-modal__title\" [id]=\"titleId\">{{ title() }}</h2>\n }\n @if (dismissible()) {\n <button\n type=\"button\"\n class=\"kf-modal__close\"\n aria-label=\"Cerrar diálogo\"\n (click)=\"open.set(false)\"\n >\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M6 6l12 12M18 6L6 18\" />\n </svg>\n </button>\n }\n </div>\n <div class=\"kf-modal__body\"><ng-content /></div>\n <div class=\"kf-modal__footer\"><ng-content select=\"[footer]\" /></div>\n </div>\n }\n </dialog>\n `,\n styles: `\n .kf-modal {\n width: min(480px, calc(100vw - 2 * var(--kf-space-md)));\n max-height: calc(100vh - 2 * var(--kf-space-xl));\n padding: 0;\n border: none;\n background: transparent;\n overflow: visible;\n font-family: var(--kf-font-body);\n }\n .kf-modal::backdrop {\n background: rgba(23, 29, 37, 0.45);\n }\n .kf-modal__panel {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-md);\n padding: var(--kf-space-lg);\n background: var(--kf-color-white);\n border-radius: var(--kf-radius-md);\n box-shadow: var(--kf-shadow-lg);\n }\n .kf-modal__head {\n display: flex;\n align-items: flex-start;\n gap: var(--kf-space-sm);\n }\n .kf-modal__title {\n flex: 1;\n margin: 0;\n font-family: var(--kf-font-title);\n font-size: 1.375rem;\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-modal__close {\n flex: none;\n display: inline-flex;\n padding: 2px;\n border: none;\n background: transparent;\n color: var(--kf-color-text-muted);\n border-radius: var(--kf-radius-xs);\n cursor: pointer;\n }\n .kf-modal__close svg {\n width: 1.25em;\n height: 1.25em;\n fill: none;\n stroke: currentColor;\n stroke-width: 1.9;\n stroke-linecap: round;\n }\n .kf-modal__close:hover {\n color: var(--kf-color-ink);\n }\n .kf-modal__close:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-modal__body {\n color: var(--kf-color-text);\n overflow-y: auto;\n }\n .kf-modal__footer:empty {\n display: none;\n }\n .kf-modal__footer {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-end;\n gap: var(--kf-space-sm);\n }\n `,\n})\nexport class Modal {\n readonly title = input('');\n /** Visibilidad, two-way: `[(open)]=\"confirmOpen\"`. */\n readonly open = model(false);\n /** Permite cerrar con el botón, `Escape` o clic en el backdrop. */\n readonly dismissible = input(true, { transform: booleanAttribute });\n\n protected readonly titleId = `kf-modal-title-${modalId++}`;\n\n private readonly dialog = viewChild<ElementRef<HTMLDialogElement>>('dialog');\n private readonly document = inject(DOCUMENT);\n\n constructor() {\n afterRenderEffect(() => {\n const el = this.dialog()?.nativeElement;\n if (!el) {\n return;\n }\n if (this.open() && !el.open) {\n // ponytail: `showModal` no existe en jsdom (tests) ni en entornos sin\n // top-layer; el atributo `open` lo deja visible, aunque no modal.\n if (typeof el.showModal === 'function') {\n el.showModal();\n } else {\n el.open = true;\n }\n } else if (!this.open() && el.open) {\n if (typeof el.close === 'function') {\n el.close();\n } else {\n el.open = false;\n }\n }\n // `<dialog>` inertiza el resto de la página pero no frena su scroll.\n this.document.body.style.overflow = this.open() ? 'hidden' : '';\n });\n\n inject(DestroyRef).onDestroy(() => {\n this.document.body.style.overflow = '';\n });\n }\n\n /** `Escape` dispara `cancel`; cancelarlo lo deja abierto. */\n protected onCancel(event: Event): void {\n if (!this.dismissible()) {\n event.preventDefault();\n }\n }\n\n /**\n * Clic en el backdrop. Un clic en la zona del backdrop tiene como `target` al\n * propio `<dialog>` (el contenido vive en el panel de adentro), así que basta\n * comparar contra él — no hace falta cortar la propagación en el panel.\n *\n * Va como HostListener y no como binding en el template porque un `(click)`\n * sobre el `<dialog>` dispara las reglas a11y de click-sin-teclado; acá el\n * equivalente de teclado es `Escape`, que el `<dialog>` nativo ya maneja.\n */\n @HostListener('click', ['$event'])\n protected onHostClick(event: MouseEvent): void {\n if (this.dismissible() && event.target === this.dialog()?.nativeElement) {\n this.open.set(false);\n }\n }\n}\n","import {\n Component,\n ElementRef,\n HostListener,\n booleanAttribute,\n computed,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { FieldLabel } from '../field-label/FieldLabel';\n\nexport interface MultiSelectOption {\n value: string;\n label: string;\n}\n\nlet nextId = 0;\n\n/**\n * Dropdown de selección múltiple con checkboxes internos, siguiendo el mismo\n * patrón de panel flotante que `SelectMenu` (panel con `position: absolute`\n * sobre el host, sin Angular CDK Overlay, que no es dependencia del proyecto).\n * Se abre y cierra por click en el disparador, y se cierra al hacer click\n * afuera o al presionar Escape.\n *\n * A diferencia de `SelectMenu`, el disparador no muestra un único valor sino\n * los nombres seleccionados junto a un badge circular con el conteo (página\n * 12: \"Sucursal Norte, Lima Centro\" + badge \"2\"), y cada opción del panel se\n * marca/desmarca con un checkbox sin cerrar el panel. Incluye una opción\n * \"Todas\" al inicio de la lista, con estado `indeterminate` cuando hay\n * selección parcial — el mismo patrón de \"seleccionar todos\" de `Checkbox`.\n *\n * <kf-multi-select\n * label=\"Sucursales\"\n * [options]=\"branches\"\n * [values]=\"selectedBranches()\"\n * (valuesChange)=\"selectedBranches.set($event)\"\n * />\n *\n * Pendiente: el prop `icon` de otros componentes del design system requiere\n * un componente Icon / sprite SVG que esta librería todavía no tiene — este\n * componente no usa iconos, así que no aplica acá.\n */\n@Component({\n selector: 'kf-multi-select',\n imports: [FieldLabel],\n template: `\n @if (label()) {\n <kf-field-label [for]=\"triggerId\">{{ label() }}</kf-field-label>\n }\n <button\n #trigger\n type=\"button\"\n [id]=\"triggerId\"\n class=\"kf-multi-select__trigger\"\n [disabled]=\"disabled()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-controls]=\"isOpen() ? listboxId : null\"\n (click)=\"toggle()\"\n >\n <span\n class=\"kf-multi-select__value\"\n [class.kf-multi-select__value--placeholder]=\"selectedCount() === 0\"\n >\n {{ summaryText() }}\n </span>\n @if (selectedCount() > 0) {\n <span class=\"kf-multi-select__count\">{{ selectedCount() }}</span>\n }\n <span\n class=\"kf-multi-select__caret\"\n [class.kf-multi-select__caret--open]=\"isOpen()\"\n aria-hidden=\"true\"\n ></span>\n </button>\n @if (isOpen()) {\n <ul\n class=\"kf-multi-select__panel\"\n [id]=\"listboxId\"\n role=\"listbox\"\n aria-multiselectable=\"true\"\n [attr.aria-labelledby]=\"triggerId\"\n >\n @if (options().length > 0) {\n <li\n class=\"kf-multi-select__option\"\n role=\"option\"\n tabindex=\"0\"\n [attr.aria-selected]=\"allSelected()\"\n (click)=\"toggleAll()\"\n (keydown.enter)=\"toggleAll()\"\n (keydown.space)=\"$event.preventDefault(); toggleAll()\"\n >\n <span\n class=\"kf-multi-select__checkbox\"\n [class.kf-multi-select__checkbox--checked]=\"allSelected()\"\n [class.kf-multi-select__checkbox--indeterminate]=\"isPartiallySelected()\"\n ></span>\n <span class=\"kf-multi-select__option-label\">Todas</span>\n </li>\n }\n @for (option of options(); track option.value) {\n <li\n class=\"kf-multi-select__option\"\n [class.kf-multi-select__option--selected]=\"isSelected(option.value)\"\n role=\"option\"\n tabindex=\"0\"\n [attr.aria-selected]=\"isSelected(option.value)\"\n (click)=\"toggleOption(option.value)\"\n (keydown.enter)=\"toggleOption(option.value)\"\n (keydown.space)=\"$event.preventDefault(); toggleOption(option.value)\"\n >\n <span\n class=\"kf-multi-select__checkbox\"\n [class.kf-multi-select__checkbox--checked]=\"isSelected(option.value)\"\n ></span>\n <span class=\"kf-multi-select__option-label\">{{ option.label }}</span>\n </li>\n } @empty {\n <li class=\"kf-multi-select__empty\">Sin opciones disponibles</li>\n }\n </ul>\n }\n `,\n styles: `\n :host {\n display: inline-flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n position: relative;\n font: inherit;\n /*\n * Ancho FIJO, no min-width: con solo un piso, el host podía seguir\n * creciendo sin límite a medida que summaryText() sumaba más labels\n * seleccionados — un multiselect con 3-4 opciones largas terminaba\n * ocupando el doble o el triple que el resto de los campos del mismo\n * formulario. El texto que no entra se corta con el\n * text-overflow: ellipsis que .kf-multi-select__value ya tenía, el\n * badge de conteo (.kf-multi-select__count) sigue siempre visible al\n * lado para comunicar cuántas opciones hay seleccionadas aunque el\n * texto se trunque.\n */\n width: 240px;\n }\n .kf-multi-select__trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-sm);\n width: 100%;\n font: inherit;\n font-family: var(--kf-font-body);\n padding: var(--kf-space-sm) var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-white);\n color: var(--kf-color-text);\n cursor: pointer;\n transition:\n border-color 0.14s,\n box-shadow 0.14s;\n }\n .kf-multi-select__trigger:hover:not(:disabled) {\n border-color: var(--kf-color-border-strong);\n }\n .kf-multi-select__trigger:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-multi-select__trigger:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .kf-multi-select__value {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n text-align: left;\n }\n .kf-multi-select__value--placeholder {\n color: var(--kf-color-text-muted);\n }\n .kf-multi-select__count {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 1.25rem;\n height: 1.25rem;\n padding: 0 5px;\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-primary);\n color: var(--kf-color-white);\n font-size: 0.72rem;\n font-weight: 700;\n }\n .kf-multi-select__caret {\n flex-shrink: 0;\n width: 8px;\n height: 8px;\n border-right: 2px solid var(--kf-color-text-muted);\n border-bottom: 2px solid var(--kf-color-text-muted);\n transform: rotate(45deg);\n transition: transform 0.14s;\n margin-top: -4px;\n }\n .kf-multi-select__caret--open {\n transform: rotate(-135deg);\n margin-top: 4px;\n }\n .kf-multi-select__panel {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n z-index: 10;\n margin: var(--kf-space-xs) 0 0;\n padding: var(--kf-space-xs) 0;\n list-style: none;\n max-height: 240px;\n overflow-y: auto;\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n box-shadow: var(--kf-shadow-md);\n }\n .kf-multi-select__option {\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-sm) var(--kf-space-md);\n color: var(--kf-color-text);\n cursor: pointer;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .kf-multi-select__option:hover {\n background: var(--kf-color-primary-soft);\n }\n .kf-multi-select__option--selected {\n color: var(--kf-color-primary);\n font-weight: 600;\n }\n .kf-multi-select__checkbox {\n display: inline-flex;\n flex-shrink: 0;\n width: var(--kf-space-md);\n height: var(--kf-space-md);\n border: 1px solid var(--kf-color-border-strong);\n border-radius: var(--kf-radius-xs);\n background: var(--kf-color-white);\n transition:\n background 0.14s,\n border-color 0.14s;\n position: relative;\n }\n .kf-multi-select__checkbox--checked {\n background: var(--kf-color-primary);\n border-color: var(--kf-color-primary);\n }\n .kf-multi-select__checkbox--checked::after {\n content: '';\n position: absolute;\n left: 4px;\n top: 1px;\n width: 4px;\n height: 8px;\n border: solid var(--kf-color-white);\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n /* \"Todas\" con selección parcial: barra horizontal, mismo patrón que Checkbox. */\n .kf-multi-select__checkbox--indeterminate {\n background: var(--kf-color-primary);\n border-color: var(--kf-color-primary);\n }\n .kf-multi-select__checkbox--indeterminate::after {\n content: '';\n position: absolute;\n left: 3px;\n top: 6px;\n width: 8px;\n height: 2px;\n background: var(--kf-color-white);\n border: none;\n transform: none;\n }\n .kf-multi-select__option-label {\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .kf-multi-select__empty {\n padding: var(--kf-space-sm) var(--kf-space-md);\n color: var(--kf-color-text-muted);\n }\n `,\n})\nexport class MultiSelect {\n readonly label = input<string>();\n readonly options = input<MultiSelectOption[]>([]);\n readonly values = input<string[]>([]);\n readonly placeholder = input<string>('Seleccionar');\n readonly disabled = input(false, { transform: booleanAttribute });\n\n readonly valuesChange = output<string[]>();\n\n private readonly instanceId = `kf-multi-select-${nextId++}`;\n readonly triggerId = `${this.instanceId}-trigger`;\n readonly listboxId = `${this.instanceId}-listbox`;\n\n readonly isOpen = signal(false);\n\n readonly selectedCount = computed(() => this.values().length);\n\n readonly allSelected = computed(\n () => this.options().length > 0 && this.values().length === this.options().length,\n );\n\n readonly isPartiallySelected = computed(() => this.values().length > 0 && !this.allSelected());\n\n /**\n * Texto del disparador: placeholder si no hay selección, o los nombres\n * seleccionados unidos por coma (el conteo va aparte, en el badge). Con\n * muchas opciones el `text-overflow: ellipsis` del `.kf-multi-select__value`\n * corta el texto — el badge de conteo siempre queda visible al lado.\n */\n readonly summaryText = computed(() => {\n const count = this.selectedCount();\n if (count === 0) {\n return this.placeholder();\n }\n const selectedLabels = this.values()\n .map((value) => this.options().find((option) => option.value === value)?.label)\n .filter((label): label is string => Boolean(label));\n return selectedLabels.join(', ');\n });\n\n private readonly host = inject(ElementRef<HTMLElement>);\n\n isSelected(value: string): boolean {\n return this.values().includes(value);\n }\n\n toggle(): void {\n if (this.disabled()) {\n return;\n }\n this.isOpen.update((open) => !open);\n }\n\n toggleOption(value: string): void {\n const current = this.values();\n const next = current.includes(value)\n ? current.filter((selectedValue) => selectedValue !== value)\n : [...current, value];\n this.valuesChange.emit(next);\n }\n\n /** Alterna entre \"todas seleccionadas\" y \"ninguna seleccionada\". */\n toggleAll(): void {\n this.valuesChange.emit(this.allSelected() ? [] : this.options().map((option) => option.value));\n }\n\n @HostListener('document:click', ['$event'])\n onDocumentClick(event: MouseEvent): void {\n if (this.isOpen() && !this.host.nativeElement.contains(event.target as Node)) {\n this.isOpen.set(false);\n }\n }\n\n @HostListener('document:keydown.escape')\n onEscape(): void {\n this.isOpen.set(false);\n }\n}\n","import { Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Bloque de título al tope de una página: chip de ícono opcional, título (h1),\n * subtítulo opcional y un área de acciones opcional proyectada vía\n * `<ng-content select=\"[actions]\">`, para no acoplar el componente a un set\n * fijo de botones.\n *\n * <kf-page-header title=\"Vehículos\" subtitle=\"Gestión de la flota activa\">\n * <button actions>Nuevo vehículo</button>\n * </kf-page-header>\n *\n * <kf-page-header icon=\"settings\" title=\"Configuración\" />\n */\n@Component({\n selector: 'kf-page-header',\n imports: [Icon],\n template: `\n @if (icon(); as iconName) {\n <span class=\"kf-page-header__icon\">\n <kf-icon [name]=\"iconName\" size=\"lg\" />\n </span>\n }\n\n <div class=\"kf-page-header__heading\">\n <h1 class=\"kf-page-header__title\">{{ title() }}</h1>\n @if (subtitle()) {\n <p class=\"kf-page-header__subtitle\">{{ subtitle() }}</p>\n }\n </div>\n\n <div class=\"kf-page-header__actions\">\n <ng-content select=\"[actions]\" />\n </div>\n `,\n styles: `\n :host {\n display: flex;\n align-items: center;\n gap: var(--kf-space-md);\n font-family: var(--kf-font-body);\n }\n .kf-page-header__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n /* El chip necesita bastante más aire que el ícono (24px \"lg\") que\n contiene — con --kf-space-xl (32px) quedaban casi pegados. */\n width: 48px;\n height: 48px;\n border-radius: var(--kf-radius-md);\n background: var(--kf-color-primary-soft);\n color: var(--kf-color-primary);\n }\n .kf-page-header__heading {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n flex: 1 1 auto;\n min-width: 0;\n }\n .kf-page-header__title {\n margin: 0;\n font-family: var(--kf-font-title);\n font-size: 1.5rem;\n font-weight: 700;\n line-height: 1.2;\n color: var(--kf-color-ink);\n }\n .kf-page-header__subtitle {\n margin: 0;\n font-size: 0.9375rem;\n color: var(--kf-color-text-muted);\n }\n .kf-page-header__actions {\n flex: none;\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n }\n `,\n})\nexport class PageHeader {\n readonly icon = input<IconName | undefined>(undefined);\n readonly title = input.required<string>();\n readonly subtitle = input<string | undefined>(undefined);\n}\n","import { Component, computed, input, output } from '@angular/core';\n\n/** Un número de página clickeable o un separador \"…\" no interactivo. */\nexport type PaginationItem = { type: 'page'; page: number } | { type: 'ellipsis' };\n\nconst SIBLINGS = 1;\n\n/**\n * Paginador numerado con elipsis + prev/next.\n *\n * Algoritmo de elipsis estándar: siempre se muestran la primera página, la\n * última, la página actual y un par de vecinas alrededor de la actual; el\n * resto de los huecos se colapsa en un separador \"…\". Cuando el hueco entre\n * dos números visibles es de exactamente una página, se muestra ese número\n * en vez de un \"…\" (no tiene sentido colapsar un solo elemento).\n *\n * El contenido proyectado (`<ng-content>`) es para el texto informativo\n * opcional (ej. \"21–40 de 273\"), a la izquierda de los controles.\n *\n * <kf-pagination [page]=\"page\" [pages]=\"totalPages\" (pageChange)=\"page = $event\">\n * 21–40 de 273\n * </kf-pagination>\n */\n@Component({\n selector: 'kf-pagination',\n template: `\n <div class=\"kf-pagination\">\n <div class=\"kf-pagination__info\">\n <ng-content />\n </div>\n <nav class=\"kf-pagination__nav\" aria-label=\"Paginación\">\n <button\n type=\"button\"\n class=\"kf-pagination__control\"\n [disabled]=\"page() <= 1\"\n aria-label=\"Página anterior\"\n (click)=\"goTo(page() - 1)\"\n >\n ‹\n </button>\n\n @for (item of items(); track $index) {\n @if (item.type === 'page') {\n <button\n type=\"button\"\n class=\"kf-pagination__page\"\n [class.kf-pagination__page--active]=\"item.page === page()\"\n [attr.aria-current]=\"item.page === page() ? 'page' : null\"\n [attr.aria-label]=\"'Ir a la página ' + item.page\"\n (click)=\"goTo(item.page)\"\n >\n {{ item.page }}\n </button>\n } @else {\n <span class=\"kf-pagination__ellipsis\" aria-hidden=\"true\">…</span>\n }\n }\n\n <button\n type=\"button\"\n class=\"kf-pagination__control\"\n [disabled]=\"page() >= pages()\"\n aria-label=\"Página siguiente\"\n (click)=\"goTo(page() + 1)\"\n >\n ›\n </button>\n </nav>\n </div>\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-pagination {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-md);\n flex-wrap: wrap;\n }\n .kf-pagination__info {\n font-size: 0.85rem;\n color: var(--kf-color-text-muted);\n }\n .kf-pagination__info:empty {\n display: none;\n }\n .kf-pagination__nav {\n display: flex;\n align-items: center;\n gap: var(--kf-space-xs);\n }\n .kf-pagination__control,\n .kf-pagination__page {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 2rem;\n height: 2rem;\n padding: 0 var(--kf-space-xs);\n font: inherit;\n font-size: 0.85rem;\n color: var(--kf-color-text);\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n cursor: pointer;\n transition:\n background 0.14s,\n border-color 0.14s,\n color 0.14s;\n }\n .kf-pagination__control:hover:not(:disabled),\n .kf-pagination__page:hover:not(.kf-pagination__page--active) {\n background: var(--kf-color-surface);\n border-color: var(--kf-color-border-strong);\n }\n .kf-pagination__control:focus-visible,\n .kf-pagination__page:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-pagination__control:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .kf-pagination__page--active {\n color: var(--kf-color-white);\n background: var(--kf-color-primary);\n border-color: var(--kf-color-primary);\n cursor: default;\n }\n .kf-pagination__ellipsis {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 2rem;\n height: 2rem;\n color: var(--kf-color-text-muted);\n }\n `,\n})\nexport class Pagination {\n readonly page = input(1);\n readonly pages = input(1);\n readonly pageChange = output<number>();\n\n /** Lista de números de página y separadores a renderizar, ya resuelta por el algoritmo de elipsis. */\n readonly items = computed<PaginationItem[]>(() =>\n buildPaginationItems(this.page(), this.pages()),\n );\n\n goTo(target: number): void {\n const clamped = Math.min(Math.max(target, 1), this.pages());\n if (clamped === this.page()) {\n return;\n }\n this.pageChange.emit(clamped);\n }\n}\n\n/**\n * Construye la lista de items visibles con el algoritmo de elipsis estándar:\n * primera página, última página, actual ± `SIBLINGS`, y un \"…\" por cada hueco\n * mayor a una página entre esos bloques.\n */\nfunction buildPaginationItems(current: number, total: number): PaginationItem[] {\n const totalPages = Math.max(total, 1);\n const safeCurrent = Math.min(Math.max(current, 1), totalPages);\n\n const visible = new Set<number>([1, totalPages, safeCurrent]);\n for (let offset = 1; offset <= SIBLINGS; offset++) {\n visible.add(safeCurrent - offset);\n visible.add(safeCurrent + offset);\n }\n\n const sortedPages = [...visible].filter((p) => p >= 1 && p <= totalPages).sort((a, b) => a - b);\n\n const items: PaginationItem[] = [];\n for (let i = 0; i < sortedPages.length; i++) {\n const pageNumber = sortedPages[i];\n if (i > 0) {\n const gap = pageNumber - sortedPages[i - 1];\n if (gap === 2) {\n // Hueco de una sola página: mostrarla en vez de colapsarla en \"…\".\n items.push({ type: 'page', page: pageNumber - 1 });\n } else if (gap > 2) {\n items.push({ type: 'ellipsis' });\n }\n }\n items.push({ type: 'page', page: pageNumber });\n }\n\n return items;\n}\n","import { Component, input } from '@angular/core';\nimport { Card } from '../card/Card';\nimport { Divider } from '../divider/Divider';\nimport { Icon } from '../icon/Icon';\n\n/**\n * Tarjeta contenedora con título, enlace de acción opcional a la derecha, y\n * cuerpo con contenido libre — página 33: \"Base de la mayoría de bloques del\n * portal\". Compone sobre `kf-card` para compartir la misma superficie\n * (radio, sombra, borde) que el resto de la librería.\n *\n * <kf-panel title=\"Mis documentos por pagar\" actionLabel=\"Ir a pagos\" actionHref=\"/pagos\">\n * <kf-action-tile-row icon=\"download\" title=\"Pagos\" description=\"Revisa tu estado de cuenta y realiza pagos.\" />\n * </kf-panel>\n */\n@Component({\n selector: 'kf-panel',\n imports: [Card, Divider, Icon],\n template: `\n <kf-card>\n <div class=\"kf-panel__head\">\n <span class=\"kf-panel__title\">{{ title() }}</span>\n @if (actionLabel()) {\n <a class=\"kf-panel__action\" [href]=\"actionHref() || '#'\">\n {{ actionLabel() }}\n <kf-icon name=\"chevron-right\" size=\"sm\" />\n </a>\n }\n </div>\n <kf-divider />\n <div class=\"kf-panel__body\">\n <ng-content />\n </div>\n </kf-card>\n `,\n styles: `\n :host {\n display: block;\n }\n .kf-panel__head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-sm);\n margin-bottom: var(--kf-space-sm);\n }\n .kf-panel__title {\n font-family: var(--kf-font-title);\n font-size: 1.05rem;\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-panel__action {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n flex: none;\n font-size: 0.8125rem;\n font-weight: 600;\n color: var(--kf-color-primary);\n text-decoration: none;\n }\n .kf-panel__action:hover {\n text-decoration: underline;\n }\n .kf-panel__body {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-sm);\n margin-top: var(--kf-space-sm);\n }\n `,\n})\nexport class Panel {\n readonly title = input.required<string>();\n readonly actionLabel = input<string>();\n readonly actionHref = input<string>();\n}\n","import {\n Component,\n ElementRef,\n HostListener,\n booleanAttribute,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { AdminBadge } from '../admin-badge/AdminBadge';\nimport { Avatar } from '../avatar/Avatar';\nimport { Icon } from '../icon/Icon';\n\n/** Un ítem de navegación de la barra de marca. */\nexport interface PortalHeaderNavItem {\n label: string;\n href: string;\n active?: boolean;\n}\n\n/** Una acción de la franja de administrador (ej. \"Consultar deuda clientes\"). */\nexport interface PortalHeaderAdminAction {\n label: string;\n href: string;\n}\n\n/**\n * Cabecera completa del portal (página 31) — franja de administrador\n * (acento ámbar, solo admins), barra de marca con logo, navegación y\n * pastilla de sesión. Compone `kf-admin-badge` para la franja y `kf-avatar\n * pill` para la sesión, en vez de reimplementar ambos.\n *\n * Es distinto de `kf-page-header`/`kf-page-head` (título de una vista\n * interna) — este es el chrome global del portal, se monta una sola vez.\n *\n * `:host` es `position: sticky; top: 0` — el header queda pegado arriba al\n * hacer scroll. No es `fixed`: como no se superpone al contenido en el\n * primer render, no hace falta que el consumidor compense con\n * `padding-top`.\n *\n * Bajo los 768px, el `<nav>` deja de mostrarse en línea junto al logo y\n * colapsa detrás de un botón de menú (ícono `menu`/`x`) que despliega un\n * drawer lateral (desde el borde derecho, `position: fixed` + overlay de\n * fondo) con los mismos `navItems` en columna. Ese drawer expone un slot\n * (`<ng-content select=\"[kf-portal-header-extra]\">`) al final, pensado\n * para que el consumidor proyecte contenido propio que en escritorio vive\n * en otro lugar (ej. el menú de sesión) — `PortalHeader` no sabe qué es\n * ese contenido ni cómo se abre, solo le da un lugar dentro del drawer ya\n * desplegado. El overlay cierra el drawer al tocarlo, y `Escape` también.\n *\n * <kf-portal-header\n * [isAdmin]=\"true\"\n * [adminActions]=\"[{ label: 'Consultar deuda clientes', href: '/deuda' }, { label: 'Cambiar DNI', href: '/dni' }]\"\n * [navItems]=\"[{ label: 'Home', href: '/', active: true }, { label: 'Vehículos', href: '/vehiculos' }]\"\n * userInitials=\"TS\"\n * >\n * <div kf-portal-header-extra>contenido propio, solo visible en el panel mobile</div>\n * </kf-portal-header>\n */\n@Component({\n selector: 'kf-portal-header',\n imports: [AdminBadge, Avatar, Icon],\n template: `\n @if (isAdmin()) {\n <div class=\"kf-portal-header__admin-bar\">\n <kf-admin-badge inline />\n <div class=\"kf-portal-header__admin-actions\">\n @for (action of adminActions(); track action.label) {\n <a class=\"kf-portal-header__admin-action\" [href]=\"action.href\">{{ action.label }}</a>\n }\n </div>\n </div>\n }\n <div class=\"kf-portal-header__brand-bar\">\n <span class=\"kf-portal-header__logo\">{{ brand() }}</span>\n\n <nav class=\"kf-portal-header__nav\">\n @for (item of navItems(); track item.label) {\n <a\n class=\"kf-portal-header__nav-item\"\n [class.kf-portal-header__nav-item--active]=\"item.active\"\n [href]=\"item.href\"\n >\n {{ item.label }}\n </a>\n }\n </nav>\n\n <button\n #sessionButton\n type=\"button\"\n class=\"kf-portal-header__session\"\n (click)=\"sessionClick.emit()\"\n >\n <kf-avatar [initials]=\"userInitials()\" pill />\n </button>\n\n <button\n type=\"button\"\n class=\"kf-portal-header__menu-toggle\"\n [attr.aria-expanded]=\"mobileMenuOpen()\"\n aria-label=\"Abrir menú de navegación\"\n (click)=\"mobileMenuOpen.set(!mobileMenuOpen())\"\n >\n <kf-icon [name]=\"mobileMenuOpen() ? 'x' : 'menu'\" size=\"md\" />\n </button>\n </div>\n\n @if (mobileMenuOpen()) {\n <div class=\"kf-portal-header__overlay\" (click)=\"mobileMenuOpen.set(false)\"></div>\n }\n\n <nav\n class=\"kf-portal-header__drawer\"\n [class.kf-portal-header__drawer--open]=\"mobileMenuOpen()\"\n role=\"menu\"\n [attr.aria-hidden]=\"!mobileMenuOpen()\"\n >\n @for (item of navItems(); track item.label) {\n <a\n class=\"kf-portal-header__mobile-nav-item\"\n [class.kf-portal-header__mobile-nav-item--active]=\"item.active\"\n [href]=\"item.href\"\n (click)=\"mobileMenuOpen.set(false)\"\n >\n {{ item.label }}\n </a>\n }\n <ng-content select=\"[kf-portal-header-extra]\" />\n </nav>\n `,\n styles: `\n :host {\n display: block;\n position: sticky;\n top: 0;\n z-index: 30;\n font-family: var(--kf-font-body);\n }\n .kf-portal-header__admin-bar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-md);\n padding: var(--kf-space-xs) var(--kf-space-lg);\n background: var(--kf-color-tertiary-deep);\n }\n .kf-portal-header__admin-actions {\n display: flex;\n gap: var(--kf-space-md);\n }\n .kf-portal-header__admin-action {\n font-size: 0.8125rem;\n font-weight: 600;\n color: rgba(255, 255, 255, 0.85);\n text-decoration: none;\n }\n .kf-portal-header__admin-action:hover {\n color: var(--kf-color-white);\n }\n .kf-portal-header__brand-bar {\n display: flex;\n align-items: center;\n gap: var(--kf-space-lg);\n padding: var(--kf-space-sm) var(--kf-space-lg);\n background: var(--kf-color-tertiary-deep);\n border-top: 1px solid rgba(255, 255, 255, 0.1);\n }\n .kf-portal-header__logo {\n font-family: var(--kf-font-title);\n font-size: 1.25rem;\n font-weight: 700;\n letter-spacing: 0.02em;\n color: var(--kf-color-white);\n text-transform: uppercase;\n /* En mobile, el logo no se abrevia — se lo deja partir en varias\n líneas antes que truncarlo, pero sin dejar que un logo largo se\n coma todo el ancho: el nav/sesión de escritorio ya están ocultos\n acá abajo de 768px, así que el logo tiene toda la fila para él y\n el botón de menú. */\n flex: 1 1 auto;\n min-width: 0;\n }\n .kf-portal-header__nav {\n display: flex;\n align-items: center;\n gap: var(--kf-space-xs);\n flex: 1 1 auto;\n }\n .kf-portal-header__nav-item {\n padding: var(--kf-space-xs) var(--kf-space-md);\n border-radius: var(--kf-radius-sm);\n color: rgba(255, 255, 255, 0.75);\n font-size: 0.875rem;\n font-weight: 600;\n text-decoration: none;\n white-space: nowrap;\n transition:\n background 0.14s,\n color 0.14s;\n }\n /*\n * :not(--active) es necesario: sin él, este :hover pisa el color del\n * item activo (fondo blanco, texto --kf-color-ink) con blanco también,\n * dejando texto blanco sobre fondo blanco al pasar el mouse por encima\n * del item ya activo.\n */\n .kf-portal-header__nav-item:hover:not(.kf-portal-header__nav-item--active) {\n color: var(--kf-color-white);\n }\n .kf-portal-header__nav-item--active {\n background: var(--kf-color-white);\n color: var(--kf-color-ink);\n }\n .kf-portal-header__session {\n flex: none;\n border: none;\n background: transparent;\n padding: 0;\n cursor: pointer;\n }\n .kf-portal-header__menu-toggle {\n display: none;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border: none;\n border-radius: var(--kf-radius-sm);\n background: transparent;\n color: var(--kf-color-white);\n cursor: pointer;\n }\n .kf-portal-header__menu-toggle:hover {\n background: rgba(255, 255, 255, 0.1);\n }\n /*\n * Overlay: capa semitransparente detrás del drawer, cubre toda la\n * pantalla. Cierra el drawer al tocarla — mismo patrón que cualquier\n * drawer/modal (click afuera cierra).\n */\n .kf-portal-header__overlay {\n position: fixed;\n inset: 0;\n background: rgba(16, 24, 40, 0.4);\n z-index: 39;\n }\n /*\n * Drawer: panel fijo a toda la altura de la pantalla, anclado al\n * borde derecho, oculto por defecto corriéndolo fuera de la pantalla\n * (translateX(100%)) en vez de con display:none — así la transición\n * de entrada/salida es un slide real, no un aparecer/desaparecer\n * abrupto. visibility: hidden en el estado cerrado evita que sea\n * focuseable/clickeable mientras está fuera de vista (translateX por\n * sí solo no saca el elemento del árbol de tabulación).\n */\n .kf-portal-header__drawer {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n z-index: 40;\n display: none;\n flex-direction: column;\n width: min(80vw, 320px);\n padding: var(--kf-space-lg);\n background: var(--kf-color-tertiary-deep);\n box-shadow: -8px 0 24px -8px rgba(16, 24, 40, 0.3);\n transform: translateX(100%);\n visibility: hidden;\n transition:\n transform 0.24s cubic-bezier(0.32, 0.72, 0, 1),\n visibility 0s linear 0.24s;\n }\n .kf-portal-header__drawer--open {\n transform: translateX(0);\n visibility: visible;\n transition:\n transform 0.24s cubic-bezier(0.32, 0.72, 0, 1),\n visibility 0s linear 0s;\n }\n .kf-portal-header__mobile-nav-item {\n padding: var(--kf-space-sm) var(--kf-space-xs);\n color: rgba(255, 255, 255, 0.85);\n font-size: 0.9375rem;\n font-weight: 600;\n text-decoration: none;\n border-radius: var(--kf-radius-sm);\n }\n .kf-portal-header__mobile-nav-item:hover {\n background: rgba(255, 255, 255, 0.08);\n }\n .kf-portal-header__mobile-nav-item--active {\n color: var(--kf-color-white);\n background: rgba(255, 255, 255, 0.14);\n }\n\n /*\n * Único breakpoint real de la librería hasta ahora: por debajo de\n * 768px el <nav> horizontal deja lugar al botón de menú + drawer\n * lateral. El resto de los componentes de la librería no maneja\n * responsive todavía — este es el primer caso.\n */\n @media (max-width: 768px) {\n .kf-portal-header__nav {\n display: none;\n }\n /*\n * El botón de sesión (avatar) también se oculta: en mobile la única\n * forma de llegar a sesión/logout es a través del drawer (ver el\n * slot kf-portal-header-extra), no un segundo camino en paralelo\n * vía este botón + el overlay de dropdown que el consumidor arma\n * para escritorio — ese overlay no está pensado para posicionarse\n * bien en una pantalla angosta.\n */\n .kf-portal-header__session {\n display: none;\n }\n .kf-portal-header__menu-toggle {\n display: inline-flex;\n }\n .kf-portal-header__drawer {\n display: flex;\n }\n }\n `,\n})\nexport class PortalHeader {\n readonly brand = input('DIVEMOTOR');\n readonly isAdmin = input(false, { transform: booleanAttribute });\n readonly adminActions = input<PortalHeaderAdminAction[]>([]);\n readonly navItems = input<PortalHeaderNavItem[]>([]);\n readonly userInitials = input.required<string>();\n\n readonly sessionClick = output<void>();\n\n /** Visibilidad del drawer de navegación mobile (bajo los 768px). */\n protected readonly mobileMenuOpen = signal(false);\n\n /** Cierra el drawer con Escape — mismo patrón que cualquier drawer/modal. */\n @HostListener('document:keydown.escape')\n protected onEscape(): void {\n this.mobileMenuOpen.set(false);\n }\n\n /**\n * `ElementRef` real del botón de sesión (el avatar en la esquina\n * derecha), no de todo el header. Pensado para anclar un `kf-dropdown`\n * externo — sin esto, el único `ElementRef` disponible desde afuera es el\n * del host de `PortalHeader`, que ocupa el ancho completo de la pantalla\n * (logo + nav + sesión), y el overlay del CDK termina \"pegado\" a la\n * esquina del header entero en vez de al botón que el usuario clickeó.\n *\n * <kf-dropdown [(open)]=\"menuOpen\" [anchor]=\"header().sessionButtonRef()\">\n */\n readonly sessionButtonRef = viewChild.required('sessionButton', { read: ElementRef });\n}\n","import { Component, input } from '@angular/core';\nimport { Icon } from '../icon/Icon';\n\n/**\n * Estado vacío de reservas en taller con llamada a agendar (página 36):\n * barra de estado vacío arriba (\"No tienes reservas de taller\"), panel de\n * invitación al medio (ícono en círculo azul, título, descripción, link) y\n * una fila de dos acciones al pie — un slot `[actions]` proyectado, para no\n * acoplar el componente a botones fijos.\n *\n * Distinto de `kf-empty-state` genérico: este combina la barra + la\n * invitación + las acciones como un bloque compuesto propio del dominio\n * \"taller\", no un placeholder de una sola pieza.\n *\n * <kf-reserve-block emptyLabel=\"No tienes reservas de taller\"\n * title=\"¿Necesitas mantención?\" description=\"Tenemos la mejor red de talleres.\"\n * actionLabel=\"Agenda tu reserva aquí\" actionHref=\"/taller/agendar\">\n * <kf-button actions icon=\"calendar\">Reservar hora</kf-button>\n * <kf-button actions variant=\"outline\" icon=\"list\">Ver agenda</kf-button>\n * </kf-reserve-block>\n */\n@Component({\n selector: 'kf-reserve-block',\n imports: [Icon],\n template: `\n <div class=\"kf-reserve-block__empty\">\n <kf-icon name=\"calendar\" size=\"sm\" />\n <span>{{ emptyLabel() }}</span>\n </div>\n <div class=\"kf-reserve-block__invite\">\n <span class=\"kf-reserve-block__invite-icon\">\n <kf-icon name=\"tool\" size=\"md\" />\n </span>\n <div class=\"kf-reserve-block__invite-text\">\n <span class=\"kf-reserve-block__invite-title\">{{ title() }}</span>\n @if (description()) {\n <span class=\"kf-reserve-block__invite-description\">{{ description() }}</span>\n }\n @if (actionLabel()) {\n <a class=\"kf-reserve-block__invite-action\" [href]=\"actionHref() || '#'\">\n {{ actionLabel() }}\n <kf-icon name=\"chevron-right\" size=\"sm\" />\n </a>\n }\n </div>\n </div>\n <div class=\"kf-reserve-block__actions\">\n <ng-content select=\"[actions]\" />\n </div>\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n background: var(--kf-color-white);\n font-family: var(--kf-font-body);\n }\n .kf-reserve-block__empty {\n display: flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding-bottom: var(--kf-space-sm);\n border-bottom: 1px solid var(--kf-color-border);\n color: var(--kf-color-text-muted);\n font-size: 0.875rem;\n }\n .kf-reserve-block__invite {\n display: flex;\n align-items: flex-start;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-sm);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-primary-soft);\n }\n .kf-reserve-block__invite-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n width: 2.25rem;\n height: 2.25rem;\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-primary);\n color: var(--kf-color-white);\n }\n .kf-reserve-block__invite-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n }\n .kf-reserve-block__invite-title {\n font-family: var(--kf-font-title);\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-reserve-block__invite-description {\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n }\n .kf-reserve-block__invite-action {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n margin-top: var(--kf-space-xs);\n font-size: 0.8125rem;\n font-weight: 600;\n color: var(--kf-color-primary);\n text-decoration: none;\n }\n .kf-reserve-block__invite-action:hover {\n text-decoration: underline;\n }\n .kf-reserve-block__actions {\n display: flex;\n flex-wrap: wrap;\n gap: var(--kf-space-sm);\n }\n `,\n})\nexport class ReserveBlock {\n readonly emptyLabel = input('No tienes reservas de taller');\n readonly title = input.required<string>();\n readonly description = input<string>();\n readonly actionLabel = input<string>();\n readonly actionHref = input<string>();\n}\n","import { booleanAttribute, Component, computed, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Título de sub-sección con chip de ícono, pensado para anidarse dentro de\n * cards o paneles (a diferencia de `PageHeader`, que encabeza una página\n * completa). Un área de acciones opcional se proyecta vía\n * `<ng-content select=\"[actions]\">` para no acoplar el componente a un set\n * fijo de botones.\n *\n * `size` sigue la misma escala `'sm'|'md'|'lg'` que `Button`/`Icon`/`Spinner`\n * (`md` es el default): `sm` reduce tipografía y espaciado para usarse\n * dentro de cards ya compactas, `lg` los agranda para encabezar un bloque\n * más prominente. Antes de la `0.2.0`, `size` solo aceptaba `'sm'` —\n * placeholder incompleto de esta misma escala; los valores de `lg` son una\n * extrapolación proporcional de la escala existente (sin un caso de uso\n * real todavía que los valide, a diferencia de `sm`, que sí viene de un\n * patrón real de uso dentro de cards). `solid` rellena el chip de ícono con\n * el color primario sólido en vez del tratamiento \"soft\" (fondo tenue) —\n * pensado para superficies que ya tienen un tinte de color propio, donde el\n * chip \"soft\" perdería contraste.\n *\n * <kf-section-header icon=\"settings\" title=\"Preferencias\"\n * subtitle=\"Configuración general de la cuenta\">\n * <button actions>Editar</button>\n * </kf-section-header>\n *\n * <kf-section-header title=\"Detalle\" size=\"sm\" [solid]=\"true\" />\n * <kf-section-header title=\"Resumen de flota\" size=\"lg\" />\n */\n@Component({\n selector: 'kf-section-header',\n imports: [Icon],\n template: `\n @if (icon(); as iconName) {\n <span class=\"kf-section-header__icon\" [class.kf-section-header__icon--solid]=\"solid()\">\n <kf-icon [name]=\"iconName\" [size]=\"iconSize()\" />\n </span>\n }\n\n <span class=\"kf-section-header__text\">\n <span class=\"kf-section-header__title\">{{ title() }}</span>\n @if (subtitle()) {\n <span class=\"kf-section-header__subtitle\">{{ subtitle() }}</span>\n }\n </span>\n\n <span class=\"kf-section-header__actions\">\n <ng-content select=\"[actions]\" />\n </span>\n `,\n styles: `\n :host {\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n font-family: var(--kf-font-body);\n }\n :host(.kf-section-header--sm) {\n gap: var(--kf-space-xs);\n }\n :host(.kf-section-header--lg) {\n gap: var(--kf-space-md);\n }\n .kf-section-header__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n inline-size: 2.5rem;\n block-size: 2.5rem;\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-primary-soft);\n color: var(--kf-color-primary);\n }\n :host(.kf-section-header--sm) .kf-section-header__icon {\n inline-size: 1.75rem;\n block-size: 1.75rem;\n border-radius: var(--kf-radius-xs);\n }\n :host(.kf-section-header--lg) .kf-section-header__icon {\n inline-size: 3.25rem;\n block-size: 3.25rem;\n border-radius: var(--kf-radius-md);\n }\n .kf-section-header__icon--solid {\n background: var(--kf-color-primary);\n color: var(--kf-color-white);\n }\n .kf-section-header__text {\n display: flex;\n flex-direction: column;\n min-width: 0;\n flex: 1 1 auto;\n }\n .kf-section-header__title {\n font-family: var(--kf-font-title);\n font-size: 1rem;\n font-weight: 700;\n color: var(--kf-color-ink);\n line-height: 1.3;\n }\n :host(.kf-section-header--sm) .kf-section-header__title {\n font-size: 0.875rem;\n }\n :host(.kf-section-header--lg) .kf-section-header__title {\n font-size: 1.25rem;\n }\n .kf-section-header__subtitle {\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n line-height: 1.3;\n }\n :host(.kf-section-header--sm) .kf-section-header__subtitle {\n font-size: 0.75rem;\n }\n :host(.kf-section-header--lg) .kf-section-header__subtitle {\n font-size: 0.9375rem;\n }\n .kf-section-header__actions {\n flex: none;\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n }\n `,\n host: {\n '[class.kf-section-header--sm]': \"size() === 'sm'\",\n '[class.kf-section-header--lg]': \"size() === 'lg'\",\n },\n})\nexport class SectionHeader {\n readonly icon = input<IconName>();\n readonly title = input.required<string>();\n readonly subtitle = input<string>();\n readonly size = input<'sm' | 'md' | 'lg'>('md');\n readonly solid = input(false, { transform: booleanAttribute });\n\n protected readonly iconSize = computed(() => {\n if (this.size() === 'sm') {\n return 'sm';\n }\n if (this.size() === 'lg') {\n return 'lg';\n }\n return 'md';\n });\n}\n","import { Component, computed, input, output } from '@angular/core';\n\nexport interface SegmentedOption {\n value: string;\n label: string;\n}\n\n/**\n * Control de segmentos relleno, tipo \"iOS segmented control\": 2-3 opciones\n * con un thumb que se desliza detrás de la opción activa.\n *\n * La posición del thumb se resuelve con una variable CSS (--kf-segmented-index)\n * y `transform: translateX()`, así la transición queda a cargo de CSS puro\n * (mismo criterio que Tabs), sin medir el DOM desde TypeScript.\n *\n * <kf-segmented [options]=\"options\" [value]=\"value\" (valueChange)=\"onChange($event)\" />\n */\n@Component({\n selector: 'kf-segmented',\n template: `\n <div class=\"kf-segmented__track\" [style.--kf-segmented-count]=\"options().length\">\n <div\n class=\"kf-segmented__thumb\"\n [style.--kf-segmented-index]=\"selectedIndex()\"\n [style.visibility]=\"selectedIndex() === -1 ? 'hidden' : 'visible'\"\n ></div>\n @for (option of options(); track option.value) {\n <button\n type=\"button\"\n class=\"kf-segmented__option\"\n [class.kf-segmented__option--active]=\"option.value === value()\"\n [attr.aria-pressed]=\"option.value === value()\"\n (click)=\"select(option.value)\"\n >\n {{ option.label }}\n </button>\n }\n </div>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-segmented__track {\n position: relative;\n display: grid;\n grid-template-columns: repeat(var(--kf-segmented-count), 1fr);\n gap: 2px;\n padding: 2px;\n background: var(--kf-color-surface);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n }\n .kf-segmented__thumb {\n position: absolute;\n top: 2px;\n left: 2px;\n width: calc((100% - 4px) / var(--kf-segmented-count));\n height: calc(100% - 4px);\n background: var(--kf-color-white);\n border-radius: var(--kf-radius-sm);\n box-shadow: var(--kf-shadow-xs);\n transform: translateX(calc(var(--kf-segmented-index, 0) * 100%));\n transition: transform 0.2s ease;\n }\n .kf-segmented__option {\n position: relative;\n z-index: 1;\n font: inherit;\n padding: var(--kf-space-xs) var(--kf-space-md);\n border: none;\n background: transparent;\n color: var(--kf-color-text-muted);\n border-radius: var(--kf-radius-sm);\n cursor: pointer;\n transition: color 0.14s;\n }\n .kf-segmented__option:hover:not(.kf-segmented__option--active) {\n color: var(--kf-color-text);\n }\n .kf-segmented__option--active {\n color: var(--kf-color-ink);\n }\n .kf-segmented__option:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n `,\n})\nexport class Segmented {\n readonly options = input.required<SegmentedOption[]>();\n readonly value = input.required<string>();\n readonly valueChange = output<string>();\n\n /** Índice de la opción activa; -1 si `value` no matchea ninguna opción. */\n readonly selectedIndex = computed(() =>\n this.options().findIndex((option) => option.value === this.value()),\n );\n\n select(nextValue: string): void {\n if (nextValue === this.value()) {\n return;\n }\n this.valueChange.emit(nextValue);\n }\n}\n","import { Component, booleanAttribute, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Indicador numérico compacto (página 34): label + valor grande, con un\n * ícono a la derecha del label — más chico y sin badge de esquina que\n * `kf-metric-card`, pensado para grillas densas de KPIs simples (\"Total\n * vehículos: 4\", \"En taller: 1\"), no para dashboards con tendencia.\n *\n * Con `cta` en vez de `value`, se convierte en la variante de llamada a la\n * acción: un bloque de fondo suave con título, descripción y un link — sin\n * número, para promover el siguiente paso (ej. \"¿Necesitas mantención?\").\n *\n * <kf-stat-tile label=\"Total vehículos\" value=\"4\" icon=\"car\" />\n * <kf-stat-tile cta title=\"¿Necesitas mantención?\"\n * description=\"Tenemos la mejor red de talleres.\"\n * actionLabel=\"Agenda aquí\" actionHref=\"/taller/agendar\" />\n */\n@Component({\n selector: 'kf-stat-tile',\n imports: [Icon],\n template: `\n @if (cta()) {\n <span class=\"kf-stat-tile__cta-title\">{{ title() }}</span>\n @if (description()) {\n <span class=\"kf-stat-tile__cta-description\">{{ description() }}</span>\n }\n @if (actionLabel()) {\n <a class=\"kf-stat-tile__cta-action\" [href]=\"actionHref() || '#'\">\n {{ actionLabel() }}\n <kf-icon name=\"chevron-right\" size=\"sm\" />\n </a>\n }\n } @else {\n <div class=\"kf-stat-tile__head\">\n <span class=\"kf-stat-tile__label\">{{ label() }}</span>\n @if (icon(); as iconName) {\n <span class=\"kf-stat-tile__icon\">\n <kf-icon [name]=\"iconName\" size=\"sm\" />\n </span>\n }\n </div>\n <span class=\"kf-stat-tile__value\">{{ value() }}</span>\n }\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-white);\n }\n :host(.kf-stat-tile--cta) {\n background: var(--kf-color-surface);\n gap: 2px;\n }\n .kf-stat-tile__head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-xs);\n }\n .kf-stat-tile__label {\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n }\n .kf-stat-tile__icon {\n display: inline-flex;\n color: var(--kf-color-primary);\n }\n .kf-stat-tile__value {\n font-family: var(--kf-font-title);\n font-size: 1.5rem;\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-stat-tile__cta-title {\n font-family: var(--kf-font-title);\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-stat-tile__cta-description {\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n }\n .kf-stat-tile__cta-action {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n margin-top: var(--kf-space-xs);\n font-size: 0.8125rem;\n font-weight: 600;\n color: var(--kf-color-primary);\n text-decoration: none;\n }\n .kf-stat-tile__cta-action:hover {\n text-decoration: underline;\n }\n `,\n host: {\n '[class.kf-stat-tile--cta]': 'cta()',\n },\n})\nexport class StatTile {\n readonly cta = input(false, { transform: booleanAttribute });\n // Variante numérica\n readonly label = input<string>();\n readonly value = input<string | number>();\n readonly icon = input<IconName>();\n // Variante CTA\n readonly title = input<string>();\n readonly description = input<string>();\n readonly actionLabel = input<string>();\n readonly actionHref = input<string>();\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\n\n/**\n * Pill con borde, en mayúsculas y con letter-spacing, pensada para indicadores\n * de estado únicos y prominentes (ej. \"ESTADO TÉCNICO\"). El fondo es siempre\n * transparente; el color de borde/texto/punto depende de `tone`.\n *\n * <kf-status-pill tone=\"ok\">Operativo</kf-status-pill>\n * <kf-status-pill tone=\"error\" dot>Fuera de servicio</kf-status-pill>\n */\n@Component({\n selector: 'kf-status-pill',\n template: `\n <span class=\"kf-status-pill\" [class]=\"'kf-status-pill--' + tone()\">\n @if (dot()) {\n <span class=\"kf-status-pill__dot\"></span>\n }\n <ng-content />\n </span>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-status-pill {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border: 1px solid currentColor;\n border-radius: var(--kf-radius-pill);\n background: transparent;\n font: inherit;\n font-size: 0.75rem;\n font-weight: 600;\n line-height: 1;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n white-space: nowrap;\n }\n .kf-status-pill__dot {\n width: 6px;\n height: 6px;\n border-radius: var(--kf-radius-pill);\n background: currentColor;\n flex-shrink: 0;\n }\n .kf-status-pill--blue {\n color: var(--kf-color-info);\n }\n .kf-status-pill--ok {\n color: var(--kf-color-success);\n }\n .kf-status-pill--warn {\n color: var(--kf-color-warning);\n }\n .kf-status-pill--error {\n color: var(--kf-color-error);\n }\n `,\n})\nexport class StatusPill {\n readonly tone = input<'blue' | 'ok' | 'warn' | 'error'>('blue');\n readonly dot = input(false, { transform: booleanAttribute });\n}\n","import {\n Component,\n DestroyRef,\n ElementRef,\n afterNextRender,\n afterRenderEffect,\n computed,\n inject,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\nexport interface TabOption {\n value: string;\n label: string;\n icon?: IconName;\n}\n\n/**\n * Barra de tabs subrayada: un único indicador se desliza horizontalmente hasta\n * la pestaña activa. Como las pestañas tienen ancho de contenido (labels de\n * largo distinto), la posición no se puede resolver con CSS puro: se mide el\n * `offsetLeft`/`offsetWidth` de la pestaña activa después de cada render y la\n * transición del `transform`/`width` queda a cargo de CSS.\n *\n * <kf-tabs [options]=\"tabs\" [value]=\"active\" (valueChange)=\"active = $event\" />\n */\n@Component({\n selector: 'kf-tabs',\n imports: [Icon],\n template: `\n <div class=\"kf-tabs\" role=\"tablist\" #track>\n @for (option of options(); track option.value) {\n <button\n type=\"button\"\n role=\"tab\"\n class=\"kf-tabs__tab\"\n [class.kf-tabs__tab--active]=\"option.value === value()\"\n [attr.aria-selected]=\"option.value === value()\"\n [attr.tabindex]=\"option.value === value() ? 0 : -1\"\n [id]=\"'kf-tab-' + option.value\"\n [attr.aria-controls]=\"'kf-tabpanel-' + option.value\"\n (click)=\"select(option.value)\"\n (keydown)=\"onKeydown($event, option.value)\"\n >\n @if (option.icon; as iconName) {\n <kf-icon class=\"kf-tabs__icon\" [name]=\"iconName\" size=\"sm\" />\n }\n <span class=\"kf-tabs__label\">{{ option.label }}</span>\n </button>\n }\n <span\n class=\"kf-tabs__indicator\"\n aria-hidden=\"true\"\n [style.transform]=\"indicatorTransform()\"\n [style.width.px]=\"indicatorWidth()\"\n [style.opacity]=\"indicatorWidth() ? 1 : 0\"\n ></span>\n </div>\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-tabs {\n position: relative;\n display: flex;\n align-items: stretch;\n gap: var(--kf-space-md);\n border-bottom: 1px solid var(--kf-color-border);\n }\n .kf-tabs__tab {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n font: inherit;\n font-size: 0.9rem;\n color: var(--kf-color-text-muted);\n background: transparent;\n border: none;\n /* Sin padding horizontal propio: el espaciado entre tabs lo da el\n gap del contenedor — con ambos sumando (como antes) el conjunto\n quedaba más separado que en el PDF, que muestra las pestañas casi\n pegadas entre sí. El padding vertical se mantiene por área de click. */\n padding: var(--kf-space-sm) 0;\n cursor: pointer;\n transition: color 0.14s;\n }\n .kf-tabs__tab:hover:not(.kf-tabs__tab--active) {\n color: var(--kf-color-text);\n }\n .kf-tabs__tab:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n border-radius: var(--kf-radius-xs);\n }\n .kf-tabs__tab--active {\n color: var(--kf-color-primary);\n font-size: 1rem;\n font-weight: 700;\n }\n .kf-tabs__indicator {\n position: absolute;\n bottom: -1px;\n left: 0;\n height: 2px;\n background: var(--kf-color-primary);\n border-radius: 2px 2px 0 0;\n pointer-events: none;\n transition:\n transform 0.28s cubic-bezier(0.32, 0.72, 0, 1),\n width 0.28s cubic-bezier(0.32, 0.72, 0, 1),\n opacity 0.14s;\n }\n @media (prefers-reduced-motion: reduce) {\n .kf-tabs__indicator {\n transition: opacity 0.14s;\n }\n }\n `,\n})\nexport class Tabs {\n readonly options = input.required<TabOption[]>();\n readonly value = input.required<string>();\n readonly valueChange = output<string>();\n\n private readonly track = viewChild.required<ElementRef<HTMLElement>>('track');\n private readonly destroyRef = inject(DestroyRef);\n\n /** Geometría de la pestaña activa; `null` mientras no haya una medición válida. */\n private readonly activeRect = signal<{ x: number; width: number } | null>(null);\n\n protected readonly indicatorTransform = computed(\n () => `translateX(${this.activeRect()?.x ?? 0}px)`,\n );\n protected readonly indicatorWidth = computed(() => this.activeRect()?.width ?? 0);\n\n constructor() {\n // Cada cambio de `value`/`options` re-mide después de que el DOM ya se actualizó.\n afterRenderEffect(() => {\n this.value();\n this.options();\n this.measure();\n });\n\n afterNextRender(() => {\n // El ancho de la pestaña activa cambia con el layout (resize, fuentes que\n // cargan tarde), y sin esto el indicador queda desfasado del texto.\n const observer = new ResizeObserver(() => this.measure());\n observer.observe(this.track().nativeElement);\n this.destroyRef.onDestroy(() => observer.disconnect());\n });\n }\n\n private measure(): void {\n const active = this.track().nativeElement.querySelector<HTMLElement>('.kf-tabs__tab--active');\n this.activeRect.set(active ? { x: active.offsetLeft, width: active.offsetWidth } : null);\n }\n\n select(value: string): void {\n if (value === this.value()) {\n return;\n }\n this.valueChange.emit(value);\n }\n\n /** Navegación estándar de ARIA tabs: flechas mueven el foco y activan la pestaña. */\n onKeydown(event: KeyboardEvent, currentValue: string): void {\n const items = this.options();\n const currentIndex = items.findIndex((option) => option.value === currentValue);\n\n let nextIndex: number;\n switch (event.key) {\n case 'ArrowRight':\n nextIndex = (currentIndex + 1) % items.length;\n break;\n case 'ArrowLeft':\n nextIndex = (currentIndex - 1 + items.length) % items.length;\n break;\n case 'Home':\n nextIndex = 0;\n break;\n case 'End':\n nextIndex = items.length - 1;\n break;\n default:\n return;\n }\n\n event.preventDefault();\n const nextOption = items[nextIndex];\n this.select(nextOption.value);\n\n const host = (event.currentTarget as HTMLElement).parentElement;\n const nextId = `kf-tab-${nextOption.value}`;\n const nextButton = Array.from(host?.querySelectorAll<HTMLButtonElement>('button') ?? []).find(\n (button) => button.id === nextId,\n );\n nextButton?.focus();\n }\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport { Component, computed, input } from '@angular/core';\n\nexport type TextAs = 'h1' | 'h2' | 'h3' | 'p' | 'span';\nexport type TextVariant = 'title-lg' | 'title-md' | 'title-sm' | 'body' | 'body-muted' | 'caption';\nexport type TextTone = 'neutral' | 'ok' | 'warn' | 'error' | 'info';\n\n/**\n * Tipografía unificada — separa la etiqueta semántica (`as`, qué es el\n * texto para el DOM/accesibilidad) del estilo visual (`variant`, cómo se\n * ve). Antes de este componente, cada pantalla que consume la librería\n * definía su propio `h1`/`p` con `font-size` suelto para el mismo rol\n * (título de página, subtítulo, texto secundario) — auditoría sobre\n * `web-portal-latam-frontend` encontró 9 tamaños distintos entre login y\n * home sin ningún paso de escala en común. `variant` resuelve eso contra\n * la escala de `tokens/base.css` (`--kf-font-size-*`).\n *\n * `tone` sigue la misma convención cerrada que `Alert`/`Badge`/`Chip`: sin\n * escape hatch de color libre. Si un caso necesita un color que `tone` no\n * cubre, es una discusión de design system, no una prop nueva acá.\n *\n * <kf-text as=\"h1\" variant=\"title-lg\">Bienvenido de nuevo</kf-text>\n * <kf-text as=\"p\" variant=\"body-muted\">Ingresá con tu cuenta corporativa.</kf-text>\n * <kf-text as=\"span\" variant=\"caption\" tone=\"error\">Campo obligatorio</kf-text>\n */\n@Component({\n selector: 'kf-text',\n imports: [NgTemplateOutlet],\n template: `\n <!--\n Una sola proyección compartida (ng-template + ngTemplateOutlet) en vez\n de un <ng-content> por cada rama del @switch: Angular solo conecta la\n proyección real del consumidor a la PRIMERA instancia de <ng-content>\n que encuentra en el árbol de compilación — con un <ng-content> por\n rama, todas menos una quedan vacías en runtime (bug detectado por\n Text.spec.ts, no algo documentado a simple vista en los docs de Angular).\n -->\n <ng-template #projected><ng-content /></ng-template>\n @switch (tag()) {\n @case ('h1') {\n <h1 [class]=\"hostClass()\"><ng-container [ngTemplateOutlet]=\"projected\" /></h1>\n }\n @case ('h2') {\n <h2 [class]=\"hostClass()\"><ng-container [ngTemplateOutlet]=\"projected\" /></h2>\n }\n @case ('h3') {\n <h3 [class]=\"hostClass()\"><ng-container [ngTemplateOutlet]=\"projected\" /></h3>\n }\n @case ('span') {\n <span [class]=\"hostClass()\"><ng-container [ngTemplateOutlet]=\"projected\" /></span>\n }\n @default {\n <p [class]=\"hostClass()\"><ng-container [ngTemplateOutlet]=\"projected\" /></p>\n }\n }\n `,\n styles: `\n :host {\n display: contents;\n }\n h1,\n h2,\n h3,\n p,\n span {\n margin: 0;\n font-family: var(--kf-font-body);\n color: var(--kf-color-text);\n }\n\n /* Variant — tamaño y peso, independiente de la etiqueta semántica. */\n .kf-text--title-lg {\n font-family: var(--kf-font-title);\n font-size: var(--kf-font-size-title-lg);\n font-weight: var(--kf-font-weight-title);\n color: var(--kf-color-ink);\n }\n .kf-text--title-md {\n font-family: var(--kf-font-title);\n font-size: var(--kf-font-size-title-md);\n font-weight: var(--kf-font-weight-title);\n color: var(--kf-color-ink);\n }\n .kf-text--title-sm {\n font-family: var(--kf-font-title);\n font-size: var(--kf-font-size-title-sm);\n font-weight: var(--kf-font-weight-title);\n color: var(--kf-color-ink);\n }\n .kf-text--body {\n font-size: var(--kf-font-size-body);\n font-weight: var(--kf-font-weight-body);\n }\n .kf-text--body-muted {\n font-size: var(--kf-font-size-body);\n font-weight: var(--kf-font-weight-body);\n color: var(--kf-color-text-muted);\n }\n .kf-text--caption {\n font-size: var(--kf-font-size-caption);\n font-weight: var(--kf-font-weight-body);\n color: var(--kf-color-text-muted);\n }\n\n /* Tone — semántica de color, se superpone al color del variant. */\n .kf-text--ok {\n color: var(--kf-color-success-strong);\n }\n .kf-text--warn {\n color: var(--kf-color-warning-strong);\n }\n .kf-text--error {\n color: var(--kf-color-error-strong);\n }\n .kf-text--info {\n color: var(--kf-color-info-strong);\n }\n `,\n})\nexport class Text {\n /** Etiqueta semántica real que se renderiza — nunca es solo un `div`. */\n readonly as = input<TextAs>('p');\n readonly variant = input<TextVariant>('body');\n readonly tone = input<TextTone>('neutral');\n\n /**\n * Copia de `as` para uso dentro del template: `as` es palabra reservada\n * en las expresiones de Angular (`@if (x; as y)`), así que `@switch (as())`\n * no parsea — NG5002. La prop pública sigue llamándose `as` (es solo un\n * atributo HTML ahí, `<kf-text as=\"h1\">`, no una expresión).\n */\n protected readonly tag = computed(() => this.as());\n\n protected hostClass(): string {\n const classes = [`kf-text--${this.variant()}`];\n if (this.tone() !== 'neutral') {\n classes.push(`kf-text--${this.tone()}`);\n }\n return classes.join(' ');\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n Injectable,\n computed,\n inject,\n signal,\n} from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Visual tone of a toast. Maps to the state tokens in\n * projects/ui/src/tokens/base.css. `loading` has no auto-dismiss and shows an\n * indeterminate bar instead of a countdown — pair it with\n * {@link ToastService.promise}. It reuses the `info` tokens, the closest\n * semantic role to \"work in progress\".\n */\nexport type ToastTone = 'success' | 'error' | 'warning' | 'info' | 'loading';\n\n/** Fixed icon per tone (page 20 of the design system) — not configurable per call. */\nconst TOAST_ICON: Record<ToastTone, IconName> = {\n success: 'check-circle',\n error: 'alert-circle',\n warning: 'alert-triangle',\n info: 'bell',\n loading: 'bell',\n};\n\n/** Options for {@link ToastService.show}. */\nexport interface ToastOptions {\n /** Color tone. Defaults to `'info'`. */\n tone?: ToastTone;\n /** Milliseconds before auto-dismiss. Ignored when `tone` is `'loading'`. Defaults to `2800`. */\n duration?: number;\n}\n\n/** Messages for each leg of {@link ToastService.promise}. */\nexport interface ToastPromiseMessages<T = unknown> {\n loading?: string;\n success?: string | ((value: T) => string);\n error?: string | ((error: unknown) => string);\n}\n\n/** The single active toast, as rendered by `kf-toast-host`. */\nexport interface ToastState {\n id: number;\n message: string;\n tone: ToastTone;\n duration: number;\n leaving: boolean;\n}\n\nconst DEFAULT_DURATION_MS = 2800;\nconst EXIT_ANIMATION_MS = 200;\n\n/**\n * Shows one toast at a time — a new `show()` call replaces whatever is\n * currently up (this mirrors a global status line, not a notification stack).\n *\n * Angular has no global function that can mount UI on its own, so the\n * imperative `showToast(...)` of the reference design system becomes a\n * root-provided service holding signal state: `ToastService.show(...)` sets\n * the active toast and `ToastHost` (standalone, mounted once in the app\n * shell) renders it.\n *\n * @example\n * ```ts\n * // app.ts\n * imports: [ToastHost]\n * template: `<kf-toast-host />`\n *\n * // anywhere else\n * private readonly toast = inject(ToastService);\n * this.toast.show('Vehículo guardado', { tone: 'success' });\n *\n * // chains a `loading` toast into the promise's outcome:\n * this.toast.promise(this.api.save(vehicle), {\n * loading: 'Guardando…',\n * success: 'Vehículo guardado',\n * error: 'No se pudo guardar',\n * });\n * ```\n */\n@Injectable({ providedIn: 'root' })\nexport class ToastService {\n private readonly _current = signal<ToastState | null>(null);\n private nextId = 0;\n private dismissTimer?: ReturnType<typeof setTimeout>;\n private removeTimer?: ReturnType<typeof setTimeout>;\n\n /** The single active toast, or `null`. */\n readonly current = this._current.asReadonly();\n\n /** Shows a toast, replacing whatever is currently shown. Returns its id. */\n show(message: string, options: ToastOptions = {}): number {\n const id = this.nextId++;\n const tone = options.tone ?? 'info';\n const duration = options.duration ?? DEFAULT_DURATION_MS;\n clearTimeout(this.dismissTimer);\n clearTimeout(this.removeTimer);\n this._current.set({ id, message, tone, duration, leaving: false });\n if (tone !== 'loading') {\n this.dismissTimer = setTimeout(() => this.dismiss(id), duration);\n }\n return id;\n }\n\n /**\n * Starts the exit animation, then removes the toast. No-op when `id` is no\n * longer the active toast, so a stale timer never kills a newer toast.\n */\n dismiss(id?: number): void {\n const toast = this._current();\n if (!toast || toast.leaving || (id !== undefined && toast.id !== id)) return;\n clearTimeout(this.dismissTimer);\n this._current.set({ ...toast, leaving: true });\n this.removeTimer = setTimeout(() => {\n if (this._current()?.id === toast.id) this._current.set(null);\n }, EXIT_ANIMATION_MS);\n }\n\n /**\n * Shows a `loading` toast, then swaps it for a `success`/`error` toast once\n * `work` settles. Re-throws `work`'s rejection so callers can still react to\n * the failure.\n */\n promise<T>(work: Promise<T>, messages: ToastPromiseMessages<T> = {}): Promise<T> {\n this.show(messages.loading ?? 'Procesando…', { tone: 'loading' });\n return work.then(\n (value) => {\n const msg = messages.success ?? 'Listo';\n this.show(typeof msg === 'function' ? msg(value) : msg, { tone: 'success' });\n return value;\n },\n (error) => {\n const msg = messages.error ?? 'Ocurrió un error';\n this.show(typeof msg === 'function' ? msg(error) : msg, { tone: 'error' });\n throw error;\n },\n );\n }\n}\n\n/**\n * Renders whatever `ToastService` currently holds, fixed bottom-right. Mount\n * one instance in the app shell (e.g. next to the router outlet); it takes no\n * inputs and re-renders itself from the service state.\n *\n * <kf-toast-host />\n */\n@Component({\n selector: 'kf-toast-host',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [Icon],\n template: `\n @for (t of toastList(); track t.id) {\n <div\n class=\"kf-toast kf-toast--{{ t.tone }}\"\n [class.kf-toast--leaving]=\"t.leaving\"\n role=\"status\"\n [attr.aria-live]=\"t.tone === 'error' ? 'assertive' : 'polite'\"\n >\n <kf-icon class=\"kf-toast__icon\" [name]=\"toastIcon(t.tone)\" size=\"sm\" />\n <span class=\"kf-toast__message\">{{ t.message }}</span>\n <button type=\"button\" class=\"kf-toast__dismiss\" aria-label=\"Cerrar\" (click)=\"dismiss(t.id)\">\n <kf-icon name=\"x\" size=\"sm\" />\n </button>\n <span class=\"kf-toast__bar\" [style.--kf-toast-dur]=\"t.duration + 'ms'\"></span>\n </div>\n }\n `,\n styles: `\n @keyframes kf-toast-in {\n from {\n transform: translateY(20px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n }\n @keyframes kf-toast-bar {\n from {\n transform: scaleX(1);\n }\n to {\n transform: scaleX(0);\n }\n }\n @keyframes kf-toast-indeterminate {\n 0% {\n left: -40%;\n width: 40%;\n }\n 50% {\n left: 30%;\n width: 55%;\n }\n 100% {\n left: 100%;\n width: 40%;\n }\n }\n\n .kf-toast {\n /* Per-tone accent, overridden by the tone classes below. */\n --kf-toast-accent: var(--kf-color-info);\n\n position: fixed;\n inset-block-end: var(--kf-space-lg);\n inset-inline-end: var(--kf-space-lg);\n z-index: 1100;\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n max-inline-size: 360px;\n padding: var(--kf-space-sm) var(--kf-space-sm) var(--kf-space-sm) var(--kf-space-md);\n border-radius: var(--kf-radius-md);\n border-left: 4px solid var(--kf-toast-accent);\n background: var(--kf-color-ink);\n color: var(--kf-color-white);\n box-shadow: var(--kf-shadow-lg);\n font-family: var(--kf-font-body);\n font-size: 0.875rem;\n font-weight: 600;\n line-height: 1.4;\n overflow: hidden;\n animation: kf-toast-in 0.25s ease forwards;\n transition:\n transform 0.2s ease,\n opacity 0.2s ease;\n }\n .kf-toast--leaving {\n transform: translateY(20px);\n opacity: 0;\n }\n .kf-toast--success {\n --kf-toast-accent: var(--kf-color-success);\n }\n .kf-toast--error {\n --kf-toast-accent: var(--kf-color-error);\n }\n .kf-toast--warning {\n --kf-toast-accent: var(--kf-color-warning);\n }\n .kf-toast--info,\n .kf-toast--loading {\n --kf-toast-accent: var(--kf-color-info);\n }\n\n .kf-toast__icon {\n flex: none;\n color: var(--kf-toast-accent);\n }\n .kf-toast__message {\n flex: 1;\n }\n .kf-toast__dismiss {\n flex: none;\n display: grid;\n place-items: center;\n inline-size: 24px;\n block-size: 24px;\n padding: 0;\n border: none;\n border-radius: var(--kf-radius-xs);\n background: transparent;\n color: inherit;\n font: inherit;\n line-height: 1;\n cursor: pointer;\n opacity: 0.6;\n }\n .kf-toast__dismiss:hover {\n opacity: 1;\n }\n\n .kf-toast__bar {\n position: absolute;\n inset-block-end: 0;\n left: 0;\n block-size: 3px;\n inline-size: 100%;\n background: var(--kf-toast-accent);\n opacity: 0.7;\n transform-origin: left;\n animation: kf-toast-bar var(--kf-toast-dur, 2800ms) linear forwards;\n }\n .kf-toast--loading .kf-toast__bar {\n left: -40%;\n inline-size: 40%;\n opacity: 0.6;\n animation: kf-toast-indeterminate 1.4s ease-in-out infinite;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .kf-toast,\n .kf-toast__bar,\n .kf-toast--loading .kf-toast__bar {\n animation: none;\n }\n .kf-toast {\n transition: none;\n }\n }\n `,\n})\nexport class ToastHost {\n private readonly toastService = inject(ToastService);\n\n /** 0-or-1 wrapper so `@for track t.id` remounts the node on every new toast, restarting its animations. */\n protected readonly toastList = computed<ToastState[]>(() => {\n const toast = this.toastService.current();\n return toast ? [toast] : [];\n });\n\n protected toastIcon(tone: ToastTone): IconName {\n return TOAST_ICON[tone];\n }\n\n protected dismiss(id: number): void {\n this.toastService.dismiss(id);\n }\n}\n","import { Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Estado puntual mostrado junto a la identidad del vehículo (ej. \"En ruta\",\n * \"Mantenimiento\", \"Fuera de servicio\"). `tone` define el color semántico:\n * \"crit\" no tiene token propio en base.css, se mapea a var(--kf-color-error).\n */\nexport interface VehicleHeaderStatus {\n label: string;\n tone?: 'ok' | 'warn' | 'crit';\n icon?: IconName;\n}\n\n/**\n * Header de identidad de un vehículo de flota: unidad (patente/id), modelo\n * (como badge, no texto plano — página 24: \"ABC-123\" junto a un badge\n * \"TITAN 4X2\"), VIN en fuente mono y un estado opcional. Un área de acciones\n * opcional se proyecta vía `<ng-content select=\"[actions]\">` para no acoplar\n * el componente a un set fijo de botones — el patrón real de la spec es\n * `kf-button variant=\"outline\"` (ej. \"Llamar\", con ícono) + un `primary`\n * (ej. \"Crear Ticket\", con ícono \"+\"):\n *\n * <kf-vehicle-header unit=\"AB123CD\" model=\"Sprinter 415\" vin=\"9BW...\"\n * [status]=\"{ label: 'En ruta', tone: 'ok' }\">\n * <kf-button actions variant=\"outline\" icon=\"phone\">Llamar</kf-button>\n * <kf-button actions icon=\"plus\">Crear Ticket</kf-button>\n * </kf-vehicle-header>\n */\n@Component({\n selector: 'kf-vehicle-header',\n imports: [Icon],\n template: `\n <div class=\"kf-vehicle-header__identity\">\n <span class=\"kf-vehicle-header__unit\">{{ unit() }}</span>\n @if (model()) {\n <span class=\"kf-vehicle-header__model\">{{ model() }}</span>\n }\n @if (vin()) {\n <span class=\"kf-vehicle-header__vin\">VIN: {{ vin() }}</span>\n }\n </div>\n\n @if (status(); as currentStatus) {\n <span\n class=\"kf-vehicle-header__status\"\n [class]=\"'kf-vehicle-header__status--' + (currentStatus.tone ?? 'ok')\"\n >\n @if (currentStatus.icon; as iconName) {\n <kf-icon [name]=\"iconName\" size=\"sm\" />\n }\n {{ currentStatus.label }}\n </span>\n }\n\n <div class=\"kf-vehicle-header__actions\">\n <ng-content select=\"[actions]\" />\n </div>\n `,\n styles: `\n :host {\n display: flex;\n align-items: center;\n gap: var(--kf-space-md);\n padding: var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n background: var(--kf-color-surface);\n font-family: var(--kf-font-body);\n }\n .kf-vehicle-header__identity {\n display: flex;\n align-items: baseline;\n flex-wrap: wrap;\n gap: var(--kf-space-sm);\n flex: 1 1 auto;\n min-width: 0;\n }\n .kf-vehicle-header__unit {\n font-family: var(--kf-font-title);\n font-size: 1.125rem;\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-vehicle-header__model {\n padding: 2px var(--kf-space-sm);\n border-radius: var(--kf-radius-xs);\n background: var(--kf-color-border);\n color: var(--kf-color-text-muted);\n font-size: 0.75rem;\n font-weight: 700;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n }\n .kf-vehicle-header__vin {\n font-family: var(--kf-font-mono);\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n }\n .kf-vehicle-header__status {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border-radius: var(--kf-radius-pill);\n font-size: 0.75rem;\n font-weight: 600;\n line-height: 1;\n white-space: nowrap;\n }\n .kf-vehicle-header__status--ok {\n background: var(--kf-color-success-soft);\n color: var(--kf-color-success);\n }\n .kf-vehicle-header__status--warn {\n background: var(--kf-color-warning-soft);\n color: var(--kf-color-warning);\n }\n .kf-vehicle-header__status--crit {\n background: var(--kf-color-error-soft);\n color: var(--kf-color-error);\n }\n .kf-vehicle-header__actions {\n flex: none;\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n }\n `,\n})\nexport class VehicleHeader {\n readonly unit = input.required<string>();\n readonly model = input<string>();\n readonly vin = input<string>();\n readonly status = input<VehicleHeaderStatus>();\n}\n","import { Component, input, output } from '@angular/core';\n\nexport type ViewToggleOption = 'table' | 'cards';\n\n/**\n * Switch de dos posiciones para alternar entre vista de tabla y vista de\n * tarjetas. Pensado para usarse dentro de DataTable, pero es standalone e\n * independiente: no asume nada sobre el componente que lo contiene.\n *\n * Se implementa como un grupo de radio (role=\"radiogroup\") en vez de dos\n * botones sueltos: semánticamente es una única selección excluyente entre\n * dos estados, no dos acciones independientes. Esto también habilita\n * navegación con flechas izquierda/derecha, igual que un <input type=\"radio\">\n * nativo agrupado.\n *\n * <kf-view-toggle [view]=\"view\" (viewChange)=\"view = $event\" />\n */\n@Component({\n selector: 'kf-view-toggle',\n template: `\n <div class=\"kf-view-toggle\" role=\"radiogroup\" aria-label=\"Alternar tipo de vista\">\n <button\n type=\"button\"\n role=\"radio\"\n class=\"kf-view-toggle__option\"\n [class.kf-view-toggle__option--active]=\"view() === 'table'\"\n [attr.aria-checked]=\"view() === 'table'\"\n [attr.tabindex]=\"view() === 'table' ? 0 : -1\"\n (click)=\"select('table')\"\n (keydown)=\"onKeydown($event)\"\n >\n Tabla\n </button>\n <button\n type=\"button\"\n role=\"radio\"\n class=\"kf-view-toggle__option\"\n [class.kf-view-toggle__option--active]=\"view() === 'cards'\"\n [attr.aria-checked]=\"view() === 'cards'\"\n [attr.tabindex]=\"view() === 'cards' ? 0 : -1\"\n (click)=\"select('cards')\"\n (keydown)=\"onKeydown($event)\"\n >\n Tarjetas\n </button>\n </div>\n `,\n styles: `\n :host {\n display: inline-block;\n font-family: var(--kf-font-body);\n }\n .kf-view-toggle {\n display: inline-flex;\n align-items: stretch;\n gap: 2px;\n padding: 2px;\n background: var(--kf-color-surface);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n }\n .kf-view-toggle__option {\n font: inherit;\n font-size: 0.85rem;\n line-height: 1;\n color: var(--kf-color-text-muted);\n background: transparent;\n border: none;\n border-radius: var(--kf-radius-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n cursor: pointer;\n transition:\n background 0.14s,\n color 0.14s,\n box-shadow 0.14s;\n }\n .kf-view-toggle__option:hover:not(.kf-view-toggle__option--active) {\n color: var(--kf-color-text);\n }\n .kf-view-toggle__option:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-view-toggle__option--active {\n color: var(--kf-color-ink);\n background: var(--kf-color-white);\n box-shadow: var(--kf-shadow-xs);\n }\n `,\n})\nexport class ViewToggle {\n readonly view = input.required<ViewToggleOption>();\n readonly viewChange = output<ViewToggleOption>();\n\n select(next: ViewToggleOption): void {\n if (next === this.view()) {\n return;\n }\n this.viewChange.emit(next);\n }\n\n /** Navegación estándar de ARIA radiogroup: flechas mueven foco y seleccionan. */\n onKeydown(event: KeyboardEvent): void {\n if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight') {\n return;\n }\n\n event.preventDefault();\n const next: ViewToggleOption = this.view() === 'table' ? 'cards' : 'table';\n this.select(next);\n\n const current = event.currentTarget as HTMLElement;\n const buttons =\n current.parentElement?.querySelectorAll<HTMLButtonElement>('.kf-view-toggle__option');\n const nextButton = Array.from(buttons ?? []).find((button) => button !== current);\n nextButton?.focus();\n }\n}\n","/*\n * Public API Surface of ui\n */\n\nexport * from './lib/action-tile/ActionTile';\nexport * from './lib/admin-badge/AdminBadge';\nexport * from './lib/button/button';\nexport * from './lib/alert/Alert';\nexport * from './lib/avatar/Avatar';\nexport * from './lib/badge/Badge';\nexport * from './lib/breadcrumb/Breadcrumb';\nexport * from './lib/card/Card';\nexport * from './lib/carousel/Carousel';\nexport * from './lib/checkbox/Checkbox';\nexport * from './lib/chip/Chip';\nexport * from './lib/company-selector/CompanySelector';\nexport * from './lib/content-slot/ContentSlot';\nexport * from './lib/content-state/ContentState';\nexport * from './lib/data-table/DataTable';\nexport * from './lib/divider/Divider';\nexport * from './lib/dropdown/Dropdown';\nexport * from './lib/empty-state/EmptyState';\nexport * from './lib/feature-card/FeatureCard';\nexport * from './lib/field/Field';\nexport * from './lib/field-label/FieldLabel';\nexport * from './lib/filter-chips/FilterChips';\nexport * from './lib/folder-tabs/FolderTabs';\nexport * from './lib/icon/Icon';\nexport * from './lib/input/Input';\nexport * from './lib/link/Link';\nexport * from './lib/metric-card/MetricCard';\nexport * from './lib/modal/Modal';\nexport * from './lib/multi-select/MultiSelect';\nexport * from './lib/page-header/PageHeader';\nexport * from './lib/pagination/Pagination';\nexport * from './lib/panel/Panel';\nexport * from './lib/portal-header/PortalHeader';\nexport * from './lib/reserve-block/ReserveBlock';\nexport * from './lib/section-header/SectionHeader';\nexport * from './lib/segmented/Segmented';\nexport * from './lib/select/Select';\nexport * from './lib/skeleton/Skeleton';\nexport * from './lib/spinner/Spinner';\nexport * from './lib/stat-tile/StatTile';\nexport * from './lib/status-pill/StatusPill';\nexport * from './lib/tabs/Tabs';\nexport * from './lib/text/Text';\nexport * from './lib/toast/Toast';\nexport * from './lib/vehicle-header/VehicleHeader';\nexport * from './lib/view-toggle/ViewToggle';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["nextId"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"kaufmann-lab-ui.mjs","sources":["../../../projects/ui/src/lib/icon/icons/activity.ts","../../../projects/ui/src/lib/icon/icons/alert-circle.ts","../../../projects/ui/src/lib/icon/icons/alert-octagon.ts","../../../projects/ui/src/lib/icon/icons/alert-triangle.ts","../../../projects/ui/src/lib/icon/icons/award.ts","../../../projects/ui/src/lib/icon/icons/bar-chart.ts","../../../projects/ui/src/lib/icon/icons/bell.ts","../../../projects/ui/src/lib/icon/icons/bus.ts","../../../projects/ui/src/lib/icon/icons/calculator.ts","../../../projects/ui/src/lib/icon/icons/calendar.ts","../../../projects/ui/src/lib/icon/icons/car.ts","../../../projects/ui/src/lib/icon/icons/cart.ts","../../../projects/ui/src/lib/icon/icons/check.ts","../../../projects/ui/src/lib/icon/icons/check-circle.ts","../../../projects/ui/src/lib/icon/icons/check-square.ts","../../../projects/ui/src/lib/icon/icons/chevron-down.ts","../../../projects/ui/src/lib/icon/icons/chevron-left.ts","../../../projects/ui/src/lib/icon/icons/chevron-left-bar.ts","../../../projects/ui/src/lib/icon/icons/chevron-right.ts","../../../projects/ui/src/lib/icon/icons/clipboard.ts","../../../projects/ui/src/lib/icon/icons/clock.ts","../../../projects/ui/src/lib/icon/icons/credit-card.ts","../../../projects/ui/src/lib/icon/icons/download.ts","../../../projects/ui/src/lib/icon/icons/edit.ts","../../../projects/ui/src/lib/icon/icons/external-link.ts","../../../projects/ui/src/lib/icon/icons/eye.ts","../../../projects/ui/src/lib/icon/icons/eye-off.ts","../../../projects/ui/src/lib/icon/icons/file.ts","../../../projects/ui/src/lib/icon/icons/filter.ts","../../../projects/ui/src/lib/icon/icons/gauge.ts","../../../projects/ui/src/lib/icon/icons/gift.ts","../../../projects/ui/src/lib/icon/icons/grid.ts","../../../projects/ui/src/lib/icon/icons/history.ts","../../../projects/ui/src/lib/icon/icons/home.ts","../../../projects/ui/src/lib/icon/icons/inbox.ts","../../../projects/ui/src/lib/icon/icons/layers.ts","../../../projects/ui/src/lib/icon/icons/list.ts","../../../projects/ui/src/lib/icon/icons/log-out.ts","../../../projects/ui/src/lib/icon/icons/map.ts","../../../projects/ui/src/lib/icon/icons/map-pin.ts","../../../projects/ui/src/lib/icon/icons/menu.ts","../../../projects/ui/src/lib/icon/icons/mic.ts","../../../projects/ui/src/lib/icon/icons/mic-off.ts","../../../projects/ui/src/lib/icon/icons/more-vertical.ts","../../../projects/ui/src/lib/icon/icons/pause.ts","../../../projects/ui/src/lib/icon/icons/phone.ts","../../../projects/ui/src/lib/icon/icons/play.ts","../../../projects/ui/src/lib/icon/icons/plus.ts","../../../projects/ui/src/lib/icon/icons/search.ts","../../../projects/ui/src/lib/icon/icons/settings.ts","../../../projects/ui/src/lib/icon/icons/shield-check.ts","../../../projects/ui/src/lib/icon/icons/sort.ts","../../../projects/ui/src/lib/icon/icons/star.ts","../../../projects/ui/src/lib/icon/icons/ticket.ts","../../../projects/ui/src/lib/icon/icons/tool.ts","../../../projects/ui/src/lib/icon/icons/trash.ts","../../../projects/ui/src/lib/icon/icons/truck.ts","../../../projects/ui/src/lib/icon/icons/upload-cloud.ts","../../../projects/ui/src/lib/icon/icons/user.ts","../../../projects/ui/src/lib/icon/icons/user-search.ts","../../../projects/ui/src/lib/icon/icons/video.ts","../../../projects/ui/src/lib/icon/icons/x.ts","../../../projects/ui/src/lib/icon/icons/index.ts","../../../projects/ui/src/lib/icon/icon-sprite.ts","../../../projects/ui/src/lib/icon/Icon.ts","../../../projects/ui/src/lib/action-tile/ActionTile.ts","../../../projects/ui/src/lib/admin-badge/AdminBadge.ts","../../../projects/ui/src/lib/spinner/Spinner.ts","../../../projects/ui/src/lib/button/button.ts","../../../projects/ui/src/lib/alert/Alert.ts","../../../projects/ui/src/lib/auth-layout/AuthLayout.ts","../../../projects/ui/src/lib/avatar/Avatar.ts","../../../projects/ui/src/lib/badge/Badge.ts","../../../projects/ui/src/lib/breadcrumb/Breadcrumb.ts","../../../projects/ui/src/lib/card/Card.ts","../../../projects/ui/src/lib/carousel/Carousel.ts","../../../projects/ui/src/lib/checkbox/Checkbox.ts","../../../projects/ui/src/lib/chip/Chip.ts","../../../projects/ui/src/lib/divider/Divider.ts","../../../projects/ui/src/lib/field-label/FieldLabel.ts","../../../projects/ui/src/lib/shared/search-text.ts","../../../projects/ui/src/lib/select/Select.ts","../../../projects/ui/src/lib/company-selector/CompanySelector.ts","../../../projects/ui/src/lib/content-slot/ContentSlot.ts","../../../projects/ui/src/lib/empty-state/EmptyState.ts","../../../projects/ui/src/lib/skeleton/Skeleton.ts","../../../projects/ui/src/lib/content-state/ContentState.ts","../../../projects/ui/src/lib/data-table/DataTable.ts","../../../projects/ui/src/lib/drawer/Drawer.ts","../../../projects/ui/src/lib/drawer-logout/DrawerLogout.ts","../../../projects/ui/src/lib/drawer-session/DrawerSession.ts","../../../projects/ui/src/lib/dropdown/Dropdown.ts","../../../projects/ui/src/lib/feature-card/FeatureCard.ts","../../../projects/ui/src/lib/field/Field.ts","../../../projects/ui/src/lib/filter-chips/FilterChips.ts","../../../projects/ui/src/lib/folder-tabs/FolderTabs.ts","../../../projects/ui/src/lib/footer/Footer.ts","../../../projects/ui/src/lib/input/Input.ts","../../../projects/ui/src/lib/link/Link.ts","../../../projects/ui/src/lib/metric-card/MetricCard.ts","../../../projects/ui/src/lib/modal/Modal.ts","../../../projects/ui/src/lib/multi-select/MultiSelect.ts","../../../projects/ui/src/lib/text/Text.ts","../../../projects/ui/src/lib/page-header/PageHeader.ts","../../../projects/ui/src/lib/pagination/Pagination.ts","../../../projects/ui/src/lib/panel/Panel.ts","../../../projects/ui/src/lib/portal-header/PortalHeader.ts","../../../projects/ui/src/lib/reserve-block/ReserveBlock.ts","../../../projects/ui/src/lib/section-header/SectionHeader.ts","../../../projects/ui/src/lib/segmented/Segmented.ts","../../../projects/ui/src/lib/tooltip/Tooltip.ts","../../../projects/ui/src/lib/sidebar-nav-item/SidebarNavItem.ts","../../../projects/ui/src/lib/shared/media-query.ts","../../../projects/ui/src/lib/sidebar-shell/SidebarShell.ts","../../../projects/ui/src/lib/stat-tile/StatTile.ts","../../../projects/ui/src/lib/status-pill/StatusPill.ts","../../../projects/ui/src/lib/tabs/Tabs.ts","../../../projects/ui/src/lib/toast/Toast.ts","../../../projects/ui/src/lib/vehicle-header/VehicleHeader.ts","../../../projects/ui/src/lib/view-toggle/ViewToggle.ts","../../../projects/ui/src/public-api.ts","../../../projects/ui/src/kaufmann-lab-ui.ts"],"sourcesContent":["import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"activity\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const activity: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"alert-circle\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const alertCircle: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" x2=\"12\" y1=\"8\" y2=\"12\" />\n <line x1=\"12\" x2=\"12.01\" y1=\"16\" y2=\"16\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"alert-octagon\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const alertOctagon: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M12 16h.01\" />\n <path d=\"M12 8v4\" />\n <path d=\"M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"alert-triangle\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const alertTriangle: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"award\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const award: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"m15.477 12.89 1.515 8.526a.5.5 0 0 1-.81.47l-3.58-2.687a1 1 0 0 0-1.197 0l-3.586 2.686a.5.5 0 0 1-.81-.469l1.514-8.526\" />\n <circle cx=\"12\" cy=\"8\" r=\"6\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"bar-chart\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const barChart: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M5 21v-6\" />\n <path d=\"M12 21V9\" />\n <path d=\"M19 21V3\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"bell\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const bell: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M10.268 21a2 2 0 0 0 3.464 0\" />\n <path d=\"M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"bus\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const bus: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M8 6v6\" />\n <path d=\"M15 6v6\" />\n <path d=\"M2 12h19.6\" />\n <path d=\"M18 18h3s.5-1.7.8-2.8c.1-.4.2-.8.2-1.2 0-.4-.1-.8-.2-1.2l-1.4-5C20.1 6.8 19.1 6 18 6H4a2 2 0 0 0-2 2v10h3\" />\n <circle cx=\"7\" cy=\"18\" r=\"2\" />\n <path d=\"M9 18h5\" />\n <circle cx=\"16\" cy=\"18\" r=\"2\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"calculator\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const calculator: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <rect width=\"16\" height=\"20\" x=\"4\" y=\"2\" rx=\"2\" />\n <line x1=\"8\" x2=\"16\" y1=\"6\" y2=\"6\" />\n <line x1=\"16\" x2=\"16\" y1=\"14\" y2=\"18\" />\n <path d=\"M16 10h.01\" />\n <path d=\"M12 10h.01\" />\n <path d=\"M8 10h.01\" />\n <path d=\"M12 14h.01\" />\n <path d=\"M8 14h.01\" />\n <path d=\"M12 18h.01\" />\n <path d=\"M8 18h.01\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"calendar\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const calendar: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M8 2v3\" />\n <path d=\"M16 2v3\" />\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" />\n <path d=\"M3 9h18\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"car\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const car: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M19 17h2c.6 0 1-.4 1-1v-3c0-.9-.7-1.7-1.5-1.9C18.7 10.6 16 10 16 10s-1.3-1.4-2.2-2.3c-.5-.4-1.1-.7-1.8-.7H5c-.6 0-1.1.4-1.4.9l-1.4 2.9A3.7 3.7 0 0 0 2 12v4c0 .6.4 1 1 1h2\" />\n <circle cx=\"7\" cy=\"17\" r=\"2\" />\n <path d=\"M9 17h6\" />\n <circle cx=\"17\" cy=\"17\" r=\"2\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"cart\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const cart: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <circle cx=\"8\" cy=\"21\" r=\"1\" />\n <circle cx=\"19\" cy=\"21\" r=\"1\" />\n <path d=\"M2.05 2.05h2l2.66 12.42a2 2 0 0 0 2 1.58h9.78a2 2 0 0 0 1.95-1.57l1.65-7.43H5.12\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"check\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const check: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M20 6 9 17l-5-5\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"check-circle\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const checkCircle: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M21.801 10A10 10 0 1 1 17 3.335\" />\n <path d=\"m9 11 3 3L22 4\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"check-square\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const checkSquare: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"m9 12 2 2 4-4\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"chevron-down\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const chevronDown: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"m6 9 6 6 6-6\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"chevron-left\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const chevronLeft: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"m15 18-6-6 6-6\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"chevron-left-bar\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const chevronLeftBar: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"M9 3v18\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"chevron-right\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const chevronRight: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"m9 18 6-6-6-6\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"clipboard\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const clipboard: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <rect width=\"8\" height=\"4\" x=\"8\" y=\"2\" rx=\"1\" ry=\"1\" />\n <path d=\"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"clock\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const clock: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 6v6l4 2\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"credit-card\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const creditCard: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <rect width=\"20\" height=\"14\" x=\"2\" y=\"5\" rx=\"2\" />\n <line x1=\"2\" x2=\"22\" y1=\"10\" y2=\"10\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"download\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const download: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M12 15V3\" />\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <path d=\"m7 10 5 5 5-5\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"edit\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const edit: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z\" />\n <path d=\"m15 5 4 4\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"external-link\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const externalLink: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M15 3h6v6\" />\n <path d=\"M10 14 21 3\" />\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"eye\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const eye: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"eye-off\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const eyeOff: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49\" />\n <path d=\"M14.084 14.158a3 3 0 0 1-4.242-4.242\" />\n <path d=\"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143\" />\n <path d=\"m2 2 20 20\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"file\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const file: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\" />\n <path d=\"M14 2v5a1 1 0 0 0 1 1h5\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"filter\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const filter: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"gauge\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const gauge: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"m12 14 4-4\" />\n <path d=\"M3.34 19a10 10 0 1 1 17.32 0\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"gift\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const gift: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M12 7v14\" />\n <path d=\"M20 11v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-8\" />\n <path d=\"M7.5 7a1 1 0 0 1 0-5A4.8 8 0 0 1 12 7a4.8 8 0 0 1 4.5-5 1 1 0 0 1 0 5\" />\n <rect x=\"3\" y=\"7\" width=\"18\" height=\"4\" rx=\"1\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"grid\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const grid: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"M3 9h18\" />\n <path d=\"M3 15h18\" />\n <path d=\"M9 3v18\" />\n <path d=\"M15 3v18\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"history\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const history: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\" />\n <path d=\"M3 3v5h5\" />\n <path d=\"M12 7v5l4 2\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"home\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const home: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M3 10.5 12 3l9 7.5\" />\n <path d=\"M5 9.5V20a1 1 0 0 0 1 1h4v-6h4v6h4a1 1 0 0 0 1-1V9.5\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"inbox\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const inbox: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <polyline points=\"22 12 16 12 14 15 10 15 8 12 2 12\" />\n <path d=\"M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"layers\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const layers: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z\" />\n <path d=\"M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12\" />\n <path d=\"M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"list\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const list: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M3 5h.01\" />\n <path d=\"M3 12h.01\" />\n <path d=\"M3 19h.01\" />\n <path d=\"M8 5h13\" />\n <path d=\"M8 12h13\" />\n <path d=\"M8 19h13\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"log-out\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const logOut: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\" />\n <path d=\"M16 17l5-5-5-5\" />\n <path d=\"M21 12H9\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"map\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const map: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M14.106 5.553a2 2 0 0 0 1.788 0l3.659-1.83A1 1 0 0 1 21 4.619v12.764a1 1 0 0 1-.553.894l-4.553 2.277a2 2 0 0 1-1.788 0l-4.212-2.106a2 2 0 0 0-1.788 0l-3.659 1.83A1 1 0 0 1 3 19.381V6.618a1 1 0 0 1 .553-.894l4.553-2.277a2 2 0 0 1 1.788 0z\" />\n <path d=\"M15 5.764v15\" />\n <path d=\"M9 3.236v15\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"map-pin\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const mapPin: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0\" />\n <circle cx=\"12\" cy=\"10\" r=\"3\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"menu\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const menu: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M4 5h16\" />\n <path d=\"M4 12h16\" />\n <path d=\"M4 19h16\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"mic\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const mic: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M12 19v3\" />\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\" />\n <rect x=\"9\" y=\"2\" width=\"6\" height=\"13\" rx=\"3\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"mic-off\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const micOff: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M12 19v3\" />\n <path d=\"M15 9.34V5a3 3 0 0 0-5.68-1.33\" />\n <path d=\"M16.95 16.95A7 7 0 0 1 5 12v-2\" />\n <path d=\"M18.89 13.23A7 7 0 0 0 19 12v-2\" />\n <path d=\"m2 2 20 20\" />\n <path d=\"M9 9v3a3 3 0 0 0 5.12 2.12\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"more-vertical\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const moreVertical: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\n <circle cx=\"12\" cy=\"5\" r=\"1\" />\n <circle cx=\"12\" cy=\"19\" r=\"1\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"pause\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const pause: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <rect x=\"14\" y=\"3\" width=\"5\" height=\"18\" rx=\"1\" />\n <rect x=\"5\" y=\"3\" width=\"5\" height=\"18\" rx=\"1\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"phone\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const phone: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M13.832 16.568a1 1 0 0 0 1.213-.303l.355-.465A2 2 0 0 1 17 15h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2A18 18 0 0 1 2 4a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-.8 1.6l-.468.351a1 1 0 0 0-.292 1.233 14 14 0 0 0 6.392 6.384\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"play\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const play: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"plus\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const plus: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M5 12h14\" />\n <path d=\"M12 5v14\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"search\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const search: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"m21 21-4.34-4.34\" />\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"settings\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const settings: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"shield-check\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const shieldCheck: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z\" />\n <path d=\"m9 12 2 2 4-4\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"sort\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const sort: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"m21 16-4 4-4-4\" />\n <path d=\"M17 20V4\" />\n <path d=\"m3 8 4-4 4 4\" />\n <path d=\"M7 4v16\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"star\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const star: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"ticket\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const ticket: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z\" />\n <path d=\"M13 5v2\" />\n <path d=\"M13 17v2\" />\n <path d=\"M13 11v2\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"tool\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const tool: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"trash\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const trash: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\" />\n <path d=\"M3 6h18\" />\n <path d=\"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"truck\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const truck: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M14 18V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v11a1 1 0 0 0 1 1h2\" />\n <path d=\"M15 18H9\" />\n <path d=\"M19 18h2a1 1 0 0 0 1-1v-3.65a1 1 0 0 0-.22-.624l-3.48-4.35A1 1 0 0 0 17.52 8H14\" />\n <circle cx=\"17\" cy=\"18\" r=\"2\" />\n <circle cx=\"7\" cy=\"18\" r=\"2\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"upload-cloud\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const uploadCloud: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M12 13v8\" />\n <path d=\"M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242\" />\n <path d=\"m8 17 4-4 4 4\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"user\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const user: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2\" />\n <circle cx=\"12\" cy=\"7\" r=\"4\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"user-search\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const userSearch: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <circle cx=\"10\" cy=\"7\" r=\"4\" />\n <path d=\"M10.3 15H7a4 4 0 0 0-4 4v2\" />\n <circle cx=\"17\" cy=\"17\" r=\"3\" />\n <path d=\"m21 21-1.9-1.9\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"video\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const video: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.87a.5.5 0 0 0-.752-.432L16 10.5\" />\n <rect x=\"2\" y=\"6\" width=\"14\" height=\"12\" rx=\"2\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\n\n/** Símbolo de trazo \"x\" (grilla 24×24) — ver `icons/index.ts` para el registro completo. */\nexport const x: IconDefinition = {\n viewBox: '0 0 24 24',\n markup: `\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n `,\n};\n","import type { IconDefinition } from '../icon-definition';\nimport type { IconName } from '../icon-name';\nimport { activity } from './activity';\nimport { alertCircle } from './alert-circle';\nimport { alertOctagon } from './alert-octagon';\nimport { alertTriangle } from './alert-triangle';\nimport { award } from './award';\nimport { barChart } from './bar-chart';\nimport { bell } from './bell';\nimport { bus } from './bus';\nimport { calculator } from './calculator';\nimport { calendar } from './calendar';\nimport { car } from './car';\nimport { cart } from './cart';\nimport { check } from './check';\nimport { checkCircle } from './check-circle';\nimport { checkSquare } from './check-square';\nimport { chevronDown } from './chevron-down';\nimport { chevronLeft } from './chevron-left';\nimport { chevronLeftBar } from './chevron-left-bar';\nimport { chevronRight } from './chevron-right';\nimport { clipboard } from './clipboard';\nimport { clock } from './clock';\nimport { creditCard } from './credit-card';\nimport { download } from './download';\nimport { edit } from './edit';\nimport { externalLink } from './external-link';\nimport { eye } from './eye';\nimport { eyeOff } from './eye-off';\nimport { file } from './file';\nimport { filter } from './filter';\nimport { gauge } from './gauge';\nimport { gift } from './gift';\nimport { grid } from './grid';\nimport { history } from './history';\nimport { home } from './home';\nimport { inbox } from './inbox';\nimport { layers } from './layers';\nimport { list } from './list';\nimport { logOut } from './log-out';\nimport { map } from './map';\nimport { mapPin } from './map-pin';\nimport { menu } from './menu';\nimport { mic } from './mic';\nimport { micOff } from './mic-off';\nimport { moreVertical } from './more-vertical';\nimport { pause } from './pause';\nimport { phone } from './phone';\nimport { play } from './play';\nimport { plus } from './plus';\nimport { search } from './search';\nimport { settings } from './settings';\nimport { shieldCheck } from './shield-check';\nimport { sort } from './sort';\nimport { star } from './star';\nimport { ticket } from './ticket';\nimport { tool } from './tool';\nimport { trash } from './trash';\nimport { truck } from './truck';\nimport { uploadCloud } from './upload-cloud';\nimport { user } from './user';\nimport { userSearch } from './user-search';\nimport { video } from './video';\nimport { x } from './x';\n\n/**\n * Registro tipado de todos los símbolos de ícono. `Record<IconName,\n * IconDefinition>` obliga al compilador a exigir una entrada por cada\n * nombre de `IconName` — agregar un nombre acá sin su archivo en\n * `icons/`, o viceversa, es un error de TypeScript, no un ícono roto\n * en runtime (que era el riesgo real del sprite como string único).\n *\n * Agregar un ícono nuevo es: crear `icons/nombre-del-icono.ts` (copiar\n * el patrón de cualquier archivo vecino), agregarlo a `IconName` en\n * `icon-name.ts`, e importarlo/registrarlo acá.\n */\nexport const ICON_DEFINITIONS: Record<IconName, IconDefinition> = {\n activity: activity,\n 'alert-circle': alertCircle,\n 'alert-octagon': alertOctagon,\n 'alert-triangle': alertTriangle,\n award: award,\n 'bar-chart': barChart,\n bell: bell,\n bus: bus,\n calculator: calculator,\n calendar: calendar,\n car: car,\n cart: cart,\n check: check,\n 'check-circle': checkCircle,\n 'check-square': checkSquare,\n 'chevron-down': chevronDown,\n 'chevron-left': chevronLeft,\n 'chevron-left-bar': chevronLeftBar,\n 'chevron-right': chevronRight,\n clipboard: clipboard,\n clock: clock,\n 'credit-card': creditCard,\n download: download,\n edit: edit,\n 'external-link': externalLink,\n eye: eye,\n 'eye-off': eyeOff,\n file: file,\n filter: filter,\n gauge: gauge,\n gift: gift,\n grid: grid,\n history: history,\n home: home,\n inbox: inbox,\n layers: layers,\n list: list,\n 'log-out': logOut,\n map: map,\n 'map-pin': mapPin,\n menu: menu,\n mic: mic,\n 'mic-off': micOff,\n 'more-vertical': moreVertical,\n pause: pause,\n phone: phone,\n play: play,\n plus: plus,\n search: search,\n settings: settings,\n 'shield-check': shieldCheck,\n sort: sort,\n star: star,\n ticket: ticket,\n tool: tool,\n trash: trash,\n truck: truck,\n 'upload-cloud': uploadCloud,\n user: user,\n 'user-search': userSearch,\n video: video,\n x: x,\n};\n","import { ICON_DEFINITIONS } from './icons';\n\n/**\n * Sprite SVG con los 60 íconos de trazo del design system (página 5:\n * \"Set de 59 iconos de trazo (1.9px, grilla 24×24)\", más `eye-off` como\n * extensión propia). Cada ícono es un `<symbol>` con su nombre real de la\n * spec como id (`kf-icon-check`, `kf-icon-alert-triangle`, etc.) — `Icon`\n * lo referencia con `<use>`.\n *\n * Los paths vienen de Lucide (https://lucide.dev, licencia ISC), la\n * librería de iconos de trazo cuyo set de nombres coincide exactamente con\n * el que pide el design system (chevron-right, alert-triangle, bar-chart…).\n * Se embeben acá en vez de agregar `lucide` como dependencia del paquete\n * para no sumar peso/versión externa a algo que consumen todos los\n * frontends del ecosistema — son símbolos estáticos, no lógica que\n * necesite actualizarse seguido.\n *\n * Mapeo de 4 nombres de la spec que no existen tal cual en Lucide (renombres\n * entre versiones de esa librería, o conceptos vecinos):\n * tool -> wrench\n * sort -> arrow-up-down (control de orden bidireccional simple)\n * cart -> shopping-cart\n * chevron-left-bar -> panel-left (icono de \"colapsar panel lateral\")\n *\n * El sprite ya no es un string único de mano: se construye acá a partir de\n * `ICON_DEFINITIONS` (ver `icons/index.ts`), el registro tipado donde cada\n * ícono vive en su propio archivo bajo `icons/`. Esto es responsabilidad de\n * ensamblado pura — los datos de cada glyph viven en otro lado.\n *\n * Se inyecta UNA sola vez en el DOM (ver `Icon`), sin importar cuántos\n * `<kf-icon>` distintos haya en la página — todos referencian el mismo\n * sprite vía `<use href=\"#kf-icon-...\">`.\n */\nexport const KF_ICON_SPRITE = buildIconSprite();\n\nfunction buildIconSprite(): string {\n const symbols = Object.entries(ICON_DEFINITIONS)\n .map(\n ([name, { viewBox, markup }]) =>\n `<symbol id=\"kf-icon-${name}\" viewBox=\"${viewBox}\">${markup}</symbol>`,\n )\n .join('\\n ');\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" style=\"display: none\">\n ${symbols}\n</svg>`;\n}\n","import { DOCUMENT } from '@angular/common';\nimport { Component, computed, effect, inject, input } from '@angular/core';\nimport { KF_ICON_SPRITE } from './icon-sprite';\nimport type { IconName } from './icon-name';\n\nexport type { IconName };\n\nexport type IconSize = 'sm' | 'md' | 'lg';\n\n/** Marca el sprite ya inyectado, para no depender de una bandera de módulo\n * — una bandera compartida entre instancias de test (o entre múltiples\n * `TestBed` en la misma suite) daría falsos negativos: el primer test que\n * corre \"gasta\" la bandera y todos los siguientes creerían que el sprite\n * nunca se inyecta. Comprobar el propio DOM es la fuente de verdad real. */\nconst SPRITE_ROOT_ID = 'kf-icon-sprite-root';\n\n/**\n * Ícono de trazo del design system — 61 glyphs (59 de la página 5 + `eye-off` y `log-out`), grilla 24×24,\n * grosor de trazo 1.9px. Referencia un sprite SVG embebido (ver\n * `icon-sprite.ts`) vía `<use>`, así que no hay peso de red adicional por\n * cada instancia: el sprite se inyecta al DOM una única vez, la primera\n * vez que se renderiza cualquier `<kf-icon>` de toda la aplicación.\n *\n * El tamaño se controla con `size` (página 6: \"el tamaño se controla con la\n * prop size\"): `sm` (16px), `md` (20px, default) o `lg` (24px). El color\n * sigue siempre `currentColor` — se hereda del texto del elemento\n * contenedor, nunca se fija en el propio ícono.\n *\n * <kf-icon name=\"alert-triangle\" size=\"sm\" />\n * <kf-button icon=\"calendar\">Reservar hora</kf-button> <!-- ver Button -->\n */\n@Component({\n selector: 'kf-icon',\n template: `\n <svg [attr.aria-hidden]=\"true\" focusable=\"false\">\n <use [attr.href]=\"'#kf-icon-' + name()\" />\n </svg>\n `,\n styles: `\n :host {\n display: inline-flex;\n flex: none;\n line-height: 0;\n }\n svg {\n width: var(--kf-icon-size, 20px);\n height: var(--kf-icon-size, 20px);\n fill: none;\n stroke: currentColor;\n stroke-width: 1.9;\n stroke-linecap: round;\n stroke-linejoin: round;\n }\n `,\n host: {\n '[style.--kf-icon-size]': 'pixelSize()',\n },\n})\nexport class Icon {\n readonly name = input.required<IconName>();\n readonly size = input<IconSize>('md');\n\n private readonly document = inject(DOCUMENT);\n\n protected readonly pixelSize = computed(() => {\n const bySize: Record<IconSize, string> = { sm: '16px', md: '20px', lg: '24px' };\n return bySize[this.size()];\n });\n\n constructor() {\n effect(() => {\n if (this.document.getElementById(SPRITE_ROOT_ID)) {\n return;\n }\n const container = this.document.createElement('div');\n container.innerHTML = KF_ICON_SPRITE;\n const sprite = container.firstElementChild;\n if (sprite) {\n sprite.id = SPRITE_ROOT_ID;\n this.document.body.prepend(sprite);\n }\n });\n }\n}\n","import { Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Dos variantes del mismo concepto — acceso rápido a una sección (página\n * 35): \"Tile de acceso destacado\" (`variant=\"tile\"`, default) es un bloque\n * centrado con ícono grande arriba y título abajo, pensado para una\n * cuadrícula de accesos (ej. \"Todos los certificados\"). \"Fila de documento\"\n * (`variant=\"row\"`) es horizontal, con ícono a la izquierda y\n * título+descripción a la derecha, pensada para listas verticales dentro de\n * un `kf-panel` (ej. \"Pagos\" / \"Revisa tu estado de cuenta y realiza pagos.\").\n *\n * <kf-action-tile icon=\"shield-check\" title=\"Todos los certificados\" />\n * <kf-action-tile variant=\"row\" icon=\"download\" title=\"Pagos\"\n * description=\"Revisa tu estado de cuenta y realiza pagos.\" />\n */\n@Component({\n selector: 'kf-action-tile',\n imports: [Icon],\n template: `\n <span class=\"kf-action-tile__icon\">\n <kf-icon [name]=\"icon()\" [size]=\"variant() === 'row' ? 'md' : 'lg'\" />\n </span>\n <span class=\"kf-action-tile__text\">\n <span class=\"kf-action-tile__title\">{{ title() }}</span>\n @if (description()) {\n <span class=\"kf-action-tile__description\">{{ description() }}</span>\n }\n </span>\n `,\n styles: `\n :host {\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-white);\n cursor: pointer;\n transition:\n border-color 0.14s,\n box-shadow 0.14s;\n }\n :host(:hover) {\n border-color: var(--kf-color-border-strong);\n box-shadow: var(--kf-shadow-xs);\n }\n :host(.kf-action-tile--tile) {\n flex-direction: column;\n text-align: center;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-lg);\n }\n .kf-action-tile__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-primary-soft);\n color: var(--kf-color-primary);\n }\n :host(.kf-action-tile--row) .kf-action-tile__icon {\n width: 2.25rem;\n height: 2.25rem;\n background: var(--kf-color-secondary-soft);\n color: var(--kf-color-secondary);\n }\n :host(.kf-action-tile--tile) .kf-action-tile__icon {\n width: 2.75rem;\n height: 2.75rem;\n }\n .kf-action-tile__text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n }\n .kf-action-tile__title {\n font-family: var(--kf-font-title);\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-action-tile__description {\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n }\n `,\n host: {\n '[class.kf-action-tile--tile]': \"variant() === 'tile'\",\n '[class.kf-action-tile--row]': \"variant() === 'row'\",\n },\n})\nexport class ActionTile {\n readonly variant = input<'tile' | 'row'>('tile');\n readonly icon = input.required<IconName>();\n readonly title = input.required<string>();\n readonly description = input<string>();\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\nimport { Icon } from '../icon/Icon';\n\n/**\n * Marca la barra superior como chrome exclusivo de administradores (página\n * 18) — acento ámbar para diferenciar contexto privilegiado del resto del\n * portal. Dos variantes: etiqueta aislada (pill), o `inline` para usarse\n * dentro de la franja de `kf-portal-header` (fondo oscuro, texto ámbar).\n *\n * <kf-admin-badge />\n * <kf-admin-badge inline />\n */\n@Component({\n selector: 'kf-admin-badge',\n imports: [Icon],\n template: `\n <kf-icon name=\"shield-check\" size=\"sm\" />\n <span>Vista administrador</span>\n `,\n styles: `\n :host {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-warning-soft);\n border: 1px solid var(--kf-color-warning);\n color: var(--kf-color-warning-strong);\n font-size: 0.75rem;\n font-weight: 700;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n line-height: 1;\n }\n :host(.kf-admin-badge--inline) {\n background: transparent;\n border-color: rgba(226, 185, 59, 0.5);\n color: var(--kf-color-warning);\n }\n `,\n host: {\n '[class.kf-admin-badge--inline]': 'inline()',\n },\n})\nexport class AdminBadge {\n /** Para usarse dentro de una superficie oscura (ej. la franja de `kf-portal-header`). */\n readonly inline = input(false, { transform: booleanAttribute });\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\n\nexport type SpinnerSize = 'sm' | 'md' | 'lg';\n\n/**\n * Indicador de carga indeterminado: inline, dentro de un botón, o como único\n * contenido de una sección mientras llega la data.\n *\n * Cuando se conoce la forma del contenido que viene, preferir `kf-skeleton`\n * (dibuja la silueta). El spinner es para \"algo está pasando\" sin forma\n * conocida — guardar, enviar, reintentar.\n *\n * Lleva `role=\"status\"`, así que el lector de pantalla anuncia el `label`\n * cuando aparece. Sin `label` cae en un texto accesible por defecto.\n *\n * <kf-spinner />\n * <kf-spinner size=\"sm\" label=\"Cargando…\" />\n * <kf-spinner onDark />\n */\n@Component({\n selector: 'kf-spinner',\n template: `\n <span class=\"kf-spinner\" [class.kf-spinner--on-dark]=\"onDark()\" role=\"status\">\n <span class=\"kf-spinner__ring\" [class]=\"'kf-spinner__ring--' + size()\"></span>\n @if (label()) {\n <span class=\"kf-spinner__label\">{{ label() }}</span>\n } @else {\n <span class=\"kf-spinner__sr\">Cargando</span>\n }\n </span>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-spinner {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-sm);\n font-family: var(--kf-font-body);\n }\n .kf-spinner__ring {\n display: inline-block;\n flex: none;\n border-radius: var(--kf-radius-pill);\n border: 2px solid var(--kf-color-border);\n border-top-color: var(--kf-color-primary);\n animation: kf-spinner-turn 0.7s linear infinite;\n }\n .kf-spinner__ring--sm {\n width: 16px;\n height: 16px;\n }\n .kf-spinner__ring--md {\n width: 24px;\n height: 24px;\n border-width: 3px;\n }\n .kf-spinner__ring--lg {\n width: 32px;\n height: 32px;\n border-width: 3px;\n }\n .kf-spinner__label {\n font-size: 0.875rem;\n color: var(--kf-color-text-muted);\n }\n /* Sobre superficies oscuras (carousel, feature card, barra de admin). */\n .kf-spinner--on-dark .kf-spinner__ring {\n border-color: rgba(255, 255, 255, 0.28);\n border-top-color: var(--kf-color-white);\n }\n .kf-spinner--on-dark .kf-spinner__label {\n color: var(--kf-color-white);\n }\n @keyframes kf-spinner-turn {\n to {\n transform: rotate(360deg);\n }\n }\n .kf-spinner__sr {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n }\n @media (prefers-reduced-motion: reduce) {\n .kf-spinner__ring {\n animation-duration: 2s;\n }\n }\n `,\n})\nexport class Spinner {\n readonly size = input<SpinnerSize>('md');\n /** Texto al lado del anillo. Vacío deja solo el anillo (y el texto para lectores). */\n readonly label = input('');\n /** Invierte los colores para fondos oscuros. */\n readonly onDark = input(false, { transform: booleanAttribute });\n}\n","import { booleanAttribute, Component, computed, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\nimport { Spinner } from '../spinner/Spinner';\n\n/**\n * Wraps a native `<button>`, so keyboard handling, focus and form submission\n * keep working. The cost of the wrapper is forwarding `disabled` and `type` by\n * hand: as attributes on a custom element they have no native effect.\n *\n * Five variants (page 9 of the design system): `primary` (main action, blue),\n * `secondary` (service actions, orange), `ghost` (low-emphasis, no fill),\n * `outline` (medium-emphasis, bordered) and `danger` (destructive\n * confirmations — red, see the Confirmation Modal pattern on page 30). Three\n * sizes (`sm`/`md`/`lg`). `icon` renders a leading glyph (`kf-icon`) before\n * the projected label; `block` stretches the button to the full width of its\n * container.\n *\n * `(click)` is not forwarded — it bubbles from the inner button to the host.\n *\n * `loading` replaces the projected content with `kf-spinner` and forces\n * `disabled` — for the common \"Ingresando…\"/\"Enviando…\" submit pattern,\n * which before this prop existed as plain text swaps with no visual\n * indicator (see `web-portal-latam-frontend`'s login submit buttons).\n *\n * <kf-button (click)=\"save()\">Save</kf-button>\n * <kf-button variant=\"ghost\" disabled>Cancel</kf-button>\n * <kf-button variant=\"danger\" (click)=\"remove()\">Delete</kf-button>\n * <kf-button size=\"sm\" icon=\"calendar\" block>Reservar hora</kf-button>\n * <kf-button type=\"submit\" [loading]=\"submitting()\">Ingresar</kf-button>\n */\n@Component({\n selector: 'kf-button',\n imports: [Icon, Spinner],\n template: `\n <button\n [type]=\"type()\"\n [disabled]=\"disabled() || loading()\"\n [class.kf-button--secondary]=\"variant() === 'secondary'\"\n [class.kf-button--ghost]=\"variant() === 'ghost'\"\n [class.kf-button--outline]=\"variant() === 'outline'\"\n [class.kf-button--danger]=\"variant() === 'danger'\"\n [class.kf-button--sm]=\"size() === 'sm'\"\n [class.kf-button--lg]=\"size() === 'lg'\"\n >\n @if (loading()) {\n <kf-spinner size=\"sm\" [onDark]=\"hasSolidFill()\" />\n } @else {\n @if (icon(); as iconName) {\n <kf-icon\n class=\"kf-button__icon\"\n [name]=\"iconName\"\n [size]=\"size() === 'lg' ? 'md' : 'sm'\"\n />\n }\n <ng-content />\n }\n </button>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n :host([block]) {\n display: block;\n }\n button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--kf-space-xs);\n width: 100%;\n font: inherit;\n font-weight: 600;\n padding: var(--kf-space-sm) var(--kf-space-md);\n border: 1px solid var(--kf-color-primary);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-primary);\n color: var(--kf-color-white);\n cursor: pointer;\n transition:\n background 0.14s,\n border-color 0.14s,\n color 0.14s;\n }\n button:hover:not(:disabled) {\n background: var(--kf-color-primary-hover);\n border-color: var(--kf-color-primary-hover);\n }\n button:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n /* Secondary — naranja, para acciones de servicio (agendar, mantención). */\n button.kf-button--secondary {\n border-color: var(--kf-color-secondary);\n background: var(--kf-color-secondary);\n }\n button.kf-button--secondary:hover:not(:disabled) {\n background: var(--kf-color-secondary-hover);\n border-color: var(--kf-color-secondary-hover);\n }\n\n /* Ghost — sin relleno, para acciones secundarias junto a un primary. */\n button.kf-button--ghost {\n background: transparent;\n border-color: transparent;\n color: var(--kf-color-primary);\n }\n button.kf-button--ghost:hover:not(:disabled) {\n background: var(--kf-color-primary-soft);\n }\n\n /* Outline — énfasis medio: borde visible, sin relleno (ej. \"Llamar\" en Vehicle Header). */\n button.kf-button--outline {\n background: transparent;\n border-color: var(--kf-color-border-strong);\n color: var(--kf-color-text);\n }\n button.kf-button--outline:hover:not(:disabled) {\n background: var(--kf-color-surface);\n border-color: var(--kf-color-text-muted);\n }\n\n /* Danger — rojo, para confirmaciones destructivas (cancelar, eliminar). */\n button.kf-button--danger {\n border-color: var(--kf-color-error);\n background: var(--kf-color-error);\n }\n button.kf-button--danger:hover:not(:disabled) {\n background: var(--kf-color-error-hover);\n border-color: var(--kf-color-error-hover);\n }\n\n /* Tamaños — el tamaño por defecto (md) usa el padding base de arriba. */\n button.kf-button--sm {\n padding: 6px var(--kf-space-sm);\n font-size: 0.85rem;\n }\n button.kf-button--lg {\n padding: var(--kf-space-sm) var(--kf-space-lg);\n font-size: 1.05rem;\n }\n `,\n host: {\n '[attr.block]': \"block() ? '' : null\",\n },\n})\nexport class Button {\n readonly variant = input<'primary' | 'secondary' | 'ghost' | 'outline' | 'danger'>('primary');\n readonly size = input<'sm' | 'md' | 'lg'>('md');\n readonly disabled = input(false, { transform: booleanAttribute });\n /** Matches the native default: submits when inside a `<form>`. */\n readonly type = input<'button' | 'submit' | 'reset'>('submit');\n /** Leading icon, rendered via `kf-icon` before the projected label. */\n readonly icon = input<IconName>();\n /** Stretches the button to the full width of its container. */\n readonly block = input(false, { transform: booleanAttribute });\n /** Replaces the projected content with `kf-spinner` and forces `disabled`. */\n readonly loading = input(false, { transform: booleanAttribute });\n\n /** `ghost`/`outline` have no solid background — the default spinner ring already reads fine there. */\n protected readonly hasSolidFill = computed(() => {\n const variant = this.variant();\n return variant !== 'ghost' && variant !== 'outline';\n });\n}\n","import { booleanAttribute, Component, computed, input, model } from '@angular/core';\n\nexport type AlertTone = 'info' | 'ok' | 'warn' | 'error';\n\n/**\n * Banner contextual que vive dentro del flujo: validaciones, avisos de\n * vencimiento, confirmaciones. Persiste hasta que se descarta o hasta que la\n * condición que lo causó desaparece — para feedback efímero está el toast.\n *\n * `open` es two-way: el botón de cerrar lo pone en `false` y el componente\n * deja de renderizar. El consumidor puede volver a abrirlo poniéndolo en\n * `true` (ej. cuando la validación falla otra vez).\n *\n * ponytail: los glifos van inline en vez de venir de un componente Icon —\n * son 4 paths fijos, uno por tono, y no existe todavía `kf-icon` en la\n * librería. Cuando exista, se reemplaza este `@switch` por `<kf-icon>`.\n *\n * <kf-alert tone=\"warn\" title=\"SOAT por vencer\">Vence el 15/08.</kf-alert>\n * <kf-alert tone=\"ok\" [(open)]=\"saved\" dismissible>Pago registrado.</kf-alert>\n */\n@Component({\n selector: 'kf-alert',\n template: `\n @if (open()) {\n <div class=\"kf-alert\" [class]=\"'kf-alert--' + tone()\" [attr.role]=\"ariaRole()\">\n <svg class=\"kf-alert__icon\" viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\n @switch (tone()) {\n @case ('ok') {\n <path d=\"M21 12a9 9 0 1 1-4.2-7.6\" />\n <path d=\"M9 11.5l3 3 8.5-8.5\" />\n }\n @case ('warn') {\n <path d=\"M12 4l9 16H3z\" />\n <path d=\"M12 10v4\" />\n <path d=\"M12 17.5h.01\" />\n }\n @case ('error') {\n <path d=\"M8 3h8l5 5v8l-5 5H8l-5-5V8z\" />\n <path d=\"M12 8v4\" />\n <path d=\"M12 16h.01\" />\n }\n @default {\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"M12 8v4\" />\n <path d=\"M12 16h.01\" />\n }\n }\n </svg>\n <div class=\"kf-alert__body\">\n @if (title()) {\n <p class=\"kf-alert__title\">{{ title() }}</p>\n }\n <div class=\"kf-alert__message\"><ng-content /></div>\n </div>\n @if (dismissible()) {\n <button\n type=\"button\"\n class=\"kf-alert__close\"\n aria-label=\"Cerrar aviso\"\n (click)=\"open.set(false)\"\n >\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M6 6l12 12M18 6L6 18\" />\n </svg>\n </button>\n }\n </div>\n }\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-alert {\n display: flex;\n align-items: flex-start;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-sm) var(--kf-space-md);\n border: 1px solid transparent;\n border-radius: var(--kf-radius-sm);\n font-size: 0.9rem;\n }\n .kf-alert--info {\n background: var(--kf-color-info-soft);\n border-color: var(--kf-color-info);\n color: var(--kf-color-info-strong);\n }\n .kf-alert--ok {\n background: var(--kf-color-success-soft);\n border-color: var(--kf-color-success);\n color: var(--kf-color-success-strong);\n }\n .kf-alert--warn {\n background: var(--kf-color-warning-soft);\n border-color: var(--kf-color-warning);\n color: var(--kf-color-warning-strong);\n }\n .kf-alert--error {\n background: var(--kf-color-error-soft);\n border-color: var(--kf-color-error);\n color: var(--kf-color-error-strong);\n }\n .kf-alert__icon,\n .kf-alert__close svg {\n flex: none;\n width: 1.15em;\n height: 1.15em;\n fill: none;\n stroke: currentColor;\n stroke-width: 1.9;\n stroke-linecap: round;\n stroke-linejoin: round;\n }\n .kf-alert__body {\n flex: 1;\n min-width: 0;\n }\n .kf-alert__title {\n margin: 0;\n font-family: var(--kf-font-title);\n font-weight: 700;\n }\n .kf-alert__message {\n color: inherit;\n }\n .kf-alert__close {\n flex: none;\n display: inline-flex;\n padding: 2px;\n border: none;\n background: transparent;\n color: inherit;\n border-radius: var(--kf-radius-xs);\n cursor: pointer;\n opacity: 0.7;\n }\n .kf-alert__close:hover {\n opacity: 1;\n }\n .kf-alert__close:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n `,\n})\nexport class Alert {\n readonly tone = input<AlertTone>('info');\n /** Línea en negrita arriba del mensaje. Vacío deja solo el contenido proyectado. */\n readonly title = input('');\n readonly dismissible = input(false, { transform: booleanAttribute });\n /** Visibilidad, two-way: `[(open)]=\"hasError\"`. */\n readonly open = model(true);\n\n /**\n * `alert` interrumpe al lector de pantalla; se reserva para error/warn.\n * Los avisos informativos se anuncian sin cortar lo que se esté leyendo.\n */\n protected readonly ariaRole = computed(() =>\n this.tone() === 'error' || this.tone() === 'warn' ? 'alert' : 'status',\n );\n}\n","import { Component, input } from '@angular/core';\n\n/**\n * Layout a pantalla completa para cualquier pantalla de autenticación\n * (login, recuperar contraseña, confirmación de envío) — split marca a la\n * izquierda / contenido libre a la derecha en desktop, formulario a\n * pantalla completa en mobile (el panel de marca completo se oculta, no se\n * apila arriba: en una pantalla angosta el usuario vino a loguearse, no a\n * leer la tagline). Un logo compacto (o wordmark de respaldo) sí se\n * mantiene visible arriba del formulario en mobile — el usuario nunca\n * pierde de vista qué portal está usando, mismo criterio que ya sigue el\n * resto del ecosistema (ver la topbar mobile de `css/otd.css`, que muestra\n * el logo aunque el sidebar completo se oculte).\n *\n * Este componente resuelve el \"cascarón\" — nunca el formulario en sí. Cada\n * portal arma su propio `<form>` con los componentes de la librería\n * (`kf-input`, `kf-checkbox`, `kf-button`, `kf-alert`) y lo proyecta en el\n * slot por defecto. Es la misma separación de responsabilidad que ya usa\n * `kf-card`: un componente da la estructura visual, el consumidor decide\n * qué va adentro.\n *\n * Antes de este componente, cada portal (LATAM primero, ahora OTD) hubiera\n * tenido que reimplementar este mismo split desde cero — la librería\n * había pospuesto esta abstracción a propósito hasta tener un segundo\n * consumidor real que confirmara qué parte es realmente compartida (el\n * cascarón) y qué parte es de cada portal (el formulario). OTD es ese\n * segundo consumidor.\n *\n * Ningún input tiene valor por defecto propio de ningún portal — `brand`\n * es obligatorio (`input.required`) y el resto de props de marca son\n * opcionales sin fallback hardcodeado, precisamente para que cada\n * consumidor (LATAM, OTD, Star, o el ERP de Asistencia en Ruta con sus\n * propios temas) traiga su propio logo/tagline sin que la librería asuma\n * cuál.\n *\n * <kf-auth-layout\n * brand=\"Mi Portal\"\n * brandLogoSrc=\"images/mi-portal-logo-white.png\"\n * brandLogoMobileSrc=\"images/mi-portal-logo-black.png\"\n * brandTagline=\"Frase corta de marca, propia de cada portal.\"\n * >\n * <form (ngSubmit)=\"onSubmit()\">\n * <kf-input label=\"Correo\" type=\"email\" />\n * <kf-input label=\"Contraseña\" type=\"password\" toggleable />\n * <kf-button type=\"submit\">Ingresar</kf-button>\n * </form>\n * </kf-auth-layout>\n */\n@Component({\n selector: 'kf-auth-layout',\n template: `\n <aside class=\"kf-auth-layout__brand\">\n @if (brandLogoSrc()) {\n <img class=\"kf-auth-layout__logo\" [src]=\"brandLogoSrc()\" [alt]=\"brand()\" />\n } @else {\n <span class=\"kf-auth-layout__wordmark\">{{ brand() }}</span>\n }\n @if (brandTagline()) {\n <p class=\"kf-auth-layout__tagline\">{{ brandTagline() }}</p>\n }\n </aside>\n\n <main class=\"kf-auth-layout__content\">\n <div class=\"kf-auth-layout__panel\">\n <div class=\"kf-auth-layout__mobile-brand\">\n @if (brandLogoMobileSrc() || brandLogoSrc()) {\n <img\n class=\"kf-auth-layout__logo kf-auth-layout__logo--mobile\"\n [src]=\"brandLogoMobileSrc() || brandLogoSrc()\"\n [alt]=\"brand()\"\n />\n } @else {\n <span class=\"kf-auth-layout__wordmark kf-auth-layout__wordmark--mobile\">{{\n brand()\n }}</span>\n }\n </div>\n <ng-content />\n </div>\n </main>\n `,\n styles: `\n :host {\n display: grid;\n grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);\n min-height: 100dvh;\n background: var(--kf-color-surface);\n }\n\n .kf-auth-layout__brand {\n display: flex;\n flex-direction: column;\n justify-content: center;\n gap: var(--kf-space-md);\n padding: var(--kf-space-xl);\n background: linear-gradient(\n 190deg,\n var(--kf-color-primary-active) 0%,\n var(--kf-color-tertiary-deep) 100%\n );\n color: var(--kf-color-white);\n }\n\n .kf-auth-layout__logo {\n height: 1.75rem;\n width: fit-content;\n }\n\n .kf-auth-layout__wordmark {\n font-family: var(--kf-font-title);\n font-weight: var(--kf-font-weight-title);\n font-size: var(--kf-font-size-title-lg);\n letter-spacing: -0.01em;\n }\n\n .kf-auth-layout__tagline {\n max-width: 34ch;\n margin: 0;\n font-family: var(--kf-font-body);\n font-size: var(--kf-font-size-body);\n color: rgba(255, 255, 255, 0.72);\n }\n\n .kf-auth-layout__content {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--kf-space-xl);\n }\n\n .kf-auth-layout__panel {\n width: 100%;\n max-width: 360px;\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-lg);\n }\n\n /* Oculto por default — el logo \"grande\" de .kf-auth-layout__brand ya\n cumple ese rol en desktop. Solo se muestra bajo el breakpoint donde\n ese panel se oculta (ver abajo). */\n .kf-auth-layout__mobile-brand {\n display: none;\n }\n\n .kf-auth-layout__logo--mobile {\n height: 1.5rem;\n }\n\n .kf-auth-layout__wordmark--mobile {\n color: var(--kf-color-ink);\n }\n\n /* Punto donde el sidebar del resto del ecosistema pasa a drawer\n off-canvas (ver css/otd.css del design system) — acá el panel de\n marca completo se oculta (no se apila arriba: en una pantalla de\n este ancho el usuario vino a loguearse, no a leer la tagline), pero\n un logo compacto se mantiene visible arriba del formulario. */\n @media (max-width: 900px) {\n :host {\n grid-template-columns: 1fr;\n }\n\n .kf-auth-layout__brand {\n display: none;\n }\n\n .kf-auth-layout__content {\n padding: var(--kf-space-lg);\n }\n\n .kf-auth-layout__mobile-brand {\n display: block;\n margin-bottom: var(--kf-space-md);\n }\n }\n\n @media (max-width: 480px) {\n .kf-auth-layout__panel {\n max-width: none;\n }\n }\n `,\n})\nexport class AuthLayout {\n /** Nombre de marca/portal, usado como wordmark de respaldo si no hay ningún logo, y como `alt` de ambos logos. */\n readonly brand = input.required<string>();\n\n /** Logo en blanco para el panel oscuro de desktop — si no se pasa, se muestra `brand()` como wordmark tipográfico. */\n readonly brandLogoSrc = input<string>();\n\n /** Frase corta bajo el logo — opcional, cada portal decide su propio texto de marca. */\n readonly brandTagline = input<string>();\n\n /**\n * Logo compacto para mobile, sobre el fondo claro del panel de contenido\n * — normalmente la variante oscura/negra del mismo logo, ya que\n * `brandLogoSrc` suele ser la variante blanca pensada para el gradiente\n * oscuro. Si no se pasa, reutiliza `brandLogoSrc`; si tampoco hay logo en\n * absoluto, cae al wordmark tipográfico igual que en desktop.\n */\n readonly brandLogoMobileSrc = input<string>();\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport { booleanAttribute, Component, computed, input } from '@angular/core';\n\n/**\n * Avatar de usuario: muestra una foto (`src`) o, si no hay foto, las\n * iniciales (`initials`) sobre un fondo con gradiente de marca. `round`\n * controla la forma: circular (por defecto) o cuadrada con radio.\n *\n * Con `pill`, el avatar se envuelve en una pastilla azul con un chevron a la\n * derecha — la \"pill de usuario (header)\" de la página 18 del design system,\n * usada en la barra de sesión del Portal Header.\n *\n * <kf-avatar initials=\"JD\" />\n * <kf-avatar src=\"https://…/foto.jpg\" [round]=\"false\" />\n * <kf-avatar initials=\"TS\" pill />\n *\n * Pendiente: si en el futuro se agrega un ícono de fallback (persona\n * genérica) para cuando no hay ni `src` ni `initials`, depende del\n * componente Icon / sprite SVG que todavía no existe en esta librería.\n */\n@Component({\n selector: 'kf-avatar',\n imports: [NgTemplateOutlet],\n template: `\n <ng-template #avatarCircle>\n <span class=\"kf-avatar\" [class.kf-avatar--square]=\"!round()\">\n @if (src()) {\n <img class=\"kf-avatar__image\" [src]=\"src()\" [alt]=\"initials() || ''\" />\n } @else {\n <span class=\"kf-avatar__initials\">{{ displayInitials() }}</span>\n }\n </span>\n </ng-template>\n\n @if (pill()) {\n <span class=\"kf-avatar-pill\">\n <ng-container [ngTemplateOutlet]=\"avatarCircle\" />\n <span class=\"kf-avatar-pill__caret\" aria-hidden=\"true\"></span>\n </span>\n } @else {\n <ng-container [ngTemplateOutlet]=\"avatarCircle\" />\n }\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-avatar {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n inline-size: 40px;\n block-size: 40px;\n overflow: hidden;\n border-radius: var(--kf-radius-pill);\n background: linear-gradient(135deg, var(--kf-color-primary), var(--kf-color-primary-active));\n color: var(--kf-color-white);\n font: inherit;\n font-size: 0.875rem;\n font-weight: 600;\n line-height: 1;\n user-select: none;\n flex: none;\n }\n .kf-avatar--square {\n border-radius: var(--kf-radius-sm);\n }\n .kf-avatar__image {\n inline-size: 100%;\n block-size: 100%;\n object-fit: cover;\n }\n .kf-avatar__initials {\n text-transform: uppercase;\n }\n\n /* Pill de usuario (header) — envuelve el avatar en una pastilla azul con chevron. */\n .kf-avatar-pill {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: 4px var(--kf-space-sm) 4px 4px;\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-primary);\n cursor: pointer;\n }\n .kf-avatar-pill .kf-avatar {\n inline-size: 32px;\n block-size: 32px;\n background: rgba(255, 255, 255, 0.18);\n }\n .kf-avatar-pill__caret {\n flex: none;\n width: 8px;\n height: 8px;\n border-right: 2px solid var(--kf-color-white);\n border-bottom: 2px solid var(--kf-color-white);\n transform: rotate(45deg);\n margin-top: -4px;\n }\n `,\n})\nexport class Avatar {\n readonly initials = input<string>();\n readonly src = input<string>();\n readonly round = input(true);\n /** Envuelve el avatar en la pastilla de sesión del header, con chevron. */\n readonly pill = input(false, { transform: booleanAttribute });\n\n /** Limita a 2 caracteres para que quepan cómodos dentro del círculo. */\n readonly displayInitials = computed(() => (this.initials() ?? '').slice(0, 2));\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\n\n/**\n * Pill chica de fondo suave (soft) para un conteo, tag o estado liviano\n * puntual (no un proceso en vivo — para eso existe `kf-status-pill`, que usa\n * borde en vez de relleno). El color de fondo/texto/punto depende de `tone`.\n *\n * El PDF (página 10) fija seis tonos con fondo soft y texto del tono fuerte\n * — nunca fondo saturado con texto blanco, que es más apto para un botón\n * que para una etiqueta de lectura rápida en una lista densa.\n *\n * <kf-badge tone=\"ok\" dot>Al día</kf-badge>\n * <kf-badge tone=\"error\">3</kf-badge>\n *\n * Mapeo de `tone` a los seis conceptos de la página 10 y sus tokens\n * semánticos en projects/ui/src/tokens/base.css:\n * neutral -> Neutral (border/text-muted), info -> Información (info-soft/-strong),\n * ok -> Activo (success-soft/-strong), warn -> Pendiente (warning-soft/-strong),\n * error -> Vencido (error-soft/-strong), service -> Servicio (secondary-soft,\n * no existe un `-strong` para secondary todavía — usa el color base).\n */\n@Component({\n selector: 'kf-badge',\n template: `\n <span class=\"kf-badge\" [class]=\"'kf-badge--' + tone()\">\n @if (dot()) {\n <span class=\"kf-badge__dot\"></span>\n }\n <ng-content />\n </span>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-badge {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border-radius: var(--kf-radius-pill);\n font: inherit;\n font-size: 0.75rem;\n font-weight: 600;\n line-height: 1;\n white-space: nowrap;\n background: var(--kf-color-border);\n color: var(--kf-color-text-muted);\n }\n .kf-badge__dot {\n inline-size: 6px;\n block-size: 6px;\n border-radius: var(--kf-radius-pill);\n flex: none;\n background: currentColor;\n }\n .kf-badge--neutral {\n background: var(--kf-color-border);\n color: var(--kf-color-text-muted);\n }\n .kf-badge--ok {\n background: var(--kf-color-success-soft);\n color: var(--kf-color-success-strong);\n }\n .kf-badge--warn {\n background: var(--kf-color-warning-soft);\n color: var(--kf-color-warning-strong);\n }\n .kf-badge--error {\n background: var(--kf-color-error-soft);\n color: var(--kf-color-error-strong);\n }\n .kf-badge--info {\n background: var(--kf-color-info-soft);\n color: var(--kf-color-info-strong);\n }\n .kf-badge--service {\n background: var(--kf-color-secondary-soft);\n color: var(--kf-color-secondary-strong);\n }\n `,\n})\nexport class Badge {\n readonly tone = input<'neutral' | 'ok' | 'warn' | 'error' | 'info' | 'service'>('neutral');\n readonly dot = input(false, { transform: booleanAttribute });\n}\n","import { Component, computed, input, output } from '@angular/core';\n\nexport interface BreadcrumbItem {\n label: string;\n /** Destino del link. Sin `href` el nivel se rinde como texto plano. */\n href?: string;\n}\n\n/**\n * Ruta de navegación de las vistas internas. El último nivel es la página\n * actual: nunca es link y lleva `aria-current=\"page\"`, aunque traiga `href`.\n *\n * Se rinde como `<nav><ol>` — es una lista ordenada de ancestros, y eso es lo\n * que los lectores de pantalla anuncian (\"navegación, lista de 3 elementos\").\n *\n * Para apps con router: escuchar `itemClick` y llamar\n * `event.preventDefault()` antes de `router.navigate(...)`. El `href` se\n * mantiene igual para que click-medio, \"abrir en pestaña nueva\" y el hover\n * de la barra de estado sigan funcionando.\n *\n * <kf-breadcrumb [items]=\"[{ label: 'Inicio', href: '/' }, { label: 'Mis vehículos' }]\" />\n */\n@Component({\n selector: 'kf-breadcrumb',\n template: `\n <nav class=\"kf-breadcrumb\" aria-label=\"Ruta de navegación\">\n <ol class=\"kf-breadcrumb__list\">\n @for (item of items(); track $index; let i = $index) {\n <li class=\"kf-breadcrumb__item\">\n @if (i > 0) {\n <svg\n class=\"kf-breadcrumb__separator\"\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path d=\"M9 6l6 6-6 6\" />\n </svg>\n }\n @if (item.href && i !== lastIndex()) {\n <a\n class=\"kf-breadcrumb__link\"\n [href]=\"item.href\"\n (click)=\"itemClick.emit({ item, index: i, event: $event })\"\n >\n {{ item.label }}\n </a>\n } @else {\n <span\n class=\"kf-breadcrumb__current\"\n [attr.aria-current]=\"i === lastIndex() ? 'page' : null\"\n >\n {{ item.label }}\n </span>\n }\n </li>\n }\n </ol>\n </nav>\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n font-size: 0.875rem;\n }\n .kf-breadcrumb__list {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--kf-space-xs);\n margin: 0;\n padding: 0;\n list-style: none;\n }\n .kf-breadcrumb__item {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n min-width: 0;\n }\n .kf-breadcrumb__separator {\n flex: none;\n width: 1em;\n height: 1em;\n fill: none;\n stroke: var(--kf-color-border-strong);\n stroke-width: 1.9;\n stroke-linecap: round;\n stroke-linejoin: round;\n }\n .kf-breadcrumb__link {\n color: var(--kf-color-primary);\n text-decoration: none;\n border-radius: var(--kf-radius-xs);\n transition: color 0.14s;\n }\n .kf-breadcrumb__link:hover {\n text-decoration: underline;\n }\n .kf-breadcrumb__link:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-breadcrumb__current {\n color: var(--kf-color-text-muted);\n overflow-wrap: anywhere;\n }\n `,\n})\nexport class Breadcrumb {\n readonly items = input.required<BreadcrumbItem[]>();\n\n /**\n * Click en un nivel con `href`. Incluye el `MouseEvent` para que un\n * consumidor con router pueda cortar la navegación nativa.\n *\n * ponytail: no dependemos de `@angular/router` acá — sería un peer dep\n * nuevo en la librería para lo que el consumidor resuelve en una línea.\n */\n readonly itemClick = output<{ item: BreadcrumbItem; index: number; event: MouseEvent }>();\n\n protected readonly lastIndex = computed(() => this.items().length - 1);\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\n\n/**\n * Contenedor base con esquinas redondeadas y sombra sutil — la base visual\n * de paneles, tarjetas de métrica, tablas y bloques de contenido de todo el\n * portal (ver página 14 del design system).\n *\n * Piensa este componente como el \"cimiento\": no impone estructura interna\n * más allá de dos slots opcionales alrededor del contenido libre —\n * `[media]` para una imagen/ícono destacado arriba, y `[actions]` para una\n * fila de botones al pie, separada por una línea. El contenido por defecto\n * (sin selector) queda en el medio, sin ningún layout forzado, para que\n * cualquier composición (una métrica, una lista, un formulario) pueda vivir\n * dentro sin pelear con estilos propios del `Card`.\n *\n * <kf-card>Contenido simple</kf-card>\n * <kf-card flush>Sin sombra — para superficies ya delimitadas por otra card</kf-card>\n * <kf-card>\n * <img kf-card-media src=\"...\" alt=\"\" />\n * <h3>Título</h3>\n * <p>Descripción</p>\n * <div kf-card-actions>\n * <kf-button variant=\"ghost\">Cancelar</kf-button>\n * <kf-button>Guardar</kf-button>\n * </div>\n * </kf-card>\n */\n@Component({\n selector: 'kf-card',\n template: `\n <ng-content select=\"[kf-card-media]\" />\n <div class=\"kf-card__body\">\n <ng-content />\n </div>\n <ng-content select=\"[kf-card-actions]\" />\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n box-shadow: var(--kf-shadow-xs);\n overflow: hidden;\n }\n :host.kf-card--flush {\n box-shadow: none;\n }\n .kf-card__body {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-md);\n flex: 1 1 auto;\n }\n ::ng-deep [kf-card-media] {\n display: block;\n inline-size: 100%;\n block-size: auto;\n object-fit: cover;\n }\n ::ng-deep [kf-card-actions] {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-sm) var(--kf-space-md);\n border-top: 1px solid var(--kf-color-border);\n }\n `,\n host: {\n '[class.kf-card--flush]': 'flush()',\n },\n})\nexport class Card {\n /** Quita la sombra — para cards anidadas dentro de otra superficie ya elevada. */\n readonly flush = input(false, { transform: booleanAttribute });\n}\n","import {\n AfterContentInit,\n Component,\n DestroyRef,\n contentChildren,\n inject,\n input,\n numberAttribute,\n output,\n signal,\n} from '@angular/core';\nimport { Icon } from '../icon/Icon';\n\n/**\n * Slide individual de un `kf-carousel`. Es un contenedor mínimo: solo existe\n * para que el carrusel pueda detectar, vía `contentChildren`, cuántos slides\n * se proyectaron y en qué orden — el contenido real es responsabilidad total\n * de quien lo consume.\n *\n * <kf-carousel-slide>...</kf-carousel-slide>\n */\n@Component({\n selector: 'kf-carousel-slide',\n template: `<ng-content />`,\n styles: `\n :host {\n display: block;\n flex: 0 0 100%;\n width: 100%;\n height: 100%;\n min-height: 0;\n }\n `,\n})\nexport class CarouselSlide {}\n\n/**\n * Carrusel de slides con flechas, dots y autoplay opcional.\n *\n * La spec original de React recibe `slides` como un array de nodos React.\n * En Angular eso no tiene equivalente directo: en vez de forzar un array de\n * datos crudos, cada slide se proyecta como contenido declarativo mediante\n * un `kf-carousel-slide` hijo, y el carrusel los detecta con\n * `contentChildren(CarouselSlide)`. Esto evita depender de un renderer de\n * nodos y deja que cada slide use plantillas Angular normales (bindings,\n * `@if`, `@for`, etc.) tal como se espera en este ecosistema.\n *\n * <kf-carousel [autoplay]=\"true\" [interval]=\"4000\" (indexChange)=\"onIndex($event)\">\n * <kf-carousel-slide>...</kf-carousel-slide>\n * <kf-carousel-slide>...</kf-carousel-slide>\n * </kf-carousel>\n */\n@Component({\n selector: 'kf-carousel',\n imports: [Icon],\n template: `\n <div\n class=\"kf-carousel\"\n (mouseenter)=\"pauseAutoplay()\"\n (mouseleave)=\"resumeAutoplay()\"\n (focusin)=\"pauseAutoplay()\"\n (focusout)=\"resumeAutoplay()\"\n >\n <div class=\"kf-carousel__viewport\">\n <div\n class=\"kf-carousel__track\"\n [style.transform]=\"'translateX(-' + activeIndex() * 100 + '%)'\"\n >\n <ng-content />\n </div>\n </div>\n\n @if (slides().length > 1) {\n <div class=\"kf-carousel__controls\">\n <div class=\"kf-carousel__dots\" role=\"tablist\">\n @for (slide of slides(); track slide; let i = $index) {\n <button\n type=\"button\"\n role=\"tab\"\n class=\"kf-carousel__dot\"\n [class.kf-carousel__dot--active]=\"i === activeIndex()\"\n [attr.aria-selected]=\"i === activeIndex()\"\n [attr.aria-label]=\"'Ir al slide ' + (i + 1)\"\n (click)=\"goTo(i)\"\n ></button>\n }\n </div>\n <button\n type=\"button\"\n class=\"kf-carousel__arrow\"\n aria-label=\"Slide anterior\"\n (click)=\"previous()\"\n >\n <kf-icon name=\"chevron-left\" size=\"sm\" />\n </button>\n <button\n type=\"button\"\n class=\"kf-carousel__arrow\"\n aria-label=\"Slide siguiente\"\n (click)=\"next()\"\n >\n <kf-icon name=\"chevron-right\" size=\"sm\" />\n </button>\n </div>\n }\n </div>\n `,\n styles: `\n :host {\n display: block;\n height: 100%;\n font-family: var(--kf-font-body);\n }\n .kf-carousel {\n position: relative;\n height: 100%;\n }\n .kf-carousel__viewport {\n height: 100%;\n overflow: hidden;\n border-radius: var(--kf-radius-md);\n }\n .kf-carousel__track {\n display: flex;\n height: 100%;\n transition: transform 0.32s ease;\n }\n .kf-carousel__controls {\n position: absolute;\n z-index: 2;\n right: var(--kf-space-sm);\n bottom: var(--kf-space-sm);\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n }\n .kf-carousel__arrow {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 1.75rem;\n height: 1.75rem;\n border: 1px solid rgb(255 255 255 / 22%);\n border-radius: var(--kf-radius-pill);\n background: rgb(255 255 255 / 12%);\n /* kf-icon usa currentColor — el SVG hereda este blanco sin más CSS. */\n color: #fff;\n cursor: pointer;\n transition: background 0.14s;\n }\n .kf-carousel__arrow:hover {\n background: rgb(255 255 255 / 24%);\n }\n .kf-carousel__arrow:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px rgb(255 255 255 / 60%);\n }\n .kf-carousel__dots {\n display: flex;\n gap: var(--kf-space-xs);\n }\n .kf-carousel__dot {\n width: 7px;\n height: 7px;\n padding: 0;\n border: none;\n border-radius: var(--kf-radius-pill);\n background: rgb(255 255 255 / 35%);\n cursor: pointer;\n transition:\n background 0.14s,\n width 0.14s;\n }\n .kf-carousel__dot:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px rgb(255 255 255 / 60%);\n }\n .kf-carousel__dot--active {\n width: 1.125rem;\n border-radius: var(--kf-radius-xs);\n background: #fff;\n }\n `,\n})\nexport class Carousel implements AfterContentInit {\n readonly autoplay = input(false);\n readonly interval = input(5000, { transform: numberAttribute });\n readonly indexChange = output<number>();\n\n readonly slides = contentChildren(CarouselSlide);\n\n private readonly activeIndexSignal = signal(0);\n readonly activeIndex = this.activeIndexSignal.asReadonly();\n\n private readonly destroyRef = inject(DestroyRef);\n private timer: ReturnType<typeof setInterval> | null = null;\n private autoplayPaused = false;\n\n ngAfterContentInit(): void {\n this.startAutoplay();\n this.destroyRef.onDestroy(() => this.stopAutoplay());\n }\n\n next(): void {\n const total = this.slides().length;\n if (total === 0) {\n return;\n }\n this.goTo((this.activeIndexSignal() + 1) % total);\n }\n\n previous(): void {\n const total = this.slides().length;\n if (total === 0) {\n return;\n }\n this.goTo((this.activeIndexSignal() - 1 + total) % total);\n }\n\n goTo(index: number): void {\n if (index === this.activeIndexSignal()) {\n return;\n }\n this.activeIndexSignal.set(index);\n this.indexChange.emit(index);\n }\n\n pauseAutoplay(): void {\n this.autoplayPaused = true;\n }\n\n resumeAutoplay(): void {\n this.autoplayPaused = false;\n }\n\n private startAutoplay(): void {\n if (!this.autoplay() || this.slides().length <= 1) {\n return;\n }\n this.timer = setInterval(() => {\n if (!this.autoplayPaused) {\n this.next();\n }\n }, this.interval());\n }\n\n private stopAutoplay(): void {\n if (this.timer !== null) {\n clearInterval(this.timer);\n this.timer = null;\n }\n }\n}\n","import {\n booleanAttribute,\n Component,\n effect,\n ElementRef,\n forwardRef,\n input,\n output,\n viewChild,\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\n/**\n * Checkbox accesible con soporte de estado \"indeterminate\".\n *\n * `indeterminate` no existe como atributo HTML: el navegador solo lo expone\n * como propiedad del elemento nativo, así que se aplica a mano sobre el\n * `<input>` interno vía `viewChild` + `effect` cada vez que cambia el input.\n *\n * Implementa `ControlValueAccessor` para poder usarse con `formControlName` /\n * `ngModel` igual que un checkbox nativo. En ese modo, `writeValue` controla\n * el DOM directamente y el input `checked` (pensado para binding manual sin\n * forms) queda en su valor por defecto — igual que `disabled` combina el\n * input signal con `setDisabledState` en el resto de la librería.\n *\n * `invalid` pinta el recuadro en rojo y setea `aria-invalid` en el `<input>`\n * nativo — mismo mecanismo que `Input.invalid`, para el caso típico de un\n * checkbox obligatorio (ej. \"Acepto términos y condiciones\") sin marcar.\n *\n * <kf-checkbox label=\"Aceptar términos\" [(checked)]=\"accepted\" />\n * <kf-checkbox label=\"Seleccionar todo\" [indeterminate]=\"isPartial()\" />\n * <kf-checkbox label=\"Notificaciones\" formControlName=\"notifications\" />\n * <kf-checkbox label=\"Acepto los términos y condiciones\" [invalid]=\"submitted() && !accepted()\" />\n */\n@Component({\n selector: 'kf-checkbox',\n template: `\n <label class=\"kf-checkbox\" [class.kf-checkbox--disabled]=\"disabled()\">\n <input\n #inputRef\n type=\"checkbox\"\n [checked]=\"checked()\"\n [disabled]=\"disabled()\"\n [attr.aria-invalid]=\"invalid() ? true : null\"\n (change)=\"onChange($event)\"\n (blur)=\"onTouched()\"\n />\n <span class=\"kf-checkbox__box\" [class.kf-checkbox__box--invalid]=\"invalid()\"></span>\n @if (label()) {\n <span class=\"kf-checkbox__label\">{{ label() }}</span>\n }\n </label>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-checkbox {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-sm);\n cursor: pointer;\n font: inherit;\n font-family: var(--kf-font-body);\n color: var(--kf-color-text);\n }\n .kf-checkbox--disabled {\n cursor: not-allowed;\n color: var(--kf-color-text-muted);\n }\n .kf-checkbox input {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n .kf-checkbox__box {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--kf-space-md);\n height: var(--kf-space-md);\n border: 1px solid var(--kf-color-border-strong);\n border-radius: var(--kf-radius-xs);\n background: var(--kf-color-white);\n transition:\n background 0.14s,\n border-color 0.14s;\n }\n .kf-checkbox input:checked + .kf-checkbox__box,\n .kf-checkbox input:indeterminate + .kf-checkbox__box {\n background: var(--kf-color-primary);\n border-color: var(--kf-color-primary);\n }\n .kf-checkbox input:checked + .kf-checkbox__box::after {\n content: '';\n width: 4px;\n height: 8px;\n border: solid var(--kf-color-white);\n border-width: 0 2px 2px 0;\n transform: rotate(45deg) translate(-1px, -1px);\n }\n .kf-checkbox input:indeterminate + .kf-checkbox__box::after {\n content: '';\n width: 8px;\n height: 2px;\n background: var(--kf-color-white);\n border-radius: var(--kf-radius-xs);\n }\n .kf-checkbox input:focus-visible + .kf-checkbox__box {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-checkbox__box--invalid {\n border-color: var(--kf-color-error);\n }\n .kf-checkbox--disabled .kf-checkbox__box {\n opacity: 0.5;\n }\n .kf-checkbox__label {\n user-select: none;\n }\n `,\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => Checkbox),\n multi: true,\n },\n ],\n})\nexport class Checkbox implements ControlValueAccessor {\n readonly label = input<string>();\n readonly checked = input(false, { transform: booleanAttribute });\n readonly disabled = input(false, { transform: booleanAttribute });\n readonly indeterminate = input(false, { transform: booleanAttribute });\n /** Recuadro en rojo + aria-invalid — ej. checkbox obligatorio sin marcar. */\n readonly invalid = input(false, { transform: booleanAttribute });\n\n readonly checkedChange = output<boolean>();\n\n private readonly inputRef = viewChild.required<ElementRef<HTMLInputElement>>('inputRef');\n\n /** Callbacks registrados por Forms; no-op hasta que registerOnChange/Touched las reemplacen. */\n private onChangeFn: (value: boolean) => void = () => {};\n private onTouchedFn: () => void = () => {};\n\n constructor() {\n // El estado \"indeterminate\" no tiene atributo HTML: hay que empujarlo\n // como propiedad DOM cada vez que cambia el input, incluyendo el\n // valor inicial del primer render.\n effect(() => {\n this.inputRef().nativeElement.indeterminate = this.indeterminate();\n });\n }\n\n onChange(event: Event): void {\n const value = (event.target as HTMLInputElement).checked;\n this.checkedChange.emit(value);\n this.onChangeFn(value);\n }\n\n onTouched(): void {\n this.onTouchedFn();\n }\n\n writeValue(value: boolean): void {\n this.inputRef().nativeElement.checked = !!value;\n }\n\n registerOnChange(fn: (value: boolean) => void): void {\n this.onChangeFn = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouchedFn = fn;\n }\n\n setDisabledState?(isDisabled: boolean): void {\n this.inputRef().nativeElement.disabled = isDisabled;\n }\n}\n","import { Component, input } from '@angular/core';\n\n/**\n * Chip de fondo suave con un punto líder que indica estado. Pensado\n * principalmente para celdas de tabla (estado de fila), pero utilizable\n * en cualquier lugar donde se necesite una etiqueta de estado compacta.\n *\n * <kf-chip tone=\"warn\">Pendiente</kf-chip>\n * <kf-chip tone=\"ok\">Aprobado</kf-chip>\n *\n * Nota: la spec original define la unión de tonos como \"ok\" | \"warn\" |\n * \"error\" | \"neutral\". Internamente se mapean a los tokens semánticos de\n * projects/ui/src/tokens/base.css: ok -> success, warn -> warning,\n * error -> error, neutral -> surface/border/text-muted (no existe un\n * token \"neutral\" dedicado en base.css, así que se arma con los tokens\n * de superficie/borde/texto-muted más cercanos).\n */\n@Component({\n selector: 'kf-chip',\n template: `\n <span\n class=\"kf-chip__dot\"\n [class.kf-chip__dot--ok]=\"tone() === 'ok'\"\n [class.kf-chip__dot--warn]=\"tone() === 'warn'\"\n [class.kf-chip__dot--error]=\"tone() === 'error'\"\n [class.kf-chip__dot--neutral]=\"tone() === 'neutral'\"\n ></span>\n <span class=\"kf-chip__label\"><ng-content /></span>\n `,\n styles: `\n :host {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border-radius: var(--kf-radius-pill);\n border: 1px solid transparent;\n font: inherit;\n font-size: 0.875em;\n line-height: 1;\n color: var(--kf-color-text);\n background: var(--kf-color-surface);\n border-color: var(--kf-color-border);\n white-space: nowrap;\n }\n :host(.kf-chip--ok) {\n background: var(--kf-color-success-soft);\n border-color: var(--kf-color-success-soft);\n color: var(--kf-color-text);\n }\n :host(.kf-chip--warn) {\n background: var(--kf-color-warning-soft);\n border-color: var(--kf-color-warning-soft);\n color: var(--kf-color-text);\n }\n :host(.kf-chip--error) {\n background: var(--kf-color-error-soft);\n border-color: var(--kf-color-error-soft);\n color: var(--kf-color-text);\n }\n :host(.kf-chip--neutral) {\n background: var(--kf-color-surface);\n border-color: var(--kf-color-border);\n color: var(--kf-color-text);\n }\n .kf-chip__dot {\n inline-size: 0.5em;\n block-size: 0.5em;\n border-radius: var(--kf-radius-pill);\n flex: none;\n background: var(--kf-color-text-muted);\n }\n .kf-chip__label {\n display: inline-block;\n }\n .kf-chip__dot--ok {\n background: var(--kf-color-success);\n }\n .kf-chip__dot--warn {\n background: var(--kf-color-warning);\n }\n .kf-chip__dot--error {\n background: var(--kf-color-error);\n }\n .kf-chip__dot--neutral {\n background: var(--kf-color-text-muted);\n }\n `,\n host: {\n '[class.kf-chip--ok]': \"tone() === 'ok'\",\n '[class.kf-chip--warn]': \"tone() === 'warn'\",\n '[class.kf-chip--error]': \"tone() === 'error'\",\n '[class.kf-chip--neutral]': \"tone() === 'neutral'\",\n },\n})\nexport class Chip {\n readonly tone = input<'ok' | 'warn' | 'error' | 'neutral'>('neutral');\n}\n","import { Component, input } from '@angular/core';\n\nexport type DividerOrientation = 'horizontal' | 'vertical';\n\n/**\n * Separador visual simple entre bloques de contenido. `orientation`\n * controla si es una línea horizontal (para separar secciones apiladas) o\n * vertical (para separar elementos en una fila, ej. acciones en una toolbar,\n * o las columnas de metadata en `kf-company-selector`).\n *\n * En `vertical`, el divisor necesita una altura del contexto donde vive —\n * `:host { align-self: stretch }` lo hace ocupar la altura del contenedor\n * flex/grid padre sin que el consumidor tenga que fijarla a mano. `flex:\n * none` evita que el propio divisor se achique a 0 dentro de ese contenedor\n * flex cuando hay contenido hermano compitiendo por espacio.\n *\n * <kf-divider />\n * <kf-divider orientation=\"vertical\" />\n */\n@Component({\n selector: 'kf-divider',\n template: '',\n styles: `\n :host {\n display: block;\n flex: none;\n border: none;\n background: var(--kf-color-border);\n }\n :host,\n :host([orientation='horizontal']) {\n width: 100%;\n height: 1px;\n }\n :host([orientation='vertical']) {\n align-self: stretch;\n width: 1px;\n height: auto;\n }\n `,\n host: {\n role: 'separator',\n '[attr.orientation]': 'orientation()',\n '[attr.aria-orientation]': 'orientation()',\n },\n})\nexport class Divider {\n readonly orientation = input<DividerOrientation>('horizontal');\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\n\n/**\n * Label superior compartido por todos los campos de formulario del design\n * system (páginas 11-12: Text Field, Select, Multiselect) — uppercase,\n * chico, gris, con letter-spacing amplio. El PDF fija un único tratamiento\n * (\"PATENTE O VIN\", \"SUCURSAL\", \"SUCURSALES\" usan exactamente el mismo\n * estilo), así que este componente es la única fuente de verdad: antes vivía\n * copiado por separado en `Input`, `Select`, `SelectMenu` y `MultiSelect`,\n * y dos de esas copias ya habían divergido del estilo real del PDF.\n *\n * No reemplaza al `<label>` nativo — lo envuelve, para no perder la\n * asociación de accesibilidad `for`/`id` con el control real.\n *\n * `required` agrega un asterisco visual en el tono de error, separado del\n * texto por un espacio y marcado `aria-hidden` — el estado obligatorio real\n * para lectores de pantalla lo comunica el propio control (`aria-required`\n * / `required` en el `<input>`/`<select>` asociado), no este label.\n *\n * <kf-field-label [for]=\"inputId\">Patente o VIN</kf-field-label>\n * <kf-field-label [for]=\"inputId\" required>Correo electrónico</kf-field-label>\n */\n@Component({\n selector: 'kf-field-label',\n template: `\n <label class=\"kf-field-label\" [for]=\"for()\">\n <ng-content />\n @if (required()) {\n <span class=\"kf-field-label__required\" aria-hidden=\"true\">*</span>\n }\n </label>\n `,\n styles: `\n :host {\n display: contents;\n }\n .kf-field-label {\n font-family: var(--kf-font-title);\n font-size: 0.75rem;\n font-weight: 600;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--kf-color-text-muted);\n }\n .kf-field-label__required {\n color: var(--kf-color-error);\n margin-inline-start: 2px;\n }\n `,\n})\nexport class FieldLabel {\n /** `id` del control asociado — se refleja como `for` en el `<label>` interno. */\n readonly for = input<string>();\n /** Muestra un asterisco visual indicando que el campo es obligatorio. */\n readonly required = input(false, { transform: booleanAttribute });\n}\n","/**\n * Normaliza texto para comparación de búsqueda insensible a mayúsculas y\n * diacríticos — así \"cor\" encuentre \"Córdoba\" sin necesidad de tildes.\n *\n * Compartida entre `Select` y `MultiSelect` (los dos componentes con\n * buscador interno auto-activado por `searchThreshold`): antes vivía\n * duplicada letra por letra en ambos archivos.\n */\nexport function normalizeForSearch(text: string): string {\n return text.normalize('NFD').replace(/[̀-ͯ]/g, '').toLowerCase();\n}\n","import { Overlay, type OverlayRef } from '@angular/cdk/overlay';\nimport { TemplatePortal } from '@angular/cdk/portal';\nimport {\n Component,\n DestroyRef,\n ElementRef,\n HostListener,\n TemplateRef,\n ViewContainerRef,\n afterRenderEffect,\n booleanAttribute,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { FieldLabel } from '../field-label/FieldLabel';\nimport { normalizeForSearch } from '../shared/search-text';\n\n/** Normalized shape used internally once `options` (string[] or object[]) is resolved. */\ninterface SelectOption {\n value: string;\n label: string;\n}\n\nlet nextId = 0;\n\n/**\n * Dropdown de selección simple con panel propio — NUNCA usa el `<select>`\n * nativo del navegador. Un `<select>` real siempre delega el popup de\n * opciones al sistema operativo, y ningún CSS puede controlar cómo se ve\n * ese popup.\n *\n * Hasta la `0.1.5` existía además `kf-select-menu`, un segundo componente\n * prácticamente idéntico (mismo trigger, mismo panel, mismo CSS) que solo\n * se diferenciaba en aceptar `options` únicamente como `{ value, label }[]`\n * (sin el atajo `string[]` que `Select` ya tenía). Se fusionaron en este\n * componente en la `0.2.0` — mantener dos componentes con la misma\n * interacción y el mismo aspecto visual, cuya única diferencia real era la\n * forma de un input, no se sostenía como dos piezas separadas del catálogo.\n *\n * El panel flotante se conecta al trigger vía `@angular/cdk/overlay` — el\n * mismo mecanismo que `Dropdown` (ver `../dropdown/Dropdown.ts`).\n *\n * <kf-select label=\"Sede\" [options]=\"['Lima', 'Arequipa', 'Trujillo']\" placeholder=\"Selecciona…\" />\n * <kf-select [options]=\"[{ value: 'pe', label: 'Perú' }]\" (valueChange)=\"onCountry($event)\" />\n *\n * Pendiente: el prop `icon` de otros componentes del design system requiere\n * un componente Icon / sprite SVG que esta librería todavía no tiene — este\n * componente no usa iconos, así que no aplica acá.\n */\n@Component({\n selector: 'kf-select',\n imports: [FieldLabel],\n template: `\n @if (label()) {\n <kf-field-label [for]=\"triggerId\">{{ label() }}</kf-field-label>\n }\n <button\n #trigger\n type=\"button\"\n [id]=\"triggerId\"\n class=\"kf-select__trigger\"\n [class.kf-select__trigger--disabled]=\"disabled()\"\n [disabled]=\"disabled()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-controls]=\"isOpen() ? listboxId : null\"\n (click)=\"toggle()\"\n >\n <span class=\"kf-select__value\" [class.kf-select__value--placeholder]=\"!selectedOption()\">\n {{ selectedOption()?.label ?? placeholder() }}\n </span>\n <span\n class=\"kf-select__caret\"\n [class.kf-select__caret--open]=\"isOpen()\"\n aria-hidden=\"true\"\n ></span>\n </button>\n <ng-template #panelTemplate>\n <div class=\"kf-select__panel\">\n @if (showSearch()) {\n <input\n #searchInput\n type=\"text\"\n class=\"kf-select__search\"\n placeholder=\"Buscar…\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($event)\"\n (keydown.arrowdown)=\"$event.preventDefault(); moveActive(1)\"\n (keydown.arrowup)=\"$event.preventDefault(); moveActive(-1)\"\n (keydown.enter)=\"$event.preventDefault(); selectActive()\"\n />\n }\n <ul\n class=\"kf-select__list\"\n [id]=\"listboxId\"\n role=\"listbox\"\n [attr.aria-labelledby]=\"triggerId\"\n >\n @for (option of filteredOptions(); track option.value; let i = $index) {\n <li\n class=\"kf-select__option\"\n [class.kf-select__option--selected]=\"option.value === value()\"\n [class.kf-select__option--active]=\"i === activeIndex()\"\n role=\"option\"\n tabindex=\"0\"\n [attr.aria-selected]=\"option.value === value()\"\n (click)=\"select(option)\"\n (mouseenter)=\"activeIndex.set(i)\"\n (keydown.enter)=\"select(option)\"\n (keydown.space)=\"$event.preventDefault(); select(option)\"\n (keydown.arrowdown)=\"$event.preventDefault(); moveActive(1)\"\n (keydown.arrowup)=\"$event.preventDefault(); moveActive(-1)\"\n >\n {{ option.label }}\n </li>\n } @empty {\n <li class=\"kf-select__empty\">\n {{ searchQuery() ? 'Sin resultados' : 'Sin opciones disponibles' }}\n </li>\n }\n </ul>\n </div>\n </ng-template>\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n /*\n * Ancho FIJO, no min-width: un :host en flex sin ancho propio se\n * ajusta al contenido de su hijo en cada render — con min-width sí se\n * evita que se achique con una opción de label corto, pero seguía\n * pudiendo CRECER de más con una opción de label largo, desalineando\n * varios kf-select en fila dentro del mismo formulario (ej. \"Sede\" /\n * \"País\" / \"Divisiones\" ya no miden lo mismo entre sí). El texto que\n * no entra se corta con el text-overflow: ellipsis que\n * .kf-select__value ya tenía preparado — antes nunca se activaba\n * porque el host crecía en vez de cortar el texto.\n */\n width: 240px;\n font-family: var(--kf-font-body);\n }\n .kf-select__trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-sm);\n width: 100%;\n font: inherit;\n color: var(--kf-color-text);\n padding: var(--kf-space-sm) var(--kf-space-md);\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n cursor: pointer;\n transition:\n border-color 0.14s,\n box-shadow 0.14s;\n }\n .kf-select__trigger:hover:not(:disabled) {\n border-color: var(--kf-color-border-strong);\n }\n .kf-select__trigger:focus-visible {\n outline: none;\n border-color: var(--kf-color-primary);\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-select__trigger--disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .kf-select__value {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .kf-select__value--placeholder {\n color: var(--kf-color-text-muted);\n }\n .kf-select__caret {\n flex-shrink: 0;\n width: 8px;\n height: 8px;\n border-right: 2px solid var(--kf-color-text-muted);\n border-bottom: 2px solid var(--kf-color-text-muted);\n transform: rotate(45deg);\n transition: transform 0.14s;\n margin-top: -4px;\n }\n .kf-select__caret--open {\n transform: rotate(-135deg);\n margin-top: 4px;\n }\n .kf-select__panel {\n box-sizing: border-box;\n width: 100%;\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n box-shadow: var(--kf-shadow-md);\n overflow: hidden;\n }\n .kf-select__search {\n box-sizing: border-box;\n width: 100%;\n font: inherit;\n font-family: var(--kf-font-body);\n color: var(--kf-color-text);\n padding: var(--kf-space-sm) var(--kf-space-md);\n border: none;\n border-bottom: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm) var(--kf-radius-sm) 0 0;\n outline: none;\n }\n .kf-select__search:focus-visible {\n box-shadow: inset 0 0 0 2px var(--kf-color-primary);\n }\n .kf-select__list {\n box-sizing: border-box;\n width: 100%;\n margin: 0;\n padding: var(--kf-space-xs) 0;\n list-style: none;\n max-height: 240px;\n overflow-y: auto;\n scrollbar-width: thin;\n scrollbar-color: var(--kf-color-gray-400) transparent;\n }\n .kf-select__list::-webkit-scrollbar {\n width: 6px;\n }\n .kf-select__list::-webkit-scrollbar-track {\n background: transparent;\n }\n .kf-select__list::-webkit-scrollbar-thumb {\n background-color: var(--kf-color-gray-400);\n border-radius: var(--kf-radius-pill);\n }\n .kf-select__list::-webkit-scrollbar-thumb:hover {\n background-color: var(--kf-color-gray-500);\n }\n .kf-select__option {\n padding: var(--kf-space-sm) var(--kf-space-md);\n color: var(--kf-color-text);\n cursor: pointer;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .kf-select__option:hover {\n background: var(--kf-color-primary-soft);\n }\n .kf-select__option--selected {\n background: var(--kf-color-primary-soft);\n color: var(--kf-color-primary);\n font-weight: 600;\n }\n /* Opción con foco de teclado — distinta del hover, comparte el mismo tinte de fondo. */\n .kf-select__option--active {\n background: var(--kf-color-primary-soft);\n }\n .kf-select__empty {\n text-align: center;\n padding: var(--kf-space-sm) var(--kf-space-md);\n color: var(--kf-color-text-muted);\n }\n `,\n})\nexport class Select {\n readonly label = input<string>();\n readonly options = input.required<string[] | SelectOption[]>();\n readonly value = input<string>();\n readonly placeholder = input<string>('Seleccionar');\n readonly disabled = input(false, { transform: booleanAttribute });\n /**\n * Tri-state: si el consumidor no lo especifica (`undefined`), el buscador\n * se activa solo cuando `options().length` supera `searchThreshold()`. Si\n * el consumidor define `true`/`false` explícitamente, ese valor manda por\n * sobre el umbral automático.\n */\n readonly searchable = input<boolean | undefined>(undefined);\n readonly searchThreshold = input<number>(7);\n\n readonly valueChange = output<string>();\n\n private readonly instanceId = `kf-select-${nextId++}`;\n readonly triggerId = `${this.instanceId}-trigger`;\n readonly listboxId = `${this.instanceId}-listbox`;\n\n readonly isOpen = signal(false);\n readonly searchQuery = signal('');\n readonly activeIndex = signal(0);\n\n /** Resolves the union (`string[] | { value; label }[]`) into a single shape for the template. */\n readonly normalizedOptions = computed<SelectOption[]>(() =>\n this.options().map((option) =>\n typeof option === 'string' ? { value: option, label: option } : option,\n ),\n );\n\n readonly selectedOption = computed(() =>\n this.normalizedOptions().find((option) => option.value === this.value()),\n );\n\n readonly showSearch = computed(\n () => this.searchable() ?? this.normalizedOptions().length > this.searchThreshold(),\n );\n\n /** Opciones visibles tras aplicar el filtro de búsqueda (case/acento-insensitive). */\n readonly filteredOptions = computed<SelectOption[]>(() => {\n const query = normalizeForSearch(this.searchQuery().trim());\n if (!query) {\n return this.normalizedOptions();\n }\n return this.normalizedOptions().filter((option) =>\n normalizeForSearch(option.label).includes(query),\n );\n });\n\n private readonly triggerRef = viewChild.required<ElementRef<HTMLButtonElement>>('trigger');\n private readonly panelTemplate = viewChild.required<TemplateRef<unknown>>('panelTemplate');\n private readonly searchInputRef = viewChild<ElementRef<HTMLInputElement>>('searchInput');\n\n private readonly overlayService = inject(Overlay);\n private readonly viewContainerRef = inject(ViewContainerRef);\n private readonly destroyRef = inject(DestroyRef);\n\n private overlayRef: OverlayRef | null = null;\n\n constructor() {\n effect(() => {\n if (this.isOpen()) {\n this.attach();\n } else {\n this.detach();\n this.searchQuery.set('');\n this.activeIndex.set(0);\n }\n });\n\n // Autofocus del buscador al abrir. afterNextRender() NO puede invocarse\n // dentro de un effect() (NG0203: pierde el contexto de inyección) — hay\n // que usar afterRenderEffect(), que sí es reactivo a signals y corre\n // después de que Angular actualizó el DOM del panel recién adjuntado.\n afterRenderEffect(() => {\n if (this.isOpen() && this.showSearch()) {\n this.searchInputRef()?.nativeElement.focus();\n }\n });\n\n this.destroyRef.onDestroy(() => this.overlayRef?.dispose());\n }\n\n /**\n * Respaldo de `overlayRef.keydownEvents()`: ese observable del CDK solo ve\n * teclas presionadas con el foco DENTRO del pane del overlay. Si el foco\n * sigue en el trigger (o en cualquier otro lado de la página) mientras el\n * panel está abierto, `keydownEvents()` nunca dispara.\n */\n @HostListener('document:keydown.escape')\n onDocumentEscape(): void {\n this.isOpen.set(false);\n }\n\n toggle(): void {\n if (this.disabled()) {\n return;\n }\n this.isOpen.update((open) => !open);\n }\n\n select(option: SelectOption): void {\n this.isOpen.set(false);\n if (option.value !== this.value()) {\n this.valueChange.emit(option.value);\n }\n }\n\n onSearchInput(event: Event): void {\n this.searchQuery.set((event.target as HTMLInputElement).value);\n // Cada cambio de filtro vuelve a arrancar la navegación desde arriba.\n this.activeIndex.set(0);\n }\n\n /**\n * Mueve `activeIndex` sobre las opciones YA FILTRADAS visibles. Clamp\n * simple (sin wraparound): llegar al final o al principio de la lista se\n * queda ahí en vez de dar la vuelta — es el comportamiento más predecible\n * cuando se combina con un buscador que puede reducir la lista a 1 opción.\n */\n moveActive(delta: number): void {\n const count = this.filteredOptions().length;\n if (count === 0) {\n return;\n }\n this.activeIndex.update((current) => Math.min(Math.max(current + delta, 0), count - 1));\n }\n\n selectActive(): void {\n const option = this.filteredOptions()[this.activeIndex()];\n if (option) {\n this.select(option);\n }\n }\n\n private attach(): void {\n if (this.overlayRef?.hasAttached()) {\n return;\n }\n\n const overlayRef = this.getOrCreateOverlayRef();\n // Se remide el ancho del trigger en cada apertura, no solo la primera —\n // ver la misma nota en SelectMenu: cachear el ancho en la creación del\n // overlay lo deja desincronizado si el trigger cambia de tamaño entre\n // una apertura y la siguiente.\n overlayRef.updateSize({ width: this.triggerRef().nativeElement.getBoundingClientRect().width });\n\n const portal = new TemplatePortal(this.panelTemplate(), this.viewContainerRef);\n overlayRef.attach(portal);\n\n // outsidePointerEvents() dispara en la fase de CAPTURA de `click` sobre\n // `body` (ver OverlayOutsideClickDispatcher en @angular/cdk), es decir\n // ANTES de que el evento llegue al trigger y corra (click)=\"toggle()\".\n // Sin este filtro, un click en el trigger para CERRAR el panel ya abierto\n // hacía: 1) este subscribe lo cierra primero (el trigger no es parte del\n // overlay, cuenta como \"afuera\"), 2) toggle() corre después y lo vuelve a\n // abrir porque ve isOpen ya en false — un solo click quedaba en no-op y\n // solo cerraba de verdad un click fuera del trigger.\n overlayRef.outsidePointerEvents().subscribe((event) => {\n const target = event.target as Node | null;\n if (target && this.triggerRef().nativeElement.contains(target)) {\n return;\n }\n this.isOpen.set(false);\n });\n overlayRef.keydownEvents().subscribe((event) => {\n if (event.key === 'Escape') {\n this.isOpen.set(false);\n }\n });\n }\n\n private detach(): void {\n this.overlayRef?.detach();\n }\n\n private getOrCreateOverlayRef(): OverlayRef {\n if (this.overlayRef) {\n return this.overlayRef;\n }\n\n const positionStrategy = this.overlayService\n .position()\n .flexibleConnectedTo(this.triggerRef())\n .withPositions([\n { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 4 },\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -4 },\n { originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top', offsetY: 4 },\n { originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', offsetY: -4 },\n ])\n .withViewportMargin(8)\n .withPush(true);\n\n this.overlayRef = this.overlayService.create({\n positionStrategy,\n scrollStrategy: this.overlayService.scrollStrategies.reposition(),\n width: this.triggerRef().nativeElement.getBoundingClientRect().width,\n maxWidth: '90vw',\n });\n\n return this.overlayRef;\n }\n}\n","import { Component, input, output } from '@angular/core';\nimport { Divider } from '../divider/Divider';\nimport { Select } from '../select/Select';\n\n/** Metadato clave mostrado junto al selector (RUC, identificación, sucursal). */\nexport interface CompanySelectorMeta {\n label: string;\n value: string;\n}\n\n/**\n * Conmutador de empresa activa con metadatos clave (página 32) — encabeza\n * la pantalla de inicio del portal. Compone `kf-select` para el propio\n * selector (mismo panel propio, sin `<select>` nativo) y proyecta hasta 3\n * pares label/valor (RUC, Identificación, Sucursal en el ejemplo del PDF).\n *\n * <kf-company-selector\n * label=\"Selecciona empresa\"\n * [companies]=\"['TRANSPORTES DEL SUR S.A.C.', 'ANDES MAQ LTDA.']\"\n * [value]=\"activeCompany()\"\n * (valueChange)=\"activeCompany.set($event)\"\n * [meta]=\"[\n * { label: 'RUC', value: '20448712359' },\n * { label: 'Identificación', value: '0004002232' },\n * { label: 'Sucursal', value: 'Sucursal Norte' },\n * ]\"\n * />\n */\n@Component({\n selector: 'kf-company-selector',\n imports: [Divider, Select],\n template: `\n <kf-select\n class=\"kf-company-selector__select\"\n [label]=\"label()\"\n [options]=\"companies()\"\n [value]=\"value()\"\n (valueChange)=\"valueChange.emit($event)\"\n />\n @if (meta().length) {\n <div class=\"kf-company-selector__meta\">\n @for (item of meta(); track item.label; let last = $last) {\n <div class=\"kf-company-selector__meta-item\">\n <span class=\"kf-company-selector__meta-label\">{{ item.label }}</span>\n <span class=\"kf-company-selector__meta-value\">{{ item.value }}</span>\n </div>\n @if (!last) {\n <kf-divider orientation=\"vertical\" />\n }\n }\n </div>\n }\n `,\n styles: `\n :host {\n display: flex;\n align-items: center;\n gap: var(--kf-space-lg);\n flex-wrap: wrap;\n padding: var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n background: var(--kf-color-white);\n font-family: var(--kf-font-body);\n }\n .kf-company-selector__select {\n flex: 1 1 260px;\n min-width: 0;\n }\n .kf-company-selector__meta {\n display: flex;\n gap: var(--kf-space-lg);\n flex-wrap: wrap;\n }\n .kf-company-selector__meta-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n .kf-company-selector__meta-label {\n font-family: var(--kf-font-title);\n font-size: 0.72rem;\n font-weight: 600;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n color: var(--kf-color-text-muted);\n }\n .kf-company-selector__meta-value {\n font-family: var(--kf-font-mono);\n font-size: 0.875rem;\n color: var(--kf-color-ink);\n }\n `,\n})\nexport class CompanySelector {\n readonly label = input('Selecciona empresa');\n readonly companies = input.required<string[]>();\n readonly value = input<string>();\n readonly meta = input<CompanySelectorMeta[]>([]);\n\n readonly valueChange = output<string>();\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Marcador genérico para contenido aún por definir (página 38) — comunica\n * \"contenido disponible para uso\" sin parecer un error, a diferencia de\n * `kf-empty-state` (que comunica ausencia real de datos del usuario).\n * Pensado para secciones del portal que un negocio todavía no completó.\n *\n * `compact` reduce el tamaño de la imagen placeholder y omite el badge de\n * pie (segunda variante de la página 38, sin la etiqueta \"Contenido\n * disponible para uso\" al final).\n *\n * <kf-content-slot title=\"Contenido disponible\"\n * description=\"Espacio reservado para contenido de Divemotor Perú. Disponible para uso.\" />\n * <kf-content-slot compact icon=\"star\" title=\"Contenido disponible\"\n * description=\"Espacio reservado para contenido de Divemotor Perú.\" />\n */\n@Component({\n selector: 'kf-content-slot',\n imports: [Icon],\n template: `\n <div class=\"kf-content-slot__media\">\n <kf-icon [name]=\"icon()\" [size]=\"compact() ? 'md' : 'lg'\" />\n </div>\n <span class=\"kf-content-slot__title\">{{ title() }}</span>\n @if (description()) {\n <p class=\"kf-content-slot__description\">{{ description() }}</p>\n }\n @if (!compact()) {\n <span class=\"kf-content-slot__footer\">Contenido disponible para uso</span>\n }\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-white);\n font-family: var(--kf-font-body);\n }\n .kf-content-slot__media {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 96px;\n margin-bottom: var(--kf-space-xs);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-surface);\n color: var(--kf-color-border-strong);\n }\n :host(.kf-content-slot--compact) .kf-content-slot__media {\n height: 56px;\n }\n .kf-content-slot__title {\n font-family: var(--kf-font-title);\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-content-slot__description {\n margin: 0;\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n }\n .kf-content-slot__footer {\n align-self: flex-start;\n margin-top: var(--kf-space-xs);\n padding: 2px var(--kf-space-sm);\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-surface);\n color: var(--kf-color-text-muted);\n font-size: 0.72rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n }\n `,\n host: {\n '[class.kf-content-slot--compact]': 'compact()',\n },\n})\nexport class ContentSlot {\n readonly title = input('Contenido disponible');\n readonly description = input<string>();\n readonly icon = input<IconName>('layers');\n readonly compact = input(false, { transform: booleanAttribute });\n}\n","import { Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Placeholder para una sección sin contenido. Dos tonos, con anatomía\n * distinta (páginas 27-28 del design system, que los trata como piezas\n * separadas — \"Error State\" no es una variante de color de \"Empty State\",\n * es un estado semánticamente distinto):\n *\n * - `neutral` (default): \"cero resultados\" — cuadro con borde punteado\n * discreto, para listas vacías o búsquedas sin coincidencias. No es un\n * error, es la ausencia normal de datos.\n * - `error`: fallo real de carga — sin borde punteado, con un ícono de\n * alerta más prominente y texto en el tono de error. Pensado para usarse\n * junto a un botón \"Reintentar\" en el slot por defecto.\n *\n * <kf-empty-state>No se encontraron resultados.</kf-empty-state>\n * <kf-empty-state icon=\"search\">Sin coincidencias para tu búsqueda.</kf-empty-state>\n * <kf-empty-state tone=\"error\" icon=\"alert-triangle\">\n * No pudimos cargar tus vehículos\n * <kf-button (click)=\"retry()\">Reintentar</kf-button>\n * </kf-empty-state>\n */\n@Component({\n selector: 'kf-empty-state',\n imports: [Icon],\n template: `\n @if (icon(); as iconName) {\n <span class=\"kf-empty-state__icon\">\n <kf-icon [name]=\"iconName\" [size]=\"tone() === 'error' ? 'lg' : 'md'\" />\n </span>\n }\n <div class=\"kf-empty-state__content\">\n <ng-content />\n </div>\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-xl);\n border: 1px dashed var(--kf-color-border-strong);\n border-radius: var(--kf-radius-md);\n background: var(--kf-color-surface);\n color: var(--kf-color-text-muted);\n font: inherit;\n text-align: center;\n }\n :host(.kf-empty-state--error) {\n border: none;\n background: var(--kf-color-error-soft);\n }\n .kf-empty-state__content {\n color: var(--kf-color-text-muted);\n font-family: var(--kf-font-body);\n }\n :host(.kf-empty-state--error) .kf-empty-state__content {\n color: var(--kf-color-error-strong);\n }\n `,\n host: {\n '[class.kf-empty-state--error]': \"tone() === 'error'\",\n },\n})\nexport class EmptyState {\n readonly icon = input<IconName | undefined>(undefined);\n /** `neutral` (default): cero resultados. `error`: fallo real de carga. */\n readonly tone = input<'neutral' | 'error'>('neutral');\n}\n","import { Component, input } from '@angular/core';\n\n/** Forma del placeholder. */\nexport type SkeletonVariant = 'text' | 'circle' | 'rect';\n\n/**\n * Bloque placeholder con shimmer para contenido que todavía carga: una línea\n * de texto, un avatar o un área de card/imagen, según `variant`.\n *\n * Es decorativo (`aria-hidden`): quien lo usa debería marcar el contenedor con\n * `aria-busy=\"true\"` mientras carga, así el lector de pantalla anuncia el\n * estado una vez en vez de leer N placeholders vacíos.\n *\n * `circle` usa `aspect-ratio`, así que alcanza con darle `width`.\n *\n * <kf-skeleton />\n * <kf-skeleton variant=\"circle\" width=\"40px\" />\n * <kf-skeleton variant=\"rect\" width=\"100%\" height=\"120px\" />\n */\n@Component({\n selector: 'kf-skeleton',\n template: `\n <span\n class=\"kf-skeleton\"\n [class]=\"'kf-skeleton--' + variant()\"\n aria-hidden=\"true\"\n [style.width]=\"width()\"\n [style.height]=\"height() || null\"\n ></span>\n `,\n styles: `\n :host {\n display: block;\n }\n .kf-skeleton {\n display: block;\n background: linear-gradient(\n 90deg,\n var(--kf-color-border) 25%,\n var(--kf-color-surface) 37%,\n var(--kf-color-border) 63%\n );\n background-size: 400% 100%;\n animation: kf-skeleton-shimmer 1.4s ease infinite;\n }\n .kf-skeleton--text {\n height: 14px;\n border-radius: var(--kf-radius-xs);\n }\n .kf-skeleton--rect {\n height: 80px;\n border-radius: var(--kf-radius-sm);\n }\n .kf-skeleton--circle {\n aspect-ratio: 1 / 1;\n border-radius: var(--kf-radius-pill);\n }\n @keyframes kf-skeleton-shimmer {\n from {\n background-position: 100% 0;\n }\n to {\n background-position: 0 0;\n }\n }\n @media (prefers-reduced-motion: reduce) {\n .kf-skeleton {\n animation: none;\n background: var(--kf-color-border);\n }\n }\n `,\n})\nexport class Skeleton {\n readonly variant = input<SkeletonVariant>('text');\n /** Ancho CSS. Default `'100%'`. */\n readonly width = input('100%');\n /** Alto CSS. Vacío deja el alto/aspect-ratio propio de la variante. */\n readonly height = input('');\n}\n","import { Component, input } from '@angular/core';\nimport { EmptyState } from '../empty-state/EmptyState';\nimport { Skeleton } from '../skeleton/Skeleton';\nimport { Spinner } from '../spinner/Spinner';\n\n/** En qué estado está la sección. */\nexport type ContentStateKind = 'ready' | 'loading' | 'empty' | 'error';\n\n/** Cómo se dibuja `loading`. Default `'skeleton'`. */\nexport type ContentStateLoad = 'skeleton' | 'spinner';\n\n/**\n * Wrapper de los cuatro estados que toda sección tiene: cargando, con datos,\n * vacía y con error. Un componente en vez de tres `@if` sueltos, porque es\n * siempre el mismo slot el que va rotando entre los cuatro.\n *\n * Con `state=\"ready\"` proyecta el contenido real y desaparece; en los otros\n * tres dibuja el placeholder correspondiente y el contenido no se instancia.\n * No inventa visuales propios: `loading` usa `kf-skeleton` (o `kf-spinner` con\n * `load=\"spinner\"`), y `empty`/`error` usan `kf-empty-state`.\n *\n * Las acciones (reintentar, crear) van en el slot `actions` — se ignoran\n * mientras carga, porque no hay nada que reintentar todavía.\n *\n * <kf-content-state [state]=\"state()\" title=\"No pudimos cargar tus vehículos\"\n * subtitle=\"Revisá tu conexión e intentá de nuevo.\">\n * <kf-button actions (click)=\"retry()\">Reintentar</kf-button>\n * <kf-data-table [columns]=\"cols\" [rows]=\"rows()\" />\n * </kf-content-state>\n */\n@Component({\n selector: 'kf-content-state',\n imports: [EmptyState, Skeleton, Spinner],\n template: `\n @switch (state()) {\n @case ('ready') {\n <ng-content />\n }\n @case ('loading') {\n <div class=\"kf-content-state__loading\" aria-busy=\"true\">\n @if (load() === 'spinner') {\n <kf-spinner [label]=\"loadingLabel()\" />\n } @else {\n <kf-skeleton />\n <kf-skeleton width=\"80%\" />\n <kf-skeleton width=\"60%\" />\n }\n </div>\n }\n @default {\n <kf-empty-state [tone]=\"state() === 'error' ? 'error' : 'neutral'\">\n @if (title()) {\n <p class=\"kf-content-state__title\">{{ title() }}</p>\n }\n @if (subtitle()) {\n <p class=\"kf-content-state__subtitle\">{{ subtitle() }}</p>\n }\n <div class=\"kf-content-state__actions\"><ng-content select=\"[actions]\" /></div>\n </kf-empty-state>\n }\n }\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-content-state__loading {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-sm);\n }\n .kf-content-state__title {\n margin: 0;\n font-family: var(--kf-font-title);\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-content-state__subtitle {\n margin: 0;\n color: var(--kf-color-text-muted);\n }\n .kf-content-state__actions:empty {\n display: none;\n }\n .kf-content-state__actions {\n display: flex;\n flex-wrap: wrap;\n justify-content: center;\n gap: var(--kf-space-sm);\n margin-top: var(--kf-space-sm);\n }\n `,\n})\nexport class ContentState {\n readonly state = input.required<ContentStateKind>();\n /** Forma del estado de carga: silueta (default) o spinner. */\n readonly load = input<ContentStateLoad>('skeleton');\n /** Título de `empty`/`error`. Ignorado mientras carga. */\n readonly title = input('');\n readonly subtitle = input('');\n /** Texto al lado del spinner cuando `load=\"spinner\"`. */\n readonly loadingLabel = input('Cargando…');\n}\n","import { Component, computed, input, output, signal, TemplateRef } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\n\n/**\n * Zona que ocupa la columna en la vista de cards. La vista de tabla ignora\n * esto (salvo `media`, que igual se rinde como thumbnail en vez de imprimir\n * la URL):\n * - `media`: thumbnail a la izquierda del encabezado; el valor de la celda se\n * usa como `src` salvo que la columna traiga su `cellTemplates`.\n * - `title`: título del encabezado (ej. la patente/unidad).\n * - `status`: chip/estado al lado del título.\n * - `field` (default): par label/valor en el cuerpo.\n * - `action`: va al pie, separado del cuerpo por una línea.\n */\nexport type DataTableCardRole = 'media' | 'title' | 'status' | 'field' | 'action';\n\nexport interface DataTableColumn {\n key: string;\n label: string;\n right?: boolean;\n className?: string;\n cardRole?: DataTableCardRole;\n}\n\n/** Vistas disponibles cuando `cardable` está activo. */\nexport type DataTableView = 'table' | 'cards';\n\n/**\n * Tabla estandarizada con soporte opcional de toggle tabla/cards.\n *\n * El \"render\" custom por columna de la spec original (una función que\n * devuelve JSX) se resuelve acá de dos formas, de la más simple a la más\n * flexible:\n * - `render`: función `(row) => string` para el caso típico de mostrar un\n * valor derivado/formateado de la fila como texto plano.\n * - `cellTemplates`: mapa `key -> TemplateRef` para cuando un consumidor\n * necesita marcado real dentro de una celda (badges, links, botones). Se\n * proyecta con `ngTemplateOutlet` y recibe `{ $implicit: row, index }`.\n * Se eligió esta combinación en vez de content-projection por columna\n * (ng-content con selector) porque las columnas son dinámicas (vienen de\n * `columns()`), y `ngTemplateOutlet` es el mecanismo estándar de Angular\n * para \"insertar esta plantilla por cada fila de este array\".\n *\n * En la vista de cards, `cardRole` por columna reparte el contenido en zonas\n * — encabezado (thumbnail + título + estado), cuerpo (pares label/valor) y\n * pie separado por una línea para las acciones. Sin `cardRole`, todas las\n * columnas caen en el cuerpo, igual que antes.\n *\n * El modo `cards` no depende de un componente ViewToggle separado: expone\n * un control de segmentos mínimo inline (mismo patrón visual que\n * kf-segmented) para no acoplarse a un componente que otro agente puede\n * estar construyendo en paralelo — ver nota en el resumen de la tarea.\n *\n * <kf-data-table [columns]=\"columns\" [rows]=\"rows\" (rowClick)=\"onRowClick($event)\">\n * <kf-empty-state empty>No hay resultados para mostrar.</kf-empty-state>\n * </kf-data-table>\n *\n * <kf-data-table [columns]=\"columns\" [rows]=\"rows\" [cardable]=\"true\" defaultView=\"cards\" />\n *\n * El slot `[footer]` (página 15: \"slot de pie para paginación\") va siempre\n * al final, en ambas vistas, separado por una línea — pensado para proyectar\n * `<kf-pagination>`, que sigue siendo un componente independiente.\n *\n * <kf-data-table [columns]=\"columns\" [rows]=\"rows\">\n * <kf-pagination footer [page]=\"page()\" [total]=\"total()\" (pageChange)=\"page.set($event)\" />\n * </kf-data-table>\n */\n@Component({\n selector: 'kf-data-table',\n imports: [NgTemplateOutlet],\n template: `\n <div class=\"kf-data-table\" [class.kf-data-table--flush]=\"flush()\">\n @if (cardable()) {\n <div class=\"kf-data-table__toolbar\">\n <div class=\"kf-data-table__view-toggle\" role=\"group\" aria-label=\"Cambiar vista\">\n <button\n type=\"button\"\n class=\"kf-data-table__view-option\"\n [class.kf-data-table__view-option--active]=\"view() === 'table'\"\n [attr.aria-pressed]=\"view() === 'table'\"\n (click)=\"setView('table')\"\n >\n Tabla\n </button>\n <button\n type=\"button\"\n class=\"kf-data-table__view-option\"\n [class.kf-data-table__view-option--active]=\"view() === 'cards'\"\n [attr.aria-pressed]=\"view() === 'cards'\"\n (click)=\"setView('cards')\"\n >\n Tarjetas\n </button>\n </div>\n </div>\n }\n\n @if (rows().length === 0) {\n <div class=\"kf-data-table__empty\">\n <ng-content select=\"[empty]\" />\n </div>\n } @else if (view() === 'table') {\n <div class=\"kf-data-table__scroll\">\n <table class=\"kf-data-table__table\">\n <thead>\n <tr>\n @for (column of columns(); track column.key) {\n <th [class]=\"column.className\" [class.kf-data-table__cell--right]=\"column.right\">\n {{ column.label }}\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of rows(); track trackRow(row, $index); let i = $index) {\n <tr\n class=\"kf-data-table__row\"\n tabindex=\"0\"\n (click)=\"onRowClick(row, i)\"\n (keydown.enter)=\"onRowClick(row, i)\"\n >\n @for (column of columns(); track column.key) {\n <td\n [class]=\"column.className\"\n [class.kf-data-table__cell--right]=\"column.right\"\n >\n @if (cellTemplates()?.[column.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else if (column.cardRole === 'media') {\n <img class=\"kf-data-table__thumb\" [src]=\"cellValue(row, column)\" alt=\"\" />\n } @else {\n {{ cellValue(row, column) }}\n }\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n } @else {\n <div class=\"kf-data-table__cards\">\n @for (row of rows(); track trackRow(row, $index); let i = $index) {\n <div\n class=\"kf-data-table__card\"\n [class.kf-data-table__card--interactive]=\"cardInteractive()\"\n [attr.role]=\"cardInteractive() ? 'button' : null\"\n [attr.tabindex]=\"cardInteractive() ? 0 : null\"\n (click)=\"cardInteractive() && onRowClick(row, i)\"\n (keydown.enter)=\"cardInteractive() && onRowClick(row, i)\"\n >\n @if (cardMediaColumn() || cardTitleColumn() || cardStatusColumns().length) {\n <div class=\"kf-data-table__card-header\">\n @if (cardMediaColumn(); as media) {\n <div class=\"kf-data-table__card-media\">\n @if (cellTemplates()?.[media.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else {\n <img [src]=\"cellValue(row, media)\" alt=\"\" />\n }\n </div>\n }\n <div class=\"kf-data-table__card-heading\">\n @if (cardTitleColumn(); as title) {\n <span class=\"kf-data-table__card-title\">\n @if (cellTemplates()?.[title.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else {\n {{ cellValue(row, title) }}\n }\n </span>\n }\n @if (cardStatusColumns().length) {\n <span class=\"kf-data-table__card-statuses\">\n @for (column of cardStatusColumns(); track column.key) {\n @if (cellTemplates()?.[column.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else {\n {{ cellValue(row, column) }}\n }\n }\n </span>\n }\n </div>\n </div>\n }\n\n @if (cardFieldColumns().length) {\n <div class=\"kf-data-table__card-fields\">\n @for (column of cardFieldColumns(); track column.key) {\n <div class=\"kf-data-table__card-field\">\n <span class=\"kf-data-table__card-label\">{{ column.label }}</span>\n <span class=\"kf-data-table__card-value\">\n @if (cellTemplates()?.[column.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else {\n {{ cellValue(row, column) }}\n }\n </span>\n </div>\n }\n </div>\n }\n\n @if (cardActionColumns().length) {\n <div class=\"kf-data-table__card-actions\">\n @for (column of cardActionColumns(); track column.key) {\n @if (cellTemplates()?.[column.key]; as template) {\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{ $implicit: row, index: i }\"\n />\n } @else {\n {{ cellValue(row, column) }}\n }\n }\n </div>\n }\n </div>\n }\n </div>\n }\n\n @if (rows().length > 0) {\n <div class=\"kf-data-table__footer\">\n <ng-content select=\"[footer]\" />\n </div>\n }\n </div>\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-data-table {\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n box-shadow: var(--kf-shadow-sm);\n overflow: hidden;\n }\n .kf-data-table--flush {\n border: none;\n box-shadow: none;\n border-radius: 0;\n }\n .kf-data-table__toolbar {\n display: flex;\n justify-content: flex-end;\n padding: var(--kf-space-sm) var(--kf-space-md);\n border-bottom: 1px solid var(--kf-color-border);\n }\n .kf-data-table__view-toggle {\n display: inline-flex;\n gap: 2px;\n padding: 2px;\n background: var(--kf-color-surface);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n }\n .kf-data-table__view-option {\n font: inherit;\n font-size: 0.875em;\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border: none;\n background: transparent;\n color: var(--kf-color-text-muted);\n border-radius: var(--kf-radius-xs);\n cursor: pointer;\n transition:\n background 0.14s,\n color 0.14s;\n }\n .kf-data-table__view-option:hover:not(.kf-data-table__view-option--active) {\n color: var(--kf-color-text);\n }\n .kf-data-table__view-option--active {\n background: var(--kf-color-white);\n color: var(--kf-color-ink);\n box-shadow: var(--kf-shadow-xs);\n }\n .kf-data-table__view-option:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n\n .kf-data-table__scroll {\n overflow-x: auto;\n }\n .kf-data-table__table {\n width: 100%;\n border-collapse: collapse;\n text-align: left;\n }\n .kf-data-table__table th,\n .kf-data-table__table td {\n padding: var(--kf-space-sm) var(--kf-space-md);\n border-bottom: 1px solid var(--kf-color-border);\n white-space: nowrap;\n }\n .kf-data-table__table th {\n font-family: var(--kf-font-title);\n font-size: 0.8125em;\n text-transform: uppercase;\n letter-spacing: 0.02em;\n color: var(--kf-color-text-muted);\n background: var(--kf-color-surface);\n }\n .kf-data-table__table td {\n color: var(--kf-color-text);\n }\n .kf-data-table__table tbody tr:last-child td {\n border-bottom: none;\n }\n .kf-data-table__row {\n cursor: pointer;\n transition: background 0.14s;\n }\n .kf-data-table__row:hover {\n background: var(--kf-color-primary-soft);\n }\n .kf-data-table__cell--right {\n text-align: right;\n }\n\n .kf-data-table__empty {\n padding: var(--kf-space-md);\n }\n\n .kf-data-table__footer {\n padding: var(--kf-space-sm) var(--kf-space-md);\n border-top: 1px solid var(--kf-color-border);\n }\n .kf-data-table__footer:empty {\n display: none;\n }\n\n .kf-data-table__cards {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));\n gap: var(--kf-space-md);\n padding: var(--kf-space-md);\n }\n .kf-data-table__card {\n display: flex;\n flex-direction: column;\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n overflow: hidden;\n transition:\n border-color 0.14s,\n box-shadow 0.14s;\n }\n .kf-data-table__card--interactive {\n cursor: pointer;\n }\n .kf-data-table__card:hover {\n border-color: var(--kf-color-border-strong);\n box-shadow: var(--kf-shadow-xs);\n }\n .kf-data-table__card--interactive:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n\n .kf-data-table__card-header {\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-md);\n }\n .kf-data-table__card-media {\n flex: none;\n }\n .kf-data-table__card-media img,\n .kf-data-table__thumb {\n display: block;\n width: 48px;\n height: 48px;\n border-radius: var(--kf-radius-xs);\n object-fit: cover;\n background: var(--kf-color-surface);\n }\n .kf-data-table__card-heading {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n min-width: 0;\n }\n .kf-data-table__card-title {\n font-family: var(--kf-font-title);\n font-weight: 600;\n color: var(--kf-color-ink);\n overflow-wrap: anywhere;\n }\n .kf-data-table__card-statuses,\n .kf-data-table__card-actions {\n display: flex;\n flex-wrap: wrap;\n gap: var(--kf-space-xs);\n }\n\n .kf-data-table__card-fields {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-md);\n }\n /* El encabezado ya aportó el padding de arriba. */\n .kf-data-table__card-header + .kf-data-table__card-fields {\n padding-top: 0;\n }\n .kf-data-table__card-field {\n display: flex;\n justify-content: space-between;\n gap: var(--kf-space-sm);\n }\n .kf-data-table__card-actions {\n justify-content: flex-end;\n margin-top: auto;\n padding: var(--kf-space-sm) var(--kf-space-md);\n border-top: 1px solid var(--kf-color-border);\n background: var(--kf-color-surface);\n }\n\n .kf-data-table__thumb {\n width: 32px;\n height: 32px;\n }\n .kf-data-table__card-label {\n font-family: var(--kf-font-title);\n font-size: 0.8125em;\n text-transform: uppercase;\n letter-spacing: 0.02em;\n color: var(--kf-color-text-muted);\n }\n .kf-data-table__card-value {\n color: var(--kf-color-text);\n text-align: right;\n }\n `,\n})\nexport class DataTable<T = unknown> {\n readonly columns = input.required<DataTableColumn[]>();\n readonly rows = input.required<T[]>();\n /** Default: índice de la fila dentro de `rows`. */\n readonly rowKey = input<(row: T, index: number) => string | number>();\n /** Sin borde/sombra de card — para tablas anidadas dentro de otra card. */\n readonly flush = input(false);\n /** Habilita el toggle de vista tabla/cards. */\n readonly cardable = input(false);\n readonly defaultView = input<DataTableView>('table');\n /**\n * Formateo simple de celda como texto: `(row) => string`. Para marcado\n * real (badges, links, botones) usar `cellTemplates`.\n */\n readonly render = input<(row: T) => string>();\n /** Mapa `columnKey -> TemplateRef` para celdas con contenido custom. */\n readonly cellTemplates = input<\n Record<string, TemplateRef<{ $implicit: T; index: number }>> | undefined\n >();\n\n readonly rowClick = output<{ row: T; index: number }>();\n\n private readonly internalView = signal<DataTableView | null>(null);\n\n /** Vista activa: la elegida por el usuario, o `defaultView` si no tocó el toggle. */\n readonly view = computed<DataTableView>(() => this.internalView() ?? this.defaultView());\n\n /** Primera columna de cada rol único; el resto se ignora en el encabezado. */\n readonly cardMediaColumn = computed(() => this.columns().find((c) => c.cardRole === 'media'));\n readonly cardTitleColumn = computed(() => this.columns().find((c) => c.cardRole === 'title'));\n readonly cardStatusColumns = computed(() =>\n this.columns().filter((c) => c.cardRole === 'status'),\n );\n readonly cardActionColumns = computed(() =>\n this.columns().filter((c) => c.cardRole === 'action'),\n );\n readonly cardFieldColumns = computed(() =>\n this.columns().filter((c) => !c.cardRole || c.cardRole === 'field'),\n );\n\n /**\n * La card entera es clickeable solo si no tiene acciones propias: un\n * `role=\"button\"` con botones adentro es inválido y deja el foco ambiguo.\n * Con columnas `action`, la interacción la manejan esos botones.\n */\n readonly cardInteractive = computed(() => this.cardActionColumns().length === 0);\n\n setView(next: DataTableView): void {\n this.internalView.set(next);\n }\n\n trackRow(row: T, index: number): string | number {\n const keyFn = this.rowKey();\n return keyFn ? keyFn(row, index) : index;\n }\n\n cellValue(row: T, column: DataTableColumn): string {\n const renderFn = this.render();\n if (renderFn) {\n return renderFn(row);\n }\n const value = (row as Record<string, unknown>)[column.key];\n return value === null || value === undefined ? '' : String(value);\n }\n\n onRowClick(row: T, index: number): void {\n this.rowClick.emit({ row, index });\n }\n}\n","import { FocusTrap, FocusTrapFactory } from '@angular/cdk/a11y';\nimport { DOCUMENT } from '@angular/common';\nimport {\n Component,\n DestroyRef,\n ElementRef,\n HostListener,\n afterRenderEffect,\n inject,\n input,\n model,\n viewChild,\n} from '@angular/core';\n\nexport type DrawerSide = 'left' | 'right';\n\n/**\n * Panel lateral genérico, agnóstico de contenido — no sabe qué es navegación\n * ni qué es sesión, solo da tres lugares para proyectar contenido\n * (`[kf-drawer-header]`, default, `[kf-drawer-footer]`) y resuelve lo que\n * cualquier drawer necesita resolver igual sin importar qué haya adentro:\n * overlay con blur que cierra al click, `Escape`, atrapado de foco real y\n * devolución de foco al cerrar.\n *\n * Extraído de `PortalHeader`, que hasta acá reimplementaba su propio drawer\n * embebido (navegación hardcodeada + slot único al final). Cualquier\n * consumidor que necesite un panel lateral — no solo `PortalHeader` — puede\n * usar este componente directamente.\n *\n * `open` es two-way, mismo patrón que `Dropdown`/`Modal`: el consumidor\n * decide qué dispara la apertura (un botón de hamburguesa, por ejemplo) y\n * qué hace con el cierre.\n *\n * Foco: al abrir, se crea un `FocusTrap` del CDK sobre el panel (la misma\n * pieza que usa Angular Material para `mat-sidenav`/`mat-dialog`) — Tab y\n * Shift+Tab ciclan solo entre los elementos focuseables del drawer, sin\n * escapar al contenido de fondo. Al cerrar, el foco vuelve al elemento que\n * tenía el foco antes de abrir (guardado en `document.activeElement`), no\n * se pierde en el `<body>`.\n *\n * `[kf-drawer-header]` tiene fondo oscuro propio (`--kf-color-tertiary-deep`),\n * distinto del body (`--kf-color-white`) — pensado para contener\n * `kf-drawer-session`, que asume ese fondo y no lo trae él mismo (ver\n * `DrawerSession.ts`). Si el slot queda vacío, el contenedor colapsa\n * (`display: none`) y no deja una franja oscura sin contenido.\n *\n * <kf-drawer [(open)]=\"menuOpen\" ariaLabel=\"Menú de navegación\">\n * <div kf-drawer-header>\n * <kf-drawer-session name=\"Tomás Soto\" email=\"tomas@kaufmann.com\" (logoutClick)=\"onLogout()\" />\n * </div>\n * <a href=\"/\">Home</a>\n * <a href=\"/vehiculos\">Vehículos</a>\n * </kf-drawer>\n */\n@Component({\n selector: 'kf-drawer',\n template: `\n @if (open()) {\n <button\n type=\"button\"\n class=\"kf-drawer__overlay\"\n aria-label=\"Cerrar menú\"\n (click)=\"open.set(false)\"\n ></button>\n }\n\n <nav\n #panel\n class=\"kf-drawer__panel\"\n [class.kf-drawer__panel--open]=\"open()\"\n [class.kf-drawer__panel--right]=\"side() === 'right'\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-hidden]=\"!open()\"\n >\n <div class=\"kf-drawer__header\"><ng-content select=\"[kf-drawer-header]\" /></div>\n <div class=\"kf-drawer__body\"><ng-content /></div>\n <div class=\"kf-drawer__footer\"><ng-content select=\"[kf-drawer-footer]\" /></div>\n </nav>\n `,\n styles: `\n /*\n * Overlay: capa semitransparente con blur sutil detrás del panel, cubre\n * toda la pantalla. Es un <button> nativo (no un <div> con (click) a\n * mano) para ser focuseable y responder a teclado sin reimplementar\n * nada — de ahí el reset de sus estilos por defecto más abajo.\n */\n .kf-drawer__overlay {\n position: fixed;\n inset: 0;\n border: none;\n padding: 0;\n cursor: pointer;\n background: rgba(23, 29, 37, 0.4);\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n z-index: 39;\n }\n /*\n * Panel: fijo a toda la altura de la pantalla, anclado al borde que\n * indique \\`side\\`, oculto por defecto corriéndolo fuera de la pantalla\n * (translateX) en vez de con display:none — así la transición de\n * entrada/salida es un slide real, no un aparecer/desaparecer abrupto.\n * visibility: hidden en el estado cerrado evita que sea\n * focuseable/clickeable mientras está fuera de vista (translateX por sí\n * solo no saca el elemento del árbol de tabulación).\n */\n .kf-drawer__panel {\n position: fixed;\n top: 0;\n left: 0;\n bottom: 0;\n z-index: 40;\n display: flex;\n flex-direction: column;\n width: 82%;\n max-width: 320px;\n background: var(--kf-color-white);\n box-shadow: 8px 0 24px -8px rgba(16, 24, 40, 0.3);\n transform: translateX(-100%);\n visibility: hidden;\n transition:\n transform 0.24s cubic-bezier(0.32, 0.72, 0, 1),\n visibility 0s linear 0.24s;\n }\n .kf-drawer__panel--right {\n left: auto;\n right: 0;\n box-shadow: -8px 0 24px -8px rgba(16, 24, 40, 0.3);\n transform: translateX(100%);\n }\n .kf-drawer__panel--open {\n transform: translateX(0);\n visibility: visible;\n transition:\n transform 0.24s cubic-bezier(0.32, 0.72, 0, 1),\n visibility 0s linear 0s;\n }\n .kf-drawer__header:empty,\n .kf-drawer__footer:empty {\n display: none;\n }\n /*\n * Fondo oscuro del header: vive acá y no en el contenido proyectado\n * porque \\`kf-drawer-session\\` (el caso de uso real de este slot) documenta\n * que asume que el contenedor padre ya se lo da — no tiene \\`background\\`\n * en su propio \\`:host\\`. Cualquier consumidor de \\`[kf-drawer-header]\\`\n * hereda este mismo fondo sin tener que reimplementarlo.\n *\n * Mismo criterio para el padding: \\`.kf-drawer__body\\` ya lo trae propio\n * (\\`--kf-space-lg\\`) en vez de esperar que cada nav-item se lo ponga —\n * \\`.kf-drawer__header\\` sigue esa misma convención, así \\`kf-drawer-session\\`\n * (o cualquier otro contenido de header) no queda pegado al borde del\n * panel ni al borde superior.\n */\n .kf-drawer__header {\n padding: var(--kf-space-lg);\n background: var(--kf-color-tertiary-deep);\n }\n .kf-drawer__body {\n flex: 1 1 auto;\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-lg);\n overflow-y: auto;\n }\n /*\n * Mismo criterio de padding que \\`.kf-drawer__header\\` (ver comentario\n * arriba): el footer no espera que su contenido proyectado (ej.\n * \\`kf-drawer-logout\\`) traiga su propio espaciado. A diferencia del\n * header, el footer vive sobre el fondo claro del panel (no tiene\n * \\`background\\` propio) — el \\`border-top\\` es lo único que lo separa\n * visualmente del body, reemplazando el borde que antes traía el propio\n * botón de logout cuando vivía dentro de \\`kf-drawer-session\\`.\n */\n .kf-drawer__footer {\n padding: var(--kf-space-lg);\n border-top: 1px solid var(--kf-color-border);\n }\n `,\n})\nexport class Drawer {\n /** Visibilidad del panel, two-way: `[(open)]=\"menuOpen\"`. */\n readonly open = model(false);\n /** Borde de anclaje del panel. `left` (default) es la convención dominante\n * (Material/iOS/Android): el botón que abre el drawer y el propio panel\n * quedan del mismo lado. */\n readonly side = input<DrawerSide>('left');\n /** `aria-label` del `<nav>` interno — describe el propósito del panel para\n * lectores de pantalla (ej. \"Menú de navegación\"). */\n readonly ariaLabel = input('Menú');\n\n private readonly panelRef = viewChild.required<ElementRef<HTMLElement>>('panel');\n private readonly focusTrapFactory = inject(FocusTrapFactory);\n private readonly document = inject(DOCUMENT);\n\n private focusTrap: FocusTrap | null = null;\n private lastFocusedElement: HTMLElement | null = null;\n\n constructor() {\n afterRenderEffect(() => {\n if (this.open()) {\n this.lastFocusedElement = this.document.activeElement as HTMLElement | null;\n const trap = this.getOrCreateFocusTrap();\n void trap.focusInitialElement();\n } else {\n this.focusTrap?.destroy();\n this.focusTrap = null;\n this.lastFocusedElement?.focus();\n this.lastFocusedElement = null;\n }\n });\n\n inject(DestroyRef).onDestroy(() => this.focusTrap?.destroy());\n }\n\n /** Cierra el drawer con Escape — mismo patrón que `Dropdown`/`Modal`. */\n @HostListener('document:keydown.escape')\n protected onEscape(): void {\n this.open.set(false);\n }\n\n private getOrCreateFocusTrap(): FocusTrap {\n if (!this.focusTrap) {\n this.focusTrap = this.focusTrapFactory.create(this.panelRef().nativeElement);\n }\n return this.focusTrap;\n }\n}\n","import { Component, booleanAttribute, input, output } from '@angular/core';\nimport { Icon } from '../icon/Icon';\n\n/**\n * Botón de cerrar sesión, pensado para proyectarse dentro de\n * `[kf-drawer-footer]` de `kf-drawer`, o junto a `kf-drawer-session` dentro\n * de `[kf-sidebar-footer]` de `kf-sidebar-shell` — separado de\n * `kf-drawer-session` (que solo muestra identidad: brand, avatar, nombre,\n * email), no anidado dentro de ella.\n *\n * Reproduce el mismo botón que antes vivía embebido en `DrawerSession`:\n * ícono `log-out` + label, color `--kf-color-error` con hover en\n * `--kf-color-error-soft` y foco visible con `--kf-shadow-focus`. Se separó\n * en un componente propio porque identidad y logout son responsabilidades\n * distintas — `kf-drawer-session` no debería saber que existe un botón de\n * cerrar sesión, y el footer del drawer ya tiene su propio padding/borde\n * superior (ver `Drawer.ts`) que reemplaza el borde que antes traía el botón\n * mismo.\n *\n * No sabe nada de autenticación real — solo emite `logoutClick` cuando el\n * consumidor debe cerrar la sesión real.\n *\n * `collapsed` oculta el label y centra el ícono, exponiéndolo vía `title`\n * — mismo criterio que `SidebarNavItem.collapsed` y\n * `DrawerSession.collapsed`, para cuando este botón vive dentro de un\n * `kf-sidebar-shell` colapsado.\n *\n * <kf-drawer-logout kf-portal-header-footer (logoutClick)=\"onLogout()\" />\n */\n@Component({\n selector: 'kf-drawer-logout',\n imports: [Icon],\n template: `\n <button\n type=\"button\"\n class=\"kf-drawer-logout__button\"\n [class.kf-drawer-logout__button--collapsed]=\"collapsed()\"\n [attr.title]=\"collapsed() ? label() : null\"\n (click)=\"logoutClick.emit()\"\n >\n <kf-icon name=\"log-out\" size=\"sm\" />\n @if (!collapsed()) {\n {{ label() }}\n }\n </button>\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-drawer-logout__button {\n display: flex;\n align-items: center;\n gap: var(--kf-space-xs);\n width: 100%;\n border: none;\n background: transparent;\n padding: 0;\n font: inherit;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--kf-color-error);\n cursor: pointer;\n }\n .kf-drawer-logout__button--collapsed {\n justify-content: center;\n }\n .kf-drawer-logout__button:hover {\n color: var(--kf-color-error-strong);\n background: var(--kf-color-error-soft);\n }\n .kf-drawer-logout__button:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n `,\n})\nexport class DrawerLogout {\n /** Label del botón, en español neutro por defecto. Input opcional por si\n * algún consumidor futuro necesita otro texto. */\n readonly label = input('Cerrar sesión');\n\n /** Oculta el label y centra el ícono — ver comentario de la clase. */\n readonly collapsed = input(false, { transform: booleanAttribute });\n\n readonly logoutClick = output<void>();\n}\n","import { Component, booleanAttribute, computed, input, output } from '@angular/core';\nimport { Avatar } from '../avatar/Avatar';\nimport { Icon } from '../icon/Icon';\n\n/**\n * Bloque de identidad para `[kf-drawer-header]` de `kf-drawer` o\n * `[kf-sidebar-footer]` de `kf-sidebar-shell`: avatar + nombre + email,\n * brand opcional arriba. Solo identidad — el logout vive aparte, en\n * `kf-drawer-logout`.\n *\n * `collapsed` oculta brand/nombre/email y deja solo el avatar (para un\n * `kf-sidebar-shell` colapsado). `interactive` convierte la tarjeta en un\n * botón real que emite `cardClick`, para cuando la identidad es el\n * disparador de un menú de acciones (ej. envuelta en `kf-dropdown`).\n *\n * <kf-dropdown [(open)]=\"menuOpen\">\n * <kf-drawer-session interactive name=\"Juan Pérez\" email=\"juan@empresa.com\" (cardClick)=\"menuOpen.set(!menuOpen())\" />\n * <kf-dropdown-panel variant=\"dark\">\n * <kf-dropdown-item icon=\"log-out\" tone=\"error\" (click)=\"onLogout()\">Cerrar sesión</kf-dropdown-item>\n * </kf-dropdown-panel>\n * </kf-dropdown>\n */\n@Component({\n selector: 'kf-drawer-session',\n imports: [Avatar, Icon],\n template: `\n @if (brand() && !collapsed()) {\n <span class=\"kf-drawer-session__brand\">{{ brand() }}</span>\n }\n\n @if (interactive()) {\n <button\n type=\"button\"\n class=\"kf-drawer-session__card kf-drawer-session__card--interactive\"\n [class.kf-drawer-session__card--collapsed]=\"collapsed()\"\n (click)=\"cardClick.emit()\"\n >\n <kf-avatar [initials]=\"displayInitials()\" [src]=\"avatarUrl()\" />\n @if (!collapsed()) {\n <div class=\"kf-drawer-session__identity\">\n <span class=\"kf-drawer-session__name\">{{ name() }}</span>\n @if (email()) {\n <span class=\"kf-drawer-session__email\">{{ email() }}</span>\n }\n </div>\n <kf-icon name=\"more-vertical\" size=\"sm\" />\n }\n </button>\n } @else {\n <div class=\"kf-drawer-session__card\" [class.kf-drawer-session__card--collapsed]=\"collapsed()\">\n <kf-avatar [initials]=\"displayInitials()\" [src]=\"avatarUrl()\" />\n @if (!collapsed()) {\n <div class=\"kf-drawer-session__identity\">\n <span class=\"kf-drawer-session__name\">{{ name() }}</span>\n @if (email()) {\n <span class=\"kf-drawer-session__email\">{{ email() }}</span>\n }\n </div>\n }\n </div>\n }\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-drawer-session__brand {\n display: block;\n margin-bottom: var(--kf-space-sm);\n font-family: var(--kf-font-mono);\n font-size: 0.6875rem;\n font-weight: 600;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: rgba(255, 255, 255, 0.65);\n }\n .kf-drawer-session__card {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n width: 100%;\n padding: var(--kf-space-sm);\n border: 1px solid rgba(255, 255, 255, 0.14);\n border-radius: var(--kf-radius-md);\n background: rgba(255, 255, 255, 0.04);\n }\n .kf-drawer-session__card--interactive {\n font: inherit;\n color: inherit;\n cursor: pointer;\n text-align: left;\n transition: background 0.14s;\n }\n .kf-drawer-session__card--interactive:hover {\n background: rgba(255, 255, 255, 0.09);\n }\n .kf-drawer-session__card--interactive:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-drawer-session__card--interactive kf-icon {\n flex: none;\n color: rgba(255, 255, 255, 0.45);\n }\n /*\n * Colapsada: solo el círculo del avatar, sin chrome de card (sin\n * borde, sin fondo, sin padding) — pedido explícito del usuario tras\n * ver el rail colapsado (simplificar a solo el círculo con iniciales).\n * Mismo cuadrado 40x40 que cada ítem de navegación y el botón de\n * colapso en ese estado — la tarjeta ya no aporta nada visualmente\n * distinguible del propio avatar cuando no hay texto que mostrar\n * dentro.\n */\n .kf-drawer-session__card--collapsed {\n justify-content: center;\n width: 40px;\n height: 40px;\n padding: 0;\n border-color: transparent;\n background: transparent;\n }\n .kf-drawer-session__card--collapsed:hover {\n background: rgba(255, 255, 255, 0.09);\n }\n .kf-drawer-session__identity {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n flex: 1 1 auto;\n }\n .kf-drawer-session__name {\n font-size: 0.9375rem;\n font-weight: 600;\n color: var(--kf-color-white);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .kf-drawer-session__email {\n font-size: 0.8125rem;\n color: rgba(255, 255, 255, 0.65);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n `,\n})\nexport class DrawerSession {\n readonly name = input.required<string>();\n readonly email = input<string>('');\n readonly initials = input<string>('');\n readonly avatarUrl = input<string>('');\n /** Label superior opcional, ej. \"Portal Kaufmann LATAM\". */\n readonly brand = input<string>('');\n\n /** Oculta brand/nombre/email y centra el avatar — ver comentario de la clase. */\n readonly collapsed = input(false, { transform: booleanAttribute });\n\n /** Convierte la tarjeta en un botón real con ícono de kebab — ver comentario de la clase. */\n readonly interactive = input(false, { transform: booleanAttribute });\n\n /** Se emite al clickear la tarjeta, solo cuando `interactive` es `true`. */\n readonly cardClick = output<void>();\n\n /** Si no se pasa `initials`, se derivan de `name`: primera letra de cada\n * una de las primeras 2 palabras, en mayúscula. */\n protected readonly displayInitials = computed(() => {\n const explicit = this.initials();\n if (explicit) {\n return explicit;\n }\n return this.name()\n .trim()\n .split(/\\s+/)\n .slice(0, 2)\n .map((word) => word.charAt(0).toUpperCase())\n .join('');\n });\n}\n","import { Overlay, type OverlayRef } from '@angular/cdk/overlay';\nimport { TemplatePortal } from '@angular/cdk/portal';\nimport {\n Component,\n DestroyRef,\n ElementRef,\n HostListener,\n TemplateRef,\n ViewContainerRef,\n contentChild,\n effect,\n inject,\n input,\n model,\n viewChild,\n} from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport { Icon } from '../icon/Icon';\nimport type { IconName } from '../icon/icon-name';\n\nexport type DropdownItemTone = 'neutral' | 'error';\n\n/**\n * Ítem de acción dentro de un `kf-dropdown-panel`. Es un `<button>` nativo\n * (no un `<a>`): dispara comportamiento en la pantalla actual, no navega.\n *\n * `icon` es opcional — sin él, el ítem es solo texto.\n *\n * <kf-dropdown-item icon=\"log-out\" (click)=\"onLogout()\" tone=\"error\">Cerrar sesión</kf-dropdown-item>\n */\n@Component({\n selector: 'kf-dropdown-item',\n imports: [Icon],\n template: `\n <button\n type=\"button\"\n class=\"kf-dropdown-item\"\n [class.kf-dropdown-item--error]=\"tone() === 'error'\"\n role=\"menuitem\"\n >\n @if (icon()) {\n <kf-icon [name]=\"icon()!\" size=\"sm\" />\n }\n <span class=\"kf-dropdown-item__label\"><ng-content /></span>\n </button>\n `,\n styles: `\n :host {\n display: block;\n }\n .kf-dropdown-item {\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n width: 100%;\n padding: var(--kf-space-sm) var(--kf-space-md);\n border: none;\n background: transparent;\n font: inherit;\n text-align: left;\n color: var(--kf-color-text);\n cursor: pointer;\n }\n .kf-dropdown-item kf-icon {\n flex: none;\n color: var(--kf-color-text-muted);\n }\n .kf-dropdown-item__label {\n flex: 1 1 auto;\n }\n .kf-dropdown-item:hover {\n background: var(--kf-color-surface);\n }\n .kf-dropdown-item:focus-visible {\n outline: none;\n box-shadow: inset var(--kf-shadow-focus);\n }\n .kf-dropdown-item--error {\n color: var(--kf-color-error-strong);\n }\n .kf-dropdown-item--error kf-icon {\n color: var(--kf-color-error-strong);\n }\n .kf-dropdown-item--error:hover {\n background: var(--kf-color-error-soft);\n }\n\n /* Contraste para cuando este ítem vive dentro de un panel\n variant=\"dark\" (ver DropdownPanel). */\n :host-context(.kf-dropdown-panel--dark) .kf-dropdown-item {\n color: rgba(255, 255, 255, 0.85);\n }\n :host-context(.kf-dropdown-panel--dark) .kf-dropdown-item kf-icon {\n color: rgba(255, 255, 255, 0.55);\n }\n :host-context(.kf-dropdown-panel--dark) .kf-dropdown-item:hover {\n background: rgba(255, 255, 255, 0.08);\n }\n :host-context(.kf-dropdown-panel--dark) .kf-dropdown-item--error {\n color: var(--kf-color-error);\n }\n :host-context(.kf-dropdown-panel--dark) .kf-dropdown-item--error kf-icon {\n color: var(--kf-color-error);\n }\n :host-context(.kf-dropdown-panel--dark) .kf-dropdown-item--error:hover {\n background: rgba(188, 69, 69, 0.16);\n }\n `,\n})\nexport class DropdownItem {\n readonly tone = input<DropdownItemTone>('neutral');\n /** Ícono opcional al inicio de la fila. */\n readonly icon = input<IconName>();\n}\n\nexport type DropdownPanelVariant = 'solid' | 'dark';\n\n/**\n * Contenido del panel flotante de un `kf-dropdown`. Es solo una plantilla\n * (`<ng-template>`, capturada vía `TemplateRef`) — `Dropdown` la conecta al\n * overlay real cuando `open` pasa a `true`, no la renderiza en su propio\n * lugar del DOM. Esto permite que el panel aparezca pegado al host de\n * `Dropdown` sin importar dónde esté ese host en la página.\n *\n * `variant`: `'solid'` (default, fondo blanco) o `'dark'` (fondo sólido\n * oscuro, mismo tono que `[kf-drawer-header]`) para cuando el trigger vive\n * sobre una superficie oscura de marca.\n *\n * `dark` es sólida a propósito, no semitransparente: el CDK Overlay\n * reposiciona el panel según dónde entra en el viewport y puede terminar\n * cayendo sobre fondo blanco en vez de sobre el rail oscuro — un color\n * sólido se ve intencional sin importar dónde lo posicione el CDK.\n */\n@Component({\n selector: 'kf-dropdown-panel',\n template: `\n <ng-template>\n <div class=\"kf-dropdown-panel\" [class.kf-dropdown-panel--dark]=\"variant() === 'dark'\">\n <div class=\"kf-dropdown-panel__inner\" role=\"menu\">\n <ng-content />\n </div>\n </div>\n </ng-template>\n `,\n styles: `\n /* Dos capas a propósito: \\`overflow: hidden\\` y \\`box-shadow\\` en el MISMO\n elemento recortarían la propia sombra en las esquinas redondeadas.\n Borde/radio/sombra viven acá (sin overflow); el recorte de contenido\n vive en \\`.kf-dropdown-panel__inner\\`. */\n .kf-dropdown-panel {\n min-width: 220px;\n max-width: min(280px, 90vw);\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n box-shadow: var(--kf-shadow-lg);\n font-family: var(--kf-font-body);\n animation: kf-dropdown-panel-enter 0.14s ease-out;\n }\n /* Mismo tono que ya usa [kf-drawer-header]. */\n .kf-dropdown-panel--dark {\n background: var(--kf-color-tertiary-deep);\n border-color: rgba(255, 255, 255, 0.14);\n }\n .kf-dropdown-panel__inner {\n padding: var(--kf-space-xs) 0;\n overflow: hidden;\n border-radius: inherit;\n }\n @media (prefers-reduced-motion: reduce) {\n .kf-dropdown-panel {\n animation: none;\n }\n }\n @keyframes kf-dropdown-panel-enter {\n from {\n opacity: 0;\n transform: translateY(-4px) scale(0.98);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n }\n `,\n})\nexport class DropdownPanel {\n readonly variant = input<DropdownPanelVariant>('solid');\n readonly templateRef = viewChild.required(TemplateRef);\n}\n\n/**\n * Menú de acciones flotante, conectado a un elemento disparador vía\n * `@angular/cdk/overlay` — la misma pieza que usa Angular Material para\n * `mat-menu`/`mat-select`.\n *\n * Se apoya en el CDK en vez de un `position: absolute` casero (a diferencia\n * de `SelectMenu`, que puede permitírselo porque su trigger vive siempre\n * dentro del propio componente) porque acá el disparador real puede vivir\n * en OTRO componente por completo — ej. el avatar dentro de\n * `kf-portal-header` — y el panel tiene que aparecer pegado a ESE elemento\n * sin importar dónde el consumidor ubique al `Dropdown` en su HTML.\n *\n * `open` es two-way: el consumidor decide qué dispara la apertura —\n * `Dropdown` en sí no renderiza ningún trigger, su propio host es el punto\n * de anclaje visual del panel.\n *\n * <kf-dropdown [(open)]=\"menuOpen\"><kf-dropdown-panel>...</kf-dropdown-panel></kf-dropdown>\n */\n@Component({\n selector: 'kf-dropdown',\n template: `<ng-content />`,\n styles: `\n :host {\n display: inline-block;\n }\n `,\n})\nexport class Dropdown {\n /** Visibilidad del panel, two-way: `[(open)]=\"menuOpen\"`. */\n readonly open = model(false);\n\n /**\n * Elemento al que se conecta el overlay, si es distinto del propio host\n * de `Dropdown`. Sin esto, `Dropdown` asume que ÉL MISMO es el\n * disparador. Útil cuando el disparador real vive dentro de OTRO\n * componente que no se puede envolver sin ensanchar el área de click\n * (ej. el avatar de sesión dentro de `PortalHeader`).\n */\n readonly anchor = input<ElementRef<HTMLElement>>();\n\n private readonly panel = contentChild(DropdownPanel);\n\n private readonly overlayService = inject(Overlay);\n private readonly host = inject(ElementRef<HTMLElement>);\n private readonly viewContainerRef = inject(ViewContainerRef);\n private readonly destroyRef = inject(DestroyRef);\n\n private overlayRef: OverlayRef | null = null;\n\n /**\n * Suscripciones a `outsidePointerEvents()`/`keydownEvents()` del overlay\n * ACTUALMENTE adjunto. `getOrCreateOverlayRef()` reutiliza el mismo\n * `overlayRef` entre aperturas (no lo recrea cada vez) — sin esto,\n * `attach()` se resuscribía a esos observables en cada apertura sin\n * cancelar la suscripción de la vez anterior, acumulando N suscripciones\n * activas sobre el mismo overlay persistente. Eso causaba el bug real de\n * \"clicks seguidos\": al abrir de nuevo, el propio pointerdown que originó\n * la apertura llegaba a más de una suscripción acumulada, disparando\n * `open.set(false)` de forma errática en el mismo tick (patrón observado:\n * abre cada 2 clicks, cierra cada 1). Se cancelan explícitamente en\n * `detach()`, antes de la siguiente `attach()`.\n */\n private overlaySubscription: Subscription | null = null;\n\n constructor() {\n effect(() => {\n if (this.open()) {\n this.attach();\n } else {\n this.detach();\n }\n });\n\n this.destroyRef.onDestroy(() => {\n this.overlaySubscription?.unsubscribe();\n this.overlayRef?.dispose();\n });\n }\n\n /**\n * Respaldo de `overlayRef.keydownEvents()`: ese observable del CDK solo\n * ve teclas con el foco DENTRO del panel. Si el foco queda en el botón\n * disparador (caso común), `keydownEvents()` nunca dispara — este\n * listener a nivel de documento cubre ese caso.\n */\n @HostListener('document:keydown.escape')\n onDocumentEscape(): void {\n this.open.set(false);\n }\n\n private attach(): void {\n const panel = this.panel();\n if (!panel || this.overlayRef?.hasAttached()) {\n return;\n }\n\n const overlayRef = this.getOrCreateOverlayRef();\n const portal = new TemplatePortal(panel.templateRef(), this.viewContainerRef);\n overlayRef.attach(portal);\n\n this.overlaySubscription = new Subscription();\n this.overlaySubscription.add(\n overlayRef.outsidePointerEvents().subscribe((event) => {\n if (this.isEventOnTrigger(event)) {\n return;\n }\n this.open.set(false);\n }),\n );\n this.overlaySubscription.add(\n overlayRef.keydownEvents().subscribe((event) => {\n if (event.key === 'Escape') {\n this.open.set(false);\n }\n }),\n );\n }\n\n /**\n * El trigger real (el `anchor`, o el propio host si no se pasó ninguno —\n * ver comentario de la clase) vive FUERA del overlay a propósito: el\n * overlay recién se crea/adjunta cuando `open` pasa a `true`, así que el\n * CDK no tiene forma de saber que ese elemento externo \"es parte\" de su\n * disparador. Sin este filtro, el mismo `pointerdown` que abre el menú\n * (el trigger no es hijo del overlay) también llega a\n * `outsidePointerEvents()`, cerrando el panel en el mismo gesto que lo\n * abrió — bug real reproducido con Playwright: \"abre y cierra\" en\n * clicks consecutivos rápidos sobre la tarjeta de sesión del sidebar.\n */\n private isEventOnTrigger(event: MouseEvent | TouchEvent): boolean {\n const trigger = this.anchor()?.nativeElement ?? this.host.nativeElement;\n const target = event.target;\n return target instanceof Node && trigger.contains(target);\n }\n\n private detach(): void {\n this.overlaySubscription?.unsubscribe();\n this.overlaySubscription = null;\n this.overlayRef?.detach();\n }\n\n private getOrCreateOverlayRef(): OverlayRef {\n if (this.overlayRef) {\n return this.overlayRef;\n }\n\n const positionStrategy = this.overlayService\n .position()\n .flexibleConnectedTo(this.anchor() ?? this.host)\n // 4 posiciones, no 2: además del par alineado al borde derecho del\n // anchor, agrega el mismo par alineado al borde IZQUIERDO — sin esto,\n // un trigger cerca del borde derecho de pantalla no tenía fallback\n // horizontal y el panel se salía del viewport.\n .withPositions([\n { originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top', offsetY: 4 },\n { originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', offsetY: -4 },\n { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 4 },\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -4 },\n ])\n .withViewportMargin(8)\n // Si ninguna de las 4 posiciones entra completa, la última se ajusta\n // con push en vez de desbordarse fuera de pantalla.\n .withPush(true);\n\n this.overlayRef = this.overlayService.create({\n positionStrategy,\n scrollStrategy: this.overlayService.scrollStrategies.reposition(),\n maxWidth: '90vw',\n });\n\n return this.overlayRef;\n }\n}\n","import { Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Bloque promocional sobre fondo oscuro de marca (página 37) — campañas,\n * accesos directos o el portal de autoatención. Usa `--kf-color-tertiary-deep`\n * como base del degradado, el mismo azul profundo que el slide destacado de\n * `kf-carousel` y la barra de `kf-portal-header`.\n *\n * <kf-feature-card badge=\"Autoatención\" badgeIcon=\"tool\" title=\"Portal de Autoatención\"\n * description=\"Con tu patente o VIN accede a soluciones para tu vehículo: mantenciones, repuestos y conectividad en un solo lugar.\"\n * actionLabel=\"Ir al portal\" actionHref=\"/autoatencion\" />\n */\n@Component({\n selector: 'kf-feature-card',\n imports: [Icon],\n template: `\n @if (badge()) {\n <span class=\"kf-feature-card__badge\">\n @if (badgeIcon(); as iconName) {\n <kf-icon [name]=\"iconName\" size=\"sm\" />\n }\n {{ badge() }}\n </span>\n }\n <span class=\"kf-feature-card__title\">{{ title() }}</span>\n @if (description()) {\n <p class=\"kf-feature-card__description\">{{ description() }}</p>\n }\n @if (actionLabel()) {\n <a class=\"kf-feature-card__action\" [href]=\"actionHref() || '#'\">\n <kf-icon name=\"chevron-right\" size=\"sm\" />\n {{ actionLabel() }}\n </a>\n }\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-lg);\n border-radius: var(--kf-radius-md);\n background: linear-gradient(\n 135deg,\n var(--kf-color-primary-active) 0%,\n var(--kf-color-tertiary-deep) 100%\n );\n color: var(--kf-color-white);\n font-family: var(--kf-font-body);\n }\n .kf-feature-card__badge {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border-radius: var(--kf-radius-pill);\n background: rgba(255, 255, 255, 0.12);\n border: 1px solid rgba(255, 255, 255, 0.24);\n font-size: 0.72rem;\n font-weight: 700;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n }\n .kf-feature-card__title {\n font-family: var(--kf-font-title);\n font-size: 1.375rem;\n font-weight: 700;\n line-height: 1.2;\n }\n .kf-feature-card__description {\n margin: 0;\n max-width: 48ch;\n color: rgba(255, 255, 255, 0.8);\n font-size: 0.9375rem;\n }\n .kf-feature-card__action {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n margin-top: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-md);\n border-radius: var(--kf-radius-sm);\n background: rgba(255, 255, 255, 0.14);\n color: var(--kf-color-white);\n font-size: 0.875rem;\n font-weight: 600;\n text-decoration: none;\n transition: background 0.14s;\n }\n .kf-feature-card__action:hover {\n background: rgba(255, 255, 255, 0.22);\n }\n `,\n})\nexport class FeatureCard {\n readonly badge = input<string>();\n readonly badgeIcon = input<IconName>();\n readonly title = input.required<string>();\n readonly description = input<string>();\n readonly actionLabel = input<string>();\n readonly actionHref = input<string>();\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Chip de solo-lectura inline (label/valor) dentro de una caja bordeada.\n * Se usa en barras de filtro y filas de resumen para mostrar información,\n * NO para entrada de datos — para eso existe `Input`.\n *\n * El valor admite dos formas, igual que en el design system de referencia:\n * - `value` (string): caso simple, ej. `[value]=\"'Jul 2026'\"`.\n * - contenido proyectado (`<ng-content>`): cuando se necesita algo más rico\n * que un string (un badge, texto con formato, etc.).\n * `value` tiene prioridad cuando está definido; si no se pasa `value`, se\n * renderiza el contenido proyectado y, si tampoco hay contenido, `placeholder`.\n *\n * <kf-field icon=\"calendar\" label=\"Periodo\" value=\"Jul 2026\" [select]=\"true\" />\n * <kf-field label=\"Sucursal\"><strong>Casa Central</strong></kf-field>\n */\n@Component({\n selector: 'kf-field',\n imports: [Icon],\n template: `\n @if (icon(); as iconName) {\n <kf-icon class=\"kf-field__icon\" [name]=\"iconName\" size=\"sm\" />\n }\n @if (label()) {\n <span class=\"kf-field__label\">{{ label() }}</span>\n }\n <span class=\"kf-field__value\">\n @if (value()) {\n {{ value() }}\n } @else {\n <ng-content></ng-content>\n @if (isPlaceholderVisible()) {\n <span class=\"kf-field__placeholder\">{{ placeholder() }}</span>\n }\n }\n </span>\n @if (select()) {\n <kf-icon class=\"kf-field__chevron\" name=\"chevron-down\" size=\"sm\" />\n }\n `,\n styles: `\n :host {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-surface);\n font: inherit;\n font-family: var(--kf-font-body);\n color: var(--kf-color-text);\n line-height: 1.2;\n }\n :host(.kf-field--select) {\n cursor: pointer;\n }\n :host(.kf-field--select:hover) {\n border-color: var(--kf-color-border-strong);\n }\n .kf-field__icon {\n color: var(--kf-color-text-muted);\n }\n .kf-field__label {\n color: var(--kf-color-text-muted);\n white-space: nowrap;\n }\n .kf-field__value {\n font-weight: 500;\n color: var(--kf-color-ink);\n white-space: nowrap;\n }\n .kf-field__placeholder {\n color: var(--kf-color-text-muted);\n font-weight: 400;\n }\n .kf-field__chevron {\n color: var(--kf-color-text-muted);\n }\n `,\n host: {\n '[class.kf-field--select]': 'select()',\n '[attr.style]': 'style() || null',\n },\n})\nexport class Field {\n readonly label = input<string>();\n readonly value = input<string>();\n readonly icon = input<IconName>();\n readonly placeholder = input<string>();\n readonly select = input(false, { transform: booleanAttribute });\n /** Estilos inline opcionales aplicados directamente al host. */\n readonly style = input<string>();\n\n /**\n * El placeholder solo tiene sentido cuando no hay `value` ni contenido\n * proyectado. Angular no expone de forma simple si `<ng-content>` recibió\n * hijos reales, así que la regla adoptada es puramente declarativa: se\n * muestra el placeholder cuando hay texto de placeholder y no hay `value`\n * (ver comentario de clase sobre la prioridad value > proyectado > placeholder).\n */\n protected isPlaceholderVisible(): boolean {\n return !this.value() && !!this.placeholder();\n }\n}\n","import { Component, computed, input, output } from '@angular/core';\n\n/** Forma normalizada interna de cada opción, ya resuelta a value/label. */\ninterface FilterChipOption {\n value: string;\n label: string;\n}\n\n/**\n * Fila de chips tipo \"pill\" para filtros de una sola selección.\n *\n * Cada opción puede pasarse como string simple (se usa como value y label\n * a la vez) o como objeto { value, label } cuando el texto mostrado difiere\n * del valor interno.\n *\n * El chip activo se resalta con el color \"ink\" oscuro (--kf-color-ink), no\n * con el color primario de marca: así lo define el sistema de diseño de\n * referencia para este componente en particular.\n *\n * <kf-filter-chips [options]=\"['Todos', 'Activos', 'Archivados']\"\n * [value]=\"filtro\"\n * (valueChange)=\"filtro = $event\" />\n *\n * <kf-filter-chips [options]=\"[{ value: 'all', label: 'Todos' }]\"\n * [value]=\"filtro\"\n * (valueChange)=\"filtro = $event\" />\n */\n@Component({\n selector: 'kf-filter-chips',\n template: `\n <div class=\"kf-filter-chips\" role=\"group\">\n @for (option of normalizedOptions(); track option.value) {\n <button\n type=\"button\"\n class=\"kf-filter-chips__chip\"\n [class.kf-filter-chips__chip--active]=\"option.value === value()\"\n [attr.aria-pressed]=\"option.value === value()\"\n (click)=\"select(option.value)\"\n >\n {{ option.label }}\n </button>\n }\n </div>\n `,\n styles: `\n :host {\n display: block;\n }\n .kf-filter-chips {\n display: flex;\n flex-wrap: wrap;\n gap: var(--kf-space-xs);\n }\n .kf-filter-chips__chip {\n font: inherit;\n padding: var(--kf-space-xs) var(--kf-space-md);\n border-radius: var(--kf-radius-pill);\n border: 1px solid var(--kf-color-border);\n background: var(--kf-color-surface);\n color: var(--kf-color-text);\n cursor: pointer;\n transition:\n background 0.14s,\n border-color 0.14s,\n color 0.14s;\n }\n .kf-filter-chips__chip:hover:not(.kf-filter-chips__chip--active) {\n border-color: var(--kf-color-border-strong);\n }\n .kf-filter-chips__chip:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-filter-chips__chip--active {\n background: var(--kf-color-ink);\n border-color: var(--kf-color-ink);\n color: var(--kf-color-white);\n }\n `,\n})\nexport class FilterChips {\n readonly options = input.required<(string | { value: string; label: string })[]>();\n readonly value = input<string>('');\n\n readonly valueChange = output<string>();\n\n /** Normaliza cada opción string/objeto a la forma { value, label }. */\n readonly normalizedOptions = computed<FilterChipOption[]>(() =>\n this.options().map((option) =>\n typeof option === 'string' ? { value: option, label: option } : option,\n ),\n );\n\n select(value: string): void {\n if (value === this.value()) {\n return;\n }\n this.valueChange.emit(value);\n }\n}\n","import { Component, Directive, computed, contentChild, input, output } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\nexport interface FolderTabOption {\n value: string;\n label: string;\n icon?: IconName;\n}\n\n/**\n * Marca el contenido que `kf-folder-tabs` debe proyectar dentro de su\n * panel. Sin lógica propia — existe solo como token de tipo para que\n * `contentChild(FolderTabsPanel)` pueda detectar si el consumidor proyectó\n * algo (mismo mecanismo que `kf-dropdown` usa con `contentChild(DropdownPanel)`;\n * acá no hace falta un componente completo, alcanza con una directiva de\n * atributo porque el panel no necesita comportamiento propio, solo marcar\n * su presencia).\n *\n * <div kfFolderTabsPanel>...</div>\n */\n@Directive({ selector: '[kfFolderTabsPanel]' })\nexport class FolderTabsPanel {}\n\n/**\n * Tabs con forma de \"carpeta\": el borde superior queda redondeado y el borde\n * inferior de la pestaña activa se funde visualmente con el panel de\n * contenido que va debajo (misma superficie, sin línea divisoria).\n *\n * Al cambiar de pestaña, la que se activa se \"abre\": gira sobre su borde\n * inferior (hinge 3D) y sube con un pequeño rebote. Es CSS solo: la clase\n * `--active` se mueve de un botón a otro, y eso vuelve a disparar el keyframe\n * sin tocar JS.\n *\n * El panel de contenido es un `<ng-content>` OPCIONAL — si el consumidor no\n * proyecta nada, `kf-folder-tabs` renderiza solo la fila de pestañas (mismo\n * comportamiento que antes de que existiera este slot, detectado con\n * `contentChild()` sin `.required`, igual patrón que usa `kf-dropdown` para\n * saber si hay un `kf-dropdown-panel` proyectado). Si SÍ proyecta contenido,\n * se envuelve en un panel con la esquina superior-izquierda recta (nace ahí\n * la primera pestaña, siempre pegada al borde izquierdo de la fila — un\n * radio ahí competiría visualmente con el propio borde redondeado de esa\n * pestaña) y las otras tres redondeadas. El `border-bottom` de 2px de la\n * pestaña activa (ver `.kf-folder-tabs__tab--active` más abajo) es la señal\n * visual de conexión con el panel para CUALQUIER pestaña activa, sin\n * necesitar mover ni medir nada.\n *\n * El borde izquierdo de toda la fila (y por lo tanto de la esquina recta\n * del panel) depende de que ninguna pestaña se corra al cambiar de estado\n * — ver `transform-origin: bottom left` en `.kf-folder-tabs__tab`: con el\n * origen centrado (como estaba antes), el `scale()` de la pestaña inactiva\n * encogía el borde izquierdo unos px, y ese corrimiento sub-pixel es lo que\n * hacía que este mismo diseño (esquina fija) se viera \"roto\" cuando la\n * pestaña activa no era la primera. Con el origen anclado a la izquierda,\n * el corrimiento desaparece y la esquina fija vuelve a ser una solución\n * válida y simple — sin necesitar medir la pestaña activa por JS.\n *\n * Antes de este slot, el patrón era que el consumidor pusiera su propia\n * card como HERMANO de `kf-folder-tabs` y anulara a mano el radio superior\n * completo (`border-top-left-radius: 0`, `border-top-right-radius: 0` — ver\n * el caso original de `web-portal-latam-frontend`). Encapsular esto acá\n * evita que cada consumidor repita esas reglas a mano.\n *\n * <kf-folder-tabs [options]=\"tabs\" [value]=\"active\" (valueChange)=\"active = $event\">\n * <div kfFolderTabsPanel>contenido de la pestaña activa</div>\n * </kf-folder-tabs>\n *\n * <!-- o, sin contenido, como antes: -->\n * <kf-folder-tabs [options]=\"tabs\" [value]=\"active\" (valueChange)=\"active = $event\" />\n */\n@Component({\n selector: 'kf-folder-tabs',\n imports: [Icon],\n template: `\n <div class=\"kf-folder-tabs\" role=\"tablist\">\n @for (option of options(); track option.value) {\n <button\n type=\"button\"\n role=\"tab\"\n class=\"kf-folder-tabs__tab\"\n [class.kf-folder-tabs__tab--active]=\"option.value === value()\"\n [attr.aria-selected]=\"option.value === value()\"\n [attr.tabindex]=\"option.value === value() ? 0 : -1\"\n [id]=\"'kf-folder-tab-' + option.value\"\n [attr.aria-controls]=\"'kf-folder-panel-' + option.value\"\n (click)=\"select(option.value)\"\n (keydown)=\"onKeydown($event, option.value)\"\n >\n @if (option.icon; as iconName) {\n <kf-icon class=\"kf-folder-tabs__icon\" [name]=\"iconName\" size=\"sm\" />\n }\n <span class=\"kf-folder-tabs__label\">{{ option.label }}</span>\n </button>\n }\n </div>\n\n <div class=\"kf-folder-tabs__panel\" [class.kf-folder-tabs__panel--empty]=\"!hasPanel()\">\n <ng-content select=\"[kfFolderTabsPanel]\" />\n </div>\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-folder-tabs {\n display: flex;\n align-items: flex-end;\n gap: var(--kf-space-xs);\n /* Da profundidad al hinge: las pestañas giran sobre su borde inferior. */\n perspective: 900px;\n }\n .kf-folder-tabs__tab {\n position: relative;\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n font: inherit;\n font-size: 0.9rem;\n color: var(--kf-color-text-muted);\n background: var(--kf-color-surface);\n border: 1px solid var(--kf-color-border);\n border-bottom-color: var(--kf-color-border-strong);\n border-radius: var(--kf-radius-sm) var(--kf-radius-sm) 0 0;\n padding: var(--kf-space-sm) var(--kf-space-md);\n cursor: pointer;\n /* bottom left, no bottom center: con el origen centrado, el\n scale() de abajo encoge/agranda la pestaña desde su centro\n horizontal — el borde IZQUIERDO se corre unos px cada vez que\n una pestaña cambia de activa a inactiva (o viceversa), lo que\n desalinea la fila entera contra el panel de abajo (se percibe\n como si la tab \"se rompiera\"). Con el origen a la izquierda, el\n crecimiento/encogimiento siempre pasa hacia la derecha: el borde\n izquierdo de cada pestaña — y por lo tanto el de toda la fila —\n nunca se mueve. */\n transform-origin: bottom left;\n /* Inactiva: hundida en la pila, un pelo más chica. */\n transform: translateY(5px) scale(0.985);\n transition:\n background 0.14s,\n color 0.14s,\n border-color 0.14s,\n transform 0.22s cubic-bezier(0.32, 0.72, 0, 1);\n }\n .kf-folder-tabs__tab:hover:not(.kf-folder-tabs__tab--active) {\n color: var(--kf-color-text);\n background: var(--kf-color-white);\n transform: translateY(2px) scale(0.99);\n }\n .kf-folder-tabs__tab:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n z-index: 1;\n }\n .kf-folder-tabs__tab--active {\n z-index: 1;\n color: var(--kf-color-primary);\n font-weight: 700;\n background: var(--kf-color-white);\n border-color: var(--kf-color-border);\n /* Marca el color del tema abajo (página 19 del design system) — no se\n funde con el panel: el borde queda visible y grueso, mismo trato\n que el subrayado de kf-tabs. */\n border-bottom: 2px solid var(--kf-color-primary);\n /* Sombra hacia arriba: la pestaña quedó por delante del resto. */\n box-shadow: 0 -6px 14px -10px rgba(16, 24, 40, 0.4);\n transform: translateY(1px);\n animation: kf-folder-tabs-pull 0.34s cubic-bezier(0.22, 1.2, 0.36, 1) both;\n }\n @keyframes kf-folder-tabs-pull {\n /*\n * Rotación y rebote reducidos a propósito: la versión original\n * (rotateX(-24deg), overshoot a scale(1.02)) se sentía excesiva en\n * un patrón de uso frecuente como cambiar de tab — la gente lo hace\n * seguido y rápido, así que un exceso de movimiento cansa más que\n * \"da personalidad\". Se mantiene el espíritu de \"carpeta que se\n * abre\" (rotateX + lift), con menos intensidad.\n */\n 0% {\n transform: translateY(7px) rotateX(-10deg) scale(0.97);\n }\n /*\n * El rebote (overshoot) se resuelve DENTRO del rango final, no por\n * encima: antes este paso intermedio llegaba a translateY(-2px) —\n * más arriba que la posición de reposo (translateY(1px)) — y esos\n * 3px de más dejaban un hueco visible contra el panel de abajo (que\n * no se mueve) durante la fracción de segundo del rebote. Ahora el\n * mínimo del rebote es translateY(1px), igual que el reposo: la\n * pestaña nunca sube más allá de donde termina.\n */\n 60% {\n transform: translateY(1px) rotateX(2deg) scale(1.01);\n }\n 100% {\n transform: translateY(1px) rotateX(0) scale(1);\n }\n }\n @media (prefers-reduced-motion: reduce) {\n .kf-folder-tabs__tab,\n .kf-folder-tabs__tab--active {\n animation: none;\n transition:\n background 0.14s,\n color 0.14s,\n border-color 0.14s;\n }\n }\n\n /*\n * Panel opcional (kfFolderTabsPanel proyectado). Vacío cuando el\n * consumidor no proyecta nada — display: contents para que no ocupe\n * espacio ni imponga su propio box en ese caso, dejando a\n * kf-folder-tabs comportarse exactamente como antes de este slot\n * (solo la fila de pestañas).\n */\n .kf-folder-tabs__panel--empty {\n display: contents;\n }\n .kf-folder-tabs__panel:not(.kf-folder-tabs__panel--empty) {\n background: var(--kf-color-white);\n /*\n * Bordes declarados por lado (en vez de la shorthand border) — dos\n * shorthands consecutivos que tocan la misma propiedad terminaban\n * pisándose mal al compilarse (el border quedaba vacío en el CSS\n * final). Declarar cada lado explícito evita el conflicto.\n */\n border-right: 1px solid var(--kf-color-border);\n border-bottom: 1px solid var(--kf-color-border);\n border-left: 1px solid var(--kf-color-border);\n border-top: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n /*\n * Solo la esquina superior-izquierda queda recta: es donde nace la\n * primera pestaña, y un radio ahí competiría visualmente con el\n * propio borde redondeado de esa pestaña. Va DESPUÉS del shorthand\n * de arriba a propósito — el shorthand fija las 4 esquinas, y esta\n * declaración más específica pisa solo la superior-izquierda.\n */\n border-top-left-radius: 0;\n /* Sin box-shadow a propósito: el borde de 1px solo es el mismo que\n usa cualquier kf-card sin sombra propia — consistente con el\n resto de la librería. */\n /* El contenido proyectado (ej. una kf-card rectangular, sin su\n propio border-radius) se desbordaba por encima de las esquinas\n redondeadas del panel — mismo motivo por el que Card usa\n overflow: hidden en su propio :host. */\n overflow: hidden;\n }\n `,\n})\nexport class FolderTabs {\n readonly options = input.required<FolderTabOption[]>();\n readonly value = input.required<string>();\n readonly valueChange = output<string>();\n\n /**\n * Detecta si el consumidor proyectó contenido marcado con\n * `kfFolderTabsPanel` — sin `.required`, así que es `undefined`\n * cuando no hay nada proyectado (mismo patrón que usa `kf-dropdown` con\n * `contentChild(DropdownPanel)` para saber si hay un panel que\n * attachear). `hasPanel()` decide si el wrapper del panel participa del\n * layout (`display: contents` si no).\n */\n private readonly projectedPanel = contentChild(FolderTabsPanel);\n protected readonly hasPanel = computed(() => this.projectedPanel() !== undefined);\n\n select(value: string): void {\n if (value === this.value()) {\n return;\n }\n this.valueChange.emit(value);\n }\n\n /** Navegación estándar de ARIA tabs: flechas mueven el foco y activan la pestaña. */\n onKeydown(event: KeyboardEvent, currentValue: string): void {\n const items = this.options();\n const currentIndex = items.findIndex((option) => option.value === currentValue);\n\n let nextIndex: number;\n switch (event.key) {\n case 'ArrowRight':\n nextIndex = (currentIndex + 1) % items.length;\n break;\n case 'ArrowLeft':\n nextIndex = (currentIndex - 1 + items.length) % items.length;\n break;\n case 'Home':\n nextIndex = 0;\n break;\n case 'End':\n nextIndex = items.length - 1;\n break;\n default:\n return;\n }\n\n event.preventDefault();\n const nextOption = items[nextIndex];\n this.select(nextOption.value);\n\n const host = (event.currentTarget as HTMLElement).parentElement;\n const nextId = `kf-folder-tab-${nextOption.value}`;\n const nextButton = Array.from(host?.querySelectorAll<HTMLButtonElement>('button') ?? []).find(\n (button) => button.id === nextId,\n );\n nextButton?.focus();\n }\n}\n","import { Component, input } from '@angular/core';\n\n/** Un link del pie — legales, contacto, soporte. */\nexport interface FooterLink {\n label: string;\n href?: string;\n}\n\n/**\n * Pie de página general del portal (página 38): logo + copyright a la\n * izquierda, links legales/soporte empujados a la derecha. Logo y copyright\n * son inputs (cada portal del ecosistema — LATAM, OTD, Star — trae su\n * propia marca y texto legal); `links` es la lista de accesos, típicamente\n * placeholders hasta que existan destinos reales.\n *\n * <kf-footer\n * logoSrc=\"images/logo-kaufmann-dark.png\"\n * logoAlt=\"Grupo Kaufmann\"\n * copyright=\"© 2026 Kaufmann LATAM · Todos los derechos reservados\"\n * [links]=\"[\n * { label: 'Políticas de privacidad' },\n * { label: 'Contacto' },\n * { label: 'Sugerencias y reclamos' },\n * ]\"\n * />\n */\n@Component({\n selector: 'kf-footer',\n template: `\n <div class=\"kf-footer__wrap\">\n @if (logoSrc()) {\n <img class=\"kf-footer__logo\" [src]=\"logoSrc()\" [alt]=\"logoAlt()\" />\n }\n <span class=\"kf-footer__copyright\">{{ copyright() }}</span>\n @if (links().length) {\n <nav class=\"kf-footer__links\">\n @for (link of links(); track link.label) {\n <a [href]=\"link.href || '#'\">{{ link.label }}</a>\n }\n </nav>\n }\n </div>\n `,\n styles: `\n :host {\n display: block;\n margin-top: auto;\n background: var(--kf-color-tertiary-deep);\n }\n .kf-footer__wrap {\n max-width: var(--kf-footer-max-width, none);\n margin: 0 auto;\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: var(--kf-space-lg);\n min-height: 4.5rem;\n padding: var(--kf-space-md) var(--kf-space-lg);\n }\n .kf-footer__logo {\n height: 1.375rem;\n opacity: 0.9;\n }\n .kf-footer__copyright {\n font-size: 0.8125rem;\n color: rgba(255, 255, 255, 0.55);\n font-family: var(--kf-font-body);\n }\n .kf-footer__links {\n margin-left: auto;\n display: flex;\n flex-wrap: wrap;\n gap: var(--kf-space-lg);\n }\n .kf-footer__links a {\n font-size: 0.8125rem;\n color: rgba(255, 255, 255, 0.66);\n text-decoration: none;\n font-family: var(--kf-font-body);\n }\n .kf-footer__links a:hover {\n color: #fff;\n }\n @media (max-width: 640px) {\n .kf-footer__wrap {\n flex-direction: column;\n align-items: flex-start;\n }\n .kf-footer__links {\n margin-left: 0;\n }\n }\n `,\n})\nexport class Footer {\n readonly logoSrc = input<string>();\n readonly logoAlt = input('');\n readonly copyright = input.required<string>();\n readonly links = input<FooterLink[]>([]);\n}\n","import {\n AfterViewInit,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n forwardRef,\n input,\n signal,\n viewChild,\n} from '@angular/core';\nimport { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { FieldLabel } from '../field-label/FieldLabel';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Input de formulario apilado: label arriba (en mayúsculas vía CSS), campo con\n * fondo gris que pasa a blanco con anillo de foco azul al enfocar.\n *\n * Implementa ControlValueAccessor, así que funciona con [(ngModel)] y con\n * Reactive Forms (formControl / formControlName), no es solo un wrapper visual.\n *\n * <kf-input label=\"Placa\" icon=\"car\" placeholder=\"ABC-123\" hint=\"Formato: 3 letras + 3 números\" />\n * <input kf-input formControlName=\"email\" type=\"email\" />\n *\n * `invalid` + `errorMessage` cubren el estado de error: con `invalid` el\n * borde pasa a rojo (`--kf-color-error`) y se setea `aria-invalid=\"true\"` en\n * el `<input>` nativo; `errorMessage` reemplaza el `hint` neutro por un\n * mensaje en rojo con `role=\"alert\"`, para que un lector de pantalla lo\n * anuncie apenas aparece (a diferencia de `hint`, que es solo informativo y\n * nunca interrumpe). Si se pasan ambos, `errorMessage` tiene prioridad\n * visual sobre `hint` — no tiene sentido mostrar los dos a la vez.\n *\n * <kf-input label=\"Correo\" formControlName=\"email\"\n * [invalid]=\"email.invalid && email.touched\"\n * [errorMessage]=\"email.touched && email.hasError('required') ? 'Ingresa tu correo.' : undefined\" />\n *\n * `toggleable` solo tiene efecto cuando `type=\"password\"`: agrega un botón\n * de ojo al final del campo que alterna la visibilidad del valor tipeado\n * (cambia el `type` real del `<input>` nativo entre `password` y `text`,\n * nunca expone el valor en el DOM de otra forma). El botón es `type=\"button\"`\n * — nunca dispara submit del form contenedor — y anuncia su acción con\n * `aria-label` dinámico y `aria-pressed`, ya que es un toggle, no un botón\n * de una sola acción.\n *\n * <kf-input type=\"password\" label=\"Contraseña\" toggleable formControlName=\"password\" />\n */\n@Component({\n selector: 'kf-input',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [FormsModule, FieldLabel, Icon],\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => Input),\n multi: true,\n },\n ],\n template: `\n @if (label()) {\n <kf-field-label [for]=\"inputId\" [required]=\"required()\">{{ label() }}</kf-field-label>\n }\n <div\n class=\"kf-input__field\"\n [class.kf-input__field--disabled]=\"isDisabled()\"\n [class.kf-input__field--focused]=\"focused()\"\n [class.kf-input__field--invalid]=\"invalid()\"\n >\n @if (icon(); as iconName) {\n <kf-icon class=\"kf-input__icon\" [name]=\"iconName\" size=\"sm\" />\n }\n <input\n #nativeInput\n [id]=\"inputId\"\n class=\"kf-input__control\"\n [type]=\"effectiveType()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-describedby]=\"errorMessage() ? errorId : hint() ? hintId : null\"\n [attr.aria-invalid]=\"invalid() ? true : null\"\n [value]=\"value()\"\n (input)=\"onInput(nativeInput.value)\"\n (blur)=\"onBlur()\"\n (focus)=\"focused.set(true)\"\n />\n @if (showPasswordToggle()) {\n <button\n type=\"button\"\n class=\"kf-input__toggle\"\n [attr.aria-label]=\"passwordVisible() ? 'Ocultar contraseña' : 'Mostrar contraseña'\"\n [attr.aria-pressed]=\"passwordVisible()\"\n (click)=\"onTogglePasswordVisibility()\"\n >\n <kf-icon [name]=\"passwordVisible() ? 'eye-off' : 'eye'\" size=\"sm\" />\n </button>\n } @else if (suffix()) {\n <span class=\"kf-input__suffix\">{{ suffix() }}</span>\n }\n </div>\n @if (errorMessage(); as message) {\n <span class=\"kf-input__error\" [id]=\"errorId\" role=\"alert\">{{ message }}</span>\n } @else if (hint()) {\n <span class=\"kf-input__hint\" [id]=\"hintId\">{{ hint() }}</span>\n }\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n font-family: var(--kf-font-body);\n }\n .kf-input__field {\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n padding: 0 var(--kf-space-sm);\n background: var(--kf-color-surface);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n transition:\n background 0.14s,\n border-color 0.14s,\n box-shadow 0.14s;\n }\n .kf-input__field--focused {\n background: var(--kf-color-white);\n border-color: var(--kf-color-primary);\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-input__field--invalid {\n border-color: var(--kf-color-error);\n }\n .kf-input__field--invalid.kf-input__field--focused {\n box-shadow: 0 0 0 3px rgba(235, 87, 87, 0.22);\n }\n .kf-input__field--disabled {\n opacity: 0.5;\n }\n .kf-input__icon {\n color: var(--kf-color-text-muted);\n }\n .kf-input__field--invalid .kf-input__icon {\n color: var(--kf-color-error);\n }\n .kf-input__control {\n flex: 1;\n min-width: 0;\n border: none;\n outline: none;\n background: transparent;\n font: inherit;\n color: var(--kf-color-text);\n padding: var(--kf-space-sm) 0;\n }\n .kf-input__control::placeholder {\n color: var(--kf-color-text-muted);\n }\n .kf-input__control:disabled {\n cursor: not-allowed;\n }\n .kf-input__suffix {\n flex: none;\n color: var(--kf-color-text-muted);\n font-size: 0.875rem;\n }\n .kf-input__toggle {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n padding: var(--kf-space-xs);\n margin: 0 calc(var(--kf-space-xs) * -1);\n color: var(--kf-color-text-muted);\n cursor: pointer;\n border-radius: var(--kf-radius-xs);\n transition: color 0.14s;\n }\n .kf-input__toggle:hover {\n color: var(--kf-color-text);\n }\n .kf-input__toggle:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-input__hint {\n font-size: 0.75rem;\n color: var(--kf-color-text-muted);\n }\n .kf-input__error {\n display: flex;\n align-items: center;\n gap: var(--kf-space-xs);\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--kf-color-error-strong);\n }\n `,\n})\nexport class Input implements ControlValueAccessor, AfterViewInit {\n private static nextId = 0;\n\n private readonly nativeInput = viewChild.required<ElementRef<HTMLInputElement>>('nativeInput');\n\n readonly label = input<string>();\n /** Marca el label con un asterisco visual — no aplica `required` al `<input>` nativo por sí solo. */\n readonly required = input(false, { transform: booleanAttribute });\n /** Ícono líder, renderizado vía `kf-icon`. */\n readonly icon = input<IconName>();\n readonly suffix = input<string>();\n readonly hint = input<string>();\n /** Borde y aria-invalid en rojo. Ver `errorMessage` para el mensaje asociado. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /** Mensaje de error con `role=\"alert\"` — reemplaza a `hint` mientras esté presente. */\n readonly errorMessage = input<string>();\n readonly disabled = input(false, { transform: booleanAttribute });\n readonly type = input<string>('text');\n readonly placeholder = input<string>('');\n /** Agrega el botón de mostrar/ocultar — sin efecto si `type` no es `\"password\"`. */\n readonly toggleable = input(false, { transform: booleanAttribute });\n\n protected readonly inputId = `kf-input-${Input.nextId++}`;\n protected readonly hintId = `${this.inputId}-hint`;\n protected readonly errorId = `${this.inputId}-error`;\n\n protected readonly value = signal('');\n protected readonly focused = signal(false);\n /** Deshabilitado por Reactive Forms (formControl.disable()). */\n private readonly disabledByForm = signal(false);\n /** Disabled real: por input() directo o por el FormControl asociado. */\n protected readonly isDisabled = computed(() => this.disabled() || this.disabledByForm());\n\n /** Estado interno del toggle — irrelevante si `showPasswordToggle()` es false. */\n protected readonly passwordVisible = signal(false);\n /** El botón solo tiene sentido si el campo realmente es de contraseña. */\n protected readonly showPasswordToggle = computed(\n () => this.toggleable() && this.type() === 'password',\n );\n /**\n * `type` real que recibe el `<input>` nativo: igual a `type()` salvo\n * cuando el toggle está activo y visible, donde pasa a `text` para\n * mostrar el valor en claro sin cambiar `type()` en sí (evita que un\n * consumidor que lee `type()` desde afuera vea un valor inconsistente).\n */\n protected readonly effectiveType = computed(() =>\n this.showPasswordToggle() && this.passwordVisible() ? 'text' : this.type(),\n );\n\n private onChange: (value: string) => void = () => {};\n private onTouched: () => void = () => {};\n\n ngAfterViewInit(): void {\n // El binding declarativo [value]=\"value()\" no siempre re-sincroniza la\n // propiedad DOM del <input> cuando el valor llega por writeValue() antes\n // de que la vista termine de inicializarse — se refuerza escribiendo la\n // propiedad DOM directamente para que el primer valor de un formulario\n // ya cargado (ngModel/formControl con valor inicial) se refleje siempre.\n this.nativeInput().nativeElement.value = this.value();\n }\n\n writeValue(value: string): void {\n const nextValue = value ?? '';\n this.value.set(nextValue);\n // Mismo motivo que en ngAfterViewInit: escritura directa a la propiedad\n // DOM además del binding declarativo, para que cambios de valor\n // posteriores (ej. patchValue de un FormControl) siempre lleguen al\n // input nativo sin depender del timing de detección de cambios.\n const el = this.nativeInput?.();\n if (el) {\n el.nativeElement.value = nextValue;\n }\n }\n\n registerOnChange(fn: (value: string) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.disabledByForm.set(isDisabled);\n }\n\n protected onInput(rawValue: string): void {\n this.value.set(rawValue);\n this.onChange(rawValue);\n }\n\n protected onBlur(): void {\n this.focused.set(false);\n this.onTouched();\n }\n\n /**\n * Alterna la visibilidad del valor. No dispara `onBlur`/pierde el foco:\n * el botón vive dentro del mismo `.kf-input__field`, así que un click acá\n * no debe tratarse como si el usuario hubiese abandonado el campo.\n */\n protected onTogglePasswordVisibility(): void {\n this.passwordVisible.update((visible) => !visible);\n }\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\n\nexport type LinkVariant = 'default' | 'muted';\n\n/**\n * Acción de bajo énfasis con apariencia de texto — \"¿Olvidaste tu\n * contraseña?\", \"Volver a iniciar sesión\". Antes de este componente,\n * `web-portal-latam-frontend` reimplementaba esto dos veces (`.login__forgot`\n * como `<a href=\"#\">` con `preventDefault()`, `.login__back` como\n * `<button>`), cada una con su propio `:focus-visible` copiado literal.\n *\n * Es siempre un `<button type=\"button\">` por dentro, nunca un `<a>`: ninguno\n * de los dos casos reales navega a otra URL, ambos disparan una acción en la\n * misma pantalla (cambiar de vista, someter un flujo). Si en el futuro un\n * consumidor necesita navegación real con href, esa es una discusión de API\n * distinta (`kf-link` con `[routerLink]`/`href`), no se fuerza acá sin caso\n * de uso confirmado.\n *\n * `variant=\"default\"` (color primario, subrayado en hover) es para la\n * acción de mayor jerarquía relativa de la pantalla (ej. \"¿Olvidaste tu\n * contraseña?\"); `variant=\"muted\"` (gris que pasa a primario en hover) es\n * para acciones de retroceso/salida (ej. \"← Volver a iniciar sesión\").\n *\n * <kf-link (click)=\"onForgotPassword()\">¿Olvidaste tu contraseña?</kf-link>\n * <kf-link variant=\"muted\" (click)=\"onBack()\">← Volver a iniciar sesión</kf-link>\n */\n@Component({\n selector: 'kf-link',\n template: `\n <button\n type=\"button\"\n class=\"kf-link\"\n [class.kf-link--muted]=\"variant() === 'muted'\"\n [disabled]=\"disabled()\"\n >\n <ng-content />\n </button>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-link {\n padding: 0;\n border: none;\n background: transparent;\n font: inherit;\n font-weight: 500;\n color: var(--kf-color-primary);\n text-decoration: none;\n cursor: pointer;\n }\n .kf-link:hover:not(:disabled) {\n text-decoration: underline;\n }\n .kf-link:focus-visible {\n outline: 2px solid var(--kf-color-primary);\n outline-offset: 2px;\n border-radius: var(--kf-radius-xs);\n }\n .kf-link:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .kf-link--muted {\n color: var(--kf-color-text-muted);\n }\n .kf-link--muted:hover:not(:disabled) {\n color: var(--kf-color-primary);\n text-decoration: none;\n }\n `,\n})\nexport class Link {\n readonly variant = input<LinkVariant>('default');\n readonly disabled = input(false, { transform: booleanAttribute });\n}\n","import { Component, input } from '@angular/core';\nimport { Card } from '../card/Card';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Card de estadística/KPI: label, valor grande, ícono opcional en la esquina\n * superior derecha, badge de esquina opcional (pegado al valor) y una nota\n * al pie. Pensada para tableros de resumen (ej. \"11 Tickets abiertos\").\n *\n * Compone sobre `kf-card` en vez de duplicar su estilo de contenedor — así\n * el look de \"card\" (radio, sombra, borde) tiene una única fuente de verdad\n * en toda la librería, tal como pide el design system (página 14: \"Card...\n * es la base de paneles, tarjetas de métrica, tablas...\").\n *\n * <kf-metric-card label=\"Tickets abiertos\" value=\"11\" icon=\"ticket\" foot=\"+2 hoy\" />\n * <kf-metric-card label=\"Tasa de resolución\" value=\"94%\" badge=\"+2%\" value-color=\"var(--kf-color-success)\" />\n */\n@Component({\n selector: 'kf-metric-card',\n imports: [Card, Icon],\n template: `\n <kf-card>\n <div class=\"kf-metric-card__head\">\n <span class=\"kf-metric-card__label\">{{ label() }}</span>\n @if (icon(); as iconName) {\n <span class=\"kf-metric-card__icon\">\n <kf-icon [name]=\"iconName\" size=\"sm\" />\n </span>\n }\n </div>\n <div class=\"kf-metric-card__value-row\">\n <div class=\"kf-metric-card__value\" [style.color]=\"valueColor()\">\n {{ value() }}\n @if (unit()) {\n <span class=\"kf-metric-card__unit\">{{ unit() }}</span>\n }\n </div>\n @if (badge()) {\n <span class=\"kf-metric-card__badge\">{{ badge() }}</span>\n }\n </div>\n @if (foot()) {\n <div class=\"kf-metric-card__foot\">{{ foot() }}</div>\n }\n </kf-card>\n `,\n styles: `\n :host {\n display: block;\n }\n .kf-metric-card__head {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: var(--kf-space-xs);\n }\n .kf-metric-card__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 1.75rem;\n height: 1.75rem;\n flex: none;\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-primary-soft);\n color: var(--kf-color-primary);\n }\n .kf-metric-card__label {\n font-size: 0.72rem;\n font-weight: 700;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n color: var(--kf-color-text-muted);\n }\n .kf-metric-card__value-row {\n display: flex;\n align-items: center;\n gap: var(--kf-space-xs);\n }\n .kf-metric-card__value {\n font-family: var(--kf-font-title);\n font-weight: 700;\n font-size: 1.6rem;\n line-height: 1.1;\n color: var(--kf-color-ink);\n }\n .kf-metric-card__unit {\n font-size: 0.85rem;\n font-weight: 500;\n color: var(--kf-color-text-muted);\n margin-left: var(--kf-space-xs);\n }\n .kf-metric-card__badge {\n font-size: 0.72rem;\n font-weight: 700;\n padding: 2px var(--kf-space-xs);\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-success-soft);\n color: var(--kf-color-success-strong);\n }\n .kf-metric-card__foot {\n font-size: 0.78rem;\n color: var(--kf-color-text-muted);\n }\n `,\n})\nexport class MetricCard {\n readonly label = input.required<string>();\n readonly value = input.required<string | number>();\n readonly unit = input<string>();\n /** Ícono en la esquina superior derecha, renderizado vía `kf-icon`. */\n readonly icon = input<IconName>();\n readonly foot = input<string>();\n /** Tinte opcional para el valor grande (ej. un color semántico de estado). */\n readonly valueColor = input<string>();\n /** Badge de esquina opcional, pegado al valor (ej. \"+2%\"). */\n readonly badge = input<string>();\n}\n","import { DOCUMENT } from '@angular/common';\nimport {\n booleanAttribute,\n Component,\n DestroyRef,\n ElementRef,\n HostListener,\n afterRenderEffect,\n inject,\n input,\n model,\n viewChild,\n} from '@angular/core';\n\nlet modalId = 0;\n\n/**\n * Diálogo centrado sobre un backdrop: confirmaciones destructivas, formularios\n * cortos, decisiones que bloquean el flujo.\n *\n * Se apoya en el `<dialog>` nativo (`showModal()`), así que el atrapado de\n * foco, el backdrop, el orden en el top-layer y el cierre con `Escape` los\n * resuelve el navegador — no hay trampa de foco escrita a mano acá. Lo único\n * que se agrega es el lock de scroll del body, que `<dialog>` no hace.\n *\n * `open` es two-way. Con `dismissible` en `false` (ej. mientras una acción\n * destructiva está en vuelo) se cancelan `Escape` y el clic en el backdrop:\n * solo cierra el consumidor poniendo `open` en `false`.\n *\n * Las acciones van en el slot `footer`.\n *\n * <kf-modal [(open)]=\"confirmOpen\" title=\"Eliminar unidad\">\n * <p>Esta acción no se puede deshacer.</p>\n * <div footer>\n * <kf-button variant=\"ghost\" (click)=\"confirmOpen.set(false)\">Cancelar</kf-button>\n * <kf-button (click)=\"remove()\">Eliminar</kf-button>\n * </div>\n * </kf-modal>\n */\n@Component({\n selector: 'kf-modal',\n template: `\n <dialog\n #dialog\n class=\"kf-modal\"\n [attr.aria-labelledby]=\"title() ? titleId : null\"\n (cancel)=\"onCancel($event)\"\n (close)=\"open.set(false)\"\n >\n @if (open()) {\n <div class=\"kf-modal__panel\">\n <div class=\"kf-modal__head\">\n @if (title()) {\n <h2 class=\"kf-modal__title\" [id]=\"titleId\">{{ title() }}</h2>\n }\n @if (dismissible()) {\n <button\n type=\"button\"\n class=\"kf-modal__close\"\n aria-label=\"Cerrar diálogo\"\n (click)=\"open.set(false)\"\n >\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M6 6l12 12M18 6L6 18\" />\n </svg>\n </button>\n }\n </div>\n <div class=\"kf-modal__body\"><ng-content /></div>\n <div class=\"kf-modal__footer\"><ng-content select=\"[footer]\" /></div>\n </div>\n }\n </dialog>\n `,\n styles: `\n .kf-modal {\n width: min(480px, calc(100vw - 2 * var(--kf-space-md)));\n max-height: calc(100vh - 2 * var(--kf-space-xl));\n padding: 0;\n border: none;\n background: transparent;\n overflow: visible;\n font-family: var(--kf-font-body);\n }\n .kf-modal::backdrop {\n background: rgba(23, 29, 37, 0.45);\n }\n .kf-modal__panel {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-md);\n padding: var(--kf-space-lg);\n background: var(--kf-color-white);\n border-radius: var(--kf-radius-md);\n box-shadow: var(--kf-shadow-lg);\n }\n .kf-modal__head {\n display: flex;\n align-items: flex-start;\n gap: var(--kf-space-sm);\n }\n .kf-modal__title {\n flex: 1;\n margin: 0;\n font-family: var(--kf-font-title);\n font-size: 1.375rem;\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-modal__close {\n flex: none;\n display: inline-flex;\n padding: 2px;\n border: none;\n background: transparent;\n color: var(--kf-color-text-muted);\n border-radius: var(--kf-radius-xs);\n cursor: pointer;\n }\n .kf-modal__close svg {\n width: 1.25em;\n height: 1.25em;\n fill: none;\n stroke: currentColor;\n stroke-width: 1.9;\n stroke-linecap: round;\n }\n .kf-modal__close:hover {\n color: var(--kf-color-ink);\n }\n .kf-modal__close:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-modal__body {\n color: var(--kf-color-text);\n overflow-y: auto;\n }\n .kf-modal__footer:empty {\n display: none;\n }\n .kf-modal__footer {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-end;\n gap: var(--kf-space-sm);\n }\n `,\n})\nexport class Modal {\n readonly title = input('');\n /** Visibilidad, two-way: `[(open)]=\"confirmOpen\"`. */\n readonly open = model(false);\n /** Permite cerrar con el botón, `Escape` o clic en el backdrop. */\n readonly dismissible = input(true, { transform: booleanAttribute });\n\n protected readonly titleId = `kf-modal-title-${modalId++}`;\n\n private readonly dialog = viewChild<ElementRef<HTMLDialogElement>>('dialog');\n private readonly document = inject(DOCUMENT);\n\n constructor() {\n afterRenderEffect(() => {\n const el = this.dialog()?.nativeElement;\n if (!el) {\n return;\n }\n if (this.open() && !el.open) {\n // ponytail: `showModal` no existe en jsdom (tests) ni en entornos sin\n // top-layer; el atributo `open` lo deja visible, aunque no modal.\n if (typeof el.showModal === 'function') {\n el.showModal();\n } else {\n el.open = true;\n }\n } else if (!this.open() && el.open) {\n if (typeof el.close === 'function') {\n el.close();\n } else {\n el.open = false;\n }\n }\n // `<dialog>` inertiza el resto de la página pero no frena su scroll.\n this.document.body.style.overflow = this.open() ? 'hidden' : '';\n });\n\n inject(DestroyRef).onDestroy(() => {\n this.document.body.style.overflow = '';\n });\n }\n\n /** `Escape` dispara `cancel`; cancelarlo lo deja abierto. */\n protected onCancel(event: Event): void {\n if (!this.dismissible()) {\n event.preventDefault();\n }\n }\n\n /**\n * Clic en el backdrop. Un clic en la zona del backdrop tiene como `target` al\n * propio `<dialog>` (el contenido vive en el panel de adentro), así que basta\n * comparar contra él — no hace falta cortar la propagación en el panel.\n *\n * Va como HostListener y no como binding en el template porque un `(click)`\n * sobre el `<dialog>` dispara las reglas a11y de click-sin-teclado; acá el\n * equivalente de teclado es `Escape`, que el `<dialog>` nativo ya maneja.\n */\n @HostListener('click', ['$event'])\n protected onHostClick(event: MouseEvent): void {\n if (this.dismissible() && event.target === this.dialog()?.nativeElement) {\n this.open.set(false);\n }\n }\n}\n","import { Overlay, type OverlayRef } from '@angular/cdk/overlay';\nimport { TemplatePortal } from '@angular/cdk/portal';\nimport {\n Component,\n DestroyRef,\n ElementRef,\n HostListener,\n TemplateRef,\n ViewContainerRef,\n afterRenderEffect,\n booleanAttribute,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { FieldLabel } from '../field-label/FieldLabel';\nimport { normalizeForSearch } from '../shared/search-text';\n\nexport interface MultiSelectOption {\n value: string;\n label: string;\n}\n\nlet nextId = 0;\n\n/**\n * Dropdown de selección múltiple con checkboxes internos. El panel flotante\n * se conecta al trigger vía `@angular/cdk/overlay` — el mismo mecanismo que\n * `Select` (ver `../select/Select.ts`) y `Dropdown` (`../dropdown/Dropdown.ts`).\n *\n * Hasta la `0.1.9` este panel vivía con `position: absolute` manual sobre el\n * propio host, sin depender del CDK Overlay. Se migró para unificar el\n * mecanismo de posicionamiento/cierre con el resto de los dropdowns flotantes\n * de la librería (4 posiciones de fallback, `withViewportMargin`, `withPush`,\n * cierre por `outsidePointerEvents()`/`keydownEvents()` en vez de un\n * `@HostListener('document:click')` manual).\n *\n * A diferencia de `Select`, el disparador no muestra un único valor sino los\n * nombres seleccionados junto a un badge circular con el conteo, y cada\n * opción del panel se marca/desmarca con un checkbox sin cerrar el panel.\n * Incluye una opción \"Todas\" al inicio de la lista, con estado\n * `indeterminate` cuando hay selección parcial — el mismo patrón de\n * \"seleccionar todos\" de `Checkbox`. \"Todas\" nunca se filtra por el buscador:\n * queda siempre visible y sigue actuando sobre el universo COMPLETO de\n * `options()`, no sobre el subconjunto filtrado (ver JSDoc de `toggleAll()`).\n *\n * <kf-multi-select\n * label=\"Sucursales\"\n * [options]=\"branches\"\n * [values]=\"selectedBranches()\"\n * (valuesChange)=\"selectedBranches.set($event)\"\n * />\n *\n * Pendiente: el prop `icon` de otros componentes del design system requiere\n * un componente Icon / sprite SVG que esta librería todavía no tiene — este\n * componente no usa iconos, así que no aplica acá.\n */\n@Component({\n selector: 'kf-multi-select',\n imports: [FieldLabel],\n template: `\n @if (label()) {\n <kf-field-label [for]=\"triggerId\">{{ label() }}</kf-field-label>\n }\n <button\n #trigger\n type=\"button\"\n [id]=\"triggerId\"\n class=\"kf-multi-select__trigger\"\n [disabled]=\"disabled()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-controls]=\"isOpen() ? listboxId : null\"\n (click)=\"toggle()\"\n >\n <span\n class=\"kf-multi-select__value\"\n [class.kf-multi-select__value--placeholder]=\"selectedCount() === 0\"\n >\n {{ summaryText() }}\n </span>\n @if (selectedCount() > 0) {\n <span class=\"kf-multi-select__count\">{{ selectedCount() }}</span>\n }\n <span\n class=\"kf-multi-select__caret\"\n [class.kf-multi-select__caret--open]=\"isOpen()\"\n aria-hidden=\"true\"\n ></span>\n </button>\n <ng-template #panelTemplate>\n <div class=\"kf-multi-select__panel\">\n @if (showSearch()) {\n <input\n #searchInput\n type=\"text\"\n class=\"kf-multi-select__search\"\n placeholder=\"Buscar…\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($event)\"\n (keydown.arrowdown)=\"$event.preventDefault(); moveActive(1)\"\n (keydown.arrowup)=\"$event.preventDefault(); moveActive(-1)\"\n (keydown.enter)=\"$event.preventDefault(); toggleActive()\"\n />\n }\n <ul\n class=\"kf-multi-select__list\"\n [id]=\"listboxId\"\n role=\"listbox\"\n aria-multiselectable=\"true\"\n [attr.aria-labelledby]=\"triggerId\"\n >\n @if (options().length > 0) {\n <li\n class=\"kf-multi-select__option\"\n role=\"option\"\n tabindex=\"0\"\n [attr.aria-selected]=\"allSelected()\"\n (click)=\"toggleAll()\"\n (keydown.enter)=\"toggleAll()\"\n (keydown.space)=\"$event.preventDefault(); toggleAll()\"\n >\n <span\n class=\"kf-multi-select__checkbox\"\n [class.kf-multi-select__checkbox--checked]=\"allSelected()\"\n [class.kf-multi-select__checkbox--indeterminate]=\"isPartiallySelected()\"\n ></span>\n <span class=\"kf-multi-select__option-label\">Todas</span>\n </li>\n }\n @for (option of filteredOptions(); track option.value; let i = $index) {\n <li\n class=\"kf-multi-select__option\"\n [class.kf-multi-select__option--selected]=\"isSelected(option.value)\"\n [class.kf-multi-select__option--active]=\"i === activeIndex()\"\n role=\"option\"\n tabindex=\"0\"\n [attr.aria-selected]=\"isSelected(option.value)\"\n (click)=\"toggleOption(option.value)\"\n (mouseenter)=\"activeIndex.set(i)\"\n (keydown.enter)=\"toggleOption(option.value)\"\n (keydown.space)=\"$event.preventDefault(); toggleOption(option.value)\"\n (keydown.arrowdown)=\"$event.preventDefault(); moveActive(1)\"\n (keydown.arrowup)=\"$event.preventDefault(); moveActive(-1)\"\n >\n <span\n class=\"kf-multi-select__checkbox\"\n [class.kf-multi-select__checkbox--checked]=\"isSelected(option.value)\"\n ></span>\n <span class=\"kf-multi-select__option-label\">{{ option.label }}</span>\n </li>\n } @empty {\n @if (options().length > 0) {\n <li class=\"kf-multi-select__empty\">Sin resultados</li>\n } @else {\n <li class=\"kf-multi-select__empty\">Sin opciones disponibles</li>\n }\n }\n </ul>\n </div>\n </ng-template>\n `,\n styles: `\n :host {\n display: inline-flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n font: inherit;\n /*\n * Ancho FIJO, no min-width: con solo un piso, el host podía seguir\n * creciendo sin límite a medida que summaryText() sumaba más labels\n * seleccionados — un multiselect con 3-4 opciones largas terminaba\n * ocupando el doble o el triple que el resto de los campos del mismo\n * formulario. El texto que no entra se corta con el\n * text-overflow: ellipsis que .kf-multi-select__value ya tenía, el\n * badge de conteo (.kf-multi-select__count) sigue siempre visible al\n * lado para comunicar cuántas opciones hay seleccionadas aunque el\n * texto se trunque.\n */\n width: 240px;\n }\n .kf-multi-select__trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-sm);\n width: 100%;\n font: inherit;\n font-family: var(--kf-font-body);\n padding: var(--kf-space-sm) var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-white);\n color: var(--kf-color-text);\n cursor: pointer;\n transition:\n border-color 0.14s,\n box-shadow 0.14s;\n }\n .kf-multi-select__trigger:hover:not(:disabled) {\n border-color: var(--kf-color-border-strong);\n }\n .kf-multi-select__trigger:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-multi-select__trigger:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .kf-multi-select__value {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n text-align: left;\n }\n .kf-multi-select__value--placeholder {\n color: var(--kf-color-text-muted);\n }\n .kf-multi-select__count {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 1.25rem;\n height: 1.25rem;\n padding: 0 5px;\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-primary);\n color: var(--kf-color-white);\n font-size: 0.72rem;\n font-weight: 700;\n }\n .kf-multi-select__caret {\n flex-shrink: 0;\n width: 8px;\n height: 8px;\n border-right: 2px solid var(--kf-color-text-muted);\n border-bottom: 2px solid var(--kf-color-text-muted);\n transform: rotate(45deg);\n transition: transform 0.14s;\n margin-top: -4px;\n }\n .kf-multi-select__caret--open {\n transform: rotate(-135deg);\n margin-top: 4px;\n }\n .kf-multi-select__panel {\n box-sizing: border-box;\n width: 100%;\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n box-shadow: var(--kf-shadow-md);\n overflow: hidden;\n }\n .kf-multi-select__search {\n box-sizing: border-box;\n width: 100%;\n font: inherit;\n font-family: var(--kf-font-body);\n color: var(--kf-color-text);\n padding: var(--kf-space-sm) var(--kf-space-md);\n border: none;\n border-bottom: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm) var(--kf-radius-sm) 0 0;\n outline: none;\n }\n .kf-multi-select__search:focus-visible {\n box-shadow: inset 0 0 0 2px var(--kf-color-primary);\n }\n .kf-multi-select__list {\n box-sizing: border-box;\n width: 100%;\n margin: 0;\n padding: var(--kf-space-xs) 0;\n list-style: none;\n max-height: 240px;\n overflow-y: auto;\n scrollbar-width: thin;\n scrollbar-color: var(--kf-color-gray-400) transparent;\n }\n .kf-multi-select__list::-webkit-scrollbar {\n width: 6px;\n }\n .kf-multi-select__list::-webkit-scrollbar-track {\n background: transparent;\n }\n .kf-multi-select__list::-webkit-scrollbar-thumb {\n background-color: var(--kf-color-gray-400);\n border-radius: var(--kf-radius-pill);\n }\n .kf-multi-select__list::-webkit-scrollbar-thumb:hover {\n background-color: var(--kf-color-gray-500);\n }\n .kf-multi-select__option {\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-sm) var(--kf-space-md);\n color: var(--kf-color-text);\n cursor: pointer;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .kf-multi-select__option:hover {\n background: var(--kf-color-primary-soft);\n }\n .kf-multi-select__option--selected {\n color: var(--kf-color-primary);\n font-weight: 600;\n }\n /* Opción con foco de teclado — distinta del hover, comparte el mismo tinte de fondo. */\n .kf-multi-select__option--active {\n background: var(--kf-color-primary-soft);\n }\n .kf-multi-select__checkbox {\n display: inline-flex;\n flex-shrink: 0;\n width: var(--kf-space-md);\n height: var(--kf-space-md);\n border: 1px solid var(--kf-color-border-strong);\n border-radius: var(--kf-radius-xs);\n background: var(--kf-color-white);\n transition:\n background 0.14s,\n border-color 0.14s;\n position: relative;\n }\n .kf-multi-select__checkbox--checked {\n background: var(--kf-color-primary);\n border-color: var(--kf-color-primary);\n }\n .kf-multi-select__checkbox--checked::after {\n content: '';\n position: absolute;\n left: 4px;\n top: 1px;\n width: 4px;\n height: 8px;\n border: solid var(--kf-color-white);\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n /* \"Todas\" con selección parcial: barra horizontal, mismo patrón que Checkbox. */\n .kf-multi-select__checkbox--indeterminate {\n background: var(--kf-color-primary);\n border-color: var(--kf-color-primary);\n }\n .kf-multi-select__checkbox--indeterminate::after {\n content: '';\n position: absolute;\n left: 3px;\n top: 6px;\n width: 8px;\n height: 2px;\n background: var(--kf-color-white);\n border: none;\n transform: none;\n }\n .kf-multi-select__option-label {\n overflow: hidden;\n text-overflow: ellipsis;\n }\n .kf-multi-select__empty {\n text-align: center;\n padding: var(--kf-space-sm) var(--kf-space-md);\n color: var(--kf-color-text-muted);\n }\n `,\n})\nexport class MultiSelect {\n readonly label = input<string>();\n readonly options = input<MultiSelectOption[]>([]);\n readonly values = input<string[]>([]);\n readonly placeholder = input<string>('Seleccionar');\n readonly disabled = input(false, { transform: booleanAttribute });\n /**\n * Tri-state: si el consumidor no lo especifica (`undefined`), el buscador\n * se activa solo cuando `options().length` supera `searchThreshold()`. Si\n * el consumidor define `true`/`false` explícitamente, ese valor manda por\n * sobre el umbral automático. Mismo criterio que `Select`.\n */\n readonly searchable = input<boolean | undefined>(undefined);\n readonly searchThreshold = input<number>(7);\n\n readonly valuesChange = output<string[]>();\n\n private readonly instanceId = `kf-multi-select-${nextId++}`;\n readonly triggerId = `${this.instanceId}-trigger`;\n readonly listboxId = `${this.instanceId}-listbox`;\n\n readonly isOpen = signal(false);\n readonly searchQuery = signal('');\n readonly activeIndex = signal(0);\n\n readonly selectedCount = computed(() => this.values().length);\n\n readonly allSelected = computed(\n () => this.options().length > 0 && this.values().length === this.options().length,\n );\n\n readonly isPartiallySelected = computed(() => this.values().length > 0 && !this.allSelected());\n\n readonly showSearch = computed(\n () => this.searchable() ?? this.options().length > this.searchThreshold(),\n );\n\n /** Opciones visibles tras aplicar el filtro de búsqueda (\"Todas\" nunca se filtra). */\n readonly filteredOptions = computed<MultiSelectOption[]>(() => {\n const query = normalizeForSearch(this.searchQuery().trim());\n if (!query) {\n return this.options();\n }\n return this.options().filter((option) => normalizeForSearch(option.label).includes(query));\n });\n\n /**\n * Texto del disparador: placeholder si no hay selección, o los nombres\n * seleccionados unidos por coma (el conteo va aparte, en el badge). Con\n * muchas opciones el `text-overflow: ellipsis` del `.kf-multi-select__value`\n * corta el texto — el badge de conteo siempre queda visible al lado.\n */\n readonly summaryText = computed(() => {\n const count = this.selectedCount();\n if (count === 0) {\n return this.placeholder();\n }\n const selectedLabels = this.values()\n .map((value) => this.options().find((option) => option.value === value)?.label)\n .filter((label): label is string => Boolean(label));\n return selectedLabels.join(', ');\n });\n\n private readonly triggerRef = viewChild.required<ElementRef<HTMLButtonElement>>('trigger');\n private readonly panelTemplate = viewChild.required<TemplateRef<unknown>>('panelTemplate');\n private readonly searchInputRef = viewChild<ElementRef<HTMLInputElement>>('searchInput');\n\n private readonly overlayService = inject(Overlay);\n private readonly viewContainerRef = inject(ViewContainerRef);\n private readonly destroyRef = inject(DestroyRef);\n\n private overlayRef: OverlayRef | null = null;\n\n constructor() {\n effect(() => {\n if (this.isOpen()) {\n this.attach();\n } else {\n this.detach();\n this.searchQuery.set('');\n this.activeIndex.set(0);\n }\n });\n\n // Autofocus del buscador al abrir — mismo patrón que Select. afterNextRender()\n // no puede invocarse dentro de un effect() (NG0203); afterRenderEffect() sí\n // es reactivo a signals y corre tras la actualización del DOM del panel.\n afterRenderEffect(() => {\n if (this.isOpen() && this.showSearch()) {\n this.searchInputRef()?.nativeElement.focus();\n }\n });\n\n this.destroyRef.onDestroy(() => this.overlayRef?.dispose());\n }\n\n isSelected(value: string): boolean {\n return this.values().includes(value);\n }\n\n toggle(): void {\n if (this.disabled()) {\n return;\n }\n this.isOpen.update((open) => !open);\n }\n\n toggleOption(value: string): void {\n const current = this.values();\n const next = current.includes(value)\n ? current.filter((selectedValue) => selectedValue !== value)\n : [...current, value];\n this.valuesChange.emit(next);\n }\n\n /**\n * Alterna entre \"todas seleccionadas\" y \"ninguna seleccionada\". Actúa\n * siempre sobre el universo COMPLETO de `options()`, no sobre\n * `filteredOptions()` — con un buscador activo, \"Todas\" no se filtra ni\n * cambia de significado: seguir marcando/desmarcando únicamente lo visible\n * sería sorprendente para quien ya tenía otras opciones (no visibles en el\n * filtro actual) seleccionadas de antes.\n */\n toggleAll(): void {\n this.valuesChange.emit(this.allSelected() ? [] : this.options().map((option) => option.value));\n }\n\n onSearchInput(event: Event): void {\n this.searchQuery.set((event.target as HTMLInputElement).value);\n this.activeIndex.set(0);\n }\n\n /** Mueve `activeIndex` sobre las opciones YA FILTRADAS visibles. Clamp simple, sin wraparound. */\n moveActive(delta: number): void {\n const count = this.filteredOptions().length;\n if (count === 0) {\n return;\n }\n this.activeIndex.update((current) => Math.min(Math.max(current + delta, 0), count - 1));\n }\n\n toggleActive(): void {\n const option = this.filteredOptions()[this.activeIndex()];\n if (option) {\n this.toggleOption(option.value);\n }\n }\n\n @HostListener('document:keydown.escape')\n onEscape(): void {\n this.isOpen.set(false);\n }\n\n private attach(): void {\n if (this.overlayRef?.hasAttached()) {\n return;\n }\n\n const overlayRef = this.getOrCreateOverlayRef();\n // Se remide el ancho del trigger en cada apertura, no solo la primera —\n // ver la misma nota en Select: cachear el ancho en la creación del\n // overlay lo deja desincronizado si el trigger cambia de tamaño entre\n // una apertura y la siguiente.\n overlayRef.updateSize({ width: this.triggerRef().nativeElement.getBoundingClientRect().width });\n\n const portal = new TemplatePortal(this.panelTemplate(), this.viewContainerRef);\n overlayRef.attach(portal);\n\n // outsidePointerEvents() dispara en la fase de CAPTURA de `click` sobre\n // `body` (ver OverlayOutsideClickDispatcher en @angular/cdk), ANTES de\n // que el evento llegue al trigger y corra (click)=\"toggle()\". Sin este\n // filtro, un click en el trigger para CERRAR el panel ya abierto hacía:\n // 1) este subscribe lo cierra primero (el trigger no es parte del\n // overlay, cuenta como \"afuera\"), 2) toggle() corre después y lo vuelve a\n // abrir porque ve isOpen ya en false — un solo click quedaba en no-op y\n // solo cerraba de verdad un click fuera del trigger. Mismo fix que Select\n // y Dropdown (ver notas ahí).\n overlayRef.outsidePointerEvents().subscribe((event) => {\n const target = event.target as Node | null;\n if (target && this.triggerRef().nativeElement.contains(target)) {\n return;\n }\n this.isOpen.set(false);\n });\n overlayRef.keydownEvents().subscribe((event) => {\n if (event.key === 'Escape') {\n this.isOpen.set(false);\n }\n });\n }\n\n private detach(): void {\n this.overlayRef?.detach();\n }\n\n private getOrCreateOverlayRef(): OverlayRef {\n if (this.overlayRef) {\n return this.overlayRef;\n }\n\n const positionStrategy = this.overlayService\n .position()\n .flexibleConnectedTo(this.triggerRef())\n .withPositions([\n { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 4 },\n { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -4 },\n { originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top', offsetY: 4 },\n { originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', offsetY: -4 },\n ])\n .withViewportMargin(8)\n .withPush(true);\n\n this.overlayRef = this.overlayService.create({\n positionStrategy,\n scrollStrategy: this.overlayService.scrollStrategies.reposition(),\n width: this.triggerRef().nativeElement.getBoundingClientRect().width,\n maxWidth: '90vw',\n });\n\n return this.overlayRef;\n }\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport { Component, computed, input } from '@angular/core';\n\nexport type TextAs = 'h1' | 'h2' | 'h3' | 'p' | 'span';\nexport type TextVariant =\n | 'title-xxl'\n | 'title-xl'\n | 'title-lg'\n | 'title-md'\n | 'title-sm'\n | 'body'\n | 'body-muted'\n | 'caption';\nexport type TextTone = 'neutral' | 'ok' | 'warn' | 'error' | 'info';\n\n/**\n * Tipografía unificada — separa la etiqueta semántica (`as`, qué es el\n * texto para el DOM/accesibilidad) del estilo visual (`variant`, cómo se\n * ve). Antes de este componente, cada pantalla que consume la librería\n * definía su propio `h1`/`p` con `font-size` suelto para el mismo rol\n * (título de página, subtítulo, texto secundario) — auditoría sobre\n * `web-portal-latam-frontend` encontró 9 tamaños distintos entre login y\n * home sin ningún paso de escala en común. `variant` resuelve eso contra\n * la escala de `tokens/base.css` (`--kf-font-size-*`).\n *\n * `tone` sigue la misma convención cerrada que `Alert`/`Badge`/`Chip`: sin\n * escape hatch de color libre. Si un caso necesita un color que `tone` no\n * cubre, es una discusión de design system, no una prop nueva acá.\n *\n * `title-xl`/`title-xxl` son un tier aparte de `title-lg|md|sm`: no vienen\n * de la auditoría de contenido de página (esa cerró en 2.125rem), son para\n * títulos protagonistas de pantalla completa (ej. bienvenida del home vía\n * `kf-page-header[size=xl|xxl]`) — ver tokens/base.css.\n *\n * <kf-text as=\"h1\" variant=\"title-lg\">Bienvenido de nuevo</kf-text>\n * <kf-text as=\"p\" variant=\"body-muted\">Ingresá con tu cuenta corporativa.</kf-text>\n * <kf-text as=\"span\" variant=\"caption\" tone=\"error\">Campo obligatorio</kf-text>\n */\n@Component({\n selector: 'kf-text',\n imports: [NgTemplateOutlet],\n template: `\n <!--\n Una sola proyección compartida (ng-template + ngTemplateOutlet) en vez\n de un <ng-content> por cada rama del @switch: Angular solo conecta la\n proyección real del consumidor a la PRIMERA instancia de <ng-content>\n que encuentra en el árbol de compilación — con un <ng-content> por\n rama, todas menos una quedan vacías en runtime (bug detectado por\n Text.spec.ts, no algo documentado a simple vista en los docs de Angular).\n -->\n <ng-template #projected><ng-content /></ng-template>\n @switch (tag()) {\n @case ('h1') {\n <h1 [class]=\"hostClass()\"><ng-container [ngTemplateOutlet]=\"projected\" /></h1>\n }\n @case ('h2') {\n <h2 [class]=\"hostClass()\"><ng-container [ngTemplateOutlet]=\"projected\" /></h2>\n }\n @case ('h3') {\n <h3 [class]=\"hostClass()\"><ng-container [ngTemplateOutlet]=\"projected\" /></h3>\n }\n @case ('span') {\n <span [class]=\"hostClass()\"><ng-container [ngTemplateOutlet]=\"projected\" /></span>\n }\n @default {\n <p [class]=\"hostClass()\"><ng-container [ngTemplateOutlet]=\"projected\" /></p>\n }\n }\n `,\n styles: `\n :host {\n display: contents;\n }\n h1,\n h2,\n h3,\n p,\n span {\n margin: 0;\n font-family: var(--kf-font-body);\n color: var(--kf-color-text);\n }\n\n /* Variant — tamaño y peso, independiente de la etiqueta semántica. */\n .kf-text--title-xxl {\n font-family: var(--kf-font-title);\n font-size: var(--kf-font-size-title-xxl);\n font-weight: var(--kf-font-weight-title);\n color: var(--kf-color-ink);\n }\n .kf-text--title-xl {\n font-family: var(--kf-font-title);\n font-size: var(--kf-font-size-title-xl);\n font-weight: var(--kf-font-weight-title);\n color: var(--kf-color-ink);\n }\n .kf-text--title-lg {\n font-family: var(--kf-font-title);\n font-size: var(--kf-font-size-title-lg);\n font-weight: var(--kf-font-weight-title);\n color: var(--kf-color-ink);\n }\n .kf-text--title-md {\n font-family: var(--kf-font-title);\n font-size: var(--kf-font-size-title-md);\n font-weight: var(--kf-font-weight-title);\n color: var(--kf-color-ink);\n }\n .kf-text--title-sm {\n font-family: var(--kf-font-title);\n font-size: var(--kf-font-size-title-sm);\n font-weight: var(--kf-font-weight-title);\n color: var(--kf-color-ink);\n }\n .kf-text--body {\n font-size: var(--kf-font-size-body);\n font-weight: var(--kf-font-weight-body);\n }\n .kf-text--body-muted {\n font-size: var(--kf-font-size-body);\n font-weight: var(--kf-font-weight-body);\n color: var(--kf-color-text-muted);\n }\n .kf-text--caption {\n font-size: var(--kf-font-size-caption);\n font-weight: var(--kf-font-weight-body);\n color: var(--kf-color-text-muted);\n }\n\n /* Tone — semántica de color, se superpone al color del variant. */\n .kf-text--ok {\n color: var(--kf-color-success-strong);\n }\n .kf-text--warn {\n color: var(--kf-color-warning-strong);\n }\n .kf-text--error {\n color: var(--kf-color-error-strong);\n }\n .kf-text--info {\n color: var(--kf-color-info-strong);\n }\n `,\n})\nexport class Text {\n /** Etiqueta semántica real que se renderiza — nunca es solo un `div`. */\n readonly as = input<TextAs>('p');\n readonly variant = input<TextVariant>('body');\n readonly tone = input<TextTone>('neutral');\n\n /**\n * Copia de `as` para uso dentro del template: `as` es palabra reservada\n * en las expresiones de Angular (`@if (x; as y)`), así que `@switch (as())`\n * no parsea — NG5002. La prop pública sigue llamándose `as` (es solo un\n * atributo HTML ahí, `<kf-text as=\"h1\">`, no una expresión).\n */\n protected readonly tag = computed(() => this.as());\n\n protected hostClass(): string {\n const classes = [`kf-text--${this.variant()}`];\n if (this.tone() !== 'neutral') {\n classes.push(`kf-text--${this.tone()}`);\n }\n return classes.join(' ');\n }\n}\n","import { Component, computed, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\nimport { Text, TextVariant } from '../text/Text';\n\n/**\n * Tamaño del título — `md` es el tamaño de siempre (no rompe a nadie que no\n * lo especifique). Cada valor mapea 1:1 a una variante `title-*` de\n * `kf-text` (ver `Text.ts`); `xl`/`xxl` son el tier \"hero\" de esa escala,\n * pensado para casos de un título más protagonista (ej. bienvenida del home).\n */\nexport type PageHeaderTitleSize = 'sm' | 'md' | 'lg' | 'xl' | 'xxl';\n\n/**\n * Bloque de título al tope de una página: chip de ícono opcional, título (h1),\n * subtítulo opcional y un área de acciones opcional proyectada vía\n * `<ng-content select=\"[actions]\">`, para no acoplar el componente a un set\n * fijo de botones.\n *\n * <kf-page-header title=\"Vehículos\" subtitle=\"Gestión de la flota activa\">\n * <button actions>Nuevo vehículo</button>\n * </kf-page-header>\n *\n * <kf-page-header icon=\"settings\" title=\"Configuración\" />\n *\n * <kf-page-header size=\"xl\" title=\"Bienvenido de nuevo\" />\n */\n@Component({\n selector: 'kf-page-header',\n imports: [Icon, Text],\n template: `\n @if (icon(); as iconName) {\n <span class=\"kf-page-header__icon\">\n <kf-icon [name]=\"iconName\" size=\"lg\" />\n </span>\n }\n\n <div class=\"kf-page-header__heading\">\n <kf-text as=\"h1\" class=\"kf-page-header__title\" [variant]=\"titleVariant()\">\n {{ title() }}\n </kf-text>\n @if (subtitle()) {\n <p class=\"kf-page-header__subtitle\">{{ subtitle() }}</p>\n }\n </div>\n\n <div class=\"kf-page-header__actions\">\n <ng-content select=\"[actions]\" />\n </div>\n `,\n styles: `\n :host {\n display: flex;\n align-items: center;\n gap: var(--kf-space-md);\n font-family: var(--kf-font-body);\n }\n .kf-page-header__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n /* El chip necesita bastante más aire que el ícono (24px \"lg\") que\n contiene — con --kf-space-xl (32px) quedaban casi pegados. */\n width: 48px;\n height: 48px;\n border-radius: var(--kf-radius-md);\n background: var(--kf-color-primary-soft);\n color: var(--kf-color-primary);\n }\n .kf-page-header__heading {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n flex: 1 1 auto;\n min-width: 0;\n }\n /* Familia, peso, tamaño y color de fuente vienen de la variante title-*\n de kf-text (ver titleVariant()) — acá solo el line-height, que kf-text\n no fija por variant. */\n .kf-page-header__title {\n line-height: 1.2;\n }\n .kf-page-header__subtitle {\n margin: 0;\n font-size: 0.9375rem;\n color: var(--kf-color-text-muted);\n }\n .kf-page-header__actions {\n flex: none;\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n }\n `,\n})\nexport class PageHeader {\n readonly icon = input<IconName | undefined>(undefined);\n readonly title = input.required<string>();\n readonly subtitle = input<string | undefined>(undefined);\n readonly size = input<PageHeaderTitleSize>('md');\n\n protected readonly titleVariant = computed<TextVariant>(() => `title-${this.size()}`);\n}\n","import { Component, computed, input, output } from '@angular/core';\n\n/** Un número de página clickeable o un separador \"…\" no interactivo. */\nexport type PaginationItem = { type: 'page'; page: number } | { type: 'ellipsis' };\n\nconst SIBLINGS = 1;\n\n/**\n * Paginador numerado con elipsis + prev/next.\n *\n * Algoritmo de elipsis estándar: siempre se muestran la primera página, la\n * última, la página actual y un par de vecinas alrededor de la actual; el\n * resto de los huecos se colapsa en un separador \"…\". Cuando el hueco entre\n * dos números visibles es de exactamente una página, se muestra ese número\n * en vez de un \"…\" (no tiene sentido colapsar un solo elemento).\n *\n * El contenido proyectado (`<ng-content>`) es para el texto informativo\n * opcional (ej. \"21–40 de 273\"), a la izquierda de los controles.\n *\n * <kf-pagination [page]=\"page\" [pages]=\"totalPages\" (pageChange)=\"page = $event\">\n * 21–40 de 273\n * </kf-pagination>\n */\n@Component({\n selector: 'kf-pagination',\n template: `\n <div class=\"kf-pagination\">\n <div class=\"kf-pagination__info\">\n <ng-content />\n </div>\n <nav class=\"kf-pagination__nav\" aria-label=\"Paginación\">\n <button\n type=\"button\"\n class=\"kf-pagination__control\"\n [disabled]=\"page() <= 1\"\n aria-label=\"Página anterior\"\n (click)=\"goTo(page() - 1)\"\n >\n ‹\n </button>\n\n @for (item of items(); track $index) {\n @if (item.type === 'page') {\n <button\n type=\"button\"\n class=\"kf-pagination__page\"\n [class.kf-pagination__page--active]=\"item.page === page()\"\n [attr.aria-current]=\"item.page === page() ? 'page' : null\"\n [attr.aria-label]=\"'Ir a la página ' + item.page\"\n (click)=\"goTo(item.page)\"\n >\n {{ item.page }}\n </button>\n } @else {\n <span class=\"kf-pagination__ellipsis\" aria-hidden=\"true\">…</span>\n }\n }\n\n <button\n type=\"button\"\n class=\"kf-pagination__control\"\n [disabled]=\"page() >= pages()\"\n aria-label=\"Página siguiente\"\n (click)=\"goTo(page() + 1)\"\n >\n ›\n </button>\n </nav>\n </div>\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-pagination {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-md);\n flex-wrap: wrap;\n }\n .kf-pagination__info {\n font-size: 0.85rem;\n color: var(--kf-color-text-muted);\n }\n .kf-pagination__info:empty {\n display: none;\n }\n .kf-pagination__nav {\n display: flex;\n align-items: center;\n gap: var(--kf-space-xs);\n }\n .kf-pagination__control,\n .kf-pagination__page {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 2rem;\n height: 2rem;\n padding: 0 var(--kf-space-xs);\n font: inherit;\n font-size: 0.85rem;\n color: var(--kf-color-text);\n background: var(--kf-color-white);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n cursor: pointer;\n transition:\n background 0.14s,\n border-color 0.14s,\n color 0.14s;\n }\n .kf-pagination__control:hover:not(:disabled),\n .kf-pagination__page:hover:not(.kf-pagination__page--active) {\n background: var(--kf-color-surface);\n border-color: var(--kf-color-border-strong);\n }\n .kf-pagination__control:focus-visible,\n .kf-pagination__page:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-pagination__control:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n .kf-pagination__page--active {\n color: var(--kf-color-white);\n background: var(--kf-color-primary);\n border-color: var(--kf-color-primary);\n cursor: default;\n }\n .kf-pagination__ellipsis {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 2rem;\n height: 2rem;\n color: var(--kf-color-text-muted);\n }\n `,\n})\nexport class Pagination {\n readonly page = input(1);\n readonly pages = input(1);\n readonly pageChange = output<number>();\n\n /** Lista de números de página y separadores a renderizar, ya resuelta por el algoritmo de elipsis. */\n readonly items = computed<PaginationItem[]>(() =>\n buildPaginationItems(this.page(), this.pages()),\n );\n\n goTo(target: number): void {\n const clamped = Math.min(Math.max(target, 1), this.pages());\n if (clamped === this.page()) {\n return;\n }\n this.pageChange.emit(clamped);\n }\n}\n\n/**\n * Construye la lista de items visibles con el algoritmo de elipsis estándar:\n * primera página, última página, actual ± `SIBLINGS`, y un \"…\" por cada hueco\n * mayor a una página entre esos bloques.\n */\nfunction buildPaginationItems(current: number, total: number): PaginationItem[] {\n const totalPages = Math.max(total, 1);\n const safeCurrent = Math.min(Math.max(current, 1), totalPages);\n\n const visible = new Set<number>([1, totalPages, safeCurrent]);\n for (let offset = 1; offset <= SIBLINGS; offset++) {\n visible.add(safeCurrent - offset);\n visible.add(safeCurrent + offset);\n }\n\n const sortedPages = [...visible].filter((p) => p >= 1 && p <= totalPages).sort((a, b) => a - b);\n\n const items: PaginationItem[] = [];\n for (let i = 0; i < sortedPages.length; i++) {\n const pageNumber = sortedPages[i];\n if (i > 0) {\n const gap = pageNumber - sortedPages[i - 1];\n if (gap === 2) {\n // Hueco de una sola página: mostrarla en vez de colapsarla en \"…\".\n items.push({ type: 'page', page: pageNumber - 1 });\n } else if (gap > 2) {\n items.push({ type: 'ellipsis' });\n }\n }\n items.push({ type: 'page', page: pageNumber });\n }\n\n return items;\n}\n","import { Component, input } from '@angular/core';\nimport { Card } from '../card/Card';\nimport { Divider } from '../divider/Divider';\nimport { Icon } from '../icon/Icon';\n\n/**\n * Tarjeta contenedora con título, enlace de acción opcional a la derecha, y\n * cuerpo con contenido libre — página 33: \"Base de la mayoría de bloques del\n * portal\". Compone sobre `kf-card` para compartir la misma superficie\n * (radio, sombra, borde) que el resto de la librería.\n *\n * <kf-panel title=\"Mis documentos por pagar\" actionLabel=\"Ir a pagos\" actionHref=\"/pagos\">\n * <kf-action-tile-row icon=\"download\" title=\"Pagos\" description=\"Revisa tu estado de cuenta y realiza pagos.\" />\n * </kf-panel>\n *\n * El host y el `kf-card` interno son flex column con `flex:1` de punta a\n * punta — si un grid/flex externo estira `kf-panel` a la altura de un\n * hermano más alto, el contenido proyectado hereda esa altura en vez de\n * dejar un hueco vacío bajo el `kf-card`. Sin esa presión externa (altura\n * \"auto\" del contenedor), `flex:1` no tiene espacio extra que repartir y el\n * panel se comporta igual que antes.\n */\n@Component({\n selector: 'kf-panel',\n imports: [Card, Divider, Icon],\n template: `\n <kf-card>\n <div class=\"kf-panel__head\">\n <span class=\"kf-panel__title\">{{ title() }}</span>\n @if (actionLabel()) {\n <a class=\"kf-panel__action\" [href]=\"actionHref() || '#'\">\n {{ actionLabel() }}\n <kf-icon name=\"chevron-right\" size=\"sm\" />\n </a>\n }\n </div>\n <kf-divider />\n <div class=\"kf-panel__body\">\n <ng-content />\n </div>\n </kf-card>\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n }\n kf-card {\n flex: 1;\n }\n .kf-panel__head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-sm);\n margin-bottom: var(--kf-space-sm);\n }\n .kf-panel__title {\n font-family: var(--kf-font-title);\n font-size: 1.05rem;\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-panel__action {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n flex: none;\n font-size: 0.8125rem;\n font-weight: 600;\n color: var(--kf-color-primary);\n text-decoration: none;\n }\n .kf-panel__action:hover {\n text-decoration: underline;\n }\n .kf-panel__body {\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: var(--kf-space-sm);\n margin-top: var(--kf-space-sm);\n }\n `,\n})\nexport class Panel {\n readonly title = input.required<string>();\n readonly actionLabel = input<string>();\n readonly actionHref = input<string>();\n}\n","import {\n Component,\n ElementRef,\n booleanAttribute,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { AdminBadge } from '../admin-badge/AdminBadge';\nimport { Avatar } from '../avatar/Avatar';\nimport { Drawer } from '../drawer/Drawer';\nimport { Icon } from '../icon/Icon';\nimport type { IconName } from '../icon/icon-name';\n\n/** Un ítem de navegación de la barra de marca. `icon` es opcional y solo se\n * usa en el drawer mobile (columna, ver template) — el `<nav>` horizontal de\n * escritorio se mantiene solo texto, sin ícono ni chevron. */\nexport interface PortalHeaderNavItem {\n label: string;\n href: string;\n active?: boolean;\n icon?: IconName;\n}\n\n/** Una acción de la franja de administrador (ej. \"Consultar deuda clientes\"). */\nexport interface PortalHeaderAdminAction {\n label: string;\n href: string;\n}\n\n/**\n * Cabecera completa del portal (página 31) — franja de administrador\n * (acento ámbar, solo admins), barra de marca con logo, navegación y\n * pastilla de sesión. Compone `kf-admin-badge` para la franja y `kf-avatar\n * pill` para la sesión, en vez de reimplementar ambos.\n *\n * Es distinto de `kf-page-header`/`kf-page-head` (título de una vista\n * interna) — este es el chrome global del portal, se monta una sola vez.\n *\n * `:host` es `position: sticky; top: 0` — el header queda pegado arriba al\n * hacer scroll. No es `fixed`: como no se superpone al contenido en el\n * primer render, no hace falta que el consumidor compense con\n * `padding-top`.\n *\n * Bajo los 768px, el `<nav>` deja de mostrarse en línea junto al logo y\n * colapsa detrás de un botón de menú (ícono `menu`/`x`) que despliega un\n * `kf-drawer` (panel lateral genérico, ver `Drawer.ts`) anclado al borde\n * IZQUIERDO — mismo lado que el botón que lo abre, convención dominante\n * Material/iOS/Android — con los mismos `navItems` en columna dentro del\n * body (fondo claro) de ese drawer.\n *\n * `PortalHeader` expone dos slots propios pensados para que el consumidor\n * proyecte contenido que en escritorio vive en otro lugar:\n * - `<ng-content select=\"[kf-portal-header-extra]\">`: identidad de sesión\n * (ej. `kf-drawer-session`). Cae en `[kf-drawer-header]` de `kf-drawer` —\n * el único contenedor con fondo oscuro (`--kf-color-tertiary-deep`, ver\n * `Drawer.ts`) que `kf-drawer-session` espera como fondo (no trae uno\n * propio, ver `DrawerSession.ts`).\n * - `<ng-content select=\"[kf-portal-header-footer]\">`: acciones separadas del\n * resto (ej. `kf-drawer-logout`). Cae en `[kf-drawer-footer]` de\n * `kf-drawer`, mismo criterio de \"no reimplementar nada del drawer\": el\n * footer ya trae su propio padding/separador (ver `Drawer.ts`).\n *\n * `PortalHeader` no sabe qué es ninguno de los dos contenidos ni cómo se\n * abren, solo les da el lugar correcto dentro del drawer ya desplegado.\n * `kf-drawer` resuelve overlay con blur, cierre con click-afuera/`Escape`,\n * atrapado de foco real y devolución de foco al cerrar — `PortalHeader` no\n * reimplementa nada de eso, solo controla su `open` desde el botón de\n * hamburguesa.\n *\n * <kf-portal-header\n * [isAdmin]=\"true\"\n * [adminActions]=\"[{ label: 'Consultar deuda clientes', href: '/deuda' }, { label: 'Cambiar DNI', href: '/dni' }]\"\n * [navItems]=\"[{ label: 'Home', href: '/', active: true, icon: 'grid' }, { label: 'Vehículos', href: '/vehiculos', icon: 'truck' }]\"\n * userInitials=\"TS\"\n * >\n * <kf-drawer-session\n * kf-portal-header-extra\n * brand=\"Portal Kaufmann LATAM\"\n * name=\"Tomás Soto\"\n * email=\"tomas.soto@kaufmann.com\"\n * />\n * <kf-drawer-logout kf-portal-header-footer (logoutClick)=\"onLogout()\" />\n * </kf-portal-header>\n */\n@Component({\n selector: 'kf-portal-header',\n imports: [AdminBadge, Avatar, Icon, Drawer],\n template: `\n @if (isAdmin()) {\n <div class=\"kf-portal-header__admin-bar\">\n <kf-admin-badge inline />\n <div class=\"kf-portal-header__admin-actions\">\n @for (action of adminActions(); track action.label) {\n <a class=\"kf-portal-header__admin-action\" [href]=\"action.href\">{{ action.label }}</a>\n }\n </div>\n </div>\n }\n <div class=\"kf-portal-header__brand-bar\">\n <span class=\"kf-portal-header__logo\">{{ brand() }}</span>\n\n <nav class=\"kf-portal-header__nav\">\n @for (item of navItems(); track item.label) {\n <a\n class=\"kf-portal-header__nav-item\"\n [class.kf-portal-header__nav-item--active]=\"item.active\"\n [href]=\"item.href\"\n >\n {{ item.label }}\n </a>\n }\n </nav>\n\n <button\n #sessionButton\n type=\"button\"\n class=\"kf-portal-header__session\"\n (click)=\"sessionClick.emit()\"\n >\n <kf-avatar [initials]=\"userInitials()\" pill />\n </button>\n\n <button\n type=\"button\"\n class=\"kf-portal-header__menu-toggle\"\n [attr.aria-expanded]=\"mobileMenuOpen()\"\n aria-label=\"Abrir menú de navegación\"\n (click)=\"mobileMenuOpen.set(!mobileMenuOpen())\"\n >\n <kf-icon [name]=\"mobileMenuOpen() ? 'x' : 'menu'\" size=\"md\" />\n </button>\n </div>\n\n <kf-drawer [(open)]=\"mobileMenuOpen\" ariaLabel=\"Menú de navegación\">\n <div kf-drawer-header>\n <ng-content select=\"[kf-portal-header-extra]\" />\n </div>\n @for (item of navItems(); track item.label) {\n <a\n class=\"kf-portal-header__mobile-nav-item\"\n [class.kf-portal-header__mobile-nav-item--active]=\"item.active\"\n [href]=\"item.href\"\n (click)=\"mobileMenuOpen.set(false)\"\n >\n @if (item.icon) {\n <kf-icon [name]=\"item.icon\" size=\"sm\" />\n }\n <span class=\"kf-portal-header__mobile-nav-item-label\">{{ item.label }}</span>\n <kf-icon name=\"chevron-right\" size=\"sm\" />\n </a>\n }\n <div kf-drawer-footer>\n <ng-content select=\"[kf-portal-header-footer]\" />\n </div>\n </kf-drawer>\n `,\n styles: `\n :host {\n display: block;\n position: sticky;\n top: 0;\n z-index: 30;\n font-family: var(--kf-font-body);\n }\n .kf-portal-header__admin-bar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-md);\n padding: var(--kf-space-xs) var(--kf-space-lg);\n background: var(--kf-color-tertiary-deep);\n }\n .kf-portal-header__admin-actions {\n display: flex;\n gap: var(--kf-space-md);\n }\n .kf-portal-header__admin-action {\n font-size: 0.8125rem;\n font-weight: 600;\n color: rgba(255, 255, 255, 0.85);\n text-decoration: none;\n }\n .kf-portal-header__admin-action:hover {\n color: var(--kf-color-white);\n }\n .kf-portal-header__brand-bar {\n display: flex;\n align-items: center;\n gap: var(--kf-space-lg);\n padding: var(--kf-space-sm) var(--kf-space-lg);\n background: var(--kf-color-tertiary-deep);\n border-top: 1px solid rgba(255, 255, 255, 0.1);\n }\n .kf-portal-header__logo {\n font-family: var(--kf-font-title);\n font-size: 1.25rem;\n font-weight: 700;\n letter-spacing: 0.02em;\n color: var(--kf-color-white);\n text-transform: uppercase;\n /* En mobile, el logo no se abrevia — se lo deja partir en varias\n líneas antes que truncarlo, pero sin dejar que un logo largo se\n coma todo el ancho: el nav/sesión de escritorio ya están ocultos\n acá abajo de 768px, así que el logo tiene toda la fila para él y\n el botón de menú. */\n flex: 1 1 auto;\n min-width: 0;\n }\n .kf-portal-header__nav {\n display: flex;\n align-items: center;\n gap: var(--kf-space-xs);\n flex: 1 1 auto;\n }\n .kf-portal-header__nav-item {\n padding: var(--kf-space-xs) var(--kf-space-md);\n border-radius: var(--kf-radius-sm);\n color: rgba(255, 255, 255, 0.75);\n font-size: 0.875rem;\n font-weight: 600;\n text-decoration: none;\n white-space: nowrap;\n transition:\n background 0.14s,\n color 0.14s;\n }\n /*\n * :not(--active) es necesario: sin él, este :hover pisa el color del\n * item activo (fondo blanco, texto --kf-color-ink) con blanco también,\n * dejando texto blanco sobre fondo blanco al pasar el mouse por encima\n * del item ya activo.\n */\n .kf-portal-header__nav-item:hover:not(.kf-portal-header__nav-item--active) {\n color: var(--kf-color-white);\n }\n .kf-portal-header__nav-item--active {\n background: var(--kf-color-white);\n color: var(--kf-color-ink);\n }\n .kf-portal-header__session {\n flex: none;\n border: none;\n background: transparent;\n padding: 0;\n cursor: pointer;\n }\n .kf-portal-header__menu-toggle {\n display: none;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border: none;\n border-radius: var(--kf-radius-sm);\n background: transparent;\n color: var(--kf-color-white);\n cursor: pointer;\n }\n .kf-portal-header__menu-toggle:hover {\n background: rgba(255, 255, 255, 0.1);\n }\n /*\n * Ítems de navegación dentro del kf-drawer: el drawer tiene fondo\n * sólido claro (--kf-color-white), a diferencia del viejo drawer\n * embebido que compartía el fondo oscuro (--kf-color-tertiary-deep) de\n * la brand-bar — de ahí que estos colores sean oscuros sobre claro y no\n * al revés, como antes.\n */\n .kf-portal-header__mobile-nav-item {\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-sm) var(--kf-space-xs);\n color: var(--kf-color-text);\n font-size: 0.9375rem;\n font-weight: 600;\n text-decoration: none;\n border-radius: var(--kf-radius-sm);\n }\n .kf-portal-header__mobile-nav-item:hover {\n background: var(--kf-color-surface);\n }\n .kf-portal-header__mobile-nav-item--active {\n color: var(--kf-color-primary-active);\n background: var(--kf-color-primary-soft);\n }\n /* Label ocupa el espacio disponible entre el ícono opcional y el chevron,\n * así el chevron queda siempre pegado al borde derecho del drawer sin\n * importar el largo de cada label. */\n .kf-portal-header__mobile-nav-item-label {\n flex: 1 1 auto;\n }\n /* El chevron es puramente decorativo (mismo color del texto vía\n * currentColor) — no repite información ya dada por el propio link. */\n .kf-portal-header__mobile-nav-item kf-icon:last-child {\n color: rgba(23, 29, 37, 0.35);\n }\n\n /*\n * Único breakpoint real de la librería hasta ahora: por debajo de\n * 768px el <nav> horizontal deja lugar al botón de menú + drawer\n * lateral. El resto de los componentes de la librería no maneja\n * responsive todavía — este es el primer caso.\n */\n @media (max-width: 768px) {\n .kf-portal-header__nav {\n display: none;\n }\n /*\n * El botón de sesión (avatar) también se oculta: en mobile la única\n * forma de llegar a sesión/logout es a través del drawer (ver el\n * slot kf-portal-header-extra), no un segundo camino en paralelo\n * vía este botón + el overlay de dropdown que el consumidor arma\n * para escritorio — ese overlay no está pensado para posicionarse\n * bien en una pantalla angosta.\n */\n .kf-portal-header__session {\n display: none;\n }\n .kf-portal-header__menu-toggle {\n display: inline-flex;\n }\n }\n `,\n})\nexport class PortalHeader {\n readonly brand = input('DIVEMOTOR');\n readonly isAdmin = input(false, { transform: booleanAttribute });\n readonly adminActions = input<PortalHeaderAdminAction[]>([]);\n readonly navItems = input<PortalHeaderNavItem[]>([]);\n readonly userInitials = input.required<string>();\n\n readonly sessionClick = output<void>();\n\n /** Visibilidad del drawer de navegación mobile (bajo los 768px). Se pasa a\n * `kf-drawer` como `[(open)]` — `PortalHeader` ya no implementa overlay,\n * `Escape` ni atrapado de foco por su cuenta, eso vive en `Drawer`. */\n protected readonly mobileMenuOpen = signal(false);\n\n /**\n * `ElementRef` real del botón de sesión (el avatar en la esquina\n * derecha), no de todo el header. Pensado para anclar un `kf-dropdown`\n * externo — sin esto, el único `ElementRef` disponible desde afuera es el\n * del host de `PortalHeader`, que ocupa el ancho completo de la pantalla\n * (logo + nav + sesión), y el overlay del CDK termina \"pegado\" a la\n * esquina del header entero en vez de al botón que el usuario clickeó.\n *\n * <kf-dropdown [(open)]=\"menuOpen\" [anchor]=\"header().sessionButtonRef()\">\n */\n readonly sessionButtonRef = viewChild.required('sessionButton', { read: ElementRef });\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\nimport { Icon } from '../icon/Icon';\n\n/**\n * Estado vacío de reservas en taller con llamada a agendar (página 36):\n * barra de estado vacío arriba (\"No tienes reservas de taller\"), panel de\n * invitación al medio (ícono en círculo azul, título, descripción, link) y\n * una fila de dos acciones al pie — un slot `[actions]` proyectado, para no\n * acoplar el componente a botones fijos.\n *\n * Distinto de `kf-empty-state` genérico: este combina la barra + la\n * invitación + las acciones como un bloque compuesto propio del dominio\n * \"taller\", no un placeholder de una sola pieza.\n *\n * `grow` estira el panel de invitación para llenar el espacio vertical\n * disponible — solo cuando el consumidor comparte fila con una tarjeta más\n * alta (ej. junto a \"Total de vehículos\"); en un lugar sin esa presión\n * (home, debajo del carousel) se deja en su alto natural.\n *\n * <kf-reserve-block emptyLabel=\"No tienes reservas de taller\" grow\n * title=\"¿Necesitas mantención?\" description=\"Tenemos la mejor red de talleres.\"\n * actionLabel=\"Agenda tu reserva aquí\" actionHref=\"/taller/agendar\">\n * <kf-button actions icon=\"calendar\">Reservar hora</kf-button>\n * <kf-button actions variant=\"outline\" icon=\"list\">Ver agenda</kf-button>\n * </kf-reserve-block>\n */\n@Component({\n selector: 'kf-reserve-block',\n imports: [Icon],\n template: `\n <div class=\"kf-reserve-block__empty\">\n <kf-icon name=\"calendar\" size=\"sm\" />\n <span>{{ emptyLabel() }}</span>\n </div>\n <div class=\"kf-reserve-block__invite\" [class.kf-reserve-block__invite--grow]=\"grow()\">\n <span class=\"kf-reserve-block__invite-icon\">\n <kf-icon name=\"tool\" size=\"md\" />\n </span>\n <div class=\"kf-reserve-block__invite-text\">\n <span class=\"kf-reserve-block__invite-title\">{{ title() }}</span>\n @if (description()) {\n <span class=\"kf-reserve-block__invite-description\">{{ description() }}</span>\n }\n @if (actionLabel()) {\n <a class=\"kf-reserve-block__invite-action\" [href]=\"actionHref() || '#'\">\n {{ actionLabel() }}\n <kf-icon name=\"chevron-right\" size=\"sm\" />\n </a>\n }\n </div>\n </div>\n <div class=\"kf-reserve-block__actions\">\n <ng-content select=\"[actions]\" />\n </div>\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n background: var(--kf-color-white);\n font-family: var(--kf-font-body);\n }\n .kf-reserve-block__empty {\n display: flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding-bottom: var(--kf-space-sm);\n border-bottom: 1px solid var(--kf-color-border);\n color: var(--kf-color-text-muted);\n font-size: 0.875rem;\n }\n .kf-reserve-block__invite {\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-sm);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-primary-soft);\n }\n .kf-reserve-block__invite--grow {\n flex: 1;\n }\n .kf-reserve-block__invite-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n width: 2.25rem;\n height: 2.25rem;\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-primary);\n color: var(--kf-color-white);\n }\n .kf-reserve-block__invite-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n }\n .kf-reserve-block__invite-title {\n font-family: var(--kf-font-title);\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-reserve-block__invite-description {\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n }\n .kf-reserve-block__invite-action {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n margin-top: var(--kf-space-xs);\n font-size: 0.8125rem;\n font-weight: 600;\n color: var(--kf-color-primary);\n text-decoration: none;\n }\n .kf-reserve-block__invite-action:hover {\n text-decoration: underline;\n }\n .kf-reserve-block__actions {\n display: flex;\n flex-wrap: wrap;\n gap: var(--kf-space-sm);\n }\n `,\n})\nexport class ReserveBlock {\n readonly emptyLabel = input('No tienes reservas de taller');\n readonly title = input.required<string>();\n readonly description = input<string>();\n readonly actionLabel = input<string>();\n readonly actionHref = input<string>();\n /** La invitación se estira para llenar la tarjeta (ej. junto a \"Total de vehículos\"). */\n readonly grow = input(false, { transform: booleanAttribute });\n}\n","import { booleanAttribute, Component, computed, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Título de sub-sección con chip de ícono, pensado para anidarse dentro de\n * cards o paneles (a diferencia de `PageHeader`, que encabeza una página\n * completa). Un área de acciones opcional se proyecta vía\n * `<ng-content select=\"[actions]\">` para no acoplar el componente a un set\n * fijo de botones.\n *\n * `size` sigue la misma escala `'sm'|'md'|'lg'` que `Button`/`Icon`/`Spinner`\n * (`md` es el default): `sm` reduce tipografía y espaciado para usarse\n * dentro de cards ya compactas, `lg` los agranda para encabezar un bloque\n * más prominente. Antes de la `0.2.0`, `size` solo aceptaba `'sm'` —\n * placeholder incompleto de esta misma escala; los valores de `lg` son una\n * extrapolación proporcional de la escala existente (sin un caso de uso\n * real todavía que los valide, a diferencia de `sm`, que sí viene de un\n * patrón real de uso dentro de cards). `solid` rellena el chip de ícono con\n * el color primario sólido en vez del tratamiento \"soft\" (fondo tenue) —\n * pensado para superficies que ya tienen un tinte de color propio, donde el\n * chip \"soft\" perdería contraste.\n *\n * <kf-section-header icon=\"settings\" title=\"Preferencias\"\n * subtitle=\"Configuración general de la cuenta\">\n * <button actions>Editar</button>\n * </kf-section-header>\n *\n * <kf-section-header title=\"Detalle\" size=\"sm\" [solid]=\"true\" />\n * <kf-section-header title=\"Resumen de flota\" size=\"lg\" />\n */\n@Component({\n selector: 'kf-section-header',\n imports: [Icon],\n template: `\n @if (icon(); as iconName) {\n <span class=\"kf-section-header__icon\" [class.kf-section-header__icon--solid]=\"solid()\">\n <kf-icon [name]=\"iconName\" [size]=\"iconSize()\" />\n </span>\n }\n\n <span class=\"kf-section-header__text\">\n <span class=\"kf-section-header__title\">{{ title() }}</span>\n @if (subtitle()) {\n <span class=\"kf-section-header__subtitle\">{{ subtitle() }}</span>\n }\n </span>\n\n <span class=\"kf-section-header__actions\">\n <ng-content select=\"[actions]\" />\n </span>\n `,\n styles: `\n :host {\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n font-family: var(--kf-font-body);\n }\n :host(.kf-section-header--sm) {\n gap: var(--kf-space-xs);\n }\n :host(.kf-section-header--lg) {\n gap: var(--kf-space-md);\n }\n .kf-section-header__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n inline-size: 2.5rem;\n block-size: 2.5rem;\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-primary-soft);\n color: var(--kf-color-primary);\n }\n :host(.kf-section-header--sm) .kf-section-header__icon {\n inline-size: 1.75rem;\n block-size: 1.75rem;\n border-radius: var(--kf-radius-xs);\n }\n :host(.kf-section-header--lg) .kf-section-header__icon {\n inline-size: 3.25rem;\n block-size: 3.25rem;\n border-radius: var(--kf-radius-md);\n }\n .kf-section-header__icon--solid {\n background: var(--kf-color-primary);\n color: var(--kf-color-white);\n }\n .kf-section-header__text {\n display: flex;\n flex-direction: column;\n min-width: 0;\n flex: 1 1 auto;\n }\n .kf-section-header__title {\n font-family: var(--kf-font-title);\n font-size: 1rem;\n font-weight: 700;\n color: var(--kf-color-ink);\n line-height: 1.3;\n }\n :host(.kf-section-header--sm) .kf-section-header__title {\n font-size: 0.875rem;\n }\n :host(.kf-section-header--lg) .kf-section-header__title {\n font-size: 1.25rem;\n }\n .kf-section-header__subtitle {\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n line-height: 1.3;\n }\n :host(.kf-section-header--sm) .kf-section-header__subtitle {\n font-size: 0.75rem;\n }\n :host(.kf-section-header--lg) .kf-section-header__subtitle {\n font-size: 0.9375rem;\n }\n .kf-section-header__actions {\n flex: none;\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n }\n `,\n host: {\n '[class.kf-section-header--sm]': \"size() === 'sm'\",\n '[class.kf-section-header--lg]': \"size() === 'lg'\",\n },\n})\nexport class SectionHeader {\n readonly icon = input<IconName>();\n readonly title = input.required<string>();\n readonly subtitle = input<string>();\n readonly size = input<'sm' | 'md' | 'lg'>('md');\n readonly solid = input(false, { transform: booleanAttribute });\n\n protected readonly iconSize = computed(() => {\n if (this.size() === 'sm') {\n return 'sm';\n }\n if (this.size() === 'lg') {\n return 'lg';\n }\n return 'md';\n });\n}\n","import { Component, computed, input, output } from '@angular/core';\n\nexport interface SegmentedOption {\n value: string;\n label: string;\n}\n\n/**\n * Control de segmentos relleno, tipo \"iOS segmented control\": 2-3 opciones\n * con un thumb que se desliza detrás de la opción activa.\n *\n * La posición del thumb se resuelve con una variable CSS (--kf-segmented-index)\n * y `transform: translateX()`, así la transición queda a cargo de CSS puro\n * (mismo criterio que Tabs), sin medir el DOM desde TypeScript.\n *\n * <kf-segmented [options]=\"options\" [value]=\"value\" (valueChange)=\"onChange($event)\" />\n */\n@Component({\n selector: 'kf-segmented',\n template: `\n <div class=\"kf-segmented__track\" [style.--kf-segmented-count]=\"options().length\">\n <div\n class=\"kf-segmented__thumb\"\n [style.--kf-segmented-index]=\"selectedIndex()\"\n [style.visibility]=\"selectedIndex() === -1 ? 'hidden' : 'visible'\"\n ></div>\n @for (option of options(); track option.value) {\n <button\n type=\"button\"\n class=\"kf-segmented__option\"\n [class.kf-segmented__option--active]=\"option.value === value()\"\n [attr.aria-pressed]=\"option.value === value()\"\n (click)=\"select(option.value)\"\n >\n {{ option.label }}\n </button>\n }\n </div>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-segmented__track {\n position: relative;\n display: grid;\n grid-template-columns: repeat(var(--kf-segmented-count), 1fr);\n gap: 2px;\n padding: 2px;\n background: var(--kf-color-surface);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n }\n .kf-segmented__thumb {\n position: absolute;\n top: 2px;\n left: 2px;\n width: calc((100% - 4px) / var(--kf-segmented-count));\n height: calc(100% - 4px);\n background: var(--kf-color-white);\n border-radius: var(--kf-radius-sm);\n box-shadow: var(--kf-shadow-xs);\n transform: translateX(calc(var(--kf-segmented-index, 0) * 100%));\n transition: transform 0.2s ease;\n }\n .kf-segmented__option {\n position: relative;\n z-index: 1;\n font: inherit;\n padding: var(--kf-space-xs) var(--kf-space-md);\n border: none;\n background: transparent;\n color: var(--kf-color-text-muted);\n border-radius: var(--kf-radius-sm);\n cursor: pointer;\n transition: color 0.14s;\n }\n .kf-segmented__option:hover:not(.kf-segmented__option--active) {\n color: var(--kf-color-text);\n }\n .kf-segmented__option--active {\n color: var(--kf-color-ink);\n }\n .kf-segmented__option:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n `,\n})\nexport class Segmented {\n readonly options = input.required<SegmentedOption[]>();\n readonly value = input.required<string>();\n readonly valueChange = output<string>();\n\n /** Índice de la opción activa; -1 si `value` no matchea ninguna opción. */\n readonly selectedIndex = computed(() =>\n this.options().findIndex((option) => option.value === this.value()),\n );\n\n select(nextValue: string): void {\n if (nextValue === this.value()) {\n return;\n }\n this.valueChange.emit(nextValue);\n }\n}\n","import { Overlay, type ConnectedPosition, type OverlayRef } from '@angular/cdk/overlay';\nimport { ComponentPortal } from '@angular/cdk/portal';\nimport {\n Component,\n Directive,\n ElementRef,\n HostListener,\n Injector,\n Input,\n Type,\n ViewContainerRef,\n inject,\n} from '@angular/core';\n\nexport type TooltipPosition = 'top' | 'bottom' | 'left' | 'right';\n\n/**\n * Contenido visual del tooltip — componente interno, no exportado en\n * `public-api.ts`. `TooltipDirective` es la única forma pública de usarlo.\n */\n@Component({\n selector: 'kf-tooltip-content',\n template: `{{ text }}`,\n styles: `\n :host {\n display: block;\n max-width: 220px;\n padding: 4px var(--kf-space-sm);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-tertiary-deep);\n color: var(--kf-color-white);\n font-family: var(--kf-font-body);\n font-size: 0.75rem;\n font-weight: 600;\n line-height: 1.4;\n white-space: nowrap;\n box-shadow: var(--kf-shadow-lg);\n animation: kf-tooltip-enter 0.1s ease-out;\n pointer-events: none;\n }\n @media (prefers-reduced-motion: reduce) {\n :host {\n animation: none;\n }\n }\n @keyframes kf-tooltip-enter {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n }\n `,\n})\nclass TooltipContent {\n text = '';\n}\n\n/**\n * Tooltip de hover/focus — reemplaza el atributo `title` nativo del\n * navegador (lento en aparecer, sin estilo, inconsistente entre\n * navegadores/SO) por un panel propio, mismo mecanismo de\n * `@angular/cdk/overlay` que ya usa `Dropdown`.\n *\n * Pensado para el caso \"ícono sin label visible necesita comunicar qué\n * es\" (ej. `kf-sidebar-nav-item` colapsado). No es two-way: a diferencia\n * de `Dropdown`, esto se abre/cierra solo con hover/focus, nunca por click.\n *\n * <a [kfTooltip]=\"label()\" kfTooltipPosition=\"right\">…</a>\n */\n@Directive({\n selector: '[kfTooltip]',\n})\nexport class TooltipDirective {\n @Input('kfTooltip') text = '';\n @Input() kfTooltipPosition: TooltipPosition = 'right';\n\n private readonly host = inject(ElementRef<HTMLElement>);\n private readonly overlayService = inject(Overlay);\n private readonly viewContainerRef = inject(ViewContainerRef);\n private readonly injector = inject(Injector);\n\n private overlayRef: OverlayRef | null = null;\n\n @HostListener('mouseenter')\n @HostListener('focus')\n protected show(): void {\n if (!this.text || this.overlayRef?.hasAttached()) {\n return;\n }\n\n const positionStrategy = this.overlayService\n .position()\n .flexibleConnectedTo(this.host)\n .withPositions(this.positionsFor(this.kfTooltipPosition))\n .withViewportMargin(8)\n .withPush(true);\n\n const overlayRef = this.overlayService.create({\n positionStrategy,\n scrollStrategy: this.overlayService.scrollStrategies.reposition(),\n });\n\n const portal = new ComponentPortal(\n TooltipContent as Type<TooltipContent>,\n this.viewContainerRef,\n this.injector,\n );\n const componentRef = overlayRef.attach(portal);\n componentRef.instance.text = this.text;\n\n this.overlayRef = overlayRef;\n }\n\n @HostListener('mouseleave')\n @HostListener('blur')\n @HostListener('document:keydown.escape')\n protected hide(): void {\n this.overlayRef?.dispose();\n this.overlayRef = null;\n }\n\n private positionsFor(placement: TooltipPosition): ConnectedPosition[] {\n const gap = 12;\n switch (placement) {\n case 'right':\n return [\n {\n originX: 'end',\n originY: 'center',\n overlayX: 'start',\n overlayY: 'center',\n offsetX: gap,\n },\n ];\n case 'left':\n return [\n {\n originX: 'start',\n originY: 'center',\n overlayX: 'end',\n overlayY: 'center',\n offsetX: -gap,\n },\n ];\n case 'top':\n return [\n {\n originX: 'center',\n originY: 'top',\n overlayX: 'center',\n overlayY: 'bottom',\n offsetY: -gap,\n },\n ];\n case 'bottom':\n default:\n return [\n {\n originX: 'center',\n originY: 'bottom',\n overlayX: 'center',\n overlayY: 'top',\n offsetY: gap,\n },\n ];\n }\n }\n}\n","import { Component, booleanAttribute, input } from '@angular/core';\nimport { Icon } from '../icon/Icon';\nimport type { IconName } from '../icon/icon-name';\nimport { TooltipDirective } from '../tooltip/Tooltip';\n\n/** Tipo que consume `kf-sidebar-shell.navItems`. `icon` es requerido: en el\n * sidebar persistente el ícono es parte permanente del diseño. */\nexport interface SidebarNavItemData {\n icon: IconName;\n label: string;\n href: string;\n active?: boolean;\n}\n\n/**\n * Ítem de navegación de `kf-sidebar-shell` — ícono + label en fila, estado\n * activo, sin agrupación. Es el equivalente vertical/persistente del `<a>`\n * que arma `kf-portal-header` para su `<nav>` horizontal.\n *\n * `collapsed` se recibe como input explícito (no vía `:host-context`): el\n * componente no necesita saber cómo funciona el estado de colapso del\n * shell, solo qué hacer cuando `collapsed` es `true`.\n *\n * No sabe nada de routing — emite `href` como cualquier link y deja que el\n * consumidor intercepte el click para integrarlo con el Router.\n */\n@Component({\n selector: 'kf-sidebar-nav-item',\n imports: [Icon, TooltipDirective],\n template: `\n <a\n class=\"kf-sidebar-nav-item\"\n [class.kf-sidebar-nav-item--active]=\"active()\"\n [class.kf-sidebar-nav-item--collapsed]=\"collapsed()\"\n [href]=\"href()\"\n [attr.aria-current]=\"active() ? 'page' : null\"\n [kfTooltip]=\"collapsed() ? label() : ''\"\n >\n <kf-icon [name]=\"icon()\" size=\"md\" />\n @if (!collapsed()) {\n <span class=\"kf-sidebar-nav-item__label\">{{ label() }}</span>\n }\n </a>\n `,\n styles: `\n .kf-sidebar-nav-item {\n box-sizing: border-box;\n position: relative;\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n padding: var(--kf-space-sm) var(--kf-space-md);\n border-radius: var(--kf-radius-sm);\n color: rgba(255, 255, 255, 0.7);\n font-family: var(--kf-font-body);\n font-size: 0.875rem;\n font-weight: 600;\n text-decoration: none;\n white-space: nowrap;\n transition:\n background 0.14s,\n color 0.14s;\n }\n .kf-sidebar-nav-item:hover:not(.kf-sidebar-nav-item--active) {\n background: rgba(255, 255, 255, 0.06);\n color: var(--kf-color-white);\n }\n .kf-sidebar-nav-item--collapsed:hover:not(.kf-sidebar-nav-item--active) {\n background: rgba(255, 255, 255, 0.12);\n }\n .kf-sidebar-nav-item--active {\n background: rgba(255, 255, 255, 0.12);\n color: var(--kf-color-white);\n }\n /* Barra lateral de selección — refuerza el contraste de fondo con una\n franja de acento sólido, detectable sin depender de leer el label. */\n .kf-sidebar-nav-item--active::before {\n content: '';\n position: absolute;\n left: calc(-1 * var(--kf-space-xs));\n top: 20%;\n bottom: 20%;\n width: 3px;\n border-radius: var(--kf-radius-pill);\n background: var(--kf-color-primary-hover);\n }\n /* Ancho y alto fijos a 40px para que el fondo de hover/activo lea como\n un cuadrado 1:1, sin depender del padding implícito del contenido. */\n .kf-sidebar-nav-item--collapsed {\n justify-content: center;\n width: 40px;\n height: 40px;\n padding-inline: 0;\n }\n .kf-sidebar-nav-item--collapsed.kf-sidebar-nav-item--active::before {\n left: calc(-1 * var(--kf-space-sm));\n }\n `,\n})\nexport class SidebarNavItem {\n readonly icon = input.required<IconName>();\n readonly label = input.required<string>();\n readonly href = input.required<string>();\n readonly active = input(false, { transform: booleanAttribute });\n\n /** Oculta el label y centra el ícono — lo controla `kf-sidebar-shell` según su propio estado de colapso. */\n readonly collapsed = input(false, { transform: booleanAttribute });\n}\n","import { DestroyRef, Signal, inject, signal } from '@angular/core';\n\n/**\n * Signal reactivo con el estado actual de un media query — para cuando un\n * componente necesita SABER en qué lado de un breakpoint está (no solo\n * mostrar/ocultar con CSS). Un `@media` en `styles` no alcanza cuando la\n * decisión no es puramente visual: por ejemplo, un componente hijo que\n * recibe un input booleano (`[collapsed]`) no puede \"leer\" un breakpoint\n * CSS del padre — necesita que alguien en TypeScript se lo diga.\n *\n * Encontrado al construir `SidebarShell`: el estado `collapsed` (colapso\n * del rail en desktop) se pasaba tal cual a cada `kf-sidebar-nav-item`, sin\n * importar el viewport. En mobile, donde el rail deslizado siempre muestra\n * etiquetas completas (ver estilos de `SidebarShell`), los ítems seguían\n * ocultando su label si el usuario había dejado el rail colapsado en\n * desktop antes de achicar la ventana — un CSS que dice \"en mobile se ve\n * ancho\" no cambia el valor del input que ya llegó al hijo.\n *\n * Debe llamarse dentro de un contexto de inyección (el `constructor` de un\n * componente, o un campo de clase inicializado ahí — mismo requisito que\n * cualquier función que use `inject()`).\n *\n * protected readonly isMobile = matchMediaSignal('(max-width: 900px)');\n * // ...\n * [collapsed]=\"collapsed() && !isMobile()\"\n */\nexport function matchMediaSignal(query: string): Signal<boolean> {\n const mediaQueryList = matchMedia(query);\n const state = signal(mediaQueryList.matches);\n\n const onChange = (event: MediaQueryListEvent) => state.set(event.matches);\n mediaQueryList.addEventListener('change', onChange);\n\n inject(DestroyRef).onDestroy(() => mediaQueryList.removeEventListener('change', onChange));\n\n return state.asReadonly();\n}\n","import { Component, HostListener, computed, input, model, output } from '@angular/core';\nimport { Icon } from '../icon/Icon';\nimport { matchMediaSignal } from '../shared/media-query';\nimport { SidebarNavItem } from '../sidebar-nav-item/SidebarNavItem';\nimport type { SidebarNavItemData } from '../sidebar-nav-item/SidebarNavItem';\nimport { TooltipDirective } from '../tooltip/Tooltip';\n\n/** Mismo breakpoint que el `@media` de este componente — ver estilos. */\nconst MOBILE_BREAKPOINT_QUERY = '(max-width: 900px)';\n\n/**\n * Shell de layout con navegación lateral persistente — el complemento\n * vertical de `kf-portal-header` (navbar horizontal). Pensado para\n * portales tipo \"aplicación interna\" (Portal OTD, Servicio Star).\n *\n * `navItems` se recibe como array de datos (no como contenido proyectado):\n * el componente no sabe nada de routing, emite `navItemClick` con el ítem\n * clickeado y deja que el consumidor decida cómo navegar.\n *\n * Slots: `[kf-sidebar-brand]` (logo del rail expandido, visible en desktop\n * y en el panel mobile — es el MISMO rail), `[kf-sidebar-brand-collapsed]`\n * (reemplazo opcional cuando el rail está colapsado en desktop),\n * `[kf-sidebar-brand-mobile]` (logo de la topbar angosta de mobile, fondo\n * claro) y `[kf-sidebar-footer]` (tarjeta de usuario / acciones al pie).\n *\n * Botón de colapso: vive como último ítem de la propia lista de\n * navegación, no flotando en el borde del rail — mismo criterio de\n * tap-target grande y predecible que el resto de los ítems.\n *\n * Responsive: bajo los 900px el sidebar NO se reemplaza por un panel\n * distinto — es el MISMO rail el que pasa a `position: fixed` fuera de la\n * pantalla (`translateX(-100%)`) y se desliza a la vista (`translateX(0)`)\n * sobre un backdrop cuando `mobileOpen` es `true`. Una topbar angosta con\n * botón de hamburguesa reemplaza al rail en el flujo del documento\n * mientras el panel está cerrado.\n *\n * A propósito NO reutiliza `kf-drawer` (el panel lateral genérico de la\n * librería): `kf-drawer` tiene su propio fondo claro fijo y duplicaría el\n * árbol de navegación en un segundo lugar del DOM. Bug de contraste ya\n * corregido en el historial: los `kf-sidebar-nav-item`, con texto claro\n * pensado para el gradiente oscuro, quedaban invisibles sobre el fondo\n * blanco de `kf-drawer`. Acá hay un solo rail, un solo árbol de nav, que\n * cambia de posición según el viewport.\n */\n@Component({\n selector: 'kf-sidebar-shell',\n imports: [Icon, SidebarNavItem, TooltipDirective],\n template: `\n @if (mobileOpen()) {\n <button\n type=\"button\"\n class=\"kf-sidebar-shell__backdrop\"\n aria-label=\"Cerrar menú\"\n (click)=\"mobileOpen.set(false)\"\n ></button>\n }\n\n <aside\n class=\"kf-sidebar-shell__rail\"\n [class.kf-sidebar-shell__rail--collapsed]=\"collapsed()\"\n [class.kf-sidebar-shell__rail--mobile-open]=\"mobileOpen()\"\n >\n <div class=\"kf-sidebar-shell__brand\">\n <div class=\"kf-sidebar-shell__brand-full\">\n <ng-content select=\"[kf-sidebar-brand]\" />\n </div>\n <div class=\"kf-sidebar-shell__brand-collapsed\">\n <ng-content select=\"[kf-sidebar-brand-collapsed]\" />\n </div>\n\n <button\n type=\"button\"\n class=\"kf-sidebar-shell__mobile-close\"\n aria-label=\"Cerrar menú\"\n (click)=\"mobileOpen.set(false)\"\n >\n <kf-icon name=\"x\" size=\"md\" />\n </button>\n </div>\n\n <nav class=\"kf-sidebar-shell__nav\">\n @for (item of navItems(); track item.href) {\n <kf-sidebar-nav-item\n [icon]=\"item.icon\"\n [label]=\"item.label\"\n [href]=\"item.href\"\n [active]=\"!!item.active\"\n [collapsed]=\"itemsCollapsed()\"\n (click)=\"onNavItemClick($event, item)\"\n />\n }\n </nav>\n\n <div class=\"kf-sidebar-shell__bottom\">\n <button\n type=\"button\"\n class=\"kf-sidebar-shell__collapse-toggle\"\n [class.kf-sidebar-shell__collapse-toggle--collapsed]=\"itemsCollapsed()\"\n [attr.aria-expanded]=\"!collapsed()\"\n [attr.aria-label]=\"collapsed() ? 'Expandir menú' : 'Colapsar menú'\"\n [kfTooltip]=\"itemsCollapsed() ? (collapsed() ? 'Expandir menú' : 'Colapsar menú') : ''\"\n (click)=\"collapsed.set(!collapsed())\"\n >\n <kf-icon [name]=\"collapsed() ? 'chevron-right' : 'chevron-left'\" size=\"sm\" />\n @if (!itemsCollapsed()) {\n <span class=\"kf-sidebar-shell__collapse-toggle-label\">\n {{ collapsed() ? 'Expandir menú' : 'Colapsar menú' }}\n </span>\n }\n </button>\n\n <div class=\"kf-sidebar-shell__footer\">\n <ng-content select=\"[kf-sidebar-footer]\" />\n </div>\n </div>\n </aside>\n\n <div class=\"kf-sidebar-shell__topbar\">\n <button\n type=\"button\"\n class=\"kf-sidebar-shell__menu-toggle\"\n aria-label=\"Abrir menú de navegación\"\n (click)=\"mobileOpen.set(true)\"\n >\n <kf-icon name=\"menu\" size=\"md\" />\n </button>\n <div class=\"kf-sidebar-shell__topbar-brand\">\n <ng-content select=\"[kf-sidebar-brand-mobile]\" />\n </div>\n </div>\n `,\n styles: `\n :host {\n display: contents;\n }\n\n .kf-sidebar-shell__backdrop {\n display: none;\n }\n\n .kf-sidebar-shell__rail {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n position: relative;\n width: 268px;\n flex: none;\n padding: var(--kf-space-lg) var(--kf-space-md);\n background: linear-gradient(\n 190deg,\n var(--kf-color-sidebar-gradient-from) 0%,\n var(--kf-color-sidebar-gradient-to) 60%\n );\n transition:\n width 0.18s ease,\n padding-inline 0.18s ease;\n }\n /* 56px = padding-inline del rail (8px) por lado + el cuadrado de 40px\n de cada ítem de navegación colapsado. */\n .kf-sidebar-shell__rail--collapsed {\n width: 56px;\n padding-inline: var(--kf-space-sm);\n }\n\n .kf-sidebar-shell__brand {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: var(--kf-space-xl);\n }\n .kf-sidebar-shell__brand-full {\n display: flex;\n justify-content: center;\n width: 100%;\n }\n .kf-sidebar-shell__brand-full ::ng-deep img {\n display: block;\n height: 1.5rem;\n }\n .kf-sidebar-shell__brand-collapsed {\n display: none;\n }\n .kf-sidebar-shell__brand-collapsed ::ng-deep img {\n display: block;\n height: 1.75rem;\n }\n .kf-sidebar-shell__rail--collapsed .kf-sidebar-shell__brand-full {\n display: none;\n }\n .kf-sidebar-shell__rail--collapsed .kf-sidebar-shell__brand-collapsed {\n display: block;\n }\n\n .kf-sidebar-shell__mobile-close {\n display: none;\n margin-left: auto;\n align-items: center;\n justify-content: center;\n width: 2rem;\n height: 2rem;\n border: none;\n border-radius: var(--kf-radius-sm);\n background: rgba(255, 255, 255, 0.08);\n color: rgba(255, 255, 255, 0.8);\n cursor: pointer;\n }\n .kf-sidebar-shell__mobile-close:hover {\n background: rgba(255, 255, 255, 0.16);\n color: var(--kf-color-white);\n }\n\n .kf-sidebar-shell__nav {\n flex: 1 1 auto;\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n overflow-y: auto;\n }\n\n /* Agrupa toggle de colapso + footer (card de sesión) al pie del rail,\n en ese orden: navegación primero, identidad de usuario al final. */\n .kf-sidebar-shell__bottom {\n display: flex;\n flex-direction: column;\n margin-top: var(--kf-space-sm);\n padding-top: var(--kf-space-sm);\n border-top: 1px solid rgba(255, 255, 255, 0.12);\n }\n\n .kf-sidebar-shell__footer {\n margin-top: var(--kf-space-sm);\n }\n .kf-sidebar-shell__footer:empty {\n display: none;\n }\n\n /* Mismo ancho/alto que un ítem de navegación (ver comentario de la\n clase sobre por qué no flota en el borde del rail). */\n .kf-sidebar-shell__collapse-toggle {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n width: 100%;\n padding: var(--kf-space-sm) var(--kf-space-md);\n border: none;\n border-radius: var(--kf-radius-sm);\n background: rgba(255, 255, 255, 0.06);\n color: rgba(255, 255, 255, 0.7);\n font-family: var(--kf-font-body);\n font-size: 0.8125rem;\n font-weight: 600;\n cursor: pointer;\n transition:\n background 0.14s,\n color 0.14s;\n }\n .kf-sidebar-shell__collapse-toggle:hover {\n background: rgba(255, 255, 255, 0.12);\n color: var(--kf-color-white);\n }\n /* Mismo cuadrado 40×40 que cada ítem de navegación colapsado. */\n .kf-sidebar-shell__collapse-toggle--collapsed {\n justify-content: center;\n width: 40px;\n height: 40px;\n padding-inline: 0;\n }\n .kf-sidebar-shell__collapse-toggle-label {\n flex: 1 1 auto;\n text-align: left;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n /* Oculto en desktop — solo existe para dar lugar al botón de menú +\n logo cuando el rail sale del flujo del documento en mobile. */\n .kf-sidebar-shell__topbar {\n display: none;\n }\n\n @media (max-width: 900px) {\n .kf-sidebar-shell__rail {\n position: fixed;\n inset: 0 auto 0 0;\n z-index: 100;\n width: 284px;\n max-width: 86vw;\n transform: translateX(-100%);\n transition: transform 0.26s cubic-bezier(0.4, 0, 0.2, 1);\n box-shadow: var(--kf-shadow-lg);\n }\n .kf-sidebar-shell__rail--mobile-open {\n transform: translateX(0);\n }\n /* En el panel deslizado se ven siempre las etiquetas completas,\n ignorando el \"collapsed\" de escritorio. El botón de colapso no\n tiene sentido acá: en mobile se cierra con backdrop, Escape o X. */\n .kf-sidebar-shell__rail--collapsed {\n width: 284px;\n max-width: 86vw;\n }\n .kf-sidebar-shell__rail--collapsed .kf-sidebar-shell__brand-full {\n display: block;\n }\n .kf-sidebar-shell__rail--collapsed .kf-sidebar-shell__brand-collapsed {\n display: none;\n }\n .kf-sidebar-shell__collapse-toggle {\n display: none;\n }\n .kf-sidebar-shell__mobile-close {\n display: flex;\n }\n\n .kf-sidebar-shell__backdrop {\n display: block;\n position: fixed;\n inset: 0;\n z-index: 90;\n border: none;\n padding: 0;\n cursor: pointer;\n background: rgba(10, 14, 20, 0.5);\n }\n\n .kf-sidebar-shell__topbar {\n display: flex;\n align-items: center;\n gap: var(--kf-space-md);\n padding: var(--kf-space-sm) var(--kf-space-lg);\n background: var(--kf-color-white);\n border-bottom: 1px solid var(--kf-color-border);\n }\n\n .kf-sidebar-shell__menu-toggle {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border: none;\n border-radius: var(--kf-radius-sm);\n background: transparent;\n color: var(--kf-color-ink);\n cursor: pointer;\n flex: none;\n }\n .kf-sidebar-shell__menu-toggle:hover {\n background: var(--kf-color-surface);\n }\n\n .kf-sidebar-shell__topbar-brand ::ng-deep img {\n display: block;\n height: 1.25rem;\n }\n }\n `,\n})\nexport class SidebarShell {\n /** Ítems del menú del rail. */\n readonly navItems = input<SidebarNavItemData[]>([]);\n\n /** Estado de colapso del rail en desktop, two-way. Sin efecto bajo los 900px (ver estilos). */\n readonly collapsed = model(false);\n\n /** Visibilidad del rail deslizado como panel en mobile, two-way. */\n readonly mobileOpen = model(false);\n\n /** Se emite al clickear un ítem — el consumidor decide cómo navegar (ej. `router.navigateByUrl`). */\n readonly navItemClick = output<SidebarNavItemData>();\n\n /** `true` bajo los 900px — sin esto, un rail dejado colapsado en desktop\n * seguía ocultando el label de cada ítem al abrir el panel en mobile. */\n private readonly isMobileViewport = matchMediaSignal(MOBILE_BREAKPOINT_QUERY);\n\n /** Estado de colapso que efectivamente se le pasa a cada `kf-sidebar-nav-item`\n * y al propio botón de colapso. */\n protected readonly itemsCollapsed = computed(() => this.collapsed() && !this.isMobileViewport());\n\n /** Cierra el panel mobile con Escape — mismo criterio que `Dropdown`/`Modal`/`Drawer`. */\n @HostListener('document:keydown.escape')\n protected onEscape(): void {\n this.mobileOpen.set(false);\n }\n\n protected onNavItemClick(event: Event, item: SidebarNavItemData): void {\n event.preventDefault();\n this.mobileOpen.set(false);\n this.navItemClick.emit(item);\n }\n}\n","import { Component, booleanAttribute, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Indicador numérico compacto (página 34): label + valor grande, con un\n * ícono a la derecha del label — más chico y sin badge de esquina que\n * `kf-metric-card`, pensado para grillas densas de KPIs simples (\"Total\n * vehículos: 4\", \"En taller: 1\"), no para dashboards con tendencia.\n *\n * Con `cta` en vez de `value`, se convierte en la variante de llamada a la\n * acción: un bloque de fondo suave con título, descripción y un link — sin\n * número, para promover el siguiente paso (ej. \"¿Necesitas mantención?\").\n *\n * <kf-stat-tile label=\"Total vehículos\" value=\"4\" icon=\"car\" />\n * <kf-stat-tile cta title=\"¿Necesitas mantención?\"\n * description=\"Tenemos la mejor red de talleres.\"\n * actionLabel=\"Agenda aquí\" actionHref=\"/taller/agendar\" />\n */\n@Component({\n selector: 'kf-stat-tile',\n imports: [Icon],\n template: `\n @if (cta()) {\n <span class=\"kf-stat-tile__cta-title\">{{ title() }}</span>\n @if (description()) {\n <span class=\"kf-stat-tile__cta-description\">{{ description() }}</span>\n }\n @if (actionLabel()) {\n <a class=\"kf-stat-tile__cta-action\" [href]=\"actionHref() || '#'\">\n {{ actionLabel() }}\n <kf-icon name=\"chevron-right\" size=\"sm\" />\n </a>\n }\n } @else {\n <div class=\"kf-stat-tile__head\">\n <span class=\"kf-stat-tile__label\">{{ label() }}</span>\n @if (icon(); as iconName) {\n <span class=\"kf-stat-tile__icon\">\n <kf-icon [name]=\"iconName\" size=\"sm\" />\n </span>\n }\n </div>\n <span class=\"kf-stat-tile__value\">{{ value() }}</span>\n }\n `,\n styles: `\n :host {\n display: flex;\n flex-direction: column;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n background: var(--kf-color-white);\n }\n :host(.kf-stat-tile--cta) {\n background: var(--kf-color-surface);\n gap: 2px;\n }\n .kf-stat-tile__head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--kf-space-xs);\n }\n .kf-stat-tile__label {\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n }\n .kf-stat-tile__icon {\n display: inline-flex;\n color: var(--kf-color-primary);\n }\n .kf-stat-tile__value {\n font-family: var(--kf-font-title);\n font-size: 1.5rem;\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-stat-tile__cta-title {\n font-family: var(--kf-font-title);\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-stat-tile__cta-description {\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n }\n .kf-stat-tile__cta-action {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n margin-top: var(--kf-space-xs);\n font-size: 0.8125rem;\n font-weight: 600;\n color: var(--kf-color-primary);\n text-decoration: none;\n }\n .kf-stat-tile__cta-action:hover {\n text-decoration: underline;\n }\n `,\n host: {\n '[class.kf-stat-tile--cta]': 'cta()',\n },\n})\nexport class StatTile {\n readonly cta = input(false, { transform: booleanAttribute });\n // Variante numérica\n readonly label = input<string>();\n readonly value = input<string | number>();\n readonly icon = input<IconName>();\n // Variante CTA\n readonly title = input<string>();\n readonly description = input<string>();\n readonly actionLabel = input<string>();\n readonly actionHref = input<string>();\n}\n","import { booleanAttribute, Component, input } from '@angular/core';\n\n/**\n * Pill con borde, en mayúsculas y con letter-spacing, pensada para indicadores\n * de estado únicos y prominentes (ej. \"ESTADO TÉCNICO\"). El fondo es siempre\n * transparente; el color de borde/texto/punto depende de `tone`.\n *\n * <kf-status-pill tone=\"ok\">Operativo</kf-status-pill>\n * <kf-status-pill tone=\"error\" dot>Fuera de servicio</kf-status-pill>\n */\n@Component({\n selector: 'kf-status-pill',\n template: `\n <span class=\"kf-status-pill\" [class]=\"'kf-status-pill--' + tone()\">\n @if (dot()) {\n <span class=\"kf-status-pill__dot\"></span>\n }\n <ng-content />\n </span>\n `,\n styles: `\n :host {\n display: inline-block;\n }\n .kf-status-pill {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border: 1px solid currentColor;\n border-radius: var(--kf-radius-pill);\n background: transparent;\n font: inherit;\n font-size: 0.75rem;\n font-weight: 600;\n line-height: 1;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n white-space: nowrap;\n }\n .kf-status-pill__dot {\n width: 6px;\n height: 6px;\n border-radius: var(--kf-radius-pill);\n background: currentColor;\n flex-shrink: 0;\n }\n .kf-status-pill--blue {\n color: var(--kf-color-info);\n }\n .kf-status-pill--ok {\n color: var(--kf-color-success);\n }\n .kf-status-pill--warn {\n color: var(--kf-color-warning);\n }\n .kf-status-pill--error {\n color: var(--kf-color-error);\n }\n `,\n})\nexport class StatusPill {\n readonly tone = input<'blue' | 'ok' | 'warn' | 'error'>('blue');\n readonly dot = input(false, { transform: booleanAttribute });\n}\n","import {\n Component,\n DestroyRef,\n ElementRef,\n afterNextRender,\n afterRenderEffect,\n computed,\n inject,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\nexport interface TabOption {\n value: string;\n label: string;\n icon?: IconName;\n}\n\n/**\n * Barra de tabs subrayada: un único indicador se desliza horizontalmente hasta\n * la pestaña activa. Como las pestañas tienen ancho de contenido (labels de\n * largo distinto), la posición no se puede resolver con CSS puro: se mide el\n * `offsetLeft`/`offsetWidth` de la pestaña activa después de cada render y la\n * transición del `transform`/`width` queda a cargo de CSS.\n *\n * <kf-tabs [options]=\"tabs\" [value]=\"active\" (valueChange)=\"active = $event\" />\n */\n@Component({\n selector: 'kf-tabs',\n imports: [Icon],\n template: `\n <div class=\"kf-tabs\" role=\"tablist\" #track>\n @for (option of options(); track option.value) {\n <button\n type=\"button\"\n role=\"tab\"\n class=\"kf-tabs__tab\"\n [class.kf-tabs__tab--active]=\"option.value === value()\"\n [attr.aria-selected]=\"option.value === value()\"\n [attr.tabindex]=\"option.value === value() ? 0 : -1\"\n [id]=\"'kf-tab-' + option.value\"\n [attr.aria-controls]=\"'kf-tabpanel-' + option.value\"\n (click)=\"select(option.value)\"\n (keydown)=\"onKeydown($event, option.value)\"\n >\n @if (option.icon; as iconName) {\n <kf-icon class=\"kf-tabs__icon\" [name]=\"iconName\" size=\"sm\" />\n }\n <span class=\"kf-tabs__label\">{{ option.label }}</span>\n </button>\n }\n <span\n class=\"kf-tabs__indicator\"\n aria-hidden=\"true\"\n [style.transform]=\"indicatorTransform()\"\n [style.width.px]=\"indicatorWidth()\"\n [style.opacity]=\"indicatorWidth() ? 1 : 0\"\n ></span>\n </div>\n `,\n styles: `\n :host {\n display: block;\n font-family: var(--kf-font-body);\n }\n .kf-tabs {\n position: relative;\n display: flex;\n align-items: stretch;\n gap: var(--kf-space-md);\n border-bottom: 1px solid var(--kf-color-border);\n }\n .kf-tabs__tab {\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n font: inherit;\n font-size: 0.9rem;\n color: var(--kf-color-text-muted);\n background: transparent;\n border: none;\n /* Sin padding horizontal propio: el espaciado entre tabs lo da el\n gap del contenedor — con ambos sumando (como antes) el conjunto\n quedaba más separado que en el PDF, que muestra las pestañas casi\n pegadas entre sí. El padding vertical se mantiene por área de click. */\n padding: var(--kf-space-sm) 0;\n cursor: pointer;\n transition: color 0.14s;\n }\n .kf-tabs__tab:hover:not(.kf-tabs__tab--active) {\n color: var(--kf-color-text);\n }\n .kf-tabs__tab:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n border-radius: var(--kf-radius-xs);\n }\n .kf-tabs__tab--active {\n color: var(--kf-color-primary);\n font-size: 1rem;\n font-weight: 700;\n }\n .kf-tabs__indicator {\n position: absolute;\n bottom: -1px;\n left: 0;\n height: 2px;\n background: var(--kf-color-primary);\n border-radius: 2px 2px 0 0;\n pointer-events: none;\n transition:\n transform 0.28s cubic-bezier(0.32, 0.72, 0, 1),\n width 0.28s cubic-bezier(0.32, 0.72, 0, 1),\n opacity 0.14s;\n }\n @media (prefers-reduced-motion: reduce) {\n .kf-tabs__indicator {\n transition: opacity 0.14s;\n }\n }\n `,\n})\nexport class Tabs {\n readonly options = input.required<TabOption[]>();\n readonly value = input.required<string>();\n readonly valueChange = output<string>();\n\n private readonly track = viewChild.required<ElementRef<HTMLElement>>('track');\n private readonly destroyRef = inject(DestroyRef);\n\n /** Geometría de la pestaña activa; `null` mientras no haya una medición válida. */\n private readonly activeRect = signal<{ x: number; width: number } | null>(null);\n\n protected readonly indicatorTransform = computed(\n () => `translateX(${this.activeRect()?.x ?? 0}px)`,\n );\n protected readonly indicatorWidth = computed(() => this.activeRect()?.width ?? 0);\n\n constructor() {\n // Cada cambio de `value`/`options` re-mide después de que el DOM ya se actualizó.\n afterRenderEffect(() => {\n this.value();\n this.options();\n this.measure();\n });\n\n afterNextRender(() => {\n // El ancho de la pestaña activa cambia con el layout (resize, fuentes que\n // cargan tarde), y sin esto el indicador queda desfasado del texto.\n const observer = new ResizeObserver(() => this.measure());\n observer.observe(this.track().nativeElement);\n this.destroyRef.onDestroy(() => observer.disconnect());\n });\n }\n\n private measure(): void {\n const active = this.track().nativeElement.querySelector<HTMLElement>('.kf-tabs__tab--active');\n this.activeRect.set(active ? { x: active.offsetLeft, width: active.offsetWidth } : null);\n }\n\n select(value: string): void {\n if (value === this.value()) {\n return;\n }\n this.valueChange.emit(value);\n }\n\n /** Navegación estándar de ARIA tabs: flechas mueven el foco y activan la pestaña. */\n onKeydown(event: KeyboardEvent, currentValue: string): void {\n const items = this.options();\n const currentIndex = items.findIndex((option) => option.value === currentValue);\n\n let nextIndex: number;\n switch (event.key) {\n case 'ArrowRight':\n nextIndex = (currentIndex + 1) % items.length;\n break;\n case 'ArrowLeft':\n nextIndex = (currentIndex - 1 + items.length) % items.length;\n break;\n case 'Home':\n nextIndex = 0;\n break;\n case 'End':\n nextIndex = items.length - 1;\n break;\n default:\n return;\n }\n\n event.preventDefault();\n const nextOption = items[nextIndex];\n this.select(nextOption.value);\n\n const host = (event.currentTarget as HTMLElement).parentElement;\n const nextId = `kf-tab-${nextOption.value}`;\n const nextButton = Array.from(host?.querySelectorAll<HTMLButtonElement>('button') ?? []).find(\n (button) => button.id === nextId,\n );\n nextButton?.focus();\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n Injectable,\n computed,\n inject,\n signal,\n} from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Visual tone of a toast. Maps to the state tokens in\n * projects/ui/src/tokens/base.css. `loading` has no auto-dismiss and shows an\n * indeterminate bar instead of a countdown — pair it with\n * {@link ToastService.promise}. It reuses the `info` tokens, the closest\n * semantic role to \"work in progress\".\n */\nexport type ToastTone = 'success' | 'error' | 'warning' | 'info' | 'loading';\n\n/** Fixed icon per tone (page 20 of the design system) — not configurable per call. */\nconst TOAST_ICON: Record<ToastTone, IconName> = {\n success: 'check-circle',\n error: 'alert-circle',\n warning: 'alert-triangle',\n info: 'bell',\n loading: 'bell',\n};\n\n/** Options for {@link ToastService.show}. */\nexport interface ToastOptions {\n /** Color tone. Defaults to `'info'`. */\n tone?: ToastTone;\n /** Milliseconds before auto-dismiss. Ignored when `tone` is `'loading'`. Defaults to `2800`. */\n duration?: number;\n}\n\n/** Messages for each leg of {@link ToastService.promise}. */\nexport interface ToastPromiseMessages<T = unknown> {\n loading?: string;\n success?: string | ((value: T) => string);\n error?: string | ((error: unknown) => string);\n}\n\n/** The single active toast, as rendered by `kf-toast-host`. */\nexport interface ToastState {\n id: number;\n message: string;\n tone: ToastTone;\n duration: number;\n leaving: boolean;\n}\n\nconst DEFAULT_DURATION_MS = 2800;\nconst EXIT_ANIMATION_MS = 200;\n\n/**\n * Shows one toast at a time — a new `show()` call replaces whatever is\n * currently up (this mirrors a global status line, not a notification stack).\n *\n * Angular has no global function that can mount UI on its own, so the\n * imperative `showToast(...)` of the reference design system becomes a\n * root-provided service holding signal state: `ToastService.show(...)` sets\n * the active toast and `ToastHost` (standalone, mounted once in the app\n * shell) renders it.\n *\n * @example\n * ```ts\n * // app.ts\n * imports: [ToastHost]\n * template: `<kf-toast-host />`\n *\n * // anywhere else\n * private readonly toast = inject(ToastService);\n * this.toast.show('Vehículo guardado', { tone: 'success' });\n *\n * // chains a `loading` toast into the promise's outcome:\n * this.toast.promise(this.api.save(vehicle), {\n * loading: 'Guardando…',\n * success: 'Vehículo guardado',\n * error: 'No se pudo guardar',\n * });\n * ```\n */\n@Injectable({ providedIn: 'root' })\nexport class ToastService {\n private readonly _current = signal<ToastState | null>(null);\n private nextId = 0;\n private dismissTimer?: ReturnType<typeof setTimeout>;\n private removeTimer?: ReturnType<typeof setTimeout>;\n\n /** The single active toast, or `null`. */\n readonly current = this._current.asReadonly();\n\n /** Shows a toast, replacing whatever is currently shown. Returns its id. */\n show(message: string, options: ToastOptions = {}): number {\n const id = this.nextId++;\n const tone = options.tone ?? 'info';\n const duration = options.duration ?? DEFAULT_DURATION_MS;\n clearTimeout(this.dismissTimer);\n clearTimeout(this.removeTimer);\n this._current.set({ id, message, tone, duration, leaving: false });\n if (tone !== 'loading') {\n this.dismissTimer = setTimeout(() => this.dismiss(id), duration);\n }\n return id;\n }\n\n /**\n * Starts the exit animation, then removes the toast. No-op when `id` is no\n * longer the active toast, so a stale timer never kills a newer toast.\n */\n dismiss(id?: number): void {\n const toast = this._current();\n if (!toast || toast.leaving || (id !== undefined && toast.id !== id)) return;\n clearTimeout(this.dismissTimer);\n this._current.set({ ...toast, leaving: true });\n this.removeTimer = setTimeout(() => {\n if (this._current()?.id === toast.id) this._current.set(null);\n }, EXIT_ANIMATION_MS);\n }\n\n /**\n * Shows a `loading` toast, then swaps it for a `success`/`error` toast once\n * `work` settles. Re-throws `work`'s rejection so callers can still react to\n * the failure.\n */\n promise<T>(work: Promise<T>, messages: ToastPromiseMessages<T> = {}): Promise<T> {\n this.show(messages.loading ?? 'Procesando…', { tone: 'loading' });\n return work.then(\n (value) => {\n const msg = messages.success ?? 'Listo';\n this.show(typeof msg === 'function' ? msg(value) : msg, { tone: 'success' });\n return value;\n },\n (error) => {\n const msg = messages.error ?? 'Ocurrió un error';\n this.show(typeof msg === 'function' ? msg(error) : msg, { tone: 'error' });\n throw error;\n },\n );\n }\n}\n\n/**\n * Renders whatever `ToastService` currently holds, fixed bottom-right. Mount\n * one instance in the app shell (e.g. next to the router outlet); it takes no\n * inputs and re-renders itself from the service state.\n *\n * <kf-toast-host />\n */\n@Component({\n selector: 'kf-toast-host',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [Icon],\n template: `\n @for (t of toastList(); track t.id) {\n <div\n class=\"kf-toast kf-toast--{{ t.tone }}\"\n [class.kf-toast--leaving]=\"t.leaving\"\n role=\"status\"\n [attr.aria-live]=\"t.tone === 'error' ? 'assertive' : 'polite'\"\n >\n <kf-icon class=\"kf-toast__icon\" [name]=\"toastIcon(t.tone)\" size=\"sm\" />\n <span class=\"kf-toast__message\">{{ t.message }}</span>\n <button type=\"button\" class=\"kf-toast__dismiss\" aria-label=\"Cerrar\" (click)=\"dismiss(t.id)\">\n <kf-icon name=\"x\" size=\"sm\" />\n </button>\n <span class=\"kf-toast__bar\" [style.--kf-toast-dur]=\"t.duration + 'ms'\"></span>\n </div>\n }\n `,\n styles: `\n @keyframes kf-toast-in {\n from {\n transform: translateY(20px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n }\n @keyframes kf-toast-bar {\n from {\n transform: scaleX(1);\n }\n to {\n transform: scaleX(0);\n }\n }\n @keyframes kf-toast-indeterminate {\n 0% {\n left: -40%;\n width: 40%;\n }\n 50% {\n left: 30%;\n width: 55%;\n }\n 100% {\n left: 100%;\n width: 40%;\n }\n }\n\n .kf-toast {\n /* Per-tone accent, overridden by the tone classes below. */\n --kf-toast-accent: var(--kf-color-info);\n\n position: fixed;\n inset-block-end: var(--kf-space-lg);\n inset-inline-end: var(--kf-space-lg);\n z-index: 1100;\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n max-inline-size: 360px;\n padding: var(--kf-space-sm) var(--kf-space-sm) var(--kf-space-sm) var(--kf-space-md);\n border-radius: var(--kf-radius-md);\n border-left: 4px solid var(--kf-toast-accent);\n background: var(--kf-color-ink);\n color: var(--kf-color-white);\n box-shadow: var(--kf-shadow-lg);\n font-family: var(--kf-font-body);\n font-size: 0.875rem;\n font-weight: 600;\n line-height: 1.4;\n overflow: hidden;\n animation: kf-toast-in 0.25s ease forwards;\n transition:\n transform 0.2s ease,\n opacity 0.2s ease;\n }\n .kf-toast--leaving {\n transform: translateY(20px);\n opacity: 0;\n }\n .kf-toast--success {\n --kf-toast-accent: var(--kf-color-success);\n }\n .kf-toast--error {\n --kf-toast-accent: var(--kf-color-error);\n }\n .kf-toast--warning {\n --kf-toast-accent: var(--kf-color-warning);\n }\n .kf-toast--info,\n .kf-toast--loading {\n --kf-toast-accent: var(--kf-color-info);\n }\n\n .kf-toast__icon {\n flex: none;\n color: var(--kf-toast-accent);\n }\n .kf-toast__message {\n flex: 1;\n }\n .kf-toast__dismiss {\n flex: none;\n display: grid;\n place-items: center;\n inline-size: 24px;\n block-size: 24px;\n padding: 0;\n border: none;\n border-radius: var(--kf-radius-xs);\n background: transparent;\n color: inherit;\n font: inherit;\n line-height: 1;\n cursor: pointer;\n opacity: 0.6;\n }\n .kf-toast__dismiss:hover {\n opacity: 1;\n }\n\n .kf-toast__bar {\n position: absolute;\n inset-block-end: 0;\n left: 0;\n block-size: 3px;\n inline-size: 100%;\n background: var(--kf-toast-accent);\n opacity: 0.7;\n transform-origin: left;\n animation: kf-toast-bar var(--kf-toast-dur, 2800ms) linear forwards;\n }\n .kf-toast--loading .kf-toast__bar {\n left: -40%;\n inline-size: 40%;\n opacity: 0.6;\n animation: kf-toast-indeterminate 1.4s ease-in-out infinite;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .kf-toast,\n .kf-toast__bar,\n .kf-toast--loading .kf-toast__bar {\n animation: none;\n }\n .kf-toast {\n transition: none;\n }\n }\n `,\n})\nexport class ToastHost {\n private readonly toastService = inject(ToastService);\n\n /** 0-or-1 wrapper so `@for track t.id` remounts the node on every new toast, restarting its animations. */\n protected readonly toastList = computed<ToastState[]>(() => {\n const toast = this.toastService.current();\n return toast ? [toast] : [];\n });\n\n protected toastIcon(tone: ToastTone): IconName {\n return TOAST_ICON[tone];\n }\n\n protected dismiss(id: number): void {\n this.toastService.dismiss(id);\n }\n}\n","import { Component, input } from '@angular/core';\nimport { Icon, IconName } from '../icon/Icon';\n\n/**\n * Estado puntual mostrado junto a la identidad del vehículo (ej. \"En ruta\",\n * \"Mantenimiento\", \"Fuera de servicio\"). `tone` define el color semántico:\n * \"crit\" no tiene token propio en base.css, se mapea a var(--kf-color-error).\n */\nexport interface VehicleHeaderStatus {\n label: string;\n tone?: 'ok' | 'warn' | 'crit';\n icon?: IconName;\n}\n\n/**\n * Header de identidad de un vehículo de flota: unidad (patente/id), modelo\n * (como badge, no texto plano — página 24: \"ABC-123\" junto a un badge\n * \"TITAN 4X2\"), VIN en fuente mono y un estado opcional. Un área de acciones\n * opcional se proyecta vía `<ng-content select=\"[actions]\">` para no acoplar\n * el componente a un set fijo de botones — el patrón real de la spec es\n * `kf-button variant=\"outline\"` (ej. \"Llamar\", con ícono) + un `primary`\n * (ej. \"Crear Ticket\", con ícono \"+\"):\n *\n * <kf-vehicle-header unit=\"AB123CD\" model=\"Sprinter 415\" vin=\"9BW...\"\n * [status]=\"{ label: 'En ruta', tone: 'ok' }\">\n * <kf-button actions variant=\"outline\" icon=\"phone\">Llamar</kf-button>\n * <kf-button actions icon=\"plus\">Crear Ticket</kf-button>\n * </kf-vehicle-header>\n */\n@Component({\n selector: 'kf-vehicle-header',\n imports: [Icon],\n template: `\n <div class=\"kf-vehicle-header__identity\">\n <span class=\"kf-vehicle-header__unit\">{{ unit() }}</span>\n @if (model()) {\n <span class=\"kf-vehicle-header__model\">{{ model() }}</span>\n }\n @if (vin()) {\n <span class=\"kf-vehicle-header__vin\">VIN: {{ vin() }}</span>\n }\n </div>\n\n @if (status(); as currentStatus) {\n <span\n class=\"kf-vehicle-header__status\"\n [class]=\"'kf-vehicle-header__status--' + (currentStatus.tone ?? 'ok')\"\n >\n @if (currentStatus.icon; as iconName) {\n <kf-icon [name]=\"iconName\" size=\"sm\" />\n }\n {{ currentStatus.label }}\n </span>\n }\n\n <div class=\"kf-vehicle-header__actions\">\n <ng-content select=\"[actions]\" />\n </div>\n `,\n styles: `\n :host {\n display: flex;\n align-items: center;\n gap: var(--kf-space-md);\n padding: var(--kf-space-md);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-md);\n background: var(--kf-color-surface);\n font-family: var(--kf-font-body);\n }\n .kf-vehicle-header__identity {\n display: flex;\n align-items: baseline;\n flex-wrap: wrap;\n gap: var(--kf-space-sm);\n flex: 1 1 auto;\n min-width: 0;\n }\n .kf-vehicle-header__unit {\n font-family: var(--kf-font-title);\n font-size: 1.125rem;\n font-weight: 700;\n color: var(--kf-color-ink);\n }\n .kf-vehicle-header__model {\n padding: 2px var(--kf-space-sm);\n border-radius: var(--kf-radius-xs);\n background: var(--kf-color-border);\n color: var(--kf-color-text-muted);\n font-size: 0.75rem;\n font-weight: 700;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n }\n .kf-vehicle-header__vin {\n font-family: var(--kf-font-mono);\n font-size: 0.8125rem;\n color: var(--kf-color-text-muted);\n }\n .kf-vehicle-header__status {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: var(--kf-space-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n border-radius: var(--kf-radius-pill);\n font-size: 0.75rem;\n font-weight: 600;\n line-height: 1;\n white-space: nowrap;\n }\n .kf-vehicle-header__status--ok {\n background: var(--kf-color-success-soft);\n color: var(--kf-color-success);\n }\n .kf-vehicle-header__status--warn {\n background: var(--kf-color-warning-soft);\n color: var(--kf-color-warning);\n }\n .kf-vehicle-header__status--crit {\n background: var(--kf-color-error-soft);\n color: var(--kf-color-error);\n }\n .kf-vehicle-header__actions {\n flex: none;\n display: flex;\n align-items: center;\n gap: var(--kf-space-sm);\n }\n `,\n})\nexport class VehicleHeader {\n readonly unit = input.required<string>();\n readonly model = input<string>();\n readonly vin = input<string>();\n readonly status = input<VehicleHeaderStatus>();\n}\n","import { Component, input, output } from '@angular/core';\n\nexport type ViewToggleOption = 'table' | 'cards';\n\n/**\n * Switch de dos posiciones para alternar entre vista de tabla y vista de\n * tarjetas. Pensado para usarse dentro de DataTable, pero es standalone e\n * independiente: no asume nada sobre el componente que lo contiene.\n *\n * Se implementa como un grupo de radio (role=\"radiogroup\") en vez de dos\n * botones sueltos: semánticamente es una única selección excluyente entre\n * dos estados, no dos acciones independientes. Esto también habilita\n * navegación con flechas izquierda/derecha, igual que un <input type=\"radio\">\n * nativo agrupado.\n *\n * <kf-view-toggle [view]=\"view\" (viewChange)=\"view = $event\" />\n */\n@Component({\n selector: 'kf-view-toggle',\n template: `\n <div class=\"kf-view-toggle\" role=\"radiogroup\" aria-label=\"Alternar tipo de vista\">\n <button\n type=\"button\"\n role=\"radio\"\n class=\"kf-view-toggle__option\"\n [class.kf-view-toggle__option--active]=\"view() === 'table'\"\n [attr.aria-checked]=\"view() === 'table'\"\n [attr.tabindex]=\"view() === 'table' ? 0 : -1\"\n (click)=\"select('table')\"\n (keydown)=\"onKeydown($event)\"\n >\n Tabla\n </button>\n <button\n type=\"button\"\n role=\"radio\"\n class=\"kf-view-toggle__option\"\n [class.kf-view-toggle__option--active]=\"view() === 'cards'\"\n [attr.aria-checked]=\"view() === 'cards'\"\n [attr.tabindex]=\"view() === 'cards' ? 0 : -1\"\n (click)=\"select('cards')\"\n (keydown)=\"onKeydown($event)\"\n >\n Tarjetas\n </button>\n </div>\n `,\n styles: `\n :host {\n display: inline-block;\n font-family: var(--kf-font-body);\n }\n .kf-view-toggle {\n display: inline-flex;\n align-items: stretch;\n gap: 2px;\n padding: 2px;\n background: var(--kf-color-surface);\n border: 1px solid var(--kf-color-border);\n border-radius: var(--kf-radius-sm);\n }\n .kf-view-toggle__option {\n font: inherit;\n font-size: 0.85rem;\n line-height: 1;\n color: var(--kf-color-text-muted);\n background: transparent;\n border: none;\n border-radius: var(--kf-radius-xs);\n padding: var(--kf-space-xs) var(--kf-space-sm);\n cursor: pointer;\n transition:\n background 0.14s,\n color 0.14s,\n box-shadow 0.14s;\n }\n .kf-view-toggle__option:hover:not(.kf-view-toggle__option--active) {\n color: var(--kf-color-text);\n }\n .kf-view-toggle__option:focus-visible {\n outline: none;\n box-shadow: var(--kf-shadow-focus);\n }\n .kf-view-toggle__option--active {\n color: var(--kf-color-ink);\n background: var(--kf-color-white);\n box-shadow: var(--kf-shadow-xs);\n }\n `,\n})\nexport class ViewToggle {\n readonly view = input.required<ViewToggleOption>();\n readonly viewChange = output<ViewToggleOption>();\n\n select(next: ViewToggleOption): void {\n if (next === this.view()) {\n return;\n }\n this.viewChange.emit(next);\n }\n\n /** Navegación estándar de ARIA radiogroup: flechas mueven foco y seleccionan. */\n onKeydown(event: KeyboardEvent): void {\n if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight') {\n return;\n }\n\n event.preventDefault();\n const next: ViewToggleOption = this.view() === 'table' ? 'cards' : 'table';\n this.select(next);\n\n const current = event.currentTarget as HTMLElement;\n const buttons =\n current.parentElement?.querySelectorAll<HTMLButtonElement>('.kf-view-toggle__option');\n const nextButton = Array.from(buttons ?? []).find((button) => button !== current);\n nextButton?.focus();\n }\n}\n","/*\n * Public API Surface of ui\n */\n\nexport * from './lib/action-tile/ActionTile';\nexport * from './lib/admin-badge/AdminBadge';\nexport * from './lib/button/button';\nexport * from './lib/alert/Alert';\nexport * from './lib/auth-layout/AuthLayout';\nexport * from './lib/avatar/Avatar';\nexport * from './lib/badge/Badge';\nexport * from './lib/breadcrumb/Breadcrumb';\nexport * from './lib/card/Card';\nexport * from './lib/carousel/Carousel';\nexport * from './lib/checkbox/Checkbox';\nexport * from './lib/chip/Chip';\nexport * from './lib/company-selector/CompanySelector';\nexport * from './lib/content-slot/ContentSlot';\nexport * from './lib/content-state/ContentState';\nexport * from './lib/data-table/DataTable';\nexport * from './lib/divider/Divider';\nexport * from './lib/drawer/Drawer';\nexport * from './lib/drawer-logout/DrawerLogout';\nexport * from './lib/drawer-session/DrawerSession';\nexport * from './lib/dropdown/Dropdown';\nexport * from './lib/empty-state/EmptyState';\nexport * from './lib/feature-card/FeatureCard';\nexport * from './lib/field/Field';\nexport * from './lib/field-label/FieldLabel';\nexport * from './lib/filter-chips/FilterChips';\nexport * from './lib/folder-tabs/FolderTabs';\nexport * from './lib/footer/Footer';\nexport * from './lib/icon/Icon';\nexport * from './lib/input/Input';\nexport * from './lib/link/Link';\nexport * from './lib/metric-card/MetricCard';\nexport * from './lib/modal/Modal';\nexport * from './lib/multi-select/MultiSelect';\nexport * from './lib/page-header/PageHeader';\nexport * from './lib/pagination/Pagination';\nexport * from './lib/panel/Panel';\nexport * from './lib/portal-header/PortalHeader';\nexport * from './lib/reserve-block/ReserveBlock';\nexport * from './lib/section-header/SectionHeader';\nexport * from './lib/segmented/Segmented';\nexport * from './lib/select/Select';\nexport * from './lib/sidebar-nav-item/SidebarNavItem';\nexport * from './lib/sidebar-shell/SidebarShell';\nexport * from './lib/skeleton/Skeleton';\nexport * from './lib/spinner/Spinner';\nexport * from './lib/stat-tile/StatTile';\nexport * from './lib/status-pill/StatusPill';\nexport * from './lib/tabs/Tabs';\nexport * from './lib/text/Text';\nexport * from './lib/toast/Toast';\nexport * from './lib/tooltip/Tooltip';\nexport * from './lib/vehicle-header/VehicleHeader';\nexport * from './lib/view-toggle/ViewToggle';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["nextId","Input"],"mappings":"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"}
|