@salesql/sql_components_vue3 1.0.0 → 2.0.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/ui/DsSpinner/DsSpinner.types.ts","../src/ui/DsSpinner/DsSpinner.vue","../src/constants/events.ts","../src/ui/DsButton/DsButton.types.ts","../src/ui/DsButton/DsButton.vue","../src/ui/DsTag/DsTag.types.ts","../src/ui/DsTag/DsTag.vue","../src/ui/DsBadge/DsBadge.types.ts","../src/ui/DsBadge/DsBadge.vue","../src/ui/DsAvatar/DsAvatar.vue","../src/ui/DsTable/DsTable.types.ts","../src/ui/DsTable/DsTable.vue","../src/ui/DsInput/DsInput.types.ts","../src/ui/DsInput/DsInput.vue","../src/ui/DsTextarea/DsTextarea.vue","../src/ui/DsCheckbox/DsCheckbox.vue","../src/ui/DsAlert/DsAlert.types.ts","../src/ui/DsAlert/DsAlert.vue","../src/ui/DsNotification/DsNotification.types.ts","../src/ui/DsNotification/DsNotification.vue","../src/ui/DsModal/DsModal.vue","../src/ui/DsVerificationIcon/DsVerificationIcon.types.ts","../src/ui/DsVerificationIcon/DsVerificationIcon.vue","../src/ui/DsContactValue/DsContactValue.vue","../src/ui/DsDataCard/DsDataCard.vue"],"sourcesContent":["// DsSpinner — the DS \"Spinner\": a rotating border-ring. Tones mirror Spinner.jsx.\n\nexport const DS_SPINNER_TONES = {\n DARK: 'dark', // slate ring — for light surfaces (default)\n LIGHT: 'light', // white ring — for dark surfaces / solid buttons\n ACCENT: 'accent', // accent ring\n} as const;\nexport type DsSpinnerTone = (typeof DS_SPINNER_TONES)[keyof typeof DS_SPINNER_TONES];\n","<template>\n <span\n class=\"ds-spinner\"\n :class=\"`ds-spinner--${tone}`\"\n role=\"status\"\n :style=\"{ width: `${size}px`, height: `${size}px` }\"\n :aria-label=\"label || undefined\"\n :aria-hidden=\"label ? undefined : 'true'\"\n >\n <span v-if=\"label\" class=\"ds-spinner__sr-only\">{{ label }}</span>\n </span>\n</template>\n\n<script setup lang=\"ts\">\nimport { type PropType } from 'vue';\nimport { DS_SPINNER_TONES, type DsSpinnerTone } from './DsSpinner.types';\n\ndefineProps({\n size: { type: Number, default: 24 },\n tone: {\n type: String as PropType<DsSpinnerTone>,\n default: DS_SPINNER_TONES.DARK,\n },\n // Optional accessible text; without it the spinner is aria-hidden.\n label: { type: String, default: '' },\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/motion.scss' as m;\n\n@keyframes ds-spinner-rot {\n to {\n transform: rotate(360deg);\n }\n}\n\n.ds-spinner {\n display: inline-block;\n\n border: 2px solid;\n border-radius: 50%;\n\n animation: ds-spinner-rot 1s linear infinite;\n\n @include m.reduce-motion {\n animation: none;\n }\n\n &--dark {\n border-color: colors.$slate-tint;\n border-top-color: colors.$slate-main;\n }\n &--light {\n border-color: rgba(255, 255, 255, 0.4);\n border-top-color: colors.$white;\n }\n &--accent {\n border-color: colors.$accent-mid;\n border-top-color: colors.$accent-main;\n }\n\n &__sr-only {\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}\n</style>\n","// Evento genérico de click para props/emit\nexport const CLICK = 'click' as const;\nexport type ClickEventName = typeof CLICK;\n\n// Evento de cierre (p. ej. DsTag con × / closable) — mapea a onClose del DS\nexport const CLOSE = 'close' as const;\nexport type CloseEventName = typeof CLOSE;\n\n// Eventos de foco de controles de formulario (DsInput / DsTextarea)\nexport const FOCUS = 'focus' as const;\nexport type FocusEventName = typeof FOCUS;\n\nexport const BLUR = 'blur' as const;\nexport type BlurEventName = typeof BLUR;\n\n// Eventos de la familia data (DsContactValue / DsDataCard).\n// COPY lleva el valor copiado; CORRECT / INCORRECT marcan el rating de un dato.\nexport const COPY = 'copy' as const;\nexport type CopyEventName = typeof COPY;\n\nexport const CORRECT = 'correct' as const;\nexport type CorrectEventName = typeof CORRECT;\n\nexport const INCORRECT = 'incorrect' as const;\nexport type IncorrectEventName = typeof INCORRECT;\n\n// Acciones de cabecera de DsDataCard.\nexport const SORT = 'sort' as const;\nexport type SortEventName = typeof SORT;\n\nexport const EDIT = 'edit' as const;\nexport type EditEventName = typeof EDIT;\n","// DsButton — 1:1 with the SalesQL Design System \"Button\" specimen.\n// Variants/sizes are the ONLY ones the DS defines; more arrive when the DS grows.\n\n// Variants (classes: ds-button--<variant>)\nexport const DS_BUTTON_VARIANTS = {\n PRIMARY: 'primary', // solid accent fill, white text\n SECONDARY: 'secondary', // slate surface fill, dark text\n TERTIARY: 'tertiary', // transparent ghost, dark text\n QUATERNARY: 'quaternary', // accent border + accent text, light fill\n SPECIAL: 'special', // accent text only, no fill/border (link-style)\n} as const;\nexport type DsButtonVariant = (typeof DS_BUTTON_VARIANTS)[keyof typeof DS_BUTTON_VARIANTS];\n\n// Sizes = DS control heights (classes: ds-button--<size>)\nexport const DS_BUTTON_SIZES = {\n SMALL: 'small', // 24px\n MEDIUM: 'medium', // 32px\n LARGE: 'large', // 36px\n XLARGE: 'xlarge', // 48px\n} as const;\nexport type DsButtonSize = (typeof DS_BUTTON_SIZES)[keyof typeof DS_BUTTON_SIZES];\n\n// Native <button> type\nexport const DS_BUTTON_NATIVE_TYPES = {\n BUTTON: 'button',\n SUBMIT: 'submit',\n RESET: 'reset',\n} as const;\nexport type DsButtonNativeType =\n (typeof DS_BUTTON_NATIVE_TYPES)[keyof typeof DS_BUTTON_NATIVE_TYPES];\n","<template>\n <button\n class=\"ds-button\"\n :type=\"nativeType\"\n :disabled=\"disabled || loading\"\n :autofocus=\"autofocus\"\n :aria-busy=\"loading || undefined\"\n :aria-disabled=\"disabled || loading || undefined\"\n :aria-label=\"ariaLabel || undefined\"\n :class=\"[\n `ds-button--${variant}`,\n `ds-button--${size}`,\n {\n 'is-disabled': disabled || loading,\n 'is-loading': loading,\n 'is-circle': circle,\n 'is-dashed': dashed,\n },\n ]\"\n @click=\"handleClick\"\n >\n <DsSpinner v-if=\"loading\" class=\"ds-button__spinner\" :size=\"iconSize\" :tone=\"spinnerTone\" />\n\n <span\n v-if=\"!loading && (leftIcon || $slots.leading)\"\n class=\"ds-button__icon ds-button__icon--leading\"\n >\n <slot name=\"leading\"\n ><i class=\"material-icons\" aria-hidden=\"true\">{{ leftIcon }}</i></slot\n >\n </span>\n\n <span v-if=\"!loading && $slots.default\" class=\"ds-button__label\"><slot /></span>\n\n <span\n v-if=\"!loading && (rightIcon || $slots.trailing)\"\n class=\"ds-button__icon ds-button__icon--trailing\"\n >\n <slot name=\"trailing\"\n ><i class=\"material-icons\" aria-hidden=\"true\">{{ rightIcon }}</i></slot\n >\n </span>\n </button>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, type PropType } from 'vue';\nimport { DsSpinner, DS_SPINNER_TONES } from '@shared/ui/DsSpinner';\nimport { CLICK } from '@shared/constants/events';\nimport {\n DS_BUTTON_NATIVE_TYPES,\n DS_BUTTON_SIZES,\n DS_BUTTON_VARIANTS,\n type DsButtonNativeType,\n type DsButtonSize,\n type DsButtonVariant,\n} from './DsButton.types';\n\nconst props = defineProps({\n variant: { type: String as PropType<DsButtonVariant>, default: DS_BUTTON_VARIANTS.PRIMARY },\n size: { type: String as PropType<DsButtonSize>, default: DS_BUTTON_SIZES.MEDIUM },\n nativeType: {\n type: String as PropType<DsButtonNativeType>,\n default: DS_BUTTON_NATIVE_TYPES.BUTTON,\n },\n // Material Icon names (rendered via <i class=\"material-icons\">); a leading/\n // trailing slot overrides. Icon-only buttons need ariaLabel.\n leftIcon: { type: String, default: '' },\n rightIcon: { type: String, default: '' },\n ariaLabel: { type: String, default: '' },\n disabled: Boolean,\n loading: Boolean,\n circle: Boolean,\n dashed: Boolean,\n autofocus: Boolean,\n});\n\n// Runtime array (not the type-only form): the SFC compiler can't resolve\n// `typeof CLICK` to a literal, leaving `emits` empty at runtime. With `click`\n// undeclared, the parent's @click both falls through to the native <button>\n// AND is invoked by emit() → the listener fires twice. Declaring it at runtime\n// (via the CLICK constant, per convention) excludes it from fallthrough.\nconst emit = defineEmits([CLICK]);\n\nconst iconSize = computed(() => (props.size === DS_BUTTON_SIZES.SMALL ? 14 : 20));\nconst spinnerTone = computed(() =>\n props.variant === DS_BUTTON_VARIANTS.PRIMARY ? DS_SPINNER_TONES.LIGHT : DS_SPINNER_TONES.DARK\n);\n\nfunction handleClick(event: MouseEvent) {\n if (props.disabled || props.loading) return;\n emit(CLICK, event);\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/spacing.scss' as s;\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n@use '../../assets/css/motion.scss' as m;\n@use '../../assets/css/icons.scss' as i;\n\n.ds-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n\n padding: 0;\n\n font-family: t.$font-family;\n font-weight: t.$weight-medium; // 500 (DS); small overrides to 400\n font-size: t.font-size('body');\n line-height: 20px;\n\n border: 1px solid transparent;\n border-radius: r.$radius-control;\n outline: none;\n\n cursor: pointer;\n transition:\n background-color m.$duration-default m.$easing,\n border-color m.$duration-default m.$easing,\n opacity m.$duration-default m.$easing;\n\n @include m.reduce-motion {\n transition: none;\n }\n\n &.is-disabled {\n opacity: 0.55;\n cursor: not-allowed;\n }\n\n &__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n // DS icon size: 20px (small → 14px). Sizing the glyph to fill its box also\n // removes the optical \"gap\" a smaller glyph leaves against the button edge.\n .material-icons {\n font-size: i.icon-size(20);\n line-height: 1;\n }\n }\n\n // Material glyphs carry a built-in keyline (~2–3px advance bearing). Absorb it\n // on the edge side so a leading/trailing icon sits at the same optical inset as\n // a text-only button. Not for icon-only (circle) buttons — those stay centered.\n &:not(.is-circle) &__icon--leading {\n margin-left: -3px;\n }\n &:not(.is-circle) &__icon--trailing {\n margin-right: -3px;\n }\n\n &__spinner {\n /* size comes from the :size prop (iconSize) */\n }\n\n /* ---------- Variants ---------- */\n &--primary {\n color: colors.$white;\n background-color: colors.$accent-main;\n\n &:hover:not(.is-disabled) {\n background-color: colors.$accent-shadow;\n }\n }\n &--secondary {\n color: colors.$slate-main;\n background-color: colors.$slate-bg;\n\n &:hover:not(.is-disabled) {\n background-color: colors.$slate-tint;\n }\n }\n &--tertiary {\n color: colors.$slate-main;\n background-color: colors.$white;\n\n &:hover:not(.is-disabled) {\n background-color: colors.$slate-tint;\n }\n }\n &--quaternary {\n color: colors.$accent-main;\n border-color: colors.$accent-mid;\n background-color: colors.$white;\n\n &:hover:not(.is-disabled) {\n border-color: colors.$accent-main;\n }\n }\n &--special {\n color: colors.$accent-main;\n background-color: colors.$white;\n\n &:hover:not(.is-disabled) {\n background-color: colors.$accent-bg;\n }\n }\n\n /* ---------- Dashed \"add\" affordance ---------- */\n &.is-dashed {\n color: colors.$slate-mid;\n font-weight: t.$weight-bold;\n\n border: 1px dashed colors.$slate-mid;\n background-color: transparent;\n\n &:hover:not(.is-disabled) {\n color: colors.$accent-main;\n border-color: colors.$accent-main;\n background-color: colors.$accent-bg;\n }\n }\n\n /* ---------- Sizes (DS control heights + paddings) ---------- */\n &--small {\n height: s.control-height('small');\n padding: 0 s.control-padding('small');\n gap: 2px;\n\n font-weight: t.$weight-regular; // 400\n font-size: t.font-size('caption');\n\n .ds-button__icon .material-icons {\n font-size: i.icon-size(14);\n }\n }\n &--medium {\n height: s.control-height('medium');\n padding: 0 s.control-padding('medium');\n }\n &--large {\n height: s.control-height('large');\n padding: 0 s.control-padding('large');\n }\n &--xlarge {\n height: s.control-height('xlarge');\n padding: 0 s.control-padding('xlarge');\n }\n\n /* ---------- Circle (icon-only) ---------- */\n &.is-circle {\n padding: 8px;\n border-radius: r.$radius-full;\n aspect-ratio: 1;\n }\n}\n</style>\n","// DsTag — the DS \"Tag\": small bordered chip with optional close (×).\n// ⚠️ NOT the solid pill (that is DsBadge). See DESIGN-SYSTEM.md reconciliation.\n// Tones mirror the DS Tag source (Tag.jsx TONES). `rounded` → semicircular sides.\n\nexport const DS_TAG_TONES = {\n DEFAULT: 'default', // white bg, slate-tint border, muted text\n SUCCESS: 'success', // e.g. Verified\n INFO: 'info', // e.g. Work\n WARNING: 'warning', // e.g. Pending\n ERROR: 'error', // e.g. Bounced\n} as const;\nexport type DsTagTone = (typeof DS_TAG_TONES)[keyof typeof DS_TAG_TONES];\n","<template>\n <span class=\"ds-tag\" :class=\"[`ds-tag--${tone}`, { 'is-rounded': rounded }]\">\n <slot />\n\n <button\n v-if=\"closable\"\n type=\"button\"\n class=\"ds-tag__close\"\n :aria-label=\"closeLabel || undefined\"\n @click=\"emit(CLOSE)\"\n >\n <i class=\"material-icons\" aria-hidden=\"true\">close</i>\n </button>\n </span>\n</template>\n\n<script setup lang=\"ts\">\nimport { type PropType } from 'vue';\nimport { CLOSE } from '@shared/constants/events';\nimport { DS_TAG_TONES, type DsTagTone } from './DsTag.types';\n\ndefineProps({\n tone: {\n type: String as PropType<DsTagTone>,\n default: DS_TAG_TONES.DEFAULT,\n },\n // Semicircular sides (DS `rounded`): radius-round vs the default radius-control.\n rounded: Boolean,\n // Show a × close control that emits `close`.\n closable: Boolean,\n // Accessible name for the × control (the app owns the wording / i18n).\n closeLabel: {\n type: String,\n default: '',\n },\n});\n\nconst emit = defineEmits<{\n (e: typeof CLOSE): void;\n}>();\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n@use '../../assets/css/icons.scss' as i;\n\n.ds-tag {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n\n padding: 0 10px;\n\n color: colors.$slate-mid;\n font-family: t.$font-family;\n font-weight: t.$weight-regular;\n font-size: t.font-size('caption');\n line-height: 30px;\n\n background-color: colors.$white;\n\n border: 1px solid colors.$slate-tint;\n border-radius: r.$radius-control;\n\n white-space: nowrap;\n\n &.is-rounded {\n border-radius: r.$radius-round;\n }\n\n &__close {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n padding: 0;\n\n color: inherit;\n\n background: transparent;\n border: 0;\n\n cursor: pointer;\n\n .material-icons {\n font-size: i.icon-size(12);\n }\n }\n\n /* ---------- Tones (default: white + tint border + muted text) ---------- */\n &--default {\n color: colors.$slate-mid;\n border-color: colors.$slate-tint;\n background-color: colors.$white;\n }\n &--success {\n color: colors.$success-shadow;\n border-color: colors.$success-mid;\n background-color: colors.$success-tint;\n }\n &--info {\n color: colors.$info-shadow;\n border-color: colors.$info-mid;\n background-color: colors.$info-tint;\n }\n &--warning {\n color: colors.$warning-shadow;\n border-color: colors.$warning-mid;\n background-color: colors.$warning-tint;\n }\n &--error {\n color: colors.$error-shadow;\n border-color: colors.$error-mid;\n background-color: colors.$error-tint;\n }\n}\n</style>\n","// DsBadge — the DS \"Badge\": solid, white-text pill (value types & counts).\n// ⚠️ NOT the tint chip (that is DsTag). See DESIGN-SYSTEM.md reconciliation.\n// Tones mirror the DS Badge source (Badge.jsx TONES).\n\nexport const DS_BADGE_TONES = {\n ACCENT: 'accent', // e.g. Work (purple)\n GREY: 'grey', // e.g. Direct (slate-soft)\n INFO: 'info', // e.g. Mobile (blue)\n SUCCESS: 'success', // e.g. New (green)\n ERROR: 'error', // coral\n WARNING: 'warning', // orange\n} as const;\nexport type DsBadgeTone = (typeof DS_BADGE_TONES)[keyof typeof DS_BADGE_TONES];\n","<template>\n <span class=\"ds-badge\" :class=\"`ds-badge--${tone}`\">\n <slot />\n </span>\n</template>\n\n<script setup lang=\"ts\">\nimport { type PropType } from 'vue';\nimport { DS_BADGE_TONES, type DsBadgeTone } from './DsBadge.types';\n\ndefineProps({\n tone: {\n type: String as PropType<DsBadgeTone>,\n default: DS_BADGE_TONES.ACCENT,\n },\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n\n.ds-badge {\n display: inline-flex;\n align-items: center;\n\n height: 17px;\n padding: 0 8px;\n\n color: colors.$white;\n font-family: t.$font-family;\n font-weight: t.$weight-bold;\n font-size: t.font-size('caption');\n line-height: 17px;\n\n border-radius: r.$radius-pill;\n\n white-space: nowrap;\n\n /* ---------- Tones (solid fill, white text) ---------- */\n &--accent {\n background-color: colors.$accent-main;\n }\n &--grey {\n background-color: colors.$slate-soft;\n }\n &--info {\n background-color: colors.$info-main;\n }\n &--success {\n background-color: colors.$success-main;\n }\n &--error {\n background-color: colors.$error-main;\n }\n &--warning {\n background-color: colors.$warning-main;\n }\n}\n</style>\n","<template>\n <img\n v-if=\"image\"\n class=\"ds-avatar\"\n :class=\"{ 'is-circular': circular }\"\n :src=\"image\"\n :alt=\"alt\"\n :style=\"boxStyle\"\n />\n\n <div\n v-else-if=\"initials\"\n class=\"ds-avatar ds-avatar--initials\"\n :class=\"{ 'is-circular': circular }\"\n role=\"img\"\n :aria-label=\"ariaLabel || undefined\"\n :style=\"[\n boxStyle,\n { background: hashed.bg, color: hashed.fg, fontSize: `${Math.round(size * 0.4)}px` },\n ]\"\n >\n {{ initials }}\n </div>\n\n <div\n v-else\n class=\"ds-avatar ds-avatar--placeholder\"\n :class=\"{ 'is-circular': circular }\"\n :style=\"boxStyle\"\n aria-hidden=\"true\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\nconst props = defineProps({\n image: { type: String, default: '' },\n firstName: { type: String, default: '' },\n lastName: { type: String, default: '' },\n uid: { type: String, default: '' },\n size: { type: Number, default: 40 },\n circular: Boolean,\n // Accessible label (defaults to \"firstName lastName\").\n alt: { type: String, default: '' },\n});\n\nconst initials = computed(() =>\n props.firstName && props.lastName\n ? (props.firstName.charAt(0) + props.lastName.charAt(0)).toUpperCase()\n : ''\n);\n\nconst ariaLabel = computed(() => props.alt || `${props.firstName} ${props.lastName}`.trim());\n\nconst boxStyle = computed(() => ({ width: `${props.size}px`, height: `${props.size}px` }));\n\n// Deterministic color from a uid — exact port of SqlAvatar.getBackgroundColor.\nconst hashed = computed(() => {\n const seed = props.uid || props.firstName + props.lastName;\n let hash = 0;\n for (let i = 0; i < seed.length; i++) {\n hash = seed.charCodeAt(i) + ((hash << 5) - hash);\n hash = hash & hash;\n }\n const rgb = [0, 0, 0];\n for (let i = 0; i < 3; i++) rgb[i] = (hash >> (i * 8)) & 255;\n const light = rgb[0] >= 200 && rgb[1] >= 200 && rgb[2] >= 200;\n return { bg: `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`, fg: light ? '#323f4b' : '#fff' };\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n\n.ds-avatar {\n display: flex;\n flex: none;\n align-items: center;\n justify-content: center;\n\n overflow: hidden;\n object-fit: cover;\n\n border-radius: r.$radius-control;\n\n &.is-circular {\n border-radius: r.$radius-full;\n }\n\n &--initials {\n font-family: t.$font-family;\n font-weight: t.$weight-black;\n line-height: 1;\n user-select: none;\n }\n\n &--placeholder {\n background-color: #c0c4cc; // DS placeholder grey (Avatar.jsx)\n }\n}\n</style>\n","// DsTable — the DS data table (data-dense density). Column/row API with hairline\n// borders, row hover, and an optional highlighted \"most likely\" row.\n\nexport const DS_TABLE_ALIGN = {\n LEFT: 'left',\n CENTER: 'center',\n RIGHT: 'right',\n} as const;\nexport type DsTableAlign = (typeof DS_TABLE_ALIGN)[keyof typeof DS_TABLE_ALIGN];\n\n// A column. `key` maps to the row property for default content and names the\n// scoped slot `cell-<key>`.\nexport interface DsTableColumn {\n key: string;\n label: string;\n align?: DsTableAlign;\n width?: string;\n}\n\n// A row: only a stable `id` is required (for :key and highlighting); the rest of\n// the properties are consumed per column via its `key`.\nexport interface DsTableRow {\n id: string | number;\n [key: string]: unknown;\n}\n","<script setup lang=\"ts\">\nimport { type PropType } from 'vue';\nimport { DS_TABLE_ALIGN, type DsTableColumn, type DsTableRow } from './DsTable.types';\n\ndefineProps({\n columns: {\n type: Array as PropType<DsTableColumn[]>,\n required: true,\n },\n rows: {\n type: Array as PropType<DsTableRow[]>,\n required: true,\n },\n emptyMessage: {\n type: String,\n default: '',\n },\n // id of the row to highlight (the DS \"most likely\" row → accent surface).\n highlightRowId: {\n type: [String, Number] as PropType<string | number | null>,\n default: null,\n },\n});\n</script>\n\n<template>\n <div class=\"ds-table\">\n <div class=\"ds-table__wrapper\">\n <table class=\"ds-table__table\">\n <thead>\n <tr>\n <th\n v-for=\"column in columns\"\n :key=\"column.key\"\n :class=\"`ds-table__th--${column.align ?? DS_TABLE_ALIGN.LEFT}`\"\n :style=\"column.width ? { width: column.width } : undefined\"\n >\n {{ column.label }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr v-if=\"rows.length === 0\">\n <td class=\"ds-table__empty\" :colspan=\"columns.length\" data-testid=\"ds-table-empty\">\n <slot name=\"empty\">{{ emptyMessage }}</slot>\n </td>\n </tr>\n <tr\n v-for=\"row in rows\"\n :key=\"row.id\"\n :class=\"{ 'is-highlighted': row.id === highlightRowId }\"\n data-testid=\"ds-table-row\"\n >\n <td\n v-for=\"column in columns\"\n :key=\"column.key\"\n :class=\"`ds-table__td--${column.align ?? DS_TABLE_ALIGN.LEFT}`\"\n >\n <slot :name=\"`cell-${column.key}`\" :row=\"row\">{{ row[column.key] }}</slot>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/spacing.scss' as s;\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n@use '../../assets/css/motion.scss' as m;\n\n.ds-table {\n &__wrapper {\n overflow-x: auto;\n\n border: 1px solid colors.$slate-tint;\n border-radius: r.$radius-card-lg;\n }\n\n &__table {\n width: 100%;\n border-collapse: collapse;\n\n // Own every border/height explicitly so host-app global table rules can't\n // leak in; scoped specificity (block + [data-v]) beats them.\n th {\n padding: s.spacing(1) s.spacing(2);\n\n color: colors.$slate-main;\n font-weight: t.$weight-bold;\n font-size: t.font-size('body');\n\n border: 0;\n border-bottom: 1px solid colors.$slate-tint;\n\n background-color: colors.$slate-bg;\n }\n\n td {\n height: auto;\n padding: s.spacing(1) s.spacing(2);\n\n color: colors.$slate-main;\n font-size: t.font-size('body');\n\n border: 0;\n }\n\n tr {\n border: 0;\n transition: background-color m.$duration-default m.$easing;\n\n @include m.reduce-motion {\n transition: none;\n }\n }\n\n // Row separator only BETWEEN adjacent body rows.\n tbody tr + tr {\n border-top: 1px solid colors.$slate-tint;\n }\n\n // Row hover (data-dense affordance).\n tbody tr:hover {\n background-color: colors.$slate-bg;\n }\n\n // The highlighted \"most likely\" row wins over hover.\n tbody tr.is-highlighted {\n background-color: colors.$accent-bg;\n }\n tbody tr.is-highlighted:hover {\n background-color: colors.$accent-tint;\n }\n }\n\n &__th--left,\n &__td--left {\n text-align: left;\n }\n &__th--center,\n &__td--center {\n text-align: center;\n }\n &__th--right,\n &__td--right {\n text-align: right;\n }\n\n &__empty {\n padding: s.spacing(5) s.spacing(3);\n\n color: colors.$slate-soft;\n text-align: center;\n }\n}\n</style>\n","// DsInput — the DS \"Input\": single-line field. Prop vocabulary mirrors Input.jsx.\n// Border: primary-main at rest → accent on focus, coral on error. NO bold-on-focus\n// (the DS source keeps the text at weight 400). Sizes are the DS input heights.\n\nexport const DS_INPUT_TYPES = {\n TEXT: 'text',\n EMAIL: 'email',\n PASSWORD: 'password',\n TEL: 'tel',\n NUMBER: 'number',\n SEARCH: 'search',\n URL: 'url',\n} as const;\nexport type DsInputType = (typeof DS_INPUT_TYPES)[keyof typeof DS_INPUT_TYPES];\n\nexport const DS_INPUT_SIZES = {\n SM: 'sm', // 36px\n MD: 'md', // 48px\n} as const;\nexport type DsInputSize = (typeof DS_INPUT_SIZES)[keyof typeof DS_INPUT_SIZES];\n","<template>\n <div\n class=\"ds-input\"\n :class=\"[`ds-input--${size}`, { 'is-error': error, 'is-disabled': disabled }]\"\n >\n <div class=\"ds-input__wrap\">\n <input\n :id=\"id || undefined\"\n v-model=\"model\"\n class=\"ds-input__control\"\n :class=\"{ 'has-suffix': hasSuffix }\"\n :type=\"resolvedType\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :name=\"name || undefined\"\n :autocomplete=\"autocomplete || undefined\"\n :aria-invalid=\"error || undefined\"\n :aria-describedby=\"error && errorMessage && id ? `${id}-error` : undefined\"\n @focus=\"emit(FOCUS, $event)\"\n @blur=\"emit(BLUR, $event)\"\n />\n\n <div v-if=\"hasSuffix\" class=\"ds-input__suffix\">\n <slot name=\"suffix\" />\n\n <i\n v-if=\"error && showErrorIcon\"\n class=\"material-icons ds-input__error-icon\"\n aria-hidden=\"true\"\n >warning</i\n >\n\n <button\n v-else-if=\"isPassword\"\n type=\"button\"\n class=\"ds-input__toggle\"\n :aria-label=\"toggleLabel || undefined\"\n :aria-pressed=\"reveal\"\n @click=\"reveal = !reveal\"\n >\n <i class=\"material-icons\" aria-hidden=\"true\">{{\n reveal ? 'visibility' : 'visibility_off'\n }}</i>\n </button>\n </div>\n </div>\n\n <p v-if=\"error && errorMessage\" :id=\"id ? `${id}-error` : undefined\" class=\"ds-input__error\">\n {{ errorMessage }}\n </p>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, useSlots, type PropType } from 'vue';\nimport { FOCUS, BLUR } from '@shared/constants/events';\nimport {\n DS_INPUT_TYPES,\n DS_INPUT_SIZES,\n type DsInputType,\n type DsInputSize,\n} from './DsInput.types';\n\nconst model = defineModel<string>({ default: '' });\n\nconst props = defineProps({\n type: { type: String as PropType<DsInputType>, default: DS_INPUT_TYPES.TEXT },\n size: { type: String as PropType<DsInputSize>, default: DS_INPUT_SIZES.SM },\n placeholder: { type: String, default: '' },\n disabled: Boolean,\n error: Boolean,\n errorMessage: { type: String, default: '' },\n showErrorIcon: Boolean,\n name: { type: String, default: '' },\n id: { type: String, default: '' },\n autocomplete: { type: String, default: '' },\n // Accessible name for the password visibility toggle.\n toggleLabel: { type: String, default: '' },\n});\n\nconst emit = defineEmits([FOCUS, BLUR]);\n\nconst slots = useSlots();\nconst reveal = ref(false);\nconst isPassword = computed(() => props.type === DS_INPUT_TYPES.PASSWORD);\nconst resolvedType = computed(() =>\n isPassword.value && reveal.value ? DS_INPUT_TYPES.TEXT : props.type\n);\nconst hasSuffix = computed(\n () => !!slots.suffix || (props.error && props.showErrorIcon) || isPassword.value\n);\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n@use '../../assets/css/motion.scss' as m;\n@use '../../assets/css/icons.scss' as i;\n\n.ds-input {\n display: block;\n width: 100%;\n\n &__wrap {\n position: relative;\n width: 100%;\n }\n\n &__control {\n box-sizing: border-box;\n width: 100%;\n padding: 0 16px;\n\n color: colors.$slate-main;\n font-family: t.$font-family;\n font-size: t.font-size('body');\n font-weight: t.$weight-regular;\n line-height: 20px;\n\n background-color: colors.$white;\n\n /* Border: primary-main at rest → accent on focus (see precedence below). */\n border: 1px solid colors.$slate-main;\n border-radius: r.$radius-control;\n outline: none;\n\n transition: border-color m.$duration-default m.$easing;\n\n @include m.reduce-motion {\n transition: none;\n }\n\n &.has-suffix {\n padding-right: 50px;\n }\n\n &:focus {\n border-color: colors.$accent-main;\n }\n\n &::placeholder {\n color: colors.$slate-soft;\n }\n }\n\n &__suffix {\n position: absolute;\n top: 0;\n right: 0;\n\n display: flex;\n align-items: center;\n gap: 4px;\n\n height: 100%;\n padding: 0 16px;\n\n color: colors.$slate-soft;\n }\n\n &__toggle {\n display: inline-flex;\n padding: 0;\n\n color: inherit;\n\n background: transparent;\n border: 0;\n\n cursor: pointer;\n }\n\n &__error-icon {\n color: colors.$error-main;\n }\n\n &__error {\n margin-top: 2px;\n\n color: colors.$error-main;\n font-family: t.$font-family;\n font-weight: t.$weight-bold;\n font-size: t.font-size('caption');\n line-height: 18px;\n }\n\n /* ---------- Sizes (DS input heights + icon sizes) ---------- */\n &--sm {\n .ds-input__control {\n height: 36px;\n }\n .material-icons {\n font-size: i.icon-size(20);\n }\n }\n &--md {\n .ds-input__control {\n height: 48px;\n }\n .material-icons {\n font-size: i.icon-size(24);\n }\n }\n\n /* ---------- States (precedence: rest → focus → disabled → error) ---------- */\n &.is-disabled .ds-input__control {\n color: colors.$slate-mid;\n background-color: colors.$slate-bg;\n border-color: colors.$slate-mid;\n cursor: not-allowed;\n }\n &.is-error .ds-input__control,\n &.is-error .ds-input__control:focus {\n border-color: colors.$error-main;\n }\n}\n</style>\n","<template>\n <div class=\"ds-textarea\" :class=\"{ 'is-error': error, 'is-disabled': disabled }\">\n <textarea\n :id=\"id || undefined\"\n v-model=\"model\"\n class=\"ds-textarea__control\"\n :placeholder=\"placeholder\"\n :rows=\"rows\"\n :disabled=\"disabled\"\n :name=\"name || undefined\"\n :aria-invalid=\"error || undefined\"\n :aria-describedby=\"error && errorMessage && id ? `${id}-error` : undefined\"\n @focus=\"emit(FOCUS, $event)\"\n @blur=\"emit(BLUR, $event)\"\n />\n <p v-if=\"error && errorMessage\" :id=\"id ? `${id}-error` : undefined\" class=\"ds-textarea__error\">\n {{ errorMessage }}\n </p>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { FOCUS, BLUR } from '@shared/constants/events';\n\nconst model = defineModel<string>({ default: '' });\n\ndefineProps({\n placeholder: { type: String, default: '' },\n rows: { type: Number, default: 4 },\n disabled: Boolean,\n error: Boolean,\n errorMessage: { type: String, default: '' },\n name: { type: String, default: '' },\n id: { type: String, default: '' },\n});\n\nconst emit = defineEmits([FOCUS, BLUR]);\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n@use '../../assets/css/motion.scss' as m;\n\n.ds-textarea {\n display: block;\n width: 100%;\n\n &__control {\n box-sizing: border-box;\n width: 100%;\n padding: 12px 16px;\n\n color: colors.$slate-main;\n font-family: t.$font-family;\n font-size: t.font-size('body');\n line-height: 20px;\n\n background-color: colors.$white;\n\n border: 1px solid colors.$slate-main;\n border-radius: r.$radius-control;\n outline: none;\n\n resize: vertical;\n transition: border-color m.$duration-default m.$easing;\n\n @include m.reduce-motion {\n transition: none;\n }\n\n &:focus {\n border-color: colors.$accent-main;\n }\n\n &::placeholder {\n color: colors.$slate-soft;\n }\n }\n\n &__error {\n margin-top: 2px;\n\n color: colors.$error-main;\n font-family: t.$font-family;\n font-weight: t.$weight-bold;\n font-size: t.font-size('caption');\n line-height: 18px;\n }\n\n &.is-disabled .ds-textarea__control {\n color: colors.$slate-mid;\n background-color: colors.$slate-bg;\n border-color: colors.$slate-mid;\n cursor: not-allowed;\n }\n &.is-error .ds-textarea__control,\n &.is-error .ds-textarea__control:focus {\n border-color: colors.$error-main;\n }\n}\n</style>\n","<template>\n <label class=\"ds-checkbox\" :class=\"{ 'is-disabled': disabled }\">\n <input\n ref=\"inputRef\"\n v-model=\"model\"\n type=\"checkbox\"\n class=\"ds-checkbox__native\"\n :disabled=\"disabled\"\n :name=\"name || undefined\"\n />\n <span\n class=\"ds-checkbox__box\"\n :class=\"{ 'is-active': model || indeterminate }\"\n aria-hidden=\"true\"\n >\n <svg\n v-if=\"indeterminate\"\n class=\"ds-checkbox__mark\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n >\n <line x1=\"4\" y1=\"8\" x2=\"12\" y2=\"8\" />\n </svg>\n <svg\n v-else-if=\"model\"\n class=\"ds-checkbox__mark\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n >\n <path d=\"M3.5 8.5l3 3 6-6\" />\n </svg>\n </span>\n <span v-if=\"$slots.default || label\" class=\"ds-checkbox__label\"\n ><slot>{{ label }}</slot></span\n >\n </label>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted, watch } from 'vue';\n\nconst model = defineModel<boolean>({ default: false });\n\nconst props = defineProps({\n indeterminate: Boolean,\n disabled: Boolean,\n name: { type: String, default: '' },\n // Label text (DS `label` prop); a default slot overrides it.\n label: { type: String, default: '' },\n});\n\nconst inputRef = ref<HTMLInputElement | null>(null);\n\n// `indeterminate` is a DOM property, not an attribute — keep it in sync for a11y.\nfunction syncIndeterminate() {\n if (inputRef.value) inputRef.value.indeterminate = props.indeterminate;\n}\nonMounted(syncIndeterminate);\nwatch(() => props.indeterminate, syncIndeterminate);\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/spacing.scss' as s;\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n@use '../../assets/css/motion.scss' as m;\n\n.ds-checkbox {\n display: inline-flex;\n align-items: center;\n gap: s.spacing(1);\n\n color: colors.$slate-main;\n font-family: t.$font-family;\n font-size: t.font-size('body');\n\n cursor: pointer;\n\n &.is-disabled {\n color: colors.$slate-soft;\n cursor: not-allowed;\n }\n\n /* Native control drives state + focus, visually replaced by the custom box. */\n &__native {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n }\n\n &__box {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n\n width: 18px;\n height: 18px;\n\n color: colors.$white;\n\n background-color: colors.$white;\n\n border: 1px solid colors.$slate-mid;\n border-radius: r.$radius-control;\n\n transition:\n background-color m.$duration-default m.$easing,\n border-color m.$duration-default m.$easing;\n\n @include m.reduce-motion {\n transition: none;\n }\n\n &.is-active {\n background-color: colors.$accent-main;\n border-color: colors.$accent-main;\n }\n }\n\n /* Focus ring on the box when the (hidden) native input is focused. */\n &__native:focus-visible + &__box {\n outline: 2px solid colors.$accent-mid;\n outline-offset: 1px;\n }\n\n &__mark {\n width: 14px;\n height: 14px;\n }\n\n &__label {\n line-height: 1.3;\n }\n}\n</style>\n","// DsAlert — the DS inline banner (Alert.jsx). type × effect (light tint / dark solid).\n\nexport const DS_ALERT_TYPES = {\n SUCCESS: 'success',\n INFO: 'info',\n WARNING: 'warning',\n ERROR: 'error',\n} as const;\nexport type DsAlertType = (typeof DS_ALERT_TYPES)[keyof typeof DS_ALERT_TYPES];\n\nexport const DS_ALERT_EFFECTS = {\n LIGHT: 'light', // tinted: family tint bg + mid border + shadow text\n DARK: 'dark', // solid: family shadow bg + white text\n} as const;\nexport type DsAlertEffect = (typeof DS_ALERT_EFFECTS)[keyof typeof DS_ALERT_EFFECTS];\n\n// Material Icon per type (leading icon when showIcon).\nexport const DS_ALERT_ICONS: Record<DsAlertType, string> = {\n success: 'check_circle',\n info: 'info',\n warning: 'warning',\n error: 'error',\n};\n","<template>\n <div\n v-if=\"visible\"\n class=\"ds-alert\"\n :class=\"[`ds-alert--${type}`, `ds-alert--${effect}`, { 'is-center': center }]\"\n role=\"alert\"\n >\n <i v-if=\"showIcon\" class=\"material-icons ds-alert__icon\" aria-hidden=\"true\">{{ icon }}</i>\n\n <div class=\"ds-alert__content\">\n <div v-if=\"title\" class=\"ds-alert__title\" :class=\"{ 'has-body': hasBody }\">{{ title }}</div>\n <div v-if=\"hasBody\" class=\"ds-alert__body\">\n <slot>{{ description }}</slot>\n </div>\n </div>\n\n <button\n v-if=\"closable\"\n type=\"button\"\n class=\"ds-alert__close\"\n :aria-label=\"closeLabel || undefined\"\n @click=\"onClose\"\n >\n <i class=\"material-icons\" aria-hidden=\"true\">close</i>\n </button>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, useSlots, type PropType } from 'vue';\nimport { CLOSE } from '@shared/constants/events';\nimport {\n DS_ALERT_TYPES,\n DS_ALERT_EFFECTS,\n DS_ALERT_ICONS,\n type DsAlertType,\n type DsAlertEffect,\n} from './DsAlert.types';\n\nconst props = defineProps({\n type: { type: String as PropType<DsAlertType>, default: DS_ALERT_TYPES.INFO },\n effect: { type: String as PropType<DsAlertEffect>, default: DS_ALERT_EFFECTS.LIGHT },\n title: { type: String, default: '' },\n description: { type: String, default: '' },\n showIcon: Boolean,\n closable: Boolean,\n center: Boolean,\n closeLabel: { type: String, default: '' },\n});\n\nconst emit = defineEmits([CLOSE]);\n\nconst slots = useSlots();\nconst visible = ref(true);\nconst icon = computed(() => DS_ALERT_ICONS[props.type]);\nconst hasBody = computed(() => !!slots.default || props.description.length > 0);\n\nfunction onClose() {\n visible.value = false;\n emit(CLOSE);\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n@use '../../assets/css/icons.scss' as i;\n\n.ds-alert {\n position: relative;\n\n display: flex;\n align-items: center;\n\n padding: 8px 16px;\n\n font-family: t.$font-family;\n\n border: 1px solid transparent;\n border-radius: r.$radius-control;\n\n &.is-center {\n justify-content: center;\n }\n\n &__icon {\n margin-right: 8px;\n // Status glyph uses the DS default icon size (md-20) for presence next to the\n // 13px title; the close ✕ below stays at 14 (discreet secondary action).\n font-size: i.icon-size(20);\n }\n\n &__content {\n flex: 1;\n padding: 0 8px;\n }\n\n &__title {\n font-size: t.font-size('small');\n font-weight: t.$weight-regular;\n line-height: 18px;\n\n &.has-body {\n font-weight: t.$weight-bold;\n }\n }\n\n &__body {\n margin-top: 5px;\n font-size: t.font-size('caption');\n }\n\n &__title.has-body + .ds-alert__body {\n margin-top: 5px;\n }\n\n &__close {\n display: inline-flex;\n padding: 0;\n\n color: inherit;\n\n background: transparent;\n border: 0;\n\n cursor: pointer;\n\n .material-icons {\n font-size: i.icon-size(14);\n }\n }\n\n /* ---------- light (tinted) — bg tint + mid border + shadow text ---------- */\n &--light {\n &.ds-alert--success {\n color: colors.$success-shadow;\n border-color: colors.$success-mid;\n background-color: colors.$success-tint;\n }\n &.ds-alert--info {\n color: colors.$info-shadow;\n border-color: colors.$info-mid;\n background-color: colors.$info-tint;\n }\n &.ds-alert--warning {\n color: colors.$warning-shadow;\n border-color: colors.$warning-mid;\n background-color: colors.$warning-tint;\n }\n &.ds-alert--error {\n color: colors.$error-shadow;\n border-color: colors.$error-mid;\n background-color: colors.$error-tint;\n }\n }\n\n /* ---------- dark (solid) — bg shadow + white text ---------- */\n &--dark {\n color: colors.$white;\n border-color: transparent;\n\n &.ds-alert--success {\n background-color: colors.$success-shadow;\n }\n &.ds-alert--info {\n background-color: colors.$info-shadow;\n }\n &.ds-alert--warning {\n background-color: colors.$warning-shadow;\n }\n &.ds-alert--error {\n background-color: colors.$error-shadow;\n }\n }\n}\n</style>\n","// DsNotification — the DS toast card (Notification.jsx). Fixed-position, 3 types.\n\nexport const DS_NOTIFICATION_TYPES = {\n INFO: 'info',\n WARNING: 'warning',\n ERROR: 'error',\n} as const;\nexport type DsNotificationType = (typeof DS_NOTIFICATION_TYPES)[keyof typeof DS_NOTIFICATION_TYPES];\n\nexport const DS_NOTIFICATION_POSITIONS = {\n TOP_LEFT: 'top-left',\n TOP_RIGHT: 'top-right',\n BOTTOM_LEFT: 'bottom-left',\n BOTTOM_RIGHT: 'bottom-right',\n} as const;\nexport type DsNotificationPosition =\n (typeof DS_NOTIFICATION_POSITIONS)[keyof typeof DS_NOTIFICATION_POSITIONS];\n\n// Material Icon per type (Notification.jsx).\nexport const DS_NOTIFICATION_ICONS: Record<DsNotificationType, string> = {\n info: 'mode_edit',\n warning: 'warning',\n error: 'warning',\n};\n","<template>\n <Teleport to=\"body\">\n <div v-if=\"visible\" class=\"ds-notification\" :class=\"`ds-notification--${position}`\">\n <div class=\"ds-notification__card\" :class=\"`ds-notification__card--${type}`\" role=\"alert\">\n <i class=\"material-icons ds-notification__icon\" aria-hidden=\"true\">{{ icon }}</i>\n\n <div class=\"ds-notification__content\">\n <span v-if=\"title\" class=\"ds-notification__title\">{{ title }}</span>\n <p v-if=\"description\" class=\"ds-notification__desc\">{{ description }}</p>\n <a\n v-if=\"linkTitle\"\n class=\"ds-notification__link\"\n :href=\"link || undefined\"\n target=\"_blank\"\n rel=\"noreferrer\"\n >{{ linkTitle }}</a\n >\n </div>\n\n <button\n v-if=\"showClose\"\n type=\"button\"\n class=\"ds-notification__close\"\n :aria-label=\"closeLabel || undefined\"\n @click=\"onClose\"\n >\n <i class=\"material-icons\" aria-hidden=\"true\">close</i>\n </button>\n </div>\n </div>\n </Teleport>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, type PropType } from 'vue';\nimport { CLOSE } from '@shared/constants/events';\nimport {\n DS_NOTIFICATION_TYPES,\n DS_NOTIFICATION_POSITIONS,\n DS_NOTIFICATION_ICONS,\n type DsNotificationType,\n type DsNotificationPosition,\n} from './DsNotification.types';\n\nconst props = defineProps({\n type: { type: String as PropType<DsNotificationType>, default: DS_NOTIFICATION_TYPES.INFO },\n position: {\n type: String as PropType<DsNotificationPosition>,\n default: DS_NOTIFICATION_POSITIONS.BOTTOM_LEFT,\n },\n title: { type: String, default: '' },\n description: { type: String, default: '' },\n linkTitle: { type: String, default: '' },\n link: { type: String, default: '' },\n showClose: { type: Boolean, default: true },\n closeLabel: { type: String, default: '' },\n});\n\nconst emit = defineEmits([CLOSE]);\n\nconst visible = ref(true);\nconst icon = computed(() => DS_NOTIFICATION_ICONS[props.type]);\n\nfunction onClose() {\n visible.value = false;\n emit(CLOSE);\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n@use '../../assets/css/shadow.scss' as sh;\n@use '../../assets/css/icons.scss' as i;\n\n.ds-notification {\n position: fixed;\n z-index: 2000;\n\n &--top-left {\n top: 0;\n left: 0;\n }\n &--top-right {\n top: 0;\n right: 0;\n }\n &--bottom-left {\n bottom: 0;\n left: 0;\n }\n &--bottom-right {\n bottom: 0;\n right: 0;\n }\n\n &__card {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n\n max-width: 331px;\n margin: 24px;\n padding: 16px;\n\n border: 1px solid transparent;\n border-radius: r.$radius-card-lg;\n\n box-shadow: sh.$shadow-soft;\n\n &--info {\n background-color: colors.$info-tint;\n border-color: rgba(colors.$info-main, 0.7);\n\n .ds-notification__icon {\n color: colors.$info-main;\n }\n }\n &--warning {\n background-color: colors.$warning-tint;\n border-color: rgba(colors.$warning-main, 0.7);\n\n .ds-notification__icon {\n color: colors.$warning-main;\n }\n }\n &--error {\n background-color: colors.$error-tint;\n border-color: rgba(colors.$error-main, 0.7);\n\n .ds-notification__icon {\n color: colors.$error-main;\n }\n }\n }\n\n &__icon {\n font-size: i.icon-size(20);\n }\n\n &__content {\n display: flex;\n flex-direction: column;\n\n color: colors.$slate-shadow;\n font-family: t.$font-family;\n font-size: t.font-size('body');\n line-height: 21px;\n }\n\n &__title {\n font-weight: t.$weight-bold;\n }\n\n &__desc {\n margin: 0;\n padding-top: 8px;\n }\n\n &__link {\n padding-top: 8px;\n\n color: colors.$accent-main;\n text-decoration: underline;\n }\n\n &__close {\n display: inline-flex;\n margin-left: auto;\n padding: 0;\n\n color: colors.$slate-soft;\n\n background: transparent;\n border: 0;\n\n cursor: pointer;\n\n .material-icons {\n font-size: i.icon-size(20);\n }\n }\n}\n</style>\n","<template>\n <Teleport to=\"body\">\n <div v-if=\"open\" class=\"ds-modal\" @click=\"onBackdrop\">\n <div\n ref=\"dialogRef\"\n class=\"ds-modal__dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-label=\"title || 'dialog'\"\n tabindex=\"-1\"\n :style=\"{ width }\"\n @click.stop\n >\n <div v-if=\"title || showClose\" class=\"ds-modal__header\">\n <span class=\"ds-modal__title\">{{ title }}</span>\n <DsButton\n v-if=\"showClose\"\n variant=\"tertiary\"\n circle\n left-icon=\"close\"\n :aria-label=\"closeLabel || undefined\"\n @click=\"emit(CLOSE)\"\n />\n </div>\n\n <div class=\"ds-modal__body\"><slot /></div>\n\n <div v-if=\"$slots.footer\" class=\"ds-modal__footer\"><slot name=\"footer\" /></div>\n </div>\n </div>\n </Teleport>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch, nextTick, onBeforeUnmount } from 'vue';\nimport { DsButton } from '@shared/ui/DsButton';\nimport { CLOSE } from '@shared/constants/events';\n\nconst props = defineProps({\n open: Boolean,\n title: { type: String, default: '' },\n showClose: { type: Boolean, default: true },\n width: { type: String, default: '440px' },\n closeOnBackdrop: { type: Boolean, default: true },\n closeLabel: { type: String, default: '' },\n});\n\nconst emit = defineEmits([CLOSE]);\n\nconst dialogRef = ref<HTMLElement | null>(null);\nlet lastFocused: HTMLElement | null = null;\n\nfunction onBackdrop() {\n if (props.closeOnBackdrop) emit(CLOSE);\n}\n\nfunction focusables(): HTMLElement[] {\n if (!dialogRef.value) return [];\n const sel =\n 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n return Array.from(dialogRef.value.querySelectorAll<HTMLElement>(sel)).filter(\n (el) => el.offsetParent !== null\n );\n}\n\nfunction onKeydown(e: KeyboardEvent) {\n if (e.key === 'Escape') {\n emit(CLOSE);\n return;\n }\n if (e.key !== 'Tab') return;\n const f = focusables();\n if (f.length === 0) {\n e.preventDefault();\n dialogRef.value?.focus();\n return;\n }\n const first = f[0];\n const last = f[f.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n}\n\nwatch(\n () => props.open,\n (open) => {\n if (typeof document === 'undefined') return;\n if (open) {\n lastFocused = document.activeElement as HTMLElement;\n document.addEventListener('keydown', onKeydown);\n document.body.style.overflow = 'hidden';\n nextTick(() => (focusables()[0] ?? dialogRef.value)?.focus());\n } else {\n document.removeEventListener('keydown', onKeydown);\n document.body.style.overflow = '';\n lastFocused?.focus?.();\n }\n },\n { immediate: true }\n);\n\nonBeforeUnmount(() => {\n if (typeof document === 'undefined') return;\n document.removeEventListener('keydown', onKeydown);\n document.body.style.overflow = '';\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n@use '../../assets/css/shadow.scss' as sh;\n\n.ds-modal {\n position: fixed;\n inset: 0;\n z-index: 2001;\n\n display: flex;\n align-items: flex-start;\n justify-content: center;\n\n padding: 15vh 16px 50px;\n overflow: auto;\n\n background: colors.$backdrop; // grey-10 @ 50%, no blur\n\n &__dialog {\n max-width: 100%;\n\n background: colors.$white;\n\n border-radius: r.$radius-card;\n box-shadow: sh.$shadow-card;\n\n padding: 8px;\n\n outline: none;\n }\n\n &__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n\n min-height: 36px;\n padding: 8px 0 8px 12px;\n\n color: colors.$slate-main;\n font-family: t.$font-family;\n font-size: t.font-size('body');\n font-weight: t.$weight-bold;\n\n border-bottom: 1px solid colors.$slate-tint;\n }\n\n &__body {\n padding: 20px;\n\n color: colors.$slate-main;\n font-family: t.$font-family;\n font-size: t.font-size('body');\n }\n\n &__footer {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n\n padding: 8px;\n\n border-top: 1px solid colors.$slate-tint;\n }\n}\n</style>\n","// DsVerificationIcon — status glyph for a contact data point.\n// 1:1 with the DS source (components/data/VerificationIcon.jsx):\n// verified === true -> \"verified\" (info-main, blue)\n// verified === false + email -> \"dangerous\" (error-main, coral)\n// verified === false + phone -> \"error\" (warning-main, orange)\n// verified == null (new) -> \"new_releases\" (slate-soft, grey)\n// `isContactData` flags emails (coral) vs phones (orange) when unverified.\n\nexport const DS_VERIFICATION_STATES = {\n VERIFIED: 'verified',\n UNVERIFIED: 'unverified',\n NEW: 'new',\n} as const;\nexport type DsVerificationState =\n (typeof DS_VERIFICATION_STATES)[keyof typeof DS_VERIFICATION_STATES];\n","<template>\n <i\n class=\"material-icons ds-verification-icon\"\n :class=\"[\n `ds-verification-icon--${status.state}`,\n { 'ds-verification-icon--email': isContactData },\n ]\"\n :style=\"{ fontSize: `${size}px` }\"\n role=\"img\"\n :aria-label=\"label || status.label\"\n :title=\"label || status.label\"\n >\n <slot>{{ status.icon }}</slot>\n </i>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, type PropType } from 'vue';\nimport { DS_VERIFICATION_STATES } from './DsVerificationIcon.types';\n\nconst props = defineProps({\n // true = verified · false = not verified · null/undefined = newly found.\n verified: {\n type: Boolean as PropType<boolean | null>,\n default: null,\n },\n // Emails (true) use the coral \"dangerous\" glyph when unverified; phones use orange.\n isContactData: {\n type: Boolean,\n default: false,\n },\n size: {\n type: Number,\n default: 20,\n },\n // Optional override for the accessible label / tooltip (the app owns i18n).\n // Empty → the English default derived from the verification state.\n label: {\n type: String,\n default: '',\n },\n});\n\nconst status = computed(() => {\n if (props.verified === null || props.verified === undefined) {\n return {\n state: DS_VERIFICATION_STATES.NEW,\n icon: 'new_releases',\n label: 'Newly found',\n };\n }\n if (props.verified) {\n return {\n state: DS_VERIFICATION_STATES.VERIFIED,\n icon: 'verified',\n label: 'Verified',\n };\n }\n return {\n state: DS_VERIFICATION_STATES.UNVERIFIED,\n icon: props.isContactData ? 'dangerous' : 'error',\n label: 'Not verified',\n };\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n\n.ds-verification-icon {\n line-height: 1;\n\n // States map DS colors (VerificationIcon.jsx). isContactData splits the\n // unverified color into coral (email) vs orange (phone).\n &--new {\n color: colors.$slate-soft; // --primary-secondary-text\n }\n &--verified {\n color: colors.$info-main;\n }\n &--unverified {\n color: colors.$warning-main; // phone (orange)\n\n &.ds-verification-icon--email {\n color: colors.$error-main; // email (coral \"dangerous\")\n }\n }\n}\n</style>\n","<template>\n <div class=\"ds-contact-value\" :class=\"{ 'ds-contact-value--main': main }\">\n <DsVerificationIcon :verified=\"verified\" :is-contact-data=\"isContactData\" />\n\n <span class=\"ds-contact-value__value\" :title=\"value\">{{ value }}</span>\n\n <!-- Marquee slot: badge and actions share one grid cell and cross-fade/slide\n on hover (or keyboard focus-within). -->\n <span class=\"ds-contact-value__marquee\">\n <DsBadge\n v-if=\"valueType\"\n class=\"ds-contact-value__badge\"\n :tone=\"main ? DS_BADGE_TONES.ACCENT : DS_BADGE_TONES.GREY\"\n aria-hidden=\"true\"\n >{{ valueType }}</DsBadge\n >\n\n <span class=\"ds-contact-value__actions\">\n <button\n type=\"button\"\n class=\"ds-contact-value__action\"\n :class=\"{ 'is-copied': copied }\"\n :aria-label=\"copied ? copiedLabel : copyLabel\"\n :title=\"copied ? copiedLabel : copyLabel\"\n @click=\"handleCopy\"\n >\n <i class=\"material-icons\" aria-hidden=\"true\">{{ copied ? 'check' : 'content_copy' }}</i>\n </button>\n\n <template v-if=\"showRate\">\n <button\n type=\"button\"\n class=\"ds-contact-value__action\"\n :class=\"{ 'is-active': correct === true }\"\n :aria-label=\"correctLabel\"\n :aria-pressed=\"correct === true\"\n :title=\"correctLabel\"\n @click=\"handleCorrect\"\n >\n <i\n :class=\"correct === true ? 'material-icons' : 'material-icons-outlined'\"\n aria-hidden=\"true\"\n >thumb_up</i\n >\n </button>\n <button\n type=\"button\"\n class=\"ds-contact-value__action\"\n :class=\"{ 'is-active': correct === false }\"\n :aria-label=\"incorrectLabel\"\n :aria-pressed=\"correct === false\"\n :title=\"incorrectLabel\"\n @click=\"handleIncorrect\"\n >\n <i\n :class=\"correct === false ? 'material-icons' : 'material-icons-outlined'\"\n aria-hidden=\"true\"\n >thumb_down</i\n >\n </button>\n </template>\n </span>\n </span>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onBeforeUnmount, type PropType } from 'vue';\nimport { DsVerificationIcon } from '@shared/ui/DsVerificationIcon';\nimport { DsBadge, DS_BADGE_TONES } from '@shared/ui/DsBadge';\nimport { COPY, CORRECT, INCORRECT } from '@shared/constants/events';\n\nconst props = defineProps({\n value: { type: String, required: true },\n valueType: { type: String, default: '' },\n verified: { type: Boolean as PropType<boolean | null>, default: null },\n main: { type: Boolean, default: false },\n isContactData: { type: Boolean, default: false },\n showRate: { type: Boolean, default: false },\n correct: { type: Boolean as PropType<boolean | null>, default: null },\n // User-facing labels (the app owns i18n); English DS defaults.\n copyLabel: { type: String, default: 'Copy' },\n copiedLabel: { type: String, default: 'Copied!' },\n correctLabel: { type: String, default: 'Correct' },\n incorrectLabel: { type: String, default: 'Incorrect' },\n});\n\n// Runtime array so the emit names are registered at runtime (the type-only\n// form with `typeof CONST` compiles to an empty `emits`, which lets listeners\n// fall through as native attrs). Names come from the shared events constants.\nconst emit = defineEmits([COPY, CORRECT, INCORRECT]);\n\nconst copied = ref(false);\nlet copiedTimer: ReturnType<typeof setTimeout> | undefined;\n\nfunction handleCopy() {\n if (typeof navigator !== 'undefined' && navigator.clipboard) {\n navigator.clipboard.writeText(props.value).catch(() => {});\n }\n copied.value = true;\n clearTimeout(copiedTimer);\n copiedTimer = setTimeout(() => {\n copied.value = false;\n }, 1200);\n emit(COPY, props.value);\n}\n\nfunction handleCorrect() {\n emit(CORRECT);\n}\nfunction handleIncorrect() {\n emit(INCORRECT);\n}\n\nonBeforeUnmount(() => clearTimeout(copiedTimer));\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n@use '../../assets/css/motion.scss' as m;\n@use '../../assets/css/icons.scss' as i;\n\n.ds-contact-value {\n display: flex;\n align-items: center;\n\n padding: 6px; // DS ContactValue.jsx\n border-radius: r.$radius-control;\n\n background: transparent;\n transition: background-color m.$duration-default m.$easing;\n\n @include m.reduce-motion {\n transition: none;\n }\n\n &:hover,\n &:focus-within {\n background-color: colors.$slate-bg; // --primary-background\n }\n\n &--main:hover,\n &--main:focus-within {\n background-color: colors.$accent-bg;\n }\n\n // -- value ---------------------------------------------------------------\n &__value {\n flex: 1;\n min-width: 0;\n margin: 0 8px; // DS\n\n color: colors.$slate-main; // --primary-main\n font-family: t.$font-family;\n font-size: t.font-size('body');\n\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n // -- marquee (badge + actions share one cell) ----------------------------\n &__marquee {\n display: inline-grid;\n align-items: center;\n justify-items: end;\n margin-left: auto;\n }\n\n &__badge,\n &__actions {\n grid-area: 1 / 1;\n transition:\n transform m.$duration-reveal m.$easing,\n opacity m.$duration-reveal m.$easing;\n\n @include m.reduce-motion {\n transition: none;\n }\n }\n\n // At rest: badge in place, actions parked to the right and hidden.\n &__badge {\n transform: translateX(0);\n opacity: 1;\n }\n &__actions {\n display: inline-flex;\n align-items: center;\n gap: 8px; // DS\n\n transform: translateX(8px);\n opacity: 0;\n pointer-events: none;\n }\n\n // On hover / keyboard focus: badge slides out, actions slide in.\n &:hover &__badge,\n &:focus-within &__badge {\n transform: translateX(8px);\n opacity: 0;\n }\n &:hover &__actions,\n &:focus-within &__actions {\n transform: translateX(0);\n opacity: 1;\n pointer-events: auto;\n }\n\n // -- action buttons ------------------------------------------------------\n &__action {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n padding: 0;\n border: none;\n background: none;\n cursor: pointer;\n\n color: colors.$slate-soft; // --primary-secondary-text\n\n .material-icons,\n .material-icons-outlined {\n font-size: i.icon-size(20);\n line-height: 1;\n }\n\n &.is-copied {\n color: colors.$success-shadow;\n }\n }\n}\n</style>\n","<template>\n <section class=\"ds-data-card\" :aria-label=\"title\">\n <!-- header -->\n <div\n class=\"ds-data-card__header\"\n :class=\"{ 'is-collapsed': isCollapsed, 'is-collapsible': collapsible }\"\n @click=\"collapsible && toggle()\"\n >\n <div class=\"ds-data-card__heading\">\n <i class=\"material-icons ds-data-card__icon\" aria-hidden=\"true\">{{ icon }}</i>\n <span class=\"ds-data-card__title\">{{ title }}</span>\n </div>\n\n <div class=\"ds-data-card__actions\" @click.stop>\n <button\n v-if=\"!isCollapsed && showEdit\"\n type=\"button\"\n class=\"ds-data-card__edit\"\n @click=\"onEdit\"\n >\n {{ editLabel }}\n </button>\n\n <DsButton\n v-if=\"!isCollapsed && showSort\"\n variant=\"tertiary\"\n size=\"medium\"\n circle\n left-icon=\"swap_vert\"\n :aria-label=\"sortLabel\"\n @click=\"onSort\"\n />\n\n <DsButton\n v-if=\"collapsible\"\n variant=\"tertiary\"\n size=\"medium\"\n circle\n :left-icon=\"collapsed ? 'keyboard_arrow_down' : 'keyboard_arrow_up'\"\n :aria-label=\"toggleLabel\"\n @click=\"toggle\"\n />\n\n <button\n v-if=\"showClose\"\n type=\"button\"\n class=\"ds-data-card__close\"\n :aria-label=\"closeLabel\"\n @click=\"onClose\"\n >\n <i class=\"material-icons\" aria-hidden=\"true\">close</i>\n </button>\n </div>\n </div>\n\n <!-- body -->\n <div v-if=\"!isCollapsed\" class=\"ds-data-card__body\">\n <div v-if=\"empty\" class=\"ds-data-card__empty\">\n <i class=\"material-icons-outlined ds-data-card__empty-icon\" aria-hidden=\"true\">{{\n icon\n }}</i>\n <span>{{ emptyLabel }}</span>\n </div>\n\n <template v-else>\n <div v-if=\"mostLikely\">\n <div v-if=\"showSections\" class=\"ds-data-card__section\">{{ mostLikelyLabel }}</div>\n <DsContactValue\n :value=\"mostLikely.value\"\n :value-type=\"mostLikely.type\"\n :verified=\"mostLikely.verified\"\n :correct=\"mostLikely.correct\"\n main\n :is-contact-data=\"isContactData\"\n :show-rate=\"showRate\"\n @copy=\"onCopy\"\n @correct=\"onCorrect(mostLikely)\"\n @incorrect=\"onIncorrect(mostLikely)\"\n />\n </div>\n\n <div v-if=\"more.length > 0\">\n <div v-if=\"showSections\" class=\"ds-data-card__section\">{{ moreLabel }}</div>\n <div class=\"ds-data-card__more\">\n <DsContactValue\n v-for=\"datum in more\"\n :key=\"datum.value\"\n :value=\"datum.value\"\n :value-type=\"datum.type\"\n :verified=\"datum.verified\"\n :correct=\"datum.correct\"\n :is-contact-data=\"isContactData\"\n :show-rate=\"showRate\"\n @copy=\"onCopy\"\n @correct=\"onCorrect(datum)\"\n @incorrect=\"onIncorrect(datum)\"\n />\n </div>\n </div>\n </template>\n </div>\n </section>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, type PropType } from 'vue';\nimport { DsButton } from '@shared/ui/DsButton';\nimport { DsContactValue } from '@shared/ui/DsContactValue';\nimport { COPY, SORT, EDIT, CLOSE, CORRECT, INCORRECT } from '@shared/constants/events';\nimport type { DsContactDatum } from './DsDataCard.types';\n\nconst props = defineProps({\n title: { type: String, required: true },\n // Material Icon name for the header (e.g. \"email\", \"call\").\n icon: { type: String, default: 'email' },\n mostLikely: { type: Object as PropType<DsContactDatum | null>, default: null },\n more: { type: Array as PropType<DsContactDatum[]>, default: () => [] },\n collapsible: { type: Boolean, default: false },\n showSort: { type: Boolean, default: true },\n showEdit: { type: Boolean, default: false },\n showClose: { type: Boolean, default: false },\n isContactData: { type: Boolean, default: false },\n showRate: { type: Boolean, default: false },\n // User-facing labels (the app owns i18n); English DS defaults.\n editLabel: { type: String, default: 'Edit' },\n emptyLabel: { type: String, default: 'No data found' },\n mostLikelyLabel: { type: String, default: 'MOST LIKELY' },\n moreLabel: { type: String, default: 'MORE' },\n sortLabel: { type: String, default: 'Sort' },\n toggleLabel: { type: String, default: 'Toggle' },\n closeLabel: { type: String, default: 'Close' },\n});\n\n// Runtime array so the emit names are registered at runtime (the type-only\n// form with `typeof CONST` compiles to an empty `emits`, which lets listeners\n// fall through as native attrs). Names come from the shared events constants.\nconst emit = defineEmits([COPY, SORT, EDIT, CLOSE, CORRECT, INCORRECT]);\n\nconst collapsed = ref(false);\n\nconst total = computed(() => props.more.length + (props.mostLikely ? 1 : 0));\nconst showSections = computed(() => total.value > 3);\nconst empty = computed(() => total.value === 0);\nconst isCollapsed = computed(() => props.collapsible && collapsed.value);\n\nfunction toggle() {\n collapsed.value = !collapsed.value;\n}\nfunction onCopy(value: string) {\n emit(COPY, value);\n}\nfunction onSort() {\n emit(SORT);\n}\nfunction onEdit() {\n emit(EDIT);\n}\nfunction onClose() {\n emit(CLOSE);\n}\nfunction onCorrect(datum: DsContactDatum) {\n emit(CORRECT, datum);\n}\nfunction onIncorrect(datum: DsContactDatum) {\n emit(INCORRECT, datum);\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n@use '../../assets/css/shadow.scss' as sh;\n@use '../../assets/css/icons.scss' as i;\n\n.ds-data-card {\n display: block;\n\n padding: 8px;\n\n background-color: colors.$white;\n border-radius: r.$radius-card;\n box-shadow: sh.$shadow-card;\n\n // -- header --------------------------------------------------------------\n &__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n\n padding: 6px 6px 14px; // DS DataCard.jsx\n border-bottom: 1px solid colors.$slate-tint; // --primary-tint\n\n &.is-collapsible {\n cursor: pointer;\n }\n &.is-collapsed {\n border-bottom: none;\n }\n }\n\n &__heading {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n }\n\n &__icon {\n font-size: i.icon-size(20);\n line-height: 1;\n color: colors.$slate-main; // --primary-main\n }\n\n &__title {\n font-family: t.$font-family;\n font-weight: t.$weight-bold;\n font-size: t.font-size('body');\n color: colors.$slate-main;\n\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n &__actions {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n &__edit {\n padding: 0;\n border: none;\n background: none;\n cursor: pointer;\n\n font-family: t.$font-family;\n font-weight: t.$weight-bold;\n font-size: t.font-size('caption');\n color: colors.$accent-main;\n }\n\n &__close {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n padding: 0;\n border: none;\n background: none;\n cursor: pointer;\n\n color: colors.$slate-soft; // --primary-secondary-text\n\n .material-icons {\n font-size: i.icon-size(20);\n line-height: 1;\n }\n }\n\n // -- body ----------------------------------------------------------------\n &__body {\n padding-top: 8px;\n }\n\n &__section {\n padding: 6px;\n\n font-family: t.$font-family;\n font-size: t.font-size('micro');\n line-height: 18px;\n letter-spacing: 0.04em;\n color: colors.$slate-main;\n }\n\n &__more {\n display: flex;\n flex-direction: column;\n gap: 8px;\n\n max-height: 132px; // DS: ~3 rows before the \"MORE\" list scrolls\n overflow: auto;\n }\n\n &__empty {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px;\n\n font-family: t.$font-family;\n font-size: t.font-size('body');\n color: colors.$slate-main;\n }\n\n &__empty-icon {\n font-size: i.icon-size(20);\n line-height: 1;\n color: colors.$slate-soft;\n }\n}\n</style>\n"],"names":["DS_SPINNER_TONES","_createElementBlock","_normalizeClass","__props","_normalizeStyle","_hoisted_2","_toDisplayString","CLICK","CLOSE","FOCUS","BLUR","COPY","CORRECT","INCORRECT","SORT","EDIT","DS_BUTTON_VARIANTS","DS_BUTTON_SIZES","DS_BUTTON_NATIVE_TYPES","props","emit","__emit","iconSize","computed","spinnerTone","handleClick","event","_createBlock","_unref","DsSpinner","$slots","_openBlock","_renderSlot","_ctx","_createElementVNode","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","DS_TAG_TONES","_cache","$event","DS_BADGE_TONES","initials","ariaLabel","boxStyle","hashed","seed","hash","i","rgb","light","DS_TABLE_ALIGN","_hoisted_1","_Fragment","_renderList","column","_a","row","DS_INPUT_TYPES","DS_INPUT_SIZES","model","_useModel","slots","useSlots","reveal","ref","isPassword","resolvedType","hasSuffix","_hoisted_7","inputRef","syncIndeterminate","onMounted","watch","DS_ALERT_TYPES","DS_ALERT_EFFECTS","DS_ALERT_ICONS","visible","icon","hasBody","onClose","DS_NOTIFICATION_TYPES","DS_NOTIFICATION_POSITIONS","DS_NOTIFICATION_ICONS","_Teleport","dialogRef","lastFocused","onBackdrop","focusables","el","onKeydown","e","f","first","last","open","nextTick","_b","onBeforeUnmount","DsButton","DS_VERIFICATION_STATES","status","_createTextVNode","copied","copiedTimer","handleCopy","handleCorrect","handleIncorrect","_createVNode","DsVerificationIcon","DsBadge","collapsed","total","showSections","empty","isCollapsed","toggle","onCopy","value","onSort","onEdit","onCorrect","datum","onIncorrect","_hoisted_8","_hoisted_9","_hoisted_10","DsContactValue","_hoisted_11","_hoisted_12","_hoisted_13"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/ui/DsSpinner/DsSpinner.types.ts","../src/ui/DsSpinner/DsSpinner.vue","../src/constants/events.ts","../src/ui/DsButton/DsButton.types.ts","../src/ui/DsButton/DsButton.vue","../src/ui/DsTag/DsTag.types.ts","../src/ui/DsTag/DsTag.vue","../src/ui/DsBadge/DsBadge.types.ts","../src/ui/DsBadge/DsBadge.vue","../src/ui/DsAvatar/DsAvatar.vue","../src/ui/DsTable/DsTable.types.ts","../src/ui/DsTable/DsTable.vue","../src/ui/DsInput/DsInput.types.ts","../src/ui/DsInput/DsInput.vue","../src/ui/DsTextarea/DsTextarea.vue","../src/ui/DsCheckbox/DsCheckbox.vue","../src/ui/DsAlert/DsAlert.types.ts","../src/ui/DsAlert/DsAlert.vue","../src/ui/DsNotification/DsNotification.types.ts","../src/ui/DsNotification/DsNotification.vue","../src/ui/DsModal/DsModal.vue","../src/ui/DsVerificationIcon/DsVerificationIcon.types.ts","../src/ui/DsVerificationIcon/DsVerificationIcon.vue","../src/ui/DsContactValue/DsContactValue.vue","../src/ui/DsDataCard/DsDataCard.vue"],"sourcesContent":["// DsSpinner — the DS \"Spinner\": a rotating border-ring. Tones mirror Spinner.jsx.\n\nexport const DS_SPINNER_TONES = {\n DARK: 'dark', // slate ring — for light surfaces (default)\n LIGHT: 'light', // white ring — for dark surfaces / solid buttons\n ACCENT: 'accent', // accent ring\n} as const;\nexport type DsSpinnerTone = (typeof DS_SPINNER_TONES)[keyof typeof DS_SPINNER_TONES];\n","<template>\n <span\n class=\"ds-spinner\"\n :class=\"`ds-spinner--${tone}`\"\n role=\"status\"\n :style=\"{ width: `${size}px`, height: `${size}px` }\"\n :aria-label=\"label || undefined\"\n ></span>\n</template>\n\n<script setup lang=\"ts\">\nimport { type PropType } from 'vue';\nimport { DS_SPINNER_TONES, type DsSpinnerTone } from './DsSpinner.types';\n\ndefineProps({\n size: { type: Number, default: 24 },\n tone: {\n type: String as PropType<DsSpinnerTone>,\n default: DS_SPINNER_TONES.DARK,\n },\n // Accessible name (DS default \"Loading\"); the consuming app can override for\n // i18n. role=\"status\" + aria-label are always present, never opt-in.\n label: { type: String, default: 'Loading' },\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/motion.scss' as m;\n\n@keyframes ds-spinner-rot {\n to {\n transform: rotate(360deg);\n }\n}\n\n.ds-spinner {\n display: inline-block;\n\n border: 2px solid;\n border-radius: 50%;\n\n animation: ds-spinner-rot 1s linear infinite;\n\n @include m.reduce-motion {\n animation: none;\n }\n\n &--dark {\n border-color: colors.$slate-tint;\n border-top-color: colors.$slate-main;\n }\n &--light {\n border-color: rgba(255, 255, 255, 0.4);\n border-top-color: colors.$white;\n }\n &--accent {\n border-color: colors.$accent-mid;\n border-top-color: colors.$accent-main;\n }\n}\n</style>\n","// Evento genérico de click para props/emit\nexport const CLICK = 'click' as const;\nexport type ClickEventName = typeof CLICK;\n\n// Evento de cierre (p. ej. DsTag con × / closable) — mapea a onClose del DS\nexport const CLOSE = 'close' as const;\nexport type CloseEventName = typeof CLOSE;\n\n// Eventos de foco de controles de formulario (DsInput / DsTextarea)\nexport const FOCUS = 'focus' as const;\nexport type FocusEventName = typeof FOCUS;\n\nexport const BLUR = 'blur' as const;\nexport type BlurEventName = typeof BLUR;\n\n// Eventos de la familia data (DsContactValue / DsDataCard).\n// COPY lleva el valor copiado; CORRECT / INCORRECT marcan el rating de un dato.\nexport const COPY = 'copy' as const;\nexport type CopyEventName = typeof COPY;\n\nexport const CORRECT = 'correct' as const;\nexport type CorrectEventName = typeof CORRECT;\n\nexport const INCORRECT = 'incorrect' as const;\nexport type IncorrectEventName = typeof INCORRECT;\n\n// Acciones de cabecera de DsDataCard.\nexport const SORT = 'sort' as const;\nexport type SortEventName = typeof SORT;\n\nexport const EDIT = 'edit' as const;\nexport type EditEventName = typeof EDIT;\n","// DsButton — 1:1 with the SalesQL Design System \"Button\" (components/core/Button.jsx).\n// Variants map to the DS `variantStyle`; sizes to the DS control heights.\n\n// Variants (classes: ds-button--<variant>)\nexport const DS_BUTTON_VARIANTS = {\n DEFAULT: 'default', // white surface, dark text (the default value; == tertiary)\n PRIMARY: 'primary', // solid accent fill, white text — the main CTA\n SECONDARY: 'secondary', // slate surface fill, dark text\n TERTIARY: 'tertiary', // white surface, dark text (low-emphasis row action)\n QUATERNARY: 'quaternary', // accent text + accent-mid border on white\n QUINARY: 'quinary', // accent text on white, no border (link-style)\n WARNING: 'warning', // solid red fill, white text — destructive / delete\n DOTTED: 'dotted', // transparent, dashed border, 24px radius — \"add\" affordance\n} as const;\nexport type DsButtonVariant = (typeof DS_BUTTON_VARIANTS)[keyof typeof DS_BUTTON_VARIANTS];\n\n// Sizes = DS control heights (classes: ds-button--<size>)\nexport const DS_BUTTON_SIZES = {\n SMALL: 'small', // 24px\n MEDIUM: 'medium', // 32px\n LARGE: 'large', // 36px\n XLARGE: 'xlarge', // 48px\n} as const;\nexport type DsButtonSize = (typeof DS_BUTTON_SIZES)[keyof typeof DS_BUTTON_SIZES];\n\n// Native <button> type\nexport const DS_BUTTON_NATIVE_TYPES = {\n BUTTON: 'button',\n SUBMIT: 'submit',\n RESET: 'reset',\n} as const;\nexport type DsButtonNativeType =\n (typeof DS_BUTTON_NATIVE_TYPES)[keyof typeof DS_BUTTON_NATIVE_TYPES];\n","<template>\n <button\n class=\"ds-button\"\n :type=\"nativeType\"\n :disabled=\"disabled || loading\"\n :autofocus=\"autofocus\"\n :aria-busy=\"loading || undefined\"\n :aria-disabled=\"disabled || loading || undefined\"\n :aria-pressed=\"selected || undefined\"\n :aria-label=\"ariaLabel || undefined\"\n :class=\"[\n `ds-button--${variant}`,\n `ds-button--${size}`,\n {\n 'is-disabled': disabled || loading,\n 'is-loading': loading,\n 'is-circle': circle,\n 'is-square': square,\n 'is-selected': selected,\n },\n ]\"\n @click=\"handleClick\"\n >\n <DsSpinner v-if=\"loading\" class=\"ds-button__spinner\" :size=\"iconSize\" :tone=\"spinnerTone\" />\n\n <span\n v-if=\"!loading && (leftIcon || $slots.leading)\"\n class=\"ds-button__icon ds-button__icon--leading\"\n >\n <slot name=\"leading\"\n ><i class=\"material-icons\" aria-hidden=\"true\">{{ leftIcon }}</i></slot\n >\n </span>\n\n <span v-if=\"!loading && $slots.default\" class=\"ds-button__label\"><slot /></span>\n\n <span\n v-if=\"!loading && (rightIcon || $slots.trailing)\"\n class=\"ds-button__icon ds-button__icon--trailing\"\n >\n <slot name=\"trailing\"\n ><i class=\"material-icons\" aria-hidden=\"true\">{{ rightIcon }}</i></slot\n >\n </span>\n </button>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, type PropType } from 'vue';\nimport { DsSpinner, DS_SPINNER_TONES } from '@shared/ui/DsSpinner';\nimport { CLICK } from '@shared/constants/events';\nimport {\n DS_BUTTON_NATIVE_TYPES,\n DS_BUTTON_SIZES,\n DS_BUTTON_VARIANTS,\n type DsButtonNativeType,\n type DsButtonSize,\n type DsButtonVariant,\n} from './DsButton.types';\n\nconst props = defineProps({\n variant: { type: String as PropType<DsButtonVariant>, default: DS_BUTTON_VARIANTS.DEFAULT },\n size: { type: String as PropType<DsButtonSize>, default: DS_BUTTON_SIZES.MEDIUM },\n nativeType: {\n type: String as PropType<DsButtonNativeType>,\n default: DS_BUTTON_NATIVE_TYPES.BUTTON,\n },\n // Material Icon names (rendered via <i class=\"material-icons\">); a leading/\n // trailing slot overrides. Icon-only buttons (circle/square) need ariaLabel.\n leftIcon: { type: String, default: '' },\n rightIcon: { type: String, default: '' },\n ariaLabel: { type: String, default: '' },\n disabled: Boolean,\n loading: Boolean,\n // Round icon-only button (width === height, fully circular).\n circle: Boolean,\n // Flat 4px-radius icon-only button (the DS `*-square` sizes): symmetric padding\n // per size, height === width.\n square: Boolean,\n // Toggle state: accent outline + fill; sets aria-pressed (DS `selected`).\n selected: Boolean,\n autofocus: Boolean,\n});\n\n// Runtime array (not the type-only form): the SFC compiler can't resolve\n// `typeof CLICK` to a literal, leaving `emits` empty at runtime. With `click`\n// undeclared, the parent's @click both falls through to the native <button>\n// AND is invoked by emit() → the listener fires twice. Declaring it at runtime\n// (via the CLICK constant, per convention) excludes it from fallthrough.\nconst emit = defineEmits([CLICK]);\n\nconst iconSize = computed(() => (props.size === DS_BUTTON_SIZES.SMALL ? 14 : 20));\n// Solid-fill variants (white text) take the light spinner; the rest, dark.\nconst spinnerTone = computed(() =>\n props.variant === DS_BUTTON_VARIANTS.PRIMARY || props.variant === DS_BUTTON_VARIANTS.WARNING\n ? DS_SPINNER_TONES.LIGHT\n : DS_SPINNER_TONES.DARK\n);\n\nfunction handleClick(event: MouseEvent) {\n if (props.disabled || props.loading) return;\n emit(CLICK, event);\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/spacing.scss' as s;\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n@use '../../assets/css/motion.scss' as m;\n@use '../../assets/css/icons.scss' as i;\n\n.ds-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n\n padding: 0;\n\n font-family: t.$font-family;\n font-weight: t.$weight-medium; // 500 (DS); small overrides to 400\n font-size: t.font-size('body');\n line-height: 20px;\n\n border: 1px solid transparent;\n border-radius: r.$radius-control;\n outline: none;\n\n cursor: pointer;\n transition:\n background-color m.$duration-default m.$easing,\n border-color m.$duration-default m.$easing,\n opacity m.$duration-default m.$easing;\n\n @include m.reduce-motion {\n transition: none;\n }\n\n &.is-disabled {\n opacity: 0.55;\n cursor: not-allowed;\n }\n\n &__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n // DS icon size: 20px (small → 14px). Sizing the glyph to fill its box also\n // removes the optical \"gap\" a smaller glyph leaves against the button edge.\n .material-icons {\n font-size: i.icon-size(20);\n line-height: 1;\n }\n }\n\n // Material glyphs carry a built-in keyline (~2–3px advance bearing). Absorb it\n // on the edge side so a leading/trailing icon sits at the same optical inset as\n // a text-only button. Not for icon-only (circle/square) buttons — those stay centered.\n &:not(.is-circle):not(.is-square) &__icon--leading {\n margin-left: -3px;\n }\n &:not(.is-circle):not(.is-square) &__icon--trailing {\n margin-right: -3px;\n }\n\n &__spinner {\n /* size comes from the :size prop (iconSize) */\n }\n\n /* ---------- Variants (DS variantStyle) ---------- */\n // `default` and `tertiary` are identical in the DS (white surface, dark text).\n &--default,\n &--tertiary {\n color: colors.$slate-main;\n background-color: colors.$white;\n\n &:hover:not(.is-disabled) {\n background-color: colors.$slate-tint;\n }\n }\n &--primary {\n color: colors.$white;\n background-color: colors.$accent-main;\n\n &:hover:not(.is-disabled) {\n background-color: colors.$accent-shadow;\n }\n }\n &--secondary {\n color: colors.$slate-main;\n background-color: colors.$slate-bg;\n\n &:hover:not(.is-disabled) {\n background-color: colors.$slate-tint;\n }\n }\n &--quaternary {\n color: colors.$accent-main;\n border-color: colors.$accent-mid;\n background-color: colors.$white;\n\n &:hover:not(.is-disabled) {\n border-color: colors.$accent-main;\n }\n }\n &--quinary {\n color: colors.$accent-main;\n background-color: colors.$white;\n\n &:hover:not(.is-disabled) {\n background-color: colors.$accent-bg;\n }\n }\n // Destructive / delete — solid red fill, white text.\n &--warning {\n color: colors.$white;\n background-color: colors.$error-main;\n\n &:hover:not(.is-disabled) {\n background-color: colors.$error-shadow;\n }\n }\n // \"Add\" affordance — dashed border, 24px radius, weight 700, no hover (DS).\n &--dotted {\n color: colors.$slate-mid;\n font-weight: t.$weight-bold;\n\n border: 1px dashed colors.$slate-mid;\n border-radius: r.$radius-dashed;\n background-color: transparent;\n }\n\n /* ---------- Selected (toggle) — wins over the variant, incl. hover ---------- */\n &.is-selected,\n &.is-selected:hover:not(.is-disabled) {\n color: colors.$accent-main;\n border-color: colors.$accent-main;\n background-color: colors.$accent-bg;\n }\n\n /* ---------- Sizes (DS control heights + paddings) ---------- */\n &--small {\n height: s.control-height('small');\n padding: 0 s.control-padding('small');\n gap: 2px;\n\n font-weight: t.$weight-regular; // 400\n font-size: t.font-size('caption');\n\n .ds-button__icon .material-icons {\n font-size: i.icon-size(14);\n }\n }\n &--medium {\n height: s.control-height('medium');\n padding: 0 s.control-padding('medium');\n }\n &--large {\n height: s.control-height('large');\n padding: 0 s.control-padding('large');\n }\n &--xlarge {\n height: s.control-height('xlarge');\n padding: 0 s.control-padding('xlarge');\n }\n\n /* ---------- Circle (icon-only, true circle) ---------- */\n // width === height (= the size's control height): aspect-ratio alone lets the\n // content stretch the box into an oval, so pin the width to the height per size.\n &.is-circle {\n padding: 0;\n border-radius: r.$radius-full;\n }\n &--small.is-circle {\n width: s.control-height('small');\n }\n &--medium.is-circle {\n width: s.control-height('medium');\n }\n &--large.is-circle {\n width: s.control-height('large');\n }\n &--xlarge.is-circle {\n width: s.control-height('xlarge');\n }\n\n /* ---------- Square (icon-only, flat 4px) ---------- */\n // DS `*-square`: symmetric padding per size on a flat 4px radius; the fixed\n // height + symmetric padding yield a square around a centered glyph.\n &.is-square {\n border-radius: r.$radius-control;\n }\n &--small.is-square {\n padding: s.control-square-padding('small');\n }\n &--medium.is-square {\n padding: s.control-square-padding('medium');\n }\n &--large.is-square {\n padding: s.control-square-padding('large');\n }\n &--xlarge.is-square {\n padding: s.control-square-padding('xlarge');\n }\n}\n</style>\n","// DsTag — the DS \"Tag\": small bordered chip with optional close (×).\n// ⚠️ NOT the solid pill (that is DsBadge). See DESIGN-SYSTEM.md reconciliation.\n// Tones mirror the DS Tag source (Tag.jsx TONES). `rounded` → semicircular sides.\n\nexport const DS_TAG_TONES = {\n DEFAULT: 'default', // white bg, slate-tint border, muted text\n GREY: 'grey', // alias of `default` — the DS app passes tone=\"grey\" (ApiApp.jsx)\n SUCCESS: 'success', // e.g. Verified\n INFO: 'info', // e.g. Work\n WARNING: 'warning', // e.g. Pending\n ERROR: 'error', // e.g. Bounced\n} as const;\nexport type DsTagTone = (typeof DS_TAG_TONES)[keyof typeof DS_TAG_TONES];\n","<template>\n <span class=\"ds-tag\" :class=\"[`ds-tag--${tone}`, { 'is-rounded': rounded }]\">\n <slot />\n\n <button\n v-if=\"closable\"\n type=\"button\"\n class=\"ds-tag__close\"\n :aria-label=\"closeLabel || undefined\"\n @click=\"emit(CLOSE)\"\n >\n <i class=\"material-icons\" aria-hidden=\"true\">close</i>\n </button>\n </span>\n</template>\n\n<script setup lang=\"ts\">\nimport { type PropType } from 'vue';\nimport { CLOSE } from '@shared/constants/events';\nimport { DS_TAG_TONES, type DsTagTone } from './DsTag.types';\n\ndefineProps({\n tone: {\n type: String as PropType<DsTagTone>,\n default: DS_TAG_TONES.DEFAULT,\n },\n // Semicircular sides (DS `rounded`): radius-round vs the default radius-control.\n rounded: Boolean,\n // Show a × close control that emits `close`.\n closable: Boolean,\n // Accessible name for the × control (the app owns the wording / i18n).\n closeLabel: {\n type: String,\n default: '',\n },\n});\n\nconst emit = defineEmits<{\n (e: typeof CLOSE): void;\n}>();\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n@use '../../assets/css/icons.scss' as i;\n\n.ds-tag {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n\n padding: 0 10px;\n\n color: colors.$slate-mid;\n font-family: t.$font-family;\n font-weight: t.$weight-regular;\n font-size: t.font-size('caption');\n line-height: 30px;\n\n background-color: colors.$white;\n\n border: 1px solid colors.$slate-tint;\n border-radius: r.$radius-control;\n\n white-space: nowrap;\n\n &.is-rounded {\n border-radius: r.$radius-round;\n }\n\n &__close {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n padding: 0;\n\n color: inherit;\n\n background: transparent;\n border: 0;\n\n cursor: pointer;\n\n .material-icons {\n font-size: i.icon-size(12);\n }\n }\n\n /* ---------- Tones (default: white + tint border + muted text) ---------- */\n // `grey` is a DS alias of `default` (the DS app passes tone=\"grey\").\n &--default,\n &--grey {\n color: colors.$slate-mid;\n border-color: colors.$slate-tint;\n background-color: colors.$white;\n }\n &--success {\n color: colors.$success-shadow;\n border-color: colors.$success-mid;\n background-color: colors.$success-tint;\n }\n &--info {\n color: colors.$info-shadow;\n border-color: colors.$info-mid;\n background-color: colors.$info-tint;\n }\n &--warning {\n color: colors.$warning-shadow;\n border-color: colors.$warning-mid;\n background-color: colors.$warning-tint;\n }\n &--error {\n color: colors.$error-shadow;\n border-color: colors.$error-mid;\n background-color: colors.$error-tint;\n }\n}\n</style>\n","// DsBadge — the DS \"Badge\": solid, white-text pill (value types & counts).\n// ⚠️ NOT the tint chip (that is DsTag). See DESIGN-SYSTEM.md reconciliation.\n// Tones mirror the DS Badge source (Badge.jsx TONES).\n\nexport const DS_BADGE_TONES = {\n ACCENT: 'accent', // e.g. Work (purple)\n GREY: 'grey', // e.g. Direct (slate-soft)\n INFO: 'info', // e.g. Mobile (blue)\n SUCCESS: 'success', // e.g. New (green)\n ERROR: 'error', // coral\n WARNING: 'warning', // orange\n} as const;\nexport type DsBadgeTone = (typeof DS_BADGE_TONES)[keyof typeof DS_BADGE_TONES];\n","<template>\n <span class=\"ds-badge\" :class=\"`ds-badge--${tone}`\">\n <slot />\n </span>\n</template>\n\n<script setup lang=\"ts\">\nimport { type PropType } from 'vue';\nimport { DS_BADGE_TONES, type DsBadgeTone } from './DsBadge.types';\n\ndefineProps({\n tone: {\n type: String as PropType<DsBadgeTone>,\n default: DS_BADGE_TONES.ACCENT,\n },\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n\n.ds-badge {\n display: inline-flex;\n align-items: center;\n\n height: 17px;\n padding: 0 8px;\n\n color: colors.$white;\n font-family: t.$font-family;\n font-weight: t.$weight-bold;\n font-size: t.font-size('caption');\n line-height: 17px;\n\n border-radius: r.$radius-pill;\n\n white-space: nowrap;\n\n /* ---------- Tones (solid fill, white text) ---------- */\n &--accent {\n background-color: colors.$accent-main;\n }\n &--grey {\n background-color: colors.$slate-soft;\n }\n &--info {\n background-color: colors.$info-main;\n }\n &--success {\n background-color: colors.$success-main;\n }\n &--error {\n background-color: colors.$error-main;\n }\n &--warning {\n background-color: colors.$warning-main;\n }\n}\n</style>\n","<template>\n <img\n v-if=\"image\"\n class=\"ds-avatar\"\n :class=\"{ 'is-circular': circular }\"\n :src=\"image\"\n :alt=\"alt\"\n :style=\"boxStyle\"\n />\n\n <div\n v-else-if=\"initials\"\n class=\"ds-avatar ds-avatar--initials\"\n :class=\"{ 'is-circular': circular }\"\n role=\"img\"\n :aria-label=\"ariaLabel || undefined\"\n :style=\"[\n boxStyle,\n { background: hashed.bg, color: hashed.fg, fontSize: `${Math.round(size * 0.4)}px` },\n ]\"\n >\n {{ initials }}\n </div>\n\n <div\n v-else\n class=\"ds-avatar ds-avatar--placeholder\"\n :class=\"{ 'is-circular': circular }\"\n :style=\"boxStyle\"\n aria-hidden=\"true\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\nconst props = defineProps({\n image: { type: String, default: '' },\n firstName: { type: String, default: '' },\n lastName: { type: String, default: '' },\n uid: { type: String, default: '' },\n size: { type: Number, default: 40 },\n circular: Boolean,\n // Accessible label (defaults to \"firstName lastName\").\n alt: { type: String, default: '' },\n});\n\nconst initials = computed(() =>\n props.firstName && props.lastName\n ? (props.firstName.charAt(0) + props.lastName.charAt(0)).toUpperCase()\n : ''\n);\n\nconst ariaLabel = computed(() => props.alt || `${props.firstName} ${props.lastName}`.trim());\n\nconst boxStyle = computed(() => ({ width: `${props.size}px`, height: `${props.size}px` }));\n\n// Deterministic color from a uid — exact port of SqlAvatar.getBackgroundColor.\nconst hashed = computed(() => {\n const seed = props.uid || props.firstName + props.lastName;\n let hash = 0;\n for (let i = 0; i < seed.length; i++) {\n hash = seed.charCodeAt(i) + ((hash << 5) - hash);\n hash = hash & hash;\n }\n const rgb = [0, 0, 0];\n for (let i = 0; i < 3; i++) rgb[i] = (hash >> (i * 8)) & 255;\n const light = rgb[0] >= 200 && rgb[1] >= 200 && rgb[2] >= 200;\n return { bg: `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`, fg: light ? '#323f4b' : '#fff' };\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n\n.ds-avatar {\n display: flex;\n flex: none;\n align-items: center;\n justify-content: center;\n\n overflow: hidden;\n object-fit: cover;\n\n border-radius: r.$radius-control;\n\n &.is-circular {\n border-radius: r.$radius-full;\n }\n\n &--initials {\n font-family: t.$font-family;\n font-weight: t.$weight-black;\n line-height: 1;\n user-select: none;\n }\n\n &--placeholder {\n background-color: #c0c4cc; // DS placeholder grey (Avatar.jsx)\n }\n}\n</style>\n","// DsTable — the DS data table (data-dense density). Column/row API with hairline\n// borders, row hover, and an optional highlighted \"most likely\" row.\n\nexport const DS_TABLE_ALIGN = {\n LEFT: 'left',\n CENTER: 'center',\n RIGHT: 'right',\n} as const;\nexport type DsTableAlign = (typeof DS_TABLE_ALIGN)[keyof typeof DS_TABLE_ALIGN];\n\n// A column. `key` maps to the row property for default content and names the\n// scoped slot `cell-<key>`.\nexport interface DsTableColumn {\n key: string;\n label: string;\n align?: DsTableAlign;\n width?: string;\n}\n\n// A row: only a stable `id` is required (for :key and highlighting); the rest of\n// the properties are consumed per column via its `key`.\nexport interface DsTableRow {\n id: string | number;\n [key: string]: unknown;\n}\n","<script setup lang=\"ts\">\nimport { computed, type PropType } from 'vue';\nimport { DS_TABLE_ALIGN, type DsTableColumn, type DsTableRow } from './DsTable.types';\n\nconst props = defineProps({\n columns: {\n type: Array as PropType<DsTableColumn[]>,\n required: true,\n },\n rows: {\n type: Array as PropType<DsTableRow[]>,\n required: true,\n },\n emptyMessage: {\n type: String,\n default: '',\n },\n // id of the row to highlight (the DS \"most likely\" row → accent surface).\n highlightRowId: {\n type: [String, Number] as PropType<string | number | null>,\n default: null,\n },\n // Optional fixed row height (number → px, or any CSS length). Rows are\n // content-driven by default; when set, this pins the height AND truncates\n // overflowing cell text with an ellipsis.\n rowHeight: {\n type: [String, Number] as PropType<string | number | null>,\n default: null,\n },\n});\n\nconst rowHeightStyle = computed(() =>\n props.rowHeight == null\n ? undefined\n : {\n '--ds-table-row-height':\n typeof props.rowHeight === 'number' ? `${props.rowHeight}px` : props.rowHeight,\n }\n);\n</script>\n\n<template>\n <div class=\"ds-table\">\n <div class=\"ds-table__wrapper\">\n <table\n class=\"ds-table__table\"\n :class=\"{ 'has-row-height': rowHeight != null }\"\n :style=\"rowHeightStyle\"\n >\n <thead>\n <tr>\n <th\n v-for=\"column in columns\"\n :key=\"column.key\"\n :class=\"`ds-table__th--${column.align ?? DS_TABLE_ALIGN.LEFT}`\"\n :style=\"column.width ? { width: column.width } : undefined\"\n >\n {{ column.label }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr v-if=\"rows.length === 0\">\n <td class=\"ds-table__empty\" :colspan=\"columns.length\" data-testid=\"ds-table-empty\">\n <slot name=\"empty\">{{ emptyMessage }}</slot>\n </td>\n </tr>\n <tr\n v-for=\"row in rows\"\n :key=\"row.id\"\n :class=\"{ 'is-highlighted': row.id === highlightRowId }\"\n data-testid=\"ds-table-row\"\n >\n <td\n v-for=\"column in columns\"\n :key=\"column.key\"\n :class=\"`ds-table__td--${column.align ?? DS_TABLE_ALIGN.LEFT}`\"\n >\n <slot :name=\"`cell-${column.key}`\" :row=\"row\">{{ row[column.key] }}</slot>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/spacing.scss' as s;\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n@use '../../assets/css/motion.scss' as m;\n\n.ds-table {\n &__wrapper {\n overflow-x: auto;\n\n border: 1px solid colors.$slate-tint;\n border-radius: r.$radius-card-lg;\n }\n\n &__table {\n width: 100%;\n border-collapse: collapse;\n\n // Own every border/height explicitly so host-app global table rules can't\n // leak in; scoped specificity (block + [data-v]) beats them.\n th {\n padding: s.spacing(1) s.spacing(2);\n\n color: colors.$slate-main;\n font-weight: t.$weight-bold;\n font-size: t.font-size('body');\n\n border: 0;\n border-bottom: 1px solid colors.$slate-tint;\n\n background-color: colors.$slate-bg;\n }\n\n td {\n height: auto;\n padding: s.spacing(1) s.spacing(2);\n vertical-align: middle;\n\n color: colors.$slate-main;\n font-size: t.font-size('body');\n\n border: 0;\n }\n\n // Opt-in fixed row height → pin td height and truncate overflowing text.\n &.has-row-height td {\n height: var(--ds-table-row-height);\n\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n\n tr {\n border: 0;\n transition: background-color m.$duration-default m.$easing;\n\n @include m.reduce-motion {\n transition: none;\n }\n }\n\n // Row separator only BETWEEN adjacent body rows.\n tbody tr + tr {\n border-top: 1px solid colors.$slate-tint;\n }\n\n // Row hover (data-dense affordance).\n tbody tr:hover {\n background-color: colors.$slate-bg;\n }\n\n // The highlighted \"most likely\" row wins over hover.\n tbody tr.is-highlighted {\n background-color: colors.$accent-bg;\n }\n tbody tr.is-highlighted:hover {\n background-color: colors.$accent-tint;\n }\n }\n\n &__th--left,\n &__td--left {\n text-align: left;\n }\n &__th--center,\n &__td--center {\n text-align: center;\n }\n &__th--right,\n &__td--right {\n text-align: right;\n }\n\n &__empty {\n padding: s.spacing(5) s.spacing(3);\n\n color: colors.$slate-soft;\n text-align: center;\n }\n}\n</style>\n","// DsInput — the DS \"Input\": single-line field. Prop vocabulary mirrors Input.jsx.\n// Border: primary-main at rest → accent on focus, coral on error. Text goes BOLD\n// on focus (DS Input.jsx: fontWeight focus ? 700 : 400). Sizes are the DS input\n// heights. (DsTextarea intentionally does NOT bold on focus — matching its source.)\n\nexport const DS_INPUT_TYPES = {\n TEXT: 'text',\n EMAIL: 'email',\n PASSWORD: 'password',\n TEL: 'tel',\n NUMBER: 'number',\n SEARCH: 'search',\n URL: 'url',\n} as const;\nexport type DsInputType = (typeof DS_INPUT_TYPES)[keyof typeof DS_INPUT_TYPES];\n\nexport const DS_INPUT_SIZES = {\n SM: 'sm', // 36px\n MD: 'md', // 48px\n} as const;\nexport type DsInputSize = (typeof DS_INPUT_SIZES)[keyof typeof DS_INPUT_SIZES];\n","<template>\n <div\n class=\"ds-input\"\n :class=\"[`ds-input--${size}`, { 'is-error': error, 'is-disabled': disabled }]\"\n >\n <div class=\"ds-input__wrap\">\n <input\n :id=\"id || undefined\"\n v-model=\"model\"\n class=\"ds-input__control\"\n :class=\"{ 'has-suffix': hasSuffix }\"\n :type=\"resolvedType\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :name=\"name || undefined\"\n :autocomplete=\"autocomplete || undefined\"\n :aria-invalid=\"error || undefined\"\n :aria-describedby=\"error && errorMessage && id ? `${id}-error` : undefined\"\n @focus=\"emit(FOCUS, $event)\"\n @blur=\"emit(BLUR, $event)\"\n />\n\n <div v-if=\"hasSuffix\" class=\"ds-input__suffix\">\n <slot name=\"suffix\" />\n\n <i\n v-if=\"error && showErrorIcon\"\n class=\"material-icons ds-input__error-icon\"\n aria-hidden=\"true\"\n >warning</i\n >\n\n <button\n v-else-if=\"isPassword\"\n type=\"button\"\n class=\"ds-input__toggle\"\n :aria-label=\"toggleLabel || undefined\"\n :aria-pressed=\"reveal\"\n @click=\"reveal = !reveal\"\n >\n <i class=\"material-icons\" aria-hidden=\"true\">{{\n reveal ? 'visibility' : 'visibility_off'\n }}</i>\n </button>\n </div>\n </div>\n\n <p v-if=\"error && errorMessage\" :id=\"id ? `${id}-error` : undefined\" class=\"ds-input__error\">\n {{ errorMessage }}\n </p>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, useSlots, type PropType } from 'vue';\nimport { FOCUS, BLUR } from '@shared/constants/events';\nimport {\n DS_INPUT_TYPES,\n DS_INPUT_SIZES,\n type DsInputType,\n type DsInputSize,\n} from './DsInput.types';\n\nconst model = defineModel<string>({ default: '' });\n\nconst props = defineProps({\n type: { type: String as PropType<DsInputType>, default: DS_INPUT_TYPES.TEXT },\n size: { type: String as PropType<DsInputSize>, default: DS_INPUT_SIZES.SM },\n placeholder: { type: String, default: '' },\n disabled: Boolean,\n error: Boolean,\n errorMessage: { type: String, default: '' },\n showErrorIcon: Boolean,\n name: { type: String, default: '' },\n id: { type: String, default: '' },\n autocomplete: { type: String, default: '' },\n // Accessible name for the password visibility toggle.\n toggleLabel: { type: String, default: '' },\n});\n\nconst emit = defineEmits([FOCUS, BLUR]);\n\nconst slots = useSlots();\nconst reveal = ref(false);\nconst isPassword = computed(() => props.type === DS_INPUT_TYPES.PASSWORD);\nconst resolvedType = computed(() =>\n isPassword.value && reveal.value ? DS_INPUT_TYPES.TEXT : props.type\n);\nconst hasSuffix = computed(\n () => !!slots.suffix || (props.error && props.showErrorIcon) || isPassword.value\n);\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n@use '../../assets/css/motion.scss' as m;\n@use '../../assets/css/icons.scss' as i;\n\n.ds-input {\n display: block;\n width: 100%;\n\n &__wrap {\n position: relative;\n width: 100%;\n }\n\n &__control {\n box-sizing: border-box;\n width: 100%;\n padding: 0 16px;\n\n color: colors.$slate-main;\n font-family: t.$font-family;\n font-size: t.font-size('body');\n font-weight: t.$weight-regular;\n line-height: 20px;\n\n background-color: colors.$white;\n\n /* Border: primary-main at rest → accent on focus (see precedence below). */\n border: 1px solid colors.$slate-main;\n border-radius: r.$radius-control;\n outline: none;\n\n transition: border-color m.$duration-default m.$easing;\n\n @include m.reduce-motion {\n transition: none;\n }\n\n &.has-suffix {\n padding-right: 50px;\n }\n\n &:focus {\n border-color: colors.$accent-main;\n font-weight: t.$weight-bold; // DS: text goes bold on focus\n }\n }\n\n &__suffix {\n position: absolute;\n top: 0;\n right: 0;\n\n display: flex;\n align-items: center;\n gap: 4px;\n\n height: 100%;\n padding: 0 16px;\n\n color: colors.$slate-soft;\n }\n\n &__toggle {\n display: inline-flex;\n padding: 0;\n\n color: inherit;\n\n background: transparent;\n border: 0;\n\n cursor: pointer;\n }\n\n &__error-icon {\n color: colors.$error-main;\n }\n\n &__error {\n margin-top: 2px;\n\n color: colors.$error-main;\n font-family: t.$font-family;\n font-weight: t.$weight-bold;\n font-size: t.font-size('caption');\n line-height: 18px;\n }\n\n /* ---------- Sizes (DS input heights + icon sizes) ---------- */\n &--sm {\n .ds-input__control {\n height: 36px;\n }\n .material-icons {\n font-size: i.icon-size(18); // DS Input.jsx: suffix glyph is 18 at sm (24 at md)\n }\n }\n &--md {\n .ds-input__control {\n height: 48px;\n }\n .material-icons {\n font-size: i.icon-size(24);\n }\n }\n\n /* ---------- States (precedence: rest → focus → disabled → error) ---------- */\n &.is-disabled .ds-input__control {\n color: colors.$slate-mid;\n background-color: colors.$slate-bg;\n border-color: colors.$slate-mid;\n cursor: not-allowed;\n }\n &.is-error .ds-input__control,\n &.is-error .ds-input__control:focus {\n border-color: colors.$error-main;\n }\n}\n</style>\n","<template>\n <div class=\"ds-textarea\" :class=\"{ 'is-error': error, 'is-disabled': disabled }\">\n <textarea\n :id=\"id || undefined\"\n v-model=\"model\"\n class=\"ds-textarea__control\"\n :placeholder=\"placeholder\"\n :rows=\"rows\"\n :disabled=\"disabled\"\n :name=\"name || undefined\"\n :aria-invalid=\"error || undefined\"\n :aria-describedby=\"error && errorMessage && id ? `${id}-error` : undefined\"\n @focus=\"emit(FOCUS, $event)\"\n @blur=\"emit(BLUR, $event)\"\n />\n <p v-if=\"error && errorMessage\" :id=\"id ? `${id}-error` : undefined\" class=\"ds-textarea__error\">\n {{ errorMessage }}\n </p>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { FOCUS, BLUR } from '@shared/constants/events';\n\nconst model = defineModel<string>({ default: '' });\n\ndefineProps({\n placeholder: { type: String, default: '' },\n rows: { type: Number, default: 4 },\n disabled: Boolean,\n error: Boolean,\n errorMessage: { type: String, default: '' },\n name: { type: String, default: '' },\n id: { type: String, default: '' },\n});\n\nconst emit = defineEmits([FOCUS, BLUR]);\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n@use '../../assets/css/motion.scss' as m;\n\n.ds-textarea {\n display: block;\n width: 100%;\n\n &__control {\n box-sizing: border-box;\n width: 100%;\n padding: 12px 16px;\n\n color: colors.$slate-main;\n font-family: t.$font-family;\n font-size: t.font-size('body');\n line-height: 20px;\n\n background-color: colors.$white;\n\n border: 1px solid colors.$slate-main;\n border-radius: r.$radius-control;\n outline: none;\n\n resize: vertical;\n transition: border-color m.$duration-default m.$easing;\n\n @include m.reduce-motion {\n transition: none;\n }\n\n &:focus {\n border-color: colors.$accent-main;\n }\n }\n\n &__error {\n margin-top: 2px;\n\n color: colors.$error-main;\n font-family: t.$font-family;\n font-weight: t.$weight-bold;\n font-size: t.font-size('caption');\n line-height: 18px;\n }\n\n &.is-disabled .ds-textarea__control {\n color: colors.$slate-mid;\n background-color: colors.$slate-bg;\n border-color: colors.$slate-mid;\n cursor: not-allowed;\n }\n &.is-error .ds-textarea__control,\n &.is-error .ds-textarea__control:focus {\n border-color: colors.$error-main;\n }\n}\n</style>\n","<template>\n <label class=\"ds-checkbox\" :class=\"{ 'is-disabled': disabled }\">\n <input\n ref=\"inputRef\"\n v-model=\"model\"\n type=\"checkbox\"\n class=\"ds-checkbox__native\"\n :disabled=\"disabled\"\n :name=\"name || undefined\"\n />\n <span\n class=\"ds-checkbox__box\"\n :class=\"{ 'is-active': model || indeterminate }\"\n aria-hidden=\"true\"\n >\n <svg\n v-if=\"indeterminate\"\n class=\"ds-checkbox__mark\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n >\n <line x1=\"4\" y1=\"8\" x2=\"12\" y2=\"8\" />\n </svg>\n <svg\n v-else-if=\"model\"\n class=\"ds-checkbox__mark\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n >\n <path d=\"M3.5 8.5l3 3 6-6\" />\n </svg>\n </span>\n <span v-if=\"$slots.default || label\" class=\"ds-checkbox__label\"\n ><slot>{{ label }}</slot></span\n >\n </label>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted, watch } from 'vue';\n\nconst model = defineModel<boolean>({ default: false });\n\nconst props = defineProps({\n indeterminate: Boolean,\n disabled: Boolean,\n name: { type: String, default: '' },\n // Label text (DS `label` prop); a default slot overrides it.\n label: { type: String, default: '' },\n});\n\nconst inputRef = ref<HTMLInputElement | null>(null);\n\n// `indeterminate` is a DOM property, not an attribute — keep it in sync for a11y.\nfunction syncIndeterminate() {\n if (inputRef.value) inputRef.value.indeterminate = props.indeterminate;\n}\nonMounted(syncIndeterminate);\nwatch(() => props.indeterminate, syncIndeterminate);\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/spacing.scss' as s;\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n@use '../../assets/css/motion.scss' as m;\n\n.ds-checkbox {\n display: inline-flex;\n align-items: center;\n gap: s.spacing(1);\n\n color: colors.$slate-main;\n font-family: t.$font-family;\n font-size: t.font-size('body');\n\n cursor: pointer;\n\n &.is-disabled {\n cursor: not-allowed;\n opacity: 0.5; // DS Checkbox.jsx: whole label dims to .5 when disabled\n }\n\n /* Native control drives state + focus, visually replaced by the custom box. */\n &__native {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n }\n\n &__box {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n\n width: 18px;\n height: 18px;\n\n color: colors.$white;\n\n background-color: colors.$white;\n\n border: 1px solid colors.$slate-mid;\n border-radius: r.$radius-control;\n\n transition:\n background-color m.$duration-default m.$easing,\n border-color m.$duration-default m.$easing;\n\n @include m.reduce-motion {\n transition: none;\n }\n\n &.is-active {\n background-color: colors.$accent-main;\n border-color: colors.$accent-main;\n }\n }\n\n /* Focus ring on the box when the (hidden) native input is focused. */\n &__native:focus-visible + &__box {\n outline: 2px solid colors.$accent-mid;\n outline-offset: 1px;\n }\n\n &__mark {\n width: 14px;\n height: 14px;\n }\n\n &__label {\n line-height: 1.3;\n }\n}\n</style>\n","// DsAlert — the DS inline banner (Alert.jsx). type × effect (light tint / dark solid).\n\nexport const DS_ALERT_TYPES = {\n SUCCESS: 'success',\n INFO: 'info',\n WARNING: 'warning',\n ERROR: 'error',\n} as const;\nexport type DsAlertType = (typeof DS_ALERT_TYPES)[keyof typeof DS_ALERT_TYPES];\n\nexport const DS_ALERT_EFFECTS = {\n LIGHT: 'light', // tinted: family tint bg + mid border + shadow text\n DARK: 'dark', // solid: family shadow bg + white text\n} as const;\nexport type DsAlertEffect = (typeof DS_ALERT_EFFECTS)[keyof typeof DS_ALERT_EFFECTS];\n\n// Material Icon per type (leading icon when showIcon).\nexport const DS_ALERT_ICONS: Record<DsAlertType, string> = {\n success: 'check_circle',\n info: 'info',\n warning: 'warning',\n error: 'error',\n};\n","<template>\n <div\n v-if=\"visible\"\n class=\"ds-alert\"\n :class=\"[`ds-alert--${type}`, `ds-alert--${effect}`, { 'is-center': center }]\"\n role=\"alert\"\n >\n <i v-if=\"showIcon\" class=\"material-icons ds-alert__icon\" aria-hidden=\"true\">{{ icon }}</i>\n\n <div class=\"ds-alert__content\">\n <div v-if=\"title\" class=\"ds-alert__title\" :class=\"{ 'has-body': hasBody }\">{{ title }}</div>\n <div v-if=\"hasBody\" class=\"ds-alert__body\">\n <slot>{{ description }}</slot>\n </div>\n </div>\n\n <button\n v-if=\"closable\"\n type=\"button\"\n class=\"ds-alert__close\"\n :aria-label=\"closeLabel || undefined\"\n @click=\"onClose\"\n >\n <i class=\"material-icons\" aria-hidden=\"true\">close</i>\n </button>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, useSlots, type PropType } from 'vue';\nimport { CLOSE } from '@shared/constants/events';\nimport {\n DS_ALERT_TYPES,\n DS_ALERT_EFFECTS,\n DS_ALERT_ICONS,\n type DsAlertType,\n type DsAlertEffect,\n} from './DsAlert.types';\n\nconst props = defineProps({\n type: { type: String as PropType<DsAlertType>, default: DS_ALERT_TYPES.INFO },\n effect: { type: String as PropType<DsAlertEffect>, default: DS_ALERT_EFFECTS.LIGHT },\n title: { type: String, default: '' },\n description: { type: String, default: '' },\n showIcon: Boolean,\n closable: Boolean,\n center: Boolean,\n closeLabel: { type: String, default: '' },\n});\n\nconst emit = defineEmits([CLOSE]);\n\nconst slots = useSlots();\nconst visible = ref(true);\nconst icon = computed(() => DS_ALERT_ICONS[props.type]);\nconst hasBody = computed(() => !!slots.default || props.description.length > 0);\n\nfunction onClose() {\n visible.value = false;\n emit(CLOSE);\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n@use '../../assets/css/icons.scss' as i;\n\n.ds-alert {\n position: relative;\n\n display: flex;\n align-items: center;\n\n padding: 8px 16px;\n\n font-family: t.$font-family;\n\n border: 1px solid transparent;\n border-radius: r.$radius-control;\n\n &.is-center {\n justify-content: center;\n }\n\n &__icon {\n margin-right: 8px;\n // DS Alert.jsx: status glyph is 16 (md-20 class, fontSize:16 override).\n font-size: i.icon-size(16);\n }\n\n &__content {\n flex: 1;\n padding: 0 8px;\n }\n\n &__title {\n font-size: t.font-size('small');\n font-weight: t.$weight-regular;\n line-height: 18px;\n\n &.has-body {\n font-weight: t.$weight-bold;\n }\n }\n\n &__body {\n font-size: t.font-size('caption');\n }\n\n // DS: body margin-top is 5 only when a title precedes it, 0 otherwise.\n &__title.has-body + .ds-alert__body {\n margin-top: 5px;\n }\n\n &__close {\n position: absolute;\n top: 12px;\n right: 15px;\n\n display: inline-flex;\n padding: 0;\n\n color: inherit;\n\n background: transparent;\n border: 0;\n\n cursor: pointer;\n\n .material-icons {\n font-size: i.icon-size(16);\n }\n }\n\n /* ---------- light (tinted) — bg tint + mid border + shadow text ---------- */\n &--light {\n &.ds-alert--success {\n color: colors.$success-shadow;\n border-color: colors.$success-mid;\n background-color: colors.$success-tint;\n }\n &.ds-alert--info {\n color: colors.$info-shadow;\n border-color: colors.$info-mid;\n background-color: colors.$info-tint;\n }\n &.ds-alert--warning {\n color: colors.$warning-shadow;\n border-color: colors.$warning-mid;\n background-color: colors.$warning-tint;\n }\n &.ds-alert--error {\n color: colors.$error-shadow;\n border-color: colors.$error-mid;\n background-color: colors.$error-tint;\n }\n }\n\n /* ---------- dark (solid) — bg shadow + white text ---------- */\n &--dark {\n color: colors.$white;\n border-color: transparent;\n\n &.ds-alert--success {\n background-color: colors.$success-shadow;\n }\n &.ds-alert--info {\n background-color: colors.$info-shadow;\n }\n &.ds-alert--warning {\n background-color: colors.$warning-shadow;\n }\n &.ds-alert--error {\n background-color: colors.$error-shadow;\n }\n }\n}\n</style>\n","// DsNotification — the DS toast card (Notification.jsx). Fixed-position, 3 types.\n\nexport const DS_NOTIFICATION_TYPES = {\n SUCCESS: 'success',\n INFO: 'info',\n WARNING: 'warning',\n ERROR: 'error',\n} as const;\nexport type DsNotificationType = (typeof DS_NOTIFICATION_TYPES)[keyof typeof DS_NOTIFICATION_TYPES];\n\nexport const DS_NOTIFICATION_POSITIONS = {\n TOP_LEFT: 'top-left',\n TOP_RIGHT: 'top-right',\n BOTTOM_LEFT: 'bottom-left',\n BOTTOM_RIGHT: 'bottom-right',\n} as const;\nexport type DsNotificationPosition =\n (typeof DS_NOTIFICATION_POSITIONS)[keyof typeof DS_NOTIFICATION_POSITIONS];\n\n// Material Icon per type. `error` uses the filled `error` glyph (circle) per the live\n// design prototype (ApiApp.jsx ToastCard) — the older _ds_bundle.js used `warning` here.\nexport const DS_NOTIFICATION_ICONS: Record<DsNotificationType, string> = {\n success: 'check_circle',\n info: 'mode_edit',\n warning: 'warning',\n error: 'error',\n};\n","<template>\n <Teleport to=\"body\">\n <Transition name=\"ds-notification\" appear>\n <div v-if=\"visible\" class=\"ds-notification\" :class=\"`ds-notification--${position}`\">\n <div\n class=\"ds-notification__card\"\n :class=\"`ds-notification__card--${type}`\"\n role=\"alert\"\n @mouseenter=\"pause\"\n @mouseleave=\"resume\"\n >\n <i class=\"material-icons ds-notification__icon\" aria-hidden=\"true\">{{ icon }}</i>\n\n <div class=\"ds-notification__content\">\n <span v-if=\"title\" class=\"ds-notification__title\">{{ title }}</span>\n <p v-if=\"description\" class=\"ds-notification__desc\">{{ description }}</p>\n <a\n v-if=\"linkTitle\"\n class=\"ds-notification__link\"\n :href=\"link || undefined\"\n target=\"_blank\"\n rel=\"noreferrer\"\n >{{ linkTitle }}</a\n >\n </div>\n\n <button\n v-if=\"showClose\"\n type=\"button\"\n class=\"ds-notification__close\"\n :aria-label=\"closeLabel || undefined\"\n @click=\"onClose\"\n >\n <i class=\"material-icons\" aria-hidden=\"true\">close</i>\n </button>\n </div>\n </div>\n </Transition>\n </Teleport>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, onMounted, ref, type PropType } from 'vue';\nimport { CLOSE } from '@shared/constants/events';\nimport {\n DS_NOTIFICATION_TYPES,\n DS_NOTIFICATION_POSITIONS,\n DS_NOTIFICATION_ICONS,\n type DsNotificationType,\n type DsNotificationPosition,\n} from './DsNotification.types';\n\nconst props = defineProps({\n type: { type: String as PropType<DsNotificationType>, default: DS_NOTIFICATION_TYPES.INFO },\n position: {\n type: String as PropType<DsNotificationPosition>,\n default: DS_NOTIFICATION_POSITIONS.BOTTOM_LEFT,\n },\n title: { type: String, default: '' },\n description: { type: String, default: '' },\n linkTitle: { type: String, default: '' },\n link: { type: String, default: '' },\n showClose: { type: Boolean, default: true },\n closeLabel: { type: String, default: '' },\n // Auto-dismiss delay in ms (DS default 3500). 0 disables it. The timer pauses\n // while the pointer is over the card and resumes with the remaining time.\n duration: { type: Number, default: 3500 },\n});\n\nconst emit = defineEmits([CLOSE]);\n\nconst visible = ref(true);\nconst icon = computed(() => DS_NOTIFICATION_ICONS[props.type]);\n\nlet timer: ReturnType<typeof setTimeout> | undefined;\nlet startedAt = 0;\nlet remaining = props.duration;\n\nfunction clearTimer() {\n if (timer) {\n clearTimeout(timer);\n timer = undefined;\n }\n}\n\nfunction schedule(ms: number) {\n clearTimer();\n if (props.duration <= 0 || !visible.value) return;\n startedAt = Date.now();\n timer = setTimeout(onClose, ms);\n}\n\nfunction pause() {\n if (!timer) return;\n remaining -= Date.now() - startedAt;\n clearTimer();\n}\n\nfunction resume() {\n schedule(remaining > 0 ? remaining : props.duration);\n}\n\nfunction onClose() {\n clearTimer();\n visible.value = false;\n emit(CLOSE);\n}\n\nonMounted(() => schedule(props.duration));\nonBeforeUnmount(clearTimer);\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n@use '../../assets/css/shadow.scss' as sh;\n@use '../../assets/css/icons.scss' as i;\n@use '../../assets/css/motion.scss' as m;\n\n.ds-notification {\n position: fixed;\n z-index: 2000;\n\n &--top-left {\n top: 0;\n left: 0;\n }\n &--top-right {\n top: 0;\n right: 0;\n }\n &--bottom-left {\n bottom: 0;\n left: 0;\n }\n &--bottom-right {\n bottom: 0;\n right: 0;\n }\n\n &__card {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n\n max-width: 331px;\n margin: 24px;\n padding: 16px;\n\n border: 1px solid transparent;\n border-radius: r.$radius-card-lg;\n\n box-shadow: sh.$shadow-soft;\n\n // Success is the DS default/most-used type. Icons use the darker -shadow step\n // for legibility on the tint (warning/error/success). NOTE: the _ds_bundle.js\n // export uses the -main step for icons — this -shadow treatment tracks the\n // live design, pending a visual confirm against claude.ai/design.\n &--success {\n background-color: colors.$success-tint;\n border-color: rgba(colors.$success-main, 0.7);\n\n .ds-notification__icon {\n color: colors.$success-shadow;\n }\n }\n &--info {\n background-color: colors.$info-tint;\n border-color: rgba(colors.$info-main, 0.7);\n\n .ds-notification__icon {\n color: colors.$info-main;\n }\n }\n &--warning {\n background-color: colors.$warning-tint;\n border-color: rgba(colors.$warning-main, 0.7);\n\n .ds-notification__icon {\n color: colors.$warning-shadow;\n }\n }\n &--error {\n background-color: colors.$error-tint;\n border-color: rgba(colors.$error-main, 0.7);\n\n .ds-notification__icon {\n color: colors.$error-shadow;\n }\n }\n }\n\n &__icon {\n font-size: i.icon-size(20);\n }\n\n &__content {\n display: flex;\n flex-direction: column;\n\n color: colors.$slate-shadow;\n font-family: t.$font-family;\n font-size: t.font-size('body');\n line-height: 21px;\n }\n\n &__title {\n font-weight: t.$weight-bold;\n }\n\n &__desc {\n margin: 0;\n padding-top: 8px;\n }\n\n &__link {\n padding-top: 8px;\n\n color: colors.$accent-main;\n text-decoration: underline;\n }\n\n &__close {\n display: inline-flex;\n margin-left: auto;\n padding: 0;\n\n color: colors.$slate-soft;\n\n background: transparent;\n border: 0;\n\n cursor: pointer;\n\n .material-icons {\n font-size: i.icon-size(20);\n }\n }\n}\n\n/* Enter: the card fades + slides up (~0.24s toast duration). */\n.ds-notification-enter-active {\n transition: opacity m.$duration-toast m.$easing;\n\n .ds-notification__card {\n transition: transform m.$duration-toast m.$easing;\n }\n\n @include m.reduce-motion {\n transition: none;\n\n .ds-notification__card {\n transition: none;\n }\n }\n}\n.ds-notification-enter-from {\n opacity: 0;\n\n .ds-notification__card {\n transform: translateY(8px);\n }\n}\n</style>\n","<template>\n <Teleport to=\"body\">\n <Transition name=\"ds-modal\">\n <div v-if=\"open\" class=\"ds-modal\" @click=\"onBackdrop\">\n <div\n ref=\"dialogRef\"\n class=\"ds-modal__dialog\"\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-label=\"title || 'dialog'\"\n tabindex=\"-1\"\n :style=\"{ width }\"\n @click.stop\n >\n <div v-if=\"title || showClose\" class=\"ds-modal__header\">\n <span class=\"ds-modal__title\">{{ title }}</span>\n <DsButton\n v-if=\"showClose\"\n variant=\"tertiary\"\n circle\n left-icon=\"close\"\n :aria-label=\"closeLabel || undefined\"\n @click=\"emit(CLOSE)\"\n />\n </div>\n\n <div class=\"ds-modal__body\"><slot /></div>\n\n <div v-if=\"$slots.footer\" class=\"ds-modal__footer\"><slot name=\"footer\" /></div>\n </div>\n </div>\n </Transition>\n </Teleport>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch, nextTick, onBeforeUnmount } from 'vue';\nimport { DsButton } from '@shared/ui/DsButton';\nimport { CLOSE } from '@shared/constants/events';\n\nconst props = defineProps({\n open: Boolean,\n title: { type: String, default: '' },\n showClose: { type: Boolean, default: true },\n width: { type: String, default: '440px' },\n closeOnBackdrop: { type: Boolean, default: true },\n closeLabel: { type: String, default: '' },\n});\n\nconst emit = defineEmits([CLOSE]);\n\nconst dialogRef = ref<HTMLElement | null>(null);\nlet lastFocused: HTMLElement | null = null;\n\nfunction onBackdrop() {\n if (props.closeOnBackdrop) emit(CLOSE);\n}\n\nfunction focusables(): HTMLElement[] {\n if (!dialogRef.value) return [];\n const sel =\n 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n return Array.from(dialogRef.value.querySelectorAll<HTMLElement>(sel)).filter(\n (el) => el.offsetParent !== null\n );\n}\n\nfunction onKeydown(e: KeyboardEvent) {\n if (e.key === 'Escape') {\n emit(CLOSE);\n return;\n }\n if (e.key !== 'Tab') return;\n const f = focusables();\n if (f.length === 0) {\n e.preventDefault();\n dialogRef.value?.focus();\n return;\n }\n const first = f[0];\n const last = f[f.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n}\n\nwatch(\n () => props.open,\n (open) => {\n if (typeof document === 'undefined') return;\n if (open) {\n lastFocused = document.activeElement as HTMLElement;\n document.addEventListener('keydown', onKeydown);\n document.body.style.overflow = 'hidden';\n nextTick(() => (focusables()[0] ?? dialogRef.value)?.focus());\n } else {\n document.removeEventListener('keydown', onKeydown);\n document.body.style.overflow = '';\n lastFocused?.focus?.();\n }\n },\n { immediate: true }\n);\n\nonBeforeUnmount(() => {\n if (typeof document === 'undefined') return;\n document.removeEventListener('keydown', onKeydown);\n document.body.style.overflow = '';\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n@use '../../assets/css/shadow.scss' as sh;\n@use '../../assets/css/motion.scss' as m;\n\n.ds-modal {\n position: fixed;\n inset: 0;\n z-index: 2001;\n\n display: flex;\n align-items: flex-start;\n justify-content: center;\n\n padding: 15vh 16px 50px;\n overflow: auto;\n\n background: colors.$backdrop; // grey-10 @ 50%, no blur\n\n &__dialog {\n max-width: 100%;\n\n background: colors.$white;\n\n border-radius: r.$radius-card-lg; // DS readme: 8px (the MCP/API mockup's 6px reconciles up to 8px)\n box-shadow: sh.$shadow-card;\n\n padding: 8px;\n\n outline: none;\n }\n\n &__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n\n min-height: 36px;\n padding: 8px 0 8px 12px;\n\n color: colors.$slate-main;\n font-family: t.$font-family;\n font-size: t.font-size('body');\n font-weight: t.$weight-bold;\n\n border-bottom: 1px solid colors.$slate-tint;\n }\n\n &__body {\n padding: 20px;\n\n color: colors.$slate-main;\n font-family: t.$font-family;\n font-size: t.font-size('body');\n }\n\n &__footer {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n\n padding: 8px;\n\n border-top: 1px solid colors.$slate-tint;\n }\n}\n\n/* Enter/leave: backdrop fades, dialog fades + lifts (0.3s dialog duration). */\n.ds-modal-enter-active,\n.ds-modal-leave-active {\n transition: opacity m.$duration-dialog m.$easing;\n\n .ds-modal__dialog {\n transition: transform m.$duration-dialog m.$easing;\n }\n\n @include m.reduce-motion {\n transition: none;\n\n .ds-modal__dialog {\n transition: none;\n }\n }\n}\n.ds-modal-enter-from,\n.ds-modal-leave-to {\n opacity: 0;\n\n .ds-modal__dialog {\n transform: translateY(-8px);\n }\n}\n</style>\n","// DsVerificationIcon — status glyph for a contact data point.\n// 1:1 with the DS source (components/data/VerificationIcon.jsx):\n// verified === true -> \"verified\" (info-main, blue)\n// verified === false + email -> \"dangerous\" (error-main, coral)\n// verified === false + phone -> \"error\" (warning-main, orange)\n// verified == null (new) -> \"new_releases\" (slate-soft, grey)\n// `isContactData` flags emails (coral) vs phones (orange) when unverified.\n\nexport const DS_VERIFICATION_STATES = {\n VERIFIED: 'verified',\n UNVERIFIED: 'unverified',\n NEW: 'new',\n} as const;\nexport type DsVerificationState =\n (typeof DS_VERIFICATION_STATES)[keyof typeof DS_VERIFICATION_STATES];\n","<template>\n <i\n class=\"material-icons ds-verification-icon\"\n :class=\"[\n `ds-verification-icon--${status.state}`,\n { 'ds-verification-icon--email': isContactData },\n ]\"\n :style=\"{ fontSize: `${size}px` }\"\n role=\"img\"\n :aria-label=\"label || status.label\"\n :title=\"label || status.label\"\n >\n <slot>{{ status.icon }}</slot>\n </i>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, type PropType } from 'vue';\nimport { DS_VERIFICATION_STATES } from './DsVerificationIcon.types';\n\nconst props = defineProps({\n // true = verified · false = not verified · null/undefined = newly found.\n verified: {\n type: Boolean as PropType<boolean | null>,\n default: null,\n },\n // Emails (true) use the coral \"dangerous\" glyph when unverified; phones use orange.\n isContactData: {\n type: Boolean,\n default: false,\n },\n size: {\n type: Number,\n default: 20,\n },\n // Optional override for the accessible label / tooltip (the app owns i18n).\n // Empty → the English default derived from the verification state.\n label: {\n type: String,\n default: '',\n },\n});\n\nconst status = computed(() => {\n if (props.verified === null || props.verified === undefined) {\n return {\n state: DS_VERIFICATION_STATES.NEW,\n icon: 'new_releases',\n label: 'Newly found',\n };\n }\n if (props.verified) {\n return {\n state: DS_VERIFICATION_STATES.VERIFIED,\n icon: 'verified',\n label: 'Verified',\n };\n }\n return {\n state: DS_VERIFICATION_STATES.UNVERIFIED,\n icon: props.isContactData ? 'dangerous' : 'error',\n label: 'Not verified',\n };\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n\n.ds-verification-icon {\n line-height: 1;\n\n // States map DS colors (VerificationIcon.jsx). isContactData splits the\n // unverified color into coral (email) vs orange (phone).\n &--new {\n color: colors.$slate-soft; // --primary-secondary-text\n }\n &--verified {\n color: colors.$info-main;\n }\n &--unverified {\n color: colors.$warning-main; // phone (orange)\n\n &.ds-verification-icon--email {\n color: colors.$error-main; // email (coral \"dangerous\")\n }\n }\n}\n</style>\n","<template>\n <div class=\"ds-contact-value\" :class=\"{ 'ds-contact-value--main': main }\">\n <DsVerificationIcon :verified=\"verified\" :is-contact-data=\"isContactData\" />\n\n <span class=\"ds-contact-value__value\" :title=\"value\">{{ value }}</span>\n\n <!-- Marquee slot: badge and actions share one grid cell and cross-fade/slide\n on hover (or keyboard focus-within). -->\n <span class=\"ds-contact-value__marquee\">\n <DsBadge\n v-if=\"valueType\"\n class=\"ds-contact-value__badge\"\n :tone=\"main ? DS_BADGE_TONES.ACCENT : DS_BADGE_TONES.GREY\"\n aria-hidden=\"true\"\n >{{ valueType }}</DsBadge\n >\n\n <span class=\"ds-contact-value__actions\">\n <button\n type=\"button\"\n class=\"ds-contact-value__action\"\n :class=\"{ 'is-copied': copied }\"\n :aria-label=\"copied ? copiedLabel : copyLabel\"\n :title=\"copied ? copiedLabel : copyLabel\"\n @click=\"handleCopy\"\n >\n <i class=\"material-icons\" aria-hidden=\"true\">{{ copied ? 'check' : 'content_copy' }}</i>\n </button>\n\n <template v-if=\"showRate\">\n <button\n type=\"button\"\n class=\"ds-contact-value__action\"\n :aria-label=\"correctLabel\"\n :aria-pressed=\"correct === true\"\n :title=\"correctLabel\"\n @click=\"handleCorrect\"\n >\n <i\n :class=\"correct === true ? 'material-icons' : 'material-icons-outlined'\"\n aria-hidden=\"true\"\n >thumb_up</i\n >\n </button>\n <button\n type=\"button\"\n class=\"ds-contact-value__action\"\n :aria-label=\"incorrectLabel\"\n :aria-pressed=\"correct === false\"\n :title=\"incorrectLabel\"\n @click=\"handleIncorrect\"\n >\n <i\n :class=\"correct === false ? 'material-icons' : 'material-icons-outlined'\"\n aria-hidden=\"true\"\n >thumb_down</i\n >\n </button>\n </template>\n </span>\n </span>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onBeforeUnmount, type PropType } from 'vue';\nimport { DsVerificationIcon } from '@shared/ui/DsVerificationIcon';\nimport { DsBadge, DS_BADGE_TONES } from '@shared/ui/DsBadge';\nimport { COPY, CORRECT, INCORRECT } from '@shared/constants/events';\n\nconst props = defineProps({\n value: { type: String, required: true },\n valueType: { type: String, default: '' },\n verified: { type: Boolean as PropType<boolean | null>, default: null },\n main: { type: Boolean, default: false },\n isContactData: { type: Boolean, default: false },\n showRate: { type: Boolean, default: false },\n correct: { type: Boolean as PropType<boolean | null>, default: null },\n // User-facing labels (the app owns i18n); English DS defaults.\n copyLabel: { type: String, default: 'Copy' },\n copiedLabel: { type: String, default: 'Copied!' },\n correctLabel: { type: String, default: 'Correct' },\n incorrectLabel: { type: String, default: 'Incorrect' },\n});\n\n// Runtime array so the emit names are registered at runtime (the type-only\n// form with `typeof CONST` compiles to an empty `emits`, which lets listeners\n// fall through as native attrs). Names come from the shared events constants.\nconst emit = defineEmits([COPY, CORRECT, INCORRECT]);\n\nconst copied = ref(false);\nlet copiedTimer: ReturnType<typeof setTimeout> | undefined;\n\nfunction handleCopy() {\n if (typeof navigator !== 'undefined' && navigator.clipboard) {\n navigator.clipboard.writeText(props.value).catch(() => {});\n }\n copied.value = true;\n clearTimeout(copiedTimer);\n copiedTimer = setTimeout(() => {\n copied.value = false;\n }, 1200);\n emit(COPY, props.value);\n}\n\nfunction handleCorrect() {\n emit(CORRECT);\n}\nfunction handleIncorrect() {\n emit(INCORRECT);\n}\n\nonBeforeUnmount(() => clearTimeout(copiedTimer));\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n@use '../../assets/css/motion.scss' as m;\n@use '../../assets/css/icons.scss' as i;\n\n.ds-contact-value {\n display: flex;\n align-items: center;\n\n padding: 6px; // DS ContactValue.jsx\n border-radius: r.$radius-control;\n\n background: transparent;\n transition: background-color m.$duration-default m.$easing;\n\n @include m.reduce-motion {\n transition: none;\n }\n\n &:hover,\n &:focus-within {\n background-color: colors.$slate-bg; // --primary-background\n }\n\n &--main:hover,\n &--main:focus-within {\n background-color: colors.$accent-bg;\n }\n\n // -- value ---------------------------------------------------------------\n &__value {\n flex: 1;\n min-width: 0;\n margin: 0 8px; // DS\n\n color: colors.$slate-main; // --primary-main\n font-family: t.$font-family;\n font-size: t.font-size('body');\n\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n // -- marquee (badge + actions share one cell) ----------------------------\n &__marquee {\n display: inline-grid;\n align-items: center;\n justify-items: end;\n margin-left: auto;\n }\n\n &__badge,\n &__actions {\n grid-area: 1 / 1;\n transition:\n transform m.$duration-reveal m.$easing,\n opacity m.$duration-reveal m.$easing;\n\n @include m.reduce-motion {\n transition: none;\n }\n }\n\n // At rest: badge in place, actions parked to the right and hidden.\n &__badge {\n transform: translateX(0);\n opacity: 1;\n }\n &__actions {\n display: inline-flex;\n align-items: center;\n gap: 8px; // DS\n\n transform: translateX(8px);\n opacity: 0;\n pointer-events: none;\n }\n\n // On hover / keyboard focus: badge slides out, actions slide in.\n &:hover &__badge,\n &:focus-within &__badge {\n transform: translateX(8px);\n opacity: 0;\n }\n &:hover &__actions,\n &:focus-within &__actions {\n transform: translateX(0);\n opacity: 1;\n pointer-events: auto;\n }\n\n // -- action buttons ------------------------------------------------------\n &__action {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n padding: 0;\n border: none;\n background: none;\n cursor: pointer;\n\n color: colors.$slate-soft; // --primary-secondary-text\n\n .material-icons,\n .material-icons-outlined {\n font-size: i.icon-size(20);\n line-height: 1;\n }\n\n &.is-copied {\n color: colors.$success-shadow;\n }\n }\n}\n</style>\n","<template>\n <section class=\"ds-data-card\" :aria-label=\"title\">\n <!-- header -->\n <div\n class=\"ds-data-card__header\"\n :class=\"{ 'is-collapsed': isCollapsed, 'is-collapsible': collapsible }\"\n @click=\"collapsible && toggle()\"\n >\n <div class=\"ds-data-card__heading\">\n <i class=\"material-icons ds-data-card__icon\" aria-hidden=\"true\">{{ icon }}</i>\n <span class=\"ds-data-card__title\">{{ title }}</span>\n </div>\n\n <div class=\"ds-data-card__actions\" @click.stop>\n <button\n v-if=\"!isCollapsed && showEdit\"\n type=\"button\"\n class=\"ds-data-card__edit\"\n @click=\"onEdit\"\n >\n {{ editLabel }}\n </button>\n\n <DsButton\n v-if=\"!isCollapsed && showSort\"\n variant=\"tertiary\"\n size=\"medium\"\n circle\n left-icon=\"swap_vert\"\n :aria-label=\"sortLabel\"\n @click=\"onSort\"\n />\n\n <DsButton\n v-if=\"collapsible\"\n variant=\"tertiary\"\n size=\"medium\"\n circle\n :left-icon=\"collapsed ? 'keyboard_arrow_down' : 'keyboard_arrow_up'\"\n :aria-label=\"toggleLabel\"\n @click=\"toggle\"\n />\n\n <button\n v-if=\"showClose\"\n type=\"button\"\n class=\"ds-data-card__close\"\n :aria-label=\"closeLabel\"\n @click=\"onClose\"\n >\n <i class=\"material-icons\" aria-hidden=\"true\">close</i>\n </button>\n </div>\n </div>\n\n <!-- body -->\n <div v-if=\"!isCollapsed\" class=\"ds-data-card__body\">\n <div v-if=\"empty\" class=\"ds-data-card__empty\">\n <i class=\"material-icons-outlined ds-data-card__empty-icon\" aria-hidden=\"true\">{{\n icon\n }}</i>\n <span>{{ emptyLabel }}</span>\n </div>\n\n <template v-else>\n <div v-if=\"mostLikely\">\n <div v-if=\"showSections\" class=\"ds-data-card__section\">{{ mostLikelyLabel }}</div>\n <DsContactValue\n :value=\"mostLikely.value\"\n :value-type=\"mostLikely.type\"\n :verified=\"mostLikely.verified\"\n :correct=\"mostLikely.correct\"\n main\n :is-contact-data=\"isContactData\"\n :show-rate=\"showRate\"\n @copy=\"onCopy\"\n @correct=\"onCorrect(mostLikely)\"\n @incorrect=\"onIncorrect(mostLikely)\"\n />\n </div>\n\n <div v-if=\"more.length > 0\">\n <div v-if=\"showSections\" class=\"ds-data-card__section\">{{ moreLabel }}</div>\n <div class=\"ds-data-card__more\">\n <DsContactValue\n v-for=\"datum in more\"\n :key=\"datum.value\"\n :value=\"datum.value\"\n :value-type=\"datum.type\"\n :verified=\"datum.verified\"\n :correct=\"datum.correct\"\n :is-contact-data=\"isContactData\"\n :show-rate=\"showRate\"\n @copy=\"onCopy\"\n @correct=\"onCorrect(datum)\"\n @incorrect=\"onIncorrect(datum)\"\n />\n </div>\n </div>\n </template>\n </div>\n </section>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, type PropType } from 'vue';\nimport { DsButton } from '@shared/ui/DsButton';\nimport { DsContactValue } from '@shared/ui/DsContactValue';\nimport { COPY, SORT, EDIT, CLOSE, CORRECT, INCORRECT } from '@shared/constants/events';\nimport type { DsContactDatum } from './DsDataCard.types';\n\nconst props = defineProps({\n title: { type: String, required: true },\n // Material Icon name for the header (e.g. \"email\", \"call\").\n icon: { type: String, default: 'email' },\n mostLikely: { type: Object as PropType<DsContactDatum | null>, default: null },\n more: { type: Array as PropType<DsContactDatum[]>, default: () => [] },\n collapsible: { type: Boolean, default: false },\n showSort: { type: Boolean, default: true },\n showEdit: { type: Boolean, default: false },\n showClose: { type: Boolean, default: false },\n isContactData: { type: Boolean, default: false },\n showRate: { type: Boolean, default: false },\n // User-facing labels (the app owns i18n); English DS defaults.\n editLabel: { type: String, default: 'Edit' },\n emptyLabel: { type: String, default: 'No data found' },\n mostLikelyLabel: { type: String, default: 'MOST LIKELY' },\n moreLabel: { type: String, default: 'MORE' },\n sortLabel: { type: String, default: 'Sort' },\n toggleLabel: { type: String, default: 'Toggle' },\n closeLabel: { type: String, default: 'Close' },\n});\n\n// Runtime array so the emit names are registered at runtime (the type-only\n// form with `typeof CONST` compiles to an empty `emits`, which lets listeners\n// fall through as native attrs). Names come from the shared events constants.\nconst emit = defineEmits([COPY, SORT, EDIT, CLOSE, CORRECT, INCORRECT]);\n\nconst collapsed = ref(false);\n\nconst total = computed(() => props.more.length + (props.mostLikely ? 1 : 0));\nconst showSections = computed(() => total.value > 3);\nconst empty = computed(() => total.value === 0);\nconst isCollapsed = computed(() => props.collapsible && collapsed.value);\n\nfunction toggle() {\n collapsed.value = !collapsed.value;\n}\nfunction onCopy(value: string) {\n emit(COPY, value);\n}\nfunction onSort() {\n emit(SORT);\n}\nfunction onEdit() {\n emit(EDIT);\n}\nfunction onClose() {\n emit(CLOSE);\n}\nfunction onCorrect(datum: DsContactDatum) {\n emit(CORRECT, datum);\n}\nfunction onIncorrect(datum: DsContactDatum) {\n emit(INCORRECT, datum);\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@use '../../assets/css/colors.scss' as colors;\n@use '../../assets/css/typography.scss' as t;\n@use '../../assets/css/radius.scss' as r;\n@use '../../assets/css/shadow.scss' as sh;\n@use '../../assets/css/icons.scss' as i;\n\n.ds-data-card {\n display: block;\n\n padding: 8px;\n\n background-color: colors.$white;\n border-radius: r.$radius-card;\n box-shadow: sh.$shadow-card;\n\n // -- header --------------------------------------------------------------\n &__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n\n padding: 6px 6px 14px; // DS DataCard.jsx\n border-bottom: 1px solid colors.$slate-tint; // --primary-tint\n\n &.is-collapsible {\n cursor: pointer;\n }\n &.is-collapsed {\n border-bottom: none;\n }\n }\n\n &__heading {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n }\n\n &__icon {\n font-size: i.icon-size(20);\n line-height: 1;\n color: colors.$slate-main; // --primary-main\n }\n\n &__title {\n font-family: t.$font-family;\n font-weight: t.$weight-bold;\n font-size: t.font-size('body');\n color: colors.$slate-main;\n\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n &__actions {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n &__edit {\n padding: 0;\n border: none;\n background: none;\n cursor: pointer;\n\n font-family: t.$font-family;\n font-weight: t.$weight-bold;\n font-size: t.font-size('caption');\n color: colors.$accent-main;\n }\n\n &__close {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n\n padding: 0;\n border: none;\n background: none;\n cursor: pointer;\n\n color: colors.$slate-soft; // --primary-secondary-text\n\n .material-icons {\n font-size: i.icon-size(20);\n line-height: 1;\n }\n }\n\n // -- body ----------------------------------------------------------------\n &__body {\n padding-top: 8px;\n }\n\n &__section {\n padding: 6px;\n\n font-family: t.$font-family;\n font-size: t.font-size('micro');\n line-height: 18px;\n letter-spacing: 0.04em;\n color: colors.$slate-main;\n }\n\n &__more {\n display: flex;\n flex-direction: column;\n gap: 8px;\n\n max-height: 132px; // DS: ~3 rows before the \"MORE\" list scrolls\n overflow: auto;\n }\n\n &__empty {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px;\n\n font-family: t.$font-family;\n font-size: t.font-size('body');\n color: colors.$slate-main;\n }\n\n &__empty-icon {\n font-size: i.icon-size(20);\n line-height: 1;\n color: colors.$slate-soft;\n }\n}\n</style>\n"],"names":["DS_SPINNER_TONES","_createElementBlock","_normalizeClass","__props","_normalizeStyle","CLICK","CLOSE","FOCUS","BLUR","COPY","CORRECT","INCORRECT","SORT","EDIT","DS_BUTTON_VARIANTS","DS_BUTTON_SIZES","DS_BUTTON_NATIVE_TYPES","props","emit","__emit","iconSize","computed","spinnerTone","handleClick","event","_createBlock","_unref","DsSpinner","$slots","_openBlock","_hoisted_2","_renderSlot","_ctx","_createElementVNode","_hoisted_3","_toDisplayString","_hoisted_4","_hoisted_5","_hoisted_6","DS_TAG_TONES","_cache","$event","DS_BADGE_TONES","initials","ariaLabel","boxStyle","hashed","seed","hash","i","rgb","light","DS_TABLE_ALIGN","rowHeightStyle","_hoisted_1","_Fragment","_renderList","column","_a","row","DS_INPUT_TYPES","DS_INPUT_SIZES","model","_useModel","slots","useSlots","reveal","ref","isPassword","resolvedType","hasSuffix","_hoisted_7","inputRef","syncIndeterminate","onMounted","watch","DS_ALERT_TYPES","DS_ALERT_EFFECTS","DS_ALERT_ICONS","visible","icon","hasBody","onClose","DS_NOTIFICATION_TYPES","DS_NOTIFICATION_POSITIONS","DS_NOTIFICATION_ICONS","timer","startedAt","remaining","clearTimer","schedule","ms","pause","resume","onBeforeUnmount","_Teleport","_createVNode","_Transition","dialogRef","lastFocused","onBackdrop","focusables","el","onKeydown","e","f","first","last","open","nextTick","_b","DsButton","DS_VERIFICATION_STATES","status","_createTextVNode","copied","copiedTimer","handleCopy","handleCorrect","handleIncorrect","DsVerificationIcon","DsBadge","collapsed","total","showSections","empty","isCollapsed","toggle","onCopy","value","onSort","onEdit","onCorrect","datum","onIncorrect","_hoisted_8","_hoisted_9","_hoisted_10","DsContactValue","_hoisted_11","_hoisted_12","_hoisted_13"],"mappings":"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"}