/* KillPest custom utilities.
 * Keep this file minimal: prefer Tailwind utilities over custom CSS.
 * Only put here styles that cannot be expressed with Tailwind. */

/* Mobile app shell: on phones/tablets the sidebar must be fully off-canvas,
   never a collapsed rail. This file loads after Tailwind, so it is the final
   authority for responsive chrome behavior.

   Tailwind v4 uses the native `translate` CSS property (not `transform`) for
   utilities like `-translate-x-full`. Overriding `transform` alone leaves the
   `translate` variable active and the sidebar stays off-canvas — we have to
   reset `translate` directly. */
@media (max-width: 1279.98px) {
    #sidebar {
        position: fixed !important;
        inset: 0 auto 0 0 !important;
        width: min(18rem, 86vw) !important;
        translate: -105% 0 !important;
        transform: none !important;
        visibility: hidden !important;
    }

    #sidebar.sidebar-mobile-open {
        translate: 0 0 !important;
        transform: none !important;
        visibility: visible !important;
    }

    body.sidebar-mobile-open {
        overflow: hidden;
    }
}

@media (min-width: 1280px) {
    #sidebar {
        translate: none !important;
        transform: none !important;
        visibility: visible !important;
    }
}

/* Defensive mobile/tablet rendering for visits: cards on small screens, table
   only once there is enough horizontal space. */
.visits-mobile-list {
    display: block;
}

.visits-table-wrap {
    display: none;
}

@media (min-width: 768px) {
    .visits-mobile-list {
        display: none;
    }

    .visits-table-wrap {
        display: block;
    }
}

/* Custom confirm/alert modal — used app-wide via window.killpestConfirm /
   window.killpestAlert. Markup is generated by static/js/confirm.js. */
