/* ============================================================
   Dairy Farm Management System - shared layout
   ============================================================ */

:root {
    --df-sidebar-width: 250px;
    --df-sidebar-collapsed: 68px;
    --df-topbar-height: 58px;
    /* Muted deep green. Desaturated so the sidebar sits behind the content
       rather than competing with the colour-coded dashboard cards, while
       keeping the dairy-farm identity. */
    --df-sidebar-bg: #1a3d2b;
    /* Same colour as channels, for gradients that need to fade to transparent. */
    --df-sidebar-bg-rgb: 26, 61, 43;
    --df-sidebar-bg-hover: #23503a;
    --df-sidebar-active: #2f7d5a;
    --df-sidebar-text: #cfe3d6;
    /* Lighter tone for the brand mark, which needs to read against the
       darker background rather than match the active pill. */
    --df-sidebar-brand: #7bc9a0;
    --df-accent: #15803d;
}

html, body {
    height: 100%;
}

body {
    background-color: #f4f6f8;
    font-size: 0.925rem;
}

/* ---------- Sidebar ---------- */

.df-sidebar {
    background-color: var(--df-sidebar-bg);
    color: var(--df-sidebar-text);
    width: var(--df-sidebar-width);
}

.df-sidebar-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: var(--df-topbar-height);
    padding: 0 1rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.12);
    flex-shrink: 0;
}

.df-brand {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    font-weight: 600;
    font-size: 1.05rem;
    white-space: nowrap;
    overflow: hidden;
}

.df-brand-icon {
    font-size: 1.35rem;
    color: var(--df-sidebar-brand);
    flex-shrink: 0;
}

/* The menu is the only scrolling region - the brand header above it stays
   put - so a long menu on a short screen never pushes the brand away. */
.df-nav {
    padding: 0.75rem 0.5rem 1.25rem;
    overflow-y: auto;
    overflow-x: hidden;
    flex: 1 1 auto;
    min-height: 0;
    /* Stops a flick at the end of the menu from scrolling the page behind. */
    overscroll-behavior: contain;
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, 0.25) transparent;
}

/* A default scrollbar renders as a pale OS bar on the dark sidebar and eats
   15px of the menu width. This one is slim, translucent and overlays. */
.df-nav::-webkit-scrollbar {
    width: 6px;
}

.df-nav::-webkit-scrollbar-track {
    background: transparent;
}

.df-nav::-webkit-scrollbar-thumb {
    background-color: rgba(255, 255, 255, 0.22);
    border-radius: 999px;
}

.df-nav:hover::-webkit-scrollbar-thumb {
    background-color: rgba(255, 255, 255, 0.36);
}

/* Fade at the foot of the menu, shown only while there is more below the
   fold. Without it the list just stops at the screen edge and there is
   nothing to say the remaining items exist. */
.df-sidebar::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 2.5rem;
    background: linear-gradient(to top,
        rgba(var(--df-sidebar-bg-rgb), 1) 15%,
        rgba(var(--df-sidebar-bg-rgb), 0) 100%);
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.15s ease;
}

.df-sidebar.df-nav-more::after {
    opacity: 1;
}

.df-nav-link {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.6rem 0.75rem;
    margin-bottom: 0.125rem;
    border-radius: 0.5rem;
    color: var(--df-sidebar-text);
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.df-nav-link i {
    font-size: 1.075rem;
    flex-shrink: 0;
    width: 1.25rem;
    text-align: center;
}

.df-nav-link:hover,
.df-nav-link:focus-visible {
    background-color: var(--df-sidebar-bg-hover);
    color: #ffffff;
}

/* The active pill is now a mid green rather than a bright one, so its label
   is white for contrast instead of near-black. */
.df-nav-link.active {
    background-color: var(--df-sidebar-active);
    color: #ffffff;
    font-weight: 600;
}

.df-nav-link.active:hover,
.df-nav-link.active:focus-visible {
    background-color: var(--df-sidebar-active);
    color: #ffffff;
}

.df-nav-link.df-nav-disabled {
    opacity: 0.55;
}

/* ---------- Desktop: sidebar is fixed, main content is offset ---------- */

@media (min-width: 992px) {
    .df-sidebar {
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        z-index: 1030;
        display: flex;
        flex-direction: column;
        transition: width 0.2s ease;

        /* Bootstrap's responsive offcanvas sets
           "background-color: transparent !important" on .offcanvas-lg above
           the lg breakpoint, which silently wiped the sidebar's colour on
           desktop and left pale nav text on the pale page background.
           Matching !important is the only way to win against it. */
        background-color: var(--df-sidebar-bg) !important;
    }

    .df-main {
        margin-left: var(--df-sidebar-width);
        transition: margin-left 0.2s ease;
    }

    /* Collapsed: icon rail only. */
    body.df-collapsed .df-sidebar {
        width: var(--df-sidebar-collapsed);
    }

    body.df-collapsed .df-main {
        margin-left: var(--df-sidebar-collapsed);
    }

    body.df-collapsed .df-nav-text {
        display: none;
    }

    body.df-collapsed .df-sidebar-header,
    body.df-collapsed .df-nav-link {
        justify-content: center;
        padding-left: 0.5rem;
        padding-right: 0.5rem;
    }

    body.df-collapsed #btnCollapseSidebar i {
        transform: rotate(180deg);
    }
}

