lvc-ui 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 lvc-ui
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,159 @@
1
+ # lvc-ui
2
+
3
+ A Vue 2.7 component library with a dark, tech-style (科技感) UI for big-screen / data-visualization dashboards. Ships as an **npm package** (ESM + UMD) and as **standalone CDN scripts** for plain HTML + Vue 2 projects.
4
+
5
+ - Dark theme tokens: primary `#12bbed`, background `#0b1a2a`, panel `#0d2339`
6
+ - Responsive units in `vmin` for large screens
7
+ - All components are bundled into the single `lvc-ui.umd.js` / `lvc-ui.esm.js` — no separate files to load.
8
+
9
+ **Live demo / 组件演示台**: https://lvminjie5201314.github.io/music/lvc-ui
10
+
11
+ ---
12
+
13
+ ## Install (npm)
14
+
15
+ ```bash
16
+ npm i lvc-ui
17
+ ```
18
+
19
+ ```js
20
+ import Vue from 'vue'
21
+ import LvcUI from 'lvc-ui'
22
+ import 'lvc-ui/dist/lvc-ui.css'
23
+
24
+ Vue.use(LvcUI) // globally registers all components + $lvcDialog / $lvcMessage / $lvcLoading
25
+
26
+ // Or import only what you need (tree-shakable):
27
+ // import { LvcButton, Bus } from 'lvc-ui'
28
+ ```
29
+
30
+ Then use components in templates:
31
+
32
+ ```html
33
+ <lvc-button type="primary" @click="onClick">按钮</lvc-button>
34
+ <lvc-select v-model="value" :options="options"></lvc-select>
35
+ ```
36
+
37
+ > `vue` is a peer dependency (>= 2.6). Do **not** import Vue from `lvc-ui`; bring your own.
38
+
39
+ ---
40
+
41
+ ## Usage in plain HTML + Vue 2 (CDN / UMD)
42
+
43
+ No build step required. Load Vue 2.7 first, then `lvc-ui.umd.js` + the CSS, call `LvcUI.install(Vue)`, and the global `LvcUI` namespace is ready.
44
+
45
+ > ⚠️ Script order matters: **Vue → lvc-ui.umd.js → css**. All components (incl. `Tree` / `MonthPicker` / `YearPicker`) are already bundled into the UMD, so no extra scripts are needed.
46
+
47
+ ```html
48
+ <!DOCTYPE html>
49
+ <html lang="zh-CN">
50
+ <head>
51
+ <meta charset="UTF-8" />
52
+ <title>lvc-ui CDN Demo</title>
53
+ <!-- 1. Styles -->
54
+ <link rel="stylesheet" href="https://unpkg.com/lvc-ui/dist/lvc-ui.css" />
55
+ <!-- 2. Vue 2.7 (global `Vue`) -->
56
+ <script src="https://unpkg.com/vue@2.7.16/dist/vue.min.js"></script>
57
+ <!-- 3. Component library (UMD, exposes global `LvcUI`) -->
58
+ <script src="https://unpkg.com/lvc-ui/dist/lvc-ui.umd.js"></script>
59
+ <!-- 4. All components (incl. Tree / MonthPicker / YearPicker) are already bundled above -->
60
+ <style>body { background:#0b1a2a; color:#e0f2fe; padding:24px; }</style>
61
+ </head>
62
+ <body>
63
+ <div id="app">
64
+ <lvc-button type="primary" @click="sayHi">按钮</lvc-button>
65
+
66
+ <lvc-switch v-model="on"></lvc-switch>
67
+
68
+ <lvc-select v-model="city" :options="options" placeholder="请选择城市"></lvc-select>
69
+
70
+ <lvc-date-picker v-model="date" type="daterange"></lvc-date-picker>
71
+ <lvc-month-picker v-model="month" type="monthrange"></lvc-month-picker>
72
+ <lvc-year-picker v-model="year" type="yearrange"></lvc-year-picker>
73
+
74
+ <lvc-tree :data="tree" :default-expand-all="true" :show-checkbox="true"></lvc-tree>
75
+ </div>
76
+
77
+ <script>
78
+ // Register every component + the prototype plugins ($lvcDialog / $lvcMessage / $lvcLoading)
79
+ LvcUI.install(Vue)
80
+
81
+ new Vue({
82
+ el: '#app',
83
+ data: {
84
+ on: true,
85
+ city: '',
86
+ options: [{ label: '北京', value: 'bj' }, { label: '上海', value: 'sh' }],
87
+ date: ['', ''],
88
+ month: ['2026-01', '2026-06'],
89
+ year: ['2024', '2026'],
90
+ tree: [{ id: '1', label: '数据中心', children: [{ id: '1-1', label: '节点 A' }] }],
91
+ },
92
+ methods: {
93
+ sayHi() {
94
+ // Imperative API (also available as this.$lvcMessage inside components)
95
+ LvcUI.Message.success('Hello lvc-ui')
96
+ },
97
+ },
98
+ })
99
+ </script>
100
+ </body>
101
+ </html>
102
+ ```
103
+
104
+ ### Using a single component from the UMD build
105
+
106
+ The UMD global `LvcUI` exposes every component and util by name, so you can register just one:
107
+
108
+ ```html
109
+ <script src="https://unpkg.com/vue@2.7.16/dist/vue.min.js"></script>
110
+ <script src="https://unpkg.com/lvc-ui/dist/lvc-ui.umd.js"></script>
111
+ <script>
112
+ Vue.component('my-button', LvcUI.LvcButton)
113
+ // tools
114
+ LvcUI.Bus.emit('refresh')
115
+ </script>
116
+ ```
117
+
118
+ ---
119
+
120
+ ## Components
121
+
122
+ | Component | Tag | Notes |
123
+ | --- | --- | --- |
124
+ | Button | `lvc-button` | types: primary / success / warning / danger / info |
125
+ | Switch | `lvc-switch` | `v-model` |
126
+ | Select | `lvc-select` | dropdown rendered into `body` |
127
+ | Table | `lvc-table` | sorting, checkbox, empty state |
128
+ | TimePicker | `lvc-time-picker` | |
129
+ | LoadMore | `lvc-load-more` | infinite scroll |
130
+ | DatePicker | `lvc-date-picker` | `type`: date / daterange / datetime / datetimerange |
131
+ | Dialog | `lvc-dialog` | `:visible.sync` + `LvcUI.Dialog.show()` |
132
+ | Odometer | `lvc-odometer` | numeric rolling animation |
133
+ | Tree | `lvc-tree` | from the main package |
134
+ | MonthPicker | `lvc-month-picker` | `type`: month / monthrange |
135
+ | YearPicker | `lvc-year-picker` | `type`: year / yearrange |
136
+
137
+ ## Tools / SDK
138
+
139
+ | Export | Description |
140
+ | --- | --- |
141
+ | `Bus` | Cross-tab / iframe event bus (`on`/`once`/`off`/`emit`/`request`) |
142
+ | `SocketClient` | WebSocket wrapper with auto-reconnect & heartbeat |
143
+ | `ScanCode` / `scanUtils` | HTML5+ barcode scanner (App only) + `isAndroid`/`isIOS`/`isApp`/`getQuery`/`throttle` |
144
+ | `CanvasTopologyUtils` | Canvas 2D topology drawing (DPR-aware) |
145
+ | `px2EchartsUrils` | design-px → actual-px for ECharts |
146
+ | `createRouter` | hash-based multi-level router with `requiresAuth` |
147
+
148
+ ## Build
149
+
150
+ ```bash
151
+ npm run build # dist/lvc-ui.esm.js + .umd.js + .css + dist/index.d.ts
152
+ npm run dev # demo showcase on :5173
153
+ npm run build:demo # build the showcase
154
+ npm test # vitest unit tests
155
+ ```
156
+
157
+ ## License
158
+
159
+ MIT
@@ -0,0 +1,86 @@
1
+ // Type definitions for lvc-ui
2
+ // Auto-generated by scripts/gen-types.mjs (run after `vite build`).
3
+ // Loosely typed on purpose: components/plugins are Vue 2 runtime components.
4
+
5
+ declare const _LvcUI: {
6
+ install(vue: any): void
7
+ version: string
8
+ LvcButton: any
9
+ LvcDialog: any
10
+ LvcSelect: any
11
+ LvcSwitch: any
12
+ LvcTable: any
13
+ LvcTimePicker: any
14
+ LvcLoadMore: any
15
+ LvcDatePicker: any
16
+ LvcOdometer: any
17
+ Dialog: any
18
+ Message: any
19
+ Loading: any
20
+ Bus: LvcBus
21
+ SocketClient: any
22
+ ScanCode: any
23
+ scanUtils: LvcScanUtils
24
+ CanvasTopologyUtils: any
25
+ px2EchartsUrils: LvcPx2Echarts
26
+ createRouter: LvcCreateRouter
27
+ [key: string]: any
28
+ }
29
+
30
+ export interface LvcBus {
31
+ on(event: string, fn: (data: any, source?: any) => void): void
32
+ once(event: string, fn: (data: any) => void): void
33
+ off(event?: string, fn?: (data: any) => void): void
34
+ emit(event: string, data?: any): void
35
+ request(event: string, data?: any, timeout?: number): Promise<any>
36
+ }
37
+
38
+ export interface LvcScanUtils {
39
+ isAndroid: boolean
40
+ isIOS: boolean
41
+ isApp: boolean
42
+ getQuery(name?: string): any
43
+ throttle(fn: (...args: any[]) => void, wait?: number): (...args: any[]) => void
44
+ }
45
+
46
+ export interface LvcPx2Echarts {
47
+ px2Echarts(designPx?: number, designWidth?: number): number
48
+ }
49
+
50
+ export interface LvcCreateRouter {
51
+ (options?: {
52
+ routes?: Record<string, string | { path: string; meta?: Record<string, any> }>
53
+ default?: string
54
+ parent?: string
55
+ level?: number
56
+ loginPage?: string
57
+ errorPage?: string
58
+ }): {
59
+ init(vm: any): void
60
+ push(name: string): void
61
+ beforeEach(fn: (to: any, from: any, next: (r?: boolean | string) => void) => void): void
62
+ }
63
+ }
64
+
65
+ export default _LvcUI
66
+
67
+ export declare const install: (vue: any) => void
68
+ export declare const LvcButton: any
69
+ export declare const LvcDialog: any
70
+ export declare const LvcSelect: any
71
+ export declare const LvcSwitch: any
72
+ export declare const LvcTable: any
73
+ export declare const LvcTimePicker: any
74
+ export declare const LvcLoadMore: any
75
+ export declare const LvcDatePicker: any
76
+ export declare const LvcOdometer: any
77
+ export declare const Dialog: any
78
+ export declare const Message: any
79
+ export declare const Loading: any
80
+ export declare const Bus: LvcBus
81
+ export declare const SocketClient: any
82
+ export declare const ScanCode: any
83
+ export declare const scanUtils: LvcScanUtils
84
+ export declare const CanvasTopologyUtils: any
85
+ export declare const px2EchartsUrils: LvcPx2Echarts
86
+ export declare const createRouter: LvcCreateRouter
@@ -0,0 +1 @@
1
+ .lvc-button{display:inline-flex;align-items:center;justify-content:center;white-space:nowrap;cursor:pointer;background:#1e446966;border:1px solid #1e4469;color:#fff;text-align:center;box-sizing:border-box;outline:none;margin:0;transition:.1s;font-weight:500;padding:1.2vmin 2.5vmin;font-size:1.4vmin;border-radius:.4vmin;-webkit-user-select:none;user-select:none;vertical-align:middle;gap:.7vmin;line-height:1}.lvc-button--primary{background-color:#12bbedcc;border-color:#12bbed;color:#fff}.lvc-button--success{background-color:#67c23acc;border-color:#67c23a;color:#fff}.lvc-button--warning{background-color:#e6a23ccc;border-color:#e6a23c;color:#fff}.lvc-button--danger{background-color:#f56c6ccc;border-color:#f56c6c;color:#fff}.lvc-button--info{background-color:#909399cc;border-color:#909399;color:#fff}.lvc-button--primary:hover{background-color:#12bbed}.lvc-button--success:hover{background-color:#67c23a}.lvc-button--warning:hover{background-color:#e6a23c}.lvc-button--danger:hover{background-color:#f56c6c}.lvc-button--info:hover{background-color:#909399}.lvc-button.is-plain{background:transparent}.lvc-button--primary.is-plain{color:#12bbed;background:#12bbed1a}.lvc-button--success.is-plain{color:#67c23a;background:#67c23a1a}.lvc-button--danger.is-plain{color:#f56c6c;background:#f56c6c1a}.lvc-button.is-round{border-radius:2.5vmin}.lvc-button.is-circle{border-radius:50%;padding:1.2vmin}.lvc-button.is-disabled{cursor:not-allowed;opacity:.5;background-image:none}.lvc-button .lvc-icon-loading{margin-right:.8vmin;display:inline-block;width:1.4vmin;height:1.4vmin;border:2px solid currentColor;border-top-color:transparent;border-radius:50%;animation:lvc-rotate 1s linear infinite}@keyframes lvc-rotate{0%{transform:rotate(0)}to{transform:rotate(360deg)}}:root{--lvc-primary: #12bbed;--lvc-bg-dark: #0b1a2a;--lvc-bg-input: #0d2339;--lvc-border: #1e4469;--lvc-text: #fff;--lvc-text-dim: #8cabc4}.lvc-dialog-mask{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#000000b3;display:flex;align-items:center;justify-content:center;z-index:10000;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.lvc-dialog-box{background:var(--lvc-bg-dark);border:1px solid var(--lvc-primary);border-radius:1.108vmin;box-shadow:0 1.385vmin 5.54vmin #000c;display:flex;flex-direction:column;overflow:hidden;min-width:44.32vmin;max-width:90vw;color:var(--lvc-text);font-size:1.9391vmin}.lvc-dialog-header{padding:2.216vmin 2.77vmin;display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid rgba(18,187,237,.1)}.lvc-dialog-title{font-weight:700;color:var(--lvc-primary);letter-spacing:.138vmin}.lvc-dialog-close{cursor:pointer;color:var(--lvc-text-dim);font-size:2.493vmin;transition:all .3s;line-height:1}.lvc-dialog-close:hover{color:var(--lvc-primary);transform:rotate(90deg)}.lvc-dialog-body{padding:2.77vmin;min-height:11.08vmin;max-height:70vh;overflow-y:auto;line-height:1.6}.lvc-dialog-footer{padding:1.662vmin 2.77vmin;display:flex;justify-content:flex-end;gap:1.662vmin;background:#12bbed08}.lvc-dialog-btn{padding:.831vmin 2.216vmin;font-size:1.662vmin;border-radius:.554vmin;cursor:pointer;transition:all .3s;border:1px solid var(--lvc-border);background:transparent;color:var(--lvc-text-dim)}.lvc-dialog-btn:hover{border-color:var(--lvc-primary);color:var(--lvc-text);box-shadow:0 0 1.108vmin #12bbed33}.lvc-dialog-btn-primary{background:var(--lvc-primary);border-color:var(--lvc-primary);color:#fff}.lvc-dialog-btn-primary:hover{background:#15d2ff;box-shadow:0 0 1.662vmin #12bbed66}.lvc-dialog-fade-enter-active,.lvc-dialog-fade-leave-active{transition:opacity .3s}.lvc-dialog-fade-enter,.lvc-dialog-fade-leave-to{opacity:0}.lvc-dialog-zoom-enter-active,.lvc-dialog-zoom-leave-active{transition:transform .3s cubic-bezier(.34,1.56,.64,1)}.lvc-dialog-zoom-enter,.lvc-dialog-zoom-leave-to{transform:scale(.9) translateY(-2.77vmin)}.lvc-select{position:relative;display:inline-block;font-size:1.9391vmin;color:#fff;-webkit-user-select:none;user-select:none;height:100%;width:100%;z-index:10;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.lvc-select-wrapper{background:#0d2339;border:1px solid #1e4469;border-radius:.831vmin;padding:1.108vmin 1.662vmin;cursor:pointer;display:flex;align-items:center;justify-content:space-between;gap:1.108vmin;transition:all .3s;height:100%;box-sizing:border-box}.lvc-select-wrapper:hover,.lvc-select-wrapper.is-active{border-color:#12bbed;box-shadow:0 0 1.385vmin #12bbed4d}.lvc-select-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#fff;font-size:1.8006vmin;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.lvc-select-placeholder{color:#dffbff;opacity:.5}.lvc-select-suffix{display:flex;align-items:center;justify-content:center;width:2vmin;position:relative}.lvc-icon-arrow{color:#12bbed;font-size:1.385vmin;transition:transform .3s,opacity .2s}.lvc-icon-clear{position:absolute;color:#4a637a;font-size:1.6vmin;transition:color .2s;opacity:0;z-index:2}.lvc-icon-clear:hover{color:#12bbed}.lvc-select-wrapper:hover .is-clearable .lvc-icon-clear{opacity:1}.lvc-select-wrapper:hover .is-clearable .lvc-icon-arrow{opacity:0}.lvc-select-dropdown{position:fixed;top:0;left:0;width:100%;background:#0b1a2a;border:1px solid #12bbed;box-shadow:0 1.385vmin 4.1551vmin #000000b3;border-radius:.831vmin;z-index:10000;overflow:hidden;opacity:0;transition:opacity .25s cubic-bezier(.23,1,.32,1);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;backface-visibility:hidden;transform-style:preserve-3d}.lvc-select-list{list-style:none;padding:.5vmin 0;margin:0;max-height:25vmin;overflow-y:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.lvc-select-list::-webkit-scrollbar{width:.554vmin}.lvc-select-list::-webkit-scrollbar-thumb{background:#1e4469;border-radius:.277vmin}.lvc-select-list::-webkit-scrollbar-thumb:hover{background:#12bbed}.lvc-select-item{padding:1.108vmin 1.662vmin;cursor:pointer;font-size:1.662vmin;color:#dffbffb3;transition:all .2s;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.lvc-select-item:hover{background:#12bbed1a;color:#fff}.lvc-select-item.is-selected{background:#0b4868;color:#fff;font-weight:700}.lvc-select-item.is-disabled{color:#3d5061;cursor:not-allowed;background:transparent!important}.lvc-select-fade-enter-active,.lvc-select-fade-leave-active{transition:opacity .25s cubic-bezier(.23,1,.32,1),transform .25s cubic-bezier(.23,1,.32,1)}.lvc-select-fade-enter,.lvc-select-fade-leave-to{opacity:0;transform:translateY(-1vmin)}.lvc-switch{position:relative;display:inline-block;transition:.3s}.lvc-switch.is-disabled{opacity:.6}.lvc-dot{position:absolute;border-radius:50%;transition:.3s}.lvc-table-container{position:relative;width:100%;height:100%;display:flex;flex-direction:column;background:#0d233966;border:1px solid #1e4469;border-radius:.831vmin;overflow:hidden;color:#fff;font-size:1.462vmin}.lvc-table-header-wrapper{background:#1e446999;border-bottom:2px solid #12bbed;flex-shrink:0}.lvc-table-body-wrapper{flex:1;overflow-y:auto;position:relative}.lvc-table-body-wrapper::-webkit-scrollbar{width:.554vmin}.lvc-table-body-wrapper::-webkit-scrollbar-thumb{background:#1e4469;border-radius:.277vmin}.lvc-table{width:100%;border-collapse:collapse;table-layout:fixed}.lvc-table th,.lvc-table td{padding:2vmin 1.6vmin;border-bottom:1px solid rgba(30,68,105,.3);position:relative;height:4.5vmin;box-sizing:border-box;text-align:left}.lvc-table-column-center{text-align:center!important}.lvc-table-column-right{text-align:right!important}.lvc-table-column-left{text-align:left!important}.lvc-checkbox{position:relative;cursor:pointer;display:inline-block;vertical-align:middle;width:1.8vmin;height:1.8vmin;border:1px solid #12bbed;border-radius:.3vmin;background:#12bbed1a;transition:background .2s;box-sizing:border-box}.lvc-checkbox.checked{background:#12bbed}.lvc-checkbox.checked:after{content:"";position:absolute;left:.5vmin;top:.1vmin;width:.5vmin;height:.9vmin;border:solid #0d2339;border-width:0 .2vmin .2vmin 0;transform:rotate(45deg)}.lvc-sort-box{display:inline-flex;flex-direction:column;align-items:center;margin-left:.5vmin;vertical-align:middle;cursor:pointer}.lvc-sort-caret{width:0;height:0;border:.5vmin solid transparent}.lvc-sort-up{border-bottom-color:#4e6a86;margin-bottom:.2vmin}.lvc-sort-down{border-top-color:#4e6a86}.sorting-asc .lvc-sort-up{border-bottom-color:#12bbed}.sorting-desc .lvc-sort-down{border-top-color:#12bbed}.lvc-table th.is-sortable{cursor:pointer;-webkit-user-select:none;user-select:none}.lvc-table th.is-sortable:hover{background:#12bbed1a}.lvc-table-body-wrapper tr:hover{background:#12bbed0d}.lvc-table-body-wrapper tr.is-selected{background:#12bbed26}.lvc-table-empty{padding:5vmin 0;text-align:center;color:#dffbff80}.lvc-time-picker{position:relative;display:inline-block;font-size:1.4vmin;color:#fff;-webkit-user-select:none;user-select:none;width:100%;height:100%}.lvc-time-input-wrapper{background:#0d2339;border:1px solid #297077;border-radius:.831vmin;padding:0 1.108vmin;cursor:pointer;display:flex;align-items:center;justify-content:space-between;transition:all .3s;height:100%;width:100%}.lvc-time-input-wrapper:hover,.lvc-time-input-wrapper.is-active{border-color:#12bbed}.lvc-time-value{color:#e0f2fe}.lvc-time-icon{color:#7dd3fc;font-size:1.2vmin;transition:transform .3s}.lvc-time-input-wrapper.is-active .lvc-time-icon{transform:rotate(180deg)}.lvc-time-panel{position:fixed;background:#0d253f;border:1px solid #1a3a5a;border-radius:.5vmin;box-shadow:0 .5vmin 1.5vmin #00000080;z-index:999999;display:flex;flex-direction:column;width:20vmin;transition:top .1s,left .1s}.lvc-time-spinner{display:flex;height:25vmin;padding:1vmin 0}.lvc-time-column{flex:1;overflow-y:auto;scrollbar-width:none;text-align:center;scroll-behavior:smooth}.lvc-time-column::-webkit-scrollbar{display:none}.lvc-time-item{padding:1vmin 0;cursor:pointer;color:#7dd3fc;transition:all .2s;font-size:1.3vmin}.lvc-time-item:hover{background:#12bbed1a}.lvc-time-item.is-selected{color:#fff;background:#12bbed;font-weight:700}.lvc-time-item.is-disabled{color:#475569;cursor:not-allowed;background:transparent}.lvc-time-footer{border-top:1px solid #1a3a5a;padding:.8vmin;display:flex;justify-content:flex-end;gap:.8vmin}.lvc-btn{padding:.5vmin 1.5vmin;border-radius:.3vmin;cursor:pointer;font-size:1.2vmin;border:none;outline:none;transition:opacity .2s}.lvc-btn:active{opacity:.8}.lvc-btn-cancel{background:transparent;color:#7dd3fc}.lvc-btn-confirm{background:#12bbed;color:#fff}.lvc-load-more{display:flex;justify-content:center;align-items:center;padding:2vmin 0;width:100%;min-height:7.5vmin;color:#fff;font-size:1.8vmin;-webkit-user-select:none;user-select:none;height:7.5vmin}.lvc-load-more-spinner{position:relative;width:2.5vmin;height:2.5vmin;margin-right:1vmin;border-radius:50%;border:.2vmin solid transparent;border-top-color:#12bbed;border-bottom-color:#12bbed;animation:lvc-lm-spin 1s linear infinite}.lvc-load-more-spinner:after{content:"";position:absolute;top:.3vmin;left:.3vmin;right:.3vmin;bottom:.3vmin;border-radius:50%;border:.2vmin solid transparent;border-left-color:#7dd3fc;border-right-color:#7dd3fc;animation:lvc-lm-spin-reverse .8s linear infinite}.lvc-load-more-text{color:#fff;opacity:.8;letter-spacing:.1vmin}.lvc-load-more-disabled{color:#fff}@keyframes lvc-lm-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes lvc-lm-spin-reverse{0%{transform:rotate(0)}to{transform:rotate(-360deg)}}.lvc-date-picker{position:relative;display:inline-block;font-size:1.9391vmin;color:#fff;-webkit-user-select:none;user-select:none;height:100%}.lvc-input-wrapper{background:#0d2339;border:1px solid #1e4469;border-radius:.831vmin;padding:1.108vmin 1.662vmin;cursor:pointer;display:flex;align-items:center;gap:1.108vmin;min-width:33.241vmin;transition:all .3s;height:100%}.lvc-input-wrapper:hover,.lvc-input-wrapper.is-active{border-color:#12bbed;box-shadow:0 0 1.385vmin #12bbed4d}.lvc-inner-input{background:transparent;border:none;color:#fff;outline:none;width:100%;text-align:center;cursor:pointer;font-size:1.8006vmin}.lvc-input-wrapper>input::placeholder{color:#dffbff;opacity:.5}.lvc-input-wrapper>input::-moz-placeholder{color:#dffbff;opacity:.5}.lvc-input-wrapper>input:-ms-input-placeholder{color:#dffbff;opacity:.5}.lvc-separator{color:#4a637a;font-size:1.662vmin}.lvc-icon-arrow{color:#12bbed;font-size:1.385vmin;transition:transform .3s}.lvc-picker-panel{position:absolute;top:6.6482vmin;left:0;background:#0b1a2a;color:#fff;border:1px solid #12bbed;box-shadow:0 1.385vmin 4.1551vmin #000000b3;border-radius:1.108vmin;padding:2.0776vmin;z-index:9999}.lvc-time-bar{display:flex;gap:1.385vmin;margin-bottom:1.108vmin}.lvc-time-slot{flex:1;position:relative}.lvc-time-btn{background:#12bbed0d;border:1px solid #1e4469;border-radius:.554vmin;padding:.277vmin .831vmin;display:flex;flex-direction:column;align-items:center;cursor:pointer}.lvc-time-btn.is-active{border-color:#12bbed;background:#12bbed26}.lvc-time-val{font-family:monospace;font-size:2.2161vmin;color:#12bbed;font-weight:700}.lvc-label{font-size:1.385vmin;color:#5d758c}.lvc-time-dropdown{position:absolute;top:7.2022vmin;left:50%;transform:translate(-50%);background:#0d2339;border:1px solid #12bbed;border-radius:.554vmin;padding:1.108vmin;display:flex;gap:.554vmin;z-index:10001;box-shadow:0 .6925vmin 2.7701vmin #000c}.lvc-scroll-col{width:6.2327vmin;height:22.1607vmin;overflow-y:auto;background:#081625;scrollbar-width:none}.lvc-scroll-col::-webkit-scrollbar{display:none}.lvc-scroll-col ul{list-style:none;padding:0;margin:0;text-align:center}.lvc-scroll-col li{padding:.831vmin 0;cursor:pointer;color:#8cabc4;font-size:1.8006vmin}.lvc-scroll-col li:hover{color:#fff;background:#12bbed1a}.lvc-scroll-col li.is-selected{color:#fff;background:#12bbed;border-radius:.554vmin}.lvc-time-divider{align-self:center;color:#12bbed;font-weight:700}.lvc-calendars-wrap{display:flex;gap:2.7701vmin}.lvc-calendar-box{width:30.4709vmin}.lvc-cal-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:1.662vmin;color:#12bbed}.lvc-nav-btn{cursor:pointer;padding:0 1.108vmin;font-size:2.2161vmin}.lvc-cal-week{display:grid;grid-template-columns:repeat(7,1fr);text-align:center;color:#4a637a;font-size:1.662vmin;margin-bottom:1.108vmin}.lvc-cal-days{display:grid;grid-template-columns:repeat(7,1fr);text-align:center}.lvc-day{height:4.1551vmin;line-height:4.1551vmin;font-size:1.662vmin;cursor:pointer;border-radius:.554vmin;margin:1px 0;position:relative}.lvc-day:not(.is-empty):hover{background:#12bbed33}.lvc-day.is-active{background:#12bbed!important;color:#fff;font-weight:700}.lvc-day.is-in-range{background:#12bbed1a;color:#12bbed;border-radius:0}.lvc-day.is-in-hover-range{background:#12bbed33;color:#fff;border-radius:0}.lvc-day.is-today:after{content:"";position:absolute;bottom:.4155vmin;left:50%;width:.554vmin;height:.554vmin;background:#12bbed;border-radius:50%;transform:translate(-50%)}.lvc-panel-footer{border-top:1px solid rgba(255,255,255,.05);margin-top:.554vmin;padding-top:1.662vmin;display:flex;justify-content:space-between;align-items:center}.lvc-action-link{font-size:1.662vmin;color:#5d758c;cursor:pointer}.lvc-action-link:hover{color:#12bbed}.lvc-right-actions{display:flex;gap:1.385vmin}.lvc-action-btn{font-size:1.662vmin;cursor:pointer;padding:.554vmin 1.662vmin;border-radius:.554vmin}.lvc-action-btn.is-outline{border:1px solid #1e4469;color:#8cabc4}.lvc-action-btn.is-primary{background:#12bbed;color:#fff}.lvc-fade-enter-active,.lvc-fade-leave-active{transition:opacity .25s cubic-bezier(.23,1,.32,1),transform .25s cubic-bezier(.23,1,.32,1)}.lvc-fade-enter,.lvc-fade-leave-to{opacity:0;transform:translateY(1.662vmin) scale(.98)}.lvc-time-fade-enter-active,.lvc-time-fade-leave-active{transition:opacity .2s ease,transform .2s ease}.lvc-time-fade-enter,.lvc-time-fade-leave-to{opacity:0;transform:translate(-50%,1.385vmin)}.odometer.odometer-auto-theme,.odometer.odometer-theme-minimal{display:-moz-inline-box;-moz-box-orient:vertical;display:inline-block;vertical-align:middle;*vertical-align: auto;position:relative}.odometer.odometer-auto-theme,.odometer.odometer-theme-minimal{*display: inline}.odometer.odometer-auto-theme .odometer-digit,.odometer.odometer-theme-minimal .odometer-digit{display:-moz-inline-box;-moz-box-orient:vertical;display:inline-block;vertical-align:middle;*vertical-align: auto;position:relative}.odometer.odometer-auto-theme .odometer-digit,.odometer.odometer-theme-minimal .odometer-digit{*display: inline}.odometer.odometer-auto-theme .odometer-digit .odometer-digit-spacer,.odometer.odometer-theme-minimal .odometer-digit .odometer-digit-spacer{display:-moz-inline-box;-moz-box-orient:vertical;display:inline-block;vertical-align:middle;*vertical-align: auto;visibility:hidden}.odometer.odometer-auto-theme .odometer-digit .odometer-digit-spacer,.odometer.odometer-theme-minimal .odometer-digit .odometer-digit-spacer{*display: inline}.odometer.odometer-auto-theme .odometer-digit .odometer-digit-inner,.odometer.odometer-theme-minimal .odometer-digit .odometer-digit-inner{text-align:left;display:block;position:absolute;top:0;left:0;right:0;bottom:0;overflow:hidden}.odometer.odometer-auto-theme .odometer-digit .odometer-ribbon,.odometer.odometer-theme-minimal .odometer-digit .odometer-ribbon{display:block}.odometer.odometer-auto-theme .odometer-digit .odometer-ribbon-inner,.odometer.odometer-theme-minimal .odometer-digit .odometer-ribbon-inner{display:block;-webkit-backface-visibility:hidden}.odometer.odometer-auto-theme .odometer-digit .odometer-value,.odometer.odometer-theme-minimal .odometer-digit .odometer-value{display:block;-webkit-transform:translateZ(0)}.odometer.odometer-auto-theme .odometer-digit .odometer-value.odometer-last-value,.odometer.odometer-theme-minimal .odometer-digit .odometer-value.odometer-last-value{position:absolute}.odometer.odometer-auto-theme.odometer-animating-up .odometer-ribbon-inner,.odometer.odometer-theme-minimal.odometer-animating-up .odometer-ribbon-inner{-webkit-transition:-webkit-transform 2s;-moz-transition:-moz-transform 2s;-ms-transition:-ms-transform 2s;-o-transition:-o-transform 2s;transition:transform 2s}.odometer.odometer-auto-theme.odometer-animating-up.odometer-animating .odometer-ribbon-inner,.odometer.odometer-theme-minimal.odometer-animating-up.odometer-animating .odometer-ribbon-inner,.odometer.odometer-auto-theme.odometer-animating-down .odometer-ribbon-inner,.odometer.odometer-theme-minimal.odometer-animating-down .odometer-ribbon-inner{-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-ms-transform:translateY(-100%);-o-transform:translateY(-100%);transform:translateY(-100%)}.odometer.odometer-auto-theme.odometer-animating-down.odometer-animating .odometer-ribbon-inner,.odometer.odometer-theme-minimal.odometer-animating-down.odometer-animating .odometer-ribbon-inner{-webkit-transition:-webkit-transform 2s;-moz-transition:-moz-transform 2s;-ms-transition:-ms-transform 2s;-o-transition:-o-transform 2s;transition:transform 2s;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}.lvc-odometer{display:inline-flex;align-items:center;height:fit-content;overflow:hidden;gap:.2em}