.km-modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 80;
    background: rgba(15, 23, 42, 0.55);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    animation: km-fade-in 120ms ease-out;
}
.km-modal-content {
    background: #fff;
    border-radius: 0.75rem;
    width: 100%;
    max-width: 28rem;
    padding: 1.25rem;
    box-shadow: 0 20px 50px rgba(15, 23, 42, 0.25);
    outline: none;
    animation: km-pop-in 140ms ease-out;
}
.km-modal-header {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 0.75rem;
}
.km-modal-icon {
    flex: none;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 9999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 1.1rem;
    line-height: 1;
}
.km-modal-title {
    margin: 0;
    font-size: 1rem;
    font-weight: 600;
    color: #0f172a;
}
.km-modal-body {
    color: #334155;
    font-size: 0.925rem;
    line-height: 1.45;
    margin-bottom: 1.25rem;
    white-space: pre-line;
}
.km-modal-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.km-modal-btn {
    border-radius: 0.375rem;
    padding: 0.5rem 0.9rem;
    font-size: 0.875rem;
    font-weight: 600;
    border: 1px solid transparent;
    cursor: pointer;
    min-height: 2.5rem;
    transition: background-color 120ms ease, box-shadow 120ms ease;
}
.km-modal-btn:focus {
    outline: none;
    box-shadow: 0 0 0 3px rgba(28, 104, 94, 0.35);
}
.km-modal-btn-secondary {
    background: #fff;
    border-color: #cbd5e1;
    color: #1e293b;
}
.km-modal-btn-secondary:hover { background: #f8fafc; }

@keyframes km-fade-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}
@keyframes km-pop-in {
    from { opacity: 0; transform: translateY(8px) scale(0.97); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}

@media (max-width: 640px) {
    .km-modal-backdrop {
        align-items: flex-end;
        padding: 0;
    }
    .km-modal-content {
        max-width: none;
        border-radius: 0.75rem 0.75rem 0 0;
        padding: 1rem 1rem calc(1rem + env(safe-area-inset-bottom));
        animation: km-slide-up 180ms ease-out;
    }
    .km-modal-actions {
        flex-direction: column-reverse;
    }
    .km-modal-actions .km-modal-btn {
        width: 100%;
    }
}

@keyframes km-slide-up {
    from { transform: translateY(100%); opacity: 0; }
    to   { transform: translateY(0);    opacity: 1; }
}

/* App-shell layout: sidebar is `position: fixed` on every viewport
   (drawer on mobile, in-view on xl+), and the main column is offset
   by the sidebar's width on xl+. Body scrolls normally — no
   h-screen / overflow-hidden chain — so this doesn't depend on a
   long list of Tailwind utilities all being present in the dist.

   Tailwind dist DOES NOT contain `pl-64` / `xl:pl-64` (handwritten
   dist, see .gitignore note), so we re-declare what we need. Also
   re-declare `.h-screen` because it's missing from dist and the
   sidebar still uses it to be a full-viewport tall column. */
.h-screen { height: 100vh; }
.kp-app-shell { min-height: 0; min-width: 0; }

@media (min-width: 1280px) {
    .kp-app-pad { padding-left: 16rem; transition: padding-left 0.2s ease; }
    /* When the sidebar collapses from w-64 (16rem) to w-16 (4rem), the
       main column's left padding follows so the freed-up space is
       actually usable instead of leaving an empty gap. The body gets
       the .kp-sidebar-collapsed class from sidebar.js. */
    body.kp-sidebar-collapsed .kp-app-pad { padding-left: 4rem; }
}

/* Sidebar header in collapsed state — the logo + "KillPest" text don't
   fit in 4rem (logo alone is 2.25rem + 2rem padding). Hide the brand
   anchor entirely; the user navigates home via the menu icons anyway,
   and the collapse-toggle button stays as the only header content,
   centered in the slim column. */
.sidebar-collapsed .sidebar-brand { display: none; }
.sidebar-collapsed .sidebar-header { justify-content: center; padding-left: 0; padding-right: 0; }
.sidebar-collapsed .sidebar-toggle svg { transform: rotate(180deg); }

/* Sidebar uses overflow-y-auto so a long menu can still scroll via
   wheel/trackpad, but we hide the visible scrollbar chrome on the
   dark background. The descendant selector covers the inner <nav>
   too — it also has overflow-y-auto and would otherwise show its
   own scrollbar. Covers Firefox, IE/Edge (legacy), and Chromium. */
#sidebar, #sidebar *,
.sidebar, .sidebar *,
aside.sidebar, aside.sidebar * {
    scrollbar-width: none !important;
    -ms-overflow-style: none !important;
}
#sidebar::-webkit-scrollbar,
#sidebar *::-webkit-scrollbar,
.sidebar::-webkit-scrollbar,
.sidebar *::-webkit-scrollbar,
aside.sidebar::-webkit-scrollbar,
aside.sidebar *::-webkit-scrollbar {
    width: 0 !important;
    height: 0 !important;
    display: none !important;
    background: transparent !important;
}

/* ------------------------------------------------------------------
 * Textareas everywhere in the app: start at ~2 rows, grow with
 * content up to a 14rem cap. `field-sizing: content` is the modern
 * (Chrome 123+, Firefox 128+, Edge 123+, Safari 17.4+) one-liner
 * that handles auto-resize. Older browsers fall back to the
 * `rows` attribute on the textarea (default 2 unless overridden).
 *
 * Opt out per-textarea with `class="kp-textarea-fixed"` if a form
 * genuinely needs a fixed-height textarea (rare — most don't).
 * ---------------------------------------------------------------- */
form textarea:not(.kp-textarea-fixed) {
    min-height: calc(2 * 1.5em + 1rem);
    max-height: 14rem;
    field-sizing: content;
    overflow-y: auto;
    resize: none;
}

/* ----- Topbar profile avatar ----- */
.kp-topbar-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 9999px;
    background: #ecfdf5;
    color: #064e3b;
    font-weight: 700;
    font-size: 0.8125rem;
    text-decoration: none;
    border: 1px solid #d1fae5;
    transition: border-color 0.15s, background 0.15s;
    overflow: hidden;
}
.kp-topbar-avatar:hover {
    border-color: #6ee7b7;
    background: #d1fae5;
    text-decoration: none;
}
.kp-topbar-avatar-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.kp-topbar-avatar-fallback {
    line-height: 1;
}

