<style>
    .sipian-calendar-popover {
        position: fixed;
        z-index: 9999;
        width: min(380px, calc(100vw - 24px));
        border-radius: 28px;
        border: 1px solid rgba(219, 230, 247, 0.95);
        background:
            radial-gradient(circle at top right, rgba(79, 70, 229, 0.16), transparent 30%),
            radial-gradient(circle at bottom left, rgba(56, 189, 248, 0.14), transparent 28%),
            linear-gradient(180deg, rgba(255, 255, 255, 0.98), rgba(248, 251, 255, 0.98));
        box-shadow: 0 28px 70px rgba(15, 23, 42, 0.22);
        backdrop-filter: blur(18px);
        overflow: hidden;
        color: #0f172a;
        font-family: 'Inter', system-ui, -apple-system, sans-serif;
    }

    .sipian-calendar-head {
        padding: 18px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        border-bottom: 1px solid rgba(219, 230, 247, 0.92);
    }

    .sipian-calendar-title {
        min-width: 0;
    }

    .sipian-calendar-kicker {
        color: #4f46e5;
        font-size: 10px;
        font-weight: 900;
        letter-spacing: 0.14em;
        text-transform: uppercase;
    }

    .sipian-calendar-month {
        margin-top: 4px;
        color: #172554;
        font-size: 20px;
        font-weight: 900;
        letter-spacing: -0.04em;
    }

    .sipian-calendar-nav {
        display: inline-flex;
        align-items: center;
        gap: 8px;
    }

    .sipian-calendar-nav button,
    .sipian-calendar-action,
    .sipian-time-stepper {
        border: 1px solid rgba(214, 226, 247, 0.98);
        background: rgba(255, 255, 255, 0.9);
        color: #334155;
        cursor: pointer;
        transition: all 0.18s ease;
    }

    .sipian-calendar-nav button {
        width: 42px;
        height: 42px;
        border-radius: 16px;
        font-size: 20px;
        font-weight: 900;
        line-height: 1;
    }

    .sipian-calendar-nav button:hover,
    .sipian-calendar-action:hover,
    .sipian-time-stepper:hover {
        transform: translateY(-1px);
        border-color: rgba(79, 70, 229, 0.28);
        background: #eef2ff;
        color: #3730a3;
    }

    .sipian-calendar-body {
        padding: 16px 18px 18px;
    }

    .sipian-weekdays,
    .sipian-days {
        display: grid;
        grid-template-columns: repeat(7, minmax(0, 1fr));
        gap: 8px;
    }

    .sipian-weekdays {
        margin-bottom: 10px;
    }

    .sipian-weekdays span {
        text-align: center;
        color: #64748b;
        font-size: 11px;
        font-weight: 900;
        text-transform: uppercase;
    }

    .sipian-day {
        min-height: 42px;
        border: 1px solid transparent;
        border-radius: 15px;
        background: transparent;
        color: #1e293b;
        font-size: 14px;
        font-weight: 900;
        cursor: pointer;
        transition: all 0.18s ease;
    }

    .sipian-day:hover {
        transform: translateY(-1px);
        border-color: rgba(79, 70, 229, 0.20);
        background: #eef2ff;
        color: #3730a3;
    }

    .sipian-day.outside {
        color: #cbd5e1;
    }

    .sipian-day.today {
        border-color: rgba(56, 189, 248, 0.45);
        background: #f0f9ff;
        color: #0369a1;
    }

    .sipian-day.selected {
        border-color: transparent;
        background: linear-gradient(135deg, #4f46e5, #2563eb);
        color: #ffffff;
        box-shadow: 0 14px 26px rgba(79, 70, 229, 0.24);
    }

    .sipian-day.disabled {
        cursor: not-allowed;
        color: #cbd5e1;
        background: #f8fafc;
        text-decoration: line-through;
        opacity: 0.72;
    }

    .sipian-time-panel {
        margin-top: 16px;
        padding: 14px;
        border-radius: 22px;
        border: 1px solid rgba(219, 230, 247, 0.95);
        background: rgba(255, 255, 255, 0.78);
    }

    .sipian-time-label {
        margin-bottom: 10px;
        color: #64748b;
        font-size: 11px;
        font-weight: 900;
        letter-spacing: 0.12em;
        text-transform: uppercase;
    }

    .sipian-time-row {
        display: grid;
        grid-template-columns: 1fr auto 1fr;
        gap: 10px;
        align-items: center;
    }

    .sipian-time-box {
        display: grid;
        gap: 8px;
    }

    .sipian-time-stepper {
        height: 34px;
        border-radius: 13px;
        font-weight: 900;
    }

    .sipian-time-value {
        min-height: 48px;
        display: flex;
        align-items: center;
        justify-content: center;
        border-radius: 16px;
        background: linear-gradient(180deg, #ffffff, #f8fbff);
        border: 1px solid rgba(214, 226, 247, 0.98);
        color: #172554;
        font-size: 24px;
        font-weight: 900;
    }

    .sipian-time-separator {
        color: #64748b;
        font-size: 28px;
        font-weight: 900;
    }

    .sipian-calendar-footer {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 10px;
        padding: 14px 18px 18px;
        border-top: 1px solid rgba(219, 230, 247, 0.92);
        background: rgba(248, 251, 255, 0.74);
    }

    .sipian-calendar-action {
        min-height: 42px;
        padding: 0 14px;
        border-radius: 16px;
        font-size: 13px;
        font-weight: 900;
    }

    .sipian-calendar-action.primary {
        color: #ffffff;
        border-color: transparent;
        background: linear-gradient(135deg, #4f46e5, #2563eb);
        box-shadow: 0 14px 24px rgba(79, 70, 229, 0.22);
    }

    .sipian-calendar-action.primary:hover {
        color: #ffffff;
        background: linear-gradient(135deg, #4338ca, #1d4ed8);
    }

    @media (max-width: 640px) {
        .sipian-calendar-popover {
            left: 12px !important;
            right: 12px !important;
            bottom: 12px !important;
            top: auto !important;
            width: auto;
            border-radius: 30px;
        }

        .sipian-day {
            min-height: 46px;
        }
    }
</style>

<script>
    (function () {
        if (window.__sipianCustomCalendarLoaded) return;
        window.__sipianCustomCalendarLoaded = true;

        const monthNames = ['Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni', 'Juli', 'Agustus', 'September', 'Oktober', 'November', 'Desember'];
        const dayNames = ['Min', 'Sen', 'Sel', 'Rab', 'Kam', 'Jum', 'Sab'];
        let activeInput = null;
        let popover = null;
        let state = null;
        let justOpenedAt = 0;

        function pad(value) {
            return String(value).padStart(2, '0');
        }

        function toDateOnly(date) {
            return date.getFullYear() + '-' + pad(date.getMonth() + 1) + '-' + pad(date.getDate());
        }

        function toDateTimeValue(date, hour, minute) {
            return toDateOnly(date) + 'T' + pad(hour) + ':' + pad(minute);
        }

        function parseInputValue(input) {
            const raw = input.value || input.getAttribute('value') || '';
            const type = input.dataset.calendarType;

            if (raw) {
                const parsed = type === 'datetime-local'
                    ? new Date(raw.replace(' ', 'T'))
                    : new Date(raw + 'T00:00:00');

                if (!Number.isNaN(parsed.getTime())) {
                    return parsed;
                }
            }

            return new Date();
        }

        function parseBoundary(value, type, isMax = false) {
            if (!value) return null;
            const parsed = type === 'datetime-local'
                ? new Date(value.replace(' ', 'T'))
                : new Date(value + (isMax ? 'T23:59:59' : 'T00:00:00'));

            return Number.isNaN(parsed.getTime()) ? null : parsed;
        }

        function isSameDay(a, b) {
            return a && b
                && a.getFullYear() === b.getFullYear()
                && a.getMonth() === b.getMonth()
                && a.getDate() === b.getDate();
        }

        function clampTimePart(value, min, max) {
            return Math.max(min, Math.min(max, value));
        }

        function setInputValue(input, selectedDate, closeAfter = false) {
            const type = input.dataset.calendarType;
            const value = type === 'datetime-local'
                ? toDateTimeValue(selectedDate, state.hour, state.minute)
                : toDateOnly(selectedDate);

            input.value = value;
            input.dispatchEvent(new Event('input', { bubbles: true }));
            input.dispatchEvent(new Event('change', { bubbles: true }));

            if (closeAfter) closeCalendar();
        }

        function closeCalendar() {
            if (popover) {
                popover.remove();
                popover = null;
            }

            activeInput = null;
            state = null;
        }

        function positionPopover(input) {
            if (!popover) return;

            const rect = input.getBoundingClientRect();
            const popRect = popover.getBoundingClientRect();
            const gap = 10;
            let top = rect.bottom + gap;
            let left = rect.left;

            if (top + popRect.height > window.innerHeight - 12) {
                top = Math.max(12, rect.top - popRect.height - gap);
            }

            if (left + popRect.width > window.innerWidth - 12) {
                left = Math.max(12, window.innerWidth - popRect.width - 12);
            }

            popover.style.top = top + 'px';
            popover.style.left = left + 'px';
        }

        function isDisabledDate(date) {
            const start = new Date(date);
            start.setHours(0, 0, 0, 0);
            const min = state.min ? new Date(state.min) : null;
            const max = state.max ? new Date(state.max) : null;

            if (min) {
                const minStart = new Date(min);
                minStart.setHours(0, 0, 0, 0);
                if (start < minStart) return true;
            }

            if (max) {
                const maxStart = new Date(max);
                maxStart.setHours(0, 0, 0, 0);
                if (start > maxStart) return true;
            }

            return false;
        }

        function buildDays() {
            const firstDay = new Date(state.viewYear, state.viewMonth, 1);
            const gridStart = new Date(firstDay);
            gridStart.setDate(firstDay.getDate() - firstDay.getDay());

            const today = new Date();
            today.setHours(0, 0, 0, 0);

            let html = '';
            for (let i = 0; i < 42; i += 1) {
                const day = new Date(gridStart);
                day.setDate(gridStart.getDate() + i);

                const classes = ['sipian-day'];
                if (day.getMonth() !== state.viewMonth) classes.push('outside');
                if (isSameDay(day, today)) classes.push('today');
                if (isSameDay(day, state.selectedDate)) classes.push('selected');
                if (isDisabledDate(day)) classes.push('disabled');

                html += '<button type="button" class="' + classes.join(' ') + '" data-date="' + toDateOnly(day) + '">' + day.getDate() + '</button>';
            }

            return html;
        }

        function render() {
            if (!popover) {
                popover = document.createElement('div');
                popover.className = 'sipian-calendar-popover';
                document.body.appendChild(popover);
            }

            const isDateTime = activeInput.dataset.calendarType === 'datetime-local';
            popover.innerHTML = `
                <div class="sipian-calendar-head">
                    <div class="sipian-calendar-title">
                        <div class="sipian-calendar-kicker">Pilih tanggal</div>
                        <div class="sipian-calendar-month">${monthNames[state.viewMonth]} ${state.viewYear}</div>
                    </div>
                    <div class="sipian-calendar-nav">
                        <button type="button" data-calendar-prev aria-label="Bulan sebelumnya">&lsaquo;</button>
                        <button type="button" data-calendar-next aria-label="Bulan berikutnya">&rsaquo;</button>
                    </div>
                </div>
                <div class="sipian-calendar-body">
                    <div class="sipian-weekdays">${dayNames.map(day => `<span>${day}</span>`).join('')}</div>
                    <div class="sipian-days">${buildDays()}</div>
                    ${isDateTime ? `
                        <div class="sipian-time-panel">
                            <div class="sipian-time-label">Atur jam</div>
                            <div class="sipian-time-row">
                                <div class="sipian-time-box">
                                    <button type="button" class="sipian-time-stepper" data-time-up="hour">+</button>
                                    <div class="sipian-time-value">${pad(state.hour)}</div>
                                    <button type="button" class="sipian-time-stepper" data-time-down="hour">-</button>
                                </div>
                                <div class="sipian-time-separator">:</div>
                                <div class="sipian-time-box">
                                    <button type="button" class="sipian-time-stepper" data-time-up="minute">+</button>
                                    <div class="sipian-time-value">${pad(state.minute)}</div>
                                    <button type="button" class="sipian-time-stepper" data-time-down="minute">-</button>
                                </div>
                            </div>
                        </div>
                    ` : ''}
                </div>
                <div class="sipian-calendar-footer">
                    <button type="button" class="sipian-calendar-action" data-calendar-today>Hari ini</button>
                    <div class="flex gap-2">
                        <button type="button" class="sipian-calendar-action" data-calendar-close>Batal</button>
                        ${isDateTime ? '<button type="button" class="sipian-calendar-action primary" data-calendar-apply>Pakai Jadwal</button>' : ''}
                    </div>
                </div>
            `;

            positionPopover(activeInput);
        }

        function openCalendar(input) {
            if (input.readOnly || input.disabled) return;

            activeInput = input;
            justOpenedAt = Date.now();
            const selectedDate = parseInputValue(input);
            const type = input.dataset.calendarType;

            state = {
                selectedDate,
                viewMonth: selectedDate.getMonth(),
                viewYear: selectedDate.getFullYear(),
                hour: type === 'datetime-local' ? selectedDate.getHours() : 0,
                minute: type === 'datetime-local' ? selectedDate.getMinutes() : 0,
                min: parseBoundary(input.getAttribute('min'), type),
                max: parseBoundary(input.getAttribute('max'), type, true),
            };

            render();
        }

        function enhanceCalendarInputs(root = document) {
            root.querySelectorAll('input[type="date"], input[type="datetime-local"]').forEach(input => {
                if (input.dataset.customCalendarReady === 'true') return;
                if (input.readOnly || input.disabled) return;

                input.dataset.calendarType = input.type;
                input.dataset.customCalendarReady = 'true';
                input.type = 'text';
                input.autocomplete = 'off';
                input.inputMode = 'none';
                input.setAttribute('data-calendar-input', 'true');

                input.addEventListener('focus', () => openCalendar(input));
                input.addEventListener('pointerdown', event => {
                    event.stopPropagation();
                });
                input.addEventListener('click', event => {
                    event.stopPropagation();
                    openCalendar(input);
                });
                input.addEventListener('keydown', event => {
                    if (event.key === 'Escape') closeCalendar();
                    if (event.key === 'Enter' || event.key === ' ') {
                        event.preventDefault();
                        openCalendar(input);
                    }
                });
            });
        }

        document.addEventListener('click', event => {
            if (!popover) return;
            if (Date.now() - justOpenedAt < 120) return;
            if (popover.contains(event.target) || event.target === activeInput) return;
            closeCalendar();
        });

        document.addEventListener('click', event => {
            if (!popover || !state || !activeInput) return;

            const prev = event.target.closest('[data-calendar-prev]');
            const next = event.target.closest('[data-calendar-next]');
            const day = event.target.closest('[data-date]');
            const today = event.target.closest('[data-calendar-today]');
            const close = event.target.closest('[data-calendar-close]');
            const apply = event.target.closest('[data-calendar-apply]');
            const timeUp = event.target.closest('[data-time-up]');
            const timeDown = event.target.closest('[data-time-down]');

            if (prev) {
                state.viewMonth -= 1;
                if (state.viewMonth < 0) {
                    state.viewMonth = 11;
                    state.viewYear -= 1;
                }
                render();
                return;
            }

            if (next) {
                state.viewMonth += 1;
                if (state.viewMonth > 11) {
                    state.viewMonth = 0;
                    state.viewYear += 1;
                }
                render();
                return;
            }

            if (day) {
                if (day.classList.contains('disabled')) return;
                state.selectedDate = new Date(day.dataset.date + 'T00:00:00');
                state.viewMonth = state.selectedDate.getMonth();
                state.viewYear = state.selectedDate.getFullYear();

                if (activeInput.dataset.calendarType === 'date') {
                    setInputValue(activeInput, state.selectedDate, true);
                } else {
                    setInputValue(activeInput, state.selectedDate, false);
                    render();
                }
                return;
            }

            if (today) {
                const current = new Date();
                if (!isDisabledDate(current)) {
                    state.selectedDate = current;
                    state.viewMonth = current.getMonth();
                    state.viewYear = current.getFullYear();
                    if (activeInput.dataset.calendarType === 'datetime-local') {
                        state.hour = current.getHours();
                        state.minute = current.getMinutes();
                    }
                    setInputValue(activeInput, state.selectedDate, activeInput.dataset.calendarType === 'date');
                    render();
                }
                return;
            }

            if (timeUp || timeDown) {
                const target = (timeUp || timeDown).dataset.timeUp || (timeUp || timeDown).dataset.timeDown;
                const direction = timeUp ? 1 : -1;

                if (target === 'hour') {
                    state.hour = (state.hour + direction + 24) % 24;
                } else {
                    state.minute = clampTimePart(state.minute + direction, 0, 59);
                }

                setInputValue(activeInput, state.selectedDate, false);
                render();
                return;
            }

            if (apply) {
                setInputValue(activeInput, state.selectedDate, true);
                return;
            }

            if (close) {
                closeCalendar();
            }
        });

        window.addEventListener('resize', () => {
            if (activeInput) positionPopover(activeInput);
        });

        window.addEventListener('scroll', () => {
            if (activeInput) positionPopover(activeInput);
        }, true);

        document.addEventListener('DOMContentLoaded', () => enhanceCalendarInputs());
        window.SipianCustomCalendar = { enhance: enhanceCalendarInputs };
    })();
</script>
