morethanui 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DESIGN.md +310 -0
- package/LICENSE +24 -0
- package/README.md +119 -0
- package/css/base.css +200 -0
- package/css/components.css +1496 -0
- package/css/layout.css +380 -0
- package/css/tokens.css +318 -0
- package/dist/mtui.css +2394 -0
- package/dist/mtui.js +1719 -0
- package/dist/mtui.min.css +1 -0
- package/dist/mtui.min.js +1 -0
- package/fonts/OFL.txt +93 -0
- package/fonts/noto-sans-arabic.woff2 +0 -0
- package/fonts/noto-sans-latin-ext.woff2 +0 -0
- package/fonts/noto-sans-latin.woff2 +0 -0
- package/fonts/noto-sans-mono-latin.woff2 +0 -0
- package/js/accordion.js +64 -0
- package/js/feedback.js +171 -0
- package/js/menu.js +72 -0
- package/js/pull-refresh.js +122 -0
- package/js/telegram.js +175 -0
- package/js/x-colorswatches.js +144 -0
- package/js/x-contextmenu.js +190 -0
- package/js/x-datepicker.js +321 -0
- package/js/x-select.js +139 -0
- package/js/x-tabs.js +48 -0
- package/js/x-theme.js +154 -0
- package/js/x-toast.js +119 -0
- package/llms.txt +409 -0
- package/package.json +48 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{color-scheme:light;--bg: #F3F0EA;--surface: #FFFFFF;--surface-2: #EAE6DD;--surface-3: #DFD9CD;--text: #1C1A17;--text-muted: #67625A;--text-faint: #A8A297;--inverse: #1C1A17;--on-inverse: #F3F0EA;--scrim: rgba(28, 26, 23, .44)}[data-theme=dark]{color-scheme:dark;--bg: #161513;--surface: #211F1C;--surface-2: #2B2925;--surface-3: #38352F;--text: #F0EDE7;--text-muted: #A39D92;--text-faint: #6B665D;--inverse: #F0EDE7;--on-inverse: #1C1A17;--scrim: rgba(0, 0, 0, .55)}:root{--on-accent: #FFFFFF;--focus: var(--accent);--accent-2: var(--accent);--accent-2-hover: var(--accent-hover);--accent-2-text: var(--accent-text);--accent-2-tint: var(--accent-tint);--on-accent-2: var(--on-accent)}:root,[data-accent=clay]{--accent: #BC4B2A;--accent-hover: #A93F20;--accent-text: #8F3016;--accent-tint: #F3DCD6}[data-theme=dark],[data-theme=dark][data-accent=clay]{--accent-text: #F0A896;--accent-tint: #3A2723}[data-accent=cobalt]{--accent: #3556C9;--accent-hover: #2B49B2;--accent-text: #2B44A6;--accent-tint: #DCE3F7}[data-theme=dark][data-accent=cobalt]{--accent-text: #A9C3EC;--accent-tint: #232B45}[data-accent=fern]{--accent: #2F7A50;--accent-hover: #276A44;--accent-text: #245D3D;--accent-tint: #DCEEE2}[data-theme=dark][data-accent=fern]{--accent-text: #8ED1AB;--accent-tint: #22352A}[data-accent=plum]{--accent: #6E46BD;--accent-hover: #5F3AA8;--accent-text: #56349B;--accent-tint: #E6E0F2}[data-theme=dark][data-accent=plum]{--accent-text: #C9BCF0;--accent-tint: #2E2A3C}@supports (color: oklch(from white l c h)){:root:not([data-theme=dark]):not([data-tint=warm]){--bg: oklch(from var(--accent) 95.6% .01 h);--surface: oklch(from var(--accent) 99% .006 h);--surface-2: oklch(from var(--accent) 92.6% .014 h);--surface-3: oklch(from var(--accent) 88.7% .018 h);--text: oklch(from var(--accent) 21.9% .008 h);--text-muted: oklch(from var(--accent) 49.8% .014 h);--text-faint: oklch(from var(--accent) 71.4% .017 h);--inverse: oklch(from var(--accent) 21.9% .008 h);--on-inverse: oklch(from var(--accent) 95.6% .01 h)}[data-theme=dark]:not([data-tint=warm]){--bg: oklch(from var(--accent) 19.6% .01 h);--surface: oklch(from var(--accent) 24% .014 h);--surface-2: oklch(from var(--accent) 28.2% .018 h);--surface-3: oklch(from var(--accent) 33% .022 h);--text: oklch(from var(--accent) 94.7% .008 h);--text-muted: oklch(from var(--accent) 69.8% .016 h);--text-faint: oklch(from var(--accent) 51.2% .015 h);--inverse: oklch(from var(--accent) 94.7% .008 h);--on-inverse: oklch(from var(--accent) 21.9% .008 h)}}:root{--danger: #B3402F;--danger-text: #8F3016;--danger-tint: #F3DCD6;--success-text: #245D3D;--success-tint: #DCEEE2;--warning-text: #7A5600;--warning-tint: #F2E8D0}[data-theme=dark]{--danger-text: #F0A896;--danger-tint: #3A2723;--success-text: #8ED1AB;--success-tint: #22352A;--warning-text: #E4C27E;--warning-tint: #383021}:root{--tint-rose-bg: #F3DCD6;--tint-rose-text: #8F3016;--tint-sky-bg: #DCE3F7;--tint-sky-text: #2B44A6;--tint-mint-bg: #DCEEE2;--tint-mint-text: #245D3D;--tint-butter-bg: #F2E8D0;--tint-butter-text: #7A5600;--tint-lavender-bg: #E6E0F2;--tint-lavender-text: #56349B}[data-theme=dark]{--tint-rose-bg: #3A2723;--tint-rose-text: #F0A896;--tint-sky-bg: #232B45;--tint-sky-text: #A9C3EC;--tint-mint-bg: #22352A;--tint-mint-text: #8ED1AB;--tint-butter-bg: #383021;--tint-butter-text: #E4C27E;--tint-lavender-bg: #2E2A3C;--tint-lavender-text: #C9BCF0}:root{--font: "Noto Sans", system-ui, sans-serif;--font-mono: "Noto Sans Mono", ui-monospace, monospace;--fs-page: 38px;--lh-page: 1.12;--fw-page: 800;--ls-page: -.02em;--fs-section: 26px;--lh-section: 1.2;--fw-section: 700;--ls-section: -.01em;--fs-card: 19px;--lh-card: 1.3;--fw-card: 700;--fs-control: 15px;--lh-control: 1.4;--fw-control: 600;--fs-body: 16px;--lh-body: 1.6;--fw-body: 400;--fs-secondary: 14px;--lh-secondary: 1.5;--fs-label: 13px;--fw-label: 600;--fs-code: 13px;--lh-code: 1.7}:root{--sp-4: 4px;--sp-8: 8px;--sp-12: 12px;--sp-16: 16px;--sp-20: 20px;--sp-24: 24px;--sp-32: 32px;--sp-40: 40px;--sp-48: 48px}:root,[data-radius=round]{--r-ctl: 999px;--r-card: 24px;--r-input: 16px;--r-chip: 999px}[data-radius=soft]{--r-ctl: 14px;--r-card: 20px;--r-input: 12px;--r-chip: 10px}[data-radius=sharp]{--r-ctl: 8px;--r-card: 12px;--r-input: 8px;--r-chip: 6px}:root,[data-density=comfortable]{--ctl-h: 48px;--field-h: 48px;--row-h: 64px;--pad: 20px;--gap: 16px}[data-density=compact]{--ctl-h: 44px;--field-h: 44px;--row-h: 52px;--pad: 14px;--gap: 10px}:root{--tap-min: 44px}:root{--ring-focus: 0 0 0 2px var(--surface), 0 0 0 4px var(--accent);--ring-avatar: 0 0 0 3px var(--surface);--ring-popover: 0 0 0 6px var(--bg)}:root{--ease: cubic-bezier(.22, .9, .28, 1);--spring: cubic-bezier(.34, 1.2, .4, 1);--t-micro: .22s;--t-lift: .28s;--t-knob: .3s;--t-popover: .3s;--t-tab: .35s;--t-delete: .35s;--t-dialog: .4s;--t-toast: .5s;--t-skeleton: 1.5s}@media(prefers-reduced-motion:reduce){:root{--t-micro: 0ms;--t-lift: 0ms;--t-knob: 0ms;--t-popover: 0ms;--t-tab: 0ms;--t-delete: 0ms;--t-dialog: 0ms;--t-toast: 0ms}}@media(forced-colors:active){:root{--scrim: Canvas;--ring-focus: none;--ring-avatar: none;--ring-popover: none}}@font-face{font-family:Noto Sans;font-style:normal;font-weight:400 800;font-display:swap;src:url(../fonts/noto-sans-latin.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Noto Sans;font-style:normal;font-weight:400 800;font-display:swap;src:url(../fonts/noto-sans-latin-ext.woff2) format("woff2");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Noto Sans;font-style:normal;font-weight:400 800;font-display:swap;src:url(../fonts/noto-sans-arabic.woff2) format("woff2");unicode-range:U+0600-06FF,U+0750-077F,U+0870-088E,U+0890-0891,U+0897-08E1,U+08E3-08FF,U+200C-200E,U+2010-2011,U+204F,U+2E41,U+FB50-FDFF,U+FE70-FE74,U+FE76-FEFC}@font-face{font-family:Noto Sans Mono;font-style:normal;font-weight:400;font-display:swap;src:url(../fonts/noto-sans-mono-latin.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}*,*:before,*:after{box-sizing:border-box}*{margin:0}html{-webkit-text-size-adjust:100%}body{min-height:100dvh;background:var(--bg);color:var(--text);font-family:var(--font);font-size:var(--fs-body);font-weight:var(--fw-body);line-height:var(--lh-body)}img,svg,video,canvas{display:block;max-inline-size:100%}button,input,select,textarea{font:inherit;color:inherit}ul[role=list],ol[role=list]{list-style:none;padding:0}.t-page{font-size:var(--fs-page);line-height:var(--lh-page);font-weight:var(--fw-page);letter-spacing:var(--ls-page)}.t-section{font-size:var(--fs-section);line-height:var(--lh-section);font-weight:var(--fw-section);letter-spacing:var(--ls-section)}.t-card{font-size:var(--fs-card);line-height:var(--lh-card);font-weight:var(--fw-card)}.t-row{font-size:var(--fs-control);line-height:var(--lh-control);font-weight:var(--fw-control)}.t-body{font-size:var(--fs-body);line-height:var(--lh-body);font-weight:var(--fw-body)}.t-secondary{font-size:var(--fs-secondary);line-height:var(--lh-secondary);font-weight:var(--fw-body);color:var(--text-muted)}.t-label{font-size:var(--fs-label);font-weight:var(--fw-label);color:var(--text-muted)}.t-code{font-family:var(--font-mono);font-size:var(--fs-code);line-height:var(--lh-code);direction:ltr;unicode-bidi:isolate;text-align:start}.t-ltr{direction:ltr;unicode-bidi:isolate}:focus-visible{outline:none;box-shadow:var(--ring-focus)}@media(forced-colors:active){:focus-visible{outline:2px solid CanvasText;outline-offset:2px;box-shadow:none}.t-secondary,.t-label{color:CanvasText}}.shell{display:grid;block-size:100dvh;overflow:hidden;grid-template-areas:"header" "content" "nav";grid-template-rows:auto 1fr auto}.shell-header{grid-area:header;display:flex;align-items:center;gap:var(--gap);min-block-size:var(--ctl-h);padding-block:var(--sp-8);padding-inline:var(--pad);padding-block-start:calc(var(--sp-8) + env(safe-area-inset-top,0px));background:var(--bg)}.shell-content{grid-area:content;overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch}.shell-nav{grid-area:nav;display:flex;justify-content:space-evenly;align-items:stretch;gap:var(--sp-4);background:var(--surface);padding-block-end:env(safe-area-inset-bottom,0px);-webkit-user-select:none;user-select:none}.shell-nav>*{min-block-size:var(--tap-min);min-inline-size:var(--tap-min);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--sp-4);border:0;background:none;color:var(--text-muted);text-decoration:none;border-radius:var(--r-ctl);font:inherit;font-size:var(--fs-label);font-weight:var(--fw-label);cursor:pointer;-webkit-tap-highlight-color:transparent;transition:color var(--t-micro) var(--ease),background-color var(--t-micro) var(--ease)}.shell-nav>*:hover{color:var(--text)}.shell-nav>[aria-current]:not([aria-current=false]){color:var(--accent)}@media(min-width:768px){.shell{grid-template-areas:"nav header" "nav content";grid-template-rows:auto 1fr;grid-template-columns:auto 1fr}.shell-nav{flex-direction:column;justify-content:flex-start;padding-block:var(--pad);padding-inline:var(--sp-8);padding-block-end:var(--pad);inline-size:5rem}}.screen-stack{display:flex;flex-direction:column;gap:var(--gap);padding-block:var(--pad);padding-inline:var(--pad);inline-size:100%}@media(min-width:768px){.screen-stack{max-inline-size:calc(40rem + 2 * var(--pad));margin-inline:auto}}.screen-list{display:flex;flex-direction:column;min-block-size:100%}.screen-list>header{position:sticky;inset-block-start:0;z-index:1;background:var(--bg);padding-block:var(--sp-8);padding-inline:var(--pad)}.screen-split{display:grid;block-size:100%;overflow:hidden;grid-template-columns:1fr}.screen-split>*{overflow-y:auto;overscroll-behavior:contain}@media(max-width:899.98px){.screen-split>:last-child{display:none}.screen-split[data-show=detail]>:first-child{display:none}.screen-split[data-show=detail]>:last-child{display:block}}@media(min-width:900px){.screen-split{grid-template-columns:clamp(20rem,30%,24rem) 1fr}}.screen-center{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--gap);min-block-size:100%;padding-block:var(--pad);padding-inline:max(var(--pad),env(safe-area-inset-left,0px),env(safe-area-inset-right,0px))}.screen-center>*{inline-size:100%;max-inline-size:24rem}.stack{display:flex;flex-direction:column;gap:var(--gap)}.stack[data-align=start]{align-items:flex-start}.stack[data-align=center]{align-items:center}.row{display:flex;align-items:center;gap:var(--gap)}.row[data-align=start]{align-items:flex-start}.row[data-align=end]{align-items:flex-end}.row[data-align=between]{justify-content:space-between}.row[data-wrap=on]{flex-wrap:wrap}.stack[data-gap="4"],.row[data-gap="4"]{gap:var(--sp-4)}.stack[data-gap="8"],.row[data-gap="8"]{gap:var(--sp-8)}.stack[data-gap="12"],.row[data-gap="12"]{gap:var(--sp-12)}.stack[data-gap="16"],.row[data-gap="16"]{gap:var(--sp-16)}.stack[data-gap="20"],.row[data-gap="20"]{gap:var(--sp-20)}.stack[data-gap="24"],.row[data-gap="24"]{gap:var(--sp-24)}.stack[data-gap="32"],.row[data-gap="32"]{gap:var(--sp-32)}.stack[data-gap="40"],.row[data-gap="40"]{gap:var(--sp-40)}.stack[data-gap="48"],.row[data-gap="48"]{gap:var(--sp-48)}.grid{display:grid;gap:var(--sp-12);grid-template-columns:repeat(4,1fr)}.grid>*{grid-column:span 1}@media(max-width:767.98px){.grid>[data-span="2"]{grid-column:span 2}.grid>[data-span="3"]{grid-column:span 3}.grid>[data-span="4"],.grid>[data-span="5"],.grid>[data-span="6"],.grid>[data-span="7"],.grid>[data-span="8"],.grid>[data-span="9"],.grid>[data-span="10"],.grid>[data-span="11"],.grid>[data-span="12"]{grid-column:1 / -1}}@media(min-width:768px)and (max-width:1199.98px){.grid{grid-template-columns:repeat(8,1fr)}.grid>[data-span="2"]{grid-column:span 2}.grid>[data-span="3"]{grid-column:span 3}.grid>[data-span="4"]{grid-column:span 4}.grid>[data-span="5"]{grid-column:span 5}.grid>[data-span="6"]{grid-column:span 6}.grid>[data-span="7"]{grid-column:span 7}.grid>[data-span="8"],.grid>[data-span="9"],.grid>[data-span="10"],.grid>[data-span="11"],.grid>[data-span="12"]{grid-column:1 / -1}.grid>[data-span-md="1"]{grid-column:span 1}.grid>[data-span-md="2"]{grid-column:span 2}.grid>[data-span-md="3"]{grid-column:span 3}.grid>[data-span-md="4"]{grid-column:span 4}.grid>[data-span-md="5"]{grid-column:span 5}.grid>[data-span-md="6"]{grid-column:span 6}.grid>[data-span-md="7"]{grid-column:span 7}.grid>[data-span-md="8"],.grid>[data-span-md="9"],.grid>[data-span-md="10"],.grid>[data-span-md="11"],.grid>[data-span-md="12"]{grid-column:1 / -1}}@media(min-width:1200px){.grid{grid-template-columns:repeat(12,1fr)}.grid>[data-span="2"]{grid-column:span 2}.grid>[data-span="3"]{grid-column:span 3}.grid>[data-span="4"]{grid-column:span 4}.grid>[data-span="5"]{grid-column:span 5}.grid>[data-span="6"]{grid-column:span 6}.grid>[data-span="7"]{grid-column:span 7}.grid>[data-span="8"]{grid-column:span 8}.grid>[data-span="9"]{grid-column:span 9}.grid>[data-span="10"]{grid-column:span 10}.grid>[data-span="11"]{grid-column:span 11}.grid>[data-span="12"]{grid-column:1 / -1}.grid>[data-span-md="1"]{grid-column:span 1}.grid>[data-span-md="2"]{grid-column:span 2}.grid>[data-span-md="3"]{grid-column:span 3}.grid>[data-span-md="4"]{grid-column:span 4}.grid>[data-span-md="5"]{grid-column:span 5}.grid>[data-span-md="6"]{grid-column:span 6}.grid>[data-span-md="7"]{grid-column:span 7}.grid>[data-span-md="8"]{grid-column:span 8}.grid>[data-span-md="9"],.grid>[data-span-md="10"],.grid>[data-span-md="11"],.grid>[data-span-md="12"]{grid-column:1 / -1}.grid>[data-span-lg="1"]{grid-column:span 1}.grid>[data-span-lg="2"]{grid-column:span 2}.grid>[data-span-lg="3"]{grid-column:span 3}.grid>[data-span-lg="4"]{grid-column:span 4}.grid>[data-span-lg="5"]{grid-column:span 5}.grid>[data-span-lg="6"]{grid-column:span 6}.grid>[data-span-lg="7"]{grid-column:span 7}.grid>[data-span-lg="8"]{grid-column:span 8}.grid>[data-span-lg="9"]{grid-column:span 9}.grid>[data-span-lg="10"]{grid-column:span 10}.grid>[data-span-lg="11"]{grid-column:span 11}.grid>[data-span-lg="12"]{grid-column:1 / -1}}[data-outline] :is(.stack,.row,.grid,.screen-stack,.screen-list,.screen-split,.screen-center,.shell-header,.shell-nav,.shell-content),:is(.stack,.row,.grid,.screen-stack,.screen-list,.screen-split,.screen-center,.shell)[data-outline]{outline:1px dashed var(--text-muted);outline-offset:-1px}[data-outline] .grid>*,.grid[data-outline]>*{outline:1px dashed var(--accent);outline-offset:-1px}.grid[data-outline]:before,[data-outline] .grid:before{grid-column:1 / -1;font-size:var(--fs-label);font-weight:var(--fw-label);color:var(--accent);content:"4 columns"}@media(min-width:768px){.grid[data-outline]:before,[data-outline] .grid:before{content:"8 columns"}}@media(min-width:1200px){.grid[data-outline]:before,[data-outline] .grid:before{content:"12 columns"}}@media(forced-colors:active){.shell-header{border-block-end:1px solid CanvasText}.shell-nav{border-block-start:1px solid CanvasText}.screen-list>header{border-block-end:1px solid CanvasText}.shell-nav>[aria-current]:not([aria-current=false]){color:Highlight;text-decoration:underline}@media(min-width:768px){.shell-header{border-block-end:none}.shell-nav{border-block-start:none;border-inline-end:1px solid CanvasText}}}:root{--icon-chevron-down: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");--icon-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");--icon-loader: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 12a9 9 0 1 1-6.219-8.56'/%3E%3C/svg%3E");--icon-home: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'/%3E%3Cpath d='M9 22V12h6v10'/%3E%3C/svg%3E");--icon-search: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E");--icon-settings: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z'/%3E%3Ccircle cx='12' cy='12' r='3'/%3E%3C/svg%3E");--icon-user: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2'/%3E%3Ccircle cx='12' cy='7' r='4'/%3E%3C/svg%3E");--icon-bell: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9'/%3E%3Cpath d='M10.3 21a1.94 1.94 0 0 0 3.4 0'/%3E%3C/svg%3E");--icon-mail: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect width='20' height='16' x='2' y='4' rx='2'/%3E%3Cpath d='m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7'/%3E%3C/svg%3E");--icon-calendar: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 2v4'/%3E%3Cpath d='M16 2v4'/%3E%3Crect width='18' height='18' x='3' y='4' rx='2'/%3E%3Cpath d='M3 10h18'/%3E%3C/svg%3E");--icon-plus: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3Cpath d='M12 5v14'/%3E%3C/svg%3E");--icon-x: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 6 6 18'/%3E%3Cpath d='m6 6 12 12'/%3E%3C/svg%3E");--icon-chevron-right: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E");--icon-chevron-left: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m15 18-6-6 6-6'/%3E%3C/svg%3E");--icon-chevron-up: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m18 15-6-6-6 6'/%3E%3C/svg%3E");--icon-more-vertical: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='1'/%3E%3Ccircle cx='12' cy='5' r='1'/%3E%3Ccircle cx='12' cy='19' r='1'/%3E%3C/svg%3E");--icon-trash: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 6h18'/%3E%3Cpath d='M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6'/%3E%3Cpath d='M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2'/%3E%3C/svg%3E");--icon-heart: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.29 1.51 4.04 3 5.5l7 7Z'/%3E%3C/svg%3E");--icon-star: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26'/%3E%3C/svg%3E");--icon-share: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='18' cy='5' r='3'/%3E%3Ccircle cx='6' cy='12' r='3'/%3E%3Ccircle cx='18' cy='19' r='3'/%3E%3Cline x1='8.59' x2='15.42' y1='13.51' y2='17.49'/%3E%3Cline x1='15.41' x2='8.59' y1='6.51' y2='10.49'/%3E%3C/svg%3E");--icon-pencil: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 20h9'/%3E%3Cpath d='M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4Z'/%3E%3C/svg%3E");--icon-info: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 16v-4'/%3E%3Cpath d='M12 8h.01'/%3E%3C/svg%3E");--icon-alert-triangle: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3'/%3E%3Cpath d='M12 9v4'/%3E%3Cpath d='M12 17h.01'/%3E%3C/svg%3E");--icon-circle-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='m9 12 2 2 4-4'/%3E%3C/svg%3E");--icon-circle-x: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='m15 9-6 6'/%3E%3Cpath d='m9 9 6 6'/%3E%3C/svg%3E")}.icon{display:inline-block;inline-size:1.25em;block-size:1.25em;vertical-align:-.2em;flex-shrink:0;background:currentColor;-webkit-mask:var(--i) center / contain no-repeat;mask:var(--i) center / contain no-repeat}.icon[data-icon=home]{--i: var(--icon-home)}.icon[data-icon=search]{--i: var(--icon-search)}.icon[data-icon=settings]{--i: var(--icon-settings)}.icon[data-icon=user]{--i: var(--icon-user)}.icon[data-icon=bell]{--i: var(--icon-bell)}.icon[data-icon=mail]{--i: var(--icon-mail)}.icon[data-icon=calendar]{--i: var(--icon-calendar)}.icon[data-icon=plus]{--i: var(--icon-plus)}.icon[data-icon=x]{--i: var(--icon-x)}.icon[data-icon=check]{--i: var(--icon-check)}.icon[data-icon=chevron-up]{--i: var(--icon-chevron-up)}.icon[data-icon=chevron-down]{--i: var(--icon-chevron-down)}.icon[data-icon=chevron-left]{--i: var(--icon-chevron-left)}.icon[data-icon=chevron-right]{--i: var(--icon-chevron-right)}.icon[data-icon=more-vertical]{--i: var(--icon-more-vertical)}.icon[data-icon=trash]{--i: var(--icon-trash)}.icon[data-icon=heart]{--i: var(--icon-heart)}.icon[data-icon=star]{--i: var(--icon-star)}.icon[data-icon=share]{--i: var(--icon-share)}.icon[data-icon=pencil]{--i: var(--icon-pencil)}.icon[data-icon=info]{--i: var(--icon-info)}.icon[data-icon=alert-triangle]{--i: var(--icon-alert-triangle)}.icon[data-icon=circle-check]{--i: var(--icon-circle-check)}.icon[data-icon=circle-x]{--i: var(--icon-circle-x)}[dir=rtl] .icon[data-icon=chevron-right],[dir=rtl] .icon[data-icon=chevron-left]{transform:scaleX(-1)}.btn{position:relative;display:inline-flex;align-items:center;justify-content:center;gap:var(--sp-8);min-block-size:var(--ctl-h);min-inline-size:var(--tap-min);padding-inline:var(--sp-20);border:0;border-radius:var(--r-ctl);background:var(--surface-2);color:var(--text);font-size:var(--fs-control);font-weight:var(--fw-control);line-height:var(--lh-control);text-decoration:none;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background-color var(--t-micro) var(--ease),color var(--t-micro) var(--ease),transform var(--t-micro) var(--ease)}.btn:before{content:"";position:absolute;inset:calc(-1 * var(--sp-4))}.btn:hover{background:var(--surface-3);transform:translateY(-2px)}.btn:active{transform:scale(.97)}.btn[data-variant=primary]{background:var(--accent);color:var(--on-accent)}.btn[data-variant=primary]:hover{background:var(--accent-hover)}.btn[data-variant=accent]{background:var(--accent-2);color:var(--on-accent-2)}.btn[data-variant=accent]:hover{background:var(--accent-2-hover)}.btn[data-variant=ghost]{background:transparent}.btn[data-variant=ghost]:hover{background:var(--surface-2)}.btn[data-variant=danger]{background:var(--danger);color:var(--on-accent)}.btn[data-size=icon]{inline-size:var(--ctl-h);padding-inline:0}.btn:disabled{color:var(--text-faint);cursor:default}.btn:disabled:hover{background:var(--surface-2);transform:none}.btn[data-variant=primary]:disabled,.btn[data-variant=accent]:disabled,.btn[data-variant=danger]:disabled{background:var(--surface-2)}.btn[data-loading]{pointer-events:none;color:transparent}.btn[data-loading]:after{content:"";position:absolute;inset:0;margin:auto;inline-size:var(--sp-20);block-size:var(--sp-20);background:var(--text);-webkit-mask:var(--icon-loader) center / contain no-repeat;mask:var(--icon-loader) center / contain no-repeat;animation:mtui-spin var(--t-skeleton) linear infinite}.btn[data-variant=primary][data-loading]:after,.btn[data-variant=danger][data-loading]:after{background:var(--on-accent)}.btn[data-variant=accent][data-loading]:after{background:var(--on-accent-2)}@keyframes mtui-spin{to{transform:rotate(360deg)}}.card{background:var(--surface);border-radius:var(--r-card);padding:var(--pad)}a.card,button.card{position:relative;display:block;inline-size:100%;border:0;color:inherit;font:inherit;text-align:start;text-decoration:none;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:transform var(--t-lift) var(--ease)}a.card:before,button.card:before{content:"";position:absolute;inset:calc(-1 * var(--sp-8))}a.card:hover,button.card:hover{transform:translateY(-3px)}a.card:active,button.card:active{transform:scale(.98)}.field{display:flex;flex-direction:column;gap:var(--sp-8)}.field input,.field select,.field textarea{min-block-size:var(--field-h);padding-inline:var(--sp-16);border:0;border-radius:var(--r-input);background:var(--surface-2);color:var(--text);font-size:var(--fs-body);line-height:var(--lh-body);transition:background-color var(--t-micro) var(--ease)}.field input:hover,.field select:hover,.field textarea:hover{background:var(--surface-3)}.field textarea{min-block-size:calc(2 * var(--field-h));padding-block:var(--sp-12);resize:vertical}.field ::placeholder{color:var(--text-faint);opacity:1}.select{position:relative;display:block}.select select{appearance:none;inline-size:100%;padding-inline-end:var(--sp-40)}.select:after{content:"";position:absolute;inset-block:0;inset-inline-end:var(--sp-16);margin-block:auto;inline-size:var(--sp-16);block-size:var(--sp-16);background:var(--text-muted);-webkit-mask:var(--icon-chevron-down) center / contain no-repeat;mask:var(--icon-chevron-down) center / contain no-repeat;pointer-events:none}.field-hint,.field-error{font-size:var(--fs-secondary);line-height:var(--lh-secondary)}.field-hint{color:var(--text-muted)}.field-error{color:var(--danger-text);display:none}.field[data-invalid] input,.field[data-invalid] select,.field[data-invalid] textarea{background:var(--danger-tint)}.field[data-invalid] .field-error{display:block}.field[data-invalid] .field-hint{display:none}.switch,.checkbox,.radio{appearance:none;flex-shrink:0;margin:0;cursor:pointer;-webkit-tap-highlight-color:transparent}.switch{inline-size:var(--sp-48);block-size:var(--sp-24);border-radius:var(--r-ctl);background:var(--surface-3);position:relative;transition:background-color var(--t-micro) var(--ease)}.switch:before{content:"";position:absolute;inset-block-start:2px;inset-inline-start:2px;inline-size:var(--sp-20);block-size:var(--sp-20);border-radius:50%;background:var(--on-accent);transition:translate var(--t-knob) var(--spring)}.switch:checked{background:var(--accent)}.switch:checked:before{translate:var(--sp-24) 0}[dir=rtl] .switch:checked:before{translate:calc(-1 * var(--sp-24)) 0}.checkbox,.radio{inline-size:var(--sp-24);block-size:var(--sp-24);background:var(--surface-2);display:inline-flex;align-items:center;justify-content:center;transition:background-color var(--t-micro) var(--ease)}.checkbox:hover,.radio:hover{background:var(--surface-3)}.checkbox:checked,.radio:checked{background:var(--accent)}.checkbox{border-radius:min(var(--r-chip),33%)}.radio{border-radius:50%}.checkbox:before{content:"";inline-size:var(--sp-16);block-size:var(--sp-16);background:var(--on-accent);-webkit-mask:var(--icon-check) center / contain no-repeat;mask:var(--icon-check) center / contain no-repeat;transform:scale(0);transition:transform var(--t-knob) var(--spring)}.checkbox:checked:before{transform:scale(1)}.radio:before{content:"";inline-size:var(--sp-8);block-size:var(--sp-8);border-radius:50%;background:var(--on-accent);transform:scale(0);transition:transform var(--t-knob) var(--spring)}.radio:checked:before{transform:scale(1)}.badge{display:inline-flex;align-items:center;gap:var(--sp-4);min-block-size:var(--sp-20);padding-inline:var(--sp-8);border-radius:var(--r-chip);background:var(--surface-2);color:var(--text-muted);font-size:var(--fs-label);font-weight:var(--fw-label)}.chip{display:inline-flex;align-items:center;gap:var(--sp-4);min-block-size:var(--sp-32);padding-inline:var(--sp-12);border:0;border-radius:var(--r-chip);background:var(--surface-2);color:var(--text);font-size:var(--fs-label);font-weight:var(--fw-label);-webkit-tap-highlight-color:transparent}button.chip{cursor:pointer;transition:background-color var(--t-micro) var(--ease),color var(--t-micro) var(--ease),transform var(--t-micro) var(--ease)}button.chip:hover{background:var(--surface-3)}button.chip:active{transform:scale(.96)}.chip[aria-pressed=true],.chip[data-selected]{background:var(--accent-tint);color:var(--accent-text)}.chip-x{display:inline-flex;align-items:center;justify-content:center;border:0;padding:0;background:none;color:inherit;font:inherit;cursor:pointer;position:relative}.chip-x:after{content:"";position:absolute;inset:calc(-1 * var(--sp-12))}[data-tint=rose]{background:var(--tint-rose-bg);color:var(--tint-rose-text)}[data-tint=sky]{background:var(--tint-sky-bg);color:var(--tint-sky-text)}[data-tint=mint]{background:var(--tint-mint-bg);color:var(--tint-mint-text)}[data-tint=butter]{background:var(--tint-butter-bg);color:var(--tint-butter-text)}[data-tint=lavender]{background:var(--tint-lavender-bg);color:var(--tint-lavender-text)}[data-status=success]{background:var(--success-tint);color:var(--success-text)}[data-status=warning]{background:var(--warning-tint);color:var(--warning-text)}[data-status=danger]{background:var(--danger-tint);color:var(--danger-text)}.avatar{display:inline-flex;align-items:center;justify-content:center;inline-size:var(--sp-40);block-size:var(--sp-40);border-radius:50%;overflow:hidden;flex-shrink:0;background:var(--surface-2);color:var(--text-muted);font-size:var(--fs-label);font-weight:var(--fw-label)}.avatar[data-size=sm]{inline-size:var(--sp-32);block-size:var(--sp-32)}.avatar[data-size=lg]{inline-size:var(--sp-48);block-size:var(--sp-48)}.avatar img{inline-size:100%;block-size:100%;object-fit:cover}.avatar-stack{display:inline-flex}.avatar-stack .avatar{box-shadow:var(--ring-avatar)}.avatar-stack .avatar+.avatar{margin-inline-start:calc(-1 * var(--sp-8))}.item{display:flex;align-items:center;gap:var(--gap);min-block-size:var(--row-h);padding-block:var(--sp-8);padding-inline:var(--pad);color:inherit;text-decoration:none}a.item,button.item{border:0;border-radius:var(--r-input);background:none;font:inherit;text-align:start;inline-size:100%;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background-color var(--t-micro) var(--ease),transform var(--t-micro) var(--ease)}a.item:hover,button.item:hover{background:var(--surface-2);background:color-mix(in srgb,var(--surface-2) 50%,transparent)}a.item:active,button.item:active{transform:scale(.98)}.item-text{flex:1;min-inline-size:0;display:flex;flex-direction:column;gap:2px}.item-title{font-size:var(--fs-control);font-weight:var(--fw-control);line-height:var(--lh-control)}.item-sub{color:var(--text-muted);font-size:var(--fs-secondary);line-height:var(--lh-secondary)}.item-title,.item-sub{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.item-meta{flex-shrink:0;display:flex;flex-direction:column;align-items:flex-end;gap:var(--sp-4);color:var(--text-muted);font-size:var(--fs-label);text-align:end}[dir=rtl] .chevron{transform:scaleX(-1)}.segmented{position:relative;display:flex;border:0;margin:0;padding:var(--sp-4);border-radius:var(--r-ctl);background:var(--surface-2)}.segmented label{flex:1;display:block;position:relative}.segmented input{appearance:none;position:absolute;inset:0;margin:0;cursor:pointer;border-radius:var(--r-ctl)}.segmented span{position:relative;pointer-events:none;display:flex;align-items:center;justify-content:center;min-block-size:calc(var(--ctl-h) - 2 * var(--sp-4));padding-inline:var(--sp-12);border-radius:var(--r-ctl);color:var(--text-muted);font-size:var(--fs-control);font-weight:var(--fw-control);transition:background-color var(--t-micro) var(--ease),color var(--t-micro) var(--ease)}.segmented input:checked+span{background:var(--surface);color:var(--text)}.segmented input:focus-visible+span{box-shadow:var(--ring-focus)}@supports selector(:has(*)){.segmented input:checked+span{background:transparent}.segmented:before{content:"";position:absolute;inset-block:var(--sp-4);inset-inline-start:var(--sp-4);inline-size:calc((100% - 2 * var(--sp-4)) / var(--seg-count, 1));border-radius:var(--r-ctl);background:var(--surface);translate:calc(var(--seg-index, 0) * 100%) 0;transition:translate var(--t-tab) var(--spring)}[dir=rtl] .segmented:before{translate:calc(var(--seg-index, 0) * -100%) 0}.segmented:has(>label:nth-child(2):last-child){--seg-count: 2}.segmented:has(>label:nth-child(3):last-child){--seg-count: 3}.segmented:has(>label:nth-child(4):last-child){--seg-count: 4}.segmented:has(>label:nth-child(5):last-child){--seg-count: 5}.segmented:has(>label:nth-child(1) input:checked){--seg-index: 0}.segmented:has(>label:nth-child(2) input:checked){--seg-index: 1}.segmented:has(>label:nth-child(3) input:checked){--seg-index: 2}.segmented:has(>label:nth-child(4) input:checked){--seg-index: 3}.segmented:has(>label:nth-child(5) input:checked){--seg-index: 4}}.accordion{background:var(--surface);border-radius:var(--r-card);overflow:hidden}.accordion summary{display:flex;align-items:center;justify-content:space-between;gap:var(--gap);min-block-size:var(--ctl-h);padding-block:var(--sp-8);padding-inline:var(--pad);font-size:var(--fs-control);font-weight:var(--fw-control);border-radius:var(--r-card);cursor:pointer;list-style:none;-webkit-tap-highlight-color:transparent;transition:background-color var(--t-micro) var(--ease)}.accordion summary::-webkit-details-marker{display:none}.accordion summary:hover{background:var(--surface-2)}.accordion summary:after{content:"";flex-shrink:0;inline-size:var(--sp-16);block-size:var(--sp-16);background:var(--text-muted);-webkit-mask:var(--icon-chevron-down) center / contain no-repeat;mask:var(--icon-chevron-down) center / contain no-repeat;transition:transform var(--t-knob) var(--spring)}.accordion:not([data-expanded])[open] summary:after{transform:rotate(180deg)}.accordion[data-expanded=true] summary:after{transform:rotate(180deg)}.accordion-body{padding-block:var(--sp-4) var(--pad);padding-inline:var(--pad)}.code{background:var(--surface-2);border-radius:var(--r-input);padding:var(--pad);overflow-x:auto;font-family:var(--font-mono);font-size:var(--fs-code);line-height:var(--lh-code);direction:ltr;unicode-bidi:isolate;text-align:start}.code-inline{background:var(--surface-2);border-radius:min(var(--r-chip),33%);padding-inline:var(--sp-4);font-family:var(--font-mono);font-size:var(--fs-code);direction:ltr;unicode-bidi:isolate}.skeleton{display:block;position:relative;overflow:hidden;background:var(--surface-2);border-radius:var(--r-input);min-block-size:var(--sp-16)}.skeleton[data-shape=title]{min-block-size:var(--sp-24);max-inline-size:60%}.skeleton[data-shape=text]{border-radius:var(--r-chip)}.skeleton[data-shape=circle]{inline-size:var(--sp-40);block-size:var(--sp-40);min-block-size:var(--sp-40);border-radius:50%;flex-shrink:0}.skeleton[data-shape=row]{min-block-size:var(--row-h)}.skeleton:after{content:"";position:absolute;inset-block:0;inset-inline-start:0;inline-size:65%;background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--surface-3) 70%,transparent),transparent);animation:mtui-sheen var(--t-skeleton) linear infinite}[dir=rtl] .skeleton:after{background:linear-gradient(-90deg,transparent,color-mix(in srgb,var(--surface-3) 70%,transparent),transparent);animation-name:mtui-sheen-rtl}@keyframes mtui-sheen{0%{transform:translate(-100%)}to{transform:translate(215%)}}@keyframes mtui-sheen-rtl{0%{transform:translate(100%)}to{transform:translate(-215%)}}@media(prefers-reduced-motion:reduce){.skeleton:after{animation:none;inset-inline:25%;inline-size:50%}}.empty{display:flex;flex-direction:column;align-items:center;gap:var(--sp-12);text-align:center;padding-block:var(--sp-32);padding-inline:var(--pad);max-inline-size:24rem;margin-inline:auto}.empty-icon{display:flex;align-items:center;justify-content:center;inline-size:var(--sp-48);block-size:var(--sp-48);border-radius:50%;background:var(--accent-tint);color:var(--accent-text)}.alert{display:flex;gap:var(--sp-12);padding:var(--sp-16);border-radius:var(--r-card);background:var(--surface-2);color:var(--text);font-size:var(--fs-secondary);line-height:var(--lh-secondary)}.alert>svg{flex-shrink:0}.alert-title{display:block;font-size:var(--fs-control);font-weight:var(--fw-control);line-height:var(--lh-control)}.alert p{margin:0}.dialog{margin:auto;border:0;padding:var(--pad);background:var(--surface);color:var(--text);border-radius:var(--r-card);inline-size:min(24rem,calc(100vw - 2 * var(--pad)));opacity:1;transform:translateY(0) scale(1);transition:opacity var(--t-dialog) var(--ease),transform var(--t-dialog) var(--spring),overlay var(--t-dialog) allow-discrete,display var(--t-dialog) allow-discrete}.dialog:not([open]){opacity:0;transform:translateY(var(--sp-16)) scale(.96)}@starting-style{.dialog[open]{opacity:0;transform:translateY(var(--sp-16)) scale(.96)}}.dialog::backdrop{background:transparent;transition:background-color var(--t-popover) var(--ease),overlay var(--t-popover) allow-discrete,display var(--t-popover) allow-discrete}.dialog[open]::backdrop{background:var(--scrim)}@starting-style{.dialog[open]::backdrop{background:transparent}}.menu{border:1px solid var(--surface-3);padding:var(--sp-8);background:var(--surface);color:var(--text);border-radius:var(--r-card)}.menu:popover-open{animation:mtui-menu-pop var(--t-popover) var(--spring),mtui-menu-fade var(--t-micro) var(--ease)}@keyframes mtui-menu-pop{0%{transform:translateY(calc(-1 * var(--sp-4))) scale(.98)}}@keyframes mtui-menu-fade{0%{opacity:0}}.menu-item{display:flex;align-items:center;gap:var(--sp-12);inline-size:100%;min-block-size:var(--tap-min);padding-inline:var(--sp-12);border:0;border-radius:var(--r-input);background:none;color:inherit;font-size:var(--fs-control);font-weight:var(--fw-control);text-align:start;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background-color var(--t-micro) var(--ease)}.menu-item:hover{background:var(--surface-2);background:color-mix(in srgb,var(--surface-2) 50%,transparent)}.menu-item:active{transform:scale(.98)}.menu-item[data-danger]{color:var(--danger-text)}x-tabs{display:flex;flex-direction:column;gap:var(--gap)}x-toast{position:fixed;inset-block-start:0;inset-inline:0;z-index:10;display:flex;flex-direction:column;align-items:center;gap:var(--sp-8);padding-block-start:calc(var(--sp-16) + env(safe-area-inset-top,0px));pointer-events:none}.toast{pointer-events:auto;display:flex;align-items:center;gap:var(--sp-12);min-block-size:var(--ctl-h);padding-inline:var(--sp-20);max-inline-size:calc(100vw - 2 * var(--pad));background:var(--inverse);color:var(--on-inverse);border-radius:var(--r-ctl);font-size:var(--fs-control);font-weight:var(--fw-control);animation:mtui-toast-in var(--t-toast) var(--spring)}.toast[data-leaving]{animation:mtui-toast-out var(--t-toast) var(--spring) forwards}@keyframes mtui-toast-in{0%{transform:translateY(calc(-6 * var(--sp-48))) scale(.92)}}@keyframes mtui-toast-out{to{transform:translateY(calc(-6 * var(--sp-48))) scale(.92)}}.toast-action{border:0;background:none;color:inherit;font:inherit;font-weight:var(--fw-card);padding-inline:var(--sp-4);min-block-size:var(--tap-min);cursor:pointer}.btn,.chip,.chip-x,a.item,button.item,.segmented,.accordion summary,.avatar,.avatar-stack,.badge,.field .t-label,.empty-icon,.menu-item,.toast{-webkit-user-select:none;user-select:none}label:has(.switch),label:has(.checkbox),label:has(.radio){-webkit-user-select:none;user-select:none}.select-trigger{position:relative;display:flex;align-items:center;inline-size:100%;min-block-size:var(--field-h);padding-inline:var(--sp-16);padding-inline-end:var(--sp-40);border:0;border-radius:var(--r-input);background:var(--surface-2);color:var(--text);font-size:var(--fs-body);line-height:var(--lh-body);text-align:start;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background-color var(--t-micro) var(--ease)}.select-trigger:hover{background:var(--surface-3)}.select-trigger:after{content:"";position:absolute;inset-block:0;inset-inline-end:var(--sp-16);margin-block:auto;inline-size:var(--sp-16);block-size:var(--sp-16);background:var(--text-muted);-webkit-mask:var(--icon-chevron-down) center / contain no-repeat;mask:var(--icon-chevron-down) center / contain no-repeat;transition:transform var(--t-micro) var(--ease)}.select-trigger[aria-expanded=true]:after{transform:rotate(180deg)}.select-trigger:disabled{color:var(--text-faint);cursor:default}.select-panel{max-block-size:18rem;overflow-y:auto}.select-option[aria-selected=true]{background:var(--accent-tint);color:var(--accent-text)}.select-option:disabled{color:var(--text-faint);cursor:default}.datepicker-panel{padding:var(--sp-8);inline-size:20rem}.datepicker-header{display:flex;align-items:center;gap:var(--sp-8);padding:var(--sp-8)}.datepicker-header-label{flex:1;border:0;background:none;border-radius:var(--r-input);padding-block:var(--sp-4);text-align:center;font:inherit;font-size:var(--fs-control);font-weight:var(--fw-control);color:inherit;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background-color var(--t-micro) var(--ease)}.datepicker-header-label:hover{background:var(--surface-2)}.datepicker-nav{display:flex;align-items:center;justify-content:center;inline-size:var(--tap-min);block-size:var(--tap-min);border:0;border-radius:50%;background:none;color:var(--text-muted);cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background-color var(--t-micro) var(--ease)}.datepicker-nav:hover{background:var(--surface-2)}.datepicker-nav:after{content:"";inline-size:var(--sp-16);block-size:var(--sp-16);background:currentColor;-webkit-mask:var(--icon-chevron-down) center / contain no-repeat;mask:var(--icon-chevron-down) center / contain no-repeat;transform:rotate(90deg)}.datepicker-nav[data-dir=next]:after{transform:rotate(-90deg)}[dir=rtl] .datepicker-nav:after{transform:rotate(-90deg)}[dir=rtl] .datepicker-nav[data-dir=next]:after{transform:rotate(90deg)}.datepicker-weekdays:not([hidden]),.datepicker-grid[data-view=days]{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}.datepicker-grid[data-view=months]{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--sp-8);padding-block:var(--sp-8)}.datepicker-grid[data-view=years]{display:flex;flex-direction:column;gap:2px;max-block-size:14rem;overflow-y:auto;scrollbar-width:thin}.datepicker-weekdays>span{display:flex;align-items:center;justify-content:center;block-size:var(--sp-32);color:var(--text-muted);font-size:var(--fs-label);font-weight:var(--fw-label)}.datepicker-day{display:flex;align-items:center;justify-content:center;aspect-ratio:1;border:0;border-radius:50%;background:none;color:var(--text);font-size:var(--fs-secondary);cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background-color var(--t-micro) var(--ease)}.datepicker-day:hover{background:var(--surface-2)}.datepicker-day[data-today]{color:var(--accent-text);font-weight:var(--fw-control)}.datepicker-day[aria-selected=true]{background:var(--accent);color:var(--on-accent)}.datepicker-day:disabled{color:var(--text-faint);cursor:default;pointer-events:none}.datepicker-day[data-outside]{color:var(--text-faint)}.datepicker-month{aspect-ratio:auto;min-block-size:var(--tap-min);border-radius:var(--r-input);font-size:var(--fs-control);font-weight:var(--fw-control)}.datepicker-year{aspect-ratio:auto;inline-size:100%;min-block-size:var(--tap-min);border-radius:var(--r-input);font-size:var(--fs-control);font-weight:var(--fw-control);flex-shrink:0}.datepicker-footer{display:flex;justify-content:center;padding-block-start:var(--sp-8)}.swatches-trigger{position:relative;display:flex;align-items:center;gap:var(--sp-12);inline-size:100%;min-block-size:var(--field-h);padding-inline:var(--sp-16);border:0;border-radius:var(--r-input);background:var(--surface-2);color:var(--text);font-size:var(--fs-body);cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background-color var(--t-micro) var(--ease)}.swatches-trigger:hover{background:var(--surface-3)}.swatches-trigger-swatch{inline-size:var(--sp-24);block-size:var(--sp-24);border-radius:50%;flex-shrink:0}.swatches-panel{padding:var(--sp-12)}.swatches-panel:popover-open{display:grid;grid-template-columns:repeat(5,1fr);gap:var(--sp-8)}.swatch{position:relative;inline-size:var(--sp-32);block-size:var(--sp-32);border:0;border-radius:50%;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:transform var(--t-micro) var(--ease)}.swatch:hover{transform:scale(1.08)}.swatch[aria-checked=true]{box-shadow:0 0 0 2px var(--surface),0 0 0 4px currentColor}.swatch:after{content:"";position:absolute;inset:0;margin:auto;inline-size:60%;block-size:60%;background:var(--swatch-check-color, var(--on-accent));-webkit-mask:var(--icon-check) center / contain no-repeat;mask:var(--icon-check) center / contain no-repeat;opacity:0;transition:opacity var(--t-micro) var(--ease)}.swatch[aria-checked=true]:after{opacity:1}x-contextmenu{display:contents}x-pull-refresh{display:block;block-size:100%;overflow:hidden}x-pull-refresh>.screen-list,x-pull-refresh>[data-pull-scroll]{block-size:100%;overflow-y:auto;-webkit-user-select:none;user-select:none}.pull-indicator{position:absolute;inset-inline:0;inset-block-start:0;display:flex;align-items:center;justify-content:center;block-size:var(--sp-48);margin-block-start:calc(-1 * var(--sp-48));color:var(--text-muted);pointer-events:none}.pull-indicator:after{content:"";inline-size:var(--sp-20);block-size:var(--sp-20);background:currentColor;-webkit-mask:var(--icon-loader) center / contain no-repeat;mask:var(--icon-loader) center / contain no-repeat}.pull-indicator[data-spinning]:after{animation:mtui-spin var(--t-skeleton) linear infinite}x-theme{display:block}.theme-group+.theme-group{margin-block-start:var(--gap)}.theme-group>.t-label{display:block;margin-block-end:var(--sp-8);color:var(--text-muted)}.theme-accents{display:flex;gap:var(--sp-8);flex-wrap:wrap}.theme-accent{position:relative;display:grid;place-items:center;inline-size:var(--tap-min);block-size:var(--tap-min);cursor:pointer;-webkit-tap-highlight-color:transparent}.theme-accent input{appearance:none;position:absolute;inset:0;margin:0;cursor:pointer;border-radius:50%}.theme-accent-dot{position:relative;inline-size:var(--sp-32);block-size:var(--sp-32);border-radius:50%;background:var(--dot);pointer-events:none;transition:transform var(--t-micro) var(--ease)}.theme-accent:hover .theme-accent-dot{transform:translateY(-2px)}.theme-accent input:active+.theme-accent-dot{transform:scale(.96)}.theme-accent input:focus-visible+.theme-accent-dot{box-shadow:var(--ring-focus)}.theme-accent input:checked+.theme-accent-dot:after{content:"";position:absolute;inset:22%;background:var(--on-accent);-webkit-mask:var(--icon-check) center / contain no-repeat;mask:var(--icon-check) center / contain no-repeat}.select-trigger,.select-option,.datepicker-day,.datepicker-nav,.datepicker-header-label,.swatches-trigger,.swatch,x-contextmenu,.theme-accent{-webkit-user-select:none;user-select:none}@media(forced-colors:active){.btn,.chip,.badge,.avatar,.segmented,.alert,.card,.field input,.field select,.field textarea,.switch,.checkbox,.radio,.accordion,.code,.code-inline,.skeleton,.empty-icon{border:1px solid ButtonBorder}.item{border-block-end:1px solid CanvasText}.switch:before,.radio:checked:before{background:ButtonText}.switch:checked,.checkbox:checked,.radio:checked{background:SelectedItem}.segmented input:checked+span{border:1px solid ButtonBorder}.segmented:before{display:none}.btn[data-loading]:after,.select:after,.accordion summary:after,.checkbox:before{forced-color-adjust:none;background:ButtonText}.checkbox:checked:before{background:SelectedItemText}.skeleton:after{display:none}.dialog,.menu,.menu-item,.toast{border:1px solid CanvasText}.select-trigger,.swatches-trigger,.datepicker-panel,.datepicker-day,.swatch{border:1px solid ButtonBorder}.select-trigger:after,.datepicker-nav:after,.pull-indicator:after{forced-color-adjust:none;background:ButtonText}.select-option[aria-selected=true],.datepicker-day[aria-selected=true]{background:SelectedItem}.swatch[aria-checked=true]{box-shadow:none;outline:2px solid ButtonText}.swatch:after{forced-color-adjust:none;background:ButtonText}.theme-accent-dot{forced-color-adjust:none;border:1px solid ButtonBorder}.theme-accent input:checked+.theme-accent-dot{outline:2px solid ButtonText}.theme-accent input:checked+.theme-accent-dot:after{background:ButtonText}}
|
package/dist/mtui.min.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(){"use strict";function x(){const y=getComputedStyle(document.documentElement).getPropertyValue("--t-lift").trim();return parseFloat(y)||0}document.addEventListener("click",y=>{const v=y.target.closest(".accordion > summary");if(!v)return;const i=v.parentElement;if("animating"in i.dataset){y.preventDefault();return}const c=x();if(c===0)return;const o=i.querySelector(":scope > .accordion-body");if(!o)return;y.preventDefault();const a=!i.open;i.dataset.animating="",i.dataset.expanded=a?"true":"false",a&&(i.open=!0);const s=getComputedStyle(o),p=s.paddingBlockStart,l=s.paddingBlockEnd,b=o.scrollHeight,f=getComputedStyle(document.documentElement).getPropertyValue("--ease").trim()||"ease",u={blockSize:`${b}px`,paddingBlockStart:p,paddingBlockEnd:l},n={blockSize:"0px",paddingBlockStart:"0px",paddingBlockEnd:"0px"};o.style.overflow="hidden";const e=o.animate(a?[n,u]:[u,n],{duration:c,easing:f});e.onfinish=()=>{o.style.blockSize="",o.style.paddingBlockStart="",o.style.paddingBlockEnd="",o.style.overflow="",delete i.dataset.animating,a||(i.open=!1)}})})(),(function(){"use strict";const x="mtui-feedback-muted",y={tick:{wave:"sine",steps:[880],duration:.05,peak:.04},"toggle-on":{wave:"sine",steps:[520,784],duration:.09,peak:.05,haptic:8},"toggle-off":{wave:"sine",steps:[784,520],duration:.09,peak:.05,haptic:8},success:{wave:"sine",steps:[660,880],duration:.14,peak:.05,haptic:8},error:{wave:"triangle",steps:[233],duration:.16,peak:.05,haptic:[20,40,20]}};function v(){try{return localStorage.getItem(x)==="1"}catch{return!1}}function i(n){try{localStorage.setItem(x,n?"1":"0")}catch{}}let c=null;function o(){if(c)return c;const n=window.AudioContext||window.webkitAudioContext;return c=n?new n:null,c}function a(n){const e=o();if(!e)return;e.state==="suspended"&&e.resume().catch(()=>{});const t=e.currentTime,r=e.createOscillator(),d=e.createGain(),g=e.createBiquadFilter();r.type=n.wave;const m=n.steps,h=n.duration/m.length;m.forEach((S,F)=>r.frequency.setValueAtTime(S,t+F*h)),g.type="lowpass",g.frequency.setValueAtTime(Math.max(...m)*3,t),g.Q.setValueAtTime(.7,t);const k=Math.min(n.peak||.05,.06);d.gain.setValueAtTime(1e-4,t),d.gain.exponentialRampToValueAtTime(k,t+.004),d.gain.exponentialRampToValueAtTime(1e-4,t+n.duration),d.gain.setValueAtTime(0,t+n.duration+.005),r.connect(g).connect(d).connect(e.destination),r.start(t),r.stop(t+n.duration+.02),r.addEventListener("ended",()=>{r.disconnect(),g.disconnect(),d.disconnect()})}function s(n){if(typeof navigator.vibrate=="function")try{navigator.vibrate(n)}catch{}}function p(n){const e=y[n];!e||v()||(a(e),e.haptic&&s(e.haptic))}window.mtui=Object.assign(window.mtui||{},{feedback:{play:p,get muted(){return v()},set muted(n){i(!!n)}}}),document.addEventListener("change",n=>{n.target.matches(".switch[data-feedback], .checkbox[data-feedback], .radio[data-feedback]")&&p(n.target.checked?"toggle-on":"toggle-off")}),document.addEventListener("click",n=>{const e=n.target.closest("button[data-feedback], .btn[data-feedback]");e&&p(e.getAttribute("data-feedback")||"success")});const l='.toast[data-kind], [data-feedback][data-status="danger"]',b=new WeakSet;function f(n){if(n.nodeType!==1)return;(n.matches(l)?[n]:[]).concat([...n.querySelectorAll(l)]).forEach(t=>{b.has(t)||(b.add(t),p(t.classList.contains("toast")?t.dataset.kind:"error"))})}function u(){new MutationObserver(n=>{n.forEach(e=>e.addedNodes.forEach(f))}).observe(document.body,{childList:!0,subtree:!0})}document.body?u():document.addEventListener("DOMContentLoaded",u,{once:!0})})(),(function(){"use strict";function x(i,c){const o=parseFloat(getComputedStyle(document.documentElement).getPropertyValue("--sp-8"))||8,a=c.getBoundingClientRect(),s=i.getBoundingClientRect(),p=getComputedStyle(i).direction==="rtl";let l=a.bottom+o;l+s.height>window.innerHeight-o&&(l=Math.max(o,a.top-s.height-o));let b=p?a.right-s.width:a.left;b=Math.min(Math.max(o,b),window.innerWidth-s.width-o),i.style.position="fixed",i.style.top=`${Math.round(l)}px`,i.style.left=`${Math.round(b)}px`,i.style.margin="0"}let y=null;function v(){y&&(cancelAnimationFrame(y.raf),window.removeEventListener("scroll",y.onScroll,!0),window.removeEventListener("resize",y.onScroll),y=null)}document.addEventListener("toggle",i=>{const c=i.target;if(!(c instanceof HTMLElement)||!c.matches(".menu[popover]"))return;if(i.newState!=="open"){y&&y.menu===c&&v();return}const o=document.querySelector(`[popovertarget="${c.id}"]`);if(!o)return;y&&v(),x(c,o);let a=!1;const s=()=>{a||(a=!0,y.raf=requestAnimationFrame(()=>{a=!1,x(c,o)}))};y={menu:c,trigger:o,raf:0,onScroll:s},window.addEventListener("scroll",s,!0),window.addEventListener("resize",s)},!0)})(),(function(){"use strict";if(customElements.get("x-pull-refresh"))return;const x=64,y=96;class v extends HTMLElement{connectedCallback(){if(this._built)return;const c=this.querySelector(".screen-list, [data-pull-scroll]");c&&(this._built=!0,this._build(c))}_build(c){c.style.position="relative",c.style.overscrollBehaviorY="contain";const o=document.createElement("div");o.className="pull-indicator",c.prepend(o);const a=()=>{const d=getComputedStyle(document.documentElement).getPropertyValue("--t-lift").trim();return(parseFloat(d)||0)===0};let s=0,p=!1,l=!1,b=null,f=0;const u=d=>{f=d,o.style.transform=`translateY(${d}px) rotate(${d*3}deg)`};c.addEventListener("pointerdown",d=>{l||c.scrollTop>0||!d.isPrimary||(s=d.clientY,b=d.pointerId,document.addEventListener("pointermove",n),document.addEventListener("pointerup",e),document.addEventListener("pointercancel",e))});function n(d){if(d.pointerId!==b)return;const g=d.clientY-s;if(g<=0){p=!1,u(0);return}p=!0,d.preventDefault(),u(Math.min(g*.5,y))}function e(){document.removeEventListener("pointermove",n),document.removeEventListener("pointerup",e),document.removeEventListener("pointercancel",e),b=null,p&&(p=!1,f>=x?r():t())}function t(){o.style.transition=a()?"none":"transform var(--t-knob) var(--spring)",u(0),o.addEventListener("transitionend",function d(){o.style.transition="",o.removeEventListener("transitionend",d)})}function r(){l=!0,o.style.transition=a()?"none":"transform var(--t-knob) var(--spring)",u(x*.6),o.dataset.spinning="";let d=!1;const g=()=>{d||(d=!0,delete o.dataset.spinning,l=!1,t())};c.dispatchEvent(new CustomEvent("refresh",{bubbles:!0,detail:{done:g}})),setTimeout(g,15e3)}}}customElements.define("x-pull-refresh",v)})(),(function(){"use strict";const x=e=>Math.min(1,Math.max(0,e)),y=e=>Number(e.toFixed(3)),v=e=>Number(e.toFixed(1));function i(e){if(typeof e!="string")return null;let t=e.trim().replace(/^#/,"");return t.length===3&&(t=t.split("").map(r=>r+r).join("")),/^[0-9a-fA-F]{6}$/.test(t)?"#"+t.toLowerCase():null}function c(e){const t=i(e);if(!t)return null;const r=_=>{const E=_/255;return E<=.04045?E/12.92:Math.pow((E+.055)/1.055,2.4)},d=r(parseInt(t.slice(1,3),16)),g=r(parseInt(t.slice(3,5),16)),m=r(parseInt(t.slice(5,7),16)),h=Math.cbrt(.4122214708*d+.5363325363*g+.0514459929*m),k=Math.cbrt(.2119034982*d+.6806995451*g+.1073969566*m),S=Math.cbrt(.0883024619*d+.2817188376*g+.6299787005*m),F=.2104542553*h+.793617785*k-.0040720468*S,w=1.9779984951*h-2.428592205*k+.4505937099*S,q=.0259040371*h+.7827717662*k-.808675766*S;let D=Math.atan2(q,w)*180/Math.PI;return D<0&&(D+=360),{L:F,C:Math.sqrt(w*w+q*q),H:D}}const o=e=>`oklch(${v(e.L*100)}% ${y(e.C)} ${Math.round(e.H)})`,a=(e,t,r)=>({L:x(e.L+Math.sign(t-e.L||1)*r),C:e.C,H:e.H});function s(e,t,r){let d=t.H-e.H;return d>180&&(d-=360),d<-180&&(d+=360),{L:e.L+(t.L-e.L)*r,C:e.C+(t.C-e.C)*r,H:e.H+d*r}}const p=(e,t)=>t?{L:.3,C:.35*e.C,H:e.H}:{L:.92,C:Math.min(.32*e.C,.05),H:e.H},l=["--bg","--surface","--surface-2","--surface-3","--text","--text-muted","--text-faint","--accent","--accent-hover","--accent-text","--accent-tint","--on-accent"];function b(e,t){const r=document.documentElement,d=t==="dark";r.setAttribute("data-theme",d?"dark":"light"),l.forEach(C=>r.style.removeProperty(C));const g=e||{},m=i(g.bg_color)||i(g.section_bg_color)||i(g.secondary_bg_color),h=i(g.secondary_bg_color),k=h&&h!==m?h:null,S=i(g.text_color);if(!m||!S)return;const F=c(m),w=c(S),q=k?c(k):{L:x(F.L-.05),C:F.C,H:F.H},D=i(g.hint_color)||i(g.subtitle_text_color),_=D?c(D):s(w,q,.45),E=(C,$)=>r.style.setProperty(C,$);E("--bg",k||o(q)),E("--surface",m),E("--surface-2",o(a(F,w.L,.035))),E("--surface-3",o(a(F,w.L,.075))),E("--text",S),E("--text-muted",D||o(_)),E("--text-faint",o(s(_,q,.45)));const M=i(g.button_color);if(M){const C=c(M);r.setAttribute("data-accent","custom"),E("--accent",M),E("--on-accent",i(g.button_text_color)||"#FFFFFF"),E("--accent-hover",o({L:x(C.L-.05),C:C.C,H:C.H})),E("--accent-text",i(g.link_color)||i(g.accent_text_color)||M),E("--accent-tint",o(p(C,d)))}else r.removeAttribute("data-accent")}function f(){return window.Telegram&&window.Telegram.WebApp||null}function u(){const e=f();return e?(b(e.themeParams||{},e.colorScheme),!0):!1}window.mtui=Object.assign(window.mtui||{},{telegram:{sync:u,apply:b}});const n=f();n&&(u(),typeof n.onEvent=="function"&&n.onEvent("themeChanged",u))})(),(function(){"use strict";if(customElements.get("x-colorswatches"))return;let x=0;function y(i){const c=i.replace("#",""),[o,a,s]=[0,2,4].map(p=>{const l=parseInt(c.slice(p,p+2),16)/255;return l<=.04045?l/12.92:((l+.055)/1.055)**2.4});return .2126*o+.7152*a+.0722*s}class v extends HTMLElement{connectedCallback(){if(this._built)return;const c=this.querySelector('input[type="color"]');c&&(this._built=!0,this._build(c))}_build(c){const o=`x-swatches-panel-${++x}`,a=this.querySelector(".t-label")?.textContent.trim(),s=(this.dataset.colors||"").split(",").map(t=>t.trim()).filter(Boolean);if(!s.length)return;c.setAttribute("tabindex","-1"),c.setAttribute("aria-hidden","true"),c.style.position="absolute",c.style.opacity="0",c.style.pointerEvents="none",c.style.inlineSize="1px",c.style.blockSize="1px";const p=document.createElement("button");p.type="button",p.className="swatches-trigger",p.setAttribute("aria-haspopup","true"),p.setAttribute("aria-expanded","false"),p.setAttribute("popovertarget",o),a&&p.setAttribute("aria-label",a);const l=document.createElement("span");l.className="swatches-trigger-swatch";const b=document.createElement("span");p.append(l,b);const f=document.createElement("div");f.className="swatches-panel menu",f.id=o,f.setAttribute("popover",""),f.setAttribute("role","radiogroup"),a&&f.setAttribute("aria-label",a);const u=s.map(t=>{const r=document.createElement("button");return r.type="button",r.className="swatch",r.style.background=t,r.style.setProperty("--swatch-check-color",y(t)>.5?"#000":"#fff"),r.setAttribute("role","radio"),r.dataset.color=t,r.setAttribute("aria-label",t),r.addEventListener("click",()=>e(t)),f.append(r),r});c.before(p),document.body.append(f);const n=()=>{const t=c.value.toUpperCase();l.style.background=t,b.textContent=t,u.forEach(r=>{r.setAttribute("aria-checked",String(r.dataset.color.toUpperCase()===t)),r.tabIndex=r.dataset.color.toUpperCase()===t?0:-1})};function e(t){const r=c.value.toUpperCase()!==t.toUpperCase();c.value=t,n(),f.hidePopover(),p.focus(),r&&c.dispatchEvent(new CustomEvent("change",{bubbles:!0,detail:{value:c.value}}))}f.addEventListener("keydown",t=>{const r=document.activeElement.closest(".swatch");if(!r)return;const d=u.indexOf(r);t.key==="ArrowRight"?(t.preventDefault(),(u[d+1]||u[0]).focus()):t.key==="ArrowLeft"?(t.preventDefault(),(u[d-1]||u[u.length-1]).focus()):(t.key==="Enter"||t.key===" ")&&(t.preventDefault(),e(r.dataset.color))}),f.addEventListener("toggle",t=>{const r=t.newState==="open";p.setAttribute("aria-expanded",String(r)),r&&f.querySelector('[tabindex="0"]')?.focus()}),s.some(t=>t.toUpperCase()===c.value.toUpperCase())||(c.value=s[0]),n()}}customElements.define("x-colorswatches",v)})(),(function(){"use strict";if(customElements.get("x-contextmenu"))return;let x=0;const y=500,v=10;class i extends HTMLElement{connectedCallback(){if(this._built)return;const o=this.querySelector("template");o&&(this._built=!0,this._build(o))}_build(o){const a=`x-contextmenu-panel-${++x}`,s=document.createElement("div");s.className="menu context-menu",s.id=a,s.setAttribute("popover","manual"),s.setAttribute("role","menu"),s.append(o.content.cloneNode(!0)),document.body.append(s);let p=null;const l=[...s.querySelectorAll(".menu-item")];l.forEach(m=>{m.setAttribute("role","menuitem"),m.addEventListener("click",()=>{const h=p;n(),this.dispatchEvent(new CustomEvent("select",{bubbles:!0,detail:{value:m.dataset.value,target:h}}))})});let b=null,f=null,u=!1;function n(){u&&(u=!1,s.hidePopover(),f&&(document.removeEventListener("pointerdown",f,!0),f=null),b?.focus(),b=null)}this._teardown=()=>{n(),s.remove()};const e=(m,h,k)=>{if(u&&n(),p=k||null,!m&&!h&&k&&k.getBoundingClientRect){const D=k.getBoundingClientRect();m=D.left,h=D.bottom}b=document.activeElement,u=!0,s.style.position="fixed",s.style.margin="0",s.showPopover();const S=4,F=s.getBoundingClientRect(),w=Math.min(Math.max(S,m),innerWidth-F.width-S),q=Math.min(Math.max(S,h),innerHeight-F.height-S);s.style.left=`${Math.round(w)}px`,s.style.top=`${Math.round(q)}px`,l[0]?.focus(),f=D=>{s.contains(D.target)||n()},setTimeout(()=>document.addEventListener("pointerdown",f,!0),0)};this.addEventListener("contextmenu",m=>{m.preventDefault(),e(m.clientX,m.clientY,m.target)}),this.addEventListener("click",m=>{const h=m.target.closest("[data-contextmenu-trigger]");if(!h||!this.contains(h))return;m.preventDefault(),m.stopPropagation();const k=h.getBoundingClientRect();e(k.left,k.bottom,h)});let t=null,r=0,d=0,g=null;this.addEventListener("touchstart",m=>{const h=m.touches[0];r=h.clientX,d=h.clientY,g=m.target,t=setTimeout(()=>e(r,d,g),y)},{passive:!0}),this.addEventListener("touchmove",m=>{const h=m.touches[0];(Math.abs(h.clientX-r)>v||Math.abs(h.clientY-d)>v)&&clearTimeout(t)},{passive:!0}),this.addEventListener("touchend",()=>clearTimeout(t)),this.addEventListener("touchcancel",()=>clearTimeout(t)),s.addEventListener("keydown",m=>{const h=l.indexOf(document.activeElement);m.key==="ArrowDown"?(m.preventDefault(),(l[h+1]||l[0])?.focus()):m.key==="ArrowUp"?(m.preventDefault(),(l[h-1]||l[l.length-1])?.focus()):m.key==="Enter"||m.key===" "?(m.preventDefault(),document.activeElement?.click()):m.key==="Escape"&&(m.preventDefault(),n())})}disconnectedCallback(){this._teardown?.(),this._teardown=null,this._built=!1}}customElements.define("x-contextmenu",i)})(),(function(){"use strict";if(customElements.get("x-datepicker"))return;let x=0;const y=o=>{const a=o.getFullYear(),s=String(o.getMonth()+1).padStart(2,"0"),p=String(o.getDate()).padStart(2,"0");return`${a}-${s}-${p}`},v=o=>{if(!o)return null;const[a,s,p]=o.split("-").map(Number);return new Date(a,s-1,p)},i=(o,a)=>o&&a&&o.getFullYear()===a.getFullYear()&&o.getMonth()===a.getMonth()&&o.getDate()===a.getDate();class c extends HTMLElement{connectedCallback(){if(this._built)return;const a=this.querySelector('input[type="date"]');a&&(this._built=!0,this._build(a))}_build(a){const s=`x-datepicker-panel-${++x}`,p=this.querySelector(".t-label")?.textContent.trim(),l=document.documentElement.lang||void 0,b=new Intl.DateTimeFormat(l,{month:"long",year:"numeric"}),f=new Intl.DateTimeFormat(l,{month:"short"}),u=new Intl.DateTimeFormat(l,{weekday:"short"}),n=v(a.min),e=v(a.max);a.setAttribute("tabindex","-1"),a.setAttribute("aria-hidden","true"),a.style.position="absolute",a.style.opacity="0",a.style.pointerEvents="none",a.style.inlineSize="1px",a.style.blockSize="1px";const t=document.createElement("button");t.type="button",t.className="select-trigger",t.setAttribute("aria-haspopup","dialog"),t.setAttribute("aria-expanded","false"),t.setAttribute("popovertarget",s),p&&t.setAttribute("aria-label",p);const r=document.createElement("span");t.append(r);const d=document.createElement("div");d.className="datepicker-panel menu",d.id=s,d.setAttribute("popover",""),p&&d.setAttribute("aria-label",p);const g=document.createElement("div");g.className="datepicker-header";const m=document.createElement("button");m.type="button",m.className="datepicker-nav",m.dataset.dir="prev";const h=document.createElement("button");h.type="button",h.className="datepicker-header-label";const k=document.createElement("button");k.type="button",k.className="datepicker-nav",k.dataset.dir="next",g.append(m,h,k);const S=document.createElement("div");S.className="datepicker-weekdays";const F=new Date(2024,0,7);for(let A=0;A<7;A++){const L=document.createElement("span"),P=new Date(F);P.setDate(P.getDate()+A),L.textContent=u.format(P),S.append(L)}const w=document.createElement("div");w.className="datepicker-grid",w.setAttribute("role","grid");const q=document.createElement("div");q.className="datepicker-footer";const D=document.createElement("button");D.type="button",D.className="btn",D.setAttribute("data-variant","ghost"),D.textContent="Today",q.append(D),d.append(g,S,w,q),a.before(t),document.body.append(d);let _=v(a.value),E=(_||new Date).getFullYear(),M=(_||new Date).getMonth(),C="days";const $=()=>{r.textContent=_?new Intl.DateTimeFormat(l,{dateStyle:"medium"}).format(_):"Select date"};function O(A){_=A,a.value=y(A),$(),d.hidePopover(),t.focus(),a.dispatchEvent(new CustomEvent("change",{bubbles:!0,detail:{value:a.value}}))}function B(){w.innerHTML="",C==="months"?Y():C==="years"?V():R()}function R(){S.hidden=!1,w.setAttribute("data-view","days"),h.textContent=b.format(new Date(E,M,1)),m.setAttribute("aria-label","Previous month"),k.setAttribute("aria-label","Next month");const L=new Date(E,M,1).getDay(),P=new Date(E,M,1-L),I=new Date;for(let N=0;N<42;N++){const H=new Date(P);H.setDate(H.getDate()+N);const T=document.createElement("button");T.type="button",T.className="datepicker-day",T.setAttribute("role","gridcell"),T.textContent=String(H.getDate()),T.dataset.iso=y(H),H.getMonth()!==M&&(T.dataset.outside=""),i(H,I)&&T.setAttribute("data-today",""),i(H,_)&&T.setAttribute("aria-selected","true"),(n&&H<n||e&&H>e)&&(T.disabled=!0),T.tabIndex=i(H,_)||!_&&i(H,I)?0:-1,T.addEventListener("click",()=>O(new Date(H))),w.append(T)}}function Y(){S.hidden=!0,w.setAttribute("data-view","months"),h.textContent=String(E),m.setAttribute("aria-label","Previous year"),k.setAttribute("aria-label","Next year");for(let A=0;A<12;A++){const L=document.createElement("button");L.type="button",L.className="datepicker-day datepicker-month",L.setAttribute("role","gridcell"),L.textContent=f.format(new Date(E,A,1)),A===M&&L.setAttribute("aria-selected","true"),L.tabIndex=A===M?0:-1,L.addEventListener("click",()=>{M=A,C="days",B(),w.querySelector('[tabindex="0"]')?.focus()}),w.append(L)}}function V(){S.hidden=!0,w.setAttribute("data-view","years"),h.textContent="Select year",m.setAttribute("aria-label","Scroll up"),k.setAttribute("aria-label","Scroll down");const A=n?n.getFullYear():E-100,L=e?e.getFullYear():E+100;for(let I=A;I<=L;I++){const N=document.createElement("button");N.type="button",N.className="datepicker-day datepicker-year",N.setAttribute("role","gridcell"),N.textContent=String(I),I===E&&N.setAttribute("aria-selected","true"),N.tabIndex=I===E?0:-1,N.addEventListener("click",()=>{E=I,C="months",B(),w.querySelector('[tabindex="0"]')?.focus()}),w.append(N)}const P=(parseFloat(getComputedStyle(document.documentElement).getPropertyValue("--t-lift"))||0)>0;requestAnimationFrame(()=>{w.querySelector('[aria-selected="true"]')?.scrollIntoView({block:"center",behavior:P?"smooth":"auto"})})}h.addEventListener("click",()=>{C=C==="days"?"months":C==="months"?"years":"days",B(),w.querySelector('[tabindex="0"]')?.focus()}),m.addEventListener("click",()=>{C==="years"?w.scrollBy({top:-w.clientHeight*.9}):C==="months"?(E-=1,B()):(M-=1,M<0&&(M=11,E-=1),B())}),k.addEventListener("click",()=>{C==="years"?w.scrollBy({top:w.clientHeight*.9}):C==="months"?(E+=1,B()):(M+=1,M>11&&(M=0,E+=1),B())}),D.addEventListener("click",()=>{const A=new Date;E=A.getFullYear(),M=A.getMonth(),C="days",B(),O(A)}),w.addEventListener("keydown",A=>{const L=document.activeElement.closest(".datepicker-day");if(!L)return;const P=[...w.children],I=P.indexOf(L),N=C==="months"?4:C==="years"?1:7,H={ArrowRight:1,ArrowLeft:-1,ArrowDown:N,ArrowUp:-N};if(A.key in H){A.preventDefault();const T=P[I+H[A.key]];T&&(T.tabIndex=0,L.tabIndex=-1,T.focus())}else(A.key==="Enter"||A.key===" ")&&(A.preventDefault(),L.disabled||L.click())}),d.addEventListener("toggle",A=>{const L=A.newState==="open";t.setAttribute("aria-expanded",String(L)),L&&(E=(_||new Date).getFullYear(),M=(_||new Date).getMonth(),C="days",B(),w.querySelector('[tabindex="0"]')?.focus())}),$()}}customElements.define("x-datepicker",c)})(),(function(){"use strict";if(customElements.get("x-select"))return;let x=0;class y extends HTMLElement{connectedCallback(){if(this._built)return;const i=this.querySelector("select");i&&(this._built=!0,this._build(i))}_build(i){const c=i.closest(".select")||i,o=`x-select-panel-${++x}`,a=this.querySelector(".t-label")?.textContent.trim();c.style.display="none",i.setAttribute("tabindex","-1"),i.setAttribute("aria-hidden","true");const s=document.createElement("button");s.type="button",s.className="select-trigger",s.setAttribute("aria-haspopup","listbox"),s.setAttribute("aria-expanded","false"),s.setAttribute("popovertarget",o),a&&s.setAttribute("aria-label",a),i.disabled&&(s.disabled=!0);const p=document.createElement("span");s.append(p);const l=document.createElement("div");l.className="select-panel menu",l.id=o,l.setAttribute("popover",""),l.setAttribute("role","listbox"),a&&l.setAttribute("aria-label",a);const b=[...i.options].map((n,e)=>{const t=document.createElement("button");return t.type="button",t.className="menu-item select-option",t.textContent=n.textContent,t.setAttribute("role","option"),t.dataset.index=String(e),n.disabled&&(t.disabled=!0,t.setAttribute("aria-disabled","true")),t.addEventListener("click",()=>u(e)),l.append(t),t});c.before(s),document.body.append(l);const f=()=>{p.textContent=i.options[i.selectedIndex]?.textContent||"",b.forEach((n,e)=>{const t=e===i.selectedIndex;n.setAttribute("aria-selected",String(t))})};f();function u(n){const e=i.selectedIndex!==n;i.selectedIndex=n,f(),l.hidePopover(),s.focus(),e&&i.dispatchEvent(new CustomEvent("change",{bubbles:!0,detail:{value:i.value}}))}l.addEventListener("keydown",n=>{const e=b.filter(d=>!d.disabled),t=document.activeElement.closest(".select-option"),r=e.indexOf(t);n.key==="ArrowDown"?(n.preventDefault(),(e[r+1]||e[0])?.focus()):n.key==="ArrowUp"?(n.preventDefault(),(e[r-1]||e[e.length-1])?.focus()):n.key==="Home"?(n.preventDefault(),e[0]?.focus()):n.key==="End"?(n.preventDefault(),e[e.length-1]?.focus()):n.key==="Enter"||n.key===" "?(n.preventDefault(),t&&u(Number(t.dataset.index))):n.key.length===1&&e.find(g=>g.textContent.trim().toLowerCase().startsWith(n.key.toLowerCase()))?.focus()}),l.addEventListener("toggle",n=>{const e=n.newState==="open";s.setAttribute("aria-expanded",String(e)),e&&(l.style.minWidth=`${s.getBoundingClientRect().width}px`,(b[i.selectedIndex]||b[0])?.focus())})}}customElements.define("x-select",y)})(),(function(){"use strict";if(customElements.get("x-tabs"))return;class x extends HTMLElement{connectedCallback(){this.addEventListener("change",this),this._sync(!1)}disconnectedCallback(){this.removeEventListener("change",this)}get value(){const v=this.querySelector(".segmented input:checked");return v?v.value:null}handleEvent(v){v.target===this||!v.target.matches(".segmented input")||this._sync(!0)}_sync(v){const i=this.value;this.querySelectorAll("[data-panel]").forEach(c=>{c.hidden=c.dataset.panel!==i}),v&&this.dispatchEvent(new CustomEvent("change",{bubbles:!0,detail:{value:i}}))}}customElements.define("x-tabs",x)})(),(function(){"use strict";const x=[{key:"theme",attr:"data-theme",label:"Appearance",opts:[["light","Light"],["dark","Dark"]]},{key:"accent",attr:"data-accent",label:"Accent",swatch:!0,opts:[["clay","Clay"],["cobalt","Cobalt"],["fern","Fern"],["plum","Plum"]]},{key:"radius",attr:"data-radius",label:"Corners",opts:[["round","Round"],["soft","Soft"],["sharp","Sharp"]]},{key:"density",attr:"data-density",label:"Density",opts:[["comfortable","Comfortable"],["compact","Compact"]]},{key:"tint",attr:"data-tint",label:"Surface tint",opts:[["accent","Accent"],["warm","Warm"]]}],y=a=>x.find(s=>s.key===a),v={get(a){try{return localStorage.getItem("mtui-"+a)}catch{return null}},set(a,s){try{localStorage.setItem("mtui-"+a,s)}catch{}}};function i(a,s){const p=a.getAttribute("data-accent"),l=getComputedStyle(a),b={};try{s.forEach(f=>{a.setAttribute("data-accent",f),b[f]=l.getPropertyValue("--accent").trim()})}finally{p===null?a.removeAttribute("data-accent"):a.setAttribute("data-accent",p)}return b}let c=0;class o extends HTMLElement{connectedCallback(){if(this._built)return;this._built=!0;const s=document.documentElement,p=++c,l=i(s,y("accent").opts.map(u=>u[0])),b={};x.forEach(u=>{const n=v.get(u.key),t=(n&&u.opts.some(([r])=>r===n)?n:s.getAttribute(u.attr))||u.opts[0][0];s.setAttribute(u.attr,t),b[u.key]=t});const f=document.createElement("div");f.className="theme-panel",x.forEach(u=>{const n=document.createElement("div");n.className="theme-group";const e=document.createElement("span");e.className="t-label",e.textContent=u.label,n.appendChild(e);const t=`mtui-${u.key}-${p}`,r=document.createElement(u.swatch?"div":"fieldset");r.dataset.knob=u.key,r.className=u.swatch?"theme-accents":"segmented",u.swatch&&(r.setAttribute("role","radiogroup"),r.setAttribute("aria-label",u.label)),u.opts.forEach(([d,g])=>{const m=document.createElement("label");m.className=u.swatch?"theme-accent":"",u.swatch&&m.style.setProperty("--dot",l[d]||"var(--accent)");const h=document.createElement("input");h.type="radio",h.name=t,h.value=d,h.checked=b[u.key]===d,u.swatch&&h.setAttribute("aria-label",g),m.appendChild(h);const k=document.createElement("span");k.className=u.swatch?"theme-accent-dot":"",u.swatch||(k.textContent=g),m.appendChild(k),r.appendChild(m)}),n.appendChild(r),f.appendChild(n)}),this.replaceChildren(f),this.addEventListener("change",u=>{const n=u.target.closest('input[type="radio"]');if(!n)return;const e=n.closest("[data-knob]");if(!e)return;const t=e.dataset.knob,r=n.value;document.documentElement.setAttribute(y(t).attr,r),v.set(t,r),this.dispatchEvent(new CustomEvent("themechange",{bubbles:!0,detail:{key:t,value:r}}))})}}customElements.get("x-theme")||customElements.define("x-theme",o)})(),(function(){"use strict";if(customElements.get("x-toast"))return;function x(i){return getComputedStyle(document.documentElement).getPropertyValue(i).trim()}function y(i,c){const o=parseFloat(x("--t-knob"))||0,a=[...i.querySelectorAll(".toast")].filter(l=>l!==c),s=a.map(l=>l.getBoundingClientRect().top);if(c.remove(),o===0)return;const p=x("--spring")||"ease";a.forEach((l,b)=>{const f=s[b]-l.getBoundingClientRect().top;f&&(l.style.transition="none",l.style.transform=`translateY(${f}px)`,l.getBoundingClientRect(),requestAnimationFrame(()=>{l.style.transition=`transform ${o}ms ${p}`,l.style.transform=""}),l.addEventListener("transitionend",function u(n){n.propertyName==="transform"&&(l.style.transition="",l.removeEventListener("transitionend",u))}))})}class v extends HTMLElement{connectedCallback(){this.setAttribute("role","status"),this.setAttribute("aria-live","polite")}show(c,o={}){const a=document.createElement("div");a.className="toast",o.kind&&(a.dataset.kind=o.kind);const s=document.createElement("span");s.textContent=c,a.append(s);const p=()=>{"leaving"in a.dataset||(a.dataset.leaving="",clearTimeout(b),a.addEventListener("animationend",()=>y(this,a),{once:!0}))};if(o.action){const f=document.createElement("button");f.className="toast-action",f.textContent=o.action.label,f.addEventListener("click",()=>{typeof o.action.onClick=="function"&&o.action.onClick(),p()}),a.append(f)}this.append(a);const l=[...this.querySelectorAll(".toast")].filter(f=>!("leaving"in f.dataset));if(l.length>3){const f=l[0];f.dataset.leaving="",f.addEventListener("animationend",()=>y(this,f),{once:!0})}let b=setTimeout(p,o.duration||4e3);return a.addEventListener("mouseenter",()=>clearTimeout(b)),a.addEventListener("focusin",()=>clearTimeout(b)),a.addEventListener("mouseleave",()=>{clearTimeout(b),b=setTimeout(p,1500)}),p}}customElements.define("x-toast",v),window.mtui=Object.assign(window.mtui||{},{toast(i,c){let o=document.querySelector("x-toast");return o||(o=document.createElement("x-toast"),document.body.append(o)),o.show(i,c)}})})();
|
package/fonts/OFL.txt
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
Copyright 2022 The Noto Project Authors (https://github.com/notofonts/latin-greek-cyrillic)
|
|
2
|
+
|
|
3
|
+
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
|
4
|
+
This license is copied below, and is also available with a FAQ at:
|
|
5
|
+
https://scripts.sil.org/OFL
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
-----------------------------------------------------------
|
|
9
|
+
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
10
|
+
-----------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
PREAMBLE
|
|
13
|
+
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
14
|
+
development of collaborative font projects, to support the font creation
|
|
15
|
+
efforts of academic and linguistic communities, and to provide a free and
|
|
16
|
+
open framework in which fonts may be shared and improved in partnership
|
|
17
|
+
with others.
|
|
18
|
+
|
|
19
|
+
The OFL allows the licensed fonts to be used, studied, modified and
|
|
20
|
+
redistributed freely as long as they are not sold by themselves. The
|
|
21
|
+
fonts, including any derivative works, can be bundled, embedded,
|
|
22
|
+
redistributed and/or sold with any software provided that any reserved
|
|
23
|
+
names are not used by derivative works. The fonts and derivatives,
|
|
24
|
+
however, cannot be released under any other type of license. The
|
|
25
|
+
requirement for fonts to remain under this license does not apply
|
|
26
|
+
to any document created using the fonts or their derivatives.
|
|
27
|
+
|
|
28
|
+
DEFINITIONS
|
|
29
|
+
"Font Software" refers to the set of files released by the Copyright
|
|
30
|
+
Holder(s) under this license and clearly marked as such. This may
|
|
31
|
+
include source files, build scripts and documentation.
|
|
32
|
+
|
|
33
|
+
"Reserved Font Name" refers to any names specified as such after the
|
|
34
|
+
copyright statement(s).
|
|
35
|
+
|
|
36
|
+
"Original Version" refers to the collection of Font Software components as
|
|
37
|
+
distributed by the Copyright Holder(s).
|
|
38
|
+
|
|
39
|
+
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
40
|
+
or substituting -- in part or in whole -- any of the components of the
|
|
41
|
+
Original Version, by changing formats or by porting the Font Software to a
|
|
42
|
+
new environment.
|
|
43
|
+
|
|
44
|
+
"Author" refers to any designer, engineer, programmer, technical
|
|
45
|
+
writer or other person who contributed to the Font Software.
|
|
46
|
+
|
|
47
|
+
PERMISSION & CONDITIONS
|
|
48
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
49
|
+
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
|
50
|
+
redistribute, and sell modified and unmodified copies of the Font
|
|
51
|
+
Software, subject to the following conditions:
|
|
52
|
+
|
|
53
|
+
1) Neither the Font Software nor any of its individual components,
|
|
54
|
+
in Original or Modified Versions, may be sold by itself.
|
|
55
|
+
|
|
56
|
+
2) Original or Modified Versions of the Font Software may be bundled,
|
|
57
|
+
redistributed and/or sold with any software, provided that each copy
|
|
58
|
+
contains the above copyright notice and this license. These can be
|
|
59
|
+
included either as stand-alone text files, human-readable headers or
|
|
60
|
+
in the appropriate machine-readable metadata fields within text or
|
|
61
|
+
binary files as long as those fields can be easily viewed by the user.
|
|
62
|
+
|
|
63
|
+
3) No Modified Version of the Font Software may use the Reserved Font
|
|
64
|
+
Name(s) unless explicit written permission is granted by the corresponding
|
|
65
|
+
Copyright Holder. This restriction only applies to the primary font name as
|
|
66
|
+
presented to the users.
|
|
67
|
+
|
|
68
|
+
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
69
|
+
Software shall not be used to promote, endorse or advertise any
|
|
70
|
+
Modified Version, except to acknowledge the contribution(s) of the
|
|
71
|
+
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
72
|
+
permission.
|
|
73
|
+
|
|
74
|
+
5) The Font Software, modified or unmodified, in part or in whole,
|
|
75
|
+
must be distributed entirely under this license, and must not be
|
|
76
|
+
distributed under any other license. The requirement for fonts to
|
|
77
|
+
remain under this license does not apply to any document created
|
|
78
|
+
using the Font Software.
|
|
79
|
+
|
|
80
|
+
TERMINATION
|
|
81
|
+
This license becomes null and void if any of the above conditions are
|
|
82
|
+
not met.
|
|
83
|
+
|
|
84
|
+
DISCLAIMER
|
|
85
|
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
86
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
87
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
88
|
+
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
89
|
+
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
90
|
+
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
91
|
+
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
92
|
+
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
93
|
+
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/js/accordion.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/* MTUI accordion motion — tier: lightly Enhanced over Basic <details>.
|
|
2
|
+
Basic (no JS): native <details>/<summary> opens/closes instantly, fully
|
|
3
|
+
functional. Enhanced: smooth height + chevron animation both ways via
|
|
4
|
+
the Web Animations API. Duration/easing are read live from --t-lift and
|
|
5
|
+
--ease, so reduced-motion (which collapses --t-lift to 0ms) disables
|
|
6
|
+
this for free — no separate check needed.
|
|
7
|
+
No custom element: this is an ambient enhancement over any
|
|
8
|
+
.accordion > summary in the page, same pattern as js/menu.js. */
|
|
9
|
+
(function () {
|
|
10
|
+
'use strict';
|
|
11
|
+
|
|
12
|
+
function durationMs() {
|
|
13
|
+
const v = getComputedStyle(document.documentElement)
|
|
14
|
+
.getPropertyValue('--t-lift').trim();
|
|
15
|
+
return parseFloat(v) || 0;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
document.addEventListener('click', (e) => {
|
|
19
|
+
const summary = e.target.closest('.accordion > summary');
|
|
20
|
+
if (!summary) return;
|
|
21
|
+
const details = summary.parentElement;
|
|
22
|
+
if ('animating' in details.dataset) { e.preventDefault(); return; }
|
|
23
|
+
|
|
24
|
+
const duration = durationMs();
|
|
25
|
+
if (duration === 0) return; // reduced motion: native instant toggle
|
|
26
|
+
|
|
27
|
+
const body = details.querySelector(':scope > .accordion-body');
|
|
28
|
+
if (!body) return; // nothing to animate; let the native toggle happen
|
|
29
|
+
|
|
30
|
+
e.preventDefault();
|
|
31
|
+
const opening = !details.open;
|
|
32
|
+
details.dataset.animating = '';
|
|
33
|
+
details.dataset.expanded = opening ? 'true' : 'false';
|
|
34
|
+
|
|
35
|
+
if (opening) details.open = true; // must be open to measure scrollHeight
|
|
36
|
+
// border-box means blockSize alone can't go below the body's own
|
|
37
|
+
// padding — animate padding to 0 in lockstep so the collapsed state is
|
|
38
|
+
// a true 0px, not a floor of ~24px of bare padding.
|
|
39
|
+
const cs = getComputedStyle(body);
|
|
40
|
+
const padTop = cs.paddingBlockStart;
|
|
41
|
+
const padBottom = cs.paddingBlockEnd;
|
|
42
|
+
const endHeight = body.scrollHeight;
|
|
43
|
+
const easing = getComputedStyle(document.documentElement)
|
|
44
|
+
.getPropertyValue('--ease').trim() || 'ease';
|
|
45
|
+
|
|
46
|
+
const open = { blockSize: `${endHeight}px`, paddingBlockStart: padTop, paddingBlockEnd: padBottom };
|
|
47
|
+
const closed = { blockSize: '0px', paddingBlockStart: '0px', paddingBlockEnd: '0px' };
|
|
48
|
+
|
|
49
|
+
body.style.overflow = 'hidden';
|
|
50
|
+
const anim = body.animate(
|
|
51
|
+
opening ? [closed, open] : [open, closed],
|
|
52
|
+
{ duration, easing }
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
anim.onfinish = () => {
|
|
56
|
+
body.style.blockSize = '';
|
|
57
|
+
body.style.paddingBlockStart = '';
|
|
58
|
+
body.style.paddingBlockEnd = '';
|
|
59
|
+
body.style.overflow = '';
|
|
60
|
+
delete details.dataset.animating;
|
|
61
|
+
if (!opening) details.open = false; // unmount only after fully collapsed
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
})();
|
package/js/feedback.js
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/* MTUI feedback — tier: JS-only, layered opt-in over phase 04-06 components
|
|
2
|
+
(doesn't change their markup or behavior contracts).
|
|
3
|
+
Five synthetic WebAudio cues (no audio files) + matching haptics, gated
|
|
4
|
+
by one global mute persisted to localStorage. AudioContext is created
|
|
5
|
+
lazily on first use; if it's still suspended (no user gesture has
|
|
6
|
+
unlocked audio yet) or unavailable, playback silently no-ops.
|
|
7
|
+
API: mtui.feedback.play('tick'|'toggle-on'|'toggle-off'|'success'|'error')
|
|
8
|
+
mtui.feedback.muted // get
|
|
9
|
+
mtui.feedback.muted = true // set, persists
|
|
10
|
+
|
|
11
|
+
Opt-in wiring — nothing fires without a matching visible event, and
|
|
12
|
+
none of this listens for hover, scroll, or focus (DESIGN.md §4.10):
|
|
13
|
+
.switch/.checkbox/.radio[data-feedback] -> toggle-on / toggle-off on change
|
|
14
|
+
button/.btn[data-feedback] -> success on click, or the
|
|
15
|
+
cue named in the attribute
|
|
16
|
+
("confirm actions")
|
|
17
|
+
.toast[data-kind] -> that cue when the toast mounts
|
|
18
|
+
[data-feedback][data-status="danger"] -> error when it mounts
|
|
19
|
+
(alert / empty boundaries)
|
|
20
|
+
|
|
21
|
+
Basic (JS off): silent — there is no audio-file fallback to degrade to. */
|
|
22
|
+
(function () {
|
|
23
|
+
'use strict';
|
|
24
|
+
|
|
25
|
+
const MUTE_KEY = 'mtui-feedback-muted';
|
|
26
|
+
|
|
27
|
+
// Frequencies, durations and the 0.06 gain ceiling are locked by
|
|
28
|
+
// DESIGN.md §2.13. `steps` are discrete pitches (a clean interval, not a
|
|
29
|
+
// continuous portamento glide) so toggles read as a crisp two-note tap
|
|
30
|
+
// rather than a slide-whistle swoop. Everything else — soft attack,
|
|
31
|
+
// exponential decay, lowpass — is envelope shaping, not spec values.
|
|
32
|
+
const CUES = {
|
|
33
|
+
tick: { wave: 'sine', steps: [880], duration: 0.05, peak: 0.04 },
|
|
34
|
+
'toggle-on': { wave: 'sine', steps: [520, 784], duration: 0.09, peak: 0.05, haptic: 8 },
|
|
35
|
+
'toggle-off': { wave: 'sine', steps: [784, 520], duration: 0.09, peak: 0.05, haptic: 8 },
|
|
36
|
+
success: { wave: 'sine', steps: [660, 880], duration: 0.14, peak: 0.05, haptic: 8 },
|
|
37
|
+
error: { wave: 'triangle', steps: [233], duration: 0.16, peak: 0.05, haptic: [20, 40, 20] },
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
function isMuted() {
|
|
41
|
+
try {
|
|
42
|
+
return localStorage.getItem(MUTE_KEY) === '1';
|
|
43
|
+
} catch (e) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function setMuted(value) {
|
|
49
|
+
try {
|
|
50
|
+
localStorage.setItem(MUTE_KEY, value ? '1' : '0');
|
|
51
|
+
} catch (e) {
|
|
52
|
+
/* storage unavailable (private mode, quota, policy) — mute stays session-only */
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
let ctx = null;
|
|
57
|
+
function audioCtx() {
|
|
58
|
+
if (ctx) return ctx;
|
|
59
|
+
const AudioContextClass = window.AudioContext || window.webkitAudioContext;
|
|
60
|
+
ctx = AudioContextClass ? new AudioContextClass() : null;
|
|
61
|
+
return ctx;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function tone(cue) {
|
|
65
|
+
const c = audioCtx();
|
|
66
|
+
if (!c) return;
|
|
67
|
+
if (c.state === 'suspended') c.resume().catch(() => {});
|
|
68
|
+
|
|
69
|
+
const t0 = c.currentTime;
|
|
70
|
+
const osc = c.createOscillator();
|
|
71
|
+
const gain = c.createGain();
|
|
72
|
+
const lp = c.createBiquadFilter();
|
|
73
|
+
osc.type = cue.wave;
|
|
74
|
+
|
|
75
|
+
// Discrete pitch steps — each note holds for an equal slice, no glide.
|
|
76
|
+
const steps = cue.steps;
|
|
77
|
+
const slice = cue.duration / steps.length;
|
|
78
|
+
steps.forEach((f, i) => osc.frequency.setValueAtTime(f, t0 + i * slice));
|
|
79
|
+
|
|
80
|
+
// Gentle lowpass rolls off the brittle upper harmonics (esp. the
|
|
81
|
+
// triangle error cue) so the tone stays soft rather than buzzy.
|
|
82
|
+
lp.type = 'lowpass';
|
|
83
|
+
lp.frequency.setValueAtTime(Math.max(...steps) * 3, t0);
|
|
84
|
+
lp.Q.setValueAtTime(0.7, t0);
|
|
85
|
+
|
|
86
|
+
// Percussive envelope: click-free ~4ms attack, then a natural
|
|
87
|
+
// exponential decay — no flat sustain plateau (that's the "beep").
|
|
88
|
+
// exponentialRampToValueAtTime can't reach 0, so decay to near-zero.
|
|
89
|
+
const peak = Math.min(cue.peak || 0.05, 0.06);
|
|
90
|
+
gain.gain.setValueAtTime(0.0001, t0);
|
|
91
|
+
gain.gain.exponentialRampToValueAtTime(peak, t0 + 0.004);
|
|
92
|
+
gain.gain.exponentialRampToValueAtTime(0.0001, t0 + cue.duration);
|
|
93
|
+
gain.gain.setValueAtTime(0, t0 + cue.duration + 0.005);
|
|
94
|
+
|
|
95
|
+
osc.connect(lp).connect(gain).connect(c.destination);
|
|
96
|
+
osc.start(t0);
|
|
97
|
+
osc.stop(t0 + cue.duration + 0.02);
|
|
98
|
+
osc.addEventListener('ended', () => {
|
|
99
|
+
osc.disconnect();
|
|
100
|
+
lp.disconnect();
|
|
101
|
+
gain.disconnect();
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function buzz(pattern) {
|
|
106
|
+
if (typeof navigator.vibrate !== 'function') return;
|
|
107
|
+
try {
|
|
108
|
+
navigator.vibrate(pattern);
|
|
109
|
+
} catch (e) {
|
|
110
|
+
/* unsupported in this context — no-op */
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function play(name) {
|
|
115
|
+
const cue = CUES[name];
|
|
116
|
+
if (!cue || isMuted()) return;
|
|
117
|
+
tone(cue);
|
|
118
|
+
if (cue.haptic) buzz(cue.haptic);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
window.mtui = Object.assign(window.mtui || {}, {
|
|
122
|
+
feedback: {
|
|
123
|
+
play,
|
|
124
|
+
get muted() {
|
|
125
|
+
return isMuted();
|
|
126
|
+
},
|
|
127
|
+
set muted(value) {
|
|
128
|
+
setMuted(!!value);
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
document.addEventListener('change', (e) => {
|
|
134
|
+
if (e.target.matches('.switch[data-feedback], .checkbox[data-feedback], .radio[data-feedback]')) {
|
|
135
|
+
play(e.target.checked ? 'toggle-on' : 'toggle-off');
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
document.addEventListener('click', (e) => {
|
|
140
|
+
const el = e.target.closest('button[data-feedback], .btn[data-feedback]');
|
|
141
|
+
if (el) play(el.getAttribute('data-feedback') || 'success');
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// A parent (e.g. the <x-toast> mount) and its just-appended child can
|
|
145
|
+
// land in separate MutationRecords from the same synchronous batch; by
|
|
146
|
+
// the time this callback runs both are already in the live tree, so
|
|
147
|
+
// scanning the parent's subtree can rediscover a child another record
|
|
148
|
+
// already reported. Track fired nodes so each element cues at most once.
|
|
149
|
+
const MOUNT_SELECTOR = '.toast[data-kind], [data-feedback][data-status="danger"]';
|
|
150
|
+
const fired = new WeakSet();
|
|
151
|
+
function scan(node) {
|
|
152
|
+
if (node.nodeType !== 1) return;
|
|
153
|
+
const found = node.matches(MOUNT_SELECTOR) ? [node] : [];
|
|
154
|
+
found.concat([...node.querySelectorAll(MOUNT_SELECTOR)]).forEach((el) => {
|
|
155
|
+
if (fired.has(el)) return;
|
|
156
|
+
fired.add(el);
|
|
157
|
+
play(el.classList.contains('toast') ? el.dataset.kind : 'error');
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Guard document.body: if this script is included in <head> without defer,
|
|
162
|
+
// body is null. The API + change/click listeners above are already live;
|
|
163
|
+
// only the mount-cue observer needs a live body, so defer it if needed.
|
|
164
|
+
function observeMounts() {
|
|
165
|
+
new MutationObserver((mutations) => {
|
|
166
|
+
mutations.forEach((m) => m.addedNodes.forEach(scan));
|
|
167
|
+
}).observe(document.body, { childList: true, subtree: true });
|
|
168
|
+
}
|
|
169
|
+
if (document.body) observeMounts();
|
|
170
|
+
else document.addEventListener('DOMContentLoaded', observeMounts, { once: true });
|
|
171
|
+
})();
|
package/js/menu.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/* MTUI menu positioning — tier: lightly Enhanced (no custom element).
|
|
2
|
+
Anchors any .menu[popover] below its [popovertarget] trigger, aligned to
|
|
3
|
+
the trigger's inline-start edge, flipped above when there is no room and
|
|
4
|
+
clamped to the viewport. Re-anchors on scroll/resize while open, so the
|
|
5
|
+
panel tracks its trigger instead of staying pinned at the viewport
|
|
6
|
+
position it opened at (which would visibly drift away from the trigger
|
|
7
|
+
as the page scrolls underneath it).
|
|
8
|
+
Basic (JS off): the popover opens centered in the top layer — Esc and
|
|
9
|
+
light-dismiss still work; nothing breaks. */
|
|
10
|
+
(function () {
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
function place(menu, trigger) {
|
|
14
|
+
const gap = parseFloat(
|
|
15
|
+
getComputedStyle(document.documentElement).getPropertyValue('--sp-8')
|
|
16
|
+
) || 8;
|
|
17
|
+
const t = trigger.getBoundingClientRect();
|
|
18
|
+
const m = menu.getBoundingClientRect();
|
|
19
|
+
const rtl = getComputedStyle(menu).direction === 'rtl';
|
|
20
|
+
|
|
21
|
+
let top = t.bottom + gap;
|
|
22
|
+
if (top + m.height > window.innerHeight - gap) {
|
|
23
|
+
top = Math.max(gap, t.top - m.height - gap);
|
|
24
|
+
}
|
|
25
|
+
let x = rtl ? t.right - m.width : t.left;
|
|
26
|
+
x = Math.min(Math.max(gap, x), window.innerWidth - m.width - gap);
|
|
27
|
+
|
|
28
|
+
menu.style.position = 'fixed';
|
|
29
|
+
menu.style.top = `${Math.round(top)}px`;
|
|
30
|
+
menu.style.left = `${Math.round(x)}px`;
|
|
31
|
+
menu.style.margin = '0';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let tracking = null; // { menu, trigger, raf }
|
|
35
|
+
|
|
36
|
+
function stopTracking() {
|
|
37
|
+
if (!tracking) return;
|
|
38
|
+
cancelAnimationFrame(tracking.raf);
|
|
39
|
+
window.removeEventListener('scroll', tracking.onScroll, true);
|
|
40
|
+
window.removeEventListener('resize', tracking.onScroll);
|
|
41
|
+
tracking = null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
document.addEventListener('toggle', (e) => {
|
|
45
|
+
const menu = e.target;
|
|
46
|
+
if (!(menu instanceof HTMLElement) || !menu.matches('.menu[popover]')) return;
|
|
47
|
+
|
|
48
|
+
if (e.newState !== 'open') {
|
|
49
|
+
if (tracking && tracking.menu === menu) stopTracking();
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const trigger = document.querySelector(`[popovertarget="${menu.id}"]`);
|
|
54
|
+
if (!trigger) return;
|
|
55
|
+
|
|
56
|
+
if (tracking) stopTracking();
|
|
57
|
+
place(menu, trigger);
|
|
58
|
+
|
|
59
|
+
let queued = false;
|
|
60
|
+
const onScroll = () => {
|
|
61
|
+
if (queued) return;
|
|
62
|
+
queued = true;
|
|
63
|
+
tracking.raf = requestAnimationFrame(() => {
|
|
64
|
+
queued = false;
|
|
65
|
+
place(menu, trigger);
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
tracking = { menu, trigger, raf: 0, onScroll };
|
|
69
|
+
window.addEventListener('scroll', onScroll, true); // capture: any scrolling ancestor
|
|
70
|
+
window.addEventListener('resize', onScroll);
|
|
71
|
+
}, true); /* popover toggle doesn't bubble — capture phase catches it */
|
|
72
|
+
})();
|