react-appointment-scheduler
Version:
A production-ready React scheduler component for appointment management with day/week views, drag-and-drop, and TypeScript support
2 lines (1 loc) • 34 kB
CSS
:root{--scheduler-color-stone-50: #fafaf9;--scheduler-color-stone-100: #f5f5f4;--scheduler-color-stone-200: #e7e5e4;--scheduler-color-stone-300: #d6d3d1;--scheduler-color-stone-400: #a8a29e;--scheduler-color-stone-500: #78716c;--scheduler-color-stone-600: #57534e;--scheduler-color-stone-700: #44403c;--scheduler-color-stone-800: #292524;--scheduler-color-stone-900: #1c1917;--scheduler-color-rose-50: #fff1f2;--scheduler-color-rose-100: #ffe4e6;--scheduler-color-rose-200: #fecdd3;--scheduler-color-rose-300: #fda4af;--scheduler-color-rose-400: #fb7185;--scheduler-color-rose-500: #f43f5e;--scheduler-color-rose-600: #e11d48;--scheduler-color-rose-700: #be123c;--scheduler-color-rose-900: #881337;--scheduler-color-violet-50: #f5f3ff;--scheduler-color-violet-100: #ede9fe;--scheduler-color-violet-300: #c4b5fd;--scheduler-color-violet-400: #a78bfa;--scheduler-color-violet-900: #4c1d95;--scheduler-color-amber-50: #fffbeb;--scheduler-color-amber-100: #fef3c7;--scheduler-color-amber-300: #fcd34d;--scheduler-color-amber-400: #fbbf24;--scheduler-color-amber-900: #78350f;--scheduler-color-emerald-50: #ecfdf5;--scheduler-color-emerald-100: #d1fae5;--scheduler-color-emerald-300: #6ee7b7;--scheduler-color-emerald-400: #34d399;--scheduler-color-emerald-900: #064e3b;--scheduler-color-red-50: #fef2f2;--scheduler-color-red-200: #fecaca;--scheduler-color-red-300: #fca5a5;--scheduler-color-red-500: #ef4444;--scheduler-color-red-600: #dc2626;--scheduler-color-red-800: #991b1b;--scheduler-slot-height: 60px;--scheduler-time-column-width: 80px;--scheduler-border-radius-sm: .375rem;--scheduler-border-radius-md: .5rem;--scheduler-border-radius-lg: .75rem;--scheduler-border-radius-xl: 1rem;--scheduler-border-radius-2xl: 1.5rem;--scheduler-shadow-sm: 0 1px 2px 0 rgb(0 0 0 / .05);--scheduler-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--scheduler-shadow-md: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--scheduler-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--scheduler-shadow-xl: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--scheduler-shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / .25);--scheduler-transition-fast: .15s ease-out;--scheduler-transition-normal: .2s ease-out;--scheduler-transition-slow: .3s ease-out;--scheduler-bg-primary: #ffffff;--scheduler-bg-secondary: #fafaf9;--scheduler-bg-tertiary: rgba(250, 250, 249, .5);--scheduler-bg-hover: rgba(245, 245, 244, .5);--scheduler-text-primary: #1c1917;--scheduler-text-secondary: #44403c;--scheduler-text-tertiary: #78716c;--scheduler-border-primary: #e7e5e4;--scheduler-border-secondary: #d6d3d1;--scheduler-border-tertiary: #a8a29e}:root[data-theme=dark]{--scheduler-bg-primary: #1c1917;--scheduler-bg-secondary: #292524;--scheduler-bg-tertiary: rgba(41, 37, 36, .5);--scheduler-bg-hover: rgba(68, 64, 60, .5);--scheduler-text-primary: #fafaf9;--scheduler-text-secondary: #e7e5e4;--scheduler-text-tertiary: #a8a29e;--scheduler-border-primary: #44403c;--scheduler-border-secondary: #57534e;--scheduler-border-tertiary: #78716c;--scheduler-shadow-sm: 0 1px 2px 0 rgb(0 0 0 / .3);--scheduler-shadow: 0 1px 3px 0 rgb(0 0 0 / .4), 0 1px 2px -1px rgb(0 0 0 / .4);--scheduler-shadow-md: 0 4px 6px -1px rgb(0 0 0 / .4), 0 2px 4px -2px rgb(0 0 0 / .4);--scheduler-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / .5), 0 4px 6px -4px rgb(0 0 0 / .5);--scheduler-shadow-xl: 0 20px 25px -5px rgb(0 0 0 / .5), 0 8px 10px -6px rgb(0 0 0 / .5);--scheduler-shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / .6);--scheduler-color-rose-50: rgba(255, 241, 242, .1);--scheduler-color-rose-100: rgba(255, 228, 230, .15);--scheduler-color-violet-50: rgba(245, 243, 255, .1);--scheduler-color-violet-100: rgba(237, 233, 254, .15);--scheduler-color-amber-50: rgba(255, 251, 235, .1);--scheduler-color-amber-100: rgba(254, 243, 199, .15);--scheduler-color-emerald-50: rgba(236, 253, 245, .1);--scheduler-color-emerald-100: rgba(209, 250, 229, .15);--scheduler-color-red-50: rgba(254, 242, 242, .1)}[data-theme=dark] .form-input:focus,[data-theme=dark] .form-select:focus,[data-theme=dark] .form-textarea:focus{box-shadow:0 0 0 3px #fb718566}[data-theme=dark] .form-input:focus-visible,[data-theme=dark] .form-select:focus-visible,[data-theme=dark] .form-textarea:focus-visible{box-shadow:0 0 0 3px #fb718573}[data-theme=dark] .service-option.selected{background-color:#fb71851f}[data-theme=dark] .service-option.selected:focus,[data-theme=dark] .service-option.selected:focus-visible{box-shadow:0 0 0 3px #fb718566}.scheduler-container{display:flex;flex-direction:column;height:100%;background-color:var(--scheduler-bg-primary);border-radius:var(--scheduler-border-radius-xl);box-shadow:var(--scheduler-shadow-sm);border:1px solid var(--scheduler-border-primary);overflow:hidden}.scheduler-header{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1rem;border-bottom:1px solid var(--scheduler-border-primary);background-color:var(--scheduler-bg-tertiary)}.scheduler-nav{display:flex;align-items:center;gap:.5rem}.scheduler-nav-btn{padding:.5rem;border-radius:var(--scheduler-border-radius-lg);color:var(--scheduler-text-tertiary);transition:all var(--scheduler-transition-fast);background:none;border:none}.scheduler-nav-btn:hover{background-color:var(--scheduler-bg-hover);color:var(--scheduler-text-secondary)}.scheduler-nav-btn svg{width:1.25rem;height:1.25rem}.scheduler-nav-label{min-width:140px;padding:.375rem .75rem;text-align:center;font-size:.875rem;font-weight:500;color:var(--scheduler-text-secondary);border-radius:var(--scheduler-border-radius-lg);transition:background-color var(--scheduler-transition-fast);cursor:pointer;background:none;border:none}.scheduler-nav-label:hover{background-color:var(--scheduler-bg-hover)}.scheduler-controls{display:flex;align-items:center;gap:.75rem}.status-filter{display:inline-flex;align-items:center;gap:.5rem}.status-filter-label{font-size:.75rem;font-weight:600;color:var(--scheduler-text-tertiary);text-transform:uppercase;letter-spacing:.04em}.status-filter-select{min-width:140px;padding:.375rem .625rem;border:1px solid var(--scheduler-border-secondary);border-radius:var(--scheduler-border-radius-md);background-color:var(--scheduler-bg-primary);color:var(--scheduler-text-secondary);font-size:.875rem}.status-filter-select:focus{outline:none;border-color:var(--scheduler-color-rose-400);box-shadow:0 0 0 3px #fb718533}.scheduler-create-btn{display:inline-flex;align-items:center;gap:.5rem;padding:.375rem 1rem;background-color:var(--scheduler-color-rose-500);color:#fff;font-size:.875rem;font-weight:500;border-radius:var(--scheduler-border-radius-lg);border:none;transition:all var(--scheduler-transition-fast);box-shadow:var(--scheduler-shadow-sm)}.scheduler-create-btn:hover{background-color:var(--scheduler-color-rose-600);box-shadow:var(--scheduler-shadow)}.scheduler-create-btn svg{width:1rem;height:1rem}.view-toggle{display:inline-flex;background-color:var(--scheduler-bg-secondary);border-radius:var(--scheduler-border-radius-lg);padding:.25rem}.view-toggle-btn{padding:.375rem 1rem;font-size:.875rem;font-weight:500;border-radius:var(--scheduler-border-radius-md);transition:all var(--scheduler-transition-normal);background:none;border:none;color:var(--scheduler-text-tertiary)}.view-toggle-btn:hover{color:var(--scheduler-text-secondary)}.view-toggle-btn.active{background-color:var(--scheduler-bg-primary);color:var(--scheduler-text-primary);box-shadow:var(--scheduler-shadow-sm)}.scheduler-content{flex:1;overflow:hidden;position:relative}.view-container{display:flex;flex-direction:column;height:100%}.view-header{flex-shrink:0;padding:.75rem 1rem;border-bottom:1px solid var(--scheduler-border-primary);background-color:var(--scheduler-bg-primary)}.view-header-content{display:flex;align-items:center;gap:.75rem;margin-left:80px}.view-header-title{font-size:1.125rem;font-weight:600;color:var(--scheduler-text-primary)}.today-badge{padding:.125rem .5rem;font-size:.75rem;font-weight:500;background-color:var(--scheduler-color-rose-100);color:var(--scheduler-color-rose-700);border-radius:9999px}.view-scroll-area{flex:1;overflow:auto}.view-grid-container{display:flex;min-width:100%}.time-column{position:sticky;left:0;z-index:20;background-color:var(--scheduler-bg-secondary);border-right:1px solid var(--scheduler-border-primary);flex-shrink:0;width:80px}.time-column-spacer{height:48px;border-bottom:1px solid var(--scheduler-border-primary)}.time-slot-label{position:relative;display:flex;align-items:flex-start;justify-content:flex-end;padding-right:.75rem}.time-slot-label span{font-size:.75rem;font-weight:500;color:var(--scheduler-text-tertiary);margin-top:-.5rem;-webkit-user-select:none;user-select:none}.time-slot-divider{position:absolute;top:0;right:0;width:.75rem;border-top:1px solid var(--scheduler-border-secondary)}.columns-container{display:flex;flex:1}.day-column,.tech-column{flex:1;min-width:120px;border-right:1px solid var(--scheduler-border-primary);transition:background-color var(--scheduler-transition-fast)}.day-column:last-child,.tech-column:last-child{border-right:none}.tech-column{min-width:180px}.day-column.drag-over,.tech-column.drag-over{background-color:#fff1f24d}.column-header{position:sticky;top:0;z-index:10;padding:.5rem;text-align:center;border-bottom:1px solid var(--scheduler-border-primary);background-color:var(--scheduler-bg-primary)}.column-header.today{background-color:var(--scheduler-color-rose-50)}.column-header.drag-over{background-color:#fff1f280}.column-header-text{font-size:.875rem;font-weight:500;color:var(--scheduler-text-secondary)}.column-header-text.today{color:var(--scheduler-color-rose-700)}.tech-header-text{font-size:.875rem;font-weight:600;color:var(--scheduler-text-primary)}.today-dot{width:.375rem;height:.375rem;background-color:var(--scheduler-color-rose-400);border-radius:50%;margin:.25rem auto 0}.day-column.in-selected-range{background-color:#fb718514}.column-header.in-selected-range{background-color:var(--scheduler-color-rose-100);border-bottom-color:var(--scheduler-color-rose-200)}.column-header-text.in-selected-range{color:var(--scheduler-color-rose-700);font-weight:600}.selected-range-dot{width:.375rem;height:.375rem;background-color:var(--scheduler-color-rose-300);border-radius:50%;margin:.25rem auto 0}.grid-slots{position:relative}.grid-slot{border-bottom:1px solid var(--scheduler-border-primary);transition:background-color .1s;cursor:pointer}.grid-slot.hour-start{border-bottom-color:var(--scheduler-border-secondary)}.grid-slot:hover{background-color:var(--scheduler-bg-hover)}.grid-slot.slot-outside-hours{background-color:var(--scheduler-color-stone-100);cursor:default;pointer-events:none}[data-theme=dark] .grid-slot.slot-outside-hours{background-color:var(--scheduler-color-stone-800)}.appointments-layer{position:absolute;inset:0;pointer-events:none}.appointment-block{position:absolute;border-left-width:4px;border-left-style:solid;border-radius:0 var(--scheduler-border-radius-lg) var(--scheduler-border-radius-lg) 0;box-shadow:var(--scheduler-shadow-sm);transition:all var(--scheduler-transition-fast);overflow:hidden;pointer-events:auto;cursor:pointer}.appointment-block:hover{z-index:20}.appointment-block.dragging{opacity:.7;box-shadow:var(--scheduler-shadow-lg);transform:scale(1.02);cursor:grabbing}.appointment-block.selected{box-shadow:0 0 0 2px var(--scheduler-color-stone-400),0 0 0 4px #a8a29e33}.appointment-content{padding:.5rem;height:100%;display:flex;flex-direction:column}.appointment-badge{display:flex;align-items:center;gap:.375rem;margin-bottom:.125rem}.appointment-badge-dot{width:.5rem;height:.5rem;border-radius:50%;flex-shrink:0}.appointment-badge-text{font-size:.625rem;font-weight:500;text-transform:uppercase;letter-spacing:.05em;opacity:.75;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.appointment-client{font-weight:600;font-size:.875rem;line-height:1.25;white-space:nowrap;text-overflow:ellipsis}.appointment-details{margin-top:auto}.appointment-time{font-size:.75rem;opacity:.75}.appointment-status{font-size:.75rem;margin-top:.125rem;font-weight:600;text-transform:capitalize;letter-spacing:.02em;opacity:.9;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.appointment-status-pending{color:#9a3412}.appointment-status-confirmed{color:#166534}.appointment-status-canceled{color:#b91c1c}.appointment-status-completed{color:#1d4ed8}[data-theme=dark] .appointment-status-pending{color:#fbbf24}[data-theme=dark] .appointment-status-confirmed{color:#4ade80}[data-theme=dark] .appointment-status-canceled{color:#f87171}[data-theme=dark] .appointment-status-completed{color:#60a5fa}.appointment-artist{font-size:.75rem;opacity:.6;margin-top:.125rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.service-classic{background-color:var(--scheduler-color-rose-50);border-left-color:var(--scheduler-color-rose-300);color:var(--scheduler-color-rose-900)}.service-classic:hover{background-color:var(--scheduler-color-rose-100)}.service-classic .appointment-badge-dot{background-color:var(--scheduler-color-rose-400)}.service-hybrid{background-color:var(--scheduler-color-violet-50);border-left-color:var(--scheduler-color-violet-300);color:var(--scheduler-color-violet-900)}.service-hybrid:hover{background-color:var(--scheduler-color-violet-100)}.service-hybrid .appointment-badge-dot{background-color:var(--scheduler-color-violet-400)}.service-volume{background-color:var(--scheduler-color-amber-50);border-left-color:var(--scheduler-color-amber-300);color:var(--scheduler-color-amber-900)}.service-volume:hover{background-color:var(--scheduler-color-amber-100)}.service-volume .appointment-badge-dot{background-color:var(--scheduler-color-amber-400)}.service-refill{background-color:var(--scheduler-color-emerald-50);border-left-color:var(--scheduler-color-emerald-300);color:var(--scheduler-color-emerald-900)}.service-refill:hover{background-color:var(--scheduler-color-emerald-100)}.service-refill .appointment-badge-dot{background-color:var(--scheduler-color-emerald-400)}.appointment-block.technician-color{background-color:color-mix(in srgb,var(--block-color) 12%,transparent);border-left-color:var(--block-color);color:var(--scheduler-color-stone-900)}.appointment-block.technician-color:hover{background-color:color-mix(in srgb,var(--block-color) 18%,transparent)}.appointment-block.technician-color .appointment-badge-dot{background-color:var(--block-color)}[data-theme=dark] .appointment-block.technician-color{color:var(--scheduler-color-stone-100)}.drag-overlay{padding:.5rem .75rem;border-radius:var(--scheduler-border-radius-lg);box-shadow:var(--scheduler-shadow-xl);border-left:4px solid;opacity:.9}.drag-overlay.technician-color{background-color:color-mix(in srgb,var(--block-color) 12%,transparent);border-left-color:var(--block-color)}.drag-overlay-client{font-weight:600;font-size:.875rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.drag-overlay-service{font-size:.75rem;opacity:.75}.modal-backdrop{position:fixed;inset:0;z-index:50;display:flex;align-items:center;justify-content:center;padding:1rem}.modal-overlay{position:absolute;inset:0;background-color:#1c191766;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);animation:fadeIn .2s ease-out}.modal-content{position:relative;background-color:var(--scheduler-bg-primary);border-radius:var(--scheduler-border-radius-2xl);box-shadow:var(--scheduler-shadow-2xl);max-width:28rem;width:100%;max-height:90vh;overflow:auto;animation:zoomIn .2s ease-out;outline:none}.modal-content.large{max-width:32rem}.modal-header-strip{height:.5rem;border-radius:var(--scheduler-border-radius-2xl) var(--scheduler-border-radius-2xl) 0 0}.modal-close-btn{position:absolute;top:1rem;right:1rem;padding:.5rem;border-radius:50%;color:var(--scheduler-text-tertiary);background:none;border:none;transition:all var(--scheduler-transition-fast);z-index:10}.modal-close-btn:hover{color:var(--scheduler-text-secondary);background-color:var(--scheduler-bg-hover)}.modal-close-btn svg{width:1.25rem;height:1.25rem}.modal-body{padding:1.5rem}.modal-title{font-size:1.25rem;font-weight:600;color:var(--scheduler-text-primary);margin-bottom:1.25rem}.modal-colored-header{padding:1rem 1.5rem;border-radius:var(--scheduler-border-radius-2xl) var(--scheduler-border-radius-2xl) 0 0;border-bottom:1px solid}.modal-colored-header h2{font-size:1.25rem;font-weight:600}.modal-colored-header p{font-size:.875rem;margin-top:.25rem;opacity:.75}.side-panel{position:fixed;top:0;right:0;height:100%;width:24rem;max-width:100%;z-index:40;transform:translate(100%);transition:transform var(--scheduler-transition-slow)}.side-panel.open{transform:translate(0)}.side-panel-content{height:100%;background-color:var(--scheduler-bg-primary);box-shadow:var(--scheduler-shadow-2xl);border-left:1px solid var(--scheduler-border-primary);display:flex;flex-direction:column;outline:none}.panel-header-strip{height:.375rem;flex-shrink:0}.panel-header{display:flex;align-items:center;justify-content:space-between;padding:1rem;border-bottom:1px solid var(--scheduler-border-primary);flex-shrink:0}.panel-title{font-size:1.125rem;font-weight:600;color:var(--scheduler-text-primary)}.panel-body{flex:1;overflow-y:auto;padding:1rem}.form-group{margin-bottom:1rem}.form-label{display:block;font-size:.875rem;font-weight:500;color:var(--scheduler-text-secondary);margin-bottom:.375rem}.form-label .required{color:var(--scheduler-color-rose-500)}.form-input,.form-select,.form-textarea{width:100%;padding:.625rem 1rem;border:1px solid var(--scheduler-border-secondary);border-radius:var(--scheduler-border-radius-xl);font-size:.875rem;transition:border-color var(--scheduler-transition-fast),box-shadow var(--scheduler-transition-fast),background-color var(--scheduler-transition-fast);background-color:var(--scheduler-bg-primary);color:var(--scheduler-text-primary);outline:none}.form-input::placeholder,.form-textarea::placeholder{color:var(--scheduler-text-tertiary);opacity:.9}.form-input:hover:not(:disabled):not(:focus),.form-select:hover:not(:disabled):not(:focus),.form-textarea:hover:not(:disabled):not(:focus){border-color:var(--scheduler-border-tertiary)}.form-input:focus,.form-select:focus,.form-textarea:focus{border-color:var(--scheduler-color-rose-400);box-shadow:0 0 0 3px #fb718540}.form-input:focus-visible,.form-select:focus-visible,.form-textarea:focus-visible{border-color:var(--scheduler-color-rose-400);box-shadow:0 0 0 3px #fb71854d}.form-input:disabled,.form-select:disabled,.form-textarea:disabled{background-color:var(--scheduler-bg-secondary);color:var(--scheduler-text-tertiary);cursor:not-allowed;border-color:var(--scheduler-border-primary);opacity:.85}.form-input.sm,.form-select.sm,.form-textarea.sm{padding:.5rem .75rem;border-radius:var(--scheduler-border-radius-lg)}.form-textarea{resize:none}.form-helper-text{margin-top:.375rem;font-size:.75rem;color:var(--scheduler-text-secondary);font-style:italic}.form-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:.75rem}.service-category{margin-bottom:1rem}.service-category:last-child{margin-bottom:0}.service-category-label{display:block;font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--scheduler-text-secondary);margin-bottom:.5rem}.service-selector{display:grid;grid-template-columns:repeat(2,1fr);gap:.5rem}.service-option{padding:.75rem 1rem;border:2px solid var(--scheduler-border-primary);border-radius:var(--scheduler-border-radius-xl);text-align:left;transition:border-color var(--scheduler-transition-fast),background-color var(--scheduler-transition-fast),box-shadow var(--scheduler-transition-fast);background:var(--scheduler-bg-primary);color:var(--scheduler-text-primary);cursor:pointer;outline:none}.service-option:hover{border-color:var(--scheduler-border-secondary)}.service-option.selected{border-color:var(--scheduler-color-rose-400);background-color:var(--scheduler-color-rose-50);box-shadow:0 0 0 2px var(--scheduler-color-rose-200);color:var(--scheduler-text-primary)}.service-option:focus,.service-option:focus-visible{border-color:var(--scheduler-color-rose-400);box-shadow:0 0 0 3px #fb71854d}.service-option.selected:focus,.service-option.selected:focus-visible{border-color:var(--scheduler-color-rose-500);background-color:var(--scheduler-color-rose-50);box-shadow:0 0 0 3px var(--scheduler-color-rose-200)}.service-option-label{display:block;font-weight:500;font-size:.875rem}.service-option-duration{display:block;font-size:.75rem;color:var(--scheduler-text-tertiary);margin-top:.125rem}.service-option.selected .service-option-duration{opacity:.75}.job-builder{display:flex;gap:.5rem;align-items:flex-end}.job-builder-fields{display:flex;flex:1;gap:.5rem}.job-builder-fields .form-select{flex:1;min-width:0}.job-builder-add-btn{flex-shrink:0;white-space:nowrap}.jobs-list{background:var(--scheduler-bg-secondary);border:1px solid var(--scheduler-border-primary);border-radius:var(--scheduler-border-radius-xl);padding:.5rem;margin-bottom:.75rem}.job-entry{display:flex;align-items:center;gap:.625rem;padding:.5rem .625rem;border-radius:var(--scheduler-border-radius-lg);transition:background-color var(--scheduler-transition-fast)}.job-entry:hover{background-color:var(--scheduler-bg-tertiary, rgba(0, 0, 0, .03))}[data-theme=dark] .job-entry:hover{background-color:#ffffff0a}.job-entry-number{display:flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:50%;background-color:var(--scheduler-color-rose-100);color:var(--scheduler-color-rose-600);font-size:.6875rem;font-weight:700;flex-shrink:0}[data-theme=dark] .job-entry-number{background-color:#fb718526;color:var(--scheduler-color-rose-400)}.job-entry-info{flex:1;min-width:0}.job-entry-service{display:block;font-size:.8125rem;font-weight:600;color:var(--scheduler-text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.job-entry-tech{display:block;font-size:.75rem;color:var(--scheduler-text-secondary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.job-entry-duration{flex-shrink:0;font-size:.6875rem;font-weight:500;color:var(--scheduler-text-tertiary);background-color:var(--scheduler-bg-primary);border:1px solid var(--scheduler-border-primary);padding:.125rem .375rem;border-radius:9999px}.job-entry-remove{display:flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;border:none;background:transparent;color:var(--scheduler-text-tertiary);cursor:pointer;border-radius:50%;flex-shrink:0;transition:background-color var(--scheduler-transition-fast),color var(--scheduler-transition-fast)}.job-entry-remove:hover{background-color:var(--scheduler-color-rose-100);color:var(--scheduler-color-rose-600)}[data-theme=dark] .job-entry-remove:hover{background-color:#fb718526;color:var(--scheduler-color-rose-400)}.jobs-summary{display:flex;justify-content:space-between;align-items:center;padding:.5rem .625rem .25rem;border-top:1px solid var(--scheduler-border-primary);margin-top:.25rem;font-size:.75rem;color:var(--scheduler-text-secondary)}.jobs-summary-duration{font-weight:600;color:var(--scheduler-color-rose-500)}[data-theme=dark] .jobs-summary-duration{color:var(--scheduler-color-rose-400)}.btn{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;padding:.625rem 1rem;font-size:.875rem;font-weight:500;border-radius:var(--scheduler-border-radius-xl);border:none;transition:all var(--scheduler-transition-fast);cursor:pointer}.btn svg{width:1rem;height:1rem}.btn-primary{background-color:var(--scheduler-color-rose-500);color:#fff;box-shadow:var(--scheduler-shadow-sm)}.btn-primary:hover{background-color:var(--scheduler-color-rose-600);box-shadow:var(--scheduler-shadow)}.btn-primary:disabled{opacity:.5;cursor:not-allowed}.btn-secondary{background-color:var(--scheduler-bg-secondary);color:var(--scheduler-text-secondary)}.btn-secondary:hover{background-color:var(--scheduler-bg-hover)}.btn-outline{background:none;border:1px solid var(--scheduler-border-secondary);color:var(--scheduler-text-secondary)}.btn-outline:hover{background-color:var(--scheduler-bg-hover)}.btn-danger-outline{background:none;border:1px solid var(--scheduler-color-red-300);color:var(--scheduler-color-red-600)}.btn-danger-outline:hover{background-color:var(--scheduler-color-red-50)}.btn-danger{background-color:var(--scheduler-color-red-500);color:#fff}.btn-danger:hover{background-color:var(--scheduler-color-red-600)}.btn-ghost{background:none;color:var(--scheduler-color-rose-600);padding:.5rem .75rem}.btn-ghost:hover{background-color:var(--scheduler-color-rose-50);color:var(--scheduler-color-rose-700)}.btn-full{width:100%}.btn-group{display:flex;gap:.75rem;padding-top:.5rem}.btn-group>.btn{flex:1}.service-badge{display:inline-flex;align-items:center;gap:.5rem;padding:.25rem .75rem;border-radius:9999px;margin-bottom:1rem}.service-badge-dot{width:.5rem;height:.5rem;border-radius:50%}.service-badge-text{font-size:.875rem;font-weight:500}.detail-client-name{font-size:1.5rem;font-weight:600;color:var(--scheduler-text-primary);margin-bottom:1rem}.detail-list{display:flex;flex-direction:column;gap:.75rem}.detail-item{display:flex;align-items:flex-start;gap:.75rem}.detail-icon{width:2rem;height:2rem;border-radius:var(--scheduler-border-radius-lg);background-color:var(--scheduler-bg-secondary);display:flex;align-items:center;justify-content:center;flex-shrink:0}.detail-icon.lg{width:2.5rem;height:2.5rem;border-radius:var(--scheduler-border-radius-xl)}.detail-icon svg{width:1rem;height:1rem;color:var(--scheduler-text-tertiary)}.detail-icon.lg svg{width:1.25rem;height:1.25rem}.detail-item-content{padding-top:.25rem}.detail-item-label{font-size:.875rem;color:var(--scheduler-text-tertiary)}.detail-item-label.xs{font-size:.75rem;text-transform:uppercase;letter-spacing:.05em;font-weight:500}.detail-item-value{color:var(--scheduler-text-primary);font-weight:500;margin-top:.125rem}.detail-item-secondary{font-size:.875rem;color:var(--scheduler-text-tertiary);margin-top:.125rem}.detail-item-text{color:var(--scheduler-text-secondary);margin-top:.125rem}.delete-confirm{background-color:var(--scheduler-color-red-50);border:1px solid var(--scheduler-color-red-200);border-radius:var(--scheduler-border-radius-xl);padding:1rem}.delete-confirm.sm{border-radius:var(--scheduler-border-radius-lg);padding:.75rem}.delete-confirm-text{font-size:.875rem;color:var(--scheduler-color-red-800);margin-bottom:.75rem}.delete-confirm.sm .delete-confirm-text{margin-bottom:.5rem}.delete-confirm-actions{display:flex;gap:.5rem}.delete-confirm-actions .btn{flex:1;padding:.5rem .75rem;border-radius:var(--scheduler-border-radius-lg)}.datepicker-modal{position:relative;background-color:var(--scheduler-bg-primary);border-radius:var(--scheduler-border-radius-2xl);box-shadow:var(--scheduler-shadow-2xl);width:100%;max-width:24rem;margin:0 1rem;overflow:hidden;animation:zoomIn .2s ease-out}.datepicker-header{padding:1rem 1.25rem;border-bottom:1px solid var(--scheduler-border-primary);background-color:var(--scheduler-bg-tertiary)}.datepicker-title{font-size:1.125rem;font-weight:600;color:var(--scheduler-text-primary)}.datepicker-subtitle{font-size:.875rem;color:var(--scheduler-text-tertiary);margin-top:.125rem}.datepicker-calendar{padding:1rem}.datepicker-nav{display:flex;align-items:center;justify-content:space-between;margin-bottom:1rem}.datepicker-nav-btn{padding:.5rem;border-radius:var(--scheduler-border-radius-lg);color:var(--scheduler-text-tertiary);transition:all var(--scheduler-transition-fast);background:none;border:none}.datepicker-nav-btn:hover{background-color:var(--scheduler-bg-hover);color:var(--scheduler-text-secondary)}.datepicker-nav-btn svg{width:1.25rem;height:1.25rem}.datepicker-month-label{font-size:.875rem;font-weight:600;color:var(--scheduler-text-primary)}.datepicker-weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:.25rem;margin-bottom:.5rem}.datepicker-weekday{width:2.25rem;height:2rem;display:flex;align-items:center;justify-content:center;font-size:.75rem;font-weight:600;color:var(--scheduler-text-tertiary);text-transform:uppercase;letter-spacing:.05em}.datepicker-days{display:grid;grid-template-columns:repeat(7,1fr);gap:.25rem}.datepicker-day{width:2.25rem;height:2.25rem;font-size:.875rem;font-weight:500;border-radius:var(--scheduler-border-radius-lg);transition:all var(--scheduler-transition-fast);background:none;border:none;color:var(--scheduler-text-secondary);cursor:pointer}.datepicker-day:hover{background-color:var(--scheduler-bg-hover)}.datepicker-day.today{background-color:var(--scheduler-bg-secondary);color:var(--scheduler-text-primary);font-weight:600}.datepicker-day.today:hover{background-color:var(--scheduler-bg-hover)}.datepicker-day.selected{background-color:var(--scheduler-color-rose-500);color:#fff;box-shadow:var(--scheduler-shadow-md)}.datepicker-day.selected:hover{background-color:var(--scheduler-color-rose-600)}.datepicker-day.in-range{background-color:var(--scheduler-color-rose-100);color:var(--scheduler-color-rose-700)}.datepicker-day.in-range:hover{background-color:var(--scheduler-color-rose-200)}.datepicker-day.disabled{color:var(--scheduler-border-secondary);cursor:not-allowed}.datepicker-day-empty{width:2.25rem;height:2.25rem}.datepicker-range-info{margin-top:1rem;text-align:center;font-size:.875rem;color:var(--scheduler-text-tertiary)}.datepicker-footer{padding:1rem 1.25rem;border-top:1px solid var(--scheduler-border-primary);background-color:var(--scheduler-bg-tertiary);display:flex;align-items:center;justify-content:space-between;gap:.75rem}.datepicker-footer-actions{display:flex;gap:.5rem}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes zoomIn{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.scheduler-scroll{scroll-behavior:smooth}.scheduler-scroll::-webkit-scrollbar{width:8px;height:8px}.scheduler-scroll::-webkit-scrollbar-track{background:var(--scheduler-bg-secondary);border-radius:4px}.scheduler-scroll::-webkit-scrollbar-thumb{background:var(--scheduler-border-secondary);border-radius:4px}.scheduler-scroll::-webkit-scrollbar-thumb:hover{background:var(--scheduler-border-tertiary)}.week-header-bar{display:flex;border-bottom:1px solid var(--scheduler-border-primary);background-color:var(--scheduler-bg-primary);position:sticky;top:0;z-index:20}.week-header-spacer{width:80px;flex-shrink:0;border-right:1px solid var(--scheduler-border-primary)}.theme-toggle{display:inline-flex;align-items:center;justify-content:center;padding:.5rem;border-radius:var(--scheduler-border-radius-lg);color:var(--scheduler-text-tertiary);transition:all var(--scheduler-transition-fast);background:none;border:none;cursor:pointer}.theme-toggle:hover{background-color:var(--scheduler-bg-hover);color:var(--scheduler-text-secondary)}.theme-toggle svg{width:1.25rem;height:1.25rem}.scheduler-container{overscroll-behavior:contain}.appointment-block{touch-action:none;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}@media(pointer:coarse){.appointment-block{min-height:44px}.appointment-block:before{content:"";position:absolute;inset:-4px}}.scheduler-container.is-dragging,.scheduler-container.is-dragging .view-scroll-area{overflow:hidden}.drag-overlay{will-change:transform;-webkit-backface-visibility:hidden;backface-visibility:hidden}@media(max-width:768px){.scheduler-header{flex-direction:column;gap:.5rem;padding:.5rem .75rem}.scheduler-nav{width:100%;justify-content:center}.scheduler-controls{width:100%;justify-content:center;flex-wrap:wrap;gap:.5rem}.status-filter-label{display:none}.status-filter-select{min-width:110px;font-size:.8125rem}.scheduler-create-btn{padding:.375rem .75rem;font-size:.8125rem}.time-column{width:56px}.time-column-spacer{height:40px}.week-header-spacer{width:56px}.view-header-content{margin-left:56px}.time-slot-label span{font-size:.625rem}.time-slot-label{padding-right:.375rem}.day-column{min-width:90px}.tech-column{min-width:120px}.column-header{padding:.375rem}.column-header-text,.tech-header-text{font-size:.75rem}.appointment-content{padding:.25rem .375rem}.appointment-client{font-size:.75rem}.appointment-badge-text{font-size:.5625rem}.appointment-time,.appointment-status{font-size:.625rem}.modal-content{max-width:100%;margin:0 .5rem;max-height:95vh;border-radius:var(--scheduler-border-radius-xl)}.modal-content.large{max-width:100%}.modal-body{padding:1rem}.modal-title{font-size:1.125rem}.side-panel{width:100%}.form-grid,.service-selector{grid-template-columns:1fr}.job-builder{flex-direction:column;align-items:stretch}.job-builder-fields{flex-direction:column}.scheduler-nav-btn{padding:.625rem;min-width:44px;min-height:44px;display:flex;align-items:center;justify-content:center}.view-toggle-btn{padding:.5rem .75rem;min-height:36px}.datepicker-modal{max-width:100%;margin:0 .5rem}.btn{min-height:44px;padding:.625rem 1rem}.modal-close-btn{min-width:44px;min-height:44px}.grid-slot{min-height:44px}}@media(max-width:480px){.scheduler-header{padding:.375rem .5rem}.scheduler-nav-label{min-width:120px;font-size:.8125rem;padding:.25rem .5rem}.scheduler-controls{gap:.375rem}.time-column,.week-header-spacer{width:44px}.view-header-content{margin-left:44px}.time-slot-label span{font-size:.5625rem}.day-column{min-width:80px}.tech-column{min-width:100px}.column-header-text,.appointment-client{font-size:.6875rem}.appointment-badge-text{font-size:.5rem}.appointment-badge-dot{width:.375rem;height:.375rem}.view-toggle-btn{padding:.375rem .625rem;font-size:.75rem}.modal-backdrop{padding:.5rem}.modal-content{margin:0;border-radius:var(--scheduler-border-radius-lg);max-height:100vh}.datepicker-modal{margin:0}}@media(hover:none){.appointment-block:hover{z-index:10}.grid-slot:hover{background-color:transparent}.appointment-block:active{z-index:20;opacity:.85}.grid-slot:active{background-color:var(--scheduler-bg-hover)}.scheduler-nav-btn:active{background-color:var(--scheduler-bg-hover);color:var(--scheduler-text-secondary)}}