/* ==========================================================================
   DairyCore - Complete Stylesheet v2.0
   Covers: Core, Accounts, Farms, Animals, Milk, Health, Breeding,
           Notifications, Sales & Distribution
   ========================================================================== */

/* --------------------------------------------------------------------------
   CSS Custom Properties (Design Tokens)
   -------------------------------------------------------------------------- */
:root {
    --dc-sidebar-width:      260px;
    --dc-sidebar-bg:         #1a2332;
    --dc-sidebar-text:       #c8d6e5;
    --dc-sidebar-text-hover: #ffffff;
    --dc-sidebar-accent:     #00b894;
    --dc-sidebar-active-bg:  rgba(0, 184, 148, 0.15);
    --dc-topbar-height:      60px;
    --dc-topbar-bg:          #ffffff;
    --dc-topbar-border:      #e9ecef;
    --dc-content-bg:         #f4f6f9;
    --dc-card-radius:        0.75rem;
    --dc-transition:         0.2s ease;
    --dc-green:              #00b894;
    --dc-green-dark:         #00a381;
    --dc-green-light:        #d4f5ee;
    --dc-public-bg:          #a6ceba;
    --dc-public-nav-border:  #dcece5;
    --dc-blue:               #0984e3;
    --dc-orange:             #e17055;
    --dc-yellow:             #fdcb6e;
    --dc-purple:             #6c5ce7;
    --dc-red:                #e74c3c;
    --dc-font:               'Segoe UI', system-ui, -apple-system, sans-serif;
    --dc-font-mono:          'Courier New', Courier, monospace;
}

/* --------------------------------------------------------------------------
   Global Reset & Base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
    overflow-x: hidden;
    max-width:  100%;
}

body {
    font-family:  var(--dc-font);
    font-size:    14px;
    color:        #060707;
    background:   var(--dc-content-bg);
    margin:       0;
    padding:      0;
    line-height:  1.6;
    overflow-x:   hidden;
}

a { color: var(--dc-blue); }
a:hover { color: #0770c2; }

/* --------------------------------------------------------------------------
   App Shell Layout
   -------------------------------------------------------------------------- */
.dc-app {
    display:    flex;
    min-height: 100vh;
    max-width:  100%;
    overflow-x: hidden;
}

/* --------------------------------------------------------------------------
   Sidebar
   -------------------------------------------------------------------------- */
.dc-sidebar {
    position:   fixed;
    top:        0;
    left:       0;
    width:      var(--dc-sidebar-width);
    height:     100vh;
    background: var(--dc-sidebar-bg);
    color:      var(--dc-sidebar-text);
    display:    flex;
    flex-direction: column;
    z-index:    1000;
    overflow-y: auto;
    transition: transform var(--dc-transition);
    scrollbar-width: thin;
    scrollbar-color: rgba(255,255,255,0.1) transparent;
}

.dc-sidebar::-webkit-scrollbar        { width: 4px; }
.dc-sidebar::-webkit-scrollbar-track  { background: transparent; }
.dc-sidebar::-webkit-scrollbar-thumb  { background: rgba(255,255,255,0.15); border-radius: 2px; }

/* Sidebar Header */
.dc-sidebar__header {
    display:         flex;
    align-items:     center;
    justify-content: space-between;
    padding:         1.25rem 1.25rem 1rem;
    border-bottom:   1px solid rgba(255,255,255,0.08);
    flex-shrink:     0;
}