/* Below lg the element is a Bootstrap offcanvas panel, so it must not keep
   the fixed desktop width. */
@media (max-width: 991.98px) {
    .df-sidebar {
        width: 260px;
    }
}

/* ---------- Top bar ---------- */

.df-topbar {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    height: var(--df-topbar-height);
    padding: 0 1rem;
    background-color: #ffffff;
    border-bottom: 1px solid #e2e8f0;
    position: sticky;
    top: 0;
    z-index: 1020;
}

.df-page-title {
    font-size: 1.05rem;
    font-weight: 600;
    margin: 0;
    color: #1e293b;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.df-topbar-right {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.df-user {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    color: #475569;
    font-weight: 500;
}

.df-user i {
    font-size: 1.15rem;
}

.df-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    padding: 0;
    border-radius: 0.5rem;
    color: #475569;
    font-size: 1.15rem;
    border: 0;
}

.df-icon-btn:hover {
    background-color: #f1f5f9;
    color: var(--df-accent);
}

/* ---------- Content ---------- */

.df-content {
    padding: 1.25rem;
}

.df-card {
    background-color: #ffffff;
    border: 1px solid #e2e8f0;
    border-radius: 0.75rem;
    padding: 1.25rem;
    margin-bottom: 1.25rem;
}

.df-card-title {
    font-size: 1rem;
    font-weight: 600;
    color: #1e293b;
    margin: 0 0 1rem 0;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.df-hint {
    color: #64748b;
    font-size: 0.85rem;
}

/* ---------- Lookup dropdown with add button ---------- */

/* Select2 renders a span, which has no natural width inside a flex
   input-group. Without this the dropdown collapses to zero width. */
.df-lookup-group .select2-container {
    flex: 1 1 auto;
    width: 1% !important;
}

.df-lookup-group .select2-container--bootstrap-5 .select2-selection {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}

.select2-container--bootstrap-5 .select2-selection {
    min-height: calc(1.5em + 0.75rem + 2px);
}

/* Select2 inside a Bootstrap modal must out-rank the modal backdrop. */
.select2-container--open {
    z-index: 1060;
}

/* ---------- Listing tables ---------- */

.df-list-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.75rem;
    margin-bottom: 1rem;
}

.df-list-toolbar .df-field {
    min-width: 220px;
}

/* Checkboxes sit on the toolbar's baseline rather than at the top of the row. */
.df-list-toolbar .df-field-check {
    padding-bottom: 0.5rem;
    white-space: nowrap;
}

/* text-uppercase also shouts the placeholder, turning "e.g. LHR" into
   "E.G. LHR". Only what the user actually types should be uppercased. */
.text-uppercase::placeholder {
    text-transform: none;
}

table.dataTable thead th {
    background-color: #f8fafc;
    font-weight: 600;
    color: #334155;
    white-space: nowrap;
}

.df-empty-hint {
    color: #94a3b8;
    font-style: italic;
}

/* ============================================================
   Dashboard
   ============================================================ */

/* Small heading that separates the metric bands. */
.df-band-title {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #64748b;
    margin: 0 0 0.65rem 0.15rem;
}

