@cognitvs/a11y-widget 0.0.0-stage → 1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a11y-widget.umd.cjs","sources":["../src/state/store.ts","../src/features/dom-effects.ts","../src/features/tts.ts","../src/features/cursor-magnet.ts","../src/features/scroll-assist.ts","../src/features/vlibras.ts","../src/widget.ts","../src/index.ts"],"sourcesContent":["import { A11yState, AssistiveProfile, DaltonismMode, MagnetForce, TTSSpeed, TextSpacingLevel } from '../types';\n\ntype Listener = (state: A11yState) => void;\n\nexport class A11yStore {\n private prefix: string;\n private state: A11yState;\n private listeners: Set<Listener> = new Set();\n\n constructor(prefix = 'cognitvs') {\n this.prefix = prefix;\n this.state = this.loadInitialState();\n }\n\n public getState(): A11yState {\n return { ...this.state };\n }\n\n public subscribe(listener: Listener): () => void {\n this.listeners.add(listener);\n listener(this.getState());\n return () => this.listeners.delete(listener);\n }\n\n private notify(): void {\n const current = this.getState();\n this.listeners.forEach((fn) => fn(current));\n }\n\n private loadInitialState(): A11yState {\n const getItem = (key: string) => {\n try {\n return localStorage.getItem(`${this.prefix}_${key}`);\n } catch {\n return null;\n }\n };\n\n const fontScale = parseFloat(getItem('font_scale') || '1') || 1;\n const isHighContrast = getItem('high_contrast') === 'true';\n const isReduceMotion = getItem('reduce_motion') === 'true';\n const isBigCursor = getItem('big_cursor') === 'true';\n const isKeyboardFocus = getItem('keyboard_focus') === 'true';\n const isHighlightLinks = getItem('highlight_links') === 'true';\n const isReadingMaskActive = getItem('reading_mask') === 'true';\n const isReadingMaskSmart = getItem('reading_mask_smart') !== 'false';\n const isDyslexiaMode = getItem('dyslexia') === 'true';\n const textSpacingLevel = (parseInt(getItem('text_spacing') || '0', 10) || 0) as TextSpacingLevel;\n const colorBlindMode = (getItem('colorblind') || 'none') as DaltonismMode;\n const isScrollAssistActive = getItem('scroll_assist') === 'true';\n const isCursorMagnetActive = getItem('magnet_cursor') === 'true';\n const cursorMagnetForce = (getItem('magnet_force') || 'suave') as MagnetForce;\n const isVLibrasActive = getItem('vlibras') === 'true';\n const isTTSActive = getItem('tts') === 'true';\n const ttsRate = (parseFloat(getItem('tts_rate') || '1') || 1) as TTSSpeed;\n const hasSeenTour = getItem('seen_tour') === 'true';\n const bannerDismissed = getItem('banner_dismissed') === 'true';\n\n return {\n isExpanded: false,\n activeProfile: 'all',\n fontScale,\n isHighContrast,\n isReadingMaskActive,\n isReadingMaskSmart,\n colorBlindMode,\n isDaltonismMenuOpen: false,\n isTTSActive,\n ttsRate,\n isVLibrasActive,\n isBigCursor,\n isKeyboardFocus,\n isScrollAssistActive,\n isCursorMagnetActive,\n cursorMagnetForce,\n isHighlightLinks,\n isReduceMotion,\n isDyslexiaMode,\n textSpacingLevel,\n showAttentionGrabber: false,\n hasInteracted: hasSeenTour,\n bannerDismissed,\n };\n }\n\n public setStorage(key: string, value: string): void {\n try {\n localStorage.setItem(`${this.prefix}_${key}`, value);\n } catch (e) {\n console.warn('A11yWidget: falha ao salvar no localStorage', e);\n }\n }\n\n public removeStorage(key: string): void {\n try {\n localStorage.removeItem(`${this.prefix}_${key}`);\n } catch (e) {\n console.warn('A11yWidget: falha ao remover do localStorage', e);\n }\n }\n\n public update(partial: Partial<A11yState>): void {\n this.state = { ...this.state, ...partial };\n this.notify();\n }\n\n public toggleExpanded(): void {\n this.update({\n isExpanded: !this.state.isExpanded,\n showAttentionGrabber: false,\n hasInteracted: true,\n });\n this.setStorage('seen_tour', 'true');\n }\n\n public setActiveProfile(profile: AssistiveProfile): void {\n this.update({ activeProfile: profile });\n }\n\n public updateFontScale(delta: number): void {\n const newScale = Math.min(Math.max(parseFloat((this.state.fontScale + delta).toFixed(2)), 0.8), 2.0);\n this.update({ fontScale: newScale });\n this.setStorage('font_scale', newScale.toString());\n }\n\n public toggleHighContrast(): void {\n const val = !this.state.isHighContrast;\n this.update({ isHighContrast: val });\n this.setStorage('high_contrast', val.toString());\n }\n\n public toggleReduceMotion(): void {\n const val = !this.state.isReduceMotion;\n this.update({ isReduceMotion: val });\n this.setStorage('reduce_motion', val.toString());\n }\n\n public toggleBigCursor(): void {\n const val = !this.state.isBigCursor;\n this.update({ isBigCursor: val });\n this.setStorage('big_cursor', val.toString());\n }\n\n public toggleKeyboardFocus(): void {\n const val = !this.state.isKeyboardFocus;\n this.update({ isKeyboardFocus: val });\n this.setStorage('keyboard_focus', val.toString());\n }\n\n public toggleHighlightLinks(): void {\n const val = !this.state.isHighlightLinks;\n this.update({ isHighlightLinks: val });\n this.setStorage('highlight_links', val.toString());\n }\n\n public toggleScrollAssist(): void {\n const val = !this.state.isScrollAssistActive;\n this.update({ isScrollAssistActive: val });\n this.setStorage('scroll_assist', val.toString());\n }\n\n public toggleCursorMagnet(): void {\n const val = !this.state.isCursorMagnetActive;\n this.update({ isCursorMagnetActive: val });\n this.setStorage('magnet_cursor', val.toString());\n }\n\n public setCursorMagnetForce(force: MagnetForce): void {\n this.update({ cursorMagnetForce: force });\n this.setStorage('magnet_force', force);\n }\n\n public toggleReadingMask(): void {\n const val = !this.state.isReadingMaskActive;\n this.update({ isReadingMaskActive: val });\n this.setStorage('reading_mask', val.toString());\n }\n\n public setReadingMaskSmart(smart: boolean): void {\n this.update({ isReadingMaskSmart: smart });\n this.setStorage('reading_mask_smart', smart.toString());\n }\n\n public toggleDyslexia(): void {\n const val = !this.state.isDyslexiaMode;\n this.update({ isDyslexiaMode: val });\n this.setStorage('dyslexia', val.toString());\n }\n\n public setTextSpacing(level: TextSpacingLevel): void {\n this.update({ textSpacingLevel: level });\n this.setStorage('text_spacing', level.toString());\n }\n\n public setColorBlindMode(mode: DaltonismMode): void {\n this.update({ colorBlindMode: mode, isDaltonismMenuOpen: false });\n this.setStorage('colorblind', mode);\n }\n\n public toggleDaltonismMenu(): void {\n this.update({ isDaltonismMenuOpen: !this.state.isDaltonismMenuOpen });\n }\n\n public toggleTTS(): void {\n const val = !this.state.isTTSActive;\n const rate = val ? 1 : this.state.ttsRate;\n this.update({ isTTSActive: val, ttsRate: rate });\n this.setStorage('tts', val.toString());\n if (val) this.setStorage('tts_rate', '1');\n }\n\n public setTTSRate(rate: TTSSpeed): void {\n this.update({ ttsRate: rate });\n this.setStorage('tts_rate', rate.toString());\n }\n\n public toggleVLibras(): void {\n const val = !this.state.isVLibrasActive;\n this.update({ isVLibrasActive: val });\n this.setStorage('vlibras', val.toString());\n }\n\n public dismissBanner(): void {\n this.update({ bannerDismissed: true });\n this.setStorage('banner_dismissed', 'true');\n }\n\n public resetAll(): void {\n const keys = [\n 'font_scale',\n 'high_contrast',\n 'reduce_motion',\n 'big_cursor',\n 'keyboard_focus',\n 'highlight_links',\n 'reading_mask',\n 'reading_mask_smart',\n 'dyslexia',\n 'text_spacing',\n 'colorblind',\n 'vlibras',\n 'magnet_cursor',\n 'magnet_force',\n 'tts',\n 'tts_rate',\n ];\n keys.forEach((k) => this.removeStorage(k));\n\n this.update({\n fontScale: 1,\n isHighContrast: false,\n isReadingMaskActive: false,\n isReadingMaskSmart: true,\n colorBlindMode: 'none',\n isDaltonismMenuOpen: false,\n isTTSActive: false,\n ttsRate: 1,\n isVLibrasActive: false,\n isBigCursor: false,\n isKeyboardFocus: false,\n isScrollAssistActive: false,\n isCursorMagnetActive: false,\n cursorMagnetForce: 'suave',\n isHighlightLinks: false,\n isReduceMotion: false,\n isDyslexiaMode: false,\n textSpacingLevel: 0,\n });\n }\n}\n","import { A11yState } from '../types';\n\nexport class DomEffectsManager {\n private prevClasses: Set<string> = new Set();\n private readingMaskEl: HTMLDivElement | null = null;\n private maskFrameId: number | null = null;\n private boundMouseMove: ((e: MouseEvent) => void) | null = null;\n\n public applyGlobalState(state: A11yState): void {\n const docEl = document.documentElement;\n\n // Escala de Fonte\n docEl.style.setProperty('--font-scale', state.fontScale.toString());\n\n // Classes no elemento raiz\n this.syncClass(docEl, 'high-contrast', state.isHighContrast);\n this.syncClass(docEl, 'reduce-motion', state.isReduceMotion);\n this.syncClass(docEl, 'big-cursor', state.isBigCursor);\n this.syncClass(docEl, 'keyboard-focus', state.isKeyboardFocus);\n this.syncClass(docEl, 'highlight-links', state.isHighlightLinks);\n this.syncClass(docEl, 'scroll-assist-active', state.isScrollAssistActive);\n this.syncClass(docEl, 'cursor-magnet-active', state.isCursorMagnetActive);\n this.syncClass(docEl, 'dyslexia-mode', state.isDyslexiaMode);\n\n // Força do ímã de cursor\n docEl.setAttribute('data-magnet-force', state.cursorMagnetForce);\n\n // Espaçamento de Texto\n docEl.classList.remove('text-spacing-1', 'text-spacing-2');\n if (state.textSpacingLevel > 0) {\n docEl.classList.add(`text-spacing-${state.textSpacingLevel}`);\n }\n\n // Daltonismo\n ['protanopia', 'deuteranopia', 'tritanopia', 'monochromacy'].forEach((m) => {\n docEl.classList.remove(`daltonism-${m}`);\n });\n if (state.colorBlindMode !== 'none') {\n docEl.classList.add(`daltonism-${state.colorBlindMode}`);\n }\n\n // Máscara de Leitura\n this.syncReadingMask(state.isReadingMaskActive, state.isReadingMaskSmart);\n }\n\n private syncClass(el: HTMLElement, className: string, active: boolean): void {\n if (active) {\n el.classList.add(className);\n this.prevClasses.add(className);\n } else {\n el.classList.remove(className);\n this.prevClasses.delete(className);\n }\n }\n\n private syncReadingMask(active: boolean, isSmart: boolean): void {\n if (!active) {\n if (this.readingMaskEl) {\n this.readingMaskEl.remove();\n this.readingMaskEl = null;\n }\n if (this.boundMouseMove) {\n window.removeEventListener('mousemove', this.boundMouseMove);\n this.boundMouseMove = null;\n }\n if (this.maskFrameId) {\n cancelAnimationFrame(this.maskFrameId);\n this.maskFrameId = null;\n }\n return;\n }\n\n if (!this.readingMaskEl) {\n this.readingMaskEl = document.createElement('div');\n this.readingMaskEl.id = 'cognitvs-a11y-reading-mask';\n this.readingMaskEl.setAttribute('aria-hidden', 'true');\n this.readingMaskEl.style.cssText = `\n position: fixed;\n left: 0;\n width: 100vw;\n pointer-events: none;\n z-index: 999998;\n border-top: 2px solid rgba(0, 119, 212, 0.7);\n border-bottom: 2px solid rgba(0, 119, 212, 0.7);\n box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.7);\n height: var(--mask-height, 140px);\n top: var(--mask-top, calc(50vh - 70px));\n transition: top 0.15s cubic-bezier(0.2, 0, 0, 1), height 0.15s cubic-bezier(0.2, 0, 0, 1);\n `;\n document.body.appendChild(this.readingMaskEl);\n }\n\n let lastTarget: Element | null = null;\n\n if (this.boundMouseMove) {\n window.removeEventListener('mousemove', this.boundMouseMove);\n }\n\n this.boundMouseMove = (e: MouseEvent) => {\n if (this.maskFrameId) cancelAnimationFrame(this.maskFrameId);\n this.maskFrameId = requestAnimationFrame(() => {\n if (isSmart) {\n const target = document.elementFromPoint(e.clientX, e.clientY);\n if (target) {\n const textContainer = target.closest('p, h1, h2, h3, h4, h5, h6, li, blockquote, figcaption, td, th, a, button, label');\n const elToMeasure = textContainer || target;\n const rect = elToMeasure.getBoundingClientRect();\n if (textContainer && rect.height > 10 && rect.height < 500) {\n if (elToMeasure !== lastTarget) {\n lastTarget = elToMeasure;\n const margin = 24;\n const maskHeight = rect.height + margin;\n const topPos = rect.top - margin / 2;\n document.documentElement.style.setProperty('--mask-height', `${maskHeight}px`);\n document.documentElement.style.setProperty('--mask-top', `${topPos}px`);\n }\n return;\n }\n }\n }\n lastTarget = null;\n document.documentElement.style.setProperty('--mask-height', '140px');\n document.documentElement.style.setProperty('--mask-top', `${e.clientY - 70}px`);\n });\n };\n\n window.addEventListener('mousemove', this.boundMouseMove, { passive: true });\n }\n\n public destroy(): void {\n const docEl = document.documentElement;\n this.prevClasses.forEach((c) => docEl.classList.remove(c));\n ['protanopia', 'deuteranopia', 'tritanopia', 'monochromacy', 'text-spacing-1', 'text-spacing-2'].forEach((c) => docEl.classList.remove(c));\n docEl.style.removeProperty('--font-scale');\n docEl.removeAttribute('data-magnet-force');\n this.syncReadingMask(false, false);\n }\n}\n","import { TTSSpeed } from '../types';\n\nexport class TTSController {\n private active = false;\n private rate: TTSSpeed = 1;\n private boundClickHandler: ((e: MouseEvent) => void) | null = null;\n private isWidgetElement: (el: Node) => boolean;\n\n constructor(isWidgetElement: (el: Node) => boolean) {\n this.isWidgetElement = isWidgetElement;\n }\n\n public update(active: boolean, rate: TTSSpeed): void {\n this.active = active;\n this.rate = rate;\n\n if (!active) {\n if (typeof window !== 'undefined' && 'speechSynthesis' in window) {\n window.speechSynthesis.cancel();\n }\n if (this.boundClickHandler) {\n document.removeEventListener('click', this.boundClickHandler, { capture: true });\n this.boundClickHandler = null;\n }\n return;\n }\n\n if (!this.boundClickHandler) {\n this.boundClickHandler = this.handleClick.bind(this);\n document.addEventListener('click', this.boundClickHandler, { capture: true });\n }\n }\n\n private handleClick(e: MouseEvent): void {\n if (!this.active) return;\n const target = e.target as HTMLElement | null;\n if (!target) return;\n\n // Não processa se o clique foi dentro do widget de acessibilidade\n if (this.isWidgetElement(target)) return;\n\n // Proteção de Layout: Evita containers gigantes estruturais\n const invalidTags = [\n 'BODY', 'HTML', 'MAIN', 'SECTION', 'ARTICLE', 'HEADER',\n 'FOOTER', 'NAV', 'ASIDE', 'FORM', 'UL', 'OL', 'TABLE', 'TBODY', 'TR'\n ];\n if (invalidTags.includes(target.tagName) || target.id === 'root') return;\n\n const blockTags = [\n 'DIV', 'P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'UL', 'OL', 'LI',\n 'SECTION', 'ARTICLE', 'IMG', 'PICTURE', 'VIDEO', 'HEADER', 'FOOTER',\n 'NAV', 'ASIDE', 'FORM', 'TABLE', 'TR', 'TD', 'TH', 'MAIN'\n ];\n const hasBlockChildren = Array.from(target.children).some((child) => blockTags.includes(child.tagName));\n if (hasBlockChildren) return;\n\n const rawText = target.innerText || target.textContent || '';\n const text = rawText.replace(/[\\p{Extended_Pictographic}]/gu, '').trim();\n\n if (text.length > 0 && 'speechSynthesis' in window) {\n if (target.closest('a') || target.closest('button')) {\n e.preventDefault();\n e.stopPropagation();\n }\n\n window.speechSynthesis.cancel();\n const utterance = new SpeechSynthesisUtterance(text);\n utterance.lang = 'pt-BR';\n utterance.rate = this.rate;\n\n const originalHTML = target.innerHTML;\n const originalOutline = target.style.outline;\n const originalOutlineOffset = target.style.outlineOffset;\n\n // Efeito Karaokê (in-place)\n const tokens = text.split(/(\\s+)/);\n target.innerHTML = '';\n const spanElements: HTMLSpanElement[] = [];\n\n tokens.forEach((token) => {\n const span = document.createElement('span');\n span.textContent = token;\n span.style.transition = 'all 150ms ease-in-out';\n span.style.borderRadius = '2px';\n target.appendChild(span);\n spanElements.push(span);\n });\n\n target.style.outline = '3px solid #f59e0b';\n target.style.outlineOffset = '2px';\n\n utterance.onboundary = (ev) => {\n if (ev.name === 'word') {\n let charCount = 0;\n for (let i = 0; i < spanElements.length; i++) {\n const spanText = spanElements[i].textContent || '';\n const span = spanElements[i];\n\n if (charCount <= ev.charIndex && charCount + spanText.length > ev.charIndex && spanText.trim().length > 0) {\n span.style.backgroundColor = '#fef08a';\n span.style.color = '#0f172a';\n span.style.boxShadow = '0 0 0 2px #fef08a';\n } else {\n span.style.backgroundColor = 'transparent';\n span.style.color = 'inherit';\n span.style.boxShadow = '0 0 0 2px transparent';\n }\n charCount += spanText.length;\n }\n }\n };\n\n const restoreDOM = () => {\n target.style.outline = originalOutline;\n target.style.outlineOffset = originalOutlineOffset;\n target.innerHTML = originalHTML;\n };\n\n utterance.onend = restoreDOM;\n utterance.onerror = restoreDOM;\n\n window.speechSynthesis.speak(utterance);\n }\n }\n\n public destroy(): void {\n if (this.boundClickHandler) {\n document.removeEventListener('click', this.boundClickHandler, { capture: true });\n this.boundClickHandler = null;\n }\n if (typeof window !== 'undefined' && 'speechSynthesis' in window) {\n window.speechSynthesis.cancel();\n }\n }\n}\n","import { MagnetForce } from '../types';\n\nexport class CursorMagnetController {\n private active = false;\n private force: MagnetForce = 'suave';\n private cursorEl: HTMLDivElement | null = null;\n private isMagnetized = false;\n private targetButton: HTMLElement | null = null;\n private cachedButtons: { el: HTMLElement; rect: DOMRect }[] = [];\n private lastCacheTime = 0;\n private isBig = false;\n\n private boundMouseMove: ((e: MouseEvent) => void) | null = null;\n private boundClick: ((e: MouseEvent) => void) | null = null;\n private boundScroll: (() => void) | null = null;\n\n public update(active: boolean, force: MagnetForce, isBig: boolean): void {\n this.active = active;\n this.force = force;\n this.isBig = isBig;\n\n if (!active) {\n this.teardown();\n return;\n }\n\n if (!this.boundMouseMove) {\n this.setup();\n }\n }\n\n private setup(): void {\n this.boundMouseMove = this.handleMouseMove.bind(this);\n this.boundClick = this.handleClick.bind(this);\n this.boundScroll = () => { this.lastCacheTime = 0; };\n\n window.addEventListener('mousemove', this.boundMouseMove, { passive: true });\n window.addEventListener('click', this.boundClick, { capture: true });\n window.addEventListener('scroll', this.boundScroll, { passive: true });\n }\n\n private teardown(): void {\n if (this.boundMouseMove) {\n window.removeEventListener('mousemove', this.boundMouseMove);\n this.boundMouseMove = null;\n }\n if (this.boundClick) {\n window.removeEventListener('click', this.boundClick, { capture: true });\n this.boundClick = null;\n }\n if (this.boundScroll) {\n window.removeEventListener('scroll', this.boundScroll);\n this.boundScroll = null;\n }\n\n document.documentElement.classList.remove('cursor-hidden');\n this.isMagnetized = false;\n this.targetButton = null;\n if (this.cursorEl) {\n this.cursorEl.remove();\n this.cursorEl = null;\n }\n }\n\n private ensureCursorElement(): HTMLDivElement {\n if (!this.cursorEl) {\n this.cursorEl = document.createElement('div');\n this.cursorEl.id = 'cognitvs-a11y-virtual-cursor';\n this.cursorEl.setAttribute('aria-hidden', 'true');\n this.cursorEl.style.cssText = `\n position: fixed;\n pointer-events: none;\n z-index: 999999;\n transition: transform 75ms ease;\n transform: translate(-5px, -5px);\n filter: drop-shadow(0 0 10px rgba(0, 119, 212, 0.9));\n `;\n document.body.appendChild(this.cursorEl);\n }\n this.cursorEl.innerHTML = this.isBig\n ? `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\" viewBox=\"0 0 32 32\">\n <path fill=\"#ffffff\" stroke=\"#0077d4\" stroke-width=\"3\" stroke-linejoin=\"round\" d=\"M2 2 L2 28 L9 22 L15 31 L19 29 L12 20 L21 20 Z\" />\n </svg>`\n : `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"28\" height=\"28\" viewBox=\"0 0 32 32\">\n <path fill=\"#ffffff\" stroke=\"#0077d4\" stroke-width=\"2.5\" stroke-linejoin=\"round\" d=\"M2 2 L2 28 L9 22 L15 31 L19 29 L12 20 L21 20 Z\" />\n </svg>`;\n return this.cursorEl;\n }\n\n private updateButtonCache(): void {\n const now = Date.now();\n if (now - this.lastCacheTime > 200) {\n const elements = document.querySelectorAll('a, button, [role=\"button\"], input[type=\"submit\"], input[type=\"button\"]');\n this.cachedButtons = Array.from(elements).map((el) => ({\n el: el as HTMLElement,\n rect: el.getBoundingClientRect(),\n }));\n this.lastCacheTime = now;\n }\n }\n\n private handleMouseMove(e: MouseEvent): void {\n if (!this.active) return;\n const ATTRACTION_RADIUS = this.force === 'forte' ? 45 : 25;\n const ESCAPE_RADIUS = this.force === 'forte' ? 60 : 40;\n\n this.updateButtonCache();\n const mouseX = e.clientX;\n const mouseY = e.clientY;\n\n let targetDistance = Infinity;\n let targetCenter = { x: 0, y: 0 };\n let closestDistance = Infinity;\n let closestButton: HTMLElement | null = null;\n let closestCenter = { x: 0, y: 0 };\n\n for (const { el } of this.cachedButtons) {\n const currentRect = el.getBoundingClientRect();\n const centerX = currentRect.left + currentRect.width / 2;\n const centerY = currentRect.top + currentRect.height / 2;\n\n const dxEdge = Math.max(currentRect.left - mouseX, 0, mouseX - currentRect.right);\n const dyEdge = Math.max(currentRect.top - mouseY, 0, mouseY - currentRect.bottom);\n const distanceToEdge = Math.sqrt(dxEdge * dxEdge + dyEdge * dyEdge);\n\n if (distanceToEdge < closestDistance) {\n closestDistance = distanceToEdge;\n closestButton = el;\n closestCenter = { x: centerX, y: centerY };\n }\n\n if (el === this.targetButton) {\n targetDistance = distanceToEdge;\n targetCenter = { x: centerX, y: centerY };\n }\n }\n\n // Histerese Magnética\n if (this.isMagnetized && this.targetButton) {\n if (targetDistance > ESCAPE_RADIUS) {\n this.isMagnetized = false;\n this.targetButton = null;\n document.documentElement.classList.remove('cursor-hidden');\n\n if (closestDistance < ATTRACTION_RADIUS && closestButton) {\n this.isMagnetized = true;\n this.targetButton = closestButton;\n this.setCursorPos(closestCenter.x, closestCenter.y);\n document.documentElement.classList.add('cursor-hidden');\n } else {\n this.hideVirtualCursor();\n }\n } else {\n this.setCursorPos(targetCenter.x, targetCenter.y);\n }\n } else {\n if (closestDistance < ATTRACTION_RADIUS && closestButton) {\n this.isMagnetized = true;\n this.targetButton = closestButton;\n this.setCursorPos(closestCenter.x, closestCenter.y);\n document.documentElement.classList.add('cursor-hidden');\n } else {\n this.hideVirtualCursor();\n }\n }\n }\n\n private setCursorPos(x: number, y: number): void {\n const el = this.ensureCursorElement();\n el.style.display = 'block';\n el.style.left = `${x}px`;\n el.style.top = `${y}px`;\n }\n\n private hideVirtualCursor(): void {\n if (this.cursorEl) {\n this.cursorEl.style.display = 'none';\n }\n document.documentElement.classList.remove('cursor-hidden');\n }\n\n private handleClick(e: MouseEvent): void {\n if (!this.active) return;\n this.lastCacheTime = 0;\n\n if (this.isMagnetized && this.targetButton) {\n if (!this.targetButton.contains(e.target as Node)) {\n e.preventDefault();\n e.stopPropagation();\n this.targetButton.click();\n }\n }\n }\n\n public destroy(): void {\n this.teardown();\n }\n}\n","export class ScrollAssistController {\n private containerEl: HTMLDivElement | null = null;\n private boundScroll: (() => void) | null = null;\n\n public update(active: boolean): void {\n if (!active) {\n this.teardown();\n return;\n }\n if (!this.containerEl) {\n this.setup();\n }\n this.checkScrollLimits();\n }\n\n private setup(): void {\n this.containerEl = document.createElement('div');\n this.containerEl.id = 'cognitvs-a11y-scroll-assist';\n this.containerEl.setAttribute('aria-label', 'Assistente de Rolagem');\n this.containerEl.style.cssText = `\n position: fixed;\n bottom: 24px;\n left: 24px;\n z-index: 999990;\n display: flex;\n flex-direction: column;\n gap: 12px;\n pointer-events: auto;\n `;\n\n const upBtn = document.createElement('button');\n upBtn.id = 'cognitvs-scroll-up';\n upBtn.setAttribute('aria-label', 'Rolar para cima');\n upBtn.title = 'Rolar para cima';\n upBtn.innerHTML = `\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"18 15 12 9 6 15\"></polyline>\n </svg>\n `;\n this.styleButton(upBtn, false);\n upBtn.onclick = () => window.scrollBy({ top: -window.innerHeight * 0.7, behavior: 'smooth' });\n\n const downBtn = document.createElement('button');\n downBtn.id = 'cognitvs-scroll-down';\n downBtn.setAttribute('aria-label', 'Rolar para baixo');\n downBtn.title = 'Rolar para baixo';\n downBtn.innerHTML = `\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"6 9 12 15 18 9\"></polyline>\n </svg>\n `;\n this.styleButton(downBtn, true);\n downBtn.onclick = () => window.scrollBy({ top: window.innerHeight * 0.7, behavior: 'smooth' });\n\n this.containerEl.appendChild(upBtn);\n this.containerEl.appendChild(downBtn);\n document.body.appendChild(this.containerEl);\n\n this.boundScroll = this.checkScrollLimits.bind(this);\n window.addEventListener('scroll', this.boundScroll, { passive: true });\n }\n\n private styleButton(btn: HTMLButtonElement, isPrimary: boolean): void {\n btn.style.cssText = `\n width: 52px;\n height: 52px;\n border-radius: 16px;\n border: 2px solid ${isPrimary ? '#0077d4' : 'rgba(0, 119, 212, 0.4)'};\n background: ${isPrimary ? '#0077d4' : '#0f172a'};\n color: #ffffff;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: 0 10px 25px rgba(0, 0, 0, 0.35);\n backdrop-filter: blur(8px);\n transition: all 0.2s ease;\n font-weight: bold;\n `;\n btn.onmouseenter = () => {\n btn.style.transform = 'scale(1.08)';\n btn.style.background = isPrimary ? '#0066b8' : '#1e293b';\n };\n btn.onmouseleave = () => {\n btn.style.transform = 'scale(1)';\n btn.style.background = isPrimary ? '#0077d4' : '#0f172a';\n };\n }\n\n private checkScrollLimits(): void {\n if (!this.containerEl) return;\n const isAtTop = window.scrollY < 20;\n const isAtBottom = Math.ceil(window.innerHeight + window.scrollY) >= document.documentElement.scrollHeight - 20;\n\n const upBtn = this.containerEl.querySelector<HTMLButtonElement>('#cognitvs-scroll-up');\n const downBtn = this.containerEl.querySelector<HTMLButtonElement>('#cognitvs-scroll-down');\n\n if (upBtn) upBtn.style.opacity = isAtTop ? '0.4' : '1';\n if (downBtn) downBtn.style.opacity = isAtBottom ? '0.4' : '1';\n }\n\n private teardown(): void {\n if (this.boundScroll) {\n window.removeEventListener('scroll', this.boundScroll);\n this.boundScroll = null;\n }\n if (this.containerEl) {\n this.containerEl.remove();\n this.containerEl = null;\n }\n }\n\n public destroy(): void {\n this.teardown();\n }\n}\n","export class VLibrasController {\n private active = false;\n private scriptLoaded = false;\n\n public update(active: boolean): void {\n this.active = active;\n\n const windowWithLibras = window as unknown as { toggleVLibras?: (active: boolean) => void; VLibras?: unknown };\n\n if (!active) {\n if (typeof windowWithLibras.toggleVLibras === 'function') {\n windowWithLibras.toggleVLibras(false);\n }\n return;\n }\n\n if (this.scriptLoaded && typeof windowWithLibras.toggleVLibras === 'function') {\n windowWithLibras.toggleVLibras(true);\n return;\n }\n\n this.loadVLibras();\n }\n\n private loadVLibras(): void {\n if (document.getElementById('vlibras-plugin-container')) {\n return;\n }\n\n // Criar o container padrão oficial do VLibras\n const div = document.createElement('div');\n div.id = 'vlibras-plugin-container';\n div.innerHTML = `\n <div vw class=\"enabled\">\n <div vw-access-button class=\"active\"></div>\n <div vw-plugin-wrapper>\n <div class=\"vw-plugin-top-wrapper\"></div>\n </div>\n </div>\n `;\n document.body.appendChild(div);\n\n // Carregar o script do VLibras Oficial\n const script = document.createElement('script');\n script.id = 'vlibras-official-script';\n script.src = 'https://vlibras.gov.br/app/vlibras-plugin.js';\n script.async = true;\n script.onload = () => {\n this.scriptLoaded = true;\n const win = window as unknown as { VLibras?: { Widget: new (url: string) => void } };\n if (win.VLibras && win.VLibras.Widget) {\n new win.VLibras.Widget('https://vlibras.gov.br/app');\n }\n };\n document.head.appendChild(script);\n }\n\n public destroy(): void {\n if (this.active) {\n this.update(false);\n }\n }\n}\n","import widgetCss from './styles/widget.css?inline';\nimport globalCss from './styles/global.css?inline';\nimport { A11yStore } from './state/store';\nimport { DomEffectsManager } from './features/dom-effects';\nimport { TTSController } from './features/tts';\nimport { CursorMagnetController } from './features/cursor-magnet';\nimport { ScrollAssistController } from './features/scroll-assist';\nimport { VLibrasController } from './features/vlibras';\nimport { A11yState, AssistiveProfile, DaltonismMode } from './types';\n\n/**\n * Símbolo Universal de Acessibilidade — SVG oficial (Adobe Illustrator export)\n * Preto para a estrutura, #44A5DD para os nós de destaque (azul ciano do ícone original)\n * currentColor = cor primária do contexto (branco no FAB azul, azul no painel)\n */\nconst A11Y_ICON_SVG = (size = 32) => `\n <svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n width=\"${size}\" height=\"${size}\" viewBox=\"0 0 539.7 501.1\" aria-hidden=\"true\">\n <!-- Estrutura principal (braços, pernas, arco superior/inferior, texto nós) -->\n <path fill=\"currentColor\" d=\"M268,276.6c-18.8,28.2-37,55.4-55.3,82.7c-14.9,22.3-29.7,44.6-44.8,66.8c-2.1,3-2.4,4.8,0.3,7.9\n c11.2,13,10.9,32.4-0.1,45.5c-11.3,13.4-30.3,16.7-45.3,7.9c-15-8.8-21.5-27-15.5-43.3c6-16.1,22.6-25.7,39.5-22.6\n c2.9,0.5,4.4,0.1,6.1-2.4c32.7-49.1,65.4-98.1,98.2-147.1c0.6-0.9,1.1-1.9,1.9-3.2c-9.2-1.1-18.1-1.8-26.9-3.2\n c-43.2-6.6-84.4-20-124.9-36c-13.8-5.4-27.3-11.4-40.9-17.3c-2.6-1.1-4.4-1-6.8,0.4c-15.2,8.8-34.2,5.3-45.2-8\n c-11-13.2-11-32.3-0.1-45.6c11-13.3,29.8-16.8,44.8-8.5c15.2,8.4,22.1,26.4,16.3,42.9c-0.9,2.7-1.3,4.1,2,5.5\n c45.8,19.7,92.3,37.1,141.3,47.4c38.9,8.2,77.4,6.5,116.1-0.9c48.7-9.3,95.8-24.1,142.4-40.8c3.9-1.4,3.7-2.5,1.9-5.8\n c-10.2-18.2-2.4-41.3,16.5-49.8c19-8.5,41.4,1.1,48.3,20.7c7,19.9-4.5,41.3-24.9,46.5c-5.9,1.5-11.9,1.6-17.8-0.2\n c-3.1-1-5.6-0.7-8.6,0.4c-48.2,18.1-97.1,33.8-147.7,43.8c-18.3,3.6-36.8,6.3-55.4,7.6c-0.9,1.9,0.7,2.8,1.5,3.9\n c32.8,49.2,65.7,98.3,98.4,147.5c1.8,2.7,3.3,3.2,6.4,2.4c17.2-4.2,34.2,4.3,41.2,20.2c7,15.9,1.5,34.5-13,44.1\n c-14.3,9.5-33.3,7.4-45.3-5c-12-12.4-13.4-31.6-3.1-45.9c1.3-1.9,2.8-3.1,0.9-5.9c-33.8-50.3-67.4-100.7-101.1-151.1\n C268.8,278.1,268.6,277.7,268,276.6z\"/>\n <!-- Arco superior -->\n <path fill=\"currentColor\" d=\"M268.9,0c94.9,3.7,167.9,44.9,217.2,126.7c2.1,3.6,1.5,5.1-2,6.5c-3.4,1.4-6.8,4.9-9.7,4.4\n c-3.1-0.5-4.1-5.6-6-8.7C376.9-21.2,158.6-20.3,68.3,130.7c-2.6,4.3-4.2,5.4-8.7,2.3c-8.6-5.8-9-5.7-3.3-14.3\n C101.9,48.4,166.3,8.8,250,1.1C256.3,0.5,262.6,0.3,268.9,0z\"/>\n <!-- Cabeça (anel externo) -->\n <path fill=\"currentColor\" d=\"M200.5,135.2c0.2-39,31.7-70.4,70.8-70.3c38.9,0.1,70.5,31.8,70.4,70.7c-0.1,39.1-31.8,70.7-71,70.5\n C231.8,206,200.3,174.2,200.5,135.2z M325.1,135.4c-0.1-29.9-24.3-54.1-54-54.1c-29.9,0-54.2,24.6-54.1,54.6\n c0.1,29.7,24.6,53.9,54.4,53.7C301.2,189.5,325.2,165.4,325.1,135.4z\"/>\n <!-- Arco lateral esquerdo -->\n <path fill=\"currentColor\" d=\"M35.1,255.4c2,61.5,23.9,114.7,66.9,158.9c3,3.1,3.4,4.6,0.1,7.7c-8.3,7.9-8.2,8.2-15.9-0.2\n C39,370.2,16.7,309.3,18.9,239.4c0.1-3.1,0.7-4.6,4.2-4.2c3.9,0.4,9.1-1.1,11.6,0.8c2.8,2.2,0.2,7.4,0.5,11.4\n C35.3,250.1,35.1,252.7,35.1,255.4z\"/>\n <!-- Arco lateral direito -->\n <path fill=\"currentColor\" d=\"M518.9,252.8c-1.4,66.4-24.6,123.9-70.4,172.2c-2.7,2.8-4.4,3.1-6.9,0.1c-2.4-2.9-7.5-4.8-7.5-8.1\n c0-2.7,4.3-5.4,6.8-8.1c43.4-48.2,63.8-104.7,61.2-169.5c-0.1-3.4,0.4-4.6,4.1-4.5c12.6,0.1,12.6,0,12.7,12.4\n C518.9,249.2,518.9,251,518.9,252.8z\"/>\n <!-- Arco inferior -->\n <path fill=\"currentColor\" d=\"M268.6,501.1c-28.7,0-56.6-4.9-83.7-14.3c-3.5-1.2-5-2.5-2.9-6.2c1.9-3.3,1.7-8.7,4.8-10\n c2.6-1.1,6.8,1.7,10.2,2.8c51.1,16,101.9,15.1,152.3-3.1c3.8-1.4,5.3-0.9,6.7,3c3.9,11,4.1,10.9-6.9,14.7\n C323.3,496.7,296.3,501.1,268.6,501.1z\"/>\n <!-- Nós de destaque (azul ciano — mantido como identidade visual do ícone) -->\n <circle fill=\"#44A5DD\" cx=\"398\" cy=\"456.5\" r=\"19.3\"/>\n <circle fill=\"#44A5DD\" cx=\"505.1\" cy=\"181.9\" r=\"19.3\"/>\n <circle fill=\"#44A5DD\" cx=\"140.6\" cy=\"456.6\" r=\"19.1\"/>\n <circle fill=\"#44A5DD\" cx=\"35.8\" cy=\"181.8\" r=\"19.2\"/>\n <!-- Cabeça (preenchimento interno azul) -->\n <path fill=\"#44A5DD\" d=\"M325.1,135.4c0.1,30-23.9,54.1-53.7,54.3c-29.8,0.1-54.3-24-54.4-53.7c-0.1-30,24.2-54.6,54.1-54.6\n C300.8,81.4,325,105.6,325.1,135.4z\"/>\n </svg>\n`.trim();\n\n\nexport class CognitvsA11yWidget extends HTMLElement {\n private shadow: ShadowRoot;\n private store: A11yStore;\n private domEffects: DomEffectsManager;\n private tts: TTSController;\n private cursorMagnet: CursorMagnetController;\n private scrollAssist: ScrollAssistController;\n private vlibras: VLibrasController;\n private unsubscribe: (() => void) | null = null;\n private tourTimeoutId: number | null = null;\n private resizeRafId: number | null = null;\n\n constructor() {\n super();\n this.shadow = this.attachShadow({ mode: 'open' });\n const prefix = this.getAttribute('storage-prefix') || 'cognitvs';\n this.store = new A11yStore(prefix);\n this.domEffects = new DomEffectsManager();\n this.tts = new TTSController((node) => this.contains(node) || this.shadow.contains(node));\n this.cursorMagnet = new CursorMagnetController();\n this.scrollAssist = new ScrollAssistController();\n this.vlibras = new VLibrasController();\n }\n\n static get observedAttributes(): string[] {\n return ['theme', 'accent-color', 'position', 'storage-prefix', 'show-banner'];\n }\n\n public attributeChangedCallback(name: string, oldValue: string, newValue: string): void {\n if (oldValue === newValue) return;\n if (name === 'accent-color' && newValue) {\n this.style.setProperty('--a11y-primary', newValue);\n }\n }\n\n public connectedCallback(): void {\n this.injectGlobalStyles();\n this.renderInitialShadow();\n\n // Listeners para redimensionamento em tempo real e adaptação suave à tela\n window.addEventListener('resize', this.onViewportChange, { passive: true });\n window.addEventListener('scroll', this.onViewportChange, { passive: true });\n\n // Iniciar Attention Grabber após 3.5s se primeira visita\n const state = this.store.getState();\n if (!state.hasInteracted) {\n this.tourTimeoutId = window.setTimeout(() => {\n if (!this.store.getState().isExpanded && !this.store.getState().hasInteracted) {\n this.store.update({ showAttentionGrabber: true });\n }\n }, 3500);\n }\n\n // Assinar mudanças do estado reativo\n this.unsubscribe = this.store.subscribe((currState) => {\n this.domEffects.applyGlobalState(currState);\n this.tts.update(currState.isTTSActive, currState.ttsRate);\n this.cursorMagnet.update(currState.isCursorMagnetActive, currState.cursorMagnetForce, currState.isBigCursor);\n this.scrollAssist.update(currState.isScrollAssistActive);\n this.vlibras.update(currState.isVLibrasActive);\n this.updateShadowUI(currState);\n });\n\n // Ajuste inicial de dimensões e transição suave do topo da página\n requestAnimationFrame(() => this.updatePanelDimensions());\n setTimeout(() => this.updatePanelDimensions(), 50);\n setTimeout(() => this.updatePanelDimensions(), 250);\n }\n\n public disconnectedCallback(): void {\n window.removeEventListener('resize', this.onViewportChange);\n window.removeEventListener('scroll', this.onViewportChange);\n if (this.resizeRafId) {\n cancelAnimationFrame(this.resizeRafId);\n }\n document.body.classList.remove('a11y-banner-active');\n\n if (this.unsubscribe) {\n this.unsubscribe();\n this.unsubscribe = null;\n }\n if (this.tourTimeoutId) {\n clearTimeout(this.tourTimeoutId);\n }\n this.domEffects.destroy();\n this.tts.destroy();\n this.cursorMagnet.destroy();\n this.scrollAssist.destroy();\n this.vlibras.destroy();\n }\n\n private injectGlobalStyles(): void {\n const styleId = 'cognitvs-a11y-global-styles';\n if (!document.getElementById(styleId)) {\n const style = document.createElement('style');\n style.id = styleId;\n style.textContent = globalCss;\n document.head.appendChild(style);\n }\n }\n\n private renderInitialShadow(): void {\n const showBanner = this.getAttribute('show-banner') !== 'false';\n const accent = this.getAttribute('accent-color');\n if (accent) {\n this.style.setProperty('--a11y-primary', accent);\n }\n\n this.shadow.innerHTML = `\n <style>${widgetCss}</style>\n ${showBanner ? `\n <div id=\"a11y-top-banner\" class=\"a11y-top-banner\" role=\"banner\">\n <div class=\"a11y-banner-content\">\n <span class=\"a11y-banner-icon\" aria-hidden=\"true\">\n ${A11Y_ICON_SVG(26)}\n </span>\n <p class=\"a11y-banner-text\">\n <strong>Acessibilidade:</strong> Personalize sua navegação clicando no botão no canto da tela.\n </p>\n </div>\n <button id=\"banner-close-btn\" class=\"a11y-banner-close\" aria-label=\"Dispensar aviso de acessibilidade\">✕</button>\n </div>\n ` : ''}\n\n <div class=\"a11y-widget-root\">\n <!-- Painel Expansível -->\n <div id=\"a11y-panel\" class=\"a11y-panel closed\" role=\"region\" aria-label=\"Painel de Ferramentas de Acessibilidade\">\n <div class=\"a11y-panel-header\">\n <div class=\"a11y-panel-title\">\n ${A11Y_ICON_SVG(18)}\n ACESSIBILIDADE\n </div>\n <button id=\"panel-close-btn\" class=\"a11y-btn-mini\" style=\"flex:0; width:28px; padding:4px;\" aria-label=\"Fechar painel\">✕</button>\n </div>\n\n <div>\n <label class=\"a11y-section-title\" for=\"profile-select\">Perfil Assistivo</label>\n <select id=\"profile-select\" class=\"a11y-profile-select\">\n <option value=\"all\">Ver Todos os Recursos</option>\n <option value=\"vision\">👁️ Visão Reduzida</option>\n <option value=\"hearing\">🧏 Audição / Surdez</option>\n <option value=\"motor\">🎯 Dificuldade Motora</option>\n <option value=\"cognitive\">🧠 TDAH e Foco</option>\n </select>\n </div>\n\n <div id=\"a11y-feature-container\"></div>\n\n <button id=\"reset-btn\" class=\"a11y-reset-btn\">Resetar Preferências</button>\n </div>\n\n <!-- Botão Flutuante e Dica -->\n <div class=\"a11y-fab-wrapper\">\n <div id=\"tour-bubble\" class=\"a11y-tour-bubble\" style=\"display: none;\">\n <span style=\"font-size: 20px;\">👋</span>\n <p style=\"font-size: 11px; font-weight: bold; line-height: 1.3;\">Dificuldade para navegar? Clique aqui!</p>\n </div>\n <div id=\"ping-ring\" class=\"a11y-ping-ring\" style=\"display: none;\"></div>\n\n <button id=\"fab-btn\" class=\"a11y-fab\" aria-label=\"Abrir recursos de acessibilidade\" aria-haspopup=\"true\">\n ${A11Y_ICON_SVG(34)}\n </button>\n </div>\n </div>\n `;\n\n this.bindEvents();\n }\n\n private bindEvents(): void {\n const fabBtn = this.shadow.querySelector('#fab-btn');\n const panelCloseBtn = this.shadow.querySelector('#panel-close-btn');\n const bannerCloseBtn = this.shadow.querySelector('#banner-close-btn');\n const tourBubble = this.shadow.querySelector('#tour-bubble');\n const resetBtn = this.shadow.querySelector('#reset-btn');\n const profileSelect = this.shadow.querySelector<HTMLSelectElement>('#profile-select');\n\n fabBtn?.addEventListener('click', () => this.store.toggleExpanded());\n panelCloseBtn?.addEventListener('click', () => this.store.toggleExpanded());\n tourBubble?.addEventListener('click', () => this.store.toggleExpanded());\n bannerCloseBtn?.addEventListener('click', () => this.store.dismissBanner());\n resetBtn?.addEventListener('click', () => this.store.resetAll());\n profileSelect?.addEventListener('change', (e) => {\n const val = (e.target as HTMLSelectElement).value as AssistiveProfile;\n this.store.setActiveProfile(val);\n });\n }\n\n private updateShadowUI(state: A11yState): void {\n // Banner Superior\n const banner = this.shadow.querySelector('#a11y-top-banner');\n if (banner) {\n if (state.bannerDismissed) {\n banner.classList.add('hidden');\n document.body.classList.remove('a11y-banner-active');\n document.documentElement.style.setProperty('--a11y-top-banner-height', '0px');\n } else {\n banner.classList.remove('hidden');\n document.body.classList.add('a11y-banner-active');\n }\n }\n\n // Painel e FAB\n const panel = this.shadow.querySelector('#a11y-panel');\n const fab = this.shadow.querySelector('#fab-btn');\n if (panel) {\n if (state.isExpanded) {\n panel.classList.remove('closed');\n } else {\n panel.classList.add('closed');\n }\n }\n if (fab) {\n fab.innerHTML = state.isExpanded\n ? `<span style=\"font-size:24px; font-weight:900;\">✕</span>`\n : A11Y_ICON_SVG(34);\n }\n\n // Tour / Attention Grabber\n const tourBubble = this.shadow.querySelector<HTMLElement>('#tour-bubble');\n const pingRing = this.shadow.querySelector<HTMLElement>('#ping-ring');\n if (tourBubble) tourBubble.style.display = state.showAttentionGrabber ? 'flex' : 'none';\n if (pingRing) pingRing.style.display = state.showAttentionGrabber ? 'block' : 'none';\n\n // Perfil Ativo\n const profileSelect = this.shadow.querySelector<HTMLSelectElement>('#profile-select');\n if (profileSelect && profileSelect.value !== state.activeProfile) {\n profileSelect.value = state.activeProfile;\n }\n\n // Renderizar Blocos Dinâmicos de Funcionalidades\n this.renderFeatureButtons(state);\n\n // Recalcular dimensões seguras do painel imediatamente\n this.updatePanelDimensions();\n }\n\n private onViewportChange = (): void => {\n if (this.resizeRafId) {\n cancelAnimationFrame(this.resizeRafId);\n }\n this.resizeRafId = requestAnimationFrame(() => {\n this.updatePanelDimensions();\n });\n };\n\n private updatePanelDimensions(): void {\n const panel = this.shadow.querySelector<HTMLElement>('#a11y-panel');\n const banner = this.shadow.querySelector<HTMLElement>('#a11y-top-banner');\n const root = this.shadow.querySelector<HTMLElement>('.a11y-widget-root');\n if (!panel || !root) return;\n\n // 1. Altura do banner superior (se visível e não dispensado)\n let bannerHeight = 0;\n const isBannerDismissed = this.store.getState().bannerDismissed;\n if (banner && !isBannerDismissed) {\n bannerHeight = banner.getBoundingClientRect().height || banner.offsetHeight || 0;\n }\n document.documentElement.style.setProperty('--a11y-top-banner-height', `${bannerHeight}px`);\n if (bannerHeight > 0) {\n document.body.classList.add('a11y-banner-active');\n } else {\n document.body.classList.remove('a11y-banner-active');\n }\n\n // 2. Detecção automática de cabeçalho / navbar fixo ou sticky no topo do site hospedeiro\n let hostHeaderBottom = 0;\n const customHeaderH = parseFloat(\n getComputedStyle(document.documentElement).getPropertyValue('--a11y-header-height') || '0'\n );\n if (customHeaderH > 0) {\n hostHeaderBottom = customHeaderH;\n } else {\n const candidates = document.querySelectorAll<HTMLElement>(\n 'header, nav, [role=\"banner\"], .header, .site-header, .navbar, .top-bar'\n );\n for (const el of candidates) {\n const style = window.getComputedStyle(el);\n if (style.position === 'fixed' || style.position === 'sticky') {\n const rect = el.getBoundingClientRect();\n if (rect.top <= 10 && rect.bottom > hostHeaderBottom && rect.bottom < window.innerHeight * 0.45) {\n hostHeaderBottom = rect.bottom;\n }\n }\n }\n }\n\n // 3. Altura ocupada pelo FAB e espaçamento inferior\n const rootRect = root.getBoundingClientRect();\n const bottomDist = Math.max(0, window.innerHeight - rootRect.bottom);\n const fabWrapper = this.shadow.querySelector<HTMLElement>('.a11y-fab-wrapper');\n const fabHeight = fabWrapper ? fabWrapper.offsetHeight : 56;\n const gap = 12; // gap entre o painel e o FAB\n\n // 4. Margem de segurança de respiro abaixo do banner/header (evita encostar ou passar por trás)\n const PANEL_TOP_MARGIN = 24;\n\n // 5. Obstáculo superior total: o maior entre banner e header + respiro\n const topObstacle = Math.max(bannerHeight, hostHeaderBottom);\n const totalTopReserved = topObstacle + PANEL_TOP_MARGIN;\n\n // 6. Max-height disponível para o painel respeitando a tela e o topo\n const availableHeight = window.innerHeight\n - totalTopReserved\n - bottomDist\n - fabHeight\n - gap;\n\n const finalMaxHeight = Math.max(160, Math.floor(availableHeight));\n\n panel.style.setProperty('--fab-panel-max-height', `${finalMaxHeight}px`);\n if (this.store.getState().isExpanded) {\n panel.style.maxHeight = `${finalMaxHeight}px`;\n } else {\n panel.style.maxHeight = '0px';\n }\n }\n\n private renderFeatureButtons(state: A11yState): void {\n const container = this.shadow.querySelector('#a11y-feature-container');\n if (!container) return;\n\n const p = state.activeProfile;\n let html = '';\n\n // AJUSTES VISUAIS\n if (['all', 'vision', 'cognitive'].includes(p)) {\n html += `<div class=\"a11y-section-title\">Ajustes Visuais</div>`;\n html += `\n <div class=\"a11y-scale-box\">\n <button id=\"btn-scale-down\" class=\"a11y-scale-btn\" aria-label=\"Diminuir texto\">A-</button>\n <span class=\"a11y-scale-val\">${Math.round(state.fontScale * 100)}%</span>\n <button id=\"btn-scale-up\" class=\"a11y-scale-btn\" aria-label=\"Aumentar texto\">A+</button>\n </div>\n `;\n html += `\n <button id=\"btn-contrast\" class=\"a11y-btn ${state.isHighContrast ? 'active' : ''}\">\n <span>${state.isHighContrast ? '☀️' : '👁️'}</span>\n <span>${state.isHighContrast ? 'Contraste Ativo' : 'Alto Contraste'}</span>\n </button>\n `;\n html += `\n <div style=\"display:flex; flex-direction:column; gap:4px; margin-top:4px;\">\n <button id=\"btn-mask\" class=\"a11y-btn ${state.isReadingMaskActive ? 'active' : ''}\">\n <span>${state.isReadingMaskActive ? '📖' : '📏'}</span>\n <span>${state.isReadingMaskActive ? 'Máscara Ativa' : 'Máscara de Leitura'}</span>\n </button>\n ${state.isReadingMaskActive ? `\n <div class=\"a11y-btn-group\" style=\"padding-left:4px;\">\n <button id=\"mask-mode-smart\" class=\"a11y-btn-mini ${state.isReadingMaskSmart ? 'active' : ''}\">🧠 Inteligente</button>\n <button id=\"mask-mode-free\" class=\"a11y-btn-mini ${!state.isReadingMaskSmart ? 'active' : ''}\">🆓 Livre</button>\n </div>\n ` : ''}\n </div>\n `;\n html += `\n <div style=\"display:flex; flex-direction:column; gap:4px; margin-top:4px;\">\n <label class=\"a11y-section-title\" style=\"margin:0;\">Filtros de Daltonismo</label>\n <select id=\"select-daltonism\" class=\"a11y-profile-select\">\n <option value=\"none\" ${state.colorBlindMode === 'none' ? 'selected' : ''}>Padrão (Desativado)</option>\n <option value=\"protanopia\" ${state.colorBlindMode === 'protanopia' ? 'selected' : ''}>Protanopia</option>\n <option value=\"deuteranopia\" ${state.colorBlindMode === 'deuteranopia' ? 'selected' : ''}>Deuteranopia</option>\n <option value=\"tritanopia\" ${state.colorBlindMode === 'tritanopia' ? 'selected' : ''}>Tritanopia</option>\n <option value=\"monochromacy\" ${state.colorBlindMode === 'monochromacy' ? 'selected' : ''}>Monocromia</option>\n </select>\n </div>\n `;\n }\n\n // AUDIÇÃO E LEITURA\n if (['all', 'hearing', 'cognitive'].includes(p)) {\n html += `<div class=\"a11y-section-title\">Audição e Leitura</div>`;\n html += `\n <div style=\"display:flex; flex-direction:column; gap:4px;\">\n <button id=\"btn-tts\" class=\"a11y-btn ${state.isTTSActive ? 'active' : ''}\">\n <span>${state.isTTSActive ? '🔊' : '🔈'}</span>\n <span>${state.isTTSActive ? 'Leitor Ativo (Clique no Texto)' : 'Leitor de Tela'}</span>\n </button>\n ${state.isTTSActive ? `\n <div class=\"a11y-btn-group\">\n <button id=\"tts-rate-05\" class=\"a11y-btn-mini ${state.ttsRate === 0.5 ? 'active' : ''}\">🐢 0.5x</button>\n <button id=\"tts-rate-1\" class=\"a11y-btn-mini ${state.ttsRate === 1 ? 'active' : ''}\">🚶 1.0x</button>\n <button id=\"tts-rate-15\" class=\"a11y-btn-mini ${state.ttsRate === 1.5 ? 'active' : ''}\">🐇 1.5x</button>\n </div>\n ` : ''}\n </div>\n `;\n html += `\n <button id=\"btn-vlibras\" class=\"a11y-btn ${state.isVLibrasActive ? 'active' : ''}\">\n <span>${state.isVLibrasActive ? '🤟' : '👐'}</span>\n <span>${state.isVLibrasActive ? 'LIBRAS Ativo' : 'Tradutor LIBRAS'}</span>\n </button>\n `;\n }\n\n // AJUSTES DE INTERAÇÃO\n if (['all', 'motor', 'vision'].includes(p)) {\n html += `<div class=\"a11y-section-title\">Interação e Mobilidade</div>`;\n html += `\n <button id=\"btn-big-cursor\" class=\"a11y-btn ${state.isBigCursor ? 'active' : ''}\">\n <span>${state.isBigCursor ? '↖️' : '🖱️'}</span>\n <span>${state.isBigCursor ? 'Ponteiro Gigante Ativo' : 'Ponteiro Gigante'}</span>\n </button>\n `;\n html += `\n <button id=\"btn-keyboard-focus\" class=\"a11y-btn ${state.isKeyboardFocus ? 'active' : ''}\">\n <span>${state.isKeyboardFocus ? '🎯' : '⌨️'}</span>\n <span>${state.isKeyboardFocus ? 'Foco Teclado Ativo' : 'Foco por Teclado'}</span>\n </button>\n `;\n html += `\n <button id=\"btn-scroll-assist\" class=\"a11y-btn ${state.isScrollAssistActive ? 'active' : ''}\">\n <span>${state.isScrollAssistActive ? '↕️' : '🖱️'}</span>\n <span>${state.isScrollAssistActive ? 'Rolagem Assistida Ativa' : 'Rolagem Assistida'}</span>\n </button>\n `;\n html += `\n <div style=\"display:flex; flex-direction:column; gap:4px;\">\n <button id=\"btn-cursor-magnet\" class=\"a11y-btn ${state.isCursorMagnetActive ? 'active' : ''}\">\n <span>🧲</span>\n <span>${state.isCursorMagnetActive ? 'Ímã de Cursor Ativo' : 'Ímã de Cursor'}</span>\n </button>\n ${state.isCursorMagnetActive ? `\n <div class=\"a11y-btn-group\">\n <button id=\"magnet-force-suave\" class=\"a11y-btn-mini ${state.cursorMagnetForce === 'suave' ? 'active' : ''}\">🪶 Suave</button>\n <button id=\"magnet-force-forte\" class=\"a11y-btn-mini ${state.cursorMagnetForce === 'forte' ? 'active' : ''}\">🧲 Forte</button>\n </div>\n ` : ''}\n </div>\n `;\n html += `\n <button id=\"btn-highlight-links\" class=\"a11y-btn ${state.isHighlightLinks ? 'active' : ''}\">\n <span>🔗</span>\n <span>${state.isHighlightLinks ? 'Links Destacados' : 'Destacar Links'}</span>\n </button>\n `;\n }\n\n // AJUSTES COGNITIVOS\n if (['all', 'cognitive'].includes(p)) {\n html += `<div class=\"a11y-section-title\">Ajustes Cognitivos</div>`;\n html += `\n <button id=\"btn-reduce-motion\" class=\"a11y-btn ${state.isReduceMotion ? 'active' : ''}\">\n <span>${state.isReduceMotion ? '⏸️' : '✨'}</span>\n <span>${state.isReduceMotion ? 'Animações Pausadas' : 'Pausar Animações'}</span>\n </button>\n `;\n html += `\n <button id=\"btn-dyslexia\" class=\"a11y-btn ${state.isDyslexiaMode ? 'active' : ''}\">\n <span>${state.isDyslexiaMode ? '📖' : '🅰️'}</span>\n <span>${state.isDyslexiaMode ? 'Fonte Dislexia Ativa' : 'Ajuste para Dislexia'}</span>\n </button>\n `;\n html += `\n <div style=\"display:flex; flex-direction:column; gap:4px;\">\n <label class=\"a11y-section-title\" style=\"margin:0;\">Espaçamento de Texto</label>\n <div class=\"a11y-btn-group\">\n <button id=\"spacing-0\" class=\"a11y-btn-mini ${state.textSpacingLevel === 0 ? 'active' : ''}\">Padrão</button>\n <button id=\"spacing-1\" class=\"a11y-btn-mini ${state.textSpacingLevel === 1 ? 'active' : ''}\">Espaçado</button>\n <button id=\"spacing-2\" class=\"a11y-btn-mini ${state.textSpacingLevel === 2 ? 'active' : ''}\">Largo</button>\n </div>\n </div>\n `;\n }\n\n container.innerHTML = html;\n this.bindFeatureButtons();\n }\n\n private bindFeatureButtons(): void {\n const bind = (id: string, fn: () => void) => {\n this.shadow.querySelector(`#${id}`)?.addEventListener('click', fn);\n };\n\n bind('btn-scale-down', () => this.store.updateFontScale(-0.1));\n bind('btn-scale-up', () => this.store.updateFontScale(0.1));\n bind('btn-contrast', () => this.store.toggleHighContrast());\n bind('btn-mask', () => this.store.toggleReadingMask());\n bind('mask-mode-smart', () => this.store.setReadingMaskSmart(true));\n bind('mask-mode-free', () => this.store.setReadingMaskSmart(false));\n bind('btn-tts', () => this.store.toggleTTS());\n bind('tts-rate-05', () => this.store.setTTSRate(0.5));\n bind('tts-rate-1', () => this.store.setTTSRate(1));\n bind('tts-rate-15', () => this.store.setTTSRate(1.5));\n bind('btn-vlibras', () => this.store.toggleVLibras());\n bind('btn-big-cursor', () => this.store.toggleBigCursor());\n bind('btn-keyboard-focus', () => this.store.toggleKeyboardFocus());\n bind('btn-scroll-assist', () => this.store.toggleScrollAssist());\n bind('btn-cursor-magnet', () => this.store.toggleCursorMagnet());\n bind('magnet-force-suave', () => this.store.setCursorMagnetForce('suave'));\n bind('magnet-force-forte', () => this.store.setCursorMagnetForce('forte'));\n bind('btn-highlight-links', () => this.store.toggleHighlightLinks());\n bind('btn-reduce-motion', () => this.store.toggleReduceMotion());\n bind('btn-dyslexia', () => this.store.toggleDyslexia());\n bind('spacing-0', () => this.store.setTextSpacing(0));\n bind('spacing-1', () => this.store.setTextSpacing(1));\n bind('spacing-2', () => this.store.setTextSpacing(2));\n\n this.shadow.querySelector('#select-daltonism')?.addEventListener('change', (e) => {\n const val = (e.target as HTMLSelectElement).value as DaltonismMode;\n this.store.setColorBlindMode(val);\n });\n }\n}\n","import { CognitvsA11yWidget } from './widget';\n\nexport { CognitvsA11yWidget };\nexport * from './types';\nexport * from './state/store';\n\n// Auto-registro do Custom Element\nif (typeof window !== 'undefined' && !customElements.get('cognitvs-a11y')) {\n customElements.define('cognitvs-a11y', CognitvsA11yWidget);\n}\n\nexport default CognitvsA11yWidget;\n"],"names":["A11yStore","constructor","prefix","__publicField","this","Set","state","loadInitialState","getState","subscribe","listener","listeners","add","delete","notify","current","forEach","fn","getItem","key","localStorage","fontScale","parseFloat","isHighContrast","isReduceMotion","isBigCursor","isKeyboardFocus","isHighlightLinks","isReadingMaskActive","isReadingMaskSmart","isDyslexiaMode","textSpacingLevel","parseInt","colorBlindMode","isScrollAssistActive","isCursorMagnetActive","cursorMagnetForce","isVLibrasActive","isExpanded","activeProfile","isDaltonismMenuOpen","isTTSActive","ttsRate","showAttentionGrabber","hasInteracted","bannerDismissed","setStorage","value","setItem","e","console","warn","removeStorage","removeItem","update","partial","toggleExpanded","setActiveProfile","profile","updateFontScale","delta","newScale","Math","min","max","toFixed","toString","toggleHighContrast","val","toggleReduceMotion","toggleBigCursor","toggleKeyboardFocus","toggleHighlightLinks","toggleScrollAssist","toggleCursorMagnet","setCursorMagnetForce","force","toggleReadingMask","setReadingMaskSmart","smart","toggleDyslexia","setTextSpacing","level","setColorBlindMode","mode","toggleDaltonismMenu","toggleTTS","rate","setTTSRate","toggleVLibras","dismissBanner","resetAll","k","DomEffectsManager","applyGlobalState","docEl","document","documentElement","style","setProperty","syncClass","setAttribute","classList","remove","m","syncReadingMask","el","className","active","prevClasses","isSmart","readingMaskEl","boundMouseMove","window","removeEventListener","maskFrameId","cancelAnimationFrame","createElement","id","cssText","body","appendChild","lastTarget","requestAnimationFrame","target","elementFromPoint","clientX","clientY","textContainer","closest","elToMeasure","rect","getBoundingClientRect","height","margin","maskHeight","topPos","top","addEventListener","passive","destroy","c","removeProperty","removeAttribute","TTSController","isWidgetElement","speechSynthesis","cancel","boundClickHandler","capture","handleClick","bind","includes","tagName","blockTags","Array","from","children","some","child","text","innerText","textContent","replace","trim","length","preventDefault","stopPropagation","utterance","SpeechSynthesisUtterance","lang","originalHTML","innerHTML","originalOutline","outline","originalOutlineOffset","outlineOffset","tokens","split","spanElements","token","span","transition","borderRadius","push","onboundary","ev","name","charCount","i","spanText","charIndex","backgroundColor","color","boxShadow","restoreDOM","onend","onerror","speak","CursorMagnetController","isBig","setup","teardown","handleMouseMove","boundClick","boundScroll","lastCacheTime","isMagnetized","targetButton","cursorEl","ensureCursorElement","updateButtonCache","now","Date","elements","querySelectorAll","cachedButtons","map","ATTRACTION_RADIUS","ESCAPE_RADIUS","mouseX","mouseY","targetDistance","Infinity","targetCenter","x","y","closestDistance","closestButton","closestCenter","currentRect","centerX","left","width","centerY","dxEdge","right","dyEdge","bottom","distanceToEdge","sqrt","setCursorPos","hideVirtualCursor","display","contains","click","ScrollAssistController","containerEl","checkScrollLimits","upBtn","title","styleButton","onclick","scrollBy","innerHeight","behavior","downBtn","btn","isPrimary","onmouseenter","transform","background","onmouseleave","isAtTop","scrollY","isAtBottom","ceil","scrollHeight","querySelector","opacity","VLibrasController","windowWithLibras","scriptLoaded","loadVLibras","getElementById","div","script","src","async","onload","win","VLibras","Widget","head","A11Y_ICON_SVG","size","CognitvsA11yWidget","HTMLElement","super","resizeRafId","updatePanelDimensions","shadow","attachShadow","getAttribute","store","domEffects","tts","node","cursorMagnet","scrollAssist","vlibras","observedAttributes","attributeChangedCallback","oldValue","newValue","connectedCallback","injectGlobalStyles","renderInitialShadow","onViewportChange","tourTimeoutId","setTimeout","unsubscribe","currState","updateShadowUI","disconnectedCallback","clearTimeout","styleId","showBanner","accent","bindEvents","fabBtn","panelCloseBtn","bannerCloseBtn","tourBubble","resetBtn","profileSelect","banner","panel","fab","pingRing","renderFeatureButtons","root","bannerHeight","isBannerDismissed","offsetHeight","hostHeaderBottom","customHeaderH","getComputedStyle","getPropertyValue","candidates","position","rootRect","bottomDist","fabWrapper","fabHeight","totalTopReserved","availableHeight","finalMaxHeight","floor","maxHeight","container","p","html","round","bindFeatureButtons","_a","customElements","get","define"],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { MagnetForce } from '../types';
2
+ export declare class CursorMagnetController {
3
+ private active;
4
+ private force;
5
+ private cursorEl;
6
+ private isMagnetized;
7
+ private targetButton;
8
+ private cachedButtons;
9
+ private lastCacheTime;
10
+ private isBig;
11
+ private boundMouseMove;
12
+ private boundClick;
13
+ private boundScroll;
14
+ update(active: boolean, force: MagnetForce, isBig: boolean): void;
15
+ private setup;
16
+ private teardown;
17
+ private ensureCursorElement;
18
+ private updateButtonCache;
19
+ private handleMouseMove;
20
+ private setCursorPos;
21
+ private hideVirtualCursor;
22
+ private handleClick;
23
+ destroy(): void;
24
+ }
@@ -0,0 +1,11 @@
1
+ import { A11yState } from '../types';
2
+ export declare class DomEffectsManager {
3
+ private prevClasses;
4
+ private readingMaskEl;
5
+ private maskFrameId;
6
+ private boundMouseMove;
7
+ applyGlobalState(state: A11yState): void;
8
+ private syncClass;
9
+ private syncReadingMask;
10
+ destroy(): void;
11
+ }
@@ -0,0 +1,10 @@
1
+ export declare class ScrollAssistController {
2
+ private containerEl;
3
+ private boundScroll;
4
+ update(active: boolean): void;
5
+ private setup;
6
+ private styleButton;
7
+ private checkScrollLimits;
8
+ private teardown;
9
+ destroy(): void;
10
+ }
@@ -0,0 +1,11 @@
1
+ import { TTSSpeed } from '../types';
2
+ export declare class TTSController {
3
+ private active;
4
+ private rate;
5
+ private boundClickHandler;
6
+ private isWidgetElement;
7
+ constructor(isWidgetElement: (el: Node) => boolean);
8
+ update(active: boolean, rate: TTSSpeed): void;
9
+ private handleClick;
10
+ destroy(): void;
11
+ }
@@ -0,0 +1,7 @@
1
+ export declare class VLibrasController {
2
+ private active;
3
+ private scriptLoaded;
4
+ update(active: boolean): void;
5
+ private loadVLibras;
6
+ destroy(): void;
7
+ }
@@ -0,0 +1,5 @@
1
+ import { CognitvsA11yWidget } from './widget';
2
+ export { CognitvsA11yWidget };
3
+ export * from './types';
4
+ export * from './state/store';
5
+ export default CognitvsA11yWidget;
Binary file
@@ -0,0 +1,38 @@
1
+ import { A11yState, AssistiveProfile, DaltonismMode, MagnetForce, TTSSpeed, TextSpacingLevel } from '../types';
2
+ type Listener = (state: A11yState) => void;
3
+ export declare class A11yStore {
4
+ private prefix;
5
+ private state;
6
+ private listeners;
7
+ constructor(prefix?: string);
8
+ getState(): A11yState;
9
+ subscribe(listener: Listener): () => void;
10
+ private notify;
11
+ private loadInitialState;
12
+ setStorage(key: string, value: string): void;
13
+ removeStorage(key: string): void;
14
+ update(partial: Partial<A11yState>): void;
15
+ toggleExpanded(): void;
16
+ setActiveProfile(profile: AssistiveProfile): void;
17
+ updateFontScale(delta: number): void;
18
+ toggleHighContrast(): void;
19
+ toggleReduceMotion(): void;
20
+ toggleBigCursor(): void;
21
+ toggleKeyboardFocus(): void;
22
+ toggleHighlightLinks(): void;
23
+ toggleScrollAssist(): void;
24
+ toggleCursorMagnet(): void;
25
+ setCursorMagnetForce(force: MagnetForce): void;
26
+ toggleReadingMask(): void;
27
+ setReadingMaskSmart(smart: boolean): void;
28
+ toggleDyslexia(): void;
29
+ setTextSpacing(level: TextSpacingLevel): void;
30
+ setColorBlindMode(mode: DaltonismMode): void;
31
+ toggleDaltonismMenu(): void;
32
+ toggleTTS(): void;
33
+ setTTSRate(rate: TTSSpeed): void;
34
+ toggleVLibras(): void;
35
+ dismissBanner(): void;
36
+ resetAll(): void;
37
+ }
38
+ export {};
@@ -0,0 +1,37 @@
1
+ export type AssistiveProfile = 'all' | 'vision' | 'hearing' | 'motor' | 'cognitive';
2
+ export type DaltonismMode = 'none' | 'protanopia' | 'deuteranopia' | 'tritanopia' | 'monochromacy';
3
+ export type MagnetForce = 'suave' | 'forte';
4
+ export type TTSSpeed = 0.5 | 1 | 1.5;
5
+ export type TextSpacingLevel = 0 | 1 | 2;
6
+ export interface A11yState {
7
+ isExpanded: boolean;
8
+ activeProfile: AssistiveProfile;
9
+ fontScale: number;
10
+ isHighContrast: boolean;
11
+ isReadingMaskActive: boolean;
12
+ isReadingMaskSmart: boolean;
13
+ colorBlindMode: DaltonismMode;
14
+ isDaltonismMenuOpen: boolean;
15
+ isTTSActive: boolean;
16
+ ttsRate: TTSSpeed;
17
+ isVLibrasActive: boolean;
18
+ isBigCursor: boolean;
19
+ isKeyboardFocus: boolean;
20
+ isScrollAssistActive: boolean;
21
+ isCursorMagnetActive: boolean;
22
+ cursorMagnetForce: MagnetForce;
23
+ isHighlightLinks: boolean;
24
+ isReduceMotion: boolean;
25
+ isDyslexiaMode: boolean;
26
+ textSpacingLevel: TextSpacingLevel;
27
+ showAttentionGrabber: boolean;
28
+ hasInteracted: boolean;
29
+ bannerDismissed: boolean;
30
+ }
31
+ export interface A11yWidgetConfig {
32
+ storagePrefix: string;
33
+ theme?: 'auto' | 'light' | 'dark';
34
+ accentColor?: string;
35
+ position?: 'bottom-right' | 'bottom-left';
36
+ showBanner?: boolean;
37
+ }
@@ -0,0 +1,25 @@
1
+ export declare class CognitvsA11yWidget extends HTMLElement {
2
+ private shadow;
3
+ private store;
4
+ private domEffects;
5
+ private tts;
6
+ private cursorMagnet;
7
+ private scrollAssist;
8
+ private vlibras;
9
+ private unsubscribe;
10
+ private tourTimeoutId;
11
+ private resizeRafId;
12
+ constructor();
13
+ static get observedAttributes(): string[];
14
+ attributeChangedCallback(name: string, oldValue: string, newValue: string): void;
15
+ connectedCallback(): void;
16
+ disconnectedCallback(): void;
17
+ private injectGlobalStyles;
18
+ private renderInitialShadow;
19
+ private bindEvents;
20
+ private updateShadowUI;
21
+ private onViewportChange;
22
+ private updatePanelDimensions;
23
+ private renderFeatureButtons;
24
+ private bindFeatureButtons;
25
+ }
package/package.json CHANGED
@@ -1,6 +1,48 @@
1
1
  {
2
2
  "name": "@cognitvs/a11y-widget",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.0",
4
+ "description": "Widget de acessibilidade plug & play, agnóstico de framework, em conformidade com WCAG 2.1",
5
+ "homepage": "https://a11y-cognitvs.vercel.app",
6
+ "type": "module",
7
+ "main": "./dist/a11y-widget.umd.cjs",
8
+ "module": "./dist/a11y-widget.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "import": "./dist/a11y-widget.js",
13
+ "require": "./dist/a11y-widget.umd.cjs",
14
+ "types": "./dist/index.d.ts"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "scripts": {
21
+ "dev": "vite",
22
+ "build": "tsc && vite build && vite build --config vite.demo.config.ts",
23
+ "build:lib": "tsc && vite build",
24
+ "build:demo": "vite build --config vite.demo.config.ts",
25
+ "preview": "vite preview"
26
+ },
27
+ "keywords": [
28
+ "accessibility",
29
+ "a11y",
30
+ "wcag",
31
+ "widget",
32
+ "web-component",
33
+ "typescript",
34
+ "libras",
35
+ "tts"
36
+ ],
37
+ "author": "Cognitvs",
38
+ "license": "MIT",
39
+ "publishConfig": {
40
+ "access": "public"
41
+ },
42
+ "devDependencies": {
43
+ "terser": "^5.51.2",
44
+ "typescript": "^5.6.3",
45
+ "vite": "^5.4.10",
46
+ "vite-plugin-dts": "^4.3.0"
47
+ }
48
+ }