/* ----- Topbar pill-style language switcher ----- */
.kp-lang-pill {
    display: inline-flex;
    align-items: center;
    padding: 2px;
    background: #f1f5f9;
    border: 1px solid #e2e8f0;
    border-radius: 9999px;
    gap: 2px;
}
.kp-lang-pill-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.35rem 0.7rem;
    border-radius: 9999px;
    background: transparent;
    border: 0;
    cursor: pointer;
    font-size: 0.75rem;
    font-weight: 600;
    color: #64748b;
    line-height: 1;
    transition: background 0.15s, color 0.15s;
}
.kp-lang-pill-btn:hover {
    background: #fff;
    color: #0f172a;
}
.kp-lang-pill-btn.is-active {
    background: #1c685e;
    color: #fff;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
}
.kp-lang-pill-btn.is-active:hover {
    background: #155b52;
    color: #fff;
}
.kp-lang-pill-code {
    letter-spacing: 0.04em;
    font-variant-numeric: tabular-nums;
}
.kp-lang-pill-name {
    font-weight: 500;
}

/* Sync indicator — softer, matches the pill aesthetic. */
#sync-indicator {
    display: none; /* JS un-hides */
    align-items: center;
    gap: 0.4rem;
    border-radius: 9999px;
    padding: 0.35rem 0.75rem;
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1;
    border: 1px solid;
    cursor: pointer;
    transition: filter 0.15s;
}
#sync-indicator.flex { display: inline-flex; }
#sync-indicator:hover { filter: brightness(0.97); }
#sync-indicator .dot { width: 0.5rem; height: 0.5rem; border-radius: 9999px; flex: none; }
#sync-indicator[data-state="online"]  { background: #ecfdf5; color: #047857; border-color: #a7f3d0; }
#sync-indicator[data-state="online"]  .dot { background: #10b981; }
#sync-indicator[data-state="offline"] { background: #fef2f2; color: #b91c1c; border-color: #fecaca; }
#sync-indicator[data-state="offline"] .dot { background: #ef4444; }
#sync-indicator[data-state="pending"] { background: #fef3c7; color: #92400e; border-color: #fde68a; }
#sync-indicator[data-state="pending"] .dot { background: #f59e0b; }
#sync-indicator[data-state="failed"]  { background: #fef2f2; color: #b91c1c; border-color: #fecaca; }
#sync-indicator[data-state="failed"]  .dot { background: #ef4444; }

/* Mobile: hide language name (keep code only). Already on the button via
   hidden sm:inline classes — these tailwind classes are typically in the
   dist, but assert here so a stripped dist still does the right thing. */
@media (max-width: 639px) {
    .kp-lang-pill-name { display: none; }
    .kp-lang-pill-btn { padding: 0.35rem 0.55rem; }
}

/* ----- Confirm modal tone-success: Tailwind's bg-emerald-600 etc.
   aren't in the committed dist (purge), but confirm.js references them
   for the success tone on data-confirm-tone="success". Re-declare here. */
.km-modal-btn.bg-emerald-600 { background-color: #059669; color: #fff; }
.km-modal-btn.bg-emerald-600.hover\:bg-emerald-700:hover,
.km-modal-btn.bg-emerald-600:hover { background-color: #047857; }
.km-modal-btn.focus\:ring-emerald-400:focus,
.km-modal-btn.bg-emerald-600:focus { outline: none; box-shadow: 0 0 0 3px rgba(52, 211, 153, 0.45); }

/* Generic emerald fallbacks for action buttons (visit page, anywhere
   else that bg-emerald-600 / hover:bg-emerald-700 etc. are referenced
   directly via Tailwind class names). The dist's purge step keeps
   only classes that were live at build time, and the IK Grill action
   row was added after — so without these rules the green button
   renders as transparent on emerald-50. */
.bg-emerald-100 { background-color: #d1fae5; }
.text-emerald-800 { color: #065f46; }
.text-emerald-700 { color: #047857; }
.border-emerald-300 { border-color: #6ee7b7; }
button.bg-emerald-600,
.bg-emerald-600 { background-color: #059669; }
.bg-emerald-600.text-white,
button.bg-emerald-600.text-white { color: #fff; }
.bg-emerald-600.hover\:bg-emerald-700:hover,
button.bg-emerald-600.hover\:bg-emerald-700:hover { background-color: #047857; }
.hover\:bg-emerald-50:hover { background-color: #ecfdf5; }