.dc-sidebar__brand {
    display:         flex;
    align-items:     center;
    gap:             0.6rem;
    color:           #ffffff;
    text-decoration: none;
    font-size:       1.2rem;
    font-weight:     700;
    letter-spacing:  -0.3px;
}
.dc-sidebar__brand:hover { color: #ffffff; text-decoration: none; }
.dc-sidebar__brand i     { color: var(--dc-green); font-size: 1.4rem; }
.dc-sidebar__brand-mark  {
    width: 30px; height: 30px; border-radius: 50%;
    object-fit: cover; background: #fff; flex-shrink: 0;
}

.dc-sidebar__toggle {
    background: none;
    border:     none;
    color:      var(--dc-sidebar-text);
    font-size:  1.1rem;
    cursor:     pointer;
    padding:    0.25rem;
}

/* Farm Switcher */
.dc-sidebar__farm {
    padding:       0.875rem 1.25rem;
    border-bottom: 1px solid rgba(255,255,255,0.08);
    flex-shrink:   0;
}

.dc-sidebar__farm-badge {
    display:        inline-block;
    font-size:      0.65rem;
    font-weight:    700;
    letter-spacing: 1px;
    color:          var(--dc-green);
    background:     rgba(0, 184, 148, 0.15);
    padding:        0.15rem 0.5rem;
    border-radius:  4px;
    margin-bottom:  0.3rem;
    font-family:    var(--dc-font-mono);
}

.dc-sidebar__farm-name {
    font-weight:   600;
    color:         #ffffff;
    font-size:     0.9rem;
    white-space:   nowrap;
    overflow:      hidden;
    text-overflow: ellipsis;
}

.dc-sidebar__farm-switch {
    display:         inline-block;
    font-size:       0.75rem;
    color:           var(--dc-sidebar-text);
    text-decoration: none;
    margin-top:      0.25rem;
    opacity:         0.7;
    transition:      opacity var(--dc-transition);
}
.dc-sidebar__farm-switch:hover { opacity: 1; color: var(--dc-sidebar-text); }

.dc-sidebar__farm-option {
    display:         flex;
    align-items:     center;
    gap:             0.5rem;
    padding:         0.4rem 0;
    color:           var(--dc-sidebar-text);
    text-decoration: none;
    font-size:       0.8rem;
    transition:      color var(--dc-transition);
}
.dc-sidebar__farm-option:hover { color: #ffffff; }

/* Navigation */
.dc-sidebar__nav {
    flex:       1;
    padding:    0.75rem 0;
    overflow-y: auto;
}

.dc-sidebar__section-label {
    font-size:      0.65rem;
    font-weight:    700;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color:          rgba(200, 214, 229, 0.45);
    padding:        1rem 1.25rem 0.35rem;
}

.dc-sidebar__link {
    display:         flex;
    align-items:     center;
    gap:             0.7rem;
    padding:         0.55rem 1.25rem;
    color:           var(--dc-sidebar-text);
    text-decoration: none;
    font-size:       0.875rem;
    transition:      background var(--dc-transition), color var(--dc-transition);
    position:        relative;
}
.dc-sidebar__link:hover {
    background: rgba(255,255,255,0.06);
    color:      var(--dc-sidebar-text-hover);
}
.dc-sidebar__link.active,
.dc-sidebar__link--active {
    background:  var(--dc-sidebar-active-bg);
    color:       var(--dc-green);
    font-weight: 500;
}
.dc-sidebar__link.active::before {
    content:       '';
    position:      absolute;
    left:          0;
    top:           0;
    bottom:        0;
    width:         3px;
    background:    var(--dc-green);
    border-radius: 0 2px 2px 0;
}
.dc-sidebar__link--danger:hover {
    background: rgba(231, 76, 60, 0.12);
    color:      var(--dc-red);
}
.dc-sidebar__link i { font-size: 1rem; width: 1.1rem; flex-shrink: 0; }

/* Sidebar Footer */
.dc-sidebar__footer {
    padding:       0.75rem 0;
    border-top:    1px solid rgba(255,255,255,0.08);
    flex-shrink:   0;
}

/* --------------------------------------------------------------------------
   Main Content Area
   -------------------------------------------------------------------------- */
.dc-main {
    margin-left:    var(--dc-sidebar-width);
    min-height:     100vh;
    display:        flex;
    flex-direction: column;
    flex:           1;
    /* .dc-main is the sole flex child of .dc-app; flex items default to
       min-width:auto, which lets their content's natural (unwrapped)
       width force them - and the whole page - wider than the viewport
       instead of shrinking/wrapping. min-width:0 is what actually lets
       long rows of buttons/table cells wrap or scroll internally instead
       of quietly pushing the page past 100vw and getting clipped. */
    min-width:      0;
    max-width:      100%;
    transition:     margin-left var(--dc-transition);
}

/* --------------------------------------------------------------------------
   Top Bar
   -------------------------------------------------------------------------- */
.dc-topbar {
    height:          var(--dc-topbar-height);
    background:      var(--dc-topbar-bg);
    border-bottom:   1px solid var(--dc-topbar-border);
    display:         flex;
    align-items:     center;
    gap:             1rem;
    padding:         0 1.5rem;
    position:        sticky;
    top:             0;
    z-index:         100;
    flex-shrink:     0;
    max-width:       100%;
    box-shadow:      0 1px 3px rgba(0,0,0,0.05);
}

.dc-topbar__menu-toggle {
    background: none;
    border:     none;
    font-size:  1.3rem;
    color:      #636e72;
    cursor:     pointer;
    padding:    0.25rem;
    display:    none;
}

.dc-topbar__row1 {
    display:     flex;
    align-items: center;
    gap:         1rem;
    flex:        1 1 auto;
    min-width:   0;
}

.dc-topbar__breadcrumb {
    flex:      1;
    min-width: 0;
    font-size: 0.85rem;
}

.breadcrumb          { margin: 0; }
.breadcrumb-item a   { color: var(--dc-blue); text-decoration: none; }
.breadcrumb-item a:hover { text-decoration: underline; }
.breadcrumb-item.active { color: #636e72; }

.dc-topbar__actions {
    display:     flex;
    align-items: center;
    gap:         0.75rem;
}

/* Wrapper used by pages that opt their action buttons into a guaranteed
   2-per-row mobile grid (see the 991.98 breakpoint below). On desktop it
   just behaves like a normal inline row of buttons. */
.dc-actions-grid2 {
    display:     flex;
    align-items: center;
    gap:         0.5rem;
}

/* --------------------------------------------------------------------------
   Page Content
   -------------------------------------------------------------------------- */
.dc-content {
    flex:    1;
    padding: 1.75rem 2rem;
    /* Belt-and-suspenders: whatever gets nested in here (rows, tables,
       button groups) must never be able to force this box - and with it
       the page - wider than the viewport. Without this, overflow on
       html/body just clips excess content invisibly instead of showing
       it, which is what was cutting off filter buttons, table columns,
       and topbar actions on some phones/screen widths. */
    max-width: 100%;
    overflow-x: hidden;
}

/* Page Header */
.dc-page-header { margin-bottom: 1.75rem; }
.dc-page-header__title {
    font-size:   1.4rem;
    font-weight: 700;
    color:       #1a2332;
    margin:      0 0 0.25rem;
}
.dc-page-header__subtitle {
    color:     #636e72;
    margin:    0;
    font-size: 0.875rem;
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */
.dc-footer {
    padding:        0.75rem 2rem;
    border-top:     1px solid var(--dc-topbar-border);
    font-size:      0.78rem;
    color:          #b2bec3;
    background:     var(--dc-topbar-bg);
    display:        flex;
    flex-wrap:      wrap;
    align-items:    center;
    justify-content: space-between;
    gap:            0.35rem 1rem;
}
.dc-footer__credit {
    color: #b2bec3;
}
.dc-footer__credit a {
    color:           inherit;
    text-decoration: none;
}
.dc-footer__credit a:hover {
    color:           var(--dc-green);
    text-decoration: underline;
}
@media (max-width: 575.98px) {
    .dc-footer {
        justify-content: center;
        text-align:      center;
        padding:         0.75rem 1rem;
    }
}

/* --------------------------------------------------------------------------
   Cards
   -------------------------------------------------------------------------- */
.card {
    border-radius: var(--dc-card-radius);
    border:        1px solid #e9ecef;
}
.card-header {
    background:    transparent;
    border-bottom: 1px solid #e9ecef;
    font-weight:   600;
    padding:       0.875rem 1.25rem;
}

/* --------------------------------------------------------------------------
   Stat Cards (Dashboard KPIs)
   -------------------------------------------------------------------------- */
.dc-stat-card__label {
    font-size:      0.55rem;
    letter-spacing: 0.5px;
}
.dc-stat-card__value {
    font-size:   1.0rem;
    color:       #1a2332;
    line-height: 1.2;
    font-weight: 500;
}
.dc-stat-card__subtitle { font-size: 0.75rem; }

.dc-stat-card__icon {
    width:         52px;
    height:        52px;
    border-radius: 12px;
    display:       flex;
    align-items:   center;
    justify-content: center;
    font-size:     1.4rem;
    flex-shrink:   0;
}

/* Icon colour variants */
.dc-stat-card__icon--primary  { background: #e3f2fd; color: var(--dc-blue); }
.dc-stat-card__icon--success  { background: var(--dc-green-light); color: var(--dc-green); }
.dc-stat-card__icon--warning  { background: #fff9e6; color: #f39c12; }
.dc-stat-card__icon--info     { background: #e8f4fd; color: #17a2b8; }
.dc-stat-card__icon--danger   { background: #fdecea; color: var(--dc-red); }
.dc-stat-card__icon--purple   { background: #f0eeff; color: var(--dc-purple); }
.dc-stat-card__icon--secondary { background: #f1f2f6; color: #636e72; }

/* --------------------------------------------------------------------------
   Tables
   -------------------------------------------------------------------------- */
.dc-table { font-size: 0.875rem; }
.dc-table thead th {
    background:     #f8f9fa;
    font-weight:    600;
    font-size:      0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color:          #636e72;
    border-bottom:  2px solid #dee2e6;
    white-space:    nowrap;
}
.dc-table tbody tr:hover { background: rgba(0,0,0,0.015); }
.dc-table td { vertical-align: middle; }

/* Row tint for "already insured" animals in the Insurance wizard - a light,
   non-distracting wash (not a bold highlight) so insured rows are easy to
   spot at a glance in a long herd list, without fighting for attention
   against the actual data in the row. Hover state still applies on top. */
.dc-table tr.dc-row-insured { background: var(--dc-green-light); }
.dc-table tr.dc-row-insured:hover { background: #c5efe4; }
.dc-legend-swatch {
    display: inline-block;
    width: 12px; height: 12px;
    border-radius: 3px;
    vertical-align: -1px;
}
.dc-legend-swatch--insured { background: var(--dc-green-light); border: 1px solid #a8e6d5; }

/* Every .dc-table lives inside a .table-responsive wrapper (per the
   existing markup pattern). On touch devices give that wrapper smooth
   momentum scrolling and a subtle right-edge fade so it's obvious the
   row continues sideways instead of looking cut off. */
.table-responsive {
    -webkit-overflow-scrolling: touch;
    position: relative;
}
@media (max-width: 767.98px) {
    .table-responsive {
        background:
            linear-gradient(to right, #fff 30%, rgba(255,255,255,0)),
            linear-gradient(to right, rgba(255,255,255,0), #fff 70%) 100% 0,
            radial-gradient(farthest-side at 0 50%, rgba(0,0,0,.12), rgba(0,0,0,0)),
            radial-gradient(farthest-side at 100% 50%, rgba(0,0,0,.12), rgba(0,0,0,0)) 100% 0;
        background-repeat: no-repeat;
        background-color: #fff;
        background-size: 40px 100%, 40px 100%, 14px 100%, 14px 100%;
        background-attachment: local, local, scroll, scroll;
    }
    .dc-table { font-size: 0.8rem; }
    .dc-table th,
    .dc-table td {
        padding: 0.5rem 0.6rem;
        white-space: nowrap;
    }
    /* Optional per-column trim: add d-none d-md-table-cell to a <th>/<td>
       to drop a lower-priority column (e.g. a secondary detail or an
       icon-only action) once the table is inside a phone viewport,
       instead of forcing the whole row to scroll further. Existing
       Bootstrap display utilities already do this - no extra class
       needed, just apply d-none d-md-table-cell in the template. */
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */
.btn-primary {
    background:   var(--dc-green);
    border-color: var(--dc-green);
    font-weight:  500;
}
.btn-primary:hover,
.btn-primary:focus {
    background:   var(--dc-green-dark);
    border-color: var(--dc-green-dark);
}
.btn-primary:disabled {
    background:   var(--dc-green);
    border-color: var(--dc-green);
    opacity:      0.65;
}
/* Bootstrap's own .btn-outline-primary was never re-themed alongside the
   solid .btn-primary above, so it was quietly falling back to Bootstrap's
   default blue - clashing anywhere the two appear together (e.g. an
   outline "secondary action" button next to a solid "main action" button
   that are supposed to read as the same colour family, one level apart
   in emphasis). */
.btn-outline-primary {
    color:        var(--dc-green);
    border-color: var(--dc-green);
}
.btn-outline-primary:hover,
.btn-outline-primary:focus,
.btn-outline-primary:not(:disabled):not(.disabled):active {
    background:   var(--dc-green);
    border-color: var(--dc-green);
    color:        #fff;
}

/* --------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */
.form-label     { margin-bottom: 0.35rem; }
.form-control:focus,
.form-select:focus {
    border-color: var(--dc-green);
    box-shadow:   0 0 0 0.2rem rgba(0, 184, 148, 0.15);
}

/* Filter / search forms (the "row g-3 align-items-end" pattern used
   across list pages) already stack cleanly on phones because every
   field is marked up col-12 col-md-N. These rules just tighten the
   spacing and make sure the Filter/Search button and "Clear" link
   don't feel like an afterthought once everything is single-column. */
@media (max-width: 767.98px) {
    form.row.g-3.align-items-end { row-gap: 0.65rem; }
    form.row.g-3.align-items-end .btn.w-100 {
        margin-top: 0.15rem;
    }
    /* A field marked .dc-filter-optional collapses out of view on
       phones and reappears once "More filters" (see dairycore.js) is
       toggled - use this on the least-used field(s) in a filter form
       that has 4+ inputs, so the form fits in one short scroll instead
       of a long stack. Leave every form as-is unless it's genuinely
       crowded; this is opt-in per field, not automatic. */
    .dc-filter-optional { display: none; }
    .dc-filter-optional.is-visible { display: block; }
    .dc-filter-more-toggle { display: inline-flex; }
}
.dc-filter-more-toggle { display: none; }

/* Form action rows - the "Save / Cancel / secondary action" pattern used
   at the bottom of ~50 add/edit forms across the app (a plain
   `d-flex gap-2` holding a few .btn elements, sometimes with one pushed
   right via ms-auto). On a phone, 3 buttons squeezed into equal flex
   columns turns labels like "Switch to Bulk Entry" into a 4-line stack.
   Letting the row wrap - with each button taking a full line if it
   needs one - fixes every one of those forms from this single rule,
   no per-template edits required. Desktop is untouched. */
@media (max-width: 575.98px) {
    .d-flex.gap-2 {
        flex-wrap: wrap;
    }
    .d-flex.gap-2 > .btn,
    .d-flex.gap-2 > a.btn {
        flex: 1 1 auto;
        min-width: 45%;
    }
    .d-flex.gap-2 > .ms-auto {
        margin-left: 0 !important;
    }

    /* Card headers that pair a title with an action button
       (`card-header d-flex justify-content-between align-items-center`,
       e.g. "Pregnant Animals" + a "Statistics" button) - let the button
       drop to its own line instead of squeezing the title into a
       cramped single row on a narrow phone. */
    .card-header.d-flex {
        flex-wrap: wrap;
        row-gap: 0.5rem;
    }
}

/* --------------------------------------------------------------------------
   Badges (Bootstrap overrides for subtle variants)
   -------------------------------------------------------------------------- */
.bg-success-subtle  { background-color: #d4f5ee !important; }
.bg-danger-subtle   { background-color: #fdecea !important; }
.bg-warning-subtle  { background-color: #fff9e6 !important; }
.bg-info-subtle     { background-color: #e8f4fd !important; }
.bg-primary-subtle  { background-color: #e3f2fd !important; }
.bg-secondary-subtle { background-color: #f1f2f6 !important; }

.text-success  { color: var(--dc-green) !important; }
.border-success { border-color: var(--dc-green) !important; }

/* --------------------------------------------------------------------------
   Empty State
   -------------------------------------------------------------------------- */
.dc-empty-state { padding: 3rem 1rem; }
.dc-empty-state__icon {
    width:           80px;
    height:          80px;
    background:      #f4f6f9;
    border-radius:   50%;
    display:         flex;
    align-items:     center;
    justify-content: center;
    font-size:       2rem;
    color:           #b2bec3;
    margin:          0 auto;
}
.dc-empty-state__title   { font-weight: 600; color: #2d3436; }
.dc-empty-state__message { max-width: 380px; margin: 0 auto; font-size: 0.875rem; }

/* --------------------------------------------------------------------------
   Error Pages
   -------------------------------------------------------------------------- */
.dc-error-page { padding: 5rem 1rem; }
.dc-error-code {
    font-size:   6rem;
    font-weight: 900;
    color:       #dee2e6;
    line-height: 1;
}

/* --------------------------------------------------------------------------
   Auth Pages
   -------------------------------------------------------------------------- */
.dc-auth-body {
    background:      linear-gradient(135deg, #1a2332 0%, #2d3e50 100%);
    min-height:      100vh;
    display:         flex;
    align-items:     center;
    justify-content: center;
    padding:         1rem;
}
.dc-auth-wrapper { width: 100%; max-width: 440px; }
.dc-auth-card {
    background:    #ffffff;
    border-radius: 1rem;
    padding:       2.5rem;
    box-shadow:    0 20px 60px rgba(0,0,0,0.25);
}
.dc-auth-brand {
    display:         flex;
    align-items:     center;
    justify-content: center;
    gap:             0.6rem;
    font-size:       1.5rem;
    font-weight:     800;
    color:           #1a2332;
    margin-bottom:   1.75rem;
}
.dc-auth-brand i { color: var(--dc-green); font-size: 1.8rem; }
.dc-auth-brand__logo { height: 88px; width: auto; }

.dc-auth-cta {
    border-color: #e9ecef !important;
    transition: border-color .15s ease, background-color .15s ease;
    font-size: 0.85rem;
}
.dc-auth-cta:hover {
    border-color: var(--dc-green) !important;
    background-color: var(--dc-green-light);
}

.dc-forgot-password-link {
    font-size: 0.85rem;
    text-decoration: none;
    font-weight: 600;
    color: var(--dc-green-dark, #00875f);
}
.dc-forgot-password-link:hover { text-decoration: underline; }

.dc-otp-input {
    font-size:      1.9rem;
    font-weight:    700;
    letter-spacing: 0.75rem;
    text-align:     center;
    padding-left:   0.5rem; /* re-centre for the letter-spacing on the right */
}

/* --------------------------------------------------------------------------
   Mobile Overlay
   -------------------------------------------------------------------------- */
.dc-overlay {
    display:    none;
    position:   fixed;
    inset:      0;
    background: rgba(0,0,0,0.5);
    z-index:    999;
}

/* --------------------------------------------------------------------------
   Flash Messages
   -------------------------------------------------------------------------- */
.dc-messages { padding: 0.75rem 1.5rem 0; }
.dc-messages .alert { border-radius: 0.5rem; font-size: 0.875rem; }

/* --------------------------------------------------------------------------
   Animal Module
   -------------------------------------------------------------------------- */

/* Animal Cards (list view) */
.dc-animal-card {
    transition:   box-shadow var(--dc-transition), transform var(--dc-transition);
    cursor:       pointer;
}
.dc-animal-card:hover {
    box-shadow: 0 4px 20px rgba(0,0,0,0.12) !important;
    transform:  translateY(-2px);
}
.dc-animal-card .card-img-top {
    height:      160px;
    object-fit:  cover;
    border-radius: var(--dc-card-radius) var(--dc-card-radius) 0 0;
}

/* Status badges - consistent across all animal views */
.badge.status-calf      { background: #e8f4fd; color: #17a2b8; border: 1px solid #b8e0f5; }
.badge.status-heifer    { background: #e3f2fd; color: var(--dc-blue); border: 1px solid #bdd8f5; }
.badge.status-lactating { background: var(--dc-green-light); color: var(--dc-green); border: 1px solid #a8e6da; }
.badge.status-dry       { background: #f1f2f6; color: #636e72; border: 1px solid #dfe4ea; }
.badge.status-pregnant  { background: #fff9e6; color: #f39c12; border: 1px solid #fde8a0; }
.badge.status-bull      { background: #2d3436; color: #ffffff; }
.badge.status-sold      { background: #f8f9fa; color: #adb5bd; border: 1px solid #dee2e6; }
.badge.status-dead,
.badge.status-culled    { background: #fdecea; color: var(--dc-red); border: 1px solid #f5c6cb; }

/* Animal Timeline */
.dc-timeline                     { position: relative; padding-left: 1.5rem; }
.dc-timeline__item               {
    position:      relative;
    padding-bottom: 1.25rem;
    border-left:   2px solid #e9ecef;
    padding-left:  1.25rem;
    margin-left:   0.4rem;
}
.dc-timeline__item:last-child    { border-left-color: transparent; }
.dc-timeline__dot                {
    position:      absolute;
    left:          -0.5rem;
    top:           0.2rem;
    width:         0.85rem;
    height:        0.85rem;
    border-radius: 50%;
    border:        2px solid #fff;
}
.dc-timeline__content            { font-size: 0.875rem; }

/* --------------------------------------------------------------------------
   Milk Module
   -------------------------------------------------------------------------- */

.dc-milk-entry-table th,
.dc-milk-entry-table td { padding: 0.5rem 0.75rem; vertical-align: middle; }
.dc-milk-entry-table input[type="number"] { min-width: 100px; }

/* Bulk entry grid rows */
.dc-bulk-row-recorded { background: rgba(0,184,148,0.05); }
.dc-bulk-row-recorded input { background: #f8f9fa; }

/* --------------------------------------------------------------------------
   Health Module
   -------------------------------------------------------------------------- */

/* Withdrawal alert banners */
.dc-withdrawal-banner {
    background:    linear-gradient(135deg, #fdecea, #fff5f5);
    border:        1px solid #f5c6cb;
    border-radius: 0.5rem;
    padding:       1rem 1.25rem;
    margin-bottom: 1rem;
}
.dc-withdrawal-banner .dc-withdrawal-days {
    font-size:   2rem;
    font-weight: 900;
    color:       var(--dc-red);
    line-height: 1;
}

/* Treatment table */
.dc-treatment-row { transition: background var(--dc-transition); }
.dc-treatment-row:hover { background: rgba(0,0,0,0.02); }
.dc-treatment-active { color: var(--dc-red); font-weight: 600; }
.dc-treatment-clear  { color: var(--dc-green); }

/* Notifiable disease flag */
.dc-notifiable-badge {
    display:        inline-flex;
    align-items:    center;
    gap:            0.3rem;
    background:     #fdecea;
    color:          var(--dc-red);
    font-size:      0.7rem;
    font-weight:    700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    padding:        0.15rem 0.5rem;
    border-radius:  4px;
    border:         1px solid #f5c6cb;
}

/* --------------------------------------------------------------------------
   Breeding Module
   -------------------------------------------------------------------------- */

/* Breeding outcome badges */
.dc-outcome-pending  { background: #e8f4fd; color: #17a2b8; border: 1px solid #b8e0f5; }
.dc-outcome-pregnant { background: #fff9e6; color: #f39c12; border: 1px solid #fde8a0; }
.dc-outcome-open     { background: #fdecea; color: var(--dc-red); border: 1px solid #f5c6cb; }
.dc-outcome-aborted  { background: #f1f2f6; color: #636e72; border: 1px solid #dfe4ea; }

/* Calving ease colours */
.dc-ease-easy      { color: var(--dc-green); }
.dc-ease-assisted  { color: #f39c12; }
.dc-ease-difficult { color: var(--dc-red); }
.dc-ease-caesarean { color: var(--dc-red); font-weight: 700; }

/* Pregnancy progress indicator */
.dc-pregnancy-bar {
    height:        6px;
    border-radius: 3px;
    background:    #e9ecef;
    overflow:      hidden;
}
.dc-pregnancy-bar__fill {
    height:        100%;
    background:    linear-gradient(90deg, var(--dc-green), #f39c12);
    border-radius: 3px;
    transition:    width 0.5s ease;
}

/* Conception rate big number */
.dc-conception-rate {
    font-size:   3.5rem;
    font-weight: 900;
    line-height: 1;
    color:       var(--dc-blue);
}

/* --------------------------------------------------------------------------
   Notifications Module
   -------------------------------------------------------------------------- */

/* Priority-coloured left border cards */
.dc-notif-urgent  { border-left: 4px solid var(--dc-red) !important; }
.dc-notif-high    { border-left: 4px solid #f39c12 !important; }
.dc-notif-medium  { border-left: 4px solid #17a2b8 !important; }
.dc-notif-low     { border-left: 4px solid #b2bec3 !important; }

/* Notification dropdown (in topbar) */
.dc-notif-dropdown {
    width:       360px;
    max-height:  440px;
    overflow-y:  auto;
    border:      none;
    box-shadow:  0 8px 30px rgba(0,0,0,0.15);
    border-radius: 0.75rem;
}
.dc-notif-dropdown-item {
    padding:      0.75rem 1rem;
    border-bottom: 1px solid #f1f2f6;
    transition:   background var(--dc-transition);
    white-space:  normal;
}
.dc-notif-dropdown-item:hover { background: #f8f9fa; }
.dc-notif-dropdown-item.unread { background: #fafffe; }

/* Bell badge */
.dc-bell-badge {
    position:  absolute;
    top:       -4px;
    right:     -4px;
    min-width: 18px;
    height:    18px;
    padding:   0 4px;
    font-size: 0.6rem;
    display:   flex;
    align-items: center;
    justify-content: center;
    border-radius: 9px;
    background: var(--dc-red);
    color:     #fff;
    font-weight: 700;
}

/* Calendar grid */
.dc-calendar-cell {
    min-height: 90px;
    vertical-align: top;
    padding:    0.4rem;
    font-size:  0.8rem;
}
.dc-calendar-cell.today {
    background:    rgba(0,184,148,0.06);
    border:        1px solid var(--dc-green) !important;
}
.dc-calendar-cell.other-month { background: #f8f9fa; opacity: 0.6; }
.dc-calendar-day-number {
    font-weight:   600;
    font-size:     0.8rem;
    margin-bottom: 0.25rem;
}
.dc-calendar-event {
    font-size:     0.65rem;
    padding:       1px 5px;
    border-radius: 3px;
    margin-bottom: 2px;
    white-space:   nowrap;
    overflow:      hidden;
    text-overflow: ellipsis;
    display:       block;
    line-height:   1.4;
}

/* --------------------------------------------------------------------------
   Sales & Distribution Module
   -------------------------------------------------------------------------- */

/* Stock level badges */
.dc-stock-good    { background: var(--dc-green-light); color: var(--dc-green); border: 1px solid #a8e6da; }
.dc-stock-medium  { background: #e8f4fd; color: var(--dc-blue); border: 1px solid #b8e0f5; }
.dc-stock-low     { background: #fff9e6; color: #f39c12; border: 1px solid #fde8a0; }
.dc-stock-empty   { background: #fdecea; color: var(--dc-red); border: 1px solid #f5c6cb; }

/* Credit ledger table */
.dc-ledger-debit  { color: var(--dc-red);   font-weight: 600; }
.dc-ledger-credit { color: var(--dc-green); font-weight: 600; }
.dc-ledger-balance {
    font-weight:  700;
    font-size:    1.05rem;
    padding-top:  0.5rem;
    border-top:   2px solid #dee2e6;
}

/* Credit balance indicator */
.dc-credit-balance {
    font-size:   2.5rem;
    font-weight: 900;
    line-height: 1;
}
.dc-credit-balance.over-limit { color: var(--dc-red); }
.dc-credit-balance.clear      { color: var(--dc-green); }

/* Selling point card grid */
.dc-sp-card {
    transition:   box-shadow var(--dc-transition), transform var(--dc-transition);
}
.dc-sp-card:hover {
    box-shadow: 0 4px 20px rgba(0,0,0,0.1) !important;
    transform:  translateY(-1px);
}

/* Delivery status flow */
.dc-delivery-pending   { color: #f39c12; }
.dc-delivery-delivered { color: var(--dc-green); }
.dc-delivery-cancelled { color: #b2bec3; }

/* Price history timeline */
.dc-price-timeline {
    position:   relative;
    padding-left: 1.25rem;
}
.dc-price-timeline::before {
    content:          '';
    position:         absolute;
    left:             5px;
    top:              0;
    bottom:           0;
    width:            2px;
    background:       #e9ecef;
}
.dc-price-dot {
    position:      absolute;
    left:          -1.25rem;
    top:           0.35rem;
    width:         10px;
    height:        10px;
    border-radius: 50%;
    background:    var(--dc-blue);
    border:        2px solid #fff;
}
.dc-price-up   { color: var(--dc-red); }
.dc-price-down { color: var(--dc-green); }

/* --------------------------------------------------------------------------
   Shared Utility Classes
   -------------------------------------------------------------------------- */

/* Section dividers */
.dc-section { margin-bottom: 2rem; }
.dc-section-header {
    display:         flex;
    align-items:     center;
    justify-content: space-between;
    margin-bottom:   1rem;
}
.dc-section-title {
    font-size:   0.8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    color:       #b2bec3;
}

/* Tab nav overrides */
.nav-tabs { border-bottom: 2px solid #e9ecef; }
.nav-tabs .nav-link {
    color:         #636e72;
    border:        none;
    border-bottom: 2px solid transparent;
    margin-bottom: -2px;
    font-size:     0.875rem;
    padding:       0.6rem 1rem;
}
.nav-tabs .nav-link:hover { color: #2d3436; border-bottom-color: #dee2e6; }
.nav-tabs .nav-link.active {
    color:              #2d3436;
    font-weight:        600;
    border-bottom-color: var(--dc-green);
    background:         transparent;
}

/* Pagination */
.page-link { color: var(--dc-blue); }
.page-item.active .page-link {
    background:   var(--dc-green);
    border-color: var(--dc-green);
}

/* List group */
.list-group-item-action:hover { background: #f8fffe; }

/* Definition lists */
dt { font-weight: 600; color: #636e72; font-size: 0.82rem; }
dd { color: #2d3436; }

/* Monospace values (IDs, codes) */
.dc-mono {
    font-family:    var(--dc-font-mono);
    font-size:      0.8rem;
    letter-spacing: 0.5px;
    color:          #636e72;
}

/* Farm ID pill */
.dc-farm-id {
    display:        inline-block;
    font-family:    var(--dc-font-mono);
    font-size:      0.7rem;
    font-weight:    700;
    letter-spacing: 1.5px;
    color:          var(--dc-green);
    background:     rgba(0,184,148,0.1);
    padding:        0.1rem 0.5rem;
    border-radius:  4px;
    border:         1px solid rgba(0,184,148,0.3);
}

/* Overdue indicator */
.dc-overdue {
    color:       var(--dc-red);
    font-weight: 600;
}
.dc-overdue::before {
    content: '⚠ ';
    font-size: 0.8em;
}

/* Positive/negative value colouring */
.dc-positive { color: var(--dc-green); font-weight: 600; }
.dc-negative { color: var(--dc-red);   font-weight: 600; }

/* --------------------------------------------------------------------------
   Responsive - Mobile
   -------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------
   Global overflow safety net - nothing on the page should ever be able
   to push the viewport wider than the screen. These are intentionally
   broad/defensive: they don't change desktop appearance (a bootstrap
   container/row/col system is already width:100% + box-sizing:border-box
   there) but stop stray long strings, images, or embeds from being the
   one element that forces a horizontal scrollbar on a phone.
   -------------------------------------------------------------------------- */
img, svg, video, iframe, embed, object, canvas {
    max-width: 100%;
    height:    auto;
}
/* Chart.js sets canvas width/height attributes directly for crisp
   rendering; let the attribute define the drawing buffer while CSS still
   caps the display box so it can never overflow its card on a phone. */
canvas[id] { height: auto; }

pre, code {
    white-space: pre-wrap;
    word-break:  break-word;
}

/* Long unbreakable strings (emails, farm IDs, ledger references) wrap
   instead of forcing their container wider than the viewport. */
.dc-page-header__title,
.dc-page-header__subtitle,
.card-header,
.dc-stat-card__value,
.dc-mono,
td, th {
    overflow-wrap: break-word;
    word-break:    break-word;
}

.modal-dialog { max-width: min(480px, calc(100vw - 1rem)); }
.modal-dialog.modal-sm { max-width: min(340px, calc(100vw - 1rem)); }
.modal-dialog.modal-lg { max-width: min(640px, calc(100vw - 1rem)); }
.modal-dialog.modal-xl { max-width: min(760px, calc(100vw - 1rem)); }

/* --------------------------------------------------------------------------
   Responsive - Mobile
   -------------------------------------------------------------------------- */
@media (max-width: 991.98px) {
    .dc-sidebar {
        transform: translateX(-100%);
    }
    .dc-sidebar.is-open {
        transform: translateX(0);
    }
    .dc-main {
        margin-left: 0;
    }
    .dc-topbar__menu-toggle {
        display: block;
    }
    .dc-overlay.is-visible {
        display: block;
    }
    .dc-content {
        padding: 1.25rem 1rem;
    }
    .dc-stat-card__value {
        font-size: 1.0rem;
    }
    .dc-notif-dropdown {
        width: calc(100vw - 2rem);
    }

    /* ------------------------------------------------------------------
       Top bar - was a fixed 60px-tall non-wrapping row. On narrower
       screens, pages with several action buttons (dashboards, list
       pages) had no room to fit everything on one line, so the buttons
       either overflowed off-screen or visually overlapped the page
       content directly below the bar. Let it wrap onto extra rows and
       grow in height instead of clipping.
       ------------------------------------------------------------------ */
    .dc-topbar {
        height:       auto;
        min-height:   var(--dc-topbar-height);
        flex-wrap:    wrap;
        row-gap:      0.5rem;
        padding:      0.65rem 1rem;
    }
    .dc-topbar__row1 {
        flex:  1 1 100%;
        width: 100%;
    }
    .dc-topbar__breadcrumb {
        flex:  1 1 auto;
        min-width: 0; /* allow the breadcrumb to actually shrink/truncate */
    }
    .dc-topbar__actions {
        flex:         1 1 100%;
        flex-wrap:    wrap;
        gap:          0.4rem;
        justify-content: flex-start;
    }
    /* Prevent individual buttons from being squeezed/shrunk (which was
       wrapping their text internally into tall narrow boxes) now that the
       row itself can wrap - each button keeps its natural width. This is
       the version that worked: no forced 50/50 columns to fight the
       browser over, buttons just wrap onto a new line when they run out
       of room. Padding/font trimmed down further per feedback that there
       was too much empty space inside each button.
       IMPORTANT: keep these on one line (white-space: nowrap, the
       Bootstrap .btn default). Letting the label itself wrap (white-space:
       normal) seems safer but actually breaks flex sizing for flex-basis:
       auto items - the browser falls back to a shrink-to-fit calculation
       that, with multi-word labels ("Preg Check", "Sire Catalog"), collapses
       every button to a narrow column and stacks them one per row instead
       of flowing side by side. Keeping labels on one line is what makes
       flex-wrap size and wrap each button correctly by its natural width. */
    .dc-topbar__actions > .btn,
    .dc-topbar__actions > a {
        flex-shrink: 0;
        padding:     0.4rem 0.6rem;
        font-size:   0.8rem;
        white-space: nowrap;
    }
    /* Action buttons/links in the top bar are marked up with Bootstrap's
       "col-6 col-md-auto" so they lay out as an auto-sized row on desktop
       (col-md-auto). Below md that "col-6" half is still active and forces
       every button to exactly 50% width, which is what was cramming long
       labels ("Off-Taker Sales", "ATM Maintenance") into two-line buttons
       instead of letting the row simply wrap. Neutralise the grid width on
       phones/tablets so each button hugs its own label - short buttons
       ("Heat", "Service", "Preg Check") then naturally sit three to a row
       and longer ones wrap to their own line, with no forced column split. */
    .dc-topbar__actions > [class*="col-"] {
        width:     auto;
        max-width: none;
        flex:      0 0 auto;
    }

    /* Pages with several longer-worded buttons (Health, Breeding) don't
       settle into a clean wrap under the natural-width rule above - one
       long label can end up alone on a line while short ones leave gaps.
       Rather than fighting Bootstrap's column classes with flex-basis
       math, those pages wrap their whole action set in a single
       <div class="dc-actions-grid2"> - see below - which switches to a
       real 2-column CSS grid on phones/tablets, guaranteeing exactly two
       buttons per row with no possibility of sideways overflow. */
    .dc-actions-grid2 {
        display:               grid;
        grid-template-columns: 1fr 1fr;
        gap:                   0.4rem;
        width:                 100%;
        flex:                  1 1 100%;
    }
    .dc-actions-grid2 .btn {
        width:           100%;
        display:         flex;
        align-items:     center;
        justify-content: center;
        padding:         0.32rem 0.4rem;
        font-size:       0.72rem;
        white-space:     normal;
        text-align:      center;
        line-height:     1.2;
    }

    /* Card headers, page headers, and any other title-plus-button /
       label-plus-value row using Bootstrap's d-flex + justify-content-
       between - same non-wrapping problem as the top bar, at the same
       breakpoint. Covers list-group items, alert banners with a dismiss
       action, and every card-header across the app, not just the ones we
       happened to touch directly. */
    .d-flex.justify-content-between {
        flex-wrap: wrap;
        row-gap:   0.5rem;
    }
}

@media (max-width: 767.98px) {
    .dc-page-header__title {
        font-size: 1.2rem;
    }
    .dc-calendar-cell {
        min-height: 60px;
        padding:    0.2rem;
    }
    .dc-calendar-event {
        display: none;
    }
    .dc-calendar-cell.has-events::after {
        content:       '●';
        color:         var(--dc-blue);
        font-size:     0.5rem;
        display:       block;
        text-align:    center;
    }

    /* Stat / KPI tiles - 2-per-row on phones (see templates using
       "col-6 col-sm-6 ...", "col-6 col-md-3", etc). Kept tight per
       feedback that there was still too much white space inside each
       tile - padding, icon, and gaps trimmed down further so label,
       value, and icon sit close together. */
    .row.g-3 > [class*="col-"] > .dc-stat-card .card-body,
    .row.g-4 > [class*="col-"] > .dc-stat-card .card-body {
        padding: 0.55rem 0.65rem;
    }
    .dc-stat-card {
        max-width:  100%;
        overflow:   hidden;
        box-sizing: border-box;
    }
    .dc-stat-card .card-body > .d-flex {
        gap: 0.3rem;
    }
    .dc-stat-card .card-body > .d-flex > div:first-child {
        min-width: 0;
        flex:      1 1 auto;
    }
    .dc-stat-card .card-body > .d-flex > div:first-child > div {
        margin-top: 0 !important;
    }
    .dc-stat-card__icon {
        width:      26px;
        height:     26px;
        font-size:  0.65rem;
        border-radius: 5px;
        flex-shrink: 0;
    }
    .dc-stat-card__label {
        font-size:   0.55rem;
        line-height: 1.2;
        word-break:  break-word;
    }
    .dc-stat-card__value {
        font-size: 1.0rem;
    }
    .dc-stat-card__subtitle {
        font-size: 0.66rem;
    }
    .row.g-3 { --bs-gutter-x: 0.3rem; row-gap: 0.3rem; }
    .row.g-4 { --bs-gutter-x: 0.3rem; row-gap: 0.3rem; }

    .dc-report-icon {
        width:     42px;
        height:    42px;
        font-size: 1.15rem;
    }
}

@media (max-width: 575.98px) {
    .dc-auth-card {
        padding: 1.75rem 1.25rem;
    }
    .dc-error-code {
        font-size: 4rem;
    }
    .dc-conception-rate {
        font-size: 2.5rem;
    }
    .dc-credit-balance {
        font-size: 2rem;
    }

    /* KPI/stat tiles that opt in via .dc-kpi-col - one per row, full
       width, on phones. Used by pages with 4-5 KPI tiles where a longer
       label ("Outstanding Credit", "Off-Taker Sales") gets cramped at
       half-width (Finance overview, Sales dashboard). Pages that want
       the denser default 2-per-row grid (Health, Breeding - see the
       767.98 breakpoint above) simply don't add this class and are left
       alone here. */
    .row > [class*="col-"].dc-kpi-col {
        flex:      0 0 100%;
        max-width: 100%;
        width:     100%;
    }

    /* Now that each .dc-kpi-col tile has the full row to itself there's
       no need for the cramped 2-per-row sizing - open it back up a
       little. Scoped to .dc-kpi-col specifically so it doesn't affect
       the denser 2-per-row pages, which keep the smaller 767.98 sizing. */
    .row > [class*="col-"].dc-kpi-col .dc-stat-card .card-body {
        padding: 0.75rem 0.9rem;
    }
    .dc-kpi-col .dc-stat-card__icon {
        width:         40px;
        height:        40px;
        font-size:     0.70rem;
        border-radius: 8px;
    }
    .dc-kpi-col .dc-stat-card__label    { font-size: 0.55rem; }
    .dc-kpi-col .dc-stat-card__value    { font-size: 1.0rem; }
    .dc-kpi-col .dc-stat-card__subtitle { font-size: 0.5rem; }
}

/* --------------------------------------------------------------------------
   Print Styles
   -------------------------------------------------------------------------- */
@media print {
    .dc-sidebar,
    .dc-topbar,
    .dc-footer,
    .btn,
    .nav-tabs,
    form[method="post"] { display: none !important; }

    .dc-main { margin-left: 0 !important; }
    .dc-content { padding: 0 !important; }

    .card {
        box-shadow: none !important;
        border:     1px solid #dee2e6 !important;
    }

    .dc-ledger-balance {
        border-top: 2px solid #000 !important;
    }

    body { font-size: 11pt; color: #000; }
    a    { color: #000; text-decoration: none; }
}

/* ==========================================================================
   Dashboard - Module 15 additions
   ========================================================================== */

/* Alert bar - horizontal strip of clickable alert chips */
.dc-alert-bar {
    display:   flex;
    flex-wrap: wrap;
    gap:       0.5rem;
    margin-bottom: 1rem;
}

.dc-alert-chip {
    display:         inline-flex;
    align-items:     center;
    gap:             0.4rem;
    padding:         0.35rem 0.75rem;
    border-radius:   2rem;
    font-size:       0.8rem;
    font-weight:     600;
    text-decoration: none;
    transition:      filter var(--dc-transition);
}
.dc-alert-chip:hover { filter: brightness(0.92); text-decoration: none; }

.dc-alert-chip--danger {
    background: #fdecea;
    color:      var(--dc-red);
    border:     1px solid #f5c6cb;
}
.dc-alert-chip--warning {
    background: #fff9e6;
    color:      #e67e22;
    border:     1px solid #fde8a0;
}
.dc-alert-chip--info {
    background: #e8f4fd;
    color:      var(--dc-blue);
    border:     1px solid #b8e0f5;
}

/* Notification type icon in list items */
.dc-notif-type-icon {
    font-size:  1.1rem;
    width:      1.4rem;
    text-align: center;
    flex-shrink: 0;
}

/* Quick action buttons */
.dc-quick-action {
    padding:        0.5rem 0.6rem;
    text-align:     left;
    border-radius:  0.5rem;
    transition:     background var(--dc-transition),
                    border-color var(--dc-transition),
                    transform var(--dc-transition);
}
.dc-quick-action:hover {
    transform: translateY(-1px);
    box-shadow: 0 3px 10px rgba(0,0,0,0.08);
}
.dc-quick-action i {
    font-size:  1rem;
    flex-shrink: 0;
}

/* Finance section border-left cards */
.border-4 { border-width: 4px !important; }

/* Section title divider */
.dc-section-title {
    font-size:      0.72rem;
    font-weight:    700;
    text-transform: uppercase;
    letter-spacing: 1.2px;
    color:          #b2bec3;
    padding-bottom: 0.25rem;
    border-bottom:  1px solid #f1f2f6;
}

/* Subscription CSS additions (Module 12) */
.dc-plan-badge {
    font-size:      0.7rem;
    letter-spacing: 0.5px;
    padding:        0.2rem 0.6rem;
}

.dc-upgrade-prompt {
    background:    #fff9e6;
    border:        1px solid #fde8a0 !important;
    border-radius: 0.5rem;
}

.dc-mpesa-spinner {
    animation: pulse 1.5s ease-in-out infinite;
}
@keyframes pulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50%       { opacity: 0.7; transform: scale(1.05); }
}

.dc-plan-current {
    border: 2px solid var(--dc-green) !important;
}

/* Report hub cards (Module 11) */
.dc-report-card {
    transition: box-shadow var(--dc-transition), transform var(--dc-transition);
    cursor:     pointer;
}
.dc-report-card:hover {
    box-shadow: 0 6px 24px rgba(0,0,0,0.1) !important;
    transform:  translateY(-2px);
}
.dc-report-icon {
    width:           52px;
    height:          52px;
    border-radius:   12px;
    display:         flex;
    align-items:     center;
    justify-content: center;
    font-size:       1.4rem;
}

/* Purple colour helpers (used in finance and reports) */
.bg-purple-subtle { background-color: #f0eeff !important; }
.text-purple       { color: var(--dc-purple) !important; }
.border-purple     { border-color: var(--dc-purple) !important; }

/* Finance P&L additions */
.dc-pl-positive { color: var(--dc-green); font-weight: 700; }
.dc-pl-negative { color: var(--dc-red);   font-weight: 700; }

/* Min-width helper for truncating flex children */
.min-w-0 { min-width: 0; }

/* ---------------------------------------------------------------------- */
/* Password field with show/hide toggle                                    */
/* ---------------------------------------------------------------------- */
.dc-password-field {
    position: relative;
}
.dc-password-field input {
    padding-right: 2.75rem;
}
.dc-password-toggle {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 2.75rem;
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    color: #636e72;
    cursor: pointer;
    z-index: 5;
}
.dc-password-toggle:hover {
    color: #2d3436;
}
.dc-password-toggle:focus {
    outline: none;
    color: var(--dc-blue, #0d6efd);
}
/* ===========================================================
   Pedigree / Lineage Tree
   Symmetric two-branch tree (Dam left, Sire right) at every
   generation, so both sides are equally visible - previously
   this component had no styling, so the dam's branch could
   look "missing" even though it was in the markup.
   =========================================================== */
.ped-tree-scroll {
    overflow-x: auto;
    padding: 1rem 0.5rem 1.5rem;
}
.ped-node {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}
.ped-box {
    position: relative;
    min-width: 150px;
    max-width: 190px;
    background: #fff;
    border: 1.5px solid #e2e6ea;
    border-radius: 0.6rem;
    padding: 0.6rem 0.75rem;
    box-shadow: 0 1px 3px rgba(0,0,0,0.04);
}
.ped-box--male {
    border-color: #a9c8f5;
    background: #f4f8fe;
}
.ped-box--female {
    border-color: #f5b8d0;
    background: #fef4f8;
}
.ped-box--external {
    border-style: dashed;
    background: #f8f9fa;
}
.ped-box--unknown {
    min-width: 150px;
    color: #adb5bd;
    font-size: 0.8rem;
    font-style: italic;
    border-style: dashed;
}
.ped-box__name {
    display: block;
    font-weight: 700;
    font-size: 0.85rem;
    color: #1a2332;
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
a.ped-box__name:hover {
    color: var(--dc-green, #00b894);
    text-decoration: underline;
}
.ped-box__tag {
    font-size: 0.7rem;
    color: #868e96;
    margin-top: 0.1rem;
}
.ped-box__breed {
    font-size: 0.7rem;
    color: #495057;
    margin-top: 0.15rem;
}
.ped-box__foundation, .ped-box__pedigree {
    display: inline-block;
    margin-top: 0.35rem;
    font-size: 0.62rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    padding: 0.1rem 0.45rem;
    border-radius: 1rem;
}
.ped-box__foundation {
    background: #e9ecef;
    color: #495057;
}
.ped-box__pedigree {
    background: #d1f2eb;
    color: #0a7d5e;
}

/* Connector lines + two-column (Dam / Sire) children row */
.ped-children {
    display: flex;
    justify-content: center;
    gap: 2.25rem;
    margin-top: 1.5rem;
    position: relative;
}
.ped-children::before {
    content: "";
    position: absolute;
    top: -0.85rem;
    left: 50%;
    width: 1px;
    height: 0.85rem;
    background: #dcdfe3;
}
.ped-child {
    position: relative;
    padding-top: 0.85rem;
}
.ped-child::before {
    content: "";
    position: absolute;
    top: 0;
    left: 50%;
    width: 1px;
    height: 0.85rem;
    background: #dcdfe3;
}
.ped-children > .ped-child:first-child::after,
.ped-children > .ped-child:last-child::after {
    content: "";
    position: absolute;
    top: 0;
    width: 50%;
    height: 1px;
    background: #dcdfe3;
}
.ped-children > .ped-child:first-child::after { left: 50%; }
.ped-children > .ped-child:last-child::after   { right: 50%; }

/* Label each side so it's unambiguous which branch is which */
.ped-child:first-child > .ped-node::before,
.ped-child:last-child > .ped-node::before {
    content: "Dam";
    display: block;
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: #d6336c;
    margin-bottom: 0.25rem;
}
.ped-child:last-child > .ped-node::before {
    content: "Sire";
    color: #1c7ed6;
}

@media (max-width: 576px) {
    .ped-box { min-width: 130px; max-width: 160px; }
    .ped-children { gap: 1rem; }
}

/* --------------------------------------------------------------------------
   Hover-lift (used by clickable summary cards, e.g. vet "My Farms" tiles)
   -------------------------------------------------------------------------- */
.dc-hover-lift {
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.dc-hover-lift:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 16px rgba(0,0,0,0.08) !important;
}
/* ==========================================================================
   PWA - Offline banner, sync queue, install modal
   ========================================================================== */

/* --------------------------------------------------------------------------
   Connectivity banner - slides in above page content when offline
   -------------------------------------------------------------------------- */
.dc-offline-banner {
    display: none;
    align-items: center;
    gap: 0.5rem;
    background: #fff4e6;
    border-bottom: 1px solid #ffd8a8;
    color: #7c4a03;
    font-size: 0.85rem;
    font-weight: 500;
    padding: 0.6rem 1.25rem;
}
.dc-offline-banner.is-visible { display: flex; }
.dc-offline-banner i { font-size: 1rem; color: #e8590c; flex-shrink: 0; }

/* --------------------------------------------------------------------------
   Sidebar "Pending Sync" badge
   -------------------------------------------------------------------------- */
.dc-sidebar__badge {
    margin-left: auto;
    background: var(--dc-orange);
    color: #fff;
    font-size: 0.68rem;
    font-weight: 700;
    line-height: 1;
    padding: 0.28rem 0.5rem;
    border-radius: 999px;
    min-width: 1.4rem;
    text-align: center;
}

/* --------------------------------------------------------------------------
   Offline sync queue list (inside the "Pending Sync" modal)
   -------------------------------------------------------------------------- */
.dc-queue-list {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    max-height: 50vh;
    overflow-y: auto;
}
.dc-queue-item {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
    background: #f8f9fb;
    border: 1px solid #edf0f3;
    border-radius: 10px;
    padding: 0.75rem 0.9rem;
}
.dc-queue-item--error {
    background: #fff5f5;
    border-color: #ffd6d6;
}
.dc-queue-item__label {
    font-weight: 600;
    font-size: 0.88rem;
    color: #1a2332;
}
.dc-queue-item__summary {
    font-size: 0.82rem;
    color: #5a6472;
    margin-top: 0.1rem;
}
.dc-queue-item__time {
    font-size: 0.74rem;
    color: #98a2b3;
    margin-top: 0.3rem;
}
.dc-queue-item__error {
    font-size: 0.78rem;
    color: #c92a2a;
    margin-top: 0.3rem;
}
.dc-queue-item__actions {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    flex-shrink: 0;
}
.dc-queue-item__actions .btn { white-space: nowrap; }

/* --------------------------------------------------------------------------
   Toasts (offline saved / synced / update available)
   -------------------------------------------------------------------------- */
.dc-toast {
    min-width: 280px;
    border-radius: 10px;
    box-shadow: 0 10px 30px rgba(0,0,0,0.25);
}

/* --------------------------------------------------------------------------
   "New version available" update banner (static/js/dc-offline.js).
   Floats above everything, bottom-center on desktop; on mobile it becomes
   a full-width bar so the Refresh button always has an easy-to-tap target.
   -------------------------------------------------------------------------- */
.dc-update-banner {
    position: fixed;
    left: 50%;
    bottom: calc(20px + env(safe-area-inset-bottom, 0px));
    transform: translateX(-50%) translateY(12px);
    z-index: 1200;
    display: flex;
    align-items: center;
    gap: 0.9rem;
    background: #1a2332;
    color: #fff;
    border-radius: 999px;
    padding: 0.6rem 0.6rem 0.6rem 1.15rem;
    box-shadow: 0 14px 34px -10px rgba(0,0,0,.5);
    max-width: calc(100% - 2rem);
    opacity: 0;
    transition: opacity .2s ease, transform .2s ease;
}
.dc-update-banner.is-visible {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}
.dc-update-banner__content {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
}
.dc-update-banner__icon {
    color: var(--dc-green);
    font-size: 1.2rem;
    flex-shrink: 0;
    animation: dc-update-spin 2.5s linear infinite;
}
@keyframes dc-update-spin { to { transform: rotate(360deg); } }
.dc-update-banner__text {
    font-size: 0.85rem;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.dc-update-banner__btn {
    background: var(--dc-green);
    color: #fff;
    border: none;
    border-radius: 999px;
    font-weight: 700;
    font-size: 0.8rem;
    padding: 0.55rem 1.2rem;
    flex-shrink: 0;
    white-space: nowrap;
    cursor: pointer;
}
.dc-update-banner__btn:hover,
.dc-update-banner__btn:focus { background: var(--dc-green-dark); color: #fff; }

/* Below ~576px: stop trying to fit everything on one line - stack the
   message on top and give Refresh its own full-width row, so the tap
   target is always generous and the text never gets squeezed or clipped.
   Also respects the iOS home-indicator safe area so it never sits flush
   against the bottom edge on notched phones (installed PWA / Safari). */
@media (max-width: 575.98px) {
    .dc-update-banner {
        left: 12px;
        right: 12px;
        bottom: calc(12px + env(safe-area-inset-bottom, 0px));
        transform: translateY(12px);
        max-width: none;
        width: auto;
        border-radius: 18px;
        flex-direction: column;
        align-items: stretch;
        gap: 0.65rem;
        padding: 0.9rem 1.1rem 1rem;
    }
    .dc-update-banner.is-visible { transform: translateY(0); }
    .dc-update-banner__content { gap: 0.6rem; }
    .dc-update-banner__text { white-space: normal; line-height: 1.35; overflow: visible; text-overflow: clip; }
    .dc-update-banner__btn { width: 100%; padding: 0.7rem 1rem; font-size: 0.85rem; }
}

/* --------------------------------------------------------------------------
   Install App modal
   -------------------------------------------------------------------------- */
.dc-install-modal {
    border: none;
    border-radius: 18px;
    overflow: hidden;
}
.dc-install-modal__icon {
    width: 76px;
    height: 76px;
    border-radius: 20px;
    box-shadow: 0 10px 24px rgba(26,35,50,0.25);
}
.dc-install-steps {
    background: #f8f9fb;
    border-radius: 10px;
    padding: 0.9rem 1rem;
}
.dc-install-step {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    font-size: 0.86rem;
    color: #333;
    padding: 0.3rem 0;
}
.dc-install-step__num {
    flex-shrink: 0;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--dc-green);
    color: #fff;
    font-size: 0.72rem;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* --------------------------------------------------------------------------
   Simple multi-step wizard indicator (Insurance: Insure Animals flow).
   -------------------------------------------------------------------------- */
.dc-wizard-steps {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.dc-wizard-step {
    font-size: 0.78rem;
    font-weight: 600;
    color: #9aa1ab;
    background: #f4f6f9;
    border-radius: 999px;
    padding: 0.35rem 0.9rem;
}
.dc-wizard-step--active {
    color: #fff;
    background: var(--dc-green);
}
.dc-wizard-step--done {
    color: var(--dc-green);
    background: #e6f7f1;
}

/* --------------------------------------------------------------------------
   Standalone (installed) app polish - hides the browser-chrome-era
   affordances that don't make sense once running as a home-screen app,
   and respects the iOS safe area around notches / home indicators.
   -------------------------------------------------------------------------- */
@media (display-mode: standalone) {
    .dc-topbar {
        padding-top: calc(env(safe-area-inset-top, 0px));
    }
    body {
        padding-bottom: env(safe-area-inset-bottom, 0px);
    }
}

/* --------------------------------------------------------------------------
   Public marketing nav - mobile menu (hamburger + collapsible panel).
   Shared by templates/base/_public_nav.html, included on the landing page,
   marketplace, for-farmers / for-vets, and pricing pages.
   -------------------------------------------------------------------------- */
.dc-nav-toggler {
    background: transparent;
    border: 1.5px solid var(--dc-public-nav-border, #dcece5);
    border-radius: 0.5rem;
    width: 40px;
    height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.3rem;
    color: #1a2332;
    line-height: 1;
}
.dc-nav-toggler:hover,
.dc-nav-toggler:focus {
    border-color: var(--dc-green);
    color: var(--dc-green-dark);
}
.dc-nav-toggler:focus { outline: none; box-shadow: 0 0 0 3px rgba(0,184,148,.15); }

.dc-mobile-nav {
    display: flex;
    flex-direction: column;
    border-top: 1px solid var(--dc-public-nav-border, #dcece5);
    padding-top: 0.75rem;
}
.dc-mobile-nav__link {
    display: block;
    padding: 0.65rem 0.25rem;
    color: #1a2332;
    font-weight: 600;
    font-size: 0.95rem;
    text-decoration: none;
    border-bottom: 1px solid #f1f5f3;
}
.dc-mobile-nav__link:hover { color: var(--dc-green-dark); }

/* --------------------------------------------------------------------------
   Public marketing footer - shared partial (templates/base/_public_footer.html)
   -------------------------------------------------------------------------- */
.dc-public-footer {
    border-top: 3px solid var(--dc-green);
    background: #f4faf8;
    padding: 2.5rem 0 2rem;
}
.dc-public-footer__whatsapp {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    background: #25D366;
    color: #fff;
    font-weight: 600;
    font-size: 0.9rem;
    padding: 0.6rem 1.4rem;
    border-radius: 999px;
    text-decoration: none;
    box-shadow: 0 10px 24px -10px rgba(37,211,102,.6);
}
.dc-public-footer__whatsapp:hover { background: #1fb857; color: #fff; }
.dc-public-footer__socials {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    margin-top: 1.5rem;
}
.dc-public-footer__social {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: #fff;
    border: 1.5px solid #dcece5;
    color: #1a2332;
    font-size: 1.05rem;
    text-decoration: none;
}
.dc-public-footer__social:hover {
    border-color: var(--dc-green);
    color: var(--dc-green-dark);
    background: var(--dc-green-light);
}
.dc-public-footer__copyright { color: #8a9591; font-size: 0.85rem; margin-top: 1.25rem; }

/* --------------------------------------------------------------------------
   Sideways-scroll affordance for any horizontally-scrolling strip (tab
   bars, wide filter/action rows, etc.) - a soft edge fade that hints
   "there's more this way", and disappears once you've scrolled all the
   way to the end. Reused wherever the site already relies on plain
   overflow-x:auto (tabs, tables) but the content can silently overflow
   past the visible edge on a narrow phone with no visual cue.
   Usage: wrap the scrolling element in <div class="dc-scroll-fade">,
   add class="dc-scroll-fade-target" to the scrolling element itself
   (in addition to whatever ID/classes it already has), then call
   initScrollFade() (see dairycore.js / inline per-page script) once
   the element exists.
   -------------------------------------------------------------------------- */
.dc-scroll-fade { position: relative; }
.dc-scroll-fade::after {
    content: "";
    position: absolute;
    top: 0; right: 0; bottom: 0;
    width: 32px;
    background: linear-gradient(to right, rgba(255,255,255,0), rgba(255,255,255,0.97));
    pointer-events: none;
    opacity: 1;
    transition: opacity .15s ease;
    border-radius: 0 0.5rem 0.5rem 0;
}
.dc-scroll-fade.dc-scroll-fade--end::after { opacity: 0; }
.dc-scroll-fade.dc-scroll-fade--none::after { opacity: 0; }
