@sauravluitel/date-time-picker-custom 1.0.1 β†’ 1.0.3

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/README.md CHANGED
@@ -1,56 +1,141 @@
1
- # Premium Date & Time Picker Custom
1
+ # @sauravluitel/date-time-picker-custom
2
2
 
3
- A high-performance, responsive React Date and Time picker project built with **Vite**, **Framer Motion**, and **Lucide React**.
3
+ [![npm version](https://img.shields.io/npm/v/@sauravluitel/date-time-picker-custom.svg)](https://www.npmjs.com/package/@sauravluitel/date-time-picker-custom)
4
+ [![license](https://img.shields.io/npm/l/@sauravluitel/date-time-picker-custom.svg)](https://github.com/Saurav-627/Custom-Date-Time-Picker)
5
+
6
+ A professional, high-performance, and responsive React Date and Time picker library. Built with **Vite**, **Framer Motion**, and **Lucide React**, it offers dedicated, premium UIs for both Desktop and Mobile devices.
7
+
8
+ ---
4
9
 
5
10
  ## ✨ Features
6
11
 
7
- - **πŸ“± Dedicated Mobile UI**:
8
- - **Date Picker**: Smooth wheel-like scroll select for Years, Months, and Days.
9
- - **Time Picker**: Interactive Visual Clock Faceβ€”ideal for illiterate users or quick selection.
10
- - **πŸ–₯️ Premium Desktop UI**:
11
- - **Date Picker**: Full-featured, elegant calendar grid.
12
- - **Time Picker**: Efficient grid-based select for Hours and Minutes.
13
- - **⌨️ Hybrid Input**: Support for both manual typing (with validation) and mouse/touch selection.
14
- - **🎨 Aesthetics**:
15
- - Glassmorphism design system.
16
- - Smooth micro-animations with Framer Motion.
17
- - Modern typography using the *Outfit* Google font.
18
- - Premium dark theme with vibrant blue accents.
19
-
20
- ## πŸš€ Getting Started
21
-
22
- 1. **Install dependencies**:
23
- ```bash
24
- npm install
25
- ```
26
-
27
- 2. **Run the development server**:
28
- ```bash
29
- npm run dev
30
- ```
31
-
32
- ## πŸ“¦ Project Structure
33
-
34
- - `src/components/DatePicker`: Contains the DatePicker logic and responsive views.
35
- - `src/components/TimePicker`: Contains the TimePicker logic and the Visual Clock Face.
36
- - `src/components/Shared`: Reusable components like the `SharedInput`.
37
- - `src/hooks`: Custom hooks like `useMediaQuery` for layout switching.
38
- - `src/index.css`: Core design system and theme variables.
12
+ - **πŸ“± Dedicated Mobile UI**:
13
+ - **Scroll-Wheel Select**: Smooth, iOS-style wheel selects for Years, Months, Days, and Time.
14
+ - **Touch Optimized**: Large tap targets and haptic-friendly scrolling.
15
+ - **React Portal Support (NEW)**: Renders via Portals to stay above all parents, even those with `transform` or `filter`.
16
+ - **πŸ–₯️ Premium Desktop UI**:
17
+ - **Elegant Calendar**: Full-featured grid with quick navigation between months and years.
18
+ - **Grid Time Select**: Fast and efficient grid selection for precision time setting.
19
+ - **πŸ”Œ Form Ready (NEW in v1.0.1)**:
20
+ - **Synthetic Events**: Emits standard `{ target: { name, value } }` objects.
21
+ - **Drop-in Support**: Seamlessly integrates with **React Hook Form**, **Formik**, and **Yup**.
22
+ - **Standard Formats**: Always returns standard strings (`YYYY-MM-DD` and `HH:mm`).
23
+ - **πŸ›‘οΈ Submission Protection**: All internal buttons are typed as `type="button"` to prevent accidental parent form submissions.
24
+ - **🎨 Glassmorphism & Themes**:
25
+ - **Manual Theme Control**: Toggle between Dark/Light modes regardless of system settings.
26
+ - **High Visibility**: High z-index (`999999`) ensures pickers always stay on top.
27
+ - **Modern Aesthetics**: Sleek glassmorphism with smooth micro-animations.
28
+
29
+ ---
30
+
31
+ ## πŸš€ Installation
32
+
33
+ ```bash
34
+ npm install @sauravluitel/date-time-picker-custom
35
+ # or
36
+ yarn add @sauravluitel/date-time-picker-custom
37
+ ```
38
+
39
+ ### ⚠️ Important: CSS Import
40
+ To use the premium styles, import the CSS file in your main entry file (e.g., `main.js` or `App.js`):
41
+
42
+ ```javascript
43
+ import '@sauravluitel/date-time-picker-custom/style.css';
44
+ ```
45
+
46
+ ---
39
47
 
40
48
  ## πŸ› οΈ Usage
41
49
 
50
+ ### Basic Example
51
+
42
52
  ```jsx
43
- import { DatePicker, TimePicker } from './components';
53
+ import React, { useState } from 'react';
54
+ import { DatePicker, TimePicker } from '@sauravluitel/date-time-picker-custom';
44
55
 
45
- function MyComponent() {
46
- const [date, setDate] = useState(new Date());
47
- const [time, setTime] = useState('12:00');
56
+ function App() {
57
+ const [date, setDate] = useState('2024-03-02');
58
+ const [time, setTime] = useState('14:30');
48
59
 
49
60
  return (
50
- <>
51
- <DatePicker value={date} onChange={setDate} />
52
- <TimePicker value={time} onChange={setTime} />
53
- </>
61
+ <div className="form-group">
62
+ <DatePicker
63
+ value={date}
64
+ onChange={(e) => setDate(e.target.value)}
65
+ />
66
+
67
+ <TimePicker
68
+ value={time}
69
+ onChange={(e) => setTime(e.target.value)}
70
+ use12h={true}
71
+ />
72
+ </div>
54
73
  );
55
74
  }
56
75
  ```
76
+
77
+ ---
78
+
79
+ ## πŸ“‹ Form Integration
80
+
81
+ ### React Hook Form
82
+
83
+ ```jsx
84
+ import { useForm, Controller } from "react-hook-form";
85
+ import { DatePicker } from "@sauravluitel/date-time-picker-custom";
86
+
87
+ function MyForm() {
88
+ const { control, handleSubmit } = useForm();
89
+
90
+ return (
91
+ <form onSubmit={handleSubmit(data => console.log(data))}>
92
+ <Controller
93
+ name="birthDate"
94
+ control={control}
95
+ render={({ field }) => (
96
+ <DatePicker
97
+ {...field}
98
+ placeholder="Select your birthday"
99
+ />
100
+ )}
101
+ />
102
+ <button type="submit">Submit</button>
103
+ </form>
104
+ );
105
+ }
106
+ ```
107
+
108
+ ---
109
+
110
+ ## βš™οΈ Props Reference
111
+
112
+ ### DatePicker
113
+ | Prop | Type | Default | Description |
114
+ | :--- | :--- | :--- | :--- |
115
+ | `value` | `string` | `""` | Date in `YYYY-MM-DD` format. |
116
+ | `onChange` | `function` | `-` | Returns standard synthetic event. |
117
+ | `placeholder` | `string` | `"YYYY/MM/DD"` | Placeholder for the input field. |
118
+ | `name` | `string` | `-` | Name for form integration. |
119
+ | `disabled` | `boolean` | `false` | Disables all interactions. |
120
+ | `isDarkMode` | `boolean` | `undefined` | Forces Dark Mode (`true`) or Light Mode (`false`). Default follows system. |
121
+
122
+ ### TimePicker
123
+ | Prop | Type | Default | Description |
124
+ | :--- | :--- | :--- | :--- |
125
+ | `value` | `string` | `""` | Time in `HH:mm` (24h) format. |
126
+ | `onChange` | `function` | `-` | Returns standard synthetic event. |
127
+ | `use12h` | `boolean` | `true` | Show AM/PM selector. |
128
+ | `showSeconds`| `boolean` | `false` | Show seconds selector. |
129
+ | `disabled` | `boolean` | `false` | Disables all interactions. |
130
+ | `isDarkMode` | `boolean` | `undefined` | Forces Dark Mode (`true`) or Light Mode (`false`). Default follows system. |
131
+
132
+ ---
133
+
134
+ ## πŸ’» Tech Stack
135
+ - **React** 18+
136
+ - **Framer Motion** (Animations)
137
+ - **Lucide React** (Icons)
138
+ - **date-fns** (Date logic)
139
+
140
+ ## πŸ“„ License
141
+ MIT Β© [Saurav Luitel](https://github.com/Saurav-627)
@@ -1 +1 @@
1
- @import"https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&display=swap";.datepicker-wrapper,.datepicker-wrapper *,.timepicker-wrapper,.timepicker-wrapper *{box-sizing:border-box;margin:0;padding:0;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-tap-highlight-color:transparent;font-family:Outfit,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;color:var(--text)}.datepicker-wrapper button,.timepicker-wrapper button{cursor:pointer;border:none;background:transparent;-moz-appearance:none;appearance:none;-webkit-appearance:none;outline:none;color:inherit}.datepicker-wrapper input,.timepicker-wrapper input{outline:none;border:none;background:transparent;-moz-appearance:none;appearance:none;-webkit-appearance:none;box-shadow:none;color:inherit}:root{--primary: #3b82f6;--primary-glow: rgba(59, 130, 246, .4);--secondary: #6366f1;--bg: #0f172a;--card-bg: rgba(30, 41, 59, 1);--text: #f8fafc;--text-dim: #94a3b8;--border: rgba(255, 255, 255, .1);--border-active: rgba(59, 130, 246, .5);--glass: rgba(15, 23, 42, .6);--hover-overlay: rgba(255, 255, 255, .1);--shadow-heavy: rgba(0, 0, 0, .5);--mobile-sheet-bg: rgba(15, 23, 42, 1);--radius: 12px;--transition: all .3s cubic-bezier(.4, 0, .2, 1)}@media(prefers-color-scheme:light){:root{--bg: #f1f5f9;--card-bg: rgba(255, 255, 255, 1);--text: #0f172a;--text-dim: #64748b;--border: rgba(0, 0, 0, .1);--glass: rgba(255, 255, 255, .8);--hover-overlay: rgba(0, 0, 0, .05);--shadow-heavy: rgba(0, 0, 0, .15);--mobile-sheet-bg: rgba(255, 255, 255, 1)}}.glass-card{background:var(--card-bg);border:1px solid var(--border);border-radius:var(--radius);box-shadow:0 8px 32px #0000004d}::-webkit-scrollbar{width:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:#ffffff1a;border-radius:10px}::-webkit-scrollbar-thumb:hover{background:#fff3}.animate-scale{transition:transform .2s ease}.animate-scale:active{transform:scale(.95)}.picker-dropdown{position:absolute;z-index:1000;margin-top:8px;overflow:hidden;box-shadow:0 10px 40px var(--shadow-heavy);background:var(--card-bg)!important}.picker-dropdown.mobile{position:fixed!important;inset:auto 0 0!important;border-radius:20px 20px 0 0!important;margin:0!important;max-height:48vh!important;width:100%!important;padding-bottom:calc(10px + env(safe-area-inset-bottom));box-shadow:0 -8px 32px var(--shadow-heavy);background:var(--mobile-sheet-bg)!important;backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px)}@media(max-width:768px){.picker-dropdown.desktop{display:none!important}}.mobile-backdrop{position:fixed;inset:0;background:#0009;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:999}.input-container.drop-up+.picker-dropdown{top:auto!important;bottom:100%!important;margin-bottom:8px;margin-top:0}.input-container.drop-down+.picker-dropdown{top:100%!important;bottom:auto!important}.scroll-columns{display:flex;justify-content:center;height:120px;min-height:120px;max-height:120px;overflow:hidden;position:relative;width:100%;margin:0 auto}.scroll-columns:after{content:"";position:absolute;top:44px;left:5%;width:90%;height:32px;background:var(--hover-overlay);border-top:1px solid var(--border);border-bottom:1px solid var(--border);pointer-events:none;border-radius:8px}.scroll-col{flex:1;max-width:70px;height:100%;max-height:120px;overflow-y:scroll;-webkit-overflow-scrolling:touch;scrollbar-width:none;display:flex;flex-direction:column;align-items:center;scroll-snap-type:y mandatory;padding:0;overscroll-behavior:none;position:relative;z-index:2}.scroll-col:before,.scroll-col:after{content:"";display:block;min-height:44px;flex-shrink:0;width:100%}.scroll-col::-webkit-scrollbar{display:none}.scroll-item{height:32px;min-height:32px;line-height:32px;display:flex;align-items:center;justify-content:center;font-size:1rem;color:var(--text-dim);transition:var(--transition);cursor:pointer;width:100%;scroll-snap-align:center;margin:0}.scroll-item.selected{font-weight:700;color:var(--primary);opacity:1;font-size:1.15rem}.mobile-scroll-picker{padding:16px 8px}.mobile-header{text-align:center;margin-bottom:12px;padding:0 16px}.mobile-header h3{margin-bottom:2px;font-size:1.2rem}.selected-preview{font-size:.9rem;color:var(--primary);font-weight:600}.confirm-btn{margin-top:16px;background-color:var(--primary)!important;padding:12px;border-radius:12px;font-weight:700;width:calc(100% - 32px);margin-left:16px;margin-right:16px;font-size:1rem;box-shadow:0 4px 12px var(--shadow-heavy);color:#fff!important;display:flex;justify-content:center;align-items:center}.input-container{display:flex;align-items:center;padding:10px 16px;gap:12px;transition:var(--transition);border:1px solid var(--border);width:100%;max-width:320px;position:relative;cursor:pointer}.input-container.focused{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-glow);background:var(--card-bg)}.input-icon-wrapper{cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--text-dim);transition:var(--transition)}.input-container.focused .input-icon-wrapper{color:var(--primary)}.shared-input{background:transparent;border:none;color:var(--text);font-size:16px;width:100%;font-weight:500;padding:0;margin:0;line-height:1.2}.shared-input:focus{outline:none!important;box-shadow:none!important}.shared-input::-moz-placeholder{color:var(--text-dim);opacity:.5}.shared-input::placeholder{color:var(--text-dim);opacity:.5}.clear-btn{color:var(--text-dim);opacity:.6;transition:var(--transition);display:flex;align-items:center;padding:4px;border-radius:50%}.clear-btn:hover{opacity:1;background:var(--hover-overlay);color:#ef4444}.input-container.error{border-color:#ef4444}.datepicker-wrapper{position:relative;width:-moz-fit-content;width:fit-content}.selector-view{width:320px;padding:16px}.grid-selector{display:grid;gap:8px;padding:8px}.grid-selector.column-3{grid-template-columns:repeat(3,1fr)}.grid-selector.column-4{grid-template-columns:repeat(4,1fr)}.select-cell{padding:12px 8px;border-radius:8px;font-size:.9rem;transition:var(--transition)}.select-cell:hover{background:var(--primary-glow);color:var(--primary)}.select-cell.active{background:var(--primary);color:#fff}.desktop-calendar{width:320px;padding:16px}.calendar-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px;font-weight:600}.header-nav{display:flex;gap:4px}.nav-btn{cursor:pointer;padding:4px 8px;border-radius:6px;transition:var(--transition)}.nav-btn:hover{background:var(--hover-overlay);color:var(--primary)}.calendar-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:8px}.calendar-day-header{font-size:.8rem;color:var(--text-dim);text-align:center;font-weight:600}.calendar-day-cell{width:100%;aspect-ratio:1;display:flex;align-items:center;justify-content:center;border-radius:8px;font-size:.9rem;transition:var(--transition);cursor:pointer}.calendar-day-cell:hover{background:var(--primary-glow);color:var(--primary)}.calendar-day-cell.active{background:var(--primary)!important;color:#fff!important}.calendar-day-cell.today{border:1px solid var(--primary);font-weight:700}.timepicker-wrapper{position:relative;width:-moz-fit-content;width:fit-content}.desktop-time-picker{width:260px;padding:12px;transition:width .3s ease}.desktop-time-picker.with-seconds{width:340px}.time-select-grid{display:flex;gap:12px}.time-col{flex:1;display:flex;flex-direction:column}.col-label{font-size:.8rem;color:var(--text-dim);text-transform:uppercase;margin-bottom:8px;text-align:center}.time-scroll{height:200px;overflow-y:auto;display:flex;flex-direction:column;gap:4px}.time-btn{padding:8px;border-radius:6px;font-size:.9rem;transition:var(--transition)}.time-btn:hover{background:var(--hover-overlay);color:var(--primary)}.time-btn.active{background:var(--primary);color:#fff}.desktop-footer{margin-top:12px;padding-top:12px;border-top:1px solid var(--border);display:flex;justify-content:flex-end}.confirm-btn.small{padding:6px 12px;font-size:.85rem;border-radius:8px;background:var(--primary);color:#fff;display:flex;align-items:center;font-weight:600}
1
+ @import"https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&display=swap";.datepicker-wrapper,.datepicker-wrapper *,.timepicker-wrapper,.timepicker-wrapper *,.datepicker-mobile-portal,.datepicker-mobile-portal *,.timepicker-mobile-portal,.timepicker-mobile-portal *{box-sizing:border-box;margin:0;padding:0;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-tap-highlight-color:transparent;font-family:Outfit,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;color:var(--text)}.datepicker-wrapper button,.timepicker-wrapper button{cursor:pointer;border:none;background:transparent;-moz-appearance:none;appearance:none;-webkit-appearance:none;outline:none;color:inherit}.datepicker-wrapper input,.timepicker-wrapper input{outline:none;border:none;background:transparent;-moz-appearance:none;appearance:none;-webkit-appearance:none;box-shadow:none;color:inherit}:root,.datepicker-wrapper,.timepicker-wrapper,.datepicker-mobile-portal,.timepicker-mobile-portal{--primary: #3b82f6;--primary-glow: rgba(59, 130, 246, .4);--secondary: #6366f1;--bg: #0f172a;--card-bg: rgba(30, 41, 59, 1);--text: #f8fafc;--text-dim: #94a3b8;--border: rgba(255, 255, 255, .1);--border-active: rgba(59, 130, 246, .5);--glass: rgba(15, 23, 42, .6);--hover-overlay: rgba(255, 255, 255, .1);--shadow-heavy: rgba(0, 0, 0, .5);--mobile-sheet-bg: rgba(15, 23, 42, 1);--radius: 12px;--transition: all .3s cubic-bezier(.4, 0, .2, 1)}@media(prefers-color-scheme:light){:root:not(.dark-theme),.datepicker-wrapper:not(.dark-theme),.timepicker-wrapper:not(.dark-theme),.datepicker-mobile-portal:not(.dark-theme),.timepicker-mobile-portal:not(.dark-theme){--bg: #f1f5f9;--card-bg: rgba(255, 255, 255, 1);--text: #0f172a;--text-dim: #64748b;--border: rgba(0, 0, 0, .1);--glass: rgba(255, 255, 255, .8);--hover-overlay: rgba(0, 0, 0, .05);--shadow-heavy: rgba(0, 0, 0, .15);--mobile-sheet-bg: rgba(255, 255, 255, 1)}}.datepicker-wrapper.light-theme,.timepicker-wrapper.light-theme,.datepicker-mobile-portal.light-theme,.timepicker-mobile-portal.light-theme{--bg: #f1f5f9;--card-bg: rgba(255, 255, 255, 1);--text: #0f172a;--text-dim: #64748b;--border: rgba(0, 0, 0, .1);--glass: rgba(255, 255, 255, .8);--hover-overlay: rgba(0, 0, 0, .05);--shadow-heavy: rgba(0, 0, 0, .15);--mobile-sheet-bg: rgba(255, 255, 255, 1)}.datepicker-wrapper.dark-theme,.timepicker-wrapper.dark-theme,.datepicker-mobile-portal.dark-theme,.timepicker-mobile-portal.dark-theme{--bg: #0f172a;--card-bg: rgba(30, 41, 59, 1);--text: #f8fafc;--text-dim: #94a3b8;--border: rgba(255, 255, 255, .1);--glass: rgba(15, 23, 42, .6);--hover-overlay: rgba(255, 255, 255, .1);--shadow-heavy: rgba(0, 0, 0, .5);--mobile-sheet-bg: rgba(15, 23, 42, 1)}.glass-card{background:var(--card-bg);border:1px solid var(--border);border-radius:var(--radius);box-shadow:0 8px 32px #0000004d}::-webkit-scrollbar{width:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:#ffffff1a;border-radius:10px}::-webkit-scrollbar-thumb:hover{background:#fff3}.animate-scale{transition:transform .2s ease}.animate-scale:active{transform:scale(.95)}.picker-dropdown{position:absolute;z-index:999999;margin-top:8px;overflow:hidden;box-shadow:0 10px 40px var(--shadow-heavy);background:var(--card-bg)!important}.picker-dropdown.mobile{position:fixed!important;inset:auto 0 0!important;border-radius:20px 20px 0 0!important;margin:0!important;max-height:48vh!important;width:100%!important;padding-bottom:calc(10px + env(safe-area-inset-bottom));box-shadow:0 -8px 32px var(--shadow-heavy);background:var(--mobile-sheet-bg)!important;backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px)}@media(max-width:768px){.picker-dropdown.desktop{display:none!important}}.mobile-backdrop{position:fixed;inset:0;background:#0009;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:999998}.input-container.drop-up+.picker-dropdown{top:auto!important;bottom:100%!important;margin-bottom:8px;margin-top:0}.input-container.drop-down+.picker-dropdown{top:100%!important;bottom:auto!important}.scroll-columns{display:flex;justify-content:center;height:120px;min-height:120px;max-height:120px;overflow:hidden;position:relative;width:100%;margin:0 auto}.scroll-columns:after{content:"";position:absolute;top:44px;left:5%;width:90%;height:32px;background:var(--hover-overlay);border-top:1px solid var(--border);border-bottom:1px solid var(--border);pointer-events:none;border-radius:8px}.scroll-col{flex:1;max-width:70px;height:100%;max-height:120px;overflow-y:scroll;-webkit-overflow-scrolling:touch;scrollbar-width:none;display:flex;flex-direction:column;align-items:center;scroll-snap-type:y mandatory;padding:0;overscroll-behavior:none;position:relative;z-index:2}.scroll-col:before,.scroll-col:after{content:"";display:block;min-height:44px;flex-shrink:0;width:100%}.scroll-col::-webkit-scrollbar{display:none}.scroll-item{height:32px;min-height:32px;line-height:32px;display:flex;align-items:center;justify-content:center;font-size:1rem;color:var(--text-dim);transition:var(--transition);cursor:pointer;width:100%;scroll-snap-align:center;margin:0}.scroll-item.selected{font-weight:700;color:var(--primary);opacity:1;font-size:1.15rem}.mobile-scroll-picker{padding:16px 8px}.mobile-header{text-align:center;margin-bottom:12px;padding:0 16px}.mobile-header h3{margin-bottom:2px;font-size:1.2rem}.selected-preview{font-size:.9rem;color:var(--primary);font-weight:600}.confirm-btn{margin-top:16px;background-color:var(--primary)!important;padding:12px;border-radius:12px;font-weight:700;width:calc(100% - 32px);margin-left:16px;margin-right:16px;font-size:1rem;box-shadow:0 4px 12px var(--shadow-heavy);color:#fff!important;display:flex;justify-content:center;align-items:center}.input-container{display:flex;align-items:center;padding:10px 16px;gap:12px;transition:var(--transition);border:1px solid var(--border);width:100%;max-width:320px;position:relative;cursor:pointer}.input-container.focused{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-glow);background:var(--card-bg)}.input-icon-wrapper{cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--text-dim);transition:var(--transition)}.input-container.focused .input-icon-wrapper{color:var(--primary)}.shared-input{background:transparent;border:none;color:var(--text);font-size:16px;width:100%;font-weight:500;padding:0;margin:0;line-height:1.2}.shared-input:focus{outline:none!important;box-shadow:none!important}.shared-input::-moz-placeholder{color:var(--text-dim);opacity:.5}.shared-input::placeholder{color:var(--text-dim);opacity:.5}.clear-btn{color:var(--text-dim);opacity:.6;transition:var(--transition);display:flex;align-items:center;padding:4px;border-radius:50%}.clear-btn:hover{opacity:1;background:var(--hover-overlay);color:#ef4444}.input-container.error{border-color:#ef4444}.datepicker-wrapper{position:relative;width:-moz-fit-content;width:fit-content}.selector-view{width:320px;padding:16px}.grid-selector{display:grid;gap:8px;padding:8px}.grid-selector.column-3{grid-template-columns:repeat(3,1fr)}.grid-selector.column-4{grid-template-columns:repeat(4,1fr)}.select-cell{padding:12px 8px;border-radius:8px;font-size:.9rem;transition:var(--transition)}.select-cell:hover{background:var(--primary-glow);color:var(--primary)}.select-cell.active{background:var(--primary);color:#fff}.desktop-calendar{width:320px;padding:16px}.calendar-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px;font-weight:600}.header-nav{display:flex;gap:4px}.nav-btn{cursor:pointer;padding:4px 8px;border-radius:6px;transition:var(--transition)}.nav-btn:hover{background:var(--hover-overlay);color:var(--primary)}.calendar-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:8px}.calendar-day-header{font-size:.8rem;color:var(--text-dim);text-align:center;font-weight:600}.calendar-day-cell{width:100%;aspect-ratio:1;display:flex;align-items:center;justify-content:center;border-radius:8px;font-size:.9rem;transition:var(--transition);cursor:pointer}.calendar-day-cell:hover{background:var(--primary-glow);color:var(--primary)}.calendar-day-cell.active{background:var(--primary)!important;color:#fff!important}.calendar-day-cell.today{border:1px solid var(--primary);font-weight:700}.timepicker-wrapper{position:relative;width:-moz-fit-content;width:fit-content}.desktop-time-picker{width:260px;padding:12px;transition:width .3s ease}.desktop-time-picker.with-seconds{width:340px}.time-select-grid{display:flex;gap:12px}.time-col{flex:1;display:flex;flex-direction:column}.col-label{font-size:.8rem;color:var(--text-dim);text-transform:uppercase;margin-bottom:8px;text-align:center}.time-scroll{height:200px;overflow-y:auto;display:flex;flex-direction:column;gap:4px}.time-btn{padding:8px;border-radius:6px;font-size:.9rem;transition:var(--transition)}.time-btn:hover{background:var(--hover-overlay);color:var(--primary)}.time-btn.active{background:var(--primary);color:#fff}.desktop-footer{margin-top:12px;padding-top:12px;border-top:1px solid var(--border);display:flex;justify-content:flex-end}.confirm-btn.small{padding:6px 12px;font-size:.85rem;border-radius:8px;background:var(--primary);color:#fff;display:flex;align-items:center;font-weight:600}