/* ZipTransfer Timepicker — iOS-style wheel picker (HH | : | MM @ 5 min)
   Native scroll-snap handles momentum and snapping. */

/* Fase 6.1a: estilos compartidos de validación inline. Mantenemos también las reglas
   inline en Home.ascx:289-308 como fallback durante 1-2 deploy cycles. En Fase 6.1b
   (deploy siguiente sin regresión) se removerán de Home.ascx. */
.zt-label-error {
    display: none;
    color: #d9534f;
    font-size: 12px;
    font-weight: 400;
    margin-left: 8px;
}
.zt-label-error.is-visible {
    display: inline;
}
.timeform.zt-has-error,
.zt-dt-native.zt-has-error,
.dateformMinDate.zt-has-error {
    border-color: #d9534f !important;
    box-shadow: 0 0 0 1px rgba(217, 83, 79, 0.15);
}

/* En .zt-dt-pair-row los inputs fecha + hora se renderizan pegados (sin
   border-right en fecha, sin border-left en hora) para parecer un único
   input. Cualquier box-shadow / outline en CUALQUIER estado (error, focus,
   hover) crea una línea visible en el borde compartido. Quitamos shadow y
   outline en TODOS los estados — el border-color rojo basta para indicar
   error, y el focus se ve por el cursor parpadeante dentro del input. */
.zt-dt-pair-row .dateformMinDate,
.zt-dt-pair-row .timeform,
.zt-dt-pair-row .dateformMinDate:focus,
.zt-dt-pair-row .timeform:focus,
.zt-dt-pair-row .dateformMinDate.zt-has-error,
.zt-dt-pair-row .timeform.zt-has-error {
    box-shadow: none !important;
    outline: none !important;
}
.zt-transfer-errors-container {
    background: #fef0f0;
    border-left: 3px solid #d9534f;
    padding: 10px 14px;
    margin-bottom: 12px;
    border-radius: 4px;
}
.zt-transfer-errors-container .zt-label-error {
    margin-left: 0;
    font-size: 14px;
}

.zt-tp-wrap {
    position: relative;
    display: block;
}

.zt-tp-wrap > input.timeform {
    cursor: pointer;
    transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}

/* --- Sheet (outer container) --- */

.zt-tp-sheet {
    background: #fff;
    border: 1px solid #ccc;
    border-radius: 8px;
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.14);
    z-index: 9999;
    font-family: inherit;
    color: #333;
    animation: ztTpFadeIn 0.15s ease-out;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    user-select: none;
    -webkit-user-select: none;
}

/* Backdrop translúcido: visual cue de que la interacción debe ser con el picker.
   z-index justo debajo del sheet (9998 < 9999). Click cierra con commit.
   touch-action: none + overscroll-behavior: contain bloquean el scroll por gesto
   (dedo en móvil, trackpad en desktop) encima del backdrop. */
.zt-tp-backdrop {
    position: fixed;
    top: 0; left: 0; right: 0; bottom: 0;
    background: rgba(0, 0, 0, 0.35);
    z-index: 9998;
    animation: ztTpBackdropIn 0.15s ease-out;
    touch-action: none;
    overscroll-behavior: contain;
}

/* La fila que contiene el par fecha+hora se eleva por encima del backdrop
   cuando hay un picker abierto. Dos clases para que time picker y date picker
   puedan operar independientemente sin pisarse entre sí (cerrar uno no quita
   la elevación si el otro sigue abierto). Mismo z-index que el sheet (9999)
   → ambos por encima del backdrop (9998); sheet y row no se solapan visualmente
   (sheet se posiciona debajo o encima del row, nunca over). */
.zt-tp-elevated,
.zt-dp-elevated {
    position: relative;
    z-index: 9999;
}

/* bootstrap-datepicker dropdown debe renderizar por encima del backdrop cuando
   éste está activo. Default z-index es 400; lo subimos a 9999 (= timepicker sheet). */
.datepicker-dropdown {
    z-index: 9999 !important;
}
@keyframes ztTpBackdropIn {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* Footer con botón OK — centrado en desktop. En mobile (max-width: 767)
   el override de abajo lo hace stretch full-width. */
.zt-tp-footer {
    display: flex;
    justify-content: center;
    padding: 8px 10px 10px;
    border-top: 1px solid #eee;
    flex-shrink: 0;
}
.zt-tp-ok {
    appearance: none;
    -webkit-appearance: none;
    background: #f5a623;
    color: #fff;
    border: none;
    border-radius: 4px;
    padding: 6px 18px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    min-width: 60px;
    transition: background-color 0.15s ease;
}
.zt-tp-ok:hover, .zt-tp-ok:focus {
    background: #e89612;
    outline: none;
}
.zt-tp-ok:active { background: #d18610; }

@keyframes ztTpFadeIn {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}

.zt-tp-sheet.zt-tp-closing {
    animation: ztTpFadeOut 0.15s ease-in forwards;
    pointer-events: none;
}

@keyframes ztTpFadeOut {
    from { opacity: 1; transform: translateY(0); }
    to   { opacity: 0; transform: translateY(-4px); }
}

/* --- Header (hidden on desktop, shown on mobile) --- */

.zt-tp-header {
    display: none;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px 8px;
    border-bottom: 1px solid #eee;
    flex-shrink: 0;
}

.zt-tp-header-label {
    font-size: 16px;
    font-weight: 600;
    color: #333;
}

.zt-tp-close {
    appearance: none;
    -webkit-appearance: none;
    background: transparent;
    border: none;
    font-size: 28px;
    line-height: 1;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    color: #888;
    cursor: pointer;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background-color 0.15s ease, color 0.15s ease;
}
.zt-tp-close:hover, .zt-tp-close:focus {
    background: rgba(0, 0, 0, 0.06);
    color: #333;
    outline: none;
}
.zt-tp-close:active { background: rgba(0, 0, 0, 0.12); }

/* --- Wheels container --- */

.zt-tp-wheels {
    /* 5 visible rows × 36px = 180px viewport. Chevron height (--zt-chev-h) adds
       vertical breathing room above and below each wheel. */
    --zt-row-h: 36px;
    --zt-rows: 5;
    --zt-chev-h: 30px;
    position: relative;
    display: flex;
    flex-direction: row;
    align-items: stretch;
    justify-content: center;
    height: calc(var(--zt-row-h) * var(--zt-rows) + var(--zt-chev-h) * 2);
    padding: 0 10px;
    background: #fff;
}

.zt-tp-col-container {
    position: relative;
    display: flex;
    flex-direction: column;
    flex: 0 1 72px;
    min-width: 0;
    height: 100%;
}

.zt-tp-chev {
    appearance: none;
    -webkit-appearance: none;
    background: transparent;
    border: none;
    cursor: pointer;
    padding: 0;
    margin: 0;
    color: #E89E00;
    line-height: 1;
    height: var(--zt-chev-h);
    flex: 0 0 var(--zt-chev-h);
    transition: color 0.15s ease, transform 0.1s ease;
    user-select: none;
    -webkit-user-select: none;
    text-align: center;
    font-family: inherit;
    display: flex;
    align-items: center;
    justify-content: center;
}

.zt-tp-chev .fa {
    font-size: 16px;
    line-height: 1;
}

.zt-tp-chev:hover {
    color: #B37E00;
}

.zt-tp-chev:hover .fa {
    transform: scale(1.15);
}

.zt-tp-chev:active {
    color: #8a6200;
}

.zt-tp-chev:active .fa {
    transform: scale(0.9);
    transition: transform 0.05s ease;
}

.zt-tp-wheel {
    list-style: none;
    margin: 0;
    padding: 0;
    min-width: 0;
    flex: 1 1 auto;
    /* position: relative makes the UL the offsetParent for its <li> children.
       Critical: getCenteredValue compares li.offsetTop (relative to offsetParent)
       with col.scrollTop+clientHeight/2 (scroll coord of the UL). Without this,
       offsetParent bubbles up to the positioned col-container, introducing a
       chev-up-height offset that shifts the "centered" detection by one row. */
    position: relative;
    /* Border-box + no padding → clientHeight = height = exactly N rows (180px).
       Centering is done via spacer <li> items, not CSS padding, to keep
       getCenteredValue math and scroll-snap alignment consistent. */
    box-sizing: border-box;
    height: calc(var(--zt-row-h) * var(--zt-rows));
    overflow-y: scroll;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: y mandatory;
    scrollbar-width: none;
    text-align: center;
    /* Mobile touch UX:
       - pan-y: only vertical swipes drive the wheel; the browser handles horizontal
         natively (e.g. back-swipe on iOS) without interference.
       - overscroll-behavior: contain: when the wheel hits top/bottom, the scroll
         does NOT bubble up to the page. Without this, rubber-banding on iOS would
         drag the body behind the bottom sheet. */
    touch-action: pan-y;
    overscroll-behavior-y: contain;
    /* Top/bottom edges fade out so items drift off the wheel instead of popping. */
    -webkit-mask-image: linear-gradient(to bottom,
        rgba(0,0,0,0) 0%,
        rgba(0,0,0,0.4) 14%,
        rgba(0,0,0,1) 40%,
        rgba(0,0,0,1) 60%,
        rgba(0,0,0,0.4) 86%,
        rgba(0,0,0,0) 100%);
            mask-image: linear-gradient(to bottom,
        rgba(0,0,0,0) 0%,
        rgba(0,0,0,0.4) 14%,
        rgba(0,0,0,1) 40%,
        rgba(0,0,0,1) 60%,
        rgba(0,0,0,0.4) 86%,
        rgba(0,0,0,0) 100%);
}

.zt-tp-wheel::-webkit-scrollbar { display: none; }

.zt-tp-wheel li {
    height: var(--zt-row-h);
    line-height: var(--zt-row-h);
    font-size: 17px;
    font-weight: 500;
    color: #999;
    cursor: pointer;
    scroll-snap-align: center;
    transition: color 0.15s ease, font-size 0.15s ease, font-weight 0.15s ease;
    letter-spacing: 0.04em;
}

.zt-tp-wheel li.zt-tp-active {
    color: #333;
    font-weight: 600;
    font-size: 19px;
}

/* Fase 2: items que violan antelación se pintan en rojo como cue visual,
   pero siguen siendo seleccionables. La validación final aparece como
   mensaje inline + borde rojo en el input cuando el user los elige. */
.zt-tp-wheel li.zt-tp-disabled,
.zt-tp-wheel li[aria-disabled="true"] {
    color: #c33;
}

.zt-tp-wheel li.zt-tp-active.zt-tp-disabled {
    color: #c33;
}

/* Spacer rows: reserve vertical space so real items can reach the visual center
   at the start/end of the wheel, but are invisible and not interactable. */
.zt-tp-wheel li.zt-tp-spacer {
    height: var(--zt-row-h);
    cursor: default;
    pointer-events: none;
    visibility: hidden;
    scroll-snap-align: none;
}

/* Colon separator — looks like a digital clock display. */
.zt-tp-wheel-colon {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 22px;
    font-weight: 600;
    color: #333;
    padding: 0 4px;
    pointer-events: none;
    flex: 0 0 auto;
}

/* Horizontal band showing the "selection window" — thin amber rules top/bottom
   of the center row plus a very subtle amber wash inside. Vertical center is
   still 50% of .zt-tp-wheels because the chevrons are symmetric (same height
   top and bottom), so the wheel's vertical center coincides with the wheels'. */
.zt-tp-wheel-band {
    position: absolute;
    left: 10px;
    right: 10px;
    top: 50%;
    transform: translateY(-50%);
    height: var(--zt-row-h);
    pointer-events: none;
    border-top: 1px solid rgba(251, 191, 16, 0.55);
    border-bottom: 1px solid rgba(251, 191, 16, 0.55);
    background: rgba(251, 191, 16, 0.06);
    z-index: 1;
}

/* --- Body scroll lock while a mobile bottom sheet is open.
   Defense in depth: overscroll-behavior on the wheels is the primary guard,
   this class is a belt-and-suspenders for browsers without good support. --- */
html.zt-tp-no-scroll,
body.zt-tp-no-scroll {
    overflow: hidden !important;
    overscroll-behavior: contain;
    touch-action: none;
}
body.zt-tp-no-scroll {
    /* Compensa el ancho del scrollbar al ocultarlo para evitar que el contenido
       salte horizontalmente al abrir el picker. */
    padding-right: var(--zt-scrollbar-w, 0px);
}

/* --- Native mode (mobile) — iOS/Android `<input type="time">` --- */

/* The [type="time"] selector only matches inputs in native mode (wheel-mode
   inputs stay type="text"), so these rules are scoped automatically. */
input.timeform[type="time"] {
    -webkit-appearance: none;
    appearance: none;
    font-family: inherit;
    font-size: inherit;
    line-height: normal;
}

.zt-native-wrap {
    position: relative;
    display: block;
}

.zt-native-wrap > input.timeform[type="time"] {
    position: relative;
    z-index: 1;
}

/* Hide the OS-drawn "--:--" when the input is empty AND not focused, so our
   fake placeholder (span below) is what the user sees in the idle state.
   When the input IS focused (iOS picker open), we want color:inherit back so
   iOS can draw the live value as the user scrolls the wheel — otherwise the
   input looks hollow/transparent during interaction. Selectors also target
   the iOS pseudo-elements because color:transparent on the input alone
   doesn't always cascade to ::-webkit-datetime-edit* on older iOS. */
.zt-native-wrap:not(.has-value) > input.timeform[type="time"]:not(:focus),
.zt-native-wrap:not(.has-value) > input.timeform[type="time"]:not(:focus)::-webkit-date-and-time-value,
.zt-native-wrap:not(.has-value) > input.timeform[type="time"]:not(:focus)::-webkit-datetime-edit,
.zt-native-wrap:not(.has-value) > input.timeform[type="time"]:not(:focus)::-webkit-datetime-edit-fields-wrapper,
.zt-native-wrap:not(.has-value) > input.timeform[type="time"]:not(:focus)::-webkit-datetime-edit-hour-field,
.zt-native-wrap:not(.has-value) > input.timeform[type="time"]:not(:focus)::-webkit-datetime-edit-minute-field,
.zt-native-wrap:not(.has-value) > input.timeform[type="time"]:not(:focus)::-webkit-datetime-edit-text {
    color: transparent;
}

.zt-native-placeholder {
    position: absolute;
    top: 50%;
    left: 12px; /* matches .form-control padding-left */
    transform: translateY(-50%);
    color: #989898; /* matches `.form-control::placeholder !important` in Master.css */
    pointer-events: none;
    font-family: inherit;
    font-size: inherit;
    line-height: 1;
    z-index: 2;
    transition: opacity 0.15s ease, visibility 0s linear 0.15s;
}

.zt-native-wrap.has-value .zt-native-placeholder,
.zt-native-wrap:focus-within .zt-native-placeholder {
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.15s ease, visibility 0s linear 0s;
}

/* --- Unified datetime-local native (mobile touch-primary) ---
   Replaces the (fecha + hora) pair with a single <input type="datetime-local">.
   Toggled via body.zt-touch-primary so desktop keeps the pair UI untouched. */

.zt-dt-native-row { display: none; }

/* Pre-JS: replicar la detección de `isTouchPrimary()` en CSS para evitar FOUC.
   El JS de zt-timepicker.js añade `body.zt-touch-primary` después de DOM ready,
   pero hasta entonces el browser pinta el pair-row (desktop) y luego lo swap-ea
   por el native-row (mobile). Esta media query hace el swap síncrono al primer
   render. Condiciones idénticas a `ZTTimePicker._isTouchPrimary()`:
     - (pointer: coarse): primary pointer es dedo (phones/tablets)
     - (max-width: 767px): fallback para browsers viejos sin pointer media query */
@media (pointer: coarse), (max-width: 767px) {
    .zt-dt-native-row { display: block; }
    .zt-dt-pair-row { display: none; }
}

/* Post-JS: la clase `zt-touch-primary` (specificity > media query) confirma la
   detección y sobrevive aunque `pointer:coarse` no estuviera disponible. */
body.zt-touch-primary .zt-dt-native-row { display: block; }
body.zt-touch-primary .zt-dt-pair-row { display: none; }

input.zt-dt-native {
    -webkit-appearance: none;
    appearance: none;
    font-family: inherit;
    font-size: inherit;
    line-height: normal;
    width: 100%;
    /* iOS Safari centers datetime-local content by default. Force left-align
       on both the input AND the internal ::-webkit-datetime-edit* pseudos so
       the rendered text starts at padding-left (12px) — identical to Android
       Chrome's default and consistent with the rest of .form-control inputs. */
    text-align: left;
}

/* Internal pseudos — iOS only; Android ignores these gracefully. */
input.zt-dt-native::-webkit-date-and-time-value {
    text-align: left;
    margin: 0;
}
input.zt-dt-native::-webkit-datetime-edit,
input.zt-dt-native::-webkit-datetime-edit-fields-wrapper {
    text-align: left;
    justify-content: flex-start;
    /* align-items: center → centra verticalmente los date/time fields dentro del
       input. Sin esto, iOS Safari renderiza el texto pegado al top con whitespace
       desigual abajo. Combinado con `display: flex` en el input (abajo) corrige
       la alineación vertical en iOS sin afectar a Android (ignora estos pseudos). */
    align-items: center;
    height: 100%;
    padding: 0;
    margin: 0;
}

/* Centrar contenido verticalmente del input nativo en iOS.
   `display: flex` + `align-items: center` en el contenedor (input) fuerza que
   el ::-webkit-datetime-edit (renderizado como hijo flex) quede centrado vert. */
input.zt-dt-native {
    display: flex;
    align-items: center;
}

.zt-dt-native-wrap {
    position: relative;
    display: block;
}

.zt-dt-native-wrap > input.zt-dt-native {
    position: relative;
    z-index: 1;
}

/* Hide native "DD/MM/YYYY ----" when empty AND not focused, so the fake
   placeholder shows idle and iOS's live value shows during picker interaction.
   Also targets ::-webkit-datetime-edit* pseudos because color:transparent on
   the input doesn't always cascade to them on older iOS. */
.zt-dt-native-wrap:not(.has-value) > input.zt-dt-native:not(:focus),
.zt-dt-native-wrap:not(.has-value) > input.zt-dt-native:not(:focus)::-webkit-date-and-time-value,
.zt-dt-native-wrap:not(.has-value) > input.zt-dt-native:not(:focus)::-webkit-datetime-edit,
.zt-dt-native-wrap:not(.has-value) > input.zt-dt-native:not(:focus)::-webkit-datetime-edit-fields-wrapper,
.zt-dt-native-wrap:not(.has-value) > input.zt-dt-native:not(:focus)::-webkit-datetime-edit-year-field,
.zt-dt-native-wrap:not(.has-value) > input.zt-dt-native:not(:focus)::-webkit-datetime-edit-month-field,
.zt-dt-native-wrap:not(.has-value) > input.zt-dt-native:not(:focus)::-webkit-datetime-edit-day-field,
.zt-dt-native-wrap:not(.has-value) > input.zt-dt-native:not(:focus)::-webkit-datetime-edit-hour-field,
.zt-dt-native-wrap:not(.has-value) > input.zt-dt-native:not(:focus)::-webkit-datetime-edit-minute-field,
.zt-dt-native-wrap:not(.has-value) > input.zt-dt-native:not(:focus)::-webkit-datetime-edit-text {
    color: transparent;
}

.zt-dt-native-placeholder {
    position: absolute;
    top: 50%;
    left: 12px;  /* matches .form-control padding-left; calendar icon is on the RIGHT */
    transform: translateY(-50%);
    color: #989898;
    pointer-events: none;
    font-family: inherit;
    font-size: inherit;
    line-height: 1;
    z-index: 2;
    transition: opacity 0.15s ease, visibility 0s linear 0.15s;
}

.zt-dt-native-wrap.has-value .zt-dt-native-placeholder,
.zt-dt-native-wrap:focus-within .zt-dt-native-placeholder {
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.15s ease, visibility 0s linear 0s;
}

/* --- Error state --- */

input.timeform.is-invalid {
    border-color: #dc3545 !important;
    box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25) !important;
    outline: none;
}

/* --- Mobile: bottom sheet --- */

@media (max-width: 767px) {
    .zt-tp-sheet {
        border-radius: 16px 16px 0 0;
        box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.15);
        border: none;
        max-height: 70vh;
        animation: ztTpSlideUp 0.22s cubic-bezier(0.2, 0.9, 0.3, 1);
        padding-bottom: env(safe-area-inset-bottom, 0px);
    }

    .zt-tp-sheet.zt-tp-closing {
        animation: ztTpSlideDown 0.22s cubic-bezier(0.4, 0, 1, 1) forwards;
    }

    @keyframes ztTpSlideUp {
        from { transform: translateY(100%); }
        to   { transform: translateY(0); }
    }

    @keyframes ztTpSlideDown {
        from { transform: translateY(0); opacity: 1; }
        to   { transform: translateY(100%); opacity: 0.85; }
    }

    .zt-tp-header { display: flex; padding: 14px 16px 10px; }

    .zt-tp-wheels {
        --zt-row-h: 48px;
        --zt-rows: 5;
        --zt-chev-h: 38px;
        padding: 0 20px 20px;
    }

    /* Column width basis moved to col-container (it's the flex item of the row now). */
    .zt-tp-col-container {
        flex: 0 1 96px;
    }

    /* Bigger tap targets + bigger icon for chevrons on narrow viewports (wheel fallback). */
    .zt-tp-chev .fa {
        font-size: 20px;
    }

    .zt-tp-wheel li { font-size: 20px; }
    .zt-tp-wheel li.zt-tp-active { font-size: 24px; }

    .zt-tp-wheel-colon {
        font-size: 28px;
        padding: 0 10px;
    }

    .zt-tp-wheel-band {
        left: 20px;
        right: 20px;
        top: 50%;
    }

    .zt-tp-footer {
        padding: 14px 20px calc(14px + env(safe-area-inset-bottom, 0px));
        justify-content: stretch;
    }
    .zt-tp-ok {
        flex: 1;
        padding: 12px 20px;
        font-size: 17px;
        border-radius: 8px;
    }
}

/* --- RTL support --- */

.right-to-left .zt-tp-sheet {
    direction: rtl;
    text-align: right;
}

/* ------------------------------------------------------------------
   Mobile input UX overrides (loaded AFTER Master.min.css).
   Master.css fuente tiene estas reglas, pero Home.master carga el .min
   que no se regenera — por eso aplicamos aquí con la misma especificidad
   y cargamos este archivo después para override garantizado.
   ------------------------------------------------------------------ */

/* Eliminar tap-delay 300ms + highlight azul/gris de iOS */
.form-control {
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
}

/* Iconos de validación (check / times) deben ser decorativos:
   sin pointer-events, los taps en el borde derecho del input
   eran interceptados y no llegaban al <input> */
.inputOK .fa-check.inputRight,
.inputError .fa-times.inputRight {
    pointer-events: none;
}