.df-band-title::after {
    content: '';
    flex: 1 1 auto;
    height: 1px;
    background: linear-gradient(to right, #e2e8f0, transparent);
}

/* KPI card. A colour-coded rail on the left carries the meaning, so the
   numbers themselves stay in one readable ink colour. */
.df-kpi {
    position: relative;
    background-color: #ffffff;
    border: 1px solid #e2e8f0;
    border-radius: 0.75rem;
    padding: 0.85rem 1rem 0.85rem 1.15rem;
    display: flex;
    align-items: center;
    gap: 0.85rem;
    height: 100%;
    overflow: hidden;
    transition: box-shadow 0.15s ease, transform 0.15s ease;
}

.df-kpi:hover {
    box-shadow: 0 4px 14px rgba(15, 23, 42, 0.07);
    transform: translateY(-1px);
}

.df-kpi::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 4px;
    background-color: var(--df-kpi-colour, #22c55e);
}

.df-kpi-icon {
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 0.6rem;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.15rem;
    flex-shrink: 0;
    color: var(--df-kpi-colour, #22c55e);
    background-color: var(--df-kpi-tint, #f0fdf4);
}

.df-kpi-body {
    min-width: 0;
}

.df-kpi-label {
    display: block;
    font-size: 0.72rem;
    color: #64748b;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    line-height: 1.25;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.df-kpi-value {
    display: block;
    font-size: 1.3rem;
    font-weight: 700;
    color: #0f172a;
    line-height: 1.35;
    font-variant-numeric: tabular-nums;
}

/* Colour variants */
.df-kpi-green  { --df-kpi-colour: #16a34a; --df-kpi-tint: #f0fdf4; }
.df-kpi-blue   { --df-kpi-colour: #2563eb; --df-kpi-tint: #eff6ff; }
.df-kpi-teal   { --df-kpi-colour: #0d9488; --df-kpi-tint: #f0fdfa; }
.df-kpi-amber  { --df-kpi-colour: #d97706; --df-kpi-tint: #fffbeb; }
.df-kpi-purple { --df-kpi-colour: #7c3aed; --df-kpi-tint: #f5f3ff; }
.df-kpi-rose   { --df-kpi-colour: #e11d48; --df-kpi-tint: #fff1f2; }

/* Raised when a figure needs attention, e.g. low stock above zero. */
.df-kpi-alert {
    --df-kpi-colour: #dc2626;
    --df-kpi-tint: #fef2f2;
    border-color: #fecaca;
    background-color: #fffafa;
}

/* ---------- Dashboard widgets ---------- */

.df-widget-head {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    margin-bottom: 0.85rem;
}

.df-widget-head h2 {
    font-size: 0.95rem;
    font-weight: 600;
    color: #1e293b;
    margin: 0;
    display: flex;
    align-items: center;
    gap: 0.45rem;
}

.df-widget-head h2 i {
    color: var(--df-accent);
}

/* Count sits in the header so the state is readable without reading rows. */
.df-widget-count {
    margin-left: auto;
    font-size: 0.75rem;
    font-weight: 600;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    background-color: #f1f5f9;
    color: #475569;
}

.df-widget-count.has-items {
    background-color: #fef3c7;
    color: #92400e;
}

.df-widget-count.is-urgent {
    background-color: #fee2e2;
    color: #991b1b;
}

/* An empty widget collapses to one quiet line instead of rendering a full
   table header to say nothing is due. */
.df-widget-empty {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.85rem 0.25rem;
    color: #94a3b8;
    font-size: 0.9rem;
}

.df-widget-empty i {
    color: #22c55e;
    font-size: 1.05rem;
}

.df-widget-card {
    height: 100%;
    display: flex;
    flex-direction: column;
}

.df-widget-card .table {
    margin-bottom: 0;
}

.df-widget-card .table > :not(caption) > * > * {
    padding-top: 0.45rem;
    padding-bottom: 0.45rem;
}

@media (max-width: 575.98px) {
    .df-kpi { padding-left: 0.9rem; gap: 0.6rem; align-items: flex-start; }
    .df-kpi-icon { width: 2.1rem; height: 2.1rem; font-size: 1rem; }
    .df-kpi-value { font-size: 1.1rem; }

    /* On a narrow screen a truncated label reads as nonsense - "Cash in
       ha..." - so let it wrap onto a second line instead. */
    .df-kpi-label {
        white-space: normal;
        overflow: visible;
        text-overflow: clip;
        font-size: 0.68rem;
    }
}

/* Headline figures on the report tabs. */
.df-stat {
    background-color: #f8fafc;
    border: 1px solid #e2e8f0;
    border-radius: 0.5rem;
    padding: 0.65rem 0.9rem;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.df-stat span {
    font-size: 0.78rem;
    color: #64748b;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.df-stat strong {
    font-size: 1.15rem;
    color: #1e293b;
}

/* Brief nudge toward Generate after switching report tabs. */
.df-pulse {
    animation: dfPulse 0.6s ease;
}

@keyframes dfPulse {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.06); }
}

/* The newly generated calf tag, shown large after a calving is recorded. */
.df-big-tag {
    font-size: 1.75rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    color: var(--df-accent);
    margin: 0.25rem 0 1.25rem 0;
}

/* Read-only context shown at the top of the confirm-pregnancy dialog. */
.df-confirm-summary {
    background-color: #f8fafc;
    border: 1px solid #e2e8f0;
    border-radius: 0.5rem;
    padding: 0.75rem 1rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 2rem;
}

/* ---------- Animal photos ---------- */

/* Thumbnail in the register listing. */
.df-thumb {
    width: 40px;
    height: 40px;
    border-radius: 0.4rem;
    object-fit: cover;
    border: 1px solid #e2e8f0;
    background-color: #f8fafc;
    display: inline-block;
}

.df-thumb-empty {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: #cbd5e1;
    font-size: 1.05rem;
}

img.df-thumb {
    cursor: zoom-in;
}

/* Photo shown on the detail panel. */
.df-detail-photo {
    max-width: 100%;
    max-height: 260px;
    border-radius: 0.6rem;
    border: 1px solid #e2e8f0;
}

/* Picker inside the add/edit modal. */
.df-photo-picker {
    display: flex;
    gap: 1rem;
    align-items: flex-start;
    padding: 0.85rem;
    border: 1px dashed #cbd5e1;
    border-radius: 0.75rem;
    background-color: #f8fafc;
}

.df-photo-preview {
    position: relative;
    width: 120px;
    height: 120px;
    flex-shrink: 0;
    border-radius: 0.6rem;
    overflow: hidden;
    background-color: #ffffff;
    border: 1px solid #e2e8f0;
    display: flex;
    align-items: center;
    justify-content: center;
}

.df-photo-preview img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.df-photo-placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;
    color: #cbd5e1;
}

.df-photo-placeholder i {
    font-size: 1.75rem;
}

.df-photo-placeholder span {
    font-size: 0.75rem;
}

.df-photo-busy {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: rgba(255, 255, 255, 0.75);
    color: var(--df-accent);
}

.df-photo-actions {
    min-width: 0;
}

@media (max-width: 575.98px) {
    .df-photo-picker { flex-direction: column; align-items: stretch; }
    .df-photo-preview { width: 100%; height: 160px; }
}

/* Stand-in panel for detail tabs whose module has not been built yet. */
.df-placeholder {
    text-align: center;
    padding: 2.5rem 1rem;
    border: 1px dashed #cbd5e1;
    border-radius: 0.75rem;
    background-color: #f8fafc;
}

.df-placeholder i {
    font-size: 2rem;
    color: #94a3b8;
}

.df-placeholder p {
    margin: 0.75rem 0 0.25rem 0;
    font-weight: 500;
    color: #475569;
}

/* ---------- Toasts ---------- */

.df-toast-host {
    position: fixed;
    top: 1rem;
    right: 1rem;
    z-index: 1090;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

/* ---------- Login ---------- */

.df-login-body {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, #14532d 0%, #15803d 55%, #22c55e 100%);
    padding: 1rem;
}

.df-login-card {
    width: 100%;
    max-width: 400px;
    background-color: #ffffff;
    border-radius: 1rem;
    padding: 2rem;
    box-shadow: 0 18px 45px rgba(0, 0, 0, 0.25);
}

.df-login-brand {
    text-align: center;
    margin-bottom: 1.5rem;
}

.df-login-brand i {
    font-size: 2.5rem;
    color: var(--df-accent);
}

.df-login-brand h1 {
    font-size: 1.25rem;
    font-weight: 700;
    margin: 0.5rem 0 0 0;
    color: #1e293b;
}
