[{"data":1,"prerenderedAt":5909},["ShallowReactive",2],{"navigation":3,"changelog":460},[4,34,51,301,327,332,337,406],{"title":5,"path":6,"stem":7,"children":8,"package":11,"icon":33},"Getting Started","\u002Fgetting-started","1.getting-started\u002F1.index",[9,13,18,23,28],{"title":10,"path":6,"stem":7,"package":11,"icon":12},"Introduction",null,"i-lucide-house",{"title":14,"path":15,"stem":16,"package":11,"icon":17},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":19,"path":20,"stem":21,"package":11,"icon":22},"Icons","\u002Fgetting-started\u002Ficons","1.getting-started\u002F3.icons","i-lucide-sparkles",{"title":24,"path":25,"stem":26,"package":11,"icon":27},"CLI","\u002Fgetting-started\u002Fcli","1.getting-started\u002F4.cli","i-lucide-terminal",{"title":29,"path":30,"stem":31,"package":11,"icon":32},"Roadmap","\u002Fgetting-started\u002Froadmap","1.getting-started\u002F5.roadmap","i-lucide-map","i-lucide-rocket",{"title":35,"package":11,"icon":36,"path":37,"stem":38,"children":39,"page":50},"Packages","i-lucide-package","\u002Fpackages","2.packages",[40,45],{"title":41,"path":42,"stem":43,"package":11,"icon":44},"@vyui\u002Fcore","\u002Fpackages\u002Fcore","2.packages\u002F1.core","i-lucide-box",{"title":46,"path":47,"stem":48,"package":11,"icon":49},"@vyui\u002Fkit","\u002Fpackages\u002Fkit","2.packages\u002F2.kit","i-lucide-layers",false,{"title":52,"package":11,"icon":53,"path":54,"stem":55,"children":56},"Components","i-lucide-layout-grid","\u002Fcomponents","3.components",[57,59,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,144,149,153,158,163,168,173,178,183,188,193,198,203,208,213,218,223,228,233,238,242,246,251,256,261,266,271,276,280,284,288,292,296],{"title":52,"path":54,"stem":58,"package":11,"icon":53},"3.components\u002Findex",{"title":60,"path":61,"stem":62,"package":63,"icon":64},"Accordion","\u002Fcomponents\u002Faccordion","3.components\u002Faccordion","kit","i-lucide-list-collapse",{"title":66,"path":67,"stem":68,"package":63,"icon":69},"Action Sheet","\u002Fcomponents\u002Faction-sheet","3.components\u002Faction-sheet","i-lucide-panel-bottom",{"title":71,"path":72,"stem":73,"package":63,"icon":74},"Alert","\u002Fcomponents\u002Falert","3.components\u002Falert","i-lucide-triangle-alert",{"title":76,"path":77,"stem":78,"package":79,"icon":74},"Alert Dialog","\u002Fcomponents\u002Falert-dialog","3.components\u002Falert-dialog","core",{"title":81,"path":82,"stem":83,"package":63,"icon":84},"App","\u002Fcomponents\u002Fapp","3.components\u002Fapp","i-lucide-smartphone",{"title":86,"path":87,"stem":88,"package":63,"icon":89},"Aspect Ratio","\u002Fcomponents\u002Faspect-ratio","3.components\u002Faspect-ratio","i-lucide-ratio",{"title":91,"path":92,"stem":93,"package":63,"icon":94},"Avatar","\u002Fcomponents\u002Favatar","3.components\u002Favatar","i-lucide-circle-user-round",{"title":96,"path":97,"stem":98,"package":63,"icon":99},"Avatar Group","\u002Fcomponents\u002Favatar-group","3.components\u002Favatar-group","i-lucide-users-round",{"title":101,"path":102,"stem":103,"package":63,"icon":104},"Button","\u002Fcomponents\u002Fbutton","3.components\u002Fbutton","i-lucide-square-mouse-pointer",{"title":106,"path":107,"stem":108,"package":63,"icon":109},"Calendar","\u002Fcomponents\u002Fcalendar","3.components\u002Fcalendar","i-lucide-calendar-days",{"title":111,"path":112,"stem":113,"package":63,"icon":114},"Card","\u002Fcomponents\u002Fcard","3.components\u002Fcard","i-lucide-square",{"title":116,"path":117,"stem":118,"package":63,"icon":119},"Checkbox","\u002Fcomponents\u002Fcheckbox","3.components\u002Fcheckbox","i-lucide-square-check",{"title":121,"path":122,"stem":123,"package":79,"icon":124},"Collapsible","\u002Fcomponents\u002Fcollapsible","3.components\u002Fcollapsible","i-lucide-chevrons-down-up",{"title":126,"path":127,"stem":128,"package":79,"icon":129},"Dialog","\u002Fcomponents\u002Fdialog","3.components\u002Fdialog","i-lucide-app-window",{"title":131,"path":132,"stem":133,"package":79,"icon":134},"Draggable","\u002Fcomponents\u002Fdraggable","3.components\u002Fdraggable","i-lucide-move",{"title":136,"path":137,"stem":138,"package":63,"icon":139},"Form","\u002Fcomponents\u002Fform","3.components\u002Fform","i-lucide-clipboard-list",{"title":141,"path":142,"stem":143,"package":79,"icon":22},"Icon","\u002Fcomponents\u002Ficon","3.components\u002Ficon",{"title":145,"path":146,"stem":147,"package":63,"icon":148},"Input","\u002Fcomponents\u002Finput","3.components\u002Finput","i-lucide-text-cursor-input",{"title":150,"path":151,"stem":152,"package":63,"icon":69},"Island","\u002Fcomponents\u002Fisland","3.components\u002Fisland",{"title":154,"path":155,"stem":156,"package":63,"icon":157},"Island Button","\u002Fcomponents\u002Fisland-button","3.components\u002Fisland-button","i-lucide-circle-ellipsis",{"title":159,"path":160,"stem":161,"package":63,"icon":162},"Island Group","\u002Fcomponents\u002Fisland-group","3.components\u002Fisland-group","i-lucide-panels-top-left",{"title":164,"path":165,"stem":166,"package":63,"icon":167},"KeyboardAware","\u002Fcomponents\u002Fkeyboard-aware","3.components\u002Fkeyboard-aware","i-lucide-keyboard",{"title":169,"path":170,"stem":171,"package":63,"icon":172},"Label","\u002Fcomponents\u002Flabel","3.components\u002Flabel","i-lucide-tag",{"title":174,"path":175,"stem":176,"package":63,"icon":177},"Modal","\u002Fcomponents\u002Fmodal","3.components\u002Fmodal","i-lucide-gallery-vertical-end",{"title":179,"path":180,"stem":181,"package":79,"icon":182},"Navigation","\u002Fcomponents\u002Fnavigation","3.components\u002Fnavigation","i-lucide-route",{"title":184,"path":185,"stem":186,"package":63,"icon":187},"Number Field","\u002Fcomponents\u002Fnumber-field","3.components\u002Fnumber-field","i-lucide-list-plus",{"title":189,"path":190,"stem":191,"package":79,"icon":192},"Pagination","\u002Fcomponents\u002Fpagination","3.components\u002Fpagination","i-lucide-ellipsis",{"title":194,"path":195,"stem":196,"package":63,"icon":197},"Pin Input","\u002Fcomponents\u002Fpin-input","3.components\u002Fpin-input","i-lucide-key-round",{"title":199,"path":200,"stem":201,"package":63,"icon":202},"Placeholder","\u002Fcomponents\u002Fplaceholder","3.components\u002Fplaceholder","i-lucide-square-dashed",{"title":204,"path":205,"stem":206,"package":63,"icon":207},"Popover","\u002Fcomponents\u002Fpopover","3.components\u002Fpopover","i-lucide-message-square-more",{"title":209,"path":210,"stem":211,"package":63,"icon":212},"Progress","\u002Fcomponents\u002Fprogress","3.components\u002Fprogress","i-lucide-chart-no-axes-column-increasing",{"title":214,"path":215,"stem":216,"package":63,"icon":217},"Radio Group","\u002Fcomponents\u002Fradio-group","3.components\u002Fradio-group","i-lucide-circle-dot",{"title":219,"path":220,"stem":221,"package":63,"icon":222},"Rating","\u002Fcomponents\u002Frating","3.components\u002Frating","i-lucide-star",{"title":224,"path":225,"stem":226,"package":79,"icon":227},"Scroll View","\u002Fcomponents\u002Fscroll-view","3.components\u002Fscroll-view","i-lucide-scroll",{"title":229,"path":230,"stem":231,"package":63,"icon":232},"Select","\u002Fcomponents\u002Fselect","3.components\u002Fselect","i-lucide-list-check",{"title":234,"path":235,"stem":236,"package":63,"icon":237},"Separator","\u002Fcomponents\u002Fseparator","3.components\u002Fseparator","i-lucide-separator-horizontal",{"title":239,"path":240,"stem":241,"package":79,"icon":69},"Sheet","\u002Fcomponents\u002Fsheet","3.components\u002Fsheet",{"title":243,"path":244,"stem":245,"package":63,"icon":162},"Skeleton","\u002Fcomponents\u002Fskeleton","3.components\u002Fskeleton",{"title":247,"path":248,"stem":249,"package":63,"icon":250},"Slider","\u002Fcomponents\u002Fslider","3.components\u002Fslider","i-lucide-sliders-horizontal",{"title":252,"path":253,"stem":254,"package":63,"icon":255},"Sortable","\u002Fcomponents\u002Fsortable","3.components\u002Fsortable","i-lucide-list-restart",{"title":257,"path":258,"stem":259,"package":63,"icon":260},"Stepper","\u002Fcomponents\u002Fstepper","3.components\u002Fstepper","i-lucide-list-ordered",{"title":262,"path":263,"stem":264,"package":63,"icon":265},"Swipe Action","\u002Fcomponents\u002Fswipe-action","3.components\u002Fswipe-action","i-lucide-move-horizontal",{"title":267,"path":268,"stem":269,"package":63,"icon":270},"Swiper","\u002Fcomponents\u002Fswiper","3.components\u002Fswiper","i-lucide-gallery-horizontal-end",{"title":272,"path":273,"stem":274,"package":63,"icon":275},"Switch","\u002Fcomponents\u002Fswitch","3.components\u002Fswitch","i-lucide-toggle-right",{"title":277,"path":278,"stem":279,"package":63,"icon":162},"Tabs","\u002Fcomponents\u002Ftabs","3.components\u002Ftabs",{"title":281,"path":282,"stem":283,"package":63,"icon":148},"Textarea","\u002Fcomponents\u002Ftextarea","3.components\u002Ftextarea",{"title":285,"path":286,"stem":287,"package":63,"icon":207},"Toast","\u002Fcomponents\u002Ftoast","3.components\u002Ftoast",{"title":289,"path":290,"stem":291,"package":63,"icon":275},"Toggle","\u002Fcomponents\u002Ftoggle","3.components\u002Ftoggle",{"title":293,"path":294,"stem":295,"package":63,"icon":162},"Toggle Group","\u002Fcomponents\u002Ftoggle-group","3.components\u002Ftoggle-group",{"title":297,"path":298,"stem":299,"package":63,"icon":300},"Tray","\u002Fcomponents\u002Ftray","3.components\u002Ftray","i-lucide-square-dashed-bottom",{"title":302,"path":303,"stem":304,"children":305,"package":11,"icon":307},"Theming","\u002Ftheming","4.theming\u002F1.index",[306,308,312,317,322],{"title":302,"path":303,"stem":304,"package":11,"icon":307},"i-lucide-palette",{"title":309,"path":310,"stem":311,"package":11,"icon":250},"Overrides","\u002Ftheming\u002Foverrides","4.theming\u002F2.overrides",{"title":313,"path":314,"stem":315,"package":11,"icon":316},"Colors","\u002Ftheming\u002Fcolors","4.theming\u002F3.colors","i-lucide-swatch-book",{"title":318,"path":319,"stem":320,"package":11,"icon":321},"Dark Mode","\u002Ftheming\u002Fdark-mode","4.theming\u002F4.dark-mode","i-lucide-moon",{"title":323,"path":324,"stem":325,"package":11,"icon":326},"Fonts","\u002Ftheming\u002Ffonts","4.theming\u002F5.fonts","i-lucide-type",{"title":328,"path":329,"stem":330,"package":11,"icon":331},"Accessibility","\u002Faccessibility","5.accessibility","i-lucide-accessibility",{"title":333,"path":334,"stem":335,"package":11,"icon":336},"i18n","\u002Fi18n","6.i18n","i-lucide-languages",{"title":338,"path":339,"stem":340,"children":341,"package":11,"icon":343},"Composables","\u002Fcomposables","7.composables\u002F1.index",[342,344,349,354,359,364,369,374,378,383,387,391,396,401],{"title":338,"path":339,"stem":340,"package":11,"icon":343},"i-lucide-square-function",{"title":345,"path":346,"stem":347,"package":11,"icon":348},"useEmitAsProps","\u002Fcomposables\u002Fuse-emit-as-props","7.composables\u002F10.use-emit-as-props","i-lucide-zap",{"title":350,"path":351,"stem":352,"package":11,"icon":353},"useForwardPropsEmits","\u002Fcomposables\u002Fuse-forward-props-emits","7.composables\u002F11.use-forward-props-emits","i-lucide-merge",{"title":355,"path":356,"stem":357,"package":11,"icon":358},"useForwardExpose","\u002Fcomposables\u002Fuse-forward-expose","7.composables\u002F12.use-forward-expose","i-lucide-share-2",{"title":360,"path":361,"stem":362,"package":11,"icon":363},"useStateMachine","\u002Fcomposables\u002Fuse-state-machine","7.composables\u002F13.use-state-machine","i-lucide-workflow",{"title":365,"path":366,"stem":367,"package":11,"icon":368},"usePrimitiveElement","\u002Fcomposables\u002Fuse-primitive-element","7.composables\u002F14.use-primitive-element","i-lucide-crosshair",{"title":370,"path":371,"stem":372,"package":11,"icon":373},"useAppConfig","\u002Fcomposables\u002Fuse-app-config","7.composables\u002F2.use-app-config","i-lucide-settings",{"title":375,"path":376,"stem":377,"package":11,"icon":321},"useColorMode","\u002Fcomposables\u002Fuse-color-mode","7.composables\u002F3.use-color-mode",{"title":379,"path":380,"stem":381,"package":11,"icon":382},"useComponentIcons","\u002Fcomposables\u002Fuse-component-icons","7.composables\u002F4.use-component-icons","i-lucide-shapes",{"title":384,"path":385,"stem":386,"package":11,"icon":69},"useTray","\u002Fcomposables\u002Fuse-tray","7.composables\u002F5.use-tray",{"title":388,"path":389,"stem":390,"package":11,"icon":336},"i18n composables","\u002Fcomposables\u002Fi18n-composables","7.composables\u002F6.i18n-composables",{"title":392,"path":393,"stem":394,"package":11,"icon":395},"useId","\u002Fcomposables\u002Fuse-id","7.composables\u002F7.use-id","i-lucide-hash",{"title":397,"path":398,"stem":399,"package":11,"icon":400},"useFilter","\u002Fcomposables\u002Fuse-filter","7.composables\u002F8.use-filter","i-lucide-filter",{"title":402,"path":403,"stem":404,"package":11,"icon":405},"useForwardProps","\u002Fcomposables\u002Fuse-forward-props","7.composables\u002F9.use-forward-props","i-lucide-arrow-right-left",{"title":407,"path":408,"stem":409,"children":410,"package":11,"icon":412},"Guides","\u002Fguides","8.guides\u002F1.index",[411,413,417,422,427,432,437,441,446,450,455],{"title":407,"path":408,"stem":409,"package":11,"icon":412},"i-lucide-book-open",{"title":414,"path":415,"stem":416,"package":11,"icon":348},"Instant first-frame rendering","\u002Fguides\u002Finstant-first-frame-rendering","8.guides\u002F10.instant-first-frame-rendering",{"title":418,"path":419,"stem":420,"package":11,"icon":421},"Why use Vy UI","\u002Fguides\u002Fwhy-vy-ui","8.guides\u002F11.why-vy-ui","i-lucide-help-circle",{"title":423,"path":424,"stem":425,"package":11,"icon":426},"Lynx UI frameworks","\u002Fguides\u002Flynx-ui-frameworks","8.guides\u002F2.lynx-ui-frameworks","i-lucide-library",{"title":428,"path":429,"stem":430,"package":11,"icon":431},"What is Vue Lynx","\u002Fguides\u002Fvue-lynx","8.guides\u002F3.vue-lynx","i-lucide-component",{"title":433,"path":434,"stem":435,"package":11,"icon":436},"Lynx vs React Native","\u002Fguides\u002Flynx-vs-react-native","8.guides\u002F4.lynx-vs-react-native","i-lucide-git-compare",{"title":438,"path":439,"stem":440,"package":11,"icon":84},"Testing on your phone","\u002Fguides\u002Ftesting-on-device","8.guides\u002F5.testing-on-device",{"title":442,"path":443,"stem":444,"package":11,"icon":445},"Testing with Xcode","\u002Fguides\u002Ftesting-with-xcode","8.guides\u002F6.testing-with-xcode","i-lucide-apple",{"title":447,"path":448,"stem":449,"package":11,"icon":27},"The rspeedy dev server","\u002Fguides\u002Frspeedy-dev-server","8.guides\u002F7.rspeedy-dev-server",{"title":451,"path":452,"stem":453,"package":11,"icon":454},"Tailwind on Lynx","\u002Fguides\u002Ftailwind-on-lynx","8.guides\u002F8.tailwind-on-lynx","i-lucide-wind",{"title":456,"path":457,"stem":458,"package":11,"icon":459},"Theming on Lynx","\u002Fguides\u002Ftheming-on-lynx","8.guides\u002F9.theming-on-lynx","i-lucide-paintbrush",[461,492,513,539,662,834,1039,1253,1352,1376,1532,1622,1871,2216,2321,2559,2604,3219,3353,3638,3744,4099,4175,4204,4281,4440,4788,4996,5133,5247,5568,5616,5856,5878],{"id":462,"title":463,"body":464,"changelogOrder":11,"date":482,"description":483,"extension":484,"meta":485,"navigation":486,"package":79,"path":487,"seo":488,"stem":489,"version":490,"__hash__":491},"changelog\u002Fchangelog\u002Fcore-0.0.1.md","First release",{"type":465,"value":466,"toc":477},"minimark",[467],[468,469,470,473,474,476],"p",{},[471,472,41],"code",{}," publishes its first primitives: behavioural, accessible building blocks that run natively on Lynx and on the web from a single Vue codebase. Zero styling — compose them yourself or reach for ",[471,475,46],{},".",{"title":478,"searchDepth":479,"depth":480,"links":481},"",1,2,[],"2026-05-28","The first headless, accessible primitives land on npm — behaviour only, bring your own styles.","md",{},true,"\u002Fchangelog\u002Fcore-0.0.1",{"title":463,"description":483},"changelog\u002Fcore-0.0.1","v0.0.1","Q_t9O8yr_5su_uRuwOE7iPpXuH53v1YK8Co_xxGWlD8",{"id":493,"title":494,"body":495,"changelogOrder":11,"date":505,"description":506,"extension":484,"meta":507,"navigation":486,"package":79,"path":508,"seo":509,"stem":510,"version":511,"__hash__":512},"changelog\u002Fchangelog\u002Fcore-0.0.2.md","Performance & packaging",{"type":465,"value":496,"toc":503},[497],[468,498,499,500,502],{},"Icon resolution is memoized across instances to cut repeated work, with dependency pruning and packaging hardening to keep ",[471,501,41],{}," lean and safe to install.",{"title":478,"searchDepth":479,"depth":480,"links":504},[],"2026-05-29","Faster icon resolution and a leaner, hardened package ahead of wider testing.",{},"\u002Fchangelog\u002Fcore-0.0.2",{"title":494,"description":506},"changelog\u002Fcore-0.0.2","v0.0.2","qmHAuP2a9lAKeZcCuIvGgL1zLD_AVGQq2xso4EhcsZg",{"id":514,"title":515,"body":516,"changelogOrder":11,"date":531,"description":532,"extension":484,"meta":533,"navigation":486,"package":79,"path":534,"seo":535,"stem":536,"version":537,"__hash__":538},"changelog\u002Fchangelog\u002Fcore-0.0.3.md","Lynx-native a11y & shared gestures",{"type":465,"value":517,"toc":529},[518],[468,519,520,521,524,525,528],{},"Accessibility is wired through Lynx-native APIs instead of DOM assumptions, and the Swiper's gesture physics is extracted into a shared engine behind ",[471,522,523],{},"useDragGesture"," with a generic ",[471,526,527],{},"pickSnap"," helper — ready to power any swipe-driven primitive.",{"title":478,"searchDepth":479,"depth":480,"links":530},[],"2026-05-30","Accessibility now resolves through Lynx-native APIs, and gesture physics moves into one shared engine.",{},"\u002Fchangelog\u002Fcore-0.0.3",{"title":515,"description":532},"changelog\u002Fcore-0.0.3","v0.0.3","s3fDzHLL-Sc509FK2kd0oIVGAPqqm5ahXrCi21WOolY",{"id":540,"title":541,"body":542,"changelogOrder":11,"date":654,"description":655,"extension":484,"meta":656,"navigation":486,"package":79,"path":657,"seo":658,"stem":659,"version":660,"__hash__":661},"changelog\u002Fchangelog\u002Fcore-0.0.4.md","@vyui\u002Fcore v0.0.4",{"type":465,"value":543,"toc":650},[544,549],[545,546,548],"h3",{"id":547},"patch-changes","Patch Changes",[550,551,552],"ul",{},[553,554,555,556,558,559,562,563,562,566,562,569,572,573,576,577,579,580,587,588,591,592,594,595,598,599,602,603,606,607,609,610,613,614,617,618,620,621,624,625,628,629,631,632,634,635,637,638,641,642,645,646,649],"li",{},"Add NumberField — headless ",[471,557,41],{}," primitive (",[471,560,561],{},"NumberFieldRoot"," \u002F ",[471,564,565],{},"NumberFieldInput",[471,567,568],{},"NumberFieldIncrement",[471,570,571],{},"NumberFieldDecrement",") with min\u002Fmax\u002Fstep, clamp\u002Fsnap and decimal-precision handling, plus a styled ",[471,574,575],{},"VyNumberField"," in ",[471,578,46],{},". (",[581,582,586],"a",{"href":583,"rel":584},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fpull\u002F44",[585],"nofollow","#44",")",[589,590],"br",{},"Fix ",[471,593,145],{}," not reflecting programmatic value changes on native Lynx — controlled updates that don't originate from typing are now pushed through the imperative ",[471,596,597],{},"setValue"," path (the reactive ",[471,600,601],{},"value"," binding is initial-only on a native ",[471,604,605],{},"\u003Cinput>","). This makes NumberField's increment\u002Fdecrement buttons update the field on iOS\u002FAndroid, not just web.",[589,608],{},"Avatar now falls back to initials\u002Ficon when its image fails to load (wires the Lynx ",[471,611,612],{},"\u003Cimage>"," ",[471,615,616],{},"binderror"," event).",[589,619],{},"Document ",[471,622,623],{},"VyCombobox"," as the autocomplete pattern — ",[471,626,627],{},"searchable"," filtering over a fixed set covers the use case, so there is no separate Autocomplete component.",[589,630],{},"Widen ",[471,633,46],{},"'s ",[471,636,41],{}," peer-dependency range from ",[471,639,640],{},"^"," to ",[471,643,644],{},"~"," so it tracks ",[471,647,648],{},"0.0.x"," core patches without forcing a major bump.",{"title":478,"searchDepth":479,"depth":480,"links":651},[652],{"id":547,"depth":653,"text":548},3,"2026-06-01","Add NumberField — headless @vyui\u002Fcore primitive (NumberFieldRoot \u002F NumberFieldInput \u002F NumberFieldIncrement \u002F NumberFieldDecrement) with min\u002Fmax\u002Fstep, clamp\u002Fs…",{},"\u002Fchangelog\u002Fcore-0.0.4",{"title":541,"description":655},"changelog\u002Fcore-0.0.4","v0.0.4","CM2B6vpfYBWZ1HchBr38avHQASkBrlvgT_0BVq1Nb_0",{"id":663,"title":664,"body":665,"changelogOrder":11,"date":826,"description":827,"extension":484,"meta":828,"navigation":486,"package":79,"path":829,"seo":830,"stem":831,"version":832,"__hash__":833},"changelog\u002Fchangelog\u002Fcore-0.0.5.md","@vyui\u002Fcore v0.0.5",{"type":465,"value":666,"toc":823},[667,669],[545,668,548],{"id":547},[550,670,671,711,770],{},[553,672,673,674,558,676,679,680,683,684,686,687,690,691,694,695,587,700,702,703,706,707,710],{},"Add AspectRatio — headless ",[471,675,41],{},[471,677,678],{},"AspectRatioRoot",", exported as both ",[471,681,682],{},"AspectRatio"," and ",[471,685,678],{},") that constrains its default slot to a given ",[471,688,689],{},"ratio"," (number, default ",[471,692,693],{},"1","). (",[581,696,699],{"href":697,"rel":698},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fpull\u002F46",[585],"#46",[589,701],{},"Built for the Lynx render layer: it renders a single ",[471,704,705],{},"\u003Cview>"," using the native CSS ",[471,708,709],{},"aspect-ratio"," property (supported by Lynx's Starlight layout engine), with no absolutely-positioned padding wrapper.",[553,712,713,714,716,717,562,720,562,723,726,727,729,730,732,733,735,736,738,739,742,743,745,746,749,750,587,753,755,756,634,758,761,762,765,766,769],{},"Add Avatar — Lynx-native ",[471,715,41],{}," primitives (",[471,718,719],{},"AvatarRoot",[471,721,722],{},"AvatarImage",[471,724,725],{},"AvatarFallback","). ",[471,728,719],{}," provides image load-status context; ",[471,731,722],{}," renders a Lynx ",[471,734,612],{}," and downgrades to the error state on ",[471,737,616],{}," (",[471,740,741],{},"@error","); ",[471,744,725],{}," shows when no image is loaded, with a ",[471,747,748],{},"delayMs"," flash-avoidance delay. (",[581,751,699],{"href":697,"rel":752},[585],[589,754],{},"Refactor ",[471,757,46],{},[471,759,760],{},"VyAvatar"," to compose the new core primitives for behaviour (load-status + fallback) while keeping its public ",[471,763,764],{},"AvatarProps"," API, initials derivation, chip overlay, theming, and ",[471,767,768],{},"AvatarGroup"," size\u002Fcolor inheritance unchanged.",[553,771,772,773,587,778,780,782,783,814,816,782,818],{},"Fixes from #67, #68 and #70. (",[581,774,777],{"href":775,"rel":776},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fpull\u002F71",[585],"#71",[589,779],{},[471,781,41],{},":",[550,784,785,792,804],{},[553,786,787,788,791],{},"Icon: reject ",[471,789,790],{},"color"," values that could inject SVG markup when resolving icon sources (#67).",[553,793,794,795,798,799,683,801,803],{},"Sheet: multi-snap drag now settles to the nearest snap point, with main-thread usage fixes across ",[471,796,797],{},"SheetContentImpl",", ",[471,800,131],{},[471,802,523],{}," (#68).",[553,805,806,807,810,811,813],{},"Primitive: treat ",[471,808,809],{},"image"," as a self-closing leaf — Vue's empty-slot fragment\u002Fcomment anchors were materialized as real children by vue-lynx, and a native ",[471,812,612],{}," with any child fails to render (native-only breakage; lynx-web tolerated it) (#70).",[589,815],{},[471,817,46],{},[550,819,820],{},[553,821,822],{},"Forward icon classes\u002Fprops through ActionSheet, Alert, Button, Tabs, Toast, ToggleGroup and DropdownMenu items, and fix Drawer\u002Ftheme slot classes so drawer animations work again (#70).",{"title":478,"searchDepth":479,"depth":480,"links":824},[825],{"id":547,"depth":653,"text":548},"2026-06-11","Add AspectRatio — headless @vyui\u002Fcore primitive (AspectRatioRoot, exported as both AspectRatio and AspectRatioRoot) that constrains its default slot to a giv…",{},"\u002Fchangelog\u002Fcore-0.0.5",{"title":664,"description":827},"changelog\u002Fcore-0.0.5","v0.0.5","vJGTL_ZF7T-mR5aykkgruJd9yfj4Z_LRTDw7oxnfg_4",{"id":835,"title":836,"body":837,"changelogOrder":11,"date":1031,"description":1032,"extension":484,"meta":1033,"navigation":486,"package":79,"path":1034,"seo":1035,"stem":1036,"version":1037,"__hash__":1038},"changelog\u002Fchangelog\u002Fcore-0.0.6.md","Gesture & scroll motion overhaul",{"type":465,"value":838,"toc":1029},[839,842,912,946,987,1001],[468,840,841],{},"A motion-focused release: the scroll and gesture primitives gain the physics they were missing on native Lynx.",[468,843,844,848,849,852,853,856,857,860,861,798,864,798,867,562,870,873,874,877,878,742,881,884,885,888,889,892,893,896,897,900,901,562,904,907,908,911],{},[845,846,847],"strong",{},"FeedList"," gets a full pull-to-refresh + paging surface. Pull-to-refresh is a custom rubber-band driven by ",[471,850,851],{},":main-thread-bindtouch*"," worklets on a bare ",[471,854,855],{},"\u003Clist>"," — it only engages at the top edge, so normal scrolling and load-more are untouched. New: ",[471,858,859],{},"enableRefresh"," + ",[471,862,863],{},"v-model:refreshing",[471,865,866],{},"refreshThreshold",[471,868,869],{},"refresh",[471,871,872],{},"refreshStateChange"," emits and a ",[471,875,876],{},"refreshHeader"," slot (",[471,879,880],{},"{ state, progress }",[471,882,883],{},"enableBounce"," rubber-band overscroll at both edges; ",[471,886,887],{},"itemSnap"," native ",[471,890,891],{},"item-snap"," paging with a ",[471,894,895],{},"snap"," emit; and debounced load-more on ",[471,898,899],{},"scrolltolower"," with ",[471,902,903],{},"loadMoreFooter",[471,905,906],{},"noMoreDataFooter"," slots. The legacy native ",[471,909,910],{},"\u003Crefresh>"," path (unregistered in the OSS Lynx runtime) is removed.",[468,913,914,917,918,798,921,798,924,927,928,798,931,562,934,937,938,941,942,945],{},[845,915,916],{},"ScrollView"," adds a main-thread custom bounce\u002Foverscroll system mirroring lynx-ui: ",[471,919,920],{},"enableBounces",[471,922,923],{},"singleSidedBounce",[471,925,926],{},"alwaysBouncing",", trigger-distance and estimated-size props, ",[471,929,930],{},"enableRTL",[471,932,933],{},"upperBounceItem",[471,935,936],{},"lowerBounceItem"," slots, and an ",[471,939,940],{},"onScrollToBounces"," event — driven by the new ",[471,943,944],{},"useBounce"," composable.",[468,947,948,950,951,954,955,798,958,798,961,860,964,967,968,798,971,798,974,860,977,798,980,983,984,476],{},[845,949,267],{}," loop is now truly seamless — edge slides are cloned and the transform rebases invisibly across the first↔last seam under both drag-release and autoplay. Adds ",[471,952,953],{},"loop","\u002F",[471,956,957],{},"circular",[471,959,960],{},"axisLock",[471,962,963],{},"autoplay",[471,965,966],{},"interval",", plus lynx-ui prop parity: ",[471,969,970],{},"spaceBetween",[471,972,973],{},"mode",[471,975,976],{},"align",[471,978,979],{},"containerWidth",[471,981,982],{},"offsetLimit",", and ",[471,985,986],{},"rtl",[468,988,989,992,993,996,997,1000],{},[845,990,991],{},"Sortable, Draggable & SwipeAction"," tighten on-device gesture fidelity: velocity-aware release (fling\u002Fmomentum), axis locking, autoscroll near Sortable list edges, and bounds clamping, via shared helpers in ",[471,994,995],{},"shared\u002Fgesture\u002Fphysics.ts",". Fixes two regressions — Sortable long-press now arms entirely on the main thread (the BG round-trip was being dropped on-device), and SwipeAction cancels its in-flight ",[471,998,999],{},"fill: 'forwards'"," snap on touchstart so a follow-up slow drag isn't masked.",[468,1002,1003,1005,1006,1009,1010,1013,1014,683,1017,1020,1021,1024,1025,1028],{},[845,1004,285],{}," internals are prepped for stacking: ",[471,1007,1008],{},"ToastRoot"," binds its own ",[471,1011,1012],{},"@layoutchange"," to feed fan-out geometry, exposes ",[471,1015,1016],{},"duration",[471,1018,1019],{},"progress"," slot values, and ships a new ",[471,1022,1023],{},"ToastSwipe"," main-thread swipe-to-dismiss layer (exporting the unit-tested ",[471,1026,1027],{},"decideDismiss"," policy).",{"title":478,"searchDepth":479,"depth":480,"links":1030},[],"2026-06-16","Custom pull-to-refresh and overscroll bounce, a seamless Swiper loop, sharper drag physics, and Sonner-ready Toast internals.",{},"\u002Fchangelog\u002Fcore-0.0.6",{"title":836,"description":1032},"changelog\u002Fcore-0.0.6","v0.0.6","5sKdzA9a3IqMTIKU8BZxvG8c3imTaNhMwDiqKKMgJHM",{"id":1040,"title":1041,"body":1042,"changelogOrder":1244,"date":1245,"description":1246,"extension":484,"meta":1247,"navigation":486,"package":79,"path":1248,"seo":1249,"stem":1250,"version":1251,"__hash__":1252},"changelog\u002Fchangelog\u002Fcore-0.1.0.md","@vyui\u002Fcore v0.1.0",{"type":465,"value":1043,"toc":1240},[1044,1048,1121,1123],[545,1045,1047],{"id":1046},"minor-changes","Minor Changes",[550,1049,1050],{},[553,1051,1052,1053,1056,1057],{},"0610d70: Input\u002FTextarea: surface the on-screen keyboard via a normalized ",[471,1054,1055],{},"keyboard"," event.",[550,1058,1059,1087,1100],{},[553,1060,1061,683,1063,1065,1066,954,1069,1072,1073,900,1075,1078,1079,1082,1083,1086],{},[471,1062,145],{},[471,1064,281],{}," (core) and ",[471,1067,1068],{},"VyInput",[471,1070,1071],{},"VyTextarea"," (kit) now emit ",[471,1074,1055],{},[471,1076,1077],{},"{ visible: boolean, height: number, safeAreaBottom: number }",", normalized from Lynx's raw element payload ",[471,1080,1081],{},"{ show, keyBoardHeight, safeAreaBottom }"," (note the capital B in ",[471,1084,1085],{},"keyBoardHeight",").",[553,1088,1089,1090,613,1093,1096,1097,476],{},"This is the reliable keyboard signal under vue-lynx: the global ",[471,1091,1092],{},"GlobalEventEmitter",[471,1094,1095],{},"keyboardstatuschanged"," event is emitted natively but is not delivered to the vue-lynx background runtime, so the per-element event is what consumers (and keyboard-aware lifts) should use. See ",[471,1098,1099],{},"docs\u002Fupstream\u002Fvue-lynx-keyboard.md",[553,1101,1102,1104,1105,954,1108,954,1111,1114,1115,1118,1119,476],{},[471,1103,1071],{}," also now forwards ",[471,1106,1107],{},"confirm",[471,1109,1110],{},"focus",[471,1112,1113],{},"blur"," (previously only ",[471,1116,1117],{},"update:modelValue","), matching ",[471,1120,1068],{},[545,1122,548],{"id":547},[550,1124,1125,1162,1177,1237],{},[553,1126,1127,1128,1131,1132,1134,1135,1137,1138,1140,1141,1144,1145,1148,1149,1151,1152,1154,1155,1157,1158,1161],{},"0610d70: FeedList: honour a ",[471,1129,1130],{},"noMoreData"," prop so the end-of-list footer no longer shows while more pages remain.",[589,1133],{},"Previously the core ",[471,1136,847],{}," rendered the ",[471,1139,906],{}," slot whenever ",[471,1142,1143],{},"loadingMore"," was false, so \"no more items\" appeared immediately even with pages still loadable (the kit ",[471,1146,1147],{},"VyFeedList"," already forwarded ",[471,1150,1130],{},", but core ignored it). The footer row now only renders while ",[471,1153,1143],{}," (load-more spinner) or once ",[471,1156,1130],{}," is ",[471,1159,1160],{},"true"," (end-of-list); otherwise no footer renders.",[553,1163,1164,1165,1168,1169,1172,1173,641,1175,476],{},"baf0692: Fix drawer\u002Fsheet not opening fully: Lynx native drops the ",[471,1166,1167],{},"dvh"," unit, collapsing the panel to its content height. Size the sheet panel with ",[471,1170,1171],{},"vh"," and switch all viewport-height classes in the kit themes (drawer, modal, select, combobox, popover, dropdownMenu, island, actionSheet) from ",[471,1174,1167],{},[471,1176,1171],{},[553,1178,1179,1180,1234,1236],{},"0610d70: Fix Sortable drag-to-reorder doing nothing on device\u002Fweb:",[550,1181,1182,1207],{},[553,1183,1184,1187,1188,613,1191,1194,1195,1198,1199,1202,1203,1206],{},[845,1185,1186],{},"Registry was empty on the main thread."," Items registered their handle via a background-thread write to the ",[471,1189,1190],{},"itemHandlesMT",[471,1192,1193],{},"MainThreadRef",", which vue-lynx 0.4.0 silently drops. The lifted row never moved, siblings never shifted, and the drop saw ",[471,1196,1197],{},"count === 0"," so no reorder committed. Registration (element + index) now runs on the main thread, bound to ",[471,1200,1201],{},"main-thread-binduiappear",", with MT teardown on unmount and ",[471,1204,1205],{},"runOnMainThread"," setter worklets for index\u002Fdisabled sync.",[553,1208,1209,1215,1216,954,1218,1221,1222,1225,1226,1229,1230,1233],{},[845,1210,1211,1212,476],{},"Long-press used MT ",[471,1213,1214],{},"setTimeout"," The main-thread worklet runtime does not expose ",[471,1217,1214],{},[471,1219,1220],{},"clearTimeout"," (internal in ",[471,1223,1224],{},"@lynx-js\u002Ftypes","), so the long-press timer threw and the row never lifted for any ",[471,1227,1228],{},"longPressMs > 0",". The hold is now timed by polling ",[471,1231,1232],{},"requestAnimationFrame"," on the main thread.",[589,1235],{},"Public props\u002Femits\u002Fslots unchanged.",[553,1238,1239],{},"300e34f: Keep sheet snap and drag geometry synchronized with dynamic viewport changes, and make kit swipers fill their measured container when no explicit item width is provided.",{"title":478,"searchDepth":479,"depth":480,"links":1241},[1242,1243],{"id":1046,"depth":653,"text":1047},{"id":547,"depth":653,"text":548},1000,"2026-06-25","0610d70: Input\u002FTextarea: surface the on-screen keyboard via a normalized keyboard event.",{},"\u002Fchangelog\u002Fcore-0.1.0",{"title":1041,"description":1246},"changelog\u002Fcore-0.1.0","v0.1.0","Qj7pVlbVelBfF_XNbNkTs0tvgXYzDVbctUb2U8p9M0E",{"id":1254,"title":1255,"body":1256,"changelogOrder":1343,"date":1344,"description":1345,"extension":484,"meta":1346,"navigation":486,"package":79,"path":1347,"seo":1348,"stem":1349,"version":1350,"__hash__":1351},"changelog\u002Fchangelog\u002Fcore-0.1.1.md","@vyui\u002Fcore v0.1.1",{"type":465,"value":1257,"toc":1340},[1258,1260],[545,1259,548],{"id":547},[550,1261,1262,1314],{},[553,1263,1264,1265,1268,1269,1271,1272,1275,1276,562,1279,1282,1283,1286,1287,1290,1291,1294,1295,1297,613,1299,1302,1303,1306,1307,1310,1311,1313],{},"bb4d208: Add ",[471,1266,1267],{},"VyTray"," — a morphing, multi-view bottom sheet built on the core ",[471,1270,239],{}," primitives. Views (",[471,1273,1274],{},"VyTrayView",") are measured per screen and the panel animates its height to fit whichever is showing (\"grows into place\"), with a back stack (",[471,1277,1278],{},"useTray().goBack",[471,1280,1281],{},"canGoBack","), a persistent ",[471,1284,1285],{},"#footer"," slot, and ",[471,1288,1289],{},"floating"," (detached card) vs ",[471,1292,1293],{},"flush"," (edge-anchored) variants.",[589,1296],{},[471,1298,41],{},[471,1300,1301],{},"SheetContent"," gains a ",[471,1304,1305],{},"fitContent"," prop that sizes the panel to its natural content height instead of a ",[471,1308,1309],{},"snapPoints × viewport"," fraction — the drag\u002Fslide\u002Fbackdrop physics reuse the measured height, so nothing else changes. This is the mode ",[471,1312,1267],{}," builds on.",[553,1315,1316,1317,1320,1321,1324,1325,1328,1329,1331,1332,1335,1336,1339],{},"31c2202: Add side-aware sheet and drawer motion. ",[471,1318,1319],{},"SheetRoot"," now accepts ",[471,1322,1323],{},"side"," for top, right, bottom, and left edge placement with matching slide animations and drag-to-dismiss physics. ",[471,1326,1327],{},"VyDrawer"," forwards its side to the core sheet, and sheet-backed kit components can opt into alternate edges.",[589,1330],{},"Edge placement and the enter\u002Fleave slide keyframes key off a ",[471,1333,1334],{},"vyui-sheet__content--{side}"," class rather than a ",[471,1337,1338],{},"[data-side]"," attribute selector, so they apply on Lynx native (which does not match attribute selectors in CSS) — restoring the open\u002Fclose animation on device.",{"title":478,"searchDepth":479,"depth":480,"links":1341},[1342],{"id":547,"depth":653,"text":548},1001,"2026-07-04","bb4d208: Add VyTray — a morphing, multi-view bottom sheet built on the core Sheet primitives.",{},"\u002Fchangelog\u002Fcore-0.1.1",{"title":1255,"description":1345},"changelog\u002Fcore-0.1.1","v0.1.1","Q3orlifP3NYpUWiXvi3oYWqCUDTtxB0FxZy--N0leiA",{"id":1353,"title":1354,"body":1355,"changelogOrder":1367,"date":1368,"description":1369,"extension":484,"meta":1370,"navigation":486,"package":79,"path":1371,"seo":1372,"stem":1373,"version":1374,"__hash__":1375},"changelog\u002Fchangelog\u002Fcore-0.1.2.md","@vyui\u002Fcore v0.1.2",{"type":465,"value":1356,"toc":1364},[1357,1359],[545,1358,548],{"id":547},[550,1360,1361],{},[553,1362,1363],{},"cbbbcbf: Ensure tray, drawer, and action sheet content renders above the sheet backdrop by default, and disable automatic capitalization and correction for kit email and password inputs.",{"title":478,"searchDepth":479,"depth":480,"links":1365},[1366],{"id":547,"depth":653,"text":548},1002,"2026-07-05","cbbbcbf: Ensure tray, drawer, and action sheet content renders above the sheet backdrop by default, and disable automatic capitalization and correction for k…",{},"\u002Fchangelog\u002Fcore-0.1.2",{"title":1354,"description":1369},"changelog\u002Fcore-0.1.2","v0.1.2","a64Fm9fx61_MJaot3Gz118FM9eqKcc6K4gJ5zsdBWEc",{"id":1377,"title":1378,"body":1379,"changelogOrder":1523,"date":1524,"description":1525,"extension":484,"meta":1526,"navigation":486,"package":79,"path":1527,"seo":1528,"stem":1529,"version":1530,"__hash__":1531},"changelog\u002Fchangelog\u002Fcore-0.2.0.md","@vyui\u002Fcore v0.2.0",{"type":465,"value":1380,"toc":1520},[1381,1383],[545,1382,1047],{"id":1046},[550,1384,1385,1454],{},[553,1386,1387,1388,1390,1391,798,1394,1397,1398,1401,1402,1405,1406,1410,1411,1413,1414,1416,1417,1419,1420,1423,1424,1426,1427,1430,1431,1434,1435,1437,1438,634,1440,1443,1444,1446,1447,1450,1451,1453],{},"c344b72: Per-component subpath entries for tree-shakeable consumption. ",[471,1389,46],{}," now exposes every component as its own entry point (",[471,1392,1393],{},"@vyui\u002Fkit\u002Fbutton",[471,1395,1396],{},"@vyui\u002Fkit\u002Ftray",", …) with the same canonical ",[471,1399,1400],{},"Vy*"," bindings as the barrel, so migrating is a specifier swap. Because the vue-lynx main-thread worklet pipeline prunes by ",[471,1403,1404],{},"sideEffects"," globs over whatever is ",[1407,1408,1409],"em",{},"reached"," (bare side-effect imports erase export usage), deep entries are the only way to ship less: importing ",[471,1412,1393],{}," now reaches ~37 modules \u002F 26 worklet registrations instead of the barrel's ~294 \u002F 118.",[589,1415],{},"To make this work end-to-end, kit's build rewrites its own ",[471,1418,41],{}," barrel imports to per-file deep specifiers (",[471,1421,1422],{},"@vyui\u002Fcore\u002Fdist\u002Fcomponents\u002F….vue.js","), and ",[471,1425,41],{}," exposes a ",[471,1428,1429],{},".\u002Fdist\u002F*.js"," wildcard export to resolve them. Barrel imports (",[471,1432,1433],{},"import { VyButton } from '@vyui\u002Fkit'",") keep working unchanged — they just keep the everything-ships behavior.",[589,1436],{},"Also fixes ",[471,1439,46],{},[471,1441,1442],{},"sideEffects: false",", which let bundlers drop the package entirely from the vue-lynx main-thread worklet slice (entered via a bare side-effect import that uses no exports), so every transitively-imported ",[471,1445,41],{}," worklet went unregistered and consumers crashed with ",[471,1448,1449],{},"bind of undefined",". Kit now declares the same ",[471,1452,1404],{}," globs as core.",[553,1455,1456,1457,1460,1461],{},"c344b72: Ship per-file, source-shaped ESM dist (Vite lib + Rollup ",[471,1458,1459],{},"preserveModules",") instead of an rslib bundle.",[550,1462,1463,1474,1502,1509],{},[553,1464,1465,1466,1469,1470,1473],{},"Fixes the ",[471,1467,1468],{},"__WEBPACK_EXTERNAL_MODULE_vue_lynx_* is not defined"," main-thread crash for npm consumers of worklet-driven components (VyTray, VyDrawer, Slider, …): worklet modules now keep direct named ",[471,1471,1472],{},"vue-lynx"," imports the consumer's MT toolchain can follow.",[553,1475,1476,1477,1480,1481,1484,1485,1488,1489,1492,1493,1496,1497,634,1499,1501],{},"Fixes the follow-on ",[471,1478,1479],{},"cannot read property 'bind' of undefined"," main-thread crash: each pre-compiled worklet module retains a ",[471,1482,1483],{},"\"main thread\""," marker so the consumer's ",[471,1486,1487],{},"worklet-loader-mt"," extracts its ",[471,1490,1491],{},"registerWorkletInternal"," calls (with ",[471,1494,1495],{},"_wkltId","s matching the background bundle) instead of dropping them. ",[471,1498,46],{},[471,1500,1404],{}," is widened to keep the transitive-core-worklet MT imports from being tree-shaken.",[553,1503,1504,1505,1508],{},"SFC ",[471,1506,1507],{},"\u003Cstyle>"," CSS is now published and auto-imported per module — the old bundle stubbed it, so consumers silently lost component styles.",[553,1510,1511,1512,1515,1516,1519],{},"Each SFC ships as a single ",[471,1513,1514],{},"X.vue.js","; a ",[471,1517,1518],{},"check-dist-shape"," guard fails the build on any bundle fingerprint or a worklet module missing its marker.",{"title":478,"searchDepth":479,"depth":480,"links":1521},[1522],{"id":1046,"depth":653,"text":1047},2000,"2026-07-06","c344b72: Per-component subpath entries for tree-shakeable consumption.",{},"\u002Fchangelog\u002Fcore-0.2.0",{"title":1378,"description":1525},"changelog\u002Fcore-0.2.0","v0.2.0","C0u9Cfkqq8lopknOYz6MNPz_OM1p5NhMXwUQVorWTYg",{"id":1533,"title":1534,"body":1535,"changelogOrder":1613,"date":1614,"description":1615,"extension":484,"meta":1616,"navigation":486,"package":79,"path":1617,"seo":1618,"stem":1619,"version":1620,"__hash__":1621},"changelog\u002Fchangelog\u002Fcore-0.2.1.md","@vyui\u002Fcore v0.2.1",{"type":465,"value":1536,"toc":1610},[1537,1539],[545,1538,548],{"id":547},[550,1540,1541,1573,1576],{},[553,1542,1543,1544,1547,1548,1550,1551,1554,1555,1558,1559,634,1561,1564,1565,1568,1569,1572],{},"4ee6a7d: Make KeyboardAware work under vue-lynx: the root now receives keyboard height from the input's per-element ",[471,1545,1546],{},"@keyboard"," event (the global ",[471,1549,1095],{}," event never reaches the vue-lynx background runtime), inputs self-register with a surrounding ",[471,1552,1553],{},"KeyboardAwareRoot"," without needing a ",[471,1556,1557],{},"KeyboardAwareTrigger"," wrap, and ",[471,1560,1267],{},[471,1562,1563],{},"keyboardAware"," now also covers the body (new ",[471,1566,1567],{},"'lift' | 'scroll'"," modes plus ",[471,1570,1571],{},"bodyScroll"," ui slot) instead of silently doing nothing without a footer slot.",[553,1574,1575],{},"d4f9b1a: Update public package and documentation copy to describe Vy UI as Lynx-native UI primitives for Vue.",[553,1577,1578,1579,1582,1583,1586,1587,1590,1591,1594,1595,1598,1599,1602,1603,1606,1607,1086],{},"1637c40: Sortable rows no longer drag list chrome along with the finger. The kit theme now renders each row as a transparent shell (the element core transforms) around a new ",[471,1580,1581],{},"itemContent"," pill slot, so only the pill visibly moves — the old ",[471,1584,1585],{},"border-b"," divider look is gone. ",[471,1588,1589],{},"SortableItem"," flips a ",[471,1592,1593],{},"ui-dragging"," class (+ ",[471,1596,1597],{},"data-state=\"dragging\"",") on the lifted row, and ",[471,1600,1601],{},"VYUI_UI_STATES"," gains ",[471,1604,1605],{},"dragging"," so themes can restyle the lifted pill (default: stronger pill border via ",[471,1608,1609],{},"group-ui-dragging:",{"title":478,"searchDepth":479,"depth":480,"links":1611},[1612],{"id":547,"depth":653,"text":548},2001,"2026-07-08","4ee6a7d: Make KeyboardAware work under vue-lynx: the root now receives keyboard height from the input's per-element @keyboard event (the global keyboardstatu…",{},"\u002Fchangelog\u002Fcore-0.2.1",{"title":1534,"description":1615},"changelog\u002Fcore-0.2.1","v0.2.1","Cf-lGwvBfMlffnXfXyOwnwiCW_ZOTeu1Ygyit-WyJt0",{"id":1623,"title":1624,"body":1625,"changelogOrder":1863,"date":1614,"description":1864,"extension":484,"meta":1865,"navigation":486,"package":79,"path":1866,"seo":1867,"stem":1868,"version":1869,"__hash__":1870},"changelog\u002Fchangelog\u002Fcore-0.2.2.md","@vyui\u002Fcore v0.2.2",{"type":465,"value":1626,"toc":1860},[1627,1629],[545,1628,548],{"id":547},[550,1630,1631,1744],{},[553,1632,1633,1634,587,1639],{},"Cleanup pass: dead code removal, export gaps, and a color-parsing bug fix. (",[581,1635,1638],{"href":1636,"rel":1637},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fpull\u002F133",[585],"#133",[550,1640,1641,1657,1673,1689,1708,1720],{},[553,1642,1643,1645,1646,1649,1650,954,1653,1656],{},[471,1644,41],{},": export ",[471,1647,1648],{},"ConfigProvider"," from the public API — ",[471,1651,1652],{},"useLocale",[471,1654,1655],{},"useDirection"," depend on its context but had no supported way to provide it",[553,1658,1659,1661,1662,1665,1666,954,1669,1672],{},[471,1660,41],{},": remove the disposable ",[471,1663,1664],{},"useMtSmoke"," diagnostic and unused ",[471,1667,1668],{},"pick",[471,1670,1671],{},"omit"," utils",[553,1674,1675,1677,1678,1681,1682,1684,1685,1688],{},[471,1676,41],{},": type ",[471,1679,1680],{},"Radio.vue","'s click handler with ",[471,1683,1224],{},"' ",[471,1686,1687],{},"MouseEvent",", not the DOM global",[553,1690,1691,1693,1694,954,1697,1700,1701,1704,1705],{},[471,1692,41],{},": fix ",[471,1695,1696],{},"parseColor()",[471,1698,1699],{},"isValidColor()"," — ",[471,1702,1703],{},"hsv()"," strings always threw despite being documented as a supported alias of ",[471,1706,1707],{},"hsb()",[553,1709,1710,1645,1712,1715,1716,1719],{},[471,1711,46],{},[471,1713,1714],{},"tray"," from ",[471,1717,1718],{},"@vyui\u002Fkit\u002Ftheme"," (missing, unlike every other component)",[553,1721,1722,1724,1725,954,1728,954,1731,1734,1735,634,1738,1740,1741],{},[471,1723,46],{},": add exported ",[471,1726,1727],{},"SelectEmits",[471,1729,1730],{},"ComboboxEmits",[471,1732,1733],{},"FeedListEmits"," interfaces; ",[471,1736,1737],{},"Combobox",[471,1739,1117],{}," is now typed instead of ",[471,1742,1743],{},"any",[553,1745,1746,1747,587,1752],{},"Performance pass around tab switching and theme resolution. (",[581,1748,1751],{"href":1749,"rel":1750},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fpull\u002F134",[585],"#134",[550,1753,1754,1772,1783,1813,1830,1844],{},[553,1755,1756,1758,1759,613,1761,1764,1765,860,1768,1771],{},[471,1757,41],{},": ",[471,1760,277],{},[471,1762,1763],{},"unmountOnHide: false"," now works — a panel mounts on first visit and stays mounted (hidden via ",[471,1766,1767],{},"display: none",[471,1769,1770],{},"accessibility-elements-hidden",") after; previously the flag was threaded into context but never read, so panels always unmounted",[553,1773,1774,1776,1777,613,1779,1782],{},[471,1775,41],{},": new ",[471,1778,277],{},[471,1780,1781],{},"deferContent"," prop — commits the content swap one macrotask after the trigger\u002Findicator update so the tab bar responds instantly while a heavy panel mounts",[553,1784,1785,1758,1787,1790,1791,1794,1795,1798,1799,562,1802,1805,1806,1808,1809,1812],{},[471,1786,41],{},[471,1788,1789],{},"TabsContent"," accepts a per-panel ",[471,1792,1793],{},"unmountOnHide"," override (kit: ",[471,1796,1797],{},"TabsItem.unmountOnHide",") — panels whose subtrees write styles from main-thread worklets (",[471,1800,1801],{},"setStyleProperty",[471,1803,1804],{},"animate(fill: 'forwards')",") can keep painting through the kept-alive ",[471,1807,1767],{}," on device and should opt back into unmounting; kept-hidden panels also set ",[471,1810,1811],{},"visibility: hidden"," as defence",[553,1814,1815,1817,1818,1821,1822,1825,1826,1829],{},[471,1816,46],{},": theme ",[471,1819,1820],{},"tv"," factories are memoized per app config (",[471,1823,1824],{},"defineThemeBuilder",", also inside ",[471,1827,1828],{},"useStyledComponent",") instead of rebuilt per component instance — visible on Lynx's interpreter whenever a screenful of components mounts",[553,1831,1832,1758,1834,1836,1837,1839,1840,1843],{},[471,1833,46],{},[471,1835,277],{}," forwards ",[471,1838,1781],{},", resolves slot classes once per variant change instead of per trigger per render, and its triggers regain press feedback (",[471,1841,1842],{},"active:opacity-60"," on the trigger itself — element opacity needs no CSS inheritance)",[553,1845,1846,1848,1849,1852,1853,954,1856,1859],{},[471,1847,46],{},": the Tailwind preset safelist now emits the EXACT classes the packaged themes generate for the configured color set (collected by walking the tv configs) instead of every ",[471,1850,1851],{},"utility × color × shade × variant"," combination — ~90% less generated CSS (857 KB → 84 KB in kit-demo), and the dead ",[471,1854,1855],{},"data-[…]",[471,1857,1858],{},"ring-*"," entries are gone",{"title":478,"searchDepth":479,"depth":480,"links":1861},[1862],{"id":547,"depth":653,"text":548},2002,"Cleanup pass: dead code removal, export gaps, and a color-parsing bug fix.",{},"\u002Fchangelog\u002Fcore-0.2.2",{"title":1624,"description":1864},"changelog\u002Fcore-0.2.2","v0.2.2","vbrzc5z0KVk3C6m-E9LDCrUJRgAKXYcFV8rAY62MQcw",{"id":1872,"title":1873,"body":1874,"changelogOrder":2207,"date":2208,"description":2209,"extension":484,"meta":2210,"navigation":486,"package":79,"path":2211,"seo":2212,"stem":2213,"version":2214,"__hash__":2215},"changelog\u002Fchangelog\u002Fcore-0.2.3.md","@vyui\u002Fcore v0.2.3",{"type":465,"value":1875,"toc":2204},[1876,1878],[545,1877,548],{"id":547},[550,1879,1880,1913,2047,2136,2152,2180],{},[553,1881,1882,1884,1885,1888,1889,1892,1893,1896,1897,634,1900,1903,1904,1907,1908,587],{},[471,1883,101],{}," forwards the Lynx tap event through its ",[471,1886,1887],{},"tap"," emit (",[471,1890,1891],{},"tap: [event: TouchEvent]","). Previously it emitted bare, so modifier-wrapped listeners merged in via ",[471,1894,1895],{},"asChild"," — like ",[471,1898,1899],{},"ToastClose",[471,1901,1902],{},"@tap.stop"," over a button — crashed with ",[471,1905,1906],{},"undefined.stopPropagation"," on tap, leaving the toast close button broken. (",[581,1909,1912],{"href":1910,"rel":1911},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fpull\u002F137",[585],"#137",[553,1914,1915,1916,587,1921,1923,1926,1927,798,1930,1933,1934,954,1937,954,1940,1943,1944,476,1946],{},"Dead-code audit: remove modules with zero consumers across core, kit, and every example app. (",[581,1917,1920],{"href":1918,"rel":1919},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fpull\u002F138",[585],"#138",[589,1922],{},[845,1924,1925],{},"Breaking"," (pre-1.0 patch by repo policy): removes never-used public exports — ",[471,1928,1929],{},"withDefault",[471,1931,1932],{},"useScrollTo",", and the ",[471,1935,1936],{},"components",[471,1938,1939],{},"originals",[471,1941,1942],{},"utilities"," registry — from ",[471,1945,41],{},[550,1947,1948,1955,1980,2008,2022,2033,2042],{},[553,1949,1950,1951,1954],{},"remove the unexported ",[471,1952,1953],{},"shared\u002Fcolor\u002F"," module (channel\u002Fconvert\u002Fgradient\u002Fparse\u002Futils) — ported for ColorArea\u002FColorSlider primitives that were never built",[553,1956,1957,1958,1961,1962,798,1965,798,1968,798,1971,798,1974,798,1977],{},"remove unused ",[471,1959,1960],{},"lynx-ui-common"," ports: ",[471,1963,1964],{},"selector.ts",[471,1966,1967],{},"version.ts",[471,1969,1970],{},"getEventDetail",[471,1972,1973],{},"mainThreadify",[471,1975,1976],{},"popoverUtils",[471,1978,1979],{},"convertToPx",[553,1981,1982,1983,798,1986,798,1989,798,1992,798,1995,798,1998,798,2000,798,2002,798,2005],{},"remove unused reka-ui ports: ",[471,1984,1985],{},"useKbd",[471,1987,1988],{},"useGraceArea",[471,1990,1991],{},"useSelectionBehavior",[471,1993,1994],{},"useFormControl",[471,1996,1997],{},"isValidVNodeElement",[471,1999,1929],{},[471,2001,1932],{},[471,2003,2004],{},"Arrow.vue",[471,2006,2007],{},"countryList",[553,2009,2010,2011,2014,2015,954,2017,954,2019,2021],{},"remove the hand-maintained ",[471,2012,2013],{},"constants.ts"," export registry (",[471,2016,1936],{},[471,2018,1939],{},[471,2020,1942],{}," exports)",[553,2023,2024,2025,2028,2029,2032],{},"remove the 31 ",[471,2026,2027],{},"*.story.vue"," files (no story runner exists; ",[471,2030,2031],{},"story\u002F_*.vue"," test fixtures are untouched)",[553,2034,2035,2036,2039,2040,587],{},"drop the ",[471,2037,2038],{},"vue-component-type-helpers"," runtime dependency (only importer was ",[471,2041,1929],{},[553,2043,2044,2046],{},[471,2045,392],{},": drop the Vue \u003C3.5 fallback branch — every workspace pins Vue 3.5+",[553,2048,2049,2050,587,2055,2057,2059,2060,2063,2064,2066,2067,2070,2071,798,2074,954,2076,2079,2080,2083,2084,2086,2087,798,2089,798,2092,2095,2096],{},"Overlay cleanup ahead of the shared-core refactor. (",[581,2051,2054],{"href":2052,"rel":2053},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fpull\u002F143",[585],"#143",[589,2056],{},[845,2058,1925],{}," (pre-1.0 patch by repo policy): removes the dead ",[471,2061,2062],{},"velocityThreshold"," prop from ",[471,2065,1319],{}," (documented as unused\u002Freserved — release logic uses the coast projection) and the consumerless ",[471,2068,2069],{},"useSheetBehavior()"," reactive wrapper, ",[471,2072,2073],{},"progressFor",[471,2075,527],{},[471,2077,2078],{},"PickSnapOpts"," (never adopted by Sheet; ",[471,2081,2082],{},"pickRelease"," is the one release spec), and their types from ",[471,2085,41],{},". The pure spec helpers (",[471,2088,2082],{},[471,2090,2091],{},"directionAxis",[471,2093,2094],{},"viewportSnapsToPositions",", …) remain.",[550,2097,2098,2120],{},[553,2099,2100,2101,2104,2105,2108,2109,2112,2113,2116,2117,587],{},"kit ",[471,2102,2103],{},"VyModal",": wire the declared-but-dead ",[471,2106,2107],{},"dismissible"," prop — backdrop taps are now blocked when ",[471,2110,2111],{},"false"," and emit ",[471,2114,2115],{},"close:prevent"," (mirrors ",[471,2118,2119],{},"VyPopover",[553,2121,2122,2123,2125,2126,2129,2130,2132,2133],{},"sheet enter\u002Fexit keyframes now take their duration from the ",[471,2124,1016],{}," prop (inline ",[471,2127,2128],{},"animation-duration"," longhand) instead of a hardcoded 280ms, fixing the enter\u002Fsettle desync for consumers like ",[471,2131,1267],{}," that pass ",[471,2134,2135],{},"duration: 300",[553,2137,2138,2139,2142,2143,2146,2147,587],{},"Export ",[471,2140,2141],{},"combineGroupState"," from Presence and use it in ",[471,2144,2145],{},"DialogContent",", deleting the inlined copy that noted \"(not exported)\". (",[581,2148,2151],{"href":2149,"rel":2150},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fpull\u002F144",[585],"#144",[553,2153,2154,2155,738,2157,2160,2161,2163,2164,2167,2168,2170,2171,2174,2175,587],{},"Remove two unused shared exports that had no consumers. ",[471,2156,360],{},[471,2158,2159],{},"\u003CPresence>"," ships its own 1:1-ported state machine and never used it) is dropped from the public ",[471,2162,41],{}," entry; ",[471,2165,2166],{},"useForwardRef"," (superseded by ",[471,2169,355],{},") is dropped from the ",[471,2172,2173],{},"@vyui\u002Fcore\u002Fshared"," entry. (",[581,2176,2179],{"href":2177,"rel":2178},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fpull\u002F140",[585],"#140",[553,2181,2182,2183,2186,2187,2190,2191,2194,2195,2198,2199,587],{},"Require ",[471,2184,2185],{},"vue-lynx@^0.4.2"," and drop the local worklet-loader patch: upstream #190 now follows aliased and package worklet imports, with ",[471,2188,2189],{},"includeWorkletPackages"," for ",[471,2192,2193],{},"node_modules"," consumers. NPM consumers must set ",[471,2196,2197],{},"pluginVueLynx({ includeWorkletPackages: ['@vyui\u002Fcore', '@vyui\u002Fkit'] })"," — documented in the installation guide. (",[581,2200,2203],{"href":2201,"rel":2202},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fpull\u002F142",[585],"#142",{"title":478,"searchDepth":479,"depth":480,"links":2205},[2206],{"id":547,"depth":653,"text":548},2003,"2026-07-19","Button forwards the Lynx tap event through its tap emit (tap: [event: TouchEvent]).",{},"\u002Fchangelog\u002Fcore-0.2.3",{"title":1873,"description":2209},"changelog\u002Fcore-0.2.3","v0.2.3","j-kZOfWH5GIDrpYVge92fzyBrv20leuQinEkt1PNVcc",{"id":2217,"title":2218,"body":2219,"changelogOrder":2312,"date":2313,"description":2314,"extension":484,"meta":2315,"navigation":486,"package":79,"path":2316,"seo":2317,"stem":2318,"version":2319,"__hash__":2320},"changelog\u002Fchangelog\u002Fcore-0.2.4.md","@vyui\u002Fcore v0.2.4",{"type":465,"value":2220,"toc":2309},[2221,2223],[545,2222,548],{"id":547},[550,2224,2225,2274,2284,2290,2299],{},[553,2226,2227,2228,2231,2232,2235,2236,562,2239,2242,2243,2246,2247,2250,2251,2253,2254,2257,2258,562,2261,2264,2265,2268,2269,587],{},"KeyboardAware lift fixes: measure the margin against the LynxView viewport via ",[471,2229,2230],{},"selectRoot()"," instead of the screen (Explorer chrome no longer shortens the lift), flip ",[471,2233,2234],{},"offset"," to its documented extra-clearance meaning (it was pushing fields INTO the keyboard), let a wrapping Trigger's registration win over the input's self-registration, and register kit VyInput\u002FVyTextarea's styled field (via an internal as-child Trigger) so the field's bottom chrome clears too. Also adds a library-level ",[471,2237,2238],{},"useSafeArea",[471,2240,2241],{},"provideSafeAreaInsets"," (elk-style normalization of Sparkling\u002FExplorer global props with OS gating); Sheet panels now pad their docked edges by the container's safe-area insets, and ",[471,2244,2245],{},"VyApp"," provides these insets app-wide with a ",[471,2248,2249],{},"safeArea"," prop to tune them (",[471,2252,2111],{}," opts the whole app out with zeros; a partial ",[471,2255,2256],{},"{ top, bottom }"," overrides specific edges). Input\u002FTextarea (core and kit) gain ",[471,2259,2260],{},"avoidKeyboard",[471,2262,2263],{},"avoidKeyboardSpacing"," passthroughs to Lynx's native ",[471,2266,2267],{},"avoid-keyboard"," root-view shift — a zero-JS alternative for simple forms. (",[581,2270,2273],{"href":2271,"rel":2272},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fpull\u002F148",[585],"#148",[553,2275,2276,2277,2280,2281,587],{},"Sheet handle now uses the mode-aware ",[471,2278,2279],{},"bg-accented"," token instead of a hardcoded translucent black, so the drag pill stays visible in dark mode. (",[581,2282,2273],{"href":2271,"rel":2283},[585],[553,2285,2286,2287,587],{},"Tabs indicator no longer animates growing in from zero width on mount \u002F CSS reload — the transition now arms one tick after the first measurement, so only genuine tab switches slide. (",[581,2288,2273],{"href":2271,"rel":2289},[585],[553,2291,2292,2293,2295,2296,587],{},"Toast viewport now pads its docked edge by the container safe-area insets (via ",[471,2294,2238],{},"), so bottom toasts clear the iPhone home indicator and top toasts clear the notch — the same insets the Sheet panels already honor. (",[581,2297,2273],{"href":2271,"rel":2298},[585],[553,2300,2301,2302,2305,2306,587],{},"Bump vue-lynx to 0.5.1 (widens peer range to ",[471,2303,2304],{},"^0.4.2 || ^0.5.1","), with a local patch making the worklet-loader-mt registration scan comment-aware until upstream #287 ships (",[581,2307,2273],{"href":2271,"rel":2308},[585],{"title":478,"searchDepth":479,"depth":480,"links":2310},[2311],{"id":547,"depth":653,"text":548},2004,"2026-07-20","KeyboardAware lift fixes: measure the margin against the LynxView viewport via selectRoot() instead of the screen (Explorer chrome no longer shortens the lif…",{},"\u002Fchangelog\u002Fcore-0.2.4",{"title":2218,"description":2314},"changelog\u002Fcore-0.2.4","v0.2.4","op4WnklH11IydO2HkHsg-fEL_wFY-yEvExcO7624T38",{"id":2322,"title":2323,"body":2324,"changelogOrder":2550,"date":2551,"description":2552,"extension":484,"meta":2553,"navigation":486,"package":79,"path":2554,"seo":2555,"stem":2556,"version":2557,"__hash__":2558},"changelog\u002Fchangelog\u002Fcore-0.2.5.md","@vyui\u002Fcore v0.2.5",{"type":465,"value":2325,"toc":2547},[2326,2328],[545,2327,548],{"id":547},[550,2329,2330,2506],{},[553,2331,2332,2333,2335,2336,587,2341,2343,2346,2347,2350,2351,2354,2355,2358,2359,683,2362,2365,2366,613,2369,2372,2373,2375,2376,2378,2379,2381,613,2387,798,2389,683,2392,2394,2395,2397,2398,2400,2401,2403,2404,1758,2406,634,2409,2412,2413,2415,2416,2418,2419,613,2430,2433,2434,2437,2438,562,2440,2443,2444,2446,2447,562,2450,562,2453,2456,2457,2460,2461,2464,2465,476,2468,2470,2471,2474,2475,2478,2479,2482,2483,2486,2487,2489,2490,2492,2495,2496,2498,2499,2501,2502,2505],{},"Fix every Sheet-backed surface rendering white in dark mode. ",[471,2334,41],{}," was shipping color it can't ship. (",[581,2337,2340],{"href":2338,"rel":2339},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fpull\u002F154",[585],"#154",[589,2342],{},[471,2344,2345],{},".vyui-sheet__content"," hardcoded ",[471,2348,2349],{},"background-color: #fff",", which beat the consumer's ",[471,2352,2353],{},"bg-default"," on source order and pinned ",[845,2356,2357],{},"drawer, tray, action sheet, select, combobox and popover"," to white in both color modes. ",[471,2360,2361],{},"SheetBackdropImpl",[471,2363,2364],{},"SwipeAction"," set ",[471,2367,2368],{},"backgroundColor",[845,2370,2371],{},"inline",", which no class can outrank at all — so a theme's dim or row color on those elements was dead on arrival. It only read as a dark-mode bug because white-on-white is invisible.",[589,2374],{},"All three now ship no color, matching the \"No defaults — pass ",[471,2377,2368],{}," here\" contract every sibling overlay already documents.",[589,2380],{},[845,2382,2383,2384,2386],{},"Breaking for bare ",[471,2385,41],{}," consumers:",[471,2388,1301],{},[471,2390,2391],{},"SheetBackdrop",[471,2393,2364],{}," no longer paint a background. Supply one (",[471,2396,46],{}," already does on every slot). The ",[471,2399,2364],{}," row in particular must stay opaque or the actions behind it show through.",[589,2402],{},"Also in ",[471,2405,46],{},[471,2407,2408],{},"actionSheet",[471,2410,2411],{},"content"," slot gains ",[471,2414,2353],{},". It was the one Sheet theme silently relying on core's white.",[589,2417],{},"The reason it stayed hidden: ",[845,2420,2421,683,2423,2425,2426,2429],{},[471,2422,1301],{},[471,2424,2391],{}," were dropping the consumer's ",[471,2427,2428],{},"class"," entirely.",[471,2431,2432],{},"OverlayPortal"," renders nothing in place — it registers its slot for ",[471,2435,2436],{},"OverlayRoot"," to paint elsewhere — so there is no root element for ",[471,2439,2428],{},[471,2441,2442],{},"style"," to fall through to, and Vue discards them without a warning. Every kit theme class on a sheet panel (",[471,2445,2353],{},", borders, radius) was being thrown away, and core's hardcoded ",[471,2448,2449],{},"#fff",[471,2451,2452],{},"position: fixed",[471,2454,2455],{},"z-index"," stood in for them. Both now forward ",[471,2458,2459],{},"useAttrs()"," onto the impl with ",[471,2462,2463],{},"inheritAttrs: false",", matching ",[471,2466,2467],{},"DialogContentModal",[589,2469],{},"Guarded by ",[471,2472,2473],{},"components\u002Fheadless-color.test.ts"," (fails if any core component declares a literal background color — ",[471,2476,2477],{},"var()"," is allowed, ",[471,2480,2481],{},"story\u002F"," is exempt) and a case in ",[471,2484,2485],{},"OverlayRoot.test.ts"," pinning the attr-forwarding contract for ",[471,2488,2432],{}," consumers.",[589,2491],{},[471,2493,2494],{},"SheetHandle"," also stops hardcoding the ",[471,2497,2279],{}," class — a ",[471,2500,46],{}," token utility, meaningless in a headless package without kit's Tailwind preset, and redundant since all three kit themes already put it on their ",[471,2503,2504],{},"handle"," slot. The guard now covers that direction too.",[553,2507,2508,2509,2512,2513,2516,2517,587,2522,2524,683,2526,2528,2529,2532,2533,2535,2536,2538,2539,2542,2543,2546],{},"Sheet now paints through the app-root ",[471,2510,2511],{},"\u003COverlayRoot>"," so it escapes ancestor ",[471,2514,2515],{},"overflow: hidden"," on Lynx native (#12). (",[581,2518,2521],{"href":2519,"rel":2520},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fpull\u002F152",[585],"#152",[589,2523],{},[471,2525,1301],{},[471,2527,2391],{}," wrap their impls in a new ",[471,2530,2531],{},"\u003COverlayPortal>"," (exported from ",[471,2534,41],{},"), matching how Dialog, DropdownMenu, Combobox and Toast already portal. Presence is unchanged — the portal mounts inside it, so enter\u002Fleave animations still run to completion before unmount.",[589,2537],{},"Consumers must have an ",[471,2540,2541],{},"\u003COverlayRoot \u002F>"," at the app root; ",[471,2544,2545],{},"\u003CVyApp>"," mounts one by default.",{"title":478,"searchDepth":479,"depth":480,"links":2548},[2549],{"id":547,"depth":653,"text":548},2005,"2026-07-21","Fix every Sheet-backed surface rendering white in dark mode.",{},"\u002Fchangelog\u002Fcore-0.2.5",{"title":2323,"description":2552},"changelog\u002Fcore-0.2.5","v0.2.5","Ve5cGbXteOka9hWoYG9pLV5ZVZiyF8HSR8bTgciTDok",{"id":2560,"title":2561,"body":2562,"changelogOrder":2595,"date":2596,"description":2597,"extension":484,"meta":2598,"navigation":486,"package":79,"path":2599,"seo":2600,"stem":2601,"version":2602,"__hash__":2603},"changelog\u002Fchangelog\u002Fcore-0.2.6.md","@vyui\u002Fcore v0.2.6",{"type":465,"value":2563,"toc":2592},[2564,2566],[545,2565,548],{"id":547},[550,2567,2568,2576,2582],{},[553,2569,2570,2571,587],{},"Animate Collapsible\u002FAccordion height on open\u002Fclose by tweening a measured px height (Tray recipe); kept-mounted content morphs both directions. (",[581,2572,2575],{"href":2573,"rel":2574},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fpull\u002F156",[585],"#156",[553,2577,2578,2579,587],{},"Scale the Sheet settle\u002Fdismiss duration by release velocity so a hard flick settles quicker while a slow release keeps the current feel. (",[581,2580,2575],{"href":2573,"rel":2581},[585],[553,2583,2584,2585,2588,2589,587],{},"Cache the TabsIndicator list rect and re-measure it only on layout\u002Forientation\u002Fdir changes, so a tab switch costs one ",[471,2586,2587],{},"boundingClientRect"," round-trip instead of two. (",[581,2590,2575],{"href":2573,"rel":2591},[585],{"title":478,"searchDepth":479,"depth":480,"links":2593},[2594],{"id":547,"depth":653,"text":548},2006,"2026-07-24","Animate Collapsible\u002FAccordion height on open\u002Fclose by tweening a measured px height (Tray recipe); kept-mounted content morphs both directions.",{},"\u002Fchangelog\u002Fcore-0.2.6",{"title":2561,"description":2597},"changelog\u002Fcore-0.2.6","v0.2.6","42SBgtE-AXGB_i9KDlDpqAlUGjFGnTyFE4IU985u_tM",{"id":2605,"title":2606,"body":2607,"changelogOrder":3210,"date":3211,"description":3212,"extension":484,"meta":3213,"navigation":486,"package":79,"path":3214,"seo":3215,"stem":3216,"version":3217,"__hash__":3218},"changelog\u002Fchangelog\u002Fcore-0.2.7.md","@vyui\u002Fcore v0.2.7",{"type":465,"value":2608,"toc":3207},[2609,2611],[545,2610,548],{"id":547},[550,2612,2613,2692,2786,2834,2925,2970,3084,3155],{},[553,2614,2615,2616,2621,2622,2624,2625,798,2627,798,2629,798,2631,798,2633,798,2635,2637,2638,798,2640,2642,2643,2645,2646,2649,2650,2652,2654,2655,2658,2659,2662,2663,2666,2667,2670,2671,2673,2674],{},"Drive every gesture surface from mouse events on Lynx web, and fix Sortable's (",[581,2617,2620],{"href":2618,"rel":2619},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fpull\u002F161",[585],"#161",")\ndrop.",[589,2623],{},"Lynx web dispatches raw mouse events and never synthesizes touch from them, so\ntouch-only worklets left every drag surface inert in a desktop browser. Each\ngesture core now takes plain coordinates, with thin touch and mouse wrappers\nover it: ",[471,2626,131],{},[471,2628,247],{},[471,2630,267],{},[471,2632,2364],{},[471,2634,239],{},[471,2636,285],{}," swipe,\n",[471,2639,252],{},[471,2641,847],{}," pull-to-refresh, and ",[471,2644,916],{},"'s custom bounce.\nRelease is explicit-buttons-only, a 500ms guard swallows the compatibility\nmousedown a touch browser replays after a tap, and no ",[471,2647,2648],{},"mouseleave"," is bound (it\ndoesn't bubble, so per-element delivery is unreliable on the Lynx dispatch\npath). The pull and the bounce only engage at an edge, so binding mouse on\nthose two doesn't disturb ordinary wheel scrolling.",[589,2651],{},[471,2653,916],{},"'s bounce also moved off ",[471,2656,2657],{},"lynx.querySelector('#id')"," onto\n",[471,2660,2661],{},"main-thread-ref"," handles. That selector exists only on the native main thread —\nweb-core's main-thread ",[471,2664,2665],{},"lynx"," object has no ",[471,2668,2669],{},"querySelector"," — so on web every\ncall threw and took the whole bounce worklet down with it.",[589,2672],{},"Sortable fixes on top of that:",[550,2675,2676,2683,2686],{},[553,2677,2678,2679,2682],{},"The lifted row gets ",[471,2680,2681],{},"zIndex"," from its background-side dragging state instead\nof painting in DOM order, so dragging down no longer slides it under the rows\nit passes — where they swallowed the pointer and the gesture's own\nmove\u002Fup worklets stopped arriving.",[553,2684,2685],{},"Release settles the row into its target slot and re-runs the sibling shift\nfor the final velocity-adjusted target; the transforms are cleared from the\nbackground once the reorder has rendered. Clearing them on the main thread at\nrelease repainted the pre-drag order for the frames the commit took to\nround-trip, which read as the list snapping back.",[553,2687,2688,2691],{},[471,2689,2690],{},"longPressMs"," defaults to 150 (was 250).",[553,2693,591,2694,2697,2698,2701,2702,2704,2705,2707,2708,2710,2711,2713,2714,2717,2718,2720,2721,2723,2724,2726,2727,2730,2731,2734,2735,2738,2739,2741,2742,2745,2746,2748,2749,2752,2753,2755,2756,2759,2760,2763,2764,2767,2768,562,2771,2774,2775,683,2778,2781,2782,2785],{},[471,2695,2696],{},"List.scrollIntoId"," throwing on Lynx web, and restore its bottom\u002Fmiddle (",[581,2699,2620],{"href":2618,"rel":2700},[585],")\nalignment everywhere.",[589,2703],{},"The worklet reached for ",[471,2706,2657],{}," three times. That global\nselector API exists only on the native main thread — web-core's MT ",[471,2709,2665],{},"\nobject has no ",[471,2712,2669],{}," — so the first call raised a ",[471,2715,2716],{},"TypeError"," and took\nthe whole worklet with it, and the list scrolled nowhere.",[589,2719],{},"Two of those lookups were for the ",[471,2722,855],{}," itself, which the component owns, so\nthey now go through a ",[471,2725,2661],{}," instead. That works on both platforms:\nweb-elements' ",[471,2728,2729],{},"\u003Cx-list>"," implements ",[471,2732,2733],{},"scrollToPosition"," as a real DOM method,\nwhich is what ",[471,2736,2737],{},"__InvokeUIMethod"," dispatches to. The third targets an arbitrary\nconsumer-owned child, where the global selector is the only route, so it is\nfeature-checked. When it is absent the scroll keeps its step-1 landing and\nstill honours ",[471,2740,2234],{}," — identical to what ",[471,2743,2744],{},"alignTo: 'none'"," already produces —\nrather than aborting. Web's ",[471,2747,2587],{}," ignores ",[471,2750,2751],{},"relativeTo"," anyway,\nso there is nothing meaningful to measure against there.",[589,2754],{},"Separately, the list's ",[471,2757,2758],{},"layoutchange"," worklet was bound as\n",[471,2761,2762],{},":main-thread:bindlayoutchange",". vue-lynx only recognises the ",[471,2765,2766],{},"main-thread-","\nprefix, so the colon form parsed as an ordinary prop and the handler never\nattached — ",[471,2769,2770],{},"listHeightMT",[471,2772,2773],{},"listWidthMT"," sat at 0 on every platform, which\nsilently broke ",[471,2776,2777],{},"alignTo: 'bottom'",[471,2779,2780],{},"alignTo: 'middle'",". Now bound with the\nhyphen form, with a test that fails on any ",[471,2783,2784],{},"main-thread:"," binding in core.",[553,2787,2788,2789,2791,2792,2794,2795,2797,2798,2800,2801,2804,2805,954,2808,954,2811,954,2814,954,2817,2820,2821,2824,2825,2828,2829,587],{},"Repo-wide over-engineering cleanup. Migrate all 38 ",[471,2790,46],{}," components off the internal ",[471,2793,1824],{}," helper onto the existing ",[471,2796,1828],{}," composable and delete the helper. Remove dead code from ",[471,2799,41],{}," (the ",[471,2802,2803],{},"useWarning"," no-op, and the unused ",[471,2806,2807],{},"areEqual",[471,2809,2810],{},"findValuesBetween",[471,2812,2813],{},"mtsLog",[471,2815,2816],{},"get",[471,2818,2819],{},"noop"," utils) and simplify ",[471,2822,2823],{},"handleAndDispatchCustomEvent",". In ",[471,2826,2827],{},"@vyui\u002Fcli",", drop the fuzzy \"did you mean\" suggestion from the unknown-component error (which already lists every available component) and simplify dependency resolution. No public component API changes. (",[581,2830,2833],{"href":2831,"rel":2832},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fpull\u002F158",[585],"#158",[553,2835,591,2836,2838,2839,2842,2843,2846,2847],{},[471,2837,2159],{}," wedging permanently on web when an animation end\u002Fcancel event (",[581,2840,2620],{"href":2618,"rel":2841},[585],")\nis lost, and restore parity with upstream ",[471,2844,2845],{},"lynx-family\u002Flynx-ui"," on the\nreopen-during-close path.",[550,2848,2849,2862,2869,2896,2913],{},[553,2850,2851,954,2854,2857,2858,2861],{},[471,2852,2853],{},"handleKFStart",[471,2855,2856],{},"handleTransitionStart"," no longer bump the entering\u002Fleaving\nloop ids. Bumping killed the frame watchdog the instant any animation started,\nleaving the machine trusting an end event that web does not reliably deliver —\na child unmounted mid-transition never fires one, and DOM bubbling feeds child\nanimation events into these handlers to begin with. A stuck ",[471,2859,2860],{},"Leaving"," kept the\ninvisible backdrop mounted, swallowing every tap under it.",[553,2863,2864,2865,2868],{},"Both watchdogs now poll through in-flight animations and force-resolve past a\n",[471,2866,2867],{},"MAX_STUCK_MS"," (3s) wall-clock ceiling. Wall-clock rather than frames because\nrAF cadence varies across environments.",[553,2870,2871,2874,2875,2877,2878,2880,2881,2884,2885,2887,2888,2891,2892,2895],{},[471,2872,2873],{},"show"," flipping back to ",[471,2876,1160],{}," during ",[471,2879,2860],{}," now remounts via ",[471,2882,2883],{},"restartShow()","\ninstead of tearing down. Previously a reopen racing ",[471,2886,2860],{}," → ",[471,2889,2890],{},"Left"," stranded\n",[471,2893,2894],{},"show=true"," with nothing mounted and the trigger went permanently dead.",[553,2897,2898,954,2901,2904,2905,2908,2909,2912],{},[471,2899,2900],{},"onOpen",[471,2902,2903],{},"onClose"," are deduped through ",[471,2906,2907],{},"hasNotifiedOpen",", so a\nreopen-during-close that routes back through ",[471,2910,2911],{},"Entered"," doesn't double-fire.",[553,2914,2915,2916,2918,2919,2922,2923,476],{},"A close that races the enter animation no longer cuts straight to ",[471,2917,2860],{},".\nThe exit keyframe starts from the element's underlying (fully-open) value, so\nswapping mid-enter snapped the element open and played the exit from there —\nthe action sheet flashing up before sliding back out. The dismiss is deferred\nuntil the enter resolves, which the existing ",[471,2920,2921],{},"handleAnimationEnd"," safeguard\nand entering watchdog already route to ",[471,2924,2860],{},[553,2926,2927,2928,587,2931,2933,2934,2937,2938,2941,2942,476,2945,2947,2948,2951,2952,2954,2955,2958,2959,2962,2963,2966,2967,2969],{},"Fix the sheet replaying its exit animation after a drag-dismiss. (",[581,2929,2620],{"href":2618,"rel":2930},[585],[589,2932],{},"Releasing a drag past the dismiss threshold drove the close twice: the MT\nrelease transition slid the panel off from where the finger left it, and\nPresence's ",[471,2935,2936],{},".ui-leaving"," keyframe then ran the same close again — starting from\nthe fully-open underlying value, so the panel snapped back up and played the\nexit a second time. The scrim did the same through ",[471,2939,2940],{},"vyui-fade-out",", which keeps\nan explicit ",[471,2943,2944],{},"from { opacity: 1 }",[589,2946],{},"The inline ",[471,2949,2950],{},"animation: 'none'"," the release worklet paints was meant to suppress\nthat keyframe, but a class-driven animation outranks it on the Lynx style path.\n",[471,2953,1319],{}," now carries a ",[471,2956,2957],{},"dragClosing"," flag, set by the release worklet before\nit emits the close, that drops ",[471,2960,2961],{},"ui-leaving"," from the panel and backdrop for that\npath — the MT transition owns the close and ",[471,2964,2965],{},"@transitionend"," still advances\nPresence to ",[471,2968,2890],{},". Non-drag closes keep the keyframe unchanged.",[553,2971,2972,2973,2978,2979,2982,2983,2986,2987,2990,2991,476,2994,3070,3072,3075,3076,3079,3080,3083],{},"Make Slider's main-thread drag the only drag implementation, and fix it so it (",[581,2974,2977],{"href":2975,"rel":2976},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fpull\u002F159",[585],"#159",")\nworks. It previously filled its thumb registry and every ",[471,2980,2981],{},"*MT"," mirror with\nbackground-thread writes to ",[471,2984,2985],{},"MainThreadRef.current",", which vue-lynx silently\nno-ops — the main thread saw an empty handle list and bailed out of\n",[471,2988,2989],{},"_paintActiveThumb"," on every frame, while the commit read a stale array and\nlanded as ",[471,2992,2993],{},"next[0] ?? 0",[550,2995,2996,3008,3025,3034,3037,3044,3058,3061],{},[553,2997,2998,3001,3002,3004,3005,3007],{},[471,2999,3000],{},"SliderRoot","'s min\u002Fmax\u002Fstep\u002Fdisabled\u002Fvalues mirrors hop through\n",[471,3003,1205],{}," setter worklets, the shape ",[471,3006,239],{}," uses.",[553,3009,3010,3013,3014,3017,3018,3021,3022,3024],{},[471,3011,3012],{},"SliderImplMTS"," resolves the thumb and range elements itself from the track via\n",[471,3015,3016],{},"querySelectorAll",", removing the BG→MT registration and its mount-time race.\n",[471,3019,3020],{},"SliderThumbImpl"," no longer touches a ",[471,3023,1193],{}," at all.",[553,3026,3027,3029,3030,3033],{},[471,3028,1117],{}," now fires per frame during the drag, so a value rendered\nnext to the slider tracks the gesture instead of jumping on release.\n",[471,3031,3032],{},"valueCommit"," stays once per gesture, compared against the value the gesture\nstarted from.",[553,3035,3036],{},"The thumb and the filled range are painted from the worklets by writing the\nsame anchor offsets the background style computes, so neither thread's write\ncan double-count the other's.",[553,3038,3039,3040,3043],{},"Values are re-sorted and the active thumb re-tracked every frame, and\n",[471,3041,3042],{},"minStepsBetweenThumbs"," is enforced per frame rather than at commit time — a\nthumb stops at the limit instead of springing back on release.",[553,3045,3046,3047,954,3050,3053,3054,3057],{},"Touch offsets are read from ",[471,3048,3049],{},"touches[0].x",[471,3051,3052],{},".y",", which are already relative to\nthe bound element. Rebuilding them from ",[471,3055,3056],{},"pageY - layoutchange.top"," mixed\nviewport and page coordinates and drifted by the scroll offset.",[553,3059,3060],{},"Fixes the thumb sitting half its own width off-centre on right-anchored\n(inverted \u002F RTL) sliders: the centring transform flips with the anchoring edge\non the vertical axis but did not on the horizontal one.",[553,3062,1465,3063,3065,3066,3069],{},[471,3064,484],{}," thumb rendering 0×0 — ",[471,3067,3068],{},"size-4.5"," is not a Tailwind v3 utility,\nso it compiled to no CSS at all.",[589,3071],{},[845,3073,3074],{},"Removed:"," the background drag implementation (",[471,3077,3078],{},"SliderImpl","), the\n",[471,3081,3082],{},"mainThreadDrag"," prop, and keyboard stepping. The keyboard handlers never fired\non Lynx native, which has no key events to bind.",[553,3085,3086,3087,587,3090,3092,3093,3095,3096,3099,3100,3102,3103,3106,3107,3110,3111,3114,3115,3118,3119,3121,3122,3124,3125,3127,3128,3131,3132,3135,3136,954,3139,3142,3143,3145,3148,3149,3151,3152,3154],{},"Fix the slider never moving on Lynx web. (",[581,3088,2620],{"href":2618,"rel":3089},[585],[589,3091],{},"Two independent bails, both before the gesture emitted anything, which is why\nthe value sat frozen at whatever it mounted with while native felt fine.",[589,3094],{},"The one that actually stranded it: ",[471,3097,3098],{},"_dragStart"," aborted when it could not\nresolve the thumb elements to paint. That lookup goes through the main-thread\n",[471,3101,3016],{}," wrapper, which calls a ",[471,3104,3105],{},"__QuerySelectorAll"," PAPI that Lynx\nweb does not expose to the main-thread realm — ",[471,3108,3109],{},"invoke"," resolves there, this\nthrows ",[471,3112,3113],{},"ReferenceError",", and a ",[471,3116,3117],{},"typeof"," check on the wrapper method cannot see\nit coming. The query is now guarded, and no longer gates the drag: those\nelements only drive the main-thread paint, which is a latency optimisation over\nthe background's own render, so losing them costs smoothness rather than\ncorrectness. The background still receives every value and renders the thumb\nfrom its own style.",[589,3120],{},"The second: the track's extent was the last piece of geometry sourced from a\nbackground ",[471,3123,1012],{}," pushed across with ",[471,3126,1205],{},". ",[471,3129,3130],{},"_beginAt","\nalready fetches ",[471,3133,3134],{},"invoke('boundingClientRect')"," once per gesture for the origin,\nand that response carries ",[471,3137,3138],{},"width",[471,3140,3141],{},"height"," too, so the extent comes from it as\nwell. One measurement, one frame, no thread hop — and re-read per gesture,\nwhich also fixes a track that resized while its tab was hidden.",[589,3144],{},[471,3146,3147],{},"draggingMT"," is wired up while here: ",[471,3150,3012],{}," was setting a local ref of\nits own, so the root's gate against echoing a live ",[471,3153,1117],{}," back\ninto the main thread's values was never armed.",[553,3156,3157,3158,587,3161,3163,3164,954,3166,3168,3169,3172,3173,3176,3177,954,3180,3183,3184,3187,3188,3190,3191,954,3194,3197,3198,3200,3201,3203,3204,3206],{},"Map Slider's touch and mouse gestures through one pointer coordinate frame. (",[581,3159,2620],{"href":2618,"rel":3160},[585],[589,3162],{},"The touch path read ",[471,3165,3049],{},[471,3167,3052],{},", which Lynx reports element-relative on\nnative but does not provide on web at all — ",[471,3170,3171],{},"createCrossThreadEvent"," builds web\ntouches from raw DOM ",[471,3174,3175],{},"Touch"," objects, which carry no ",[471,3178,3179],{},"x",[471,3181,3182],{},"y",", so every offset\ncame through as ",[471,3185,3186],{},"NaN"," and the thumb never moved on a touchscreen browser.",[589,3189],{},"Both paths now read ",[471,3192,3193],{},"clientX",[471,3195,3196],{},"clientY",", the only pointer field Lynx reports on\nnative and web alike, and share a single ",[471,3199,3130],{}," that captures the track's\norigin from ",[471,3202,3134],{}," once per gesture and subtracts it.\nThe origin still never comes from ",[471,3205,2758],{},", which reports page-relative\ncoordinates that drift from the pointer's viewport frame by the scroll offset.",{"title":478,"searchDepth":479,"depth":480,"links":3208},[3209],{"id":547,"depth":653,"text":548},2007,"2026-07-25","Drive every gesture surface from mouse events on Lynx web, and fix Sortable's",{},"\u002Fchangelog\u002Fcore-0.2.7",{"title":2606,"description":3212},"changelog\u002Fcore-0.2.7","v0.2.7","9PGsInH8z5Y96J1nPNqol97KVutOCxfv0irDK5TqHw4",{"id":3220,"title":3221,"body":3222,"changelogOrder":11,"date":654,"description":3347,"extension":484,"meta":3348,"navigation":486,"package":63,"path":3349,"seo":3350,"stem":3351,"version":511,"__hash__":3352},"changelog\u002Fchangelog\u002Fkit-0.0.2.md","NumberField, Island DX & polish",{"type":465,"value":3223,"toc":3345},[3224,3230,3250,3300,3305],[468,3225,3226,3229],{},[471,3227,3228],{},"@vyui\u002Fkit@0.0.2"," adds a component, sharpens an existing one, and fixes a handful of native-Lynx rough edges.",[468,3231,3232,3235,3236,558,3238,562,3240,562,3242,562,3244,572,3246,576,3248,476],{},[845,3233,3234],{},"NumberField"," — a new headless ",[471,3237,41],{},[471,3239,561],{},[471,3241,565],{},[471,3243,568],{},[471,3245,571],{},[471,3247,575],{},[471,3249,46],{},[468,3251,3252,3254,3255,3258,3259,562,3262,562,3265,3267,3268,3271,3272,562,3275,3278,3279,3281,3282,3284,3285,3288,3289,3291,3292,683,3294,641,3297,3299],{},[845,3253,150],{}," gets a clearer API and better defaults. A new ",[471,3256,3257],{},"layer"," prop (",[471,3260,3261],{},"overlay",[471,3263,3264],{},"base",[471,3266,2371],{},") splits stacking from placement: ",[471,3269,3270],{},"position"," now only picks the viewport edge (",[471,3273,3274],{},"top",[471,3276,3277],{},"bottom","), while ",[471,3280,3257],{}," decides whether the island floats over content, sits on a low layer beneath modals and drawers, or drops into normal flow for a parent to place. Floating is applied via an inline ",[471,3283,2442],{},", so a lone ",[471,3286,3287],{},"\u003CVyIsland>"," hovers with no wrapper on Lynx. Out of the box ",[471,3290,150],{}," defaults to ",[471,3293,3261],{},[471,3295,3296],{},"IslandGroup",[471,3298,3277],{},", so both float sensibly with zero config.",[468,3301,3302],{},[845,3303,3304],{},"Fixes & docs",[550,3306,3307,3315,3324,3332],{},[553,3308,3309,3311,3312,3314],{},[471,3310,145],{}," now reflects programmatic value changes on native Lynx — controlled updates that don't come from typing are pushed through the imperative ",[471,3313,597],{}," path, so NumberField's increment\u002Fdecrement work on iOS and Android, not just web.",[553,3316,3317,3319,3320,613,3322,1056],{},[471,3318,91],{}," falls back to initials\u002Ficon when its image fails to load, wiring the Lynx ",[471,3321,612],{},[471,3323,616],{},[553,3325,3326,3328,3329,3331],{},[471,3327,623],{}," is documented as the autocomplete pattern — ",[471,3330,627],{}," filtering covers the use case, so there's no separate Autocomplete component.",[553,3333,3334,3335,3337,3338,641,3340,3342,3343,649],{},"The ",[471,3336,41],{}," peer-dependency range widens from ",[471,3339,640],{},[471,3341,644],{},", so kit tracks ",[471,3344,648],{},{"title":478,"searchDepth":479,"depth":480,"links":3346},[],"A new NumberField primitive, a cleaner Island API with sensible floating defaults, and a round of native-Lynx fixes.",{},"\u002Fchangelog\u002Fkit-0.0.2",{"title":3221,"description":3347},"changelog\u002Fkit-0.0.2","4NBYYz4fPAzYYf4dNih7Th2pMUbSqL-4t0euelogF7c",{"id":3354,"title":3355,"body":3356,"changelogOrder":11,"date":826,"description":3632,"extension":484,"meta":3633,"navigation":486,"package":63,"path":3634,"seo":3635,"stem":3636,"version":537,"__hash__":3637},"changelog\u002Fchangelog\u002Fkit-0.0.3.md","@vyui\u002Fkit v0.0.3",{"type":465,"value":3357,"toc":3629},[3358,3360],[545,3359,548],{"id":547},[550,3361,3362,3399,3495,3532,3601],{},[553,3363,713,3364,716,3366,562,3368,562,3370,726,3372,729,3374,732,3376,735,3378,738,3380,742,3382,745,3384,749,3386,587,3389,755,3391,634,3393,761,3395,765,3397,769],{},[471,3365,41],{},[471,3367,719],{},[471,3369,722],{},[471,3371,725],{},[471,3373,719],{},[471,3375,722],{},[471,3377,612],{},[471,3379,616],{},[471,3381,741],{},[471,3383,725],{},[471,3385,748],{},[581,3387,699],{"href":697,"rel":3388},[585],[589,3390],{},[471,3392,46],{},[471,3394,760],{},[471,3396,764],{},[471,3398,768],{},[553,3400,3401,3402,587,3407,3483,3485,3486,3488,3489,3491,3492,1086],{},"Configurable semantic colors (nuxt\u002Fui-style), defined once and extensible. (",[581,3403,3406],{"href":3404,"rel":3405},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fpull\u002F48",[585],"#48",[550,3408,3409,3424,3438,3448,3466],{},[553,3410,3411,3412,3415,3416,3419,3420,3423],{},"Single source of truth ",[471,3413,3414],{},"theme\u002Fcolor-constants.js"," (shared by themes + Tailwind preset); ",[471,3417,3418],{},"neutral"," split out of the configurable ",[471,3421,3422],{},"COLORS"," list and appended automatically (nuxt\u002Fui parity).",[553,3425,3426,3427,3430,3431,3433,3434,3437],{},"Theme files are now builder functions ",[471,3428,3429],{},"(colors) => themeObject","; ",[471,3432,1828],{}," invokes them with the resolved list so ",[471,3435,3436],{},"appConfig.ui.colors"," configures the set at runtime.",[553,3439,3440,3443,3444,3447],{},[471,3441,3442],{},"@vyui\u002Fkit\u002Ftailwind"," adds a ",[471,3445,3446],{},"createVyuiPreset({ colors })"," factory; the default export is unchanged.",[553,3449,3450,3451,3454,3455,3458,3459,3461,3462,3465],{},"True type parity via the augmentable ",[471,3452,3453],{},"VyuiColorRegistry"," interface — ",[471,3456,3457],{},"declare module '@vyui\u002Fkit' { interface VyuiColorRegistry { tertiary: true } }"," makes custom colors autocomplete + typo-check on every component ",[471,3460,790],{}," prop, no build plugin needed. ",[471,3463,3464],{},"scripts\u002Fgen-colors.mjs"," generates the registry augmentation + CSS-var block.",[553,3467,3468,3469,3472,3473,3475,3476,3479,3480,3482],{},"Fixes a latent ",[471,3470,3471],{},"ThemeTV"," widening that typed ",[471,3474,790],{}," (and other variants) as ",[471,3477,3478],{},"PropertyKey"," on ",[471,3481,1828],{},"-based components.",[589,3484],{},"Breaking: theme default exports changed from objects to builder functions; ",[471,3487,3422],{}," no longer includes ",[471,3490,3418],{}," (use ",[471,3493,3494],{},"ALL_COLORS",[553,3496,772,3497,587,3500,3502,782,3504,3524,3526,782,3528],{},[581,3498,777],{"href":775,"rel":3499},[585],[589,3501],{},[471,3503,41],{},[550,3505,3506,3510,3518],{},[553,3507,787,3508,791],{},[471,3509,790],{},[553,3511,794,3512,798,3514,683,3516,803],{},[471,3513,797],{},[471,3515,131],{},[471,3517,523],{},[553,3519,806,3520,810,3522,813],{},[471,3521,809],{},[471,3523,612],{},[589,3525],{},[471,3527,46],{},[550,3529,3530],{},[553,3531,822],{},[553,3533,3534,3535,3538,3539,3541,3542,587,3547,3549,3550,3553,3554,798,3557,798,3560,798,3563,798,3566,798,3569,798,3572,798,3575,798,3578,798,3581,798,3584,798,3587,798,3590,798,3593,3596,3597,3600],{},"Fix stranded foreground colors on Lynx (",[471,3536,3537],{},"enableCSSInheritance: false","). Color set on a wrapping ",[471,3540,705],{}," slot never reached the nested text\u002Ficon, so it rendered in the default color — invisible on dark\u002Fcolored surfaces (e.g. a neutral-solid button or solid card). (",[581,3543,3546],{"href":3544,"rel":3545},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fpull\u002F52",[585],"#52",[589,3548],{},"Foreground ",[471,3551,3552],{},"text-*"," now lands on the text-bearing slots (label \u002F title \u002F description \u002F icon \u002F input value) across ",[471,3555,3556],{},"input",[471,3558,3559],{},"textarea",[471,3561,3562],{},"numberField",[471,3564,3565],{},"select",[471,3567,3568],{},"combobox",[471,3570,3571],{},"toggle",[471,3573,3574],{},"toggleGroup",[471,3576,3577],{},"chip",[471,3579,3580],{},"islandButton",[471,3582,3583],{},"card",[471,3585,3586],{},"accordion",[471,3588,3589],{},"dropdownMenu",[471,3591,3592],{},"tabs",[471,3594,3595],{},"stepper",". State-driven colors on child elements use the ",[471,3598,3599],{},"group-data-[state=…]"," form, and the Tailwind preset safelist is widened to cover those variants so they aren't purged.",[553,3602,3603,3604,798,3611,798,3616,3623,3624],{},"Updated dependencies [",[581,3605,3608],{"href":3606,"rel":3607},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fcommit\u002F1b0d3bc1f6932e668a1830ea031dc046888c0711",[585],[471,3609,3610],{},"1b0d3bc",[581,3612,3614],{"href":3606,"rel":3613},[585],[471,3615,3610],{},[581,3617,3620],{"href":3618,"rel":3619},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fcommit\u002F9a0241cdad8a594e49f9e8965c10fdc70b3bee0c",[585],[471,3621,3622],{},"9a0241c","]:",[550,3625,3626],{},[553,3627,3628],{},"@vyui\u002Fcore@0.0.5",{"title":478,"searchDepth":479,"depth":480,"links":3630},[3631],{"id":547,"depth":653,"text":548},"Add Avatar — Lynx-native @vyui\u002Fcore primitives (AvatarRoot \u002F AvatarImage \u002F AvatarFallback).",{},"\u002Fchangelog\u002Fkit-0.0.3",{"title":3355,"description":3632},"changelog\u002Fkit-0.0.3","3er91xlxQ-x36d2y7j1hciegYUdemK3QxlQkkCpjrr0",{"id":3639,"title":3640,"body":3641,"changelogOrder":11,"date":1031,"description":3738,"extension":484,"meta":3739,"navigation":486,"package":63,"path":3740,"seo":3741,"stem":3742,"version":660,"__hash__":3743},"changelog\u002Fchangelog\u002Fkit-0.0.4.md","Stacked toasts & FeedList gestures",{"type":465,"value":3642,"toc":3736},[3643,3649,3654,3696,3703],[468,3644,3645,3648],{},[471,3646,3647],{},"@vyui\u002Fkit@0.0.4"," brings the new core gesture surface to the styled components.",[468,3650,3651,3653],{},[845,3652,285],{}," gains Sonner-style behaviour, all off by default:",[550,3655,3656,3675,3688],{},[553,3657,3658,3661,3662,738,3665,3667,3668,3670,3671,3674],{},[471,3659,3660],{},"stacked"," — collapses toasts into an overlapping pile (front toast fully visible, the rest peeking scaled-down behind it) and fans them out when expanded; tap to toggle. Pair ",[471,3663,3664],{},"stackFrom",[471,3666,3274],{}," | ",[471,3669,3277],{},") with the ",[471,3672,3673],{},"ToastViewport"," position.",[553,3676,3677,3680,3681,3684,3685,3687],{},[471,3678,3679],{},"swipe"," (+ ",[471,3682,3683],{},"swipeDirection",") — fling a toast sideways to dismiss. The card rides an inner ",[471,3686,1023],{}," layer so the swipe transform never collides with the stacking transform.",[553,3689,3690,3692,3693,1086],{},[471,3691,1019],{}," — a thin countdown bar that drains with the auto-dismiss timer (pauses while expanded, hidden when ",[471,3694,3695],{},"duration: 0",[468,3697,3698,3699,3702],{},"A plain ",[471,3700,3701],{},"VyToast"," still renders as a single gapped-column card.",[468,3704,3705,3707,3708,798,3710,798,3712,798,3714,3716,3717,562,3719,3721,3722,877,3724,3726,3727,3729,3730,3732,3733,3735],{},[845,3706,847],{}," wrapper now forwards the full pull-to-refresh surface to core — ",[471,3709,859],{},[471,3711,863],{},[471,3713,866],{},[471,3715,883],{},", the ",[471,3718,869],{},[471,3720,872],{}," emits, and the ",[471,3723,876],{},[471,3725,880],{},") — plus the new ",[471,3728,887],{}," prop and ",[471,3731,895],{}," emit. The ",[471,3734,903],{}," slot is aligned with core's new no-arg signature (the footer renders only while loading).",{"title":478,"searchDepth":479,"depth":480,"links":3737},[],"Sonner-style stacked, swipeable toasts with a countdown bar, and a FeedList wrapper that forwards the new pull-to-refresh, bounce and snap surface.",{},"\u002Fchangelog\u002Fkit-0.0.4",{"title":3640,"description":3738},"changelog\u002Fkit-0.0.4","Q-ltKOMEkPqFP6WeafeDiWyyCV9_va7-AhE7idw0jxE",{"id":3745,"title":3746,"body":3747,"changelogOrder":1244,"date":1245,"description":1246,"extension":484,"meta":4094,"navigation":486,"package":63,"path":4095,"seo":4096,"stem":4097,"version":1251,"__hash__":4098},"changelog\u002Fchangelog\u002Fkit-0.1.0.md","@vyui\u002Fkit v0.1.0",{"type":465,"value":3748,"toc":4090},[3749,3751,3799,3801],[545,3750,1047],{"id":1046},[550,3752,3753],{},[553,3754,1052,3755,1056,3757],{},[471,3756,1055],{},[550,3758,3759,3777,3785],{},[553,3760,3761,683,3763,1065,3765,954,3767,1072,3769,900,3771,1078,3773,1082,3775,1086],{},[471,3762,145],{},[471,3764,281],{},[471,3766,1068],{},[471,3768,1071],{},[471,3770,1055],{},[471,3772,1077],{},[471,3774,1081],{},[471,3776,1085],{},[553,3778,1089,3779,613,3781,1096,3783,476],{},[471,3780,1092],{},[471,3782,1095],{},[471,3784,1099],{},[553,3786,3787,1104,3789,954,3791,954,3793,1114,3795,1118,3797,476],{},[471,3788,1071],{},[471,3790,1107],{},[471,3792,1110],{},[471,3794,1113],{},[471,3796,1117],{},[471,3798,1068],{},[545,3800,548],{"id":547},[550,3802,3803,3806,3837,3898,3965,3975,3977,4049,4060,4067,4071,4076,4080],{},[553,3804,3805],{},"300e34f: Add small horizontal (landscape) mode support — the work that gets the kit-demo running on mobile in landscape. Compact, viewport-safe layouts for overlays, sheets, menus, tabs, steppers, islands, cards, alerts, and toasts. Select and Combobox sheet structure is now fully themeable for responsive overrides.",[553,3807,3808,3809,683,3812,3815,3816],{},"0610d70: Input: forward ",[471,3810,3811],{},"@focus",[471,3813,3814],{},"@blur"," events.",[550,3817,3818],{},[553,3819,3820,3821,3823,3824,954,3826,3828,3829,3831,3832,683,3834,3836],{},"The core ",[471,3822,145],{}," emits ",[471,3825,1110],{},[471,3827,1113],{}," (with the current value), but the ",[471,3830,1068],{}," wrapper only re-emitted ",[471,3833,1117],{},[471,3835,1107],{},", so consumers couldn't react to focus changes (e.g. to drive a keyboard-aware lift). It now forwards both.",[553,3838,3839,3840],{},"0610d70: IslandButton: bake the icon color so the theme's foreground actually applies.",[550,3841,3842,3868],{},[553,3843,3844,3847,3848,3851,3852,3855,3856,3859,3860,3863,3864,3867],{},[471,3845,3846],{},"IslandButton"," rendered its glyph through Lynx's ",[471,3849,3850],{},"\u003Csvg>",", which rasterizes the XML and can't inherit ",[471,3853,3854],{},"currentColor"," — so the ",[471,3857,3858],{},"text-slate-*"," utility on the ",[471,3861,3862],{},"leadingIcon"," slot (and the darker ",[471,3865,3866],{},"text-slate-900"," active shade) never reached the icon, leaving it stuck on its default fill (invisible on dark\u002Factive pills).",[553,3869,3870,3871,3873,3874,3877,3878,3881,3882,798,3884,798,3886,983,3888,3890,3891,3894,3895,3897],{},"It now resolves the foreground utility off the merged ",[471,3872,3862],{}," class — honoring the active state and any consumer ",[471,3875,3876],{},"ui.leadingIcon"," override — and passes it to ",[471,3879,3880],{},"\u003CVyIcon :color>",", matching the pattern already used by ",[471,3883,101],{},[471,3885,145],{},[471,3887,71],{},[471,3889,1737],{},". Non-palette colors (e.g. arbitrary ",[471,3892,3893],{},"text-[#abc]",") fall back to the icon's ",[471,3896,3854],{}," default.",[553,3899,3900,3901],{},"491db6a: Default input chrome to neutral: form controls no longer paint a primary border or icon by default.",[550,3902,3903,3931,3951],{},[553,3904,3905,3906,798,3908,798,3910,798,3912,798,3914,683,3916,3919,3920,3923,3924,3926,3927,3930],{},"Resting border on ",[471,3907,145],{},[471,3909,281],{},[471,3911,229],{},[471,3913,1737],{},[471,3915,3234],{},[471,3917,3918],{},"PinInput"," is now neutral (",[471,3921,3922],{},"border-neutral-200",") regardless of ",[471,3925,790],{}," — matching the no-focus-state reality on Lynx. The colored border stays available as opt-in via the ",[471,3928,3929],{},"highlight"," prop.",[553,3932,3933,3934,3936,3937,3939,3940,3943,3944,562,3947,3950],{},"Leading\u002Ftrailing icons (and ",[471,3935,3234],{}," steppers) now default to neutral (dimmed) instead of the ",[471,3938,790],{}," palette; override per-icon with your own ",[471,3941,3942],{},":color"," via the ",[471,3945,3946],{},"leading",[471,3948,3949],{},"trailing"," slots.",[553,3952,3953,3956,3957,3960,3961,3964],{},[471,3954,3955],{},"RadioGroup",": space the control from its label with ",[471,3958,3959],{},"gap-2"," on the item instead of ",[471,3962,3963],{},"ms-2"," on the wrapper — Lynx ignores logical inline margins, which collapsed the dot and text together.",[553,3966,1164,3967,1168,3969,1172,3971,641,3973,476],{},[471,3968,1167],{},[471,3970,1171],{},[471,3972,1167],{},[471,3974,1171],{},[553,3976,1239],{},[553,3978,3979,3980,3982,3983,3985,3986,4034,4036,4037,4040,4041,4044,4045,4048],{},"14e0722: Add ",[471,3981,2827],{},", a shadcn-style CLI that copies ",[471,3984,46],{}," components (and their dependencies) into a project from a style-namespaced registry, rewriting imports to the consumer's aliases.",[550,3987,3988,4000,4003,4021,4024,4031],{},[553,3989,3990,562,3993,562,3996,3999],{},[471,3991,3992],{},"init",[471,3994,3995],{},"add",[471,3997,3998],{},"styles"," commands; tsconfig\u002Fjsconfig alias + package-manager detection.",[553,4001,4002],{},"Shadcn-style project preflight and automatic, idempotent app-entry\u002FTailwind wiring.",[553,4004,4005,798,4008,798,4011,4014,4015,983,4017,4020],{},[471,4006,4007],{},"list",[471,4009,4010],{},"view",[471,4012,4013],{},"info",", interactive ",[471,4016,3995],{},[471,4018,4019],{},"--dry-run"," discovery\u002Fpreview workflows.",[553,4022,4023],{},"Safe upgrades: explicit components may be overwritten while shared files and transitive dependencies remain user-owned.",[553,4025,4026,4027,4030],{},"Registry targets are contained to the project root (rejects ",[471,4028,4029],{},"..\u002F"," \u002F absolute \u002F null-byte paths).",[553,4032,4033],{},"Cyclic registry dependency graphs resolve instead of deadlocking.",[589,4035],{},"kit: drive the switch thumb with flex justification instead of ",[471,4038,4039],{},"translate-x-*"," (Lynx drops ",[471,4042,4043],{},"transform"," painting), and reset the native ",[471,4046,4047],{},"\u003Ctextarea>"," user-agent border.",[553,4050,4051,4052,4055,4056,4059],{},"300e34f: Make vertical tabs reserve a navigation rail and let their content fill the remaining width. Vertical triggers no longer inherit the horizontal ",[471,4053,4054],{},"pill"," variant's ",[471,4057,4058],{},"flex-1"," stretch — they keep their natural height and left-align their icon\u002Flabel so the rail reads as a sidebar list.",[553,4061,4062,4063],{},"Updated dependencies ",[4064,4065,4066],"span",{},"0610d70",[553,4068,4062,4069],{},[4064,4070,4066],{},[553,4072,4062,4073],{},[4064,4074,4075],{},"baf0692",[553,4077,4062,4078],{},[4064,4079,4066],{},[553,4081,4062,4082,4085],{},[4064,4083,4084],{},"300e34f",[550,4086,4087],{},[553,4088,4089],{},"@vyui\u002Fcore@0.1.0",{"title":478,"searchDepth":479,"depth":480,"links":4091},[4092,4093],{"id":1046,"depth":653,"text":1047},{"id":547,"depth":653,"text":548},{},"\u002Fchangelog\u002Fkit-0.1.0",{"title":3746,"description":1246},"changelog\u002Fkit-0.1.0","bxuy3lyu8hsJVghc8Av0jWjrpL4zS0_i-J5JVnGnSNY",{"id":4100,"title":4101,"body":4102,"changelogOrder":1343,"date":1344,"description":1345,"extension":484,"meta":4170,"navigation":486,"package":63,"path":4171,"seo":4172,"stem":4173,"version":1350,"__hash__":4174},"changelog\u002Fchangelog\u002Fkit-0.1.1.md","@vyui\u002Fkit v0.1.1",{"type":465,"value":4103,"toc":4167},[4104,4106],[545,4105,548],{"id":547},[550,4107,4108,4138,4152,4157],{},[553,4109,1264,4110,1268,4112,1271,4114,1275,4116,562,4118,1282,4120,1286,4122,1290,4124,1294,4126,4128,613,4130,1302,4132,1306,4134,1310,4136,1313],{},[471,4111,1267],{},[471,4113,239],{},[471,4115,1274],{},[471,4117,1278],{},[471,4119,1281],{},[471,4121,1285],{},[471,4123,1289],{},[471,4125,1293],{},[589,4127],{},[471,4129,41],{},[471,4131,1301],{},[471,4133,1305],{},[471,4135,1309],{},[471,4137,1267],{},[553,4139,1316,4140,1320,4142,1324,4144,1328,4146,1331,4148,1335,4150,1339],{},[471,4141,1319],{},[471,4143,1323],{},[471,4145,1327],{},[589,4147],{},[471,4149,1334],{},[471,4151,1338],{},[553,4153,4062,4154],{},[4064,4155,4156],{},"bb4d208",[553,4158,4062,4159,4162],{},[4064,4160,4161],{},"31c2202",[550,4163,4164],{},[553,4165,4166],{},"@vyui\u002Fcore@0.1.1",{"title":478,"searchDepth":479,"depth":480,"links":4168},[4169],{"id":547,"depth":653,"text":548},{},"\u002Fchangelog\u002Fkit-0.1.1",{"title":4101,"description":1345},"changelog\u002Fkit-0.1.1","ZaOvogLY63Q564OJ8OqRIazLf91b_jTtZQNiZLBo4mI",{"id":4176,"title":4177,"body":4178,"changelogOrder":1367,"date":1368,"description":1369,"extension":484,"meta":4199,"navigation":486,"package":63,"path":4200,"seo":4201,"stem":4202,"version":1374,"__hash__":4203},"changelog\u002Fchangelog\u002Fkit-0.1.2.md","@vyui\u002Fkit v0.1.2",{"type":465,"value":4179,"toc":4196},[4180,4182],[545,4181,548],{"id":547},[550,4183,4184,4186],{},[553,4185,1363],{},[553,4187,4062,4188,4191],{},[4064,4189,4190],{},"cbbbcbf",[550,4192,4193],{},[553,4194,4195],{},"@vyui\u002Fcore@0.1.2",{"title":478,"searchDepth":479,"depth":480,"links":4197},[4198],{"id":547,"depth":653,"text":548},{},"\u002Fchangelog\u002Fkit-0.1.2",{"title":4177,"description":1369},"changelog\u002Fkit-0.1.2","hwVs_ANbq3dHPgzVvD-UTEPOy31mxdSmoJsBNWFGkBI",{"id":4205,"title":4206,"body":4207,"changelogOrder":1523,"date":1368,"description":4275,"extension":484,"meta":4276,"navigation":486,"package":63,"path":4277,"seo":4278,"stem":4279,"version":1530,"__hash__":4280},"changelog\u002Fchangelog\u002Fkit-0.2.0.md","@vyui\u002Fkit v0.2.0",{"type":465,"value":4208,"toc":4272},[4209,4211],[545,4210,1047],{"id":1046},[550,4212,4213],{},[553,4214,4215,4216,4219,4220,4223,4224,954,4227,4230,4231,4234,4235],{},"5109043: Add ",[471,4217,4218],{},"defineVyuiConfig"," (new ",[471,4221,4222],{},"@vyui\u002Fkit\u002Fconfig"," entry) so a project's theme is authored once and fed to both the Tailwind preset (build) and ",[471,4225,4226],{},"provideVyUI",[471,4228,4229],{},"app.use(VyUI)"," (runtime), removing the hand-synced ",[471,4232,4233],{},"colors"," duplication between the two planes.",[550,4236,4237,4254,4263],{},[553,4238,4239,4242,4243,4245,4246,4249,4250,4253],{},[471,4240,4241],{},"createVyuiPreset"," now accepts a ",[471,4244,4218],{}," result (",[471,4247,4248],{},"{ ui: { colors } }",") alongside the flat ",[471,4251,4252],{},"{ colors, neutral, shades }"," form",[553,4255,4256,4258,4259,4262],{},[471,4257,4241],{}," dev-warns when a semantic color can't be backed by a ",[471,4260,4261],{},"--ui-color-*"," var (no more silent \"class resolves to nothing\")",[553,4264,4265,4267,4268,4271],{},[471,4266,4222],{}," is a light, jiti-safe entry — importing it in ",[471,4269,4270],{},"tailwind.config.ts"," never pulls component code into the build path",{"title":478,"searchDepth":479,"depth":480,"links":4273},[4274],{"id":1046,"depth":653,"text":1047},"5109043: Add defineVyuiConfig (new @vyui\u002Fkit\u002Fconfig entry) so a project's theme is authored once and fed to both the Tailwind preset (build) and provideVyUI\u002F…",{},"\u002Fchangelog\u002Fkit-0.2.0",{"title":4206,"description":4275},"changelog\u002Fkit-0.2.0","omoUWZWtCbAuJ5OaT2QgOVsVyj7MN-nrtiEyRfkGlhQ",{"id":4282,"title":4283,"body":4284,"changelogOrder":4433,"date":1524,"description":1525,"extension":484,"meta":4434,"navigation":486,"package":63,"path":4435,"seo":4436,"stem":4437,"version":4438,"__hash__":4439},"changelog\u002Fchangelog\u002Fkit-0.3.0.md","@vyui\u002Fkit v0.3.0",{"type":465,"value":4285,"toc":4429},[4286,4288,4368,4370],[545,4287,1047],{"id":1046},[550,4289,4290,4330],{},[553,4291,1387,4292,1390,4294,798,4296,1397,4298,1401,4300,1405,4302,1410,4304,1413,4306,1416,4308,1419,4310,1423,4312,1426,4314,1430,4316,1434,4318,1437,4320,634,4322,1443,4324,1446,4326,1450,4328,1453],{},[471,4293,46],{},[471,4295,1393],{},[471,4297,1396],{},[471,4299,1400],{},[471,4301,1404],{},[1407,4303,1409],{},[471,4305,1393],{},[589,4307],{},[471,4309,41],{},[471,4311,1422],{},[471,4313,41],{},[471,4315,1429],{},[471,4317,1433],{},[589,4319],{},[471,4321,46],{},[471,4323,1442],{},[471,4325,41],{},[471,4327,1449],{},[471,4329,1404],{},[553,4331,1456,4332,1460,4334],{},[471,4333,1459],{},[550,4335,4336,4342,4358,4362],{},[553,4337,1465,4338,1469,4340,1473],{},[471,4339,1468],{},[471,4341,1472],{},[553,4343,1476,4344,1480,4346,1484,4348,1488,4350,1492,4352,1496,4354,634,4356,1501],{},[471,4345,1479],{},[471,4347,1483],{},[471,4349,1487],{},[471,4351,1491],{},[471,4353,1495],{},[471,4355,46],{},[471,4357,1404],{},[553,4359,1504,4360,1508],{},[471,4361,1507],{},[553,4363,1511,4364,1515,4366,1519],{},[471,4365,1514],{},[471,4367,1518],{},[545,4369,548],{"id":547},[550,4371,4372,4379,4415,4420],{},[553,4373,4374,4375,4378],{},"a2696c9: Add an experimental ",[471,4376,4377],{},"VyCalendar"," component with ISO-string date selection and a built-in Lynx date-runtime caveat.",[553,4380,4381,4382,4385,4386,4388,4389,798,4391,798,4393,798,4395,4397,4398,4401,4402,641,4405,4407,4408,954,4410,4412,4413,476],{},"a2696c9: ",[845,4383,4384],{},"Breaking:"," components are now exported under a single canonical ",[471,4387,1400],{}," name only. The bare aliases (",[471,4390,101],{},[471,4392,111],{},[471,4394,141],{},[471,4396,682],{},", …) have been removed so there is one name per component — the same one the ",[471,4399,4400],{},"VyUI"," plugin registers globally. Update imports from ",[471,4403,4404],{},"import { Button } from '@vyui\u002Fkit'",[471,4406,1433],{},". The unprefixed ",[471,4409,141],{},[471,4411,682],{}," primitives remain available from ",[471,4414,41],{},[553,4416,4062,4417],{},[4064,4418,4419],{},"c344b72",[553,4421,4062,4422,4424],{},[4064,4423,4419],{},[550,4425,4426],{},[553,4427,4428],{},"@vyui\u002Fcore@0.2.0",{"title":478,"searchDepth":479,"depth":480,"links":4430},[4431,4432],{"id":1046,"depth":653,"text":1047},{"id":547,"depth":653,"text":548},3000,{},"\u002Fchangelog\u002Fkit-0.3.0",{"title":4283,"description":1525},"changelog\u002Fkit-0.3.0","v0.3.0","8bITypOemdWKZ-030SNHehx-qTucC7HzXYIEobFurVE",{"id":4441,"title":4442,"body":4443,"changelogOrder":4781,"date":1614,"description":4451,"extension":484,"meta":4782,"navigation":486,"package":63,"path":4783,"seo":4784,"stem":4785,"version":4786,"__hash__":4787},"changelog\u002Fchangelog\u002Fkit-0.3.1.md","@vyui\u002Fkit v0.3.1",{"type":465,"value":4444,"toc":4778},[4445,4447],[545,4446,548],{"id":547},[550,4448,4449,4612,4642,4660,4662,4680,4758,4763,4768],{},[553,4450,4451,4452],{},"62d9f13: Dark mode via semantic design tokens.",[550,4453,4454,4511,4534,4555,4588],{},[553,4455,4456,4457,562,4460,562,4463,562,4466,562,4469,562,4472,4475,4476,562,4478,562,4481,562,4484,562,4486,4489,4490,562,4493,562,4496,562,4499,4502,4503,4506,4507,4510],{},"New role-based token layer (the nuxt\u002Fui + shadcn convention, Lynx-adapted): text (",[471,4458,4459],{},"text-highlighted",[471,4461,4462],{},"text-default",[471,4464,4465],{},"text-toned",[471,4467,4468],{},"text-muted",[471,4470,4471],{},"text-dimmed",[471,4473,4474],{},"text-inverted","), background (",[471,4477,2353],{},[471,4479,4480],{},"bg-muted",[471,4482,4483],{},"bg-elevated",[471,4485,2279],{},[471,4487,4488],{},"bg-inverted",") and border (",[471,4491,4492],{},"border-default",[471,4494,4495],{},"border-muted",[471,4497,4498],{},"border-accented",[471,4500,4501],{},"border-inverted","). Each is a single-hop ",[471,4504,4505],{},"var(--ui-*)"," → concrete ",[471,4508,4509],{},"theme()"," literal, so it resolves on Lynx and flips between modes on its own.",[553,4512,4513,4514,562,4517,562,4520,4523,4524,4527,4528,4530,4531,476],{},"Every theme migrated off raw ",[471,4515,4516],{},"text-neutral-*",[471,4518,4519],{},"bg-neutral-*",[471,4521,4522],{},"border-neutral-*"," onto these tokens, so a component flips in dark with zero ",[471,4525,4526],{},"dark:"," variants. Consumers get the same for their own chrome — write ",[471,4529,4468],{},", not ",[471,4532,4533],{},"text-neutral-500 dark:text-neutral-400",[553,4535,4536,4537,4540,4541,4544,4545,4548,4549,2887,4552,476],{},"A single ",[471,4538,4539],{},".dark"," class on an app-root ancestor (",[471,4542,4543],{},"useColorMode()",") redefines the tokens to their dark values; the neutral RAMP stays fixed (raw ",[471,4546,4547],{},"neutral-*"," is a literal shade in both modes — least surprise), and only the accent mode tier shifts ",[471,4550,4551],{},"-500",[471,4553,4554],{},"-400",[553,4556,4557,4559,4560,4563,4564,562,4567,562,4570,4572,4573,4576,4577,860,4580,4583,4584,4587],{},[471,4558,4543],{}," composable (",[471,4561,4562],{},"'light' | 'dark' | 'system'",", plus ",[471,4565,4566],{},"isDark",[471,4568,4569],{},"setMode",[471,4571,3571],{},") folds ",[471,4574,4575],{},"'system'"," to the OS appearance and follows it live on web. App-root contract: bind ",[471,4578,4579],{},":class=\"{ dark: colorMode.isDark }\"",[471,4581,4582],{},":key=\"colorMode.mode\""," — the ",[471,4585,4586],{},":key"," remount re-skins an already-mounted tree on Lynx native.",[553,4589,4590,4591,4593,4594,4597,4598,4600,4601,562,4604,4607,4608,4611],{},"Mode-tier tokens hold ",[471,4592,4509],{}," literals (not ",[471,4595,4596],{},"var(--ui-color-*)"," refs), fixing a latent two-level ",[471,4599,2477],{}," collapse on device. ",[471,4602,4603],{},"rounded",[471,4605,4606],{},"shadcn"," style overlays (which redeclare ",[471,4609,4610],{},":root",") gain the full token set for light AND dark.",[553,4613,4614,4615,4617,4618,4621,4622,4624,4625,738,4628,4631,4632,954,4635,4638,4639,4641],{},"3c08b29: ",[471,4616,1068],{}," now paints its colored border plus a shadow-ring while focused (tracked in JS — Lynx has no ",[471,4619,4620],{},":focus-within","), instead of only via the static ",[471,4623,3929],{}," prop. The ring is a flat arbitrary ",[471,4626,4627],{},"box-shadow",[471,4629,4630],{},"0 0 0 2px var(--ui-color-{color}-200)",") because the Lynx preset has no ",[471,4633,4634],{},"ring*",[471,4636,4637],{},"boxShadowColor"," plugins; the per-color classes are safelisted in the Tailwind preset. ",[471,4640,3929],{}," still forces the same treatment on permanently.",[553,4643,1543,4644,1547,4646,1550,4648,1554,4650,1558,4652,634,4654,1564,4656,1568,4658,1572],{},[471,4645,1546],{},[471,4647,1095],{},[471,4649,1553],{},[471,4651,1557],{},[471,4653,1267],{},[471,4655,1563],{},[471,4657,1567],{},[471,4659,1571],{},[553,4661,1575],{},[553,4663,1578,4664,1582,4666,1586,4668,1590,4670,1594,4672,1598,4674,1602,4676,1606,4678,1086],{},[471,4665,1581],{},[471,4667,1585],{},[471,4669,1589],{},[471,4671,1593],{},[471,4673,1597],{},[471,4675,1601],{},[471,4677,1605],{},[471,4679,1609],{},[553,4681,4682,4683,4685,4686,4689,4690,4692,4693,4695,4696,4698,4699,4702,4703,3943,4706,4709,4710,4713,4714,4716,4717,4720,4721,4724,4725,634,4728,4730,4731,4733,4734,4736,4737,4739,4740,4743,4744,4747,4748,4751,4752,4754,4755,476],{},"93c9827: Add ",[471,4684,2245],{},", the app-root shell: owns the ",[471,4687,4688],{},"dark"," class + ",[471,4691,4586],{}," remount from ",[471,4694,375],{},", mounts ",[471,4697,2436],{}," (opt-out via ",[471,4700,4701],{},":overlays=\"false\"","), sets ",[471,4704,4705],{},"--ui-radius",[471,4707,4708],{},"radius"," prop, and emits ",[471,4711,4712],{},"viewport-change"," with the root layout size.",[589,4715],{},"Also export ",[471,4718,4719],{},"resolveColorHex"," (from the barrel and the ",[471,4722,4723],{},".\u002Fprovide"," entry) so consumers can bake semantic colors into ",[471,4726,4727],{},"VyIcon",[471,4729,790],{}," prop — Lynx rasterizes ",[471,4732,3850],{},", so ",[471,4735,3552],{}," classes never color an icon.",[589,4738],{},"Fix icon-only (",[471,4741,4742],{},"square",") buttons rendering off-center: vue-lynx realizes empty slot\u002F",[471,4745,4746],{},"v-if"," anchors as real zero-size nodes, so the base ",[471,4749,4750],{},"gap-*"," added phantom width after the icon. ",[471,4753,4742],{}," now applies ",[471,4756,4757],{},"justify-center gap-0",[553,4759,4062,4760],{},[4064,4761,4762],{},"4ee6a7d",[553,4764,4062,4765],{},[4064,4766,4767],{},"d4f9b1a",[553,4769,4062,4770,4773],{},[4064,4771,4772],{},"1637c40",[550,4774,4775],{},[553,4776,4777],{},"@vyui\u002Fcore@0.2.1",{"title":478,"searchDepth":479,"depth":480,"links":4779},[4780],{"id":547,"depth":653,"text":548},3001,{},"\u002Fchangelog\u002Fkit-0.3.1",{"title":4442,"description":4451},"changelog\u002Fkit-0.3.1","v0.3.1","8pSpQBri2L7l6D_GpI3Eome6_Iy-qCXZS8-XKFCIWKE",{"id":4789,"title":4790,"body":4791,"changelogOrder":4989,"date":1614,"description":1864,"extension":484,"meta":4990,"navigation":486,"package":63,"path":4991,"seo":4992,"stem":4993,"version":4994,"__hash__":4995},"changelog\u002Fchangelog\u002Fkit-0.3.2.md","@vyui\u002Fkit v0.3.2",{"type":465,"value":4792,"toc":4986},[4793,4795],[545,4794,548],{"id":547},[550,4796,4797,4870,4945,4965],{},[553,4798,1633,4799,587,4802],{},[581,4800,1638],{"href":1636,"rel":4801},[585],[550,4803,4804,4814,4824,4834,4846,4854],{},[553,4805,4806,1645,4808,1649,4810,954,4812,1656],{},[471,4807,41],{},[471,4809,1648],{},[471,4811,1652],{},[471,4813,1655],{},[553,4815,4816,1661,4818,1665,4820,954,4822,1672],{},[471,4817,41],{},[471,4819,1664],{},[471,4821,1668],{},[471,4823,1671],{},[553,4825,4826,1677,4828,1681,4830,1684,4832,1688],{},[471,4827,41],{},[471,4829,1680],{},[471,4831,1224],{},[471,4833,1687],{},[553,4835,4836,1693,4838,954,4840,1700,4842,1704,4844],{},[471,4837,41],{},[471,4839,1696],{},[471,4841,1699],{},[471,4843,1703],{},[471,4845,1707],{},[553,4847,4848,1645,4850,1715,4852,1719],{},[471,4849,46],{},[471,4851,1714],{},[471,4853,1718],{},[553,4855,4856,1724,4858,954,4860,954,4862,1734,4864,634,4866,1740,4868],{},[471,4857,46],{},[471,4859,1727],{},[471,4861,1730],{},[471,4863,1733],{},[471,4865,1737],{},[471,4867,1117],{},[471,4869,1743],{},[553,4871,1746,4872,587,4875],{},[581,4873,1751],{"href":1749,"rel":4874},[585],[550,4876,4877,4889,4897,4915,4925,4935],{},[553,4878,4879,1758,4881,613,4883,1764,4885,860,4887,1771],{},[471,4880,41],{},[471,4882,277],{},[471,4884,1763],{},[471,4886,1767],{},[471,4888,1770],{},[553,4890,4891,1776,4893,613,4895,1782],{},[471,4892,41],{},[471,4894,277],{},[471,4896,1781],{},[553,4898,4899,1758,4901,1790,4903,1794,4905,1798,4907,562,4909,1805,4911,1808,4913,1812],{},[471,4900,41],{},[471,4902,1789],{},[471,4904,1793],{},[471,4906,1797],{},[471,4908,1801],{},[471,4910,1804],{},[471,4912,1767],{},[471,4914,1811],{},[553,4916,4917,1817,4919,1821,4921,1825,4923,1829],{},[471,4918,46],{},[471,4920,1820],{},[471,4922,1824],{},[471,4924,1828],{},[553,4926,4927,1758,4929,1836,4931,1839,4933,1843],{},[471,4928,46],{},[471,4930,277],{},[471,4932,1781],{},[471,4934,1842],{},[553,4936,4937,1848,4939,1852,4941,954,4943,1859],{},[471,4938,46],{},[471,4940,1851],{},[471,4942,1855],{},[471,4944,1858],{},[553,4946,4947,4948,4951,4952,4955,4956,4959,4960,587],{},"Fix tailwind preset failing to load from source under jiti (",[471,4949,4950],{},"Cannot find module '.\u002Ftheme\u002Findex.js'",") — import the theme barrel with an explicit ",[471,4953,4954],{},".ts"," extension; Vite still emits ",[471,4957,4958],{},".\u002Ftheme\u002Findex.js"," in dist. (",[581,4961,4964],{"href":4962,"rel":4963},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fpull\u002F135",[585],"#135",[553,4966,3603,4967,798,4974,3623,4981],{},[581,4968,4971],{"href":4969,"rel":4970},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fcommit\u002F0e34d181e02d66502ddc06e5b61a61b75e654578",[585],[471,4972,4973],{},"0e34d18",[581,4975,4978],{"href":4976,"rel":4977},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fcommit\u002Fce424a71774e0d6b6eda0920ede2caf34fdc036b",[585],[471,4979,4980],{},"ce424a7",[550,4982,4983],{},[553,4984,4985],{},"@vyui\u002Fcore@0.2.2",{"title":478,"searchDepth":479,"depth":480,"links":4987},[4988],{"id":547,"depth":653,"text":548},3002,{},"\u002Fchangelog\u002Fkit-0.3.2",{"title":4790,"description":1864},"changelog\u002Fkit-0.3.2","v0.3.2","m1D55HS4g7CGWbXdi22JpNEjuB0R5BMkjpYPuDwXaYI",{"id":4997,"title":4998,"body":4999,"changelogOrder":5125,"date":2208,"description":5126,"extension":484,"meta":5127,"navigation":486,"package":63,"path":5128,"seo":5129,"stem":5130,"version":5131,"__hash__":5132},"changelog\u002Fchangelog\u002Fkit-0.3.3.md","@vyui\u002Fkit v0.3.3",{"type":465,"value":5000,"toc":5122},[5001,5003],[545,5002,548],{"id":547},[550,5004,5005,5060,5073],{},[553,5006,2049,5007,587,5010,5012,2059,5014,2063,5016,2066,5018,2070,5020,798,5022,954,5024,2079,5026,2083,5028,2086,5030,798,5032,798,5034,2095,5036],{},[581,5008,2054],{"href":2052,"rel":5009},[585],[589,5011],{},[845,5013,1925],{},[471,5015,2062],{},[471,5017,1319],{},[471,5019,2069],{},[471,5021,2073],{},[471,5023,527],{},[471,5025,2078],{},[471,5027,2082],{},[471,5029,41],{},[471,5031,2082],{},[471,5033,2091],{},[471,5035,2094],{},[550,5037,5038,5050],{},[553,5039,2100,5040,2104,5042,2108,5044,2112,5046,2116,5048,587],{},[471,5041,2103],{},[471,5043,2107],{},[471,5045,2111],{},[471,5047,2115],{},[471,5049,2119],{},[553,5051,2122,5052,2125,5054,2129,5056,2132,5058],{},[471,5053,1016],{},[471,5055,2128],{},[471,5057,1267],{},[471,5059,2135],{},[553,5061,2182,5062,2186,5064,2190,5066,2194,5068,2198,5070,587],{},[471,5063,2185],{},[471,5065,2189],{},[471,5067,2193],{},[471,5069,2197],{},[581,5071,2203],{"href":2201,"rel":5072},[585],[553,5074,3603,5075,798,5082,798,5089,798,5096,798,5103,798,5110,3623,5117],{},[581,5076,5079],{"href":5077,"rel":5078},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fcommit\u002F53c027bdb9c2577449bbb24a746154304a220a38",[585],[471,5080,5081],{},"53c027b",[581,5083,5086],{"href":5084,"rel":5085},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fcommit\u002F2e9811241087f3c47f4e8bb88168b38e2dd91fbd",[585],[471,5087,5088],{},"2e98112",[581,5090,5093],{"href":5091,"rel":5092},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fcommit\u002Fdf383f59ac47245abf88c7ca6388c5bbbc6156c9",[585],[471,5094,5095],{},"df383f5",[581,5097,5100],{"href":5098,"rel":5099},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fcommit\u002F758a2315e70248c750d4feb3132add6d1ff87bcc",[585],[471,5101,5102],{},"758a231",[581,5104,5107],{"href":5105,"rel":5106},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fcommit\u002F251b586777b081a12db2e0d795b3237584f70d8d",[585],[471,5108,5109],{},"251b586",[581,5111,5114],{"href":5112,"rel":5113},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fcommit\u002F21ec23ad5bcb0e61a921ab536abbfdbb4254325b",[585],[471,5115,5116],{},"21ec23a",[550,5118,5119],{},[553,5120,5121],{},"@vyui\u002Fcore@0.2.3",{"title":478,"searchDepth":479,"depth":480,"links":5123},[5124],{"id":547,"depth":653,"text":548},3003,"Overlay cleanup ahead of the shared-core refactor.",{},"\u002Fchangelog\u002Fkit-0.3.3",{"title":4998,"description":5126},"changelog\u002Fkit-0.3.3","v0.3.3","-XOZbqYHIt9N2SSREBcf32_VO7eZaci3LboAoixM2Hc",{"id":5134,"title":5135,"body":5136,"changelogOrder":5240,"date":2313,"description":2314,"extension":484,"meta":5241,"navigation":486,"package":63,"path":5242,"seo":5243,"stem":5244,"version":5245,"__hash__":5246},"changelog\u002Fchangelog\u002Fkit-0.3.4.md","@vyui\u002Fkit v0.3.4",{"type":465,"value":5137,"toc":5237},[5138,5140],[545,5139,548],{"id":547},[550,5141,5142,5169,5185,5196,5203],{},[553,5143,2227,5144,2231,5146,2235,5148,562,5150,2242,5152,2246,5154,2250,5156,2253,5158,2257,5160,562,5162,2264,5164,2268,5166,587],{},[471,5145,2230],{},[471,5147,2234],{},[471,5149,2238],{},[471,5151,2241],{},[471,5153,2245],{},[471,5155,2249],{},[471,5157,2111],{},[471,5159,2256],{},[471,5161,2260],{},[471,5163,2263],{},[471,5165,2267],{},[581,5167,2273],{"href":2271,"rel":5168},[585],[553,5170,5171,5172,5174,5175,5177,5178,5181,5182,587],{},"Select\u002FCombobox selection tick now bakes its fill via the Icon ",[471,5173,790],{}," prop (accent ramp) instead of a class the rasterized svg can't receive — it rendered black and vanished in dark mode. Combobox's \"No results\" text also carries ",[471,5176,4468],{}," on the ",[471,5179,5180],{},"\u003Ctext>"," itself so it flips with the theme. (",[581,5183,2273],{"href":2271,"rel":5184},[585],[553,5186,5187,5188,5177,5190,5192,5193,587],{},"Separator label now uses ",[471,5189,4459],{},[471,5191,5180],{}," itself, so its color flips with the theme (Lynx doesn't inherit the container's color into the text — the label rendered black in dark mode). (",[581,5194,2273],{"href":2271,"rel":5195},[585],[553,5197,2301,5198,2305,5200,587],{},[471,5199,2304],{},[581,5201,2273],{"href":2271,"rel":5202},[585],[553,5204,3603,5205,798,5212,798,5217,798,5222,798,5227,3623,5232],{},[581,5206,5209],{"href":5207,"rel":5208},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fcommit\u002F73ed40268cb4c0c17c89181fb0cd5f7470d87018",[585],[471,5210,5211],{},"73ed402",[581,5213,5215],{"href":5207,"rel":5214},[585],[471,5216,5211],{},[581,5218,5220],{"href":5207,"rel":5219},[585],[471,5221,5211],{},[581,5223,5225],{"href":5207,"rel":5224},[585],[471,5226,5211],{},[581,5228,5230],{"href":5207,"rel":5229},[585],[471,5231,5211],{},[550,5233,5234],{},[553,5235,5236],{},"@vyui\u002Fcore@0.2.4",{"title":478,"searchDepth":479,"depth":480,"links":5238},[5239],{"id":547,"depth":653,"text":548},3004,{},"\u002Fchangelog\u002Fkit-0.3.4",{"title":5135,"description":2314},"changelog\u002Fkit-0.3.4","v0.3.4","XQ0MG9diCrrY5o8KrXuiiDJk0IgKP9Ji8CKkipBeWFw",{"id":5248,"title":5249,"body":5250,"changelogOrder":5561,"date":2551,"description":2552,"extension":484,"meta":5562,"navigation":486,"package":63,"path":5563,"seo":5564,"stem":5565,"version":5566,"__hash__":5567},"changelog\u002Fchangelog\u002Fkit-0.3.5.md","@vyui\u002Fkit v0.3.5",{"type":465,"value":5251,"toc":5558},[5252,5254],[545,5253,548],{"id":547},[550,5255,5256,5365,5481,5537],{},[553,5257,2332,5258,2335,5260,587,5263,5265,2346,5267,2350,5269,2354,5271,2358,5273,683,5275,2365,5277,613,5279,2372,5281,2375,5283,2378,5285,5287,613,5291,798,5293,683,5295,2394,5297,2397,5299,2400,5301,2403,5303,1758,5305,634,5307,2412,5309,2415,5311,2418,5313,613,5321,2433,5323,2437,5325,562,5327,2443,5329,2446,5331,562,5333,562,5335,2456,5337,2460,5339,2464,5341,476,5343,2470,5345,2474,5347,2478,5349,2482,5351,2486,5353,2489,5355,5357,2495,5359,2498,5361,2501,5363,2505],{},[471,5259,41],{},[581,5261,2340],{"href":2338,"rel":5262},[585],[589,5264],{},[471,5266,2345],{},[471,5268,2349],{},[471,5270,2353],{},[845,5272,2357],{},[471,5274,2361],{},[471,5276,2364],{},[471,5278,2368],{},[845,5280,2371],{},[589,5282],{},[471,5284,2368],{},[589,5286],{},[845,5288,2383,5289,2386],{},[471,5290,41],{},[471,5292,1301],{},[471,5294,2391],{},[471,5296,2364],{},[471,5298,46],{},[471,5300,2364],{},[589,5302],{},[471,5304,46],{},[471,5306,2408],{},[471,5308,2411],{},[471,5310,2353],{},[589,5312],{},[845,5314,5315,683,5317,2425,5319,2429],{},[471,5316,1301],{},[471,5318,2391],{},[471,5320,2428],{},[471,5322,2432],{},[471,5324,2436],{},[471,5326,2428],{},[471,5328,2442],{},[471,5330,2353],{},[471,5332,2449],{},[471,5334,2452],{},[471,5336,2455],{},[471,5338,2459],{},[471,5340,2463],{},[471,5342,2467],{},[589,5344],{},[471,5346,2473],{},[471,5348,2477],{},[471,5350,2481],{},[471,5352,2485],{},[471,5354,2432],{},[589,5356],{},[471,5358,2494],{},[471,5360,2279],{},[471,5362,46],{},[471,5364,2504],{},[553,5366,5367,5368,5371,5372,587,5375,5475,5477,5478,476],{},"Add the ",[471,5369,5370],{},"lunaris"," registry style, and fix four token-layer bugs the audit turned up. (",[581,5373,2340],{"href":2338,"rel":5374},[585],[550,5376,5377,5399,5420,5439,5455,5463],{},[553,5378,5379,5381,5382,5387,5388,5391,5392,683,5395,5398],{},[471,5380,5370],{}," — the LUNA design system (from ",[581,5383,5386],{"href":5384,"rel":5385},"https:\u002F\u002Fgithub.com\u002Flynx-family\u002Flynx-ui\u002Ftree\u002Fmain\u002Fluna",[585],"lynx-ui",", Apache-2.0) ported to the token layer: pure-grey canvas\u002Fpaper\u002Fcontent chrome, rose accent, and the five ",[471,5389,5390],{},".luna-gradient-*"," classes. A token-only overlay, so every base ",[471,5393,5394],{},".vue",[471,5396,5397],{},"theme\u002F*.ts"," is reused unchanged. LUNA's neutral variant shares this chrome byte-for-byte and differs only in accent, so it is documented as a delta in the file header rather than shipped as a second style.",[553,5400,5401,5402,683,5404,5406,5407,5409,5410,5412,5413,562,5416,5419],{},"Fix: ",[471,5403,4606],{},[471,5405,4603],{}," held nested ",[471,5408,4596],{}," refs on the mode tier, which collapse on Lynx native (one level of ",[471,5411,2477],{}," only), so consumer-written ",[471,5414,5415],{},"bg-primary",[471,5417,5418],{},"text-error"," painted nothing on device.",[553,5421,5401,5422,634,5424,5427,5428,5431,5432,5434,5435,5438],{},[471,5423,4606],{},[471,5425,5426],{},"primary"," now follows ",[471,5429,5430],{},"--base-color"," like ",[471,5433,3418],{}," does. It was pinned to ",[471,5436,5437],{},"zinc"," while surfaces tracked the chosen gray, producing combinations shadcn\u002Fui can't express (zinc accent on stone surfaces).",[553,5440,5401,5441,5443,5444,798,5447,5450,5451,5454],{},[471,5442,4719],{}," now resolves shade-less colors (",[471,5445,5446],{},"black",[471,5448,5449],{},"white","). They are single strings in ",[471,5452,5453],{},"tailwindcss\u002Fcolors",", so indexing them by shade fell through to the slate-500 fallback — a monochrome accent painted black surfaces with slate-blue baked SVG icons on them.",[553,5456,5401,5457,5459,5460,5462],{},[471,5458,3992],{}," warns when a chosen ",[471,5461,5430],{}," can't apply because the style ships its own palette, instead of silently ignoring it.",[553,5464,5465,5466,5468,5469,5471,5472,5474],{},"Guards: registry tests now assert every shipped style declares the full 120-token surface, declares no nested ",[471,5467,2477],{}," value, and that ",[471,5470,4603],{}," differs from the base in ",[471,5473,4705],{}," alone.",[589,5476],{},"Install with ",[471,5479,5480],{},"vyui init --style lunaris",[553,5482,5483,5484,798,5487,798,5490,683,5492,5494,5495,587,5498,5500,5501,5503,5504,798,5507,5510,5511,5513,5514,5517,5518,5521,5522,5524,5525,5527,5528,5530,5531,2470,5533,5536],{},"Fix the overlay dim: ",[471,5485,5486],{},"modal",[471,5488,5489],{},"drawer",[471,5491,1714],{},[471,5493,2408],{}," all painted no scrim at all. (",[581,5496,2340],{"href":2338,"rel":5497},[585],[589,5499],{},"Their ",[471,5502,3261],{}," slot used an alpha modifier on a semantic color (",[471,5505,5506],{},"bg-neutral-900\u002F50",[471,5508,5509],{},"bg-neutral-900\u002F40","). The Tailwind preset maps semantic colors to raw ",[471,5512,2477],{}," strings with no ",[471,5515,5516],{},"\u003Calpha-value>"," placeholder, so Tailwind 3 skips generating those utilities entirely — the class resolved to no CSS and the element painted nothing. All four now use ",[471,5519,5520],{},"bg-black\u002F50",", which parses to rgb so the modifier applies.",[589,5523],{},"Most visible in dark mode, where a ",[471,5526,2353],{}," panel over an undimmed ",[471,5529,2353],{}," page had nothing separating it.",[589,5532],{},[471,5534,5535],{},"theme\u002Falpha-modifier.test.ts",", which fails if any theme file reintroduces an alpha modifier on a semantic color.",[553,5538,3603,5539,798,5546,3623,5553],{},[581,5540,5543],{"href":5541,"rel":5542},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fcommit\u002F3298de9acda1e46e36c1402fdd5708bc5eff7131",[585],[471,5544,5545],{},"3298de9",[581,5547,5550],{"href":5548,"rel":5549},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fcommit\u002F9d82f23af16982193202849682cf13b0c4682d1f",[585],[471,5551,5552],{},"9d82f23",[550,5554,5555],{},[553,5556,5557],{},"@vyui\u002Fcore@0.2.5",{"title":478,"searchDepth":479,"depth":480,"links":5559},[5560],{"id":547,"depth":653,"text":548},3005,{},"\u002Fchangelog\u002Fkit-0.3.5",{"title":5249,"description":2552},"changelog\u002Fkit-0.3.5","v0.3.5","ZVD8IFUPwnGBns1zAHxn-a3wSdBlQQmn_jVmTnyVh8U",{"id":5569,"title":5570,"body":5571,"changelogOrder":5609,"date":2596,"description":2597,"extension":484,"meta":5610,"navigation":486,"package":63,"path":5611,"seo":5612,"stem":5613,"version":5614,"__hash__":5615},"changelog\u002Fchangelog\u002Fkit-0.3.6.md","@vyui\u002Fkit v0.3.6",{"type":465,"value":5572,"toc":5606},[5573,5575],[545,5574,548],{"id":547},[550,5576,5577,5582],{},[553,5578,2570,5579,587],{},[581,5580,2575],{"href":2573,"rel":5581},[585],[553,5583,3603,5584,798,5591,798,5596,3623,5601],{},[581,5585,5588],{"href":5586,"rel":5587},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fcommit\u002Fc9f828763c94f37b0a15c9a35392b9b4d40b550e",[585],[471,5589,5590],{},"c9f8287",[581,5592,5594],{"href":5586,"rel":5593},[585],[471,5595,5590],{},[581,5597,5599],{"href":5586,"rel":5598},[585],[471,5600,5590],{},[550,5602,5603],{},[553,5604,5605],{},"@vyui\u002Fcore@0.2.6",{"title":478,"searchDepth":479,"depth":480,"links":5607},[5608],{"id":547,"depth":653,"text":548},3006,{},"\u002Fchangelog\u002Fkit-0.3.6",{"title":5570,"description":2597},"changelog\u002Fkit-0.3.6","v0.3.6","oMqBj-p_JcAZVlhf_Wvir_9-YVHAulrb3Xol2nhpGNk",{"id":5617,"title":5618,"body":5619,"changelogOrder":5849,"date":3211,"description":3212,"extension":484,"meta":5850,"navigation":486,"package":63,"path":5851,"seo":5852,"stem":5853,"version":5854,"__hash__":5855},"changelog\u002Fchangelog\u002Fkit-0.3.7.md","@vyui\u002Fkit v0.3.7",{"type":465,"value":5620,"toc":5846},[5621,5623],[545,5622,548],{"id":547},[550,5624,5625,5678,5707,5776,5793],{},[553,5626,2615,5627,2621,5630,2624,5632,798,5634,798,5636,798,5638,798,5640,798,5642,2637,5644,798,5646,2642,5648,2645,5650,2649,5652,5654,2654,5656,2658,5658,2662,5660,2666,5662,2670,5664,2673,5666],{},[581,5628,2620],{"href":2618,"rel":5629},[585],[589,5631],{},[471,5633,131],{},[471,5635,247],{},[471,5637,267],{},[471,5639,2364],{},[471,5641,239],{},[471,5643,285],{},[471,5645,252],{},[471,5647,847],{},[471,5649,916],{},[471,5651,2648],{},[589,5653],{},[471,5655,916],{},[471,5657,2657],{},[471,5659,2661],{},[471,5661,2665],{},[471,5663,2669],{},[589,5665],{},[550,5667,5668,5672,5674],{},[553,5669,2678,5670,2682],{},[471,5671,2681],{},[553,5673,2685],{},[553,5675,5676,2691],{},[471,5677,2690],{},[553,5679,2788,5680,2791,5682,2794,5684,2797,5686,2800,5688,2804,5690,954,5692,954,5694,954,5696,954,5698,2820,5700,2824,5702,2828,5704,587],{},[471,5681,46],{},[471,5683,1824],{},[471,5685,1828],{},[471,5687,41],{},[471,5689,2803],{},[471,5691,2807],{},[471,5693,2810],{},[471,5695,2813],{},[471,5697,2816],{},[471,5699,2819],{},[471,5701,2823],{},[471,5703,2827],{},[581,5705,2833],{"href":2831,"rel":5706},[585],[553,5708,2972,5709,2978,5712,2982,5714,2986,5716,2990,5718,476,5720,5768,5770,3075,5772,3079,5774,3083],{},[581,5710,2977],{"href":2975,"rel":5711},[585],[471,5713,2981],{},[471,5715,2985],{},[471,5717,2989],{},[471,5719,2993],{},[550,5721,5722,5730,5740,5746,5748,5752,5760,5762],{},[553,5723,5724,3001,5726,3004,5728,3007],{},[471,5725,3000],{},[471,5727,1205],{},[471,5729,239],{},[553,5731,5732,3013,5734,3017,5736,3021,5738,3024],{},[471,5733,3012],{},[471,5735,3016],{},[471,5737,3020],{},[471,5739,1193],{},[553,5741,5742,3029,5744,3033],{},[471,5743,1117],{},[471,5745,3032],{},[553,5747,3036],{},[553,5749,3039,5750,3043],{},[471,5751,3042],{},[553,5753,3046,5754,954,5756,3053,5758,3057],{},[471,5755,3049],{},[471,5757,3052],{},[471,5759,3056],{},[553,5761,3060],{},[553,5763,1465,5764,3065,5766,3069],{},[471,5765,484],{},[471,5767,3068],{},[589,5769],{},[845,5771,3074],{},[471,5773,3078],{},[471,5775,3082],{},[553,5777,5778,5779,5781,5782,5784,5785,5788,5789,5792],{},"Fix the default (",[471,5780,484],{},") Slider thumb rendering 0×0. Its size was ",[471,5783,3068],{},", and (",[581,5786,2977],{"href":2975,"rel":5787},[585],")\nTailwind v3's spacing scale has no 4.5 step, so the class compiled to no CSS —\nsafelisted, no build warning. It is now ",[471,5790,5791],{},"size-[18px]",", and the preset test suite\nfails on any theme class using a fractional spacing step v3 cannot generate.",[553,5794,3603,5795,798,5802,798,5807,798,5814,798,5819,798,5824,798,5831,798,5836,3623,5841],{},[581,5796,5799],{"href":5797,"rel":5798},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fcommit\u002F949edd34636c939604040db3d821807617bd6d80",[585],[471,5800,5801],{},"949edd3",[581,5803,5805],{"href":5797,"rel":5804},[585],[471,5806,5801],{},[581,5808,5811],{"href":5809,"rel":5810},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fcommit\u002Ff9f0946c902f7718f5f3e1dd3ec78d3c33470c5d",[585],[471,5812,5813],{},"f9f0946",[581,5815,5817],{"href":5797,"rel":5816},[585],[471,5818,5801],{},[581,5820,5822],{"href":5797,"rel":5821},[585],[471,5823,5801],{},[581,5825,5828],{"href":5826,"rel":5827},"https:\u002F\u002Fgithub.com\u002FKealanAU\u002Fvyui\u002Fcommit\u002F01415de18898a3a9ac76234d3a881ab87e2d9bb7",[585],[471,5829,5830],{},"01415de",[581,5832,5834],{"href":5797,"rel":5833},[585],[471,5835,5801],{},[581,5837,5839],{"href":5797,"rel":5838},[585],[471,5840,5801],{},[550,5842,5843],{},[553,5844,5845],{},"@vyui\u002Fcore@0.2.7",{"title":478,"searchDepth":479,"depth":480,"links":5847},[5848],{"id":547,"depth":653,"text":548},3007,{},"\u002Fchangelog\u002Fkit-0.3.7",{"title":5618,"description":3212},"changelog\u002Fkit-0.3.7","v0.3.7","fNi4Bfh-VSIXvWedxggS9NVhRvjBgwsJwghyEJdoAmM",{"id":5857,"title":5858,"body":5859,"changelogOrder":11,"date":482,"description":5871,"extension":484,"meta":5872,"navigation":486,"package":63,"path":5873,"seo":5874,"stem":5875,"version":5876,"__hash__":5877},"changelog\u002Fchangelog\u002Fkit-scaffold.md","Kit scaffolded",{"type":465,"value":5860,"toc":5869},[5861],[468,5862,5863,5865,5866,5868],{},[471,5864,46],{}," is scaffolded as part of the monorepo, sitting alongside ",[471,5867,41],{}," and the documentation site — the home for opinionated, themed components.",{"title":478,"searchDepth":479,"depth":480,"links":5870},[],"The styled-component package joins the monorepo alongside core and the docs site.",{},"\u002Fchangelog\u002Fkit-scaffold",{"title":5858,"description":5871},"changelog\u002Fkit-scaffold","Initial","7cEQisROCLM6kbYPmYRb6460XnaeGk6czt8eMTNYOFM",{"id":5879,"title":5880,"body":5881,"changelogOrder":11,"date":531,"description":5903,"extension":484,"meta":5904,"navigation":486,"package":63,"path":5905,"seo":5906,"stem":5907,"version":490,"__hash__":5908},"changelog\u002Fchangelog\u002Fkit-styled.md","Styled Button, Switch & Tabs",{"type":465,"value":5882,"toc":5901},[5883],[468,5884,5885,5887,5888,798,5890,983,5892,5894,5895,5897,5898,476],{},[471,5886,46],{}," publishes its first styled components — ",[845,5889,101],{},[845,5891,272],{},[845,5893,277],{}," — composed on top of ",[471,5896,41],{}," primitives. Available now on npm as ",[471,5899,5900],{},"@vyui\u002Fkit@0.0.1",{"title":478,"searchDepth":479,"depth":480,"links":5902},[],"The first styled components land on npm — composed on core primitives, themed and ready to drop in.",{},"\u002Fchangelog\u002Fkit-styled",{"title":5880,"description":5903},"changelog\u002Fkit-styled","rp-Opx518UBbFwsQQNX6tDHhHaQKPzJnYuOa_Fvg0uc",1785060112048]