/* Fixed app shell — DESKTOP ONLY (see the matching `@media (min-width:
   992px)` block below that gives `.main-panel` its own `overflow-y: auto`):
   the page itself never scrolls there — only the sidebar and the main
   content pane scroll independently, each showing a scrollbar only when
   ITS OWN content exceeds the viewport. This must not apply below 992px:
   the mobile layout has no independently-scrolling `.main-panel` (that
   fix is desktop-scoped), so an unconditional `overflow: hidden` here left
   mobile pages completely unscrollable — confirmed as a real bug, not
   intentional. Mobile instead gets ordinary whole-page scrolling, with the
   fixed-position bottom tab bar staying pinned above it regardless. */
@media (min-width: 992px) {
  html, body {
    height: 100%;
    overflow: hidden;
  }
}

/* Standard stat-tile look (label + big value + a colored circular icon
   badge on the right) — shared sitewide so every page's summary cards
   (Dashboard, Planner, ...) match instead of each page styling its own
   `.stat-card` in a local <style> block and slowly drifting apart. Was
   previously defined only inside /dashboard, which is why the same
   `.stat-card`/`.stat-card-icon` markup on the Planner page rendered with
   no icon styling at all (plain square background, no circle). */
/* Active sidebar item — a soft diagonal gradient + colored glow instead of
   the vendor theme's flat `#0f3d18` fill, so the active page reads as a
   raised/glossy pill rather than a plain solid block. Overrides
   vertical-layout-light/style.css:29048 (loaded before this file). */
.sidebar .nav .nav-item.active > .nav-link {
  background: linear-gradient(135deg, #2a7a31, #14501c);
  box-shadow: 0 4px 14px rgba(21, 87, 36, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.18);
  border-radius: 10px;
  margin: 0 0.75rem;
  width: auto;
}

.stat-card { cursor: pointer; transition: box-shadow 0.15s ease, transform 0.15s ease; }
.stat-card:hover { box-shadow: 0 0.5rem 1.5rem rgba(0,0,0,0.12); transform: translateY(-2px); }
.stat-card .stat-card-icon { width: 48px; height: 48px; flex-shrink: 0; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 1.4rem; color: #fff; }
.stat-card .card-body > div:first-child { min-width: 0; flex: 1 1 auto; }
/* One line always; tenant-features.js shrinks a value that would not fit its tile (long rand amounts on phones). */
.stat-card .stat-card-value { font-size: 1.75rem; font-weight: 700; margin-bottom: 0.15rem; white-space: nowrap; }
.stat-card .stat-card-label { color: #8f9cb3; margin-bottom: 0.35rem; font-size: 0.9rem; }

/* Vendor bug (present in both the light and dark compiled stylesheets): a
   leftover "Alerts" demo-showcase block later in each file re-declares
   `.alert-light { color: #f8f9fa }` — a near-white text color — clobbering
   the correct, earlier Bootstrap-variable-driven rule that already computes
   a readable dark gray (var(--bs-light-text-emphasis), #495057) for this
   alert's light background. The result is white text on a near-white alert
   box, confirmed on the Production and HR & Payroll pages. Restoring the
   correct color here (this file loads last on every page, in both themes)
   fixes it without touching the vendored theme files directly. */
.alert-light {
  color: var(--bs-light-text-emphasis, #495057);
}

/* Vendor bug, broader case of the same class of issue as .alert-light above:
   Bootstrap 5.3 ships a SECOND, correct set of dark-mode variable values in
   every compiled stylesheet, but gates it behind `[data-bs-theme="dark"]` —
   an attribute this app never sets (it swaps the whole stylesheet FILE
   instead). So --bs-secondary-bg/--bs-tertiary-bg/etc. silently keep their
   light-mode value even when the dark stylesheet is loaded, e.g. disabled
   form fields (which use --bs-secondary-bg) staying pale gray with
   near-white text on top — confirmed on the Profile page's Email/Role
   fields. `body.theme-dark` is set by theme-toggle.js whenever dark mode is
   active; restoring the values Bootstrap itself already ships (just
   unreachable) here fixes every component that reads these variables at
   once, sitewide, without touching either vendored theme file. */
body.theme-dark {
  --bs-secondary-bg: #343a40;
  --bs-secondary-color: rgba(222, 226, 230, 0.75);
  --bs-tertiary-bg: #2b3035;
  --bs-tertiary-color: rgba(222, 226, 230, 0.5);
  --bs-emphasis-color: #fff;
  --agricore-content-bg: #1e1e2f;
}

/* `.content-wrapper`'s own real background per theme (#f6f7fb light /
   #1e1e2f dark — vertical-layout-light/dark's own hardcoded, non-variable
   values; --bs-body-bg itself is one of the unreachable-dark-variant
   variables above, so it can't be reused here). Exposed as a variable so
   the mobile hero's curved bottom edge (below) can blend into whichever
   theme is active without duplicating the color in two places. */
:root {
  --agricore-content-bg: #F8F4EA;
}

/* 7khalas cream (#F8F4EA) replaces the theme's grey-white page background in
   light mode: the page behind the cards, the footer and the loading screen.
   Cards stay white so they still lift off the page. Dark mode is untouched. */
body:not(.theme-dark),
body:not(.theme-dark) .content-wrapper,
body:not(.theme-dark) .footer,
body:not(.theme-dark) .main-panel {
  background: var(--agricore-content-bg);
}

/* Bootstrap's tooltip reuses --bs-emphasis-color for its background
   (--bs-tooltip-bg: var(--bs-emphasis-color)) and --bs-body-bg for its text
   color — fine in true light/dark builds, but --bs-body-bg never got a dark
   override above (only form-field variables did), so it stays white. Once
   --bs-emphasis-color was corrected to white for dark mode (the fix above),
   every tooltip became white text on a white background. Restoring the
   tooltip's own colors directly, scoped to dark mode, fixes it without
   touching the emphasis-color fix's original purpose. */
body.theme-dark .tooltip {
  --bs-tooltip-bg: #000;
  --bs-tooltip-color: #fff;
}

/* Page stylesheets hard-code light surfaces (#f8f9fa section headers,
   #f0f0f0 totals rows, #fff focused inputs, light hover rows, the
   Production page's #f7faf8 backdrop). In dark mode those became pale
   boxes under near-white text. Repoint them to the dark surfaces above. */
body.theme-dark .agricore-production-page { background: transparent; }
body.theme-dark .bs-section-header,
body.theme-dark .budget-section-header,
body.theme-dark .smart-filter-box,
body.theme-dark .cp-stage-chip,
body.theme-dark .agricore-planting-detail-row td { background: var(--bs-tertiary-bg); color: inherit; }
body.theme-dark .bs-total-row,
body.theme-dark .cf-total-row,
body.theme-dark .budget-total-row,
body.theme-dark .status-card.active { background: var(--bs-secondary-bg); color: #fff; }
body.theme-dark .group-card:hover,
body.theme-dark .planting-row:hover,
body.theme-dark .agricore-cp-table tbody tr.js-planting-row:hover,
body.theme-dark .cp-quick-action:hover,
body.theme-dark .field-list-item:hover { background: var(--bs-tertiary-bg); }
body.theme-dark .bs-row input.form-control:focus,
body.theme-dark .bs-row input.bs-label-input:focus,
body.theme-dark .budget-cell-input:focus { background: var(--bs-secondary-bg); color: #fff; }
body.theme-dark .agricore-lg-drawer { background: #27293d; color: #e0e0e0; }
body.theme-dark .withholding-banner { background: rgba(244, 180, 0, .12); color: #ffd666; }
body.theme-dark .retreat-banner { background: rgba(120, 140, 255, .12); color: #b9c4ff; }
/* The Production page's cards use --bs-body-bg, which stays #fff in dark mode (see above), so its
   rows showed near-white text on white. Give them the dark card surface and readable text. */
body.theme-dark .agricore-production-card,
body.theme-dark .agricore-production-kpi,
body.theme-dark .access-card { background: #27293d; border-color: rgba(255, 255, 255, .08); color: #e0e0e0; }
body.theme-dark .agricore-production-card-title,
body.theme-dark .agricore-production-kpi-value,
body.theme-dark .agricore-production-stage-name,
body.theme-dark .agricore-production-chart-total { color: #f2f4f8; }
body.theme-dark .agricore-production-kpi-label,
body.theme-dark .agricore-production-performance-legend,
body.theme-dark .agricore-production-records .table th { color: rgba(222, 226, 230, .7); }
body.theme-dark .agricore-production-stage,
body.theme-dark .agricore-production-empty,
body.theme-dark .agricore-production-event-date,
body.theme-dark .agricore-production-overview-tabs button:not(.active) { background: var(--bs-tertiary-bg); color: #dfe6e1; border-color: rgba(255, 255, 255, .08); }
body.theme-dark .agricore-production-list-row,
body.theme-dark .agricore-production-event,
body.theme-dark .agricore-production-records .table td { border-color: rgba(255, 255, 255, .08); }
body.theme-dark .agricore-production-records .table td a { color: #7fb8ff; }
body.theme-dark .agricore-production-records .table tbody tr:hover > * { background: var(--bs-tertiary-bg); color: #fff; }
body.theme-dark .pricing-card .badge.bg-light { background: var(--bs-tertiary-bg) !important; color: #c9d3cc !important; }
body.theme-dark .production-filter-box .input-group-text,
body.theme-dark .production-filter-box .form-control { border-color: rgba(255, 255, 255, .12); }

@media (min-width: 992px) {
  .container-scroller {
    height: 100vh;
    overflow: hidden;
  }

  /* No overflow-x/y here (deliberately NOT auto/hidden): the collapsed
     icon-only sidebar's hover flyout (category submenus, single-item
     labels) pops out via position:absolute with a left offset past the
     sidebar's own narrow width — any overflow clipping on this element,
     even overflow-y alone, forces the browser to clip both axes per the
     CSS overflow spec and hides the flyout entirely. The nav list grew
     enough to need a scrollbar (Account Settings dropdown pushed the
     item count past one viewport), so per the note below, only the
     inner .nav list scrolls — this element stays a flex column with no
     overflow of its own, keeping the flyout escape hatch intact.
  */
  #sidebar.sidebar {
    position: static;
    align-self: auto;
    height: 100vh;
    max-height: none;
    min-height: 0;
    display: flex;
    flex-direction: column;
  }

  #sidebar.sidebar .sidebar-brand,
  #sidebar.sidebar .sidebar-brand-divider {
    flex-shrink: 0;
  }

  /* Scrolls only when items overlap the viewport — flex:1 + min-height:0
     lets this list shrink below its content's natural height (the
     default min-height:auto on a flex child would otherwise force the
     parent to grow instead of this list scrolling), and overflow-y:auto
     shows a scrollbar only once scrollHeight actually exceeds this.
     Scrollbar itself is hidden (still scrolls via wheel/touch/keyboard) —
     a visible native scrollbar track sits right on top of the collapsed
     sidebar's hover-flyout labels (see the icon-only override below) and
     looks out of place against the themed sidebar either way. */
  #sidebar.sidebar .nav {
    margin-bottom: 0;
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    scrollbar-width: none;
  }
  #sidebar.sidebar .nav::-webkit-scrollbar {
    display: none;
  }

  /* Collapsed rail: the rail scrolls (so the bottom icons are reachable on a short window) and the
     hover flyouts are `position: fixed` — hoverable-collapse.js places them from the item's screen
     position, so the scroll container can't clip them and they never run off the bottom. */
  .sidebar-icon-only #sidebar.sidebar .nav {
    overflow-y: auto;
    overflow-x: hidden;
  }

  .page-body-wrapper {
    height: 100vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
  }

  /* Navbar (photo banner + search row) scrolls away with the rest of the
     content again, same as the original template — only the content PANE
     as a whole is what stays fixed-height; the banner itself isn't pinned. */
  .page-body-wrapper > .navbar {
    flex-shrink: 0;
  }

  .main-panel {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
  }

  /* Sticky footer: .content-wrapper already has flex-grow:1 from the base
     template (meant to push the footer down), but the footer is nested
     INSIDE .content-wrapper as its last child, not a sibling of it — so
     that flex-grow only stretches .content-wrapper's own box, and its
     children (cards, then <footer>) still just stack in normal block flow
     inside that stretched box, leaving empty space below a short page's
     footer instead of the footer sitting at the very bottom. Making
     .content-wrapper itself a flex column and giving the footer
     margin-top:auto pushes it (and only it) to the end of that stretched
     box on short pages, while a tall page's footer still flows after its
     content and the pane scrolls exactly as before.
  */
  .content-wrapper {
    display: flex;
    flex-direction: column;
  }
  .content-wrapper > .footer {
    margin-top: auto;
  }
}

/* Brand lives at the top of the sidebar now instead of the navbar — a thin
   divider marks it off from the nav items below, inset on both sides so it
   doesn't run edge-to-edge. */
.sidebar-brand-divider {
  margin: 0 20px 12px;
  border: 0;
  border-top: 1px solid rgba(255, 255, 255, 0.15);
}

/* Collapsed (icon-only) sidebar: show just the logo mark, drop the
   "AgriCore" wordmark and its spacing, same as every nav item's own label. */
.sidebar-icon-only .sidebar-brand > span:last-child {
  display: none;
}
.sidebar-icon-only .sidebar-brand > span:first-child {
  margin-right: 0 !important;
}

/* The Logout button is a plain <a class="btn ..."> directly inside its
   <li class="nav-item">, not the <a class="nav-link"><span
   class="menu-title">...</span></a> structure the vendor's collapsed-
   sidebar rules target — so nothing hides its "Logout" text label when the
   sidebar collapses to icon-only, and the label visibly spills out past
   the narrow 70px rail. Collapsing the button's own font-size to 0 (then
   restoring just the icon's) hides the label the same way every other nav
   item's label disappears, without needing to touch the Logout markup on
   every page. */
.sidebar-icon-only .sidebar .nav > .nav-item > a.btn {
  font-size: 0;
  padding-left: 0;
  padding-right: 0;
}
.sidebar-icon-only .sidebar .nav > .nav-item > a.btn i {
  font-size: 1.1rem;
}

/* ------------------------------------------------------------------ */
/* Floating AI chat widget — replaces the old floating theme-toggle FAB */
/* ------------------------------------------------------------------ */
#ai-chat-trigger {
  position: fixed;
  bottom: 40px;
  right: 10px;
  height: 50px;
  width: 50px;
  background: #1f6428;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 100%;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
  cursor: pointer;
}
/* Shown only for tenants that have the AI module — tenant-features.js adds
   body.agricore-ai-on once it knows (and removes it again if the module is turned off). */
body:not(.agricore-ai-on) #ai-chat-trigger,
body:not(.agricore-ai-on) #ai-chat-panel {
  display: none !important;
}
/* Scan & import reads photos with the AI, so its entries show only for tenants that have the AI module. */
body:not(.agricore-ai-on) .js-scan-entry {
  display: none !important;
}
#ai-chat-trigger i {
  color: #fff;
  font-size: 1.4rem;
}

#ai-chat-panel {
  position: fixed;
  bottom: 100px;
  right: 30px;
  width: 360px;
  max-width: calc(100vw - 40px);
  height: 480px;
  max-height: calc(100vh - 140px);
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
  z-index: 1000;
  display: none;
  flex-direction: column;
  overflow: hidden;
}
#ai-chat-panel.open {
  display: flex;
}
.ai-chat-header {
  background: #1f6428;
  color: #fff;
  padding: 0.85rem 1rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: 600;
  flex-shrink: 0;
}
.ai-chat-header .ai-chat-close {
  cursor: pointer;
  opacity: 0.85;
}
.ai-chat-header .ai-chat-close:hover {
  opacity: 1;
}
.ai-chat-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 1rem;
}
.ai-chat-greeting {
  text-align: center;
  color: #6c757d;
  padding-top: 1.5rem;
}
.ai-chat-greeting i {
  font-size: 2.2rem;
  color: #1f6428;
}
.ai-chat-greeting h5 {
  margin: 0.5rem 0 0.15rem;
  color: #212529;
}
.ai-chat-hint {
  font-size: 0.75rem;
  margin-top: 1rem;
  opacity: 0.8;
}
.ai-chat-msg {
  max-width: 85%;
  padding: 0.5rem 0.75rem;
  border-radius: 10px;
  margin-bottom: 0.6rem;
  font-size: 0.85rem;
  word-break: break-word;
}
/* Assistant replies are rendered as real <p>/<ul>/<strong> (see
   renderMarkdown in ai-chat-widget.js) rather than pre-wrapped plain text —
   trim the default block-element spacing so it still reads as one bubble. */
.ai-chat-msg p {
  margin: 0 0 0.5rem;
}
.ai-chat-msg p:last-child {
  margin-bottom: 0;
}
.ai-chat-msg ul {
  margin: 0 0 0.5rem;
  padding-left: 1.1rem;
}
.ai-chat-msg ul:last-child {
  margin-bottom: 0;
}
.ai-chat-msg table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 0.5rem;
  font-size: 0.78rem;
}
.ai-chat-msg th, .ai-chat-msg td {
  border: 1px solid rgba(0, 0, 0, 0.12);
  padding: 0.25rem 0.4rem;
  text-align: left;
}
.ai-chat-msg th {
  background: rgba(0, 0, 0, 0.05);
}
.ai-chat-confirm {
  margin-top: 0.5rem;
  padding-top: 0.5rem;
  border-top: 1px solid rgba(0, 0, 0, 0.1);
}
.ai-chat-confirm-text {
  font-weight: 600;
  margin: 0 0 0.5rem;
}
.ai-chat-msg.user {
  white-space: pre-wrap;
}
.ai-chat-msg.user {
  background: #1f6428;
  color: #fff;
  margin-left: auto;
  border-bottom-right-radius: 2px;
}
.ai-chat-msg.assistant {
  background: #f1f3f5;
  color: #212529;
  margin-right: auto;
  border-bottom-left-radius: 2px;
}
.ai-chat-msg.pending {
  opacity: 0.6;
  font-style: italic;
}
.ai-chat-msg img {
  max-width: 100%;
  border-radius: 6px;
  margin-bottom: 0.35rem;
  display: block;
}
.ai-chat-footer {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.6rem;
  border-top: 1px solid #eceff1;
  flex-shrink: 0;
}
.ai-chat-footer input[type="text"] {
  flex: 1;
  border: 1px solid #dee2e6;
  border-radius: 20px;
  padding: 0.45rem 0.9rem;
  font-size: 0.85rem;
  outline: none;
}
.ai-chat-attach, .ai-chat-send {
  border: none;
  background: none;
  color: #1f6428;
  font-size: 1.2rem;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.ai-chat-attach:hover, .ai-chat-send:hover {
  background: rgba(31, 100, 40, 0.1);
}

/* Shared "hero banner" header — photo background + eyebrow pill + title +
   primary CTA — and the small stat tile row beneath it. Used by Livestock,
   Grazing, Herds & Groups (any list page that wants a summary strip of
   real counts above its table/cards). */
.agricore-hero-card { overflow: hidden; border: none; }
.agricore-hero {
  position: relative; background-size: cover; background-position: center;
  border-radius: inherit; padding: 2rem 2rem 4.25rem;
}
.agricore-hero-eyebrow {
  display: inline-flex; align-items: center; gap: .35rem; margin-bottom: .75rem;
  background: rgba(255,255,255,.18); color: #fff; font-weight: 600;
  padding: .3rem .75rem; border-radius: 999px;
}
.agricore-hero-cta { position: absolute; top: 2rem; right: 2rem; }
@media (max-width: 767px) { .agricore-hero-cta { position: static; margin-top: 1rem; } }

.agricore-stat-tile {
  display: flex; align-items: center; gap: .85rem; background: #fff;
  border: 1px solid #d8e0ec; border-radius: 12px; padding: 1rem 1.1rem; height: 100%;
}
.agricore-stat-tile .agricore-stat-icon {
  width: 44px; height: 44px; border-radius: 10px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; font-size: 1.3rem; color: #fff;
}
.agricore-stat-tile > div:not(.agricore-stat-icon) { min-width: 0; flex: 1 1 auto; }
.agricore-stat-tile .agricore-stat-value { font-size: 1.35rem; font-weight: 700; line-height: 1.2; white-space: nowrap; }
.agricore-stat-tile .agricore-stat-label { font-size: .8rem; color: #8f9cb3; }
/* Same dark-mode gap as the .card fix above: this custom component isn't a
   Bootstrap .card, so it never picked up --bs-card-bg — stayed white-on-dark
   on every page that uses it (Grazing, My Crops, Grow Locations, Yield
   Comparison, Crop Plan, Livestock, Planner). Values match the vendor dark
   theme's own .card look (style.css --bs-card-bg / --bs-card-border-color). */
body.theme-dark .agricore-stat-tile {
  background: #26293b;
  border-color: #313452;
}

/* A `.card` sitting directly in .content-wrapper (e.g. a page's header/hero
   card) has no margin-bottom of its own — only the grid-margin utility on a
   .row's individual columns provides that — so a bare header card butts
   flush against whatever follows it (confirmed 0px gap above the Grazing/
   Planner stat-tile rows). Scoped to direct children only, so cards nested
   inside a col/row (which already get their spacing from grid-margin) are
   unaffected. */
.content-wrapper > .card {
  margin-bottom: 1.875rem;
}
.content-wrapper > .card:last-child {
  margin-bottom: 0;
}

.agricore-row-avatar {
  width: 34px; height: 34px; border-radius: 50%; object-fit: cover;
  display: inline-block; vertical-align: middle; margin-right: .5rem; flex-shrink: 0;
}
.agricore-row-avatar-icon {
  width: 34px; height: 34px; border-radius: 50%; display: inline-flex;
  align-items: center; justify-content: center; color: #fff; margin-right: .5rem;
  vertical-align: middle; flex-shrink: 0; font-size: 1rem;
}

/* Shared pill filter chip — click to toggle a category filter, active
   state fills with the chip's own accent color. Used by Herds & Groups'
   species filter and anywhere else with the same "click a colored pill to
   filter a list" pattern. */
.agricore-filter-chip {
  display: inline-flex; align-items: center; gap: 0.35rem;
  border: 1.5px solid var(--chip-color, #adb5bd);
  background: transparent; color: var(--bs-body-color);
  border-radius: 999px; padding: 0.3rem 0.85rem; font-size: 0.82rem;
  line-height: 1.3; cursor: pointer; transition: background-color 0.15s ease, color 0.15s ease, opacity 0.15s ease;
}
.agricore-filter-chip::before {
  content: ''; display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  background: var(--chip-color, #adb5bd); flex-shrink: 0;
}
.agricore-filter-chip.active { background: var(--chip-color, #adb5bd); color: #fff; }
.agricore-filter-chip.active::before { background: #fff; }
.agricore-filter-chip:not(.active) { opacity: 0.6; }
.agricore-filter-chip:hover { opacity: 1; }

/* Entity grid cards — Livestock/Crops "grid view" tiles. Boxed like the
   theme's portfolio sample (rounded photo tile, hover lift) but the details
   are a permanently-visible section below the image instead of a
   hover-only caption — a farmer needs to see status/location at a glance,
   not have to hover over every tile. */
.entity-card {
  background: #fff;
  border: 1px solid #d8e0ec;
  border-radius: 0.75rem;
  overflow: hidden;
  height: 100%;
  display: flex;
  flex-direction: column;
  transition: box-shadow 0.2s ease, transform 0.2s ease;
}
.entity-card:hover {
  box-shadow: 0 0.75rem 1.75rem rgba(0, 0, 0, 0.1);
  transform: translateY(-3px);
}
.entity-card-thumb {
  width: 100%;
  aspect-ratio: 4 / 3; /* same shape as the stored thumbnails, so every card photo is cropped alike */
  flex-shrink: 0;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 2.75rem;
}
.entity-card-body {
  padding: 1.1rem 1.25rem 0.75rem;
  flex: 1;
}
.entity-card-title {
  font-size: 1.05rem;
  font-weight: 600;
  color: #001737;
  line-height: 1.3;
}
.entity-card-sub {
  font-size: 0.78rem;
  color: #6c757d;
  margin: 0.15rem 0 0.5rem;
}
.entity-card-meta {
  font-size: 0.78rem;
  color: #6c757d;
  margin-top: 0.5rem;
}
.entity-card-meta > div {
  margin-bottom: 0.2rem;
  display: flex;
  align-items: center;
  gap: 0.35rem;
}
.entity-card-meta i {
  font-size: 0.9rem;
}
.entity-card-actions {
  display: flex;
  gap: 0.5rem;
  padding: 0.75rem 1.25rem;
  border-top: 1px solid #eceff1;
}

/* Sidebar item counters (Planner, AI Command Center) — a fixed-size circle
   matching the navbar bell's own count badge, instead of Bootstrap's
   .rounded-pill (which stretches into an oval around single-digit text). */
.sidebar-badge-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 4px;
  border-radius: 50%;
  font-size: 0.7rem;
  line-height: 1;
  vertical-align: middle;
}

/* Sitewide rounded-corner design language, matching the weather forecast
   tiles' rounded-4 (1rem) treatment. Bootstrap 5.3's own components read
   their border-radius from these CSS custom properties (--bs-border-radius
   and friends), so overriding them here reskins cards, buttons, modals,
   dropdowns, alerts, badges, and form controls all at once, sitewide,
   without hunting down every component's own selector. The explicit
   .card/.modal-content/.dropdown-menu/etc rules below are a belt-and-braces
   fallback for any compiled vendor CSS that hard-coded a radius instead of
   reading the variable. */
:root {
  --bs-border-radius: 1rem;
  --bs-border-radius-sm: 0.75rem;
  --bs-border-radius-lg: 1.25rem;
  --bs-border-radius-xl: 1.5rem;
  --bs-border-radius-xxl: 2rem;
  --bs-border-radius-pill: 50rem;
}
.card,
.modal-content,
.dropdown-menu,
.dropdown .dropdown-menu,
.toast,
.alert,
.form-control,
.form-select,
.input-group-text,
.table-responsive,
.settings-panel {
  border-radius: 1rem;
}
.btn {
  border-radius: 0.75rem;
}
/* Every button converges on this one rounded-rectangle shape — overriding
   both the theme's own .btn-rounded utility (previously a full 50px pill,
   used as the primary CTA style on ~20 pages including Crops and
   Livestock) and Bootstrap's .rounded-pill utility when applied to a
   button (also a full pill, and shipped with !important, hence the
   !important here too — matching specificity/weight is the only way to
   reliably beat it regardless of where either class shows up). */
.btn.btn-rounded,
.btn.rounded-pill {
  border-radius: 0.75rem !important;
}

/* DataTables ships its own `.btn` padding override (0.1rem 1rem) for buttons
   inside a `.dataTable`, squishing icon-only row-action buttons (Livestock's
   View/Delete, Crops' Plantings/Log Harvest) down to a barely-visible
   sliver — Inventory's action buttons look right by comparison only because
   its table is plain HTML, not a DataTable, so it never inherits this rule.
   Restoring the same padding vars a plain `.btn.btn-sm` already resolves to
   makes every table's action buttons match. */
.dataTables_wrapper .dataTable .btn {
  padding: var(--bs-btn-padding-y) var(--bs-btn-padding-x);
}

/* Shared "Board / List / Calendar"-style view-switch pills — originally a
   Crop Plan-only local style (`.cp-view-tabs`), promoted here so every page
   with the same tri-tab view switcher (Planner's Board/List/Calendar,
   Crop Plan's own Crop Plan/List/Calendar) renders identically instead of
   drifting apart as separate page-local copies. */
.agricore-view-tabs .nav-link {
  border-radius: 999px;
  padding: 0.4rem 0.9rem;
  font-size: 0.85rem;
  /* var(--bs-secondary-color) instead of a flat hex so this reads correctly
     in dark mode too — body.theme-dark above already repoints this same
     variable to a light gray for exactly this kind of muted-text case. */
  color: var(--bs-secondary-color, #495057);
}
.agricore-view-tabs .nav-link.active {
  background: #1f6428;
  color: #fff;
}

/* ============================================================
   Top header / hero navbar — modern SaaS restyle.
   Only touches layout/skin of _navbar-farm-owner.html's own elements.
   Does NOT otherwise touch `.navbar`'s background-image (the mountain
   photo, set in vertical-layout-light/style.css) — see that file's own
   comment for why the photo lives there — except for the time-of-day
   override directly below, which is the one deliberate exception.
   ============================================================ */

/* Time-of-day hero background (desktop) — mirrors the mobile
   .agricore-mobile-sticky-bar / .agricore-mobile-hero-content overrides
   elsewhere in this file; api-client.js sets one of these three classes on
   <body> based on the current hour. All three point at the same
   placeholder photo for now — swap each url() for its own morning/
   afternoon/evening image once supplied. `.navbar` alone is vendor CSS
   (lower specificity, and this file always loads after it anyway), so no
   !important is needed to win here. */
/* One photo per time slot (morning, day, afternoon, evening); api-client.js puts the matching agricore-time-* class on
   <body>. Each slot has a wide banner for computers (-.jpg) and a compact picture for phones and tablets (-sm.jpg),
   both cropped around what shows the time of day (made by scripts/make-hero-images.py). --agricore-hero-pos* choose which
   part stays visible when the banner is shorter than the picture; --agricore-hero-shade darkens the left side a little so the
   white greeting stays readable. */
body.agricore-time-morning {
  --agricore-hero-photo: url(../images/hero/morning.jpg); --agricore-hero-photo-sm: url(../images/hero/morning-sm.jpg);
  --agricore-hero-pos: center 88%; --agricore-hero-pos-sm: center 45%; --agricore-hero-shade: 0.5; --agricore-hero-shade-sm: 0.45;
}
body.agricore-time-day {
  --agricore-hero-photo: url(../images/hero/day.jpg); --agricore-hero-photo-sm: url(../images/hero/day-sm.jpg);
  --agricore-hero-pos: center 50%; --agricore-hero-pos-sm: center 50%; --agricore-hero-shade: 0.3; --agricore-hero-shade-sm: 0.2;
}
body.agricore-time-afternoon {
  --agricore-hero-photo: url(../images/hero/afternoon.jpg); --agricore-hero-photo-sm: url(../images/hero/afternoon-sm.jpg);
  --agricore-hero-pos: center 30%; --agricore-hero-pos-sm: center 40%; --agricore-hero-shade: 0.5; --agricore-hero-shade-sm: 0.45;
}
body.agricore-time-evening {
  --agricore-hero-photo: url(../images/hero/evening.jpg); --agricore-hero-photo-sm: url(../images/hero/evening-sm.jpg);
  --agricore-hero-pos: center 45%; --agricore-hero-pos-sm: center 50%; --agricore-hero-shade: 0.28; --agricore-hero-shade-sm: 0.2;
}
body[class*="agricore-time-"] .navbar.agricore-navbar {
  background-image:
    linear-gradient(90deg, rgba(6, 24, 16, var(--agricore-hero-shade)) 0%, rgba(6, 24, 16, calc(var(--agricore-hero-shade) * 0.5)) 40%, rgba(6, 24, 16, 0) 72%),
    var(--agricore-hero-photo);
  background-size: 100% 100%, cover;
  background-position: 0 0, var(--agricore-hero-pos);
  background-repeat: no-repeat;
}

/* Top row (desktop, ≥992px): hamburger + welcome message (left), weather +
   bell (right). Hidden entirely on mobile — see the mobile section below,
   its content (welcome/date, weather, search, farm selector) is relocated
   by mobile-nav.js into dedicated mobile-only containers instead. */
.agricore-navbar-toprow {
  padding-bottom: 0.85rem;
  flex-wrap: wrap;
  row-gap: 0.5rem;
  column-gap: 1rem;
}
.agricore-navbar-toprow #navbar-welcome-name {
  color: #fff;
  font-size: 1.5rem;
  font-weight: 600;
  margin-left: 0.85rem;
}
/* Grouped with .agricore-welcome-date so the "Good Morning," line above the
   name always matches the date line below it exactly — one rule, not two
   copies that could drift apart. */
.agricore-welcome-greeting,
.agricore-welcome-date {
  color: rgba(255, 255, 255, 0.75);
  font-size: 0.85rem;
  margin-left: 0.85rem;
}
/* The weather chip + bell live in their own <ul>, which needs its own right
   margin — otherwise, at widths where the second row wraps under it, this
   <ul> sits flush against the row's own right edge with no breathing room. */
.agricore-navbar-toprow > .navbar-nav-right { margin-right: 0; gap: 0.5rem; }

/* Weather pill: dark glass chip, now with a location line under the temp
   and a decorative chevron (the widget itself stays a tooltip, not a real
   dropdown — see weather-widget.js, functionality is unchanged). */
.weather-chip {
  background: rgba(20, 20, 20, 0.4);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 50px;
  padding: 0.5rem 1rem;
  cursor: default;
  gap: 0.6rem;
}
.weather-chip-text { line-height: 1.15; }
.weather-chip-text #weather-temp { font-size: 0.95rem; }
.weather-chip-location-row { display: flex; align-items: center; gap: 0.2rem; }
.weather-chip-location {
  color: rgba(255, 255, 255, 0.7);
  font-size: 0.72rem;
}
.weather-chip-chevron {
  color: rgba(255, 255, 255, 0.6);
  font-size: 0.95rem;
}

/* Circular action buttons — notification bell, quick-add, language, clock.
   All four share this base (white glass circle + soft shadow); the
   quick-add button additionally gets the solid green primary treatment. */
.agricore-icon-btn {
  position: relative;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border: 1px solid rgba(255, 255, 255, 0.5);
  box-shadow: 0 2px 10px rgba(15, 23, 42, 0.12);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
}
.agricore-icon-btn i {
  font-size: 1.3rem !important;
  color: #2b3a4a;
  margin: 0 !important;
}
.agricore-icon-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 14px rgba(15, 23, 42, 0.18);
  background: #fff;
}
.agricore-icon-btn.agricore-icon-btn-primary {
  background: #1f6428;
  border-color: rgba(255, 255, 255, 0.25);
  box-shadow: 0 3px 12px rgba(31, 100, 40, 0.4);
}
.agricore-icon-btn.agricore-icon-btn-primary i { color: #fff; }
.agricore-icon-btn.agricore-icon-btn-primary:hover {
  background: #276b2a;
  box-shadow: 0 5px 16px rgba(31, 100, 40, 0.5);
}
/* Notification bell: plain white glyph directly over the hero photo (no
   circle backdrop, unlike the other three action buttons) with the count
   badge sitting on its top-right corner. */
.agricore-bell-btn {
  position: relative;
  width: 3rem;
  height: 3rem;
}
.agricore-bell-btn i {
  font-size: 1.9rem !important;
  color: #fff;
  margin: 0 !important;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}
/* The vendor's own badge styling (size/shape/position) AND its own caret-
   hiding rule for this exact button both require the full ancestor chain
   `.navbar .navbar-menu-wrapper .navbar-nav .nav-item.dropdown
   .count-indicator` — true in the desktop navbar, but no longer true once
   mobile-nav.js moves this same <li> into .agricore-mobile-sticky-actions,
   so on mobile the badge fell back to being a plain unstyled red rectangle
   AND Bootstrap's default .dropdown-toggle::after caret (normally hidden
   by that same vendor rule) reappeared next to it. Restoring both here,
   independent of ancestor chain, fixes it regardless of where this button
   currently lives. */
#notificationDropdown.dropdown-toggle::after {
  display: none !important;
}
.agricore-bell-btn .count {
  position: absolute;
  left: auto !important;
  right: 2px;
  top: 2px;
  width: 21px;
  height: 21px;
  border-radius: 10px;
  font-size: 10px;
  line-height: 21px;
  text-align: center;
  padding: 0;
}

/* Second row (desktop, ≥992px): search pill + farm/profile pills + action
   buttons, floating with gaps over the transparent hero image instead of
   one solid white bar spanning edge-to-edge. Always visible inline here. */
.agricore-navbar-secondrow {
  background: transparent !important;
  height: auto !important;
  gap: 0.85rem;
  flex-wrap: wrap;
  row-gap: 0.75rem;
  padding-bottom: 0.5rem;
}
.agricore-navbar-actions { align-items: center; flex-wrap: wrap; gap: 0.6rem; }
.agricore-navbar-actions .nav-item { margin-left: 0 !important; margin-right: 0 !important; }
/* Desktop: search/farm/profile/quick-add/clock row is allowed to collapse
   away on scroll, same as mobile's own header collapse — template.js adds
   `navbar-mini` after ~197px of scroll (a vendor "compact navbar" effect),
   which carries its own `.navbar-mini .navbar-search-wrapper { display:
   none !important }` rule; left alone (no override) rather than forced
   permanently visible. */

/* Mobile (<992px): the desktop toprow/secondrow are hidden entirely (the
   vendor's own `.navbar-mini .navbar-search-wrapper { display: none
   !important }` already hides the secondrow; the toprow gets the same via
   `d-none d-lg-flex` directly in the markup — neither needs an override
   here, unlike the various `.nav-item`-level ones below, which DO need one
   — see the .agricore-hidden-action comment earlier in this file for why).
   Their content is relocated by mobile-nav.js into two purpose-built mobile
   containers instead:
     .agricore-mobile-sticky-bar   — logo+wordmark, bell, quick-add, profile
                                      avatar. `position: sticky` so it's the
                                      persistent "collapsed" bar once the
                                      rest scrolls past it.
     .agricore-mobile-hero-content — welcome+date, weather, search, farm
                                      selector. Normal document flow, so it
                                      scrolls away under the sticky bar.
   `.navbar` itself must NOT stay `position: fixed` here (vendor's
   `navbar-mini`/`fixed-top` classes, added unconditionally below 991px) —
   a fixed navbar has no normal-flow height for the sticky bar to scroll
   past, which is the whole mechanism this depends on. */
@media (max-width: 991.98px) {
  /* Vendor's `.main-panel { display: flex; flex-direction: column;
     height: 100%; }` is unconditional (all widths) — on desktop it's load-
     bearing (paired with `.page-body-wrapper { height: 100vh; overflow:
     hidden }` and `.main-panel { overflow-y: auto }` above, so a short
     page's content-wrapper still visually fills the fixed-height pane).
     On mobile there's no such fixed-height pane — the page just scrolls
     normally — but `.main-panel` still had `height: 100%` against a
     `.page-body-wrapper` whose own height is driven by content (via its
     `min-height: 100vh`), and `.content-wrapper`'s `flex-grow: 1` then
     stretched it to fill 100% of THAT, pushing `.footer` (a separate flex
     sibling of content-wrapper, not its child, despite an old comment
     here assuming otherwise) hundreds of pixels below the real content on
     any page shorter than one viewport — confirmed: a 480px dead gap
     between the last card and the footer on the Dashboard, collapsing to
     the intended ~84px (the fixed tab bar's own clearance padding, see
     below) once `.main-panel` goes back to plain block flow here. */
  .main-panel {
    display: block;
    height: auto;
  }

  /* `position: sticky` resolves against the nearest ancestor with a non-
     `visible` overflow — not necessarily the element that actually
     scrolls. The vendor's `.container-scroller { overflow: hidden }`
     (unconditional, unrelated to anything added here) sits between the
     sticky bar and the real scrolling element (the document, per the
     earlier mobile-scroll fix above), so the sticky bar was resolving
     against a container that itself never scrolls — confirmed: it moved
     off-screen with the rest of the content instead of sticking. Scoped to
     farm-owner pages only (`body:has(.agricore-mobile-sticky-bar)`, a
     marker unique to this partial) since super-admin/field-worker pages
     still use the original off-canvas sidebar slide-in, which this
     overflow:hidden may be clipping to its container. */
  body:has(.agricore-mobile-sticky-bar) .container-scroller {
    overflow: visible;
  }
  .navbar.navbar-mini.fixed-top.agricore-navbar {
    position: static !important;
    left: auto !important;
    width: auto !important;
    height: auto !important;
  }
  /* Vendor compensates for its own fixed navbar with a 65px padding-top
     elsewhere (`.main-panel.navbar-fixed-top`) — with the navbar back in
     normal flow that compensation would just leave a 65px gap of empty
     background above the content. */
  body.navbar-fixed-top .main-panel {
    padding-top: 0 !important;
  }

  /* `position: sticky` only stays stuck while its OWN containing block
     (here, the small ~340px-tall <nav>) is still scrolling through the
     viewport — once the user scrolls past the nav's own height, the
     sticky child necessarily scrolls away with it (confirmed: the whole
     bar vanished a page-height down on /tasks). `position: fixed` has
     no such limit — it's what an "always pinned" bar actually needs, since
     unlike a real sticky-header use case (stick once you reach it, scrolled
     FROM further down), this bar must be pinned from the very top. */
  .agricore-mobile-sticky-bar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 1025;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.85rem 1.25rem;
    /* Transparent by default — rather than painting its own copy of the
       hero photo (the previous approach, which needed `background-
       attachment: fixed` to stay in lockstep with .agricore-mobile-hero-
       content's copy underneath, and both janked on scroll AND still
       showed a visible seam between the two independently-scrolling
       copies once `fixed` was dropped to fix that jank). This element is
       `position: fixed` and sits on TOP of .agricore-mobile-hero-content
       (itself in normal flow, starting at the same y:0), so with no
       background of its own the single photo underneath simply shows
       through — one real image, not two synced ones. Scrolling still
       swaps it to a solid color below, same as before. */
    background: transparent;
    transition: background-color 0.25s ease, box-shadow 0.25s ease;
  }
  /* Past a small scroll threshold (mobile-nav.js toggles this), swap the
     hero photo for a solid color matching the bottom tab bar — same
     #0a3d2a — and invert the quick-add button (white circle, green icon)
     instead of its usual green-circle/white-icon look. Both effects are
     scoped to this scrolled state only; the un-scrolled bar keeps the
     photo background and the normal quick-add colors. */
  .agricore-mobile-sticky-bar.agricore-scrolled {
    background: #0a3d2a;
    box-shadow: 0 4px 14px rgba(6, 24, 16, 0.25);
  }
  .agricore-mobile-sticky-bar.agricore-scrolled .agricore-icon-btn.agricore-icon-btn-primary {
    background: #fff;
    border-color: rgba(31, 100, 40, 0.25);
  }
  .agricore-mobile-sticky-bar.agricore-scrolled .agricore-icon-btn.agricore-icon-btn-primary i {
    color: #1f6428;
  }
  .agricore-mobile-brand { display: flex; align-items: center; gap: 0.6rem; }
  .agricore-mobile-brand-mark {
    width: 32px; height: 32px; border-radius: 8px; flex-shrink: 0;
    background: #1f6428; color: #fff; font-size: 1.1rem;
    display: flex; align-items: center; justify-content: center;
  }
  .agricore-mobile-brand-text { color: #fff; font-weight: 700; font-size: 1.05rem; }
  .agricore-mobile-sticky-actions { display: flex; align-items: center; gap: 0.5rem; }
  /* The bell/quick-add/profile <li>s are moved here from the (proper <ul>)
     desktop navbar by mobile-nav.js — sitting in a plain <div> now, they
     lose the reset a <ul>/<li> normally gets from being inside `.nav`, so
     the browser's own default bullet marker (and its list-item indent
     spacing) showed up between each icon. */
  .agricore-mobile-sticky-actions > li {
    list-style: none;
    margin: 0;
  }
  /* The notification/farm/profile dropdown menus use the OLD Bootstrap 4
     class `dropdown-menu-right`, not Bootstrap 5's real `dropdown-menu-end`
     — meaning it does nothing, and every one of these menus actually
     LEFT-aligns with its toggle. On desktop that's rarely a problem (lots
     of room to spare to the right); on a narrow phone, with the toggle
     sitting right at the screen edge, the menu opens off-screen to the
     right and gets clipped — confirmed on the profile menu. Force real
     right-alignment for every navbar dropdown on mobile, and cap the width
     so it can never exceed the viewport regardless of alignment. Also
     bumps each item's touch target up from the vendor's compact desktop
     sizing (0.25rem 1.5rem) to something comfortably tappable. */
  /* Right-aligning relative to each dropdown's OWN toggle (the previous
     approach here) only works for toggles already near the screen's right
     edge (profile, farm selector) — the notification bell sits further
     left in the sticky bar, so "align my right edge with my own toggle"
     pushed IT off the LEFT edge instead once the menu's width exceeded the
     space to the bell's left. Anchoring every navbar dropdown to the
     VIEWPORT itself (not its toggle) fixes this everywhere, and reads as a
     baseline "notifications/menu panel" pattern much like the More sheet's
     own genuinely-mobile-not-desktop-shrunk-down behavior. */
  .navbar-dropdown {
    position: fixed !important;
    top: 70px !important;
    left: 0.75rem !important;
    right: 0.75rem !important;
    width: auto !important;
    max-width: none;
    max-height: calc(100vh - 90px);
    overflow-y: auto;
  }
  .navbar-dropdown .dropdown-item {
    padding: 0.75rem 1.25rem;
    font-size: 0.95rem;
  }

  .agricore-mobile-hero-content {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    /* Top padding pushes the actual content (greeting/weather/search/farm)
       down clear of the fixed sticky bar above — the bar's own ~67px
       height plus its 0.85rem vertical padding, rounded up with a little
       extra room. width:100% avoids the narrow, off-center box confirmed
       earlier (a `<nav>` with `flex-wrap: wrap` doesn't stretch a plain
       block child to full width on its own).

       This is the ONE element that actually paints the hero photo now —
       the sticky bar above is transparent and just overlays it (see that
       rule), rather than each painting its own synced copy of the same
       image. One real photo instead of two means no seam to keep aligned
       and no need for `background-attachment: fixed` (which was also
       janking mobile scroll performance — a plain `scroll` attachment on
       a normal, non-fixed-position element like this one has no such
       cost). */
    width: 100%;
    padding: 5.5rem 1.25rem 2.75rem;
    background: url(../images/other/navbar-cover.jpg) top center / cover;
    position: relative;
  }
  /* Curved bottom edge instead of the hero photo's previous hard,
     straight cutoff — a real drawn wave (single smooth dip via one cubic
     bezier per side, see the <svg> markup in _navbar-farm-owner.html)
     rather than an oversized CSS ellipse, which rendered with a visibly
     messy/jagged edge in testing. `preserveAspectRatio="none"` lets the
     viewBox stretch to the element's own box exactly, so the curve stays
     the same shape at any phone width. Fill matches the page's real
     content background (--agricore-content-bg, theme-aware — see
     body.theme-dark above) so it reads as the curve simply revealing the
     page underneath, not a shape drawn on top of the photo. */
  .agricore-mobile-hero-curve {
    position: absolute;
    left: 0;
    right: 0;
    bottom: -1px;
    width: 100%;
    height: 40px;
    display: block;
    pointer-events: none;
  }
  .agricore-mobile-hero-curve path {
    fill: var(--agricore-content-bg);
  }
  /* Kept identical to the .agricore-mobile-sticky-bar copy above — see that
     rule's comment. */
  body[class*="agricore-time-"] .agricore-mobile-hero-content {
    background-image:
      linear-gradient(180deg, rgba(6, 24, 16, var(--agricore-hero-shade-sm)) 0%, rgba(6, 24, 16, calc(var(--agricore-hero-shade-sm) * 0.6)) 45%, rgba(6, 24, 16, 0) 80%),
      var(--agricore-hero-photo-sm);
    background-size: 100% 100%, cover;
    background-position: 0 0, var(--agricore-hero-pos-sm);
    background-repeat: no-repeat;
  }
  /* Vertical accent bar beside the greeting text — same two-tone green
     gradient as the sidebar's active-item highlight (agricore-layout.css
     line ~30), so it reads as the app's own brand accent rather than an
     arbitrary color. A pseudo-element rather than a border so it can be
     rounded and inset slightly from the text's own line-height. */
  .agricore-mobile-greeting {
    position: relative;
    padding-left: 0.9rem;
  }
  .agricore-mobile-greeting::before {
    content: '';
    position: absolute;
    left: 0;
    top: 2px;
    bottom: 2px;
    width: 4px;
    border-radius: 4px;
    background: linear-gradient(180deg, #2a7a31, #14501c);
  }
  .agricore-mobile-greeting #navbar-welcome-name {
    color: #fff; font-size: 1.3rem; font-weight: 700; margin: 0;
  }
  .agricore-mobile-greeting .agricore-welcome-greeting,
  .agricore-mobile-greeting .agricore-welcome-date {
    color: rgba(255, 255, 255, 0.8); font-size: 0.85rem; margin: 0;
  }
  /* Content-sized, not full-width — width:auto alone wasn't enough (the
     chip still stretched to fill the row), so the row itself is made a
     flex container that doesn't stretch its child, with a hard cap as a
     second safety net regardless of content length. */
  .agricore-mobile-weather-row {
    display: flex;
    justify-content: flex-start;
  }
  .agricore-mobile-weather-row .weather-chip {
    display: inline-flex;
    width: auto;
    max-width: 55%;
    flex: 0 0 auto;
  }
  .agricore-mobile-search-row .agricore-search-item,
  .agricore-mobile-farm-row .nav-item {
    list-style: none;
  }
  /* Farm selector + the two icon buttons beside it (Market, Tasks — see
     _navbar-farm-owner.html) as one horizontal row: the pill takes the
     remaining space (capped so it doesn't crowd the buttons off a narrow
     phone), the buttons stay fixed-size on the right. */
  .agricore-mobile-farm-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
  }
  .agricore-mobile-farm-row .nav-item.dropdown {
    flex: 1 1 auto;
    min-width: 0;
  }
  .agricore-mobile-farm-row .agricore-nav-pill {
    width: 100%;
    max-width: none;
  }
  /* Market / Tasks buttons: same dark-glass treatment as the farm pill
     beside them, not .agricore-icon-btn's own default light-glass look
     (that default is kept as-is for the sticky bar's bell/quick-add,
     which sit on a much busier part of the photo and read better light). */
  .agricore-mobile-farm-row .agricore-icon-btn {
    flex: 0 0 auto;
    background: rgba(20, 20, 20, 0.4);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    border: 1px solid rgba(255, 255, 255, 0.12);
    box-shadow: none;
  }
  .agricore-mobile-farm-row .agricore-icon-btn i {
    color: #fff;
  }
  .agricore-mobile-farm-row .agricore-icon-btn:hover {
    background: rgba(20, 20, 20, 0.55);
    box-shadow: none;
  }
  /* Farm pill: dark glass, matching .weather-chip immediately above it in
     the same hero — was solid white (.agricore-nav-pill's shared base
     rule, still used as-is by the desktop navbar's second row), which
     read as a plain opaque button rather than part of the same glass
     family as the weather chip and icon buttons around it on mobile. */
  .agricore-mobile-farm-row .agricore-nav-pill {
    background: rgba(20, 20, 20, 0.4) !important;
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    border: 1px solid rgba(255, 255, 255, 0.12);
    box-shadow: none;
  }
  .agricore-mobile-farm-row .agricore-nav-pill-icon { color: #a5d6a7; }
  .agricore-mobile-farm-row .agricore-nav-pill .nav-profile-name {
    color: #fff;
    max-width: none;
    flex: 1 1 auto;
  }
  .agricore-mobile-farm-row .agricore-nav-pill-chevron { color: rgba(255, 255, 255, 0.7); }
  /* Search pill: light glass — was fully opaque white
     (.agricore-search-pill's shared base rule); a touch of transparency +
     blur puts it in the same glass family as the rest of the hero without
     losing the light, legible surface a search field needs. */
  .agricore-mobile-search-row .agricore-search-pill {
    background: rgba(255, 255, 255, 0.85) !important;
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.5);
  }

  /* Quick-add + profile avatar, relocated into the sticky bar by mobile-
     nav.js: strip the profile pill down to just the avatar circle
     ("nothing special", per spec) — no name label, no chevron, no white
     pill background — so it reads the same as the plain circular bell/
     quick-add buttons next to it. */
  .agricore-mobile-sticky-actions .agricore-nav-pill {
    background: transparent !important;
    box-shadow: none !important;
    padding: 0 !important;
    height: auto !important;
    width: auto !important;
  }
  .agricore-mobile-sticky-actions .agricore-nav-pill .nav-profile-name,
  .agricore-mobile-sticky-actions .agricore-nav-pill .agricore-nav-pill-icon,
  .agricore-mobile-sticky-actions .agricore-nav-pill .agricore-nav-pill-chevron {
    display: none;
  }
  .agricore-mobile-sticky-actions #navbar-profile-avatar { margin-right: 0 !important; }
  .agricore-mobile-sticky-actions .agricore-icon-btn,
  .agricore-mobile-sticky-actions .agricore-bell-btn {
    width: 2.5rem !important;
    height: 2.5rem !important;
  }
  .agricore-mobile-sticky-actions .agricore-bell-btn i,
  .agricore-mobile-sticky-actions .agricore-icon-btn i {
    font-size: 1.15rem !important;
  }
  .agricore-mobile-sticky-actions #navbar-profile-avatar img,
  .agricore-mobile-sticky-actions #navbar-profile-avatar > div {
    width: 2.5rem !important;
    height: 2.5rem !important;
    font-size: 1rem !important;
  }
}
/* Plain `.d-none` can't hide this <li> — the vendor stylesheet has its own
   `.navbar-nav.navbar-nav-right .nav-item { display: flex !important }`
   rule (bundled with the `.align-items-center` utility) whose longer
   selector chain outranks Bootstrap's own single-class `.d-none` even
   though both use !important. Match that same chain plus this dedicated
   class so specificity — not just !important — wins here. */
.navbar .navbar-menu-wrapper .navbar-nav.navbar-nav-right .nav-item.agricore-hidden-action {
  display: none !important;
}

.agricore-search-item { flex: 1 1 auto; max-width: 640px; }
/* !important throughout this rule: the vendor's own
   `.nav-item.nav-search .input-group` selector (6 chained classes) outranks
   a single `.agricore-search-pill` class on specificity alone, regardless of
   source order — it was winning on background/padding, leaving the pill
   nearly transparent (background alpha 0.13) with the hero photo showing
   straight through it instead of a solid, legible white pill. */
.agricore-search-pill {
  position: relative !important;
  background: rgba(255, 255, 255, 0.97) !important;
  border-radius: 32px !important;
  box-shadow: 0 4px 18px rgba(15, 23, 42, 0.1);
  height: 60px;
  align-items: center;
  padding: 0 1.25rem 0 3rem !important;
}
.agricore-search-icon {
  position: absolute;
  left: 1.25rem;
  top: 50%;
  transform: translateY(-50%);
  color: #9aa5b1;
  font-size: 1.25rem;
  pointer-events: none;
}
.agricore-search-pill .form-control {
  border: none !important;
  background: transparent !important;
  box-shadow: none !important;
  height: 100% !important;
  padding-left: 0 !important;
  padding-right: 0.5rem !important;
  font-size: 0.95rem;
  color: #2b3a4a !important;
}
.agricore-search-pill .form-control::placeholder { color: #9aa5b1; opacity: 1; }

/* Global placeholder color — the vendor theme's default is a very pale
   gray with weak contrast against white inputs (hard to read on forms
   like Login/Register). Applies wherever a plain .form-control is used;
   the search-pill rule above is a distinct, darker glass-specific case
   and stays as-is. */
.form-control::placeholder { color: #6c757d; opacity: 1; }

/* Farm selector + user profile pills. */
.agricore-nav-pill {
  background: rgba(255, 255, 255, 0.96) !important;
  border-radius: 32px;
  height: 56px;
  padding: 0 1.1rem !important;
  box-shadow: 0 4px 14px rgba(15, 23, 42, 0.1);
  color: #2b3a4a !important;
  white-space: nowrap;
  transition: box-shadow 0.15s ease, transform 0.15s ease;
}
.agricore-nav-pill:hover {
  box-shadow: 0 6px 18px rgba(15, 23, 42, 0.15);
  transform: translateY(-1px);
}
.agricore-nav-pill-icon { color: #1f6428; font-size: 1.15rem; margin-right: 0.5rem; flex-shrink: 0; }
.agricore-nav-pill-chevron { color: #9aa5b1; font-size: 1.05rem; margin-left: 0.4rem; flex-shrink: 0; }
/* Long farm/tenant names (e.g. "Molekwa CPA Magalakwena") get cut off with
   an ellipsis rather than stretching the pill wider and wider — min-width:0
   lets this flex item actually shrink below its own text width, which
   text-overflow:ellipsis needs to have any effect. The 180px cap is for
   contexts where the pill sizes to its content (desktop); the mobile farm
   row below overrides it since that pill already fills whatever space its
   own flex row leaves it. */
.agricore-nav-pill .nav-profile-name {
  color: #2b3a4a;
  font-weight: 600;
  font-size: 0.9rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
  max-width: 180px;
}
.agricore-nav-pill #navbar-profile-avatar { margin-right: 0.55rem !important; }
/* Bootstrap's own .dropdown-toggle::after caret would otherwise render a
   second, plain triangle right next to our own mdi chevron icon on these
   pills — drop the native one since we already show a chevron explicitly. */
.agricore-nav-pill.dropdown-toggle::after { display: none; }

@media (max-width: 1199px) {
  .agricore-search-item { max-width: 380px; }
}

/* ============================================================
   Sidebar restyle — 2026 look on top of the vendor's flat, no-radius,
   no-hover nav rows. Structure/hrefs/data-agricore-feature attributes are
   all untouched, this is pure visual overlay.
   ============================================================ */
.sidebar .nav .nav-item {
  padding: 0 0.75rem;
  margin-bottom: 2px;
}
.sidebar .nav .nav-item > .nav-link {
  border-radius: 10px;
  padding: 0.6rem 0.85rem;
  transition: background 0.15s ease, color 0.15s ease;
}
.sidebar .nav .nav-item:not(.active) > .nav-link:hover {
  background: rgba(255, 255, 255, 0.08);
}
.sidebar .nav .nav-item .nav-link i.menu-icon {
  font-size: 1.05rem;
  width: 22px;
  margin-right: 0.85rem;
  text-align: center;
}
.sidebar .nav .nav-item .nav-link .menu-title {
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.01em;
}
.sidebar .nav .sidebar-category p {
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.55;
}

/* Submenu-parent arrow (Livestock/Plantings/.../Reports/Account Settings)
   rendered as a garbled/notdef glyph — the vendor CSS hardcodes old-style
   4-hex MDI codepoints (`\f142` collapsed, `\f140` expanded/active), but
   the actually-bundled icon font is MDI 7.3.67, which remapped its whole
   private-use range to 5-hex codepoints (`\F0142`/`\F0140` respectively —
   confirmed against assets/vendors/mdi/css/materialdesignicons.min.css).
   The old codepoints just don't exist in this font anymore. Pre-existing
   vendor/font-version mismatch, unrelated to anything else changed this
   session — corrected here rather than in the vendored file. */
.sidebar .nav .nav-item .nav-link i.menu-arrow::before {
  content: "\F0142";
}
.sidebar .nav .nav-item.active > .nav-link i.menu-arrow::before {
  content: "\F0140";
}

/* Collapsed (icon-only) sidebar restyle: center icons in a fixed rounded
   chip instead of the vendor's plain centered icon with no highlight. */
@media (min-width: 992px) {
  /* `>` all the way from `.nav` down to `.nav-link` — NOT `.nav:not(.sub-
     menu) .nav-item ...` (tried first, still broken): a `:not()` on one
     ancestor in a descendant chain doesn't stop a DIFFERENT, higher-up
     ancestor from satisfying the same compound selector, and the
     sidebar's own top-level `<ul class="nav">` legitimately wraps every
     submenu too — so `.nav:not(.sub-menu) .nav-item` was still satisfied
     by that outer, non-sub-menu `<ul>`, even for a `.nav-item` that's
     actually nested inside a `<ul class="nav sub-menu">` several levels
     down. Only requiring an unbroken chain of DIRECT children from the
     top-level `<ul class="nav">` genuinely excludes the flyout's own
     nested list — confirmed live: without this, every submenu link (e.g.
     "Compliance & Funding" under Reports) was squeezed into the same
     fixed 46x46 icon box meant for the collapsed rail's top-level icons,
     "cutting off" the label well before any width issue on the flyout
     panel itself. */
  .sidebar-icon-only .sidebar > .nav > .nav-item {
    padding: 0 0.5rem;
  }
  .sidebar-icon-only .sidebar > .nav > .nav-item > .nav-link {
    border-radius: 10px;
    padding: 0.65rem 0;
    margin: 0 auto;
    width: 46px;
    height: 46px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .sidebar-icon-only .sidebar > .nav > .nav-item.active > .nav-link {
    width: 46px;
    margin: 0 auto;
  }
  .sidebar-icon-only .sidebar .nav .nav-item .nav-link i.menu-icon {
    margin: 0;
    font-size: 1.15rem;
  }
  /* Reskin the existing hover-flyout label/submenu panel (hoverable-
     collapse.js still drives it, unchanged) to match the new rounded/
     shadow language instead of the vendor's square dark-green box.
     Widened from the vendor's 190px — too narrow for real labels like
     "Compliance & Funding" once the 46x46-icon-box bug above is fixed;
     the text no longer gets squeezed, but the panel itself still needs
     the room. text-align/justify-content are already left by default
     (vendor + .agricore-submenu-icon's own CSS), restated here so the
     flyout's alignment doesn't depend on that staying true elsewhere. */
  .sidebar-icon-only .sidebar .nav .nav-item.hover-open .nav-link .menu-title,
  .sidebar-icon-only .sidebar .nav .nav-item.hover-open .collapse,
  .sidebar-icon-only .sidebar .nav .nav-item.hover-open .collapsing {
    width: 240px;
    border-radius: 0 12px 12px 0;
    box-shadow: 6px 6px 20px rgba(0, 0, 0, 0.25);
  }
  .sidebar-icon-only .sidebar .nav .nav-item.hover-open .nav-link .menu-title {
    justify-content: flex-start;
    text-align: left;
  }
  .sidebar-icon-only .sidebar .nav.sub-menu .nav-item .nav-link {
    text-align: left;
    white-space: nowrap;
  }
}

/* Notification dropdown (desktop) — the mobile fix further down
   (.navbar-dropdown { position: fixed !important; ... }) only applies
   below 992px; above that it fell back to the vendor's bare
   `.dropdown-menu` default (min-width: 10rem / ~160px), meant for a short
   list of plain links like Settings/Logout, not a list of rich
   title+description+date notification cards — every row wrapped onto 5-6
   crushed lines. Scoped to `.preview-list` specifically (the notification
   dropdown's own marker class, per _navbar-farm-owner.html) so the
   farm-selector and profile dropdowns — genuinely short lists — are
   untouched. */
@media (min-width: 992px) {
  .navbar-dropdown.preview-list {
    width: 360px;
    max-width: calc(100vw - 2rem);
    max-height: calc(100vh - 100px);
    overflow-y: auto;
  }
}

/* ============================================================
   Mobile bottom tab bar + "More" sheet — farm-owner pages only
   (scoped via .agricore-sidebar, added alongside #sidebar/.sidebar-
   offcanvas only on these pages — see _sidebar-farm-owner.html).
   Replaces the old off-canvas full-sidebar slide-in below 992px.
   ============================================================ */
@media (max-width: 991.98px) {
  .agricore-sidebar.sidebar-offcanvas {
    display: none !important;
  }
}

.agricore-mobile-tabbar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 1030;
  display: flex;
  background: #1b5e20;
  box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.15);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.agricore-tab-link {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 8px 4px 6px;
  color: rgba(255, 255, 255, 0.65);
  font-size: 0.68rem;
  border: 0;
  background: transparent;
  text-decoration: none;
}
.agricore-tab-link i { font-size: 1.35rem; line-height: 1; }
.agricore-tab-link.agricore-tab-active,
.agricore-tab-link:active { color: #ffffff; }

.agricore-more-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  z-index: 1035;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
}
.agricore-more-backdrop.agricore-open { opacity: 1; pointer-events: auto; }

.agricore-more-sheet {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 1036;
  background: #fff;
  border-radius: 16px 16px 0 0;
  max-height: 70vh;
  display: flex;
  flex-direction: column;
  transform: translateY(100%);
  transition: transform 0.25s ease-out;
  padding-bottom: env(safe-area-inset-bottom, 0px);
  box-shadow: 0 -8px 30px rgba(0, 0, 0, 0.2);
}
.agricore-more-sheet.agricore-open { transform: translateY(0); }
.agricore-more-sheet-handle {
  width: 36px; height: 4px; border-radius: 2px;
  background: #dcdfe3; margin: 10px auto 6px;
  flex-shrink: 0;
}
.agricore-more-sheet-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 4px 16px 12px; font-weight: 700; border-bottom: 1px solid #eef0f2;
  flex-shrink: 0;
}
.agricore-more-sheet-close { border: 0; background: transparent; font-size: 1.2rem; color: #6c757d; }
.agricore-more-sheet-grid {
  display: block;
  overflow-y: auto;
}
/* Sectioned list — one section per sidebar item that has a submenu (title +
   every real child link as its own row), plus one "General" section for the
   plain, no-submenu links. Replaces the old flat 4-column icon-tile grid,
   which only ever exposed each group's single "primary" page and had no
   room to also list e.g. Accounting's 8 real destinations. */
.agricore-more-section { padding: 4px 16px; }
.agricore-more-section + .agricore-more-section { border-top: 8px solid var(--agricore-content-bg); }
.agricore-more-section-title {
  display: flex; align-items: center; gap: 0.5rem;
  font-weight: 700; font-size: 0.78rem; color: #2b3a4a;
  text-transform: uppercase; letter-spacing: 0.03em;
  padding: 10px 0 6px;
}
.agricore-more-section-title i { color: #1f6428; font-size: 1rem; }
/* 4-per-row icon tile grid — each section's own children/links, not a long
   scrolling list of text rows. */
.agricore-more-tile-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
  padding-bottom: 8px;
}
.agricore-more-tile {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 5px; padding: 12px 2px; text-decoration: none; color: #333;
  font-size: 0.66rem; line-height: 1.15; text-align: center; border-radius: 12px;
  background: #f8f9fa;
}
.agricore-more-tile:active { background: #eef1f3; }
.agricore-more-tile i { font-size: 1.35rem; color: #1f6428; }
.agricore-more-sheet-footer { padding: 12px 16px 14px; border-top: 1px solid #eef0f2; flex-shrink: 0; }
/* Dark mode: same card surface (#27293d) and green accent (#8fd49a) the rest
   of the dark theme uses. The section separators already follow
   --agricore-content-bg. */
body.theme-dark .agricore-more-sheet { background: #27293d; color: #e0e0e0; box-shadow: 0 -8px 30px rgba(0, 0, 0, 0.5); }
body.theme-dark .agricore-more-sheet-handle { background: rgba(255, 255, 255, .2); }
body.theme-dark .agricore-more-sheet-header { color: #f2f4f8; border-bottom-color: rgba(255, 255, 255, .08); }
body.theme-dark .agricore-more-sheet-close { color: #a9b4c2; }
body.theme-dark .agricore-more-section-title { color: #dfe6e1; }
body.theme-dark .agricore-more-section-title i,
body.theme-dark .agricore-more-tile i { color: #8fd49a; }
body.theme-dark .agricore-more-tile { background: #31344b; color: #e0e0e0; }
body.theme-dark .agricore-more-tile:active { background: #3a3e58; }
body.theme-dark .agricore-more-sheet-footer { border-top-color: rgba(255, 255, 255, .08); }

/* AI chat bubble/panel: hand-copied onto 36 pages across multiple themes
   sharing this one global stylesheet, so scope the reposition precisely to
   farm-owner pages — the only ones with a `.agricore-mobile-tabbar` in the
   DOM — rather than shifting it (harmlessly, but pointlessly) everywhere. */
@media (max-width: 991.98px) {
  body:has(.agricore-mobile-tabbar) #ai-chat-trigger {
    bottom: calc(60px + env(safe-area-inset-bottom, 0px) + 16px);
  }
  body:has(.agricore-mobile-tabbar) #ai-chat-panel {
    bottom: calc(60px + env(safe-area-inset-bottom, 0px) + 76px);
    max-height: calc(100vh - 60px - env(safe-area-inset-bottom, 0px) - 140px);
  }
  /* Leave room at the bottom of the (now normally-scrolling) page content
     so the fixed tab bar never covers the last card/row when scrolled all
     the way down. */
  body:has(.agricore-mobile-tabbar) .content-wrapper {
    padding-bottom: calc(1.5rem + 60px + env(safe-area-inset-bottom, 0px));
  }
}

/* Weather item's OLD home (inside .agricore-navbar-toprow) is now hidden on
   mobile as a whole (the toprow itself is `d-none` <992px) — this is just a
   belt-and-braces guard from before that restructure, kept since the
   vendor's forced `display: flex !important` on `.nav-item` here (see the
   .agricore-hidden-action comment above) would otherwise still be able to
   force it visible in some edge case (e.g. before mobile-nav.js has moved
   it out on first paint). */
@media (max-width: 991.98px) {
  .navbar .navbar-menu-wrapper .navbar-nav.navbar-nav-right .nav-item.agricore-weather-item {
    display: none !important;
  }
  .navbar .navbar-menu-wrapper .navbar-nav.navbar-nav-right .nav-item.agricore-clock-item {
    display: none !important;
  }
}

/* Sidebar submenu links (Livestock > Animals, Herds & Groups, ...) get a
   real icon (injected by mobile-nav.js, reusing its per-href icon map)
   instead of the vendor's plain CSS bullet dot — applies to both the
   expanded sidebar's inline submenu and the collapsed sidebar's hover-
   flyout, since it's the same DOM either way. */
.sidebar .nav.sub-menu .nav-item::before {
  display: none;
}
/* Vendor's general `.sidebar .nav .nav-item .nav-link` rule sets
   `white-space: nowrap` for every link, sidebar-wide — fine for the
   short top-level labels it was written for, but combined with the
   sub-menu list's own `overflow: hidden` (also vendor), a longer label
   like "Subscription & Billing" gets hard-clipped mid-word instead of
   wrapping once it's indented under the submenu's left padding (2.5rem)
   and squeezed by the icon's own width — confirmed live: 189px of content
   in a 176px box. Wrapping onto a 2nd line here (not widening the sidebar
   itself, which would shift the whole app's main-content width) is the
   same word-wrap-not-truncate fix already applied to notification text
   elsewhere in this file. */
.sidebar .nav.sub-menu .nav-item .nav-link {
  white-space: normal;
  line-height: 1.3;
}
.sidebar .nav.sub-menu .nav-item .nav-link .agricore-submenu-icon {
  width: 18px;
  margin-right: 0.65rem;
  font-size: 1rem;
  color: rgba(255, 255, 255, 0.75);
  text-align: center;
  flex-shrink: 0;
}

/* Notification/preview-list rows (`.preview-item`) are a flex row, and a
   flex child's default min-width is its own content's natural width, not
   0 — so long task titles never actually wrapped, they just forced the
   whole row (and the dropdown around it) wider than intended, which read
   as the text being cut off once the panel's own width was capped. Letting
   this child shrink below its content size is what lets it wrap instead. */
.preview-list .preview-item .preview-item-content {
  min-width: 0;
  flex: 1 1 auto;
}
.preview-list .preview-item .preview-item-content h6,
.preview-list .preview-item .preview-item-content p {
  white-space: normal;
  overflow-wrap: break-word;
}

/* Contacts page type tabs (All/Customers/Suppliers/…) */
.agricore-contact-tabs {
  gap: 0.5rem;
}
.agricore-contact-tabs .nav-link {
  border: 1px solid #dee2e6;
  border-radius: 999px;
  padding: 0.35rem 0.9rem;
  font-size: 0.85rem;
  font-weight: 500;
  /* Both theme-aware (see body.theme-dark's --bs-secondary-color/
     --bs-tertiary-bg overrides above) so this pill doesn't stay a
     light-gray-on-white block once the rest of the page goes dark. */
  color: var(--bs-secondary-color, #495057);
  background: var(--bs-tertiary-bg, #fff);
}
.agricore-contact-tabs .nav-link:hover {
  border-color: #1f6428;
  color: #1f6428;
}
.agricore-contact-tabs .nav-link.active {
  background: #1f6428;
  border-color: #1f6428;
  color: #fff;
}

/* ============================================================
   Page preloader — full-page overlay shown while a page's first batch of
   data is still loading (see page-preloader.js, which injects this markup
   and decides light/dark via localStorage before body.theme-dark even
   exists — hence the standalone .agricore-preloader-dark class here
   instead of body.theme-dark like the rest of this file).
   ============================================================ */
#agricore-preloader {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: var(--agricore-content-bg);
  transition: opacity 0.25s ease;
}
#agricore-preloader.agricore-preloader-dark {
  background: #1e1e2f;
}
#agricore-preloader.agricore-preloader-hidden {
  opacity: 0;
  pointer-events: none;
}
/* One icon (and one message) visible at a time, cross-fading to the next
   — see page-preloader.js's cycleIcon()/cycleMessage(). Both cycles are
   only running while this overlay is still mounted, so a fast page just
   shows icon 1 + "Hang in there…" for a moment and is gone; the sequence
   only visibly progresses if a page is genuinely slow to load. */
.agricore-preloader-icon {
  width: 64px;
  height: 64px;
  border-radius: 18px;
  background: linear-gradient(180deg, #2f7f35, #14501c);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.18);
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.agricore-preloader-icon.agricore-preloader-fade {
  opacity: 0;
  transform: scale(0.85);
}
.agricore-preloader-icon .mdi {
  color: #fff;
  font-size: 1.9rem;
}
.agricore-preloader-text {
  margin-top: 1.25rem;
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: 0.02em;
  color: #495057;
  transition: opacity 0.2s ease;
}
.agricore-preloader-text.agricore-preloader-fade {
  opacity: 0;
}
#agricore-preloader.agricore-preloader-dark .agricore-preloader-text {
  color: rgba(222, 226, 230, 0.85);
}
@media (prefers-reduced-motion: reduce) {
  .agricore-preloader-icon { transition: opacity 0.2s ease; }
  .agricore-preloader-icon.agricore-preloader-fade { transform: none; }
}

/* ============================================================
   Tighter spacing sitewide, every card on every page, every screen size
   — not just mobile (the vendor's own defaults were generous everywhere,
   mobile just made the compounding more obvious). Originally scoped to
   <992px only; extended unconditionally per explicit follow-up request.
   Measured on a 375px phone before this: content-wrapper's own edge
   padding (24px) + a stacked column's Bootstrap gutter (12px) + the
   card's own body padding (30px) added up to 66px dead space per side —
   nearly 30% of the screen width gone before any real content. Halving
   each layer (rather than zeroing one out) keeps things breathing but
   noticeably tightens the frame around actual content, on desktop too. */
.content-wrapper {
  padding-left: 1rem;
  padding-right: 1rem;
}
.row {
  --bs-gutter-x: 1rem;
}
.card .card-body {
  padding: 1.1rem 1.25rem;
}
.grid-margin {
  margin-bottom: 1.25rem;
}
.agricore-page-btn {
  min-width: 32px;
}

/* ---------------------------------------------------------------------------
   Dashboard / module-page visuals (dashboard-viz.js).
   A "band" is one module family: header, a fixed grid of metric tiles, then a
   fixed 3-up grid of visual cards. Bands are rendered whole or not at all, so
   turning a module off removes complete rows — there is never a half-empty
   row to leave a hole.
   --------------------------------------------------------------------------- */
.viz-band { margin-bottom: 1.75rem; }
.viz-band:empty { display: none; }
.viz-loading { padding: 3rem 0; text-align: center; color: #8f9cb3; }
.viz-band-head { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.9rem; }
.viz-band-head h5 { font-weight: 700; color: #2b3445; }
.viz-band-icon { width: 30px; height: 30px; border-radius: 8px; background: #e8f1ea; color: #386641; display: inline-flex; align-items: center; justify-content: center; font-size: 1.1rem; }

.viz-tiles { display: grid; gap: 1.25rem; margin-bottom: 1.25rem; grid-template-columns: 1fr; }
.viz-tiles--four { grid-template-columns: repeat(4, minmax(0, 1fr)); }
/* Flex (not grid) so a short last row stretches to the full width instead of leaving a gap. */
.viz-tiles--fluid { display: flex; flex-wrap: wrap; }
.viz-tiles--fluid .viz-tile { flex: 1 1 230px; min-width: 0; }
.viz-tile .card { height: 100%; margin: 0; }

.viz-visuals { display: grid; gap: 1.25rem; grid-template-columns: repeat(var(--viz-cols, 3), minmax(0, 1fr)); margin-bottom: 1.25rem; }
.viz-page { margin-bottom: 0.5rem; }
.viz-page:empty { display: none; }
.viz-card { min-width: 0; }
.viz-card .card { height: 100%; margin: 0; }
.viz-card .card-body { min-height: 360px; display: flex; flex-direction: column; }
.viz-sub { min-height: 1.2rem; margin-bottom: 0.5rem; }
.viz-body { flex: 1 1 auto; position: relative; min-height: 220px; }
.viz-canvas { position: relative; height: 240px; }
.viz-morris, .viz-flot, .viz-c3 { height: 220px; }
.viz-pie-label { font-size: 11px; font-weight: 700; color: #fff; text-align: center; }
.viz-empty { height: 220px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.4rem; color: #8f9cb3; text-align: center; font-size: 0.85rem; padding: 0 1rem; }
.viz-empty .mdi { font-size: 2rem; opacity: 0.6; }
.viz-bars { display: flex; flex-direction: column; gap: 0.9rem; padding-top: 0.25rem; }
.viz-bar-row .progress { margin-top: 0.3rem; }

@media (max-width: 1199.98px) {
  .viz-tiles--four { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .viz-visuals { grid-template-columns: repeat(min(var(--viz-cols, 3), 2), minmax(0, 1fr)); }
  /* an odd last card spans the row rather than leaving a hole beside it */
  .viz-visuals > .viz-card:last-child:nth-child(odd) { grid-column: 1 / -1; }
}
@media (max-width: 767.98px) {
  .viz-visuals { grid-template-columns: minmax(0, 1fr); }
  .viz-card .card-body { min-height: 0; }

  /* Phones: summary tiles sit two across (compact) instead of one long column. */
  .viz-tiles--four, .viz-tiles--fluid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.75rem; margin-bottom: 0.75rem; }
  .viz-tiles--fluid .viz-tile { flex: none; }
  .viz-tiles--four .viz-tile:last-child:nth-child(odd), .viz-tiles--fluid .viz-tile:last-child:nth-child(odd) { grid-column: 1 / -1; }
  .viz-tiles--four .stat-card .card-body, .viz-tiles--fluid .stat-card .card-body { padding: 0.8rem 0.85rem; gap: 0.5rem; }
  .viz-tiles--four .stat-card .stat-card-label, .viz-tiles--fluid .stat-card .stat-card-label { font-size: 0.75rem; line-height: 1.25; margin-bottom: 0.15rem; }
  .viz-tiles--four .stat-card .stat-card-value, .viz-tiles--fluid .stat-card .stat-card-value { font-size: 1.3rem; }
  .viz-tiles--four .stat-card .text-muted, .viz-tiles--fluid .stat-card .text-muted { font-size: 0.72rem; line-height: 1.25; display: block; }
  .viz-tiles--four .stat-card .stat-card-icon, .viz-tiles--fluid .stat-card .stat-card-icon { width: 34px; height: 34px; font-size: 1rem; }
}

/* To-Do card (dashboard): theme "Todo" layout, rounded card kept. */
.viz-todo .add-items { gap: 0.6rem; margin-bottom: 0.75rem; }
.viz-todo .todo-list { list-style: none; margin: 0; padding: 0; max-height: 252px; overflow-y: auto; }
.viz-todo .todo-list li { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; padding: 0.55rem 0; border-bottom: 1px solid #e9edf3; cursor: pointer; transition: opacity 0.35s ease, max-height 0.35s ease; max-height: 80px; overflow: hidden; }
.viz-todo .todo-list li:last-child { border-bottom: 0; }
.viz-todo .todo-list .form-check { margin: 0; flex: 1 1 auto; min-width: 0; }
.viz-todo .todo-list .form-check-label { display: flex; align-items: center; gap: 0.5rem; cursor: pointer; width: 100%; margin: 0; }
.viz-todo .todo-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.viz-todo .todo-due { margin-left: auto; font-size: 0.75rem; color: #8f9cb3; white-space: nowrap; padding-left: 0.5rem; }
.viz-todo .todo-due.is-overdue { color: #dc3545; font-weight: 600; }
.viz-todo .todo-list li.completed .todo-title { text-decoration: line-through; color: #2a9d8f; }
.viz-todo .todo-list li.completed { opacity: 0.35; }
.viz-todo .todo-list li.leaving { opacity: 0; max-height: 0; padding-top: 0; padding-bottom: 0; border-bottom-width: 0; }
.viz-todo .todo-list .remove { font-size: 1.25rem; color: #8f9cb3; cursor: pointer; }
.viz-todo .todo-list .remove:hover { color: #dc3545; }
.viz-todo .todo-more { font-size: 0.8rem; color: #8f9cb3; padding-top: 0.4rem; }

/* Split layout: one chart on the left, its tiles as a compact grid on the right. */
.viz-split { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.25rem; margin-bottom: 1.25rem; align-items: stretch; }
.viz-split .viz-visuals { margin-bottom: 0; height: 100%; }
.viz-split-side { display: flex; }
.viz-tiles--grid2 { flex: 1; margin-bottom: 0; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: 1fr; }
.viz-tiles--grid2 .viz-tile:last-child:nth-child(odd) { grid-column: 1 / -1; }
.viz-tiles--grid2 .stat-card .card-body { padding: 1rem 1.1rem; }
.viz-tiles--grid2 .stat-card .stat-card-value { font-size: 1.5rem; }
.viz-tiles--grid2 .stat-card .stat-card-icon { width: 40px; height: 40px; font-size: 1.15rem; }
/* Phones: the same compact tile as the other summary rows, so long rand amounts keep a readable size. */
@media (max-width: 767.98px) {
  .viz-tiles--grid2 .stat-card .card-body { padding: 0.8rem 0.85rem; gap: 0.5rem; }
  .viz-tiles--grid2 .stat-card .stat-card-label { font-size: 0.75rem; line-height: 1.25; margin-bottom: 0.15rem; }
  .viz-tiles--grid2 .stat-card .stat-card-value { font-size: 1.3rem; }
  .viz-tiles--grid2 .stat-card .text-muted { font-size: 0.72rem; line-height: 1.25; display: block; }
  .viz-tiles--grid2 .stat-card .stat-card-icon { width: 34px; height: 34px; font-size: 1rem; }
}
@media (max-width: 991.98px) {
  .viz-split { grid-template-columns: 1fr; }
}

/* Existing page stat tiles (agricore-stat-tile) reused inside a split grid. */
.viz-split-main { min-width: 0; }
.viz-split-main .viz-page { height: 100%; margin-bottom: 0; }
.viz-split-main .viz-page .viz-visuals, .viz-split-main .viz-page .viz-card { height: 100%; }
.viz-tiles--plain .viz-tile { display: flex; }
.viz-tiles--plain .agricore-stat-tile { flex: 1; margin: 0; height: 100%; }

/* Phones: every dialog fits the screen with its action buttons in view.
   The theme's 100px top margin pushed scrollable dialogs' footers (e.g.
   "Save Animal") below the fold, and long button rows stacked. */
@media (max-width: 575.98px) {
  .modal-dialog { margin: .5rem auto; max-width: calc(100% - 1rem); }
  .modal-dialog-scrollable { height: calc(100dvh - 1rem); }
  .modal-dialog-scrollable .modal-content { max-height: 100%; }
  .modal-footer { flex-wrap: nowrap; gap: .5rem; }
  .modal-footer > .btn { flex: 1 1 0; margin: 0; min-width: 0; }
}

/* The theme justifies every .tab-content, which stretches word spacing on
   narrow cards (task titles, record lists). Left-align app content. */
.tab-content { text-align: left; }

/* Generated form checks (Add Animal etc.): keep the control inside the form
   — the theme's negative input margin pushed radios past the modal edge. */
.agricore-check { padding-left: 1.6rem; min-height: 1.5rem; }
.agricore-check .form-check-input { margin-left: -1.6rem; position: relative; }
.agricore-check .form-check-label { margin-left: .25rem; }

/* Refer a friend card (Subscription + Profile). */
.agx-ref-card { border: 1px solid rgba(31, 100, 40, .25); background: linear-gradient(135deg, rgba(31, 100, 40, .06), rgba(139, 224, 154, .08)); }
.agx-ref-icon { width: 48px; height: 48px; border-radius: 14px; display: grid; place-items: center; font-size: 1.6rem; color: #fff; background: #1f6428; flex-shrink: 0; }
.agx-ref-code { display: flex; align-items: center; justify-content: space-between; gap: .75rem; flex-wrap: wrap; padding: .75rem 1rem; border: 1px dashed rgba(31, 100, 40, .55); border-radius: .75rem; background: var(--bs-body-bg, #fff); }
.agx-ref-code-value { font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace; font-size: 1.5rem; font-weight: 700; letter-spacing: .12em; color: #1f6428; }
.agx-ref-actions { display: flex; flex-wrap: wrap; gap: .5rem; }
.agx-ref-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .5rem; }
.agx-ref-stats > div { padding: .6rem .75rem; border-radius: .6rem; background: rgba(31, 100, 40, .07); display: flex; flex-direction: column; }
.agx-ref-stats strong { font-size: 1.15rem; font-variant-numeric: tabular-nums; }
.agx-ref-stats span { font-size: .75rem; color: var(--bs-secondary-color, #6c757d); }
@media (max-width: 575.98px) {
  .agx-ref-actions .btn { flex: 1 1 calc(50% - .5rem); }
  .agx-ref-code-value { font-size: 1.3rem; }
}
body.theme-dark .agx-ref-code { background: var(--bs-tertiary-bg); }
body.theme-dark .agx-ref-code-value { color: #8be09a; }
body.theme-dark .agx-ref-stats > div { background: var(--bs-secondary-bg); }
/* Jumping to #refer from the account menu keeps the card title clear of the fixed header. */
#refer { scroll-margin-top: 90px; }

/* Live-count card on an animal/group page (batch-panel.js). */
.agx-bp-top { display: grid; grid-template-columns: auto 1fr; gap: .75rem 1.25rem; align-items: center; }
.agx-bp-count { display: flex; align-items: center; gap: .6rem; }
.agx-bp-alive { font-size: 2.6rem; font-weight: 800; line-height: 1; color: #1f6428; font-variant-numeric: tabular-nums; }
.agx-bp-of { font-size: .8rem; line-height: 1.2; color: var(--bs-secondary-color, #6c757d); }
.agx-bp-bar { height: 10px; border-radius: 99px; background: rgba(31, 100, 40, .15); overflow: hidden; }
.agx-bp-bar span { display: block; height: 100%; background: #1f6428; border-radius: 99px; }
.agx-bp-chips { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: .4rem; }
.agx-bp-chip { display: inline-flex; align-items: center; gap: .3rem; padding: .3rem .65rem; border-radius: 99px; font-size: .82rem; background: rgba(31, 100, 40, .08); }
.agx-bp-chip.is-bad { background: rgba(220, 53, 69, .1); color: #b02a37; }
.agx-bp-actions { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 1rem; }
.agx-bp-actions .btn { min-height: 46px; border-radius: 12px; font-weight: 600; }
.agx-bp-closed { margin-top: 1rem; padding: .6rem .8rem; border-radius: 10px; background: rgba(31, 100, 40, .08); font-size: .9rem; }
.agx-bp-answer { font-size: 1.05rem; font-weight: 600; margin: .25rem 0 .75rem; }
.agx-bp-answer.is-good, .agx-bp-money-grid .is-good strong { color: #1f6428; }
.agx-bp-answer.is-bad, .agx-bp-money-grid .is-bad strong { color: #b02a37; }
.agx-bp-money-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .5rem; }
.agx-bp-money-grid > div { padding: .7rem .8rem; border-radius: 12px; background: rgba(31, 100, 40, .06); display: flex; flex-direction: column; min-width: 0; }
.agx-bp-money-grid span { font-size: .78rem; color: var(--bs-secondary-color, #6c757d); }
.agx-bp-money-grid strong { font-size: 1.15rem; font-variant-numeric: tabular-nums; }
.agx-bp-money-grid small { font-size: .72rem; color: var(--bs-secondary-color, #6c757d); }
.agx-bp-history { list-style: none; padding: 0; margin: 0; }
.agx-bp-history li { display: flex; gap: .6rem; padding: .5rem 0; border-bottom: 1px solid rgba(0, 0, 0, .06); }
.agx-bp-history li:last-child { border-bottom: 0; }
.agx-bp-history i { font-size: 1.2rem; }
.agx-bp-ev-in { color: #1f6428; } .agx-bp-ev-out { color: #b02a37; } .agx-bp-ev-count { color: #0d6efd; }
@media (max-width: 575.98px) {
  .agx-bp-top { grid-template-columns: 1fr; }
  .agx-bp-actions .btn { flex: 1 1 calc(50% - .5rem); }
  .agx-bp-money-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .agx-bp-money-grid > div:last-child:nth-child(odd) { grid-column: 1 / -1; }
}
body.theme-dark .agx-bp-alive { color: #8be09a; }
body.theme-dark .agx-bp-chip, body.theme-dark .agx-bp-closed, body.theme-dark .agx-bp-money-grid > div { background: var(--bs-secondary-bg); }
body.theme-dark .agx-bp-history li { border-color: rgba(255, 255, 255, .08); }

/* Plant in bulk (planting-bulk.js): one card per line, phone first */
.agx-pb-line { margin-bottom: .75rem; border-radius: 14px; }
.agx-pb-line .card-body { padding: .9rem 1rem; }
.agx-pb-line-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: .4rem; }
.agx-pb-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: .6rem .75rem; }
.agx-pb-grid .agx-pb-wide { grid-column: span 2; }
.agx-pb-grid .form-label { font-size: .8rem; margin-bottom: .2rem; }
@media (max-width: 575.98px) {
  .agx-pb-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Subscription page plan cards: a border you can actually see, stronger for the popular and current plan. */
.pricing-card .pricing-card-body { border: 1.5px solid #b9c9bf !important; border-radius: 18px; }
.pricing-card .pricing-card-body.is-popular { border: 2.5px solid #1f6428 !important; }
.pricing-card .pricing-card-body.is-current { border: 2.5px solid #1f6428 !important; }
body.theme-dark .pricing-card .pricing-card-body { border-color: rgba(255, 255, 255, .22) !important; }
body.theme-dark .pricing-card .pricing-card-body.is-popular,
body.theme-dark .pricing-card .pricing-card-body.is-current { border-color: #4caf50 !important; }

/* Rongwa tier picker on the Subscription page: the radio sits inside each card, the picked card is highlighted. */
.ai-tier-tile { display: flex; gap: .75rem; align-items: flex-start; height: 100%; margin: 0; padding: .85rem 1rem; border: 1.5px solid #b9c9bf; border-radius: 14px; cursor: pointer; transition: border-color .15s, background .15s; }
.ai-tier-tile .form-check-input { float: none; margin: .2rem 0 0; flex: 0 0 auto; width: 1.15rem; height: 1.15rem; }
.ai-tier-tile .ai-tier-body { min-width: 0; }
.ai-tier-tile:hover { border-color: #1f6428; }
.ai-tier-tile.is-selected { border: 2px solid #1f6428; background: rgba(31, 100, 40, .07); }
body.theme-dark .ai-tier-tile { border-color: rgba(255, 255, 255, .22); }
body.theme-dark .ai-tier-tile.is-selected { border-color: #4caf50; background: rgba(76, 175, 80, .12); }
button.ai-tier-tile { background: transparent; color: inherit; font: inherit; }

/* Subscription page plan cards (planCardHtml), following the plan-card mockup: badge, leaf icon + name,
   subtitle, description, a farm photo in the top-right corner, a big price, four metric tiles, what's included
   as a grid, the Rongwa add-on (selector, saving, Add button) and the full-width plan button. */
.pricing-table .pricing-card .card.plan-card { padding: 1.4rem 1.35rem 1.25rem !important; }
.plan-card { --pc-accent: #1fae67; --pc-accent-2: #168a52; --pc-soft: rgba(31, 174, 103, .1); --pc-line: #dfe8e3; --pc-muted: #5f7180; --pc-tile: #f7faf8;
  position: relative; overflow: hidden; text-align: left; display: flex; flex-direction: column; gap: 1rem; border-radius: 20px !important; }
body.theme-dark .plan-card { --pc-accent: #2fd27f; --pc-accent-2: #1a9a5c; --pc-soft: rgba(47, 210, 127, .12); --pc-line: rgba(160, 200, 185, .16); --pc-muted: #93a6b4; --pc-tile: rgba(255, 255, 255, .025); background: #101d24 !important; }
.plan-card .pc-art { position: absolute; top: 0; right: 0; width: 42%; height: 168px; background: url('/assets/images/plans/plan-field.jpg') center / cover no-repeat;
  border-bottom-left-radius: 120px 100%; -webkit-mask-image: linear-gradient(200deg, #000 55%, transparent 100%); mask-image: linear-gradient(200deg, #000 55%, transparent 100%); opacity: .95; pointer-events: none; }
.plan-card .pc-top { position: relative; padding-right: 38%; min-height: 130px; }
.plan-card .pc-badge { display: inline-flex; align-items: center; gap: .35rem; font-size: .72rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; padding: .32rem .8rem; border-radius: 999px; background: var(--pc-soft); color: var(--pc-accent); margin-bottom: .7rem; }
.plan-card .pc-badge.is-current { background: var(--pc-accent); color: #fff; }
.plan-card .pc-badge.is-popular { background: #f4b400; color: #3d2c00; }
.plan-card .pc-title { display: flex; align-items: center; gap: .6rem; }
.plan-card .pc-title h3 { margin: 0; font-size: 1.75rem; font-weight: 800; letter-spacing: -.01em; }
.plan-card .pc-icon { flex: 0 0 auto; font-size: 2rem; line-height: 1; color: var(--pc-accent); }
.plan-card .pc-icon .mdi { font-size: 2rem; line-height: 1; }
.plan-card .pc-tagline { margin: .35rem 0 0; font-weight: 700; font-size: 1.02rem; color: var(--pc-muted); }
.plan-card .pc-desc { margin: .45rem 0 0; font-size: .88rem; line-height: 1.5; color: var(--pc-muted); }
.plan-card .pc-price { display: flex; align-items: baseline; flex-wrap: wrap; gap: .5rem; }
.plan-card .pc-amount { font-size: 2.6rem; font-weight: 800; line-height: 1; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.plan-card .pc-amount-sm { font-size: 1.8rem; }
.plan-card .pc-per { font-size: 1.05rem; color: var(--pc-muted); }
.plan-card .pc-limits { display: grid; grid-template-columns: repeat(var(--pc-n, 4), minmax(0, 1fr)); gap: .55rem; }
.plan-card .pc-limit { display: flex; flex-direction: column; align-items: center; text-align: center; padding: .8rem .35rem .7rem; border: 1px solid var(--pc-line); border-radius: 14px; background: var(--pc-tile); }
.plan-card .pc-limit-wide { grid-column: 1 / -1; }
.plan-card .pc-limit-ic { display: block; margin-bottom: .35rem; color: var(--pc-accent); background: none !important; }
.plan-card .pc-limit-ic .mdi { font-size: 1.7rem; line-height: 1; }
.plan-card .pc-limit strong { font-size: 1.3rem; line-height: 1.1; }
.plan-card .pc-limit span { font-size: .8rem; color: var(--pc-muted); }
.plan-card .pc-limit small { font-size: .7rem; color: var(--pc-muted); }
.plan-card .pc-sub { font-weight: 800; font-size: 1.05rem; margin-bottom: .55rem; }
.plan-card .pc-included-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .45rem .8rem; }
.plan-card .pc-included-grid li { display: flex; align-items: flex-start; gap: .45rem; font-size: .86rem; line-height: 1.3; }
.plan-card .pc-included-grid .mdi { flex: 0 0 auto; font-size: 1.15rem; line-height: 1; color: var(--pc-accent); }
.plan-card .plan-rongwa { border: 1px solid var(--pc-line); border-radius: 16px; padding: .95rem 1rem 1rem; background: var(--pc-tile); }
.plan-rongwa-head { display: flex; align-items: flex-start; gap: .75rem; }
.plan-rongwa-avatar { flex: 0 0 auto; width: 2.9rem; height: 2.9rem; border-radius: 50%; display: grid; place-items: center; color: #fff; background: linear-gradient(135deg, #2fd27f, #168a52); }
.plan-rongwa-avatar .mdi { font-size: 1.6rem; line-height: 1; }
.plan-rongwa-head strong { display: block; font-size: 1.1rem; line-height: 1.15; }
.plan-rongwa-role { display: block; font-size: .82rem; font-weight: 700; color: var(--pc-accent, #1fae67); }
.plan-rongwa-role span { font-weight: 500; color: var(--pc-muted, #5f7180); }
.plan-rongwa-intro { margin: .3rem 0 0; font-size: .82rem; line-height: 1.45; color: var(--pc-muted, #5f7180); }
.plan-rongwa-rec { margin-top: .75rem; font-size: .88rem; }
.plan-rongwa-select { position: relative; margin-top: .45rem; }
.plan-rongwa-select > .mdi { position: absolute; left: .7rem; top: 50%; transform: translateY(-50%); color: var(--pc-muted); pointer-events: none; }
.plan-rongwa-select .form-select { padding-left: 2.1rem; border-radius: 12px; border-color: var(--pc-line); background-color: transparent; color: inherit; font-size: .88rem; }
body.theme-dark .plan-rongwa-select .form-select option { background: #101d24; }
.plan-rongwa-note { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem .6rem; margin-top: .55rem; }
.plan-rongwa-save { display: inline-flex; align-items: center; gap: .3rem; font-size: .8rem; font-weight: 700; color: #b77900; border: 1px solid rgba(244, 180, 0, .55); background: rgba(244, 180, 0, .1); padding: .22rem .7rem; border-radius: 999px; }
body.theme-dark .plan-rongwa-save { color: #ffca28; }
.plan-rongwa-together { font-size: .78rem; color: var(--pc-muted, #5f7180); }
.plan-card .pc-foot { margin-top: auto; }
.plan-card .pc-btn { border-radius: 14px; padding: .7rem .9rem; font-weight: 700; }
.plan-card .btn-success.pc-btn { background: linear-gradient(180deg, #2fd27f, #1a9a5c); border: 0; color: #fff; }
.plan-card .btn-success.pc-btn:disabled { opacity: 1; }
.plan-card .btn-outline-success.pc-btn { border-color: var(--pc-accent); color: var(--pc-accent); }
.plan-card .btn-outline-success.pc-btn:hover { background: var(--pc-soft); }
.pricing-card .pricing-card-body.plan-card.is-popular, .pricing-card .pricing-card-body.plan-card.is-current { box-shadow: 0 0 0 1px rgba(47, 210, 127, .25), 0 18px 40px -24px rgba(47, 210, 127, .45); }
body.theme-dark .plan-card .pc-title h3, body.theme-dark .plan-card .pc-amount, body.theme-dark .plan-card .pc-limit strong, body.theme-dark .plan-card .pc-sub, body.theme-dark .plan-rongwa-head strong, body.theme-dark .plan-card .pc-included-grid li { color: #f2f6f4; }
@media (max-width: 575.98px) {
  .plan-card .pc-art { width: 46%; height: 132px; }
  .plan-card .pc-top { padding-right: 34%; }
  .plan-card .pc-limits { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .plan-card .pc-amount { font-size: 2.2rem; }
}
@media (max-width: 380px) { .plan-card .pc-included-grid { grid-template-columns: 1fr; } }
.plan-card .pc-limit-ic .mdi, .plan-card .pc-limit-ic { color: var(--pc-accent) !important; }
@media (max-width: 575.98px) { .plan-card .pc-art { width: 40%; height: 116px; } .plan-card .pc-top { padding-right: 42%; } .plan-card .pc-title h3 { font-size: 1.5rem; } }
@media (max-width: 575.98px) {
  .plan-card .pc-sub { font-size: 1.15rem; }
  .plan-card .pc-included-grid { gap: .6rem .9rem; }
  .plan-card .pc-included-grid li { font-size: 1.02rem; line-height: 1.35; }
  .plan-card .pc-included-grid .mdi { font-size: 1.3rem; }
}

/* Sidebar in the light theme: the deep forest green of the sign-in page (agricore-auth.css --bx-green-deep),
   instead of the brighter brand green. Dark mode keeps its own dark sidebar. */
body:not(.theme-dark) #sidebar.sidebar,
body:not(.theme-dark) #sidebar.sidebar .nav .nav-item .collapse,
body:not(.theme-dark) #sidebar.sidebar .sub-menu { background: #0a3d2a; }
body:not(.theme-dark) #sidebar.sidebar { background: linear-gradient(180deg, #0a3d2a 0%, #083423 55%, #06281c 100%); }
body:not(.theme-dark) .agricore-mobile-tabbar { background: #0a3d2a; }

/* ===== Brand green, matching the sign-in page (agricore-auth.css .bx-btn-primary) =====
   One deep green for every button, badge, toggle and floating control, replacing the older bright #1f6428 and
   the minty #2fb380 "success" green. Dark mode keeps a lighter green only where text needs contrast. */
:root, body {
  --agx-green: #1f6428; --agx-green-hi: #2f7f35; --agx-green-lo: #14501c; --agx-green-rgb: 31, 100, 40;
  --bs-primary: #1f6428; --bs-primary-rgb: 31, 100, 40; --bs-success: #1f6428; --bs-success-rgb: 31, 100, 40;
  --bs-link-color: #1f6428; --bs-link-color-rgb: 31, 100, 40; --bs-link-hover-color: #14501c;
}
.btn-primary, .btn-success, .btn-primary:disabled, .btn-success:disabled, .btn-primary.disabled, .btn-success.disabled {
  background: linear-gradient(180deg, var(--agx-green-hi), var(--agx-green)) !important; border-color: var(--agx-green) !important; color: #fff !important;
  box-shadow: 0 6px 14px -8px rgba(var(--agx-green-rgb), .7);
}
.btn-primary:hover, .btn-success:hover, .btn-primary:focus, .btn-success:focus, .btn-primary:active, .btn-success:active {
  background: linear-gradient(180deg, var(--agx-green), var(--agx-green-lo)) !important; border-color: var(--agx-green-lo) !important; color: #fff !important;
}
.btn-outline-primary, .btn-outline-success { color: var(--agx-green) !important; border-color: var(--agx-green) !important; background: transparent !important; }
.btn-outline-primary:hover, .btn-outline-success:hover, .btn-outline-primary.active, .btn-outline-success.active { background: var(--agx-green) !important; color: #fff !important; }
body.theme-dark .btn-outline-primary, body.theme-dark .btn-outline-success { color: #8fd49a !important; border-color: #3f8f4a !important; }
body.theme-dark .btn-outline-primary:hover, body.theme-dark .btn-outline-success:hover { color: #fff !important; background: var(--agx-green) !important; }
.badge.bg-success, .badge.bg-primary, .bg-success:not(.progress-bar), .bg-primary:not(.progress-bar) { background-color: var(--agx-green) !important; }
.progress-bar.bg-success { background-color: #2f7f35 !important; }
/* Tinted badges ("In plan", the AI tier): a pale green with green text, not solid green on green. */
.bg-success[class*="bg-opacity-"], .bg-primary[class*="bg-opacity-"] { background-color: rgba(var(--agx-green-rgb), .13) !important; }
.badge.bg-success[class*="bg-opacity-"], .badge.bg-primary[class*="bg-opacity-"] { color: var(--agx-green) !important; }
body.theme-dark .bg-success[class*="bg-opacity-"], body.theme-dark .bg-primary[class*="bg-opacity-"] { background-color: rgba(143, 212, 154, .16) !important; }
body.theme-dark .badge.bg-success[class*="bg-opacity-"], body.theme-dark .badge.bg-primary[class*="bg-opacity-"] { color: #8fd49a !important; }
body:not(.theme-dark) .text-success, body:not(.theme-dark) .text-primary { color: var(--agx-green) !important; }
.form-check-input:checked { background-color: var(--agx-green); border-color: var(--agx-green); }
.nav-pills .nav-link.active, .nav-pills .show > .nav-link { background: var(--agx-green) !important; color: #fff !important; }
/* Underline page tabs (Crops & Plantings): green text and a rounded bar under the active tab, a soft tint on hover. */
.agricore-cp-tabs { gap: .35rem !important; }
.agricore-cp-tabs a { position: relative; padding: .6rem .85rem !important; border-bottom: 0 !important; border-radius: 10px 10px 0 0; color: #6c7a8a; transition: color .2s ease, background-color .2s ease; }
.agricore-cp-tabs a::after { content: ""; position: absolute; left: .6rem; right: .6rem; bottom: -1px; height: 3px; border-radius: 3px 3px 0 0; background: var(--agx-green); transform: scaleX(0); transition: transform .25s ease; }
.agricore-cp-tabs a:hover { color: var(--agx-green) !important; background: rgba(var(--agx-green-rgb), .06); }
.agricore-cp-tabs a.active { color: var(--agx-green) !important; background: transparent; }
.agricore-cp-tabs a.active::after { transform: scaleX(1); }
body.theme-dark .agricore-cp-tabs { border-bottom-color: rgba(255, 255, 255, .1) !important; }
body.theme-dark .agricore-cp-tabs a { color: #9aa8b8; }
body.theme-dark .agricore-cp-tabs a:hover, body.theme-dark .agricore-cp-tabs a.active { color: #8fd49a !important; }
body.theme-dark .agricore-cp-tabs a:hover { background: rgba(143, 212, 154, .08); }
body.theme-dark .agricore-cp-tabs a::after { background: #8fd49a; }
/* Sidebar: active item and Logout in the same deep green, lifted slightly off the forest-green panel. */
.sidebar .nav .nav-item.active > .nav-link { background: linear-gradient(135deg, #2a7a31, #14501c); box-shadow: 0 4px 14px rgba(0, 0, 0, .28), inset 0 1px 0 rgba(255, 255, 255, .14); }
#sidebar .btn-success { background: linear-gradient(180deg, #2a7a31, #14501c) !important; border: 1px solid rgba(255, 255, 255, .16) !important; }
/* Floating AI chat button, quick-add and other round primary icons. */
#ai-chat-trigger { background: linear-gradient(180deg, var(--agx-green-hi), var(--agx-green-lo)); box-shadow: 0 8px 18px -6px rgba(var(--agx-green-rgb), .7); }
.agricore-icon-btn.agricore-icon-btn-primary { background: linear-gradient(180deg, var(--agx-green-hi), var(--agx-green)); box-shadow: 0 3px 12px rgba(var(--agx-green-rgb), .45); }
/* Plan cards on the Subscription page follow the same green. */
.plan-card { --pc-accent: #1f6428; --pc-accent-2: #14501c; --pc-soft: rgba(31, 100, 40, .1); }
body.theme-dark .plan-card { --pc-accent: #6fcf7f; --pc-soft: rgba(111, 207, 127, .12); }
.plan-card .btn-success.pc-btn { background: linear-gradient(180deg, var(--agx-green-hi), var(--agx-green-lo)) !important; }
.plan-rongwa-avatar { background: linear-gradient(135deg, #2f7f35, #14501c); }
.ai-tier-tile.is-selected { border-color: var(--agx-green); background: rgba(var(--agx-green-rgb), .07); }
body.theme-dark .ai-tier-tile.is-selected { border-color: #4f9f5a; background: rgba(79, 159, 90, .14); }
body.theme-dark { --bs-link-color: #8fd49a; --bs-link-color-rgb: 143, 212, 154; --bs-link-hover-color: #b5e6bc; }
body.theme-dark a.card-view-more, body.theme-dark .card a:not(.btn):not(.dropdown-item):not(.nav-link) { color: #8fd49a; }

/* Desktop mini header for pages without the farm header (admin; template.js applyNavbarScrollState): the
   placeholder holds the header's space, so the page never shifts, and the mini header slides in. */
@media (min-width: 992px) {
  body.navbar-fixed-top .main-panel { padding-top: 0 !important; }
  .navbar.agx-nav-slide { animation: agx-nav-in .22s ease-out both; }
}
@keyframes agx-nav-in { from { transform: translateY(-100%); opacity: .4; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .navbar.agx-nav-slide { animation: none; } }

/* Farm header (desktop, template.js collapseAppNav): it floats over the scrolling pane, which starts with the
   header's full height as padding. Scrolling shrinks it in step with the scroll, the search row sliding up under
   the greeting row, so nothing in the page changes size: no jump, no flicker. */
@media (min-width: 992px) {
  body.agx-floating-nav .page-body-wrapper { position: relative; }
  body.agx-floating-nav .navbar.agricore-navbar {
    position: absolute; top: 0; left: 0; right: 0; z-index: 1020;
    transition: box-shadow .25s ease;
  }
  body.agx-floating-nav .navbar.agricore-navbar.agx-nav-collapsed { box-shadow: 0 6px 18px rgba(6, 24, 16, .22); }
  body.agx-floating-nav .main-panel { padding-top: var(--agx-nav-h, 0px); }
  body.agx-floating-nav .agricore-navbar-secondrow { will-change: transform, opacity; }
  body.agx-floating-nav .agricore-navbar-secondrow.agx-row-hidden { pointer-events: none; }
}

/* Smooth scrolling for jumps to a section (links, "back to top"), and the page alone takes the scroll. */
html, .main-panel { scroll-behavior: smooth; }
.main-panel { overscroll-behavior-y: contain; }

/* Cards rise gently into view the first time they are scrolled to (template.js; once only, never on the first
   screen, nothing when the device asks for less motion). */
.agx-reveal { opacity: 0; transform: translateY(16px); }
.agx-reveal-in { animation: agx-rise .5s cubic-bezier(.2, .7, .3, 1) both; }
@keyframes agx-rise { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  html, .main-panel { scroll-behavior: auto; }
  .agx-reveal { opacity: 1; transform: none; }
  .agx-reveal-in { animation: none; }
}
@media print { .agx-reveal { opacity: 1; transform: none; } }

/* Modern dialogs everywhere: SweetAlert confirms/prompts (agricore-notify.js) and every Bootstrap modal share one
   look — rounded card, soft deep shadow, blurred green-tinted backdrop, a gentle scale-in, full-width buttons. */
.swal-overlay { background-color: rgba(6, 24, 16, .45); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); }
.swal-modal {
  width: min(440px, calc(100vw - 32px)); border-radius: 20px; padding: 26px 22px 20px; font-family: inherit;
  box-shadow: 0 30px 70px -22px rgba(6, 24, 16, .5); border: 0;
}
.swal-overlay--show-modal .swal-modal { animation: agx-dialog-in .26s cubic-bezier(.2, .8, .3, 1.08); }
@keyframes agx-dialog-in { from { opacity: 0; transform: translateY(10px) scale(.95); } to { opacity: 1; transform: none; } }
.swal-icon { width: 64px; height: 64px; margin: 4px auto 12px; border-width: 3px; }
.swal-icon--warning { border-color: #f2b544; }
.swal-icon--warning__body, .swal-icon--warning__dot { background-color: #e39a1b; }
.swal-icon--info { border-color: var(--agx-green); }
.swal-icon--info:before, .swal-icon--info:after { background-color: var(--agx-green); }
.swal-icon--success { border-color: rgba(var(--agx-green-rgb), .25); }
.swal-icon--success__line { background-color: var(--agx-green); }
.swal-icon--success__ring { border-color: rgba(var(--agx-green-rgb), .25); }
.swal-icon--warning { animation: none; }
.swal-icon--warning__body { width: 4px; height: 26px; top: 12px; }
.swal-icon--warning__dot { width: 6px; height: 6px; bottom: -9px; margin-left: -3px; }
.swal-icon--info:before { height: 22px; bottom: 12px; width: 4px; margin-left: -2px; }
.swal-icon--info:after { top: 12px; width: 6px; height: 6px; margin-left: -3px; }
.swal-title { font-size: 1.3rem; font-weight: 700; color: #0f2a1d; padding: 0 6px; margin: 2px 0 0; line-height: 1.3; }
.swal-title:not(:last-child) { margin-bottom: 6px; }
.swal-text { display: block; text-align: center; color: #5b6b7b; font-size: .94rem; line-height: 1.55; padding: 0 6px; margin: 0 auto; max-width: none; white-space: pre-line; }
.swal-content { padding: 0 6px; margin-top: 16px; }
.swal-footer { display: flex; gap: 10px; padding: 0 6px; margin-top: 20px; border-top: 0; background: none; }
.swal-button-container { flex: 1 1 0; margin: 0; }
.swal-button { width: 100%; border-radius: 12px; padding: 11px 16px; font-size: .95rem; font-weight: 600; letter-spacing: 0; box-shadow: none; }
.swal-button:focus { box-shadow: 0 0 0 3px rgba(var(--agx-green-rgb), .25); }
.swal-button.btn-light { background: #eef2ef !important; color: #2f3d35 !important; border: 0 !important; }
.swal-button.btn-light:hover { background: #e2e8e4 !important; }
.swal-button.btn-danger { background: linear-gradient(180deg, #e2563f, #c63d2b) !important; color: #fff !important; border: 0 !important; }
.swal-button.btn-danger:hover { background: linear-gradient(180deg, #c63d2b, #ab3121) !important; }
.swal-button.btn-danger:focus { box-shadow: 0 0 0 3px rgba(198, 61, 43, .25); }
.agx-dialog-fields { display: grid; gap: 12px; text-align: left; }
.agx-dialog-field label { display: block; font-size: .82rem; font-weight: 600; color: #3d4d44; margin-bottom: 5px; }
.agx-dialog-field .form-control { border-radius: 12px; padding: .7rem .9rem; font-size: .95rem; border: 1px solid #d5ddd8; }
.agx-dialog-field .form-control:focus { border-color: var(--agx-green); box-shadow: 0 0 0 3px rgba(var(--agx-green-rgb), .15); }
@media (max-width: 420px) { .swal-footer { flex-direction: column-reverse; } }

body.theme-dark .swal-modal { background: #1d242d; box-shadow: 0 30px 70px -22px rgba(0, 0, 0, .7); }
body.theme-dark .swal-title { color: #eef3f7; }
body.theme-dark .swal-text { color: #a9b4c2; }
body.theme-dark .swal-icon--success:before, body.theme-dark .swal-icon--success:after, body.theme-dark .swal-icon--success__hide-corners { background: #1d242d; }
body.theme-dark .swal-icon--info, body.theme-dark .swal-icon--info:before, body.theme-dark .swal-icon--info:after { border-color: #8fd49a; }
body.theme-dark .swal-icon--info:before, body.theme-dark .swal-icon--info:after { background-color: #8fd49a; }
body.theme-dark .swal-button.btn-light { background: #2a333e !important; color: #dfe6ee !important; }
body.theme-dark .swal-button.btn-light:hover { background: #333d4a !important; }
body.theme-dark .agx-dialog-field label { color: #c3ccd6; }
body.theme-dark .agx-dialog-field .form-control { background: #151b22; border-color: #343e4a; color: #eef3f7; }

.modal-backdrop { --bs-backdrop-bg: #061810; --bs-backdrop-opacity: .45; backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); }
.modal-content { border: 0; border-radius: 20px; box-shadow: 0 30px 70px -24px rgba(6, 24, 16, .5); }
.modal-header { border-bottom: 1px solid rgba(15, 42, 29, .07); padding: 1.1rem 1.4rem; }
.modal-header .modal-title { font-weight: 700; }
.modal-body { padding: 1.2rem 1.4rem; }
.modal-footer { border-top: 0; padding: .4rem 1.4rem 1.25rem; gap: .5rem; }
.modal-footer > * { margin: 0; }
.modal-header .btn-close { border-radius: 50%; padding: .55rem; opacity: .55; transition: background-color .15s ease, opacity .15s ease; }
.modal-header .btn-close:hover { opacity: .9; background-color: rgba(15, 42, 29, .08); }
.modal.fade .modal-dialog { transform: translateY(14px) scale(.97); transition: transform .26s cubic-bezier(.2, .8, .3, 1.05), opacity .2s ease; }
.modal.show .modal-dialog { transform: none; }
body.theme-dark .modal-content { box-shadow: 0 30px 70px -22px rgba(0, 0, 0, .7); }
body.theme-dark .modal-header { border-bottom-color: rgba(255, 255, 255, .07); }
body.theme-dark .modal-header .btn-close:hover { background-color: rgba(255, 255, 255, .1); }
@media (prefers-reduced-motion: reduce) {
  .swal-overlay--show-modal .swal-modal { animation: none; }
  .modal.fade .modal-dialog { transition: none; }
}

/* "Your current plan" card on Subscription, for a farm not on one of the plans for sale (subscription-modules.js). */
.current-setup { --cs-accent: var(--agx-green); --cs-soft: rgba(var(--agx-green-rgb), .08); --cs-muted: #5f7180; --cs-tile: #f6f9f7; border-radius: 18px !important; border-width: 2px !important; border-color: rgba(var(--agx-green-rgb), .55) !important; }
body.theme-dark .current-setup { --cs-accent: #8fd49a; --cs-soft: rgba(143, 212, 154, .1); --cs-muted: #a3b1bf; --cs-tile: rgba(255, 255, 255, .03); border-color: rgba(143, 212, 154, .4) !important; }
.current-setup .card-body { padding: 1.4rem 1.5rem; text-align: left; }
.current-setup .cs-head { display: flex; align-items: flex-start; gap: .9rem; flex-wrap: wrap; }
.current-setup .pc-icon { flex: 0 0 auto; width: 48px; height: 48px; border-radius: 14px; display: inline-flex; align-items: center; justify-content: center; background: var(--cs-soft); color: var(--cs-accent); }
.current-setup .pc-icon .mdi { font-size: 1.6rem; line-height: 1; }
.current-setup .cs-kicker { font-size: .72rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--cs-accent); display: flex; align-items: center; gap: .3rem; }
.current-setup .cs-name { font-size: 1.35rem; font-weight: 700; margin: .15rem 0 .2rem; }
.current-setup .cs-sub { color: var(--cs-muted); font-size: .9rem; margin: 0; }
.current-setup .pc-status { display: inline-flex; align-items: center; gap: .35rem; font-size: .8rem; font-weight: 700; padding: .35rem .8rem; border-radius: 999px; white-space: nowrap; }
.current-setup .pc-status.is-active { background: var(--cs-soft); color: var(--cs-accent); }
.current-setup .pc-status.is-trial { background: rgba(227, 154, 27, .12); color: #a86a06; }
.current-setup .pc-status.is-due { background: rgba(198, 61, 43, .1); color: #b5382a; }
body.theme-dark .current-setup .pc-status.is-trial { color: #f2c063; }
body.theme-dark .current-setup .pc-status.is-due { color: #f08a7c; }
.current-setup .cs-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: .6rem; margin: 1.1rem 0; }
.current-setup .cs-fact { background: var(--cs-tile); border: 1px solid rgba(15, 42, 29, .06); border-radius: 12px; padding: .65rem .85rem; }
body.theme-dark .current-setup .cs-fact { border-color: rgba(255, 255, 255, .06); }
.current-setup .cs-fact span { display: block; font-size: .75rem; color: var(--cs-muted); }
.current-setup .cs-fact strong { font-size: 1.05rem; }
.current-setup .cs-fact small { font-weight: 500; color: var(--cs-muted); }
.current-setup .pc-sub { font-size: .78rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--cs-muted); margin-bottom: .5rem; }
.current-setup .pc-included-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: .45rem .8rem; }
.current-setup .pc-included-grid li { display: flex; align-items: flex-start; gap: .45rem; font-size: .9rem; line-height: 1.3; }
.current-setup .pc-included-grid .mdi { font-size: 1.1rem; line-height: 1; color: var(--cs-accent); }
.current-setup .cs-note { margin-top: 1rem; font-size: .85rem; color: var(--cs-muted); }

/* Compact plan cards (Subscription): a row of plans fits on one screen — shorter photo, two-line description,
   smaller price, the limits as one slim row (What's included unchanged) and Rongwa as a single add-on row
   (she is introduced once above the plans, .rongwa-intro). */
.pricing-table .pricing-card .card.plan-card { padding: 1.1rem 1.15rem 1.05rem !important; }
.plan-card { gap: .75rem; border-radius: 18px !important; }
.plan-card .pc-art { width: 38%; height: 112px; border-bottom-left-radius: 90px 100%; }
.plan-card .pc-top { padding-right: 34%; min-height: 0; }
.plan-card .pc-badge { font-size: .66rem; padding: .25rem .65rem; margin-bottom: .45rem; }
.plan-card .pc-title { gap: .45rem; }
.plan-card .pc-title h3 { font-size: 1.4rem; }
.plan-card .pc-icon, .plan-card .pc-icon .mdi { font-size: 1.55rem; }
.plan-card .pc-tagline { font-size: .9rem; margin-top: .2rem; }
.plan-card .pc-desc { font-size: .82rem; line-height: 1.45; margin-top: .3rem; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.plan-card .pc-amount { font-size: 2rem; }
.plan-card .pc-amount-sm { font-size: 1.45rem; }
.plan-card .pc-per { font-size: .9rem; }
.plan-card .pc-limits { gap: .35rem; }
.plan-card .pc-limit { padding: .45rem .25rem .4rem; border-radius: 11px; }
.plan-card .pc-limit-ic { margin-bottom: .15rem; }
.plan-card .pc-limit-ic .mdi { font-size: 1.15rem; }
.plan-card .pc-limit strong { font-size: 1rem; }
.plan-card .pc-limit span { font-size: .72rem; line-height: 1.2; }
.plan-card .pc-limit small { font-size: .64rem; line-height: 1.2; }
.plan-card .pc-btn { padding: .55rem .8rem; border-radius: 12px; }

.plan-card .plan-rongwa { padding: .6rem .7rem; border-radius: 12px; }
.plan-rongwa-row { display: flex; align-items: center; gap: .5rem; }
.plan-rongwa .plan-rongwa-avatar { width: 1.9rem; height: 1.9rem; }
.plan-rongwa .plan-rongwa-avatar .mdi { font-size: 1.1rem; }
.plan-rongwa-label { margin: 0; font-size: .82rem; font-weight: 700; white-space: nowrap; }
.plan-rongwa .js-rw-select { flex: 1 1 auto; min-width: 0; font-size: .78rem; border-radius: 9px; border-color: var(--pc-line); background-color: transparent; color: inherit; padding-top: .25rem; padding-bottom: .25rem; }
body.theme-dark .plan-rongwa .js-rw-select option { background: #101d24; }
.plan-rongwa-foot { margin-top: .45rem; justify-content: space-between; }
.plan-rongwa .plan-rongwa-note { margin: 0; gap: .4rem; min-width: 0; }
.plan-rongwa .plan-rongwa-save { font-size: .72rem; padding: .12rem .5rem; }
.plan-rongwa .plan-rongwa-together { font-size: .74rem; }
.plan-rongwa-add { flex: 0 0 auto; border-radius: 9px; padding: .2rem .65rem; font-size: .78rem; font-weight: 700; }

.rongwa-intro { display: flex; align-items: center; gap: .75rem; text-align: left; font-size: .88rem; line-height: 1.45; color: #4e5f6c;
  padding: .7rem 1rem; margin-bottom: 1rem; border-radius: 14px; background: rgba(var(--agx-green-rgb), .06); border: 1px solid rgba(var(--agx-green-rgb), .14); }
.rongwa-intro strong { color: #14301f; }
body.theme-dark .rongwa-intro { color: #a3b1bf; background: rgba(143, 212, 154, .06); border-color: rgba(143, 212, 154, .14); }
body.theme-dark .rongwa-intro strong { color: #eef3f7; }
.rongwa-intro .plan-rongwa-avatar { width: 2.3rem; height: 2.3rem; }
.rongwa-intro .plan-rongwa-avatar .mdi { font-size: 1.3rem; }

@media (max-width: 575.98px) {
  .plan-card .pc-art { width: 36%; height: 100px; }
  .plan-card .pc-top { padding-right: 36%; }
  .plan-card .pc-title h3 { font-size: 1.3rem; }
  .plan-card .pc-amount { font-size: 1.8rem; }
  .plan-card .pc-limits { grid-template-columns: repeat(var(--pc-n, 4), minmax(0, 1fr)); }
}

/* Animals list: tighter cells, long text wraps, and the row actions stay on one line as small round icon buttons. */
#livestock-table > thead > tr > th, #livestock-table > tbody > tr > td { padding: .65rem .6rem; vertical-align: middle; }
#livestock-table td { white-space: normal; }
#livestock-table td:first-child { white-space: nowrap; }
#livestock-table .agx-row-actions { width: 1%; white-space: nowrap; }
.agx-row-actions-inner { display: flex; align-items: center; gap: .35rem; }
.agx-icon-btn { width: 34px; height: 34px; padding: 0 !important; border-radius: 50% !important; display: inline-flex; align-items: center; justify-content: center; }
.agx-icon-btn .mdi { font-size: 1.05rem; line-height: 1; margin: 0; }

/* House Climate (house-climate.js) ------------------------------------------------------------------------------- */
.hc-card { border: 1px solid transparent; cursor: pointer; transition: box-shadow .15s, border-color .15s; height: 100%; }
.hc-card:hover, .hc-card.is-selected { border-color: #2e7d32; box-shadow: 0 6px 18px rgba(46, 125, 50, .15); }
.hc-card.hc-alert { border-left: 5px solid #c62828; }
.hc-card.hc-ok { border-left: 5px solid #2e7d32; }
.hc-card.hc-stale { border-left: 5px solid #f4b942; }
.hc-card.hc-none { border-left: 5px solid #b0bec5; }
.hc-status { font-size: .78rem; font-weight: 700; padding: .25rem .6rem; border-radius: 999px; white-space: nowrap; background: #eceff1; color: #455a64; }
.hc-ok .hc-status { background: #e8f5e9; color: #1b5e20; }
.hc-alert .hc-status { background: #ffebee; color: #b71c1c; }
.hc-stale .hc-status { background: #fff6e0; color: #8a5a00; }
.hc-now { display: grid; grid-template-columns: repeat(3, 1fr); gap: .5rem; margin: 1rem 0 .5rem; }
.hc-now > div { background: #F8F4EA; border-radius: 12px; padding: .6rem .5rem; text-align: center; }
.hc-big { display: block; font-size: 1.7rem; font-weight: 800; line-height: 1.1; color: #0a3d2a; }
.hc-big small { font-size: .9rem; font-weight: 600; margin-left: 1px; }
.hc-big.hc-nh3 { font-size: 1.05rem; padding: .35rem 0 .25rem; }
.hc-alert .hc-big { color: #b71c1c; }
.hc-lbl { display: block; font-size: .72rem; color: #6c757d; text-transform: uppercase; letter-spacing: .04em; }
.hc-problems { background: #ffebee; color: #b71c1c; border-radius: 10px; padding: .45rem .7rem; font-size: .85rem; font-weight: 600; margin-bottom: .4rem; }
.hc-spark { min-height: 34px; }
.hc-chart { height: 300px; }
.hc-stat { display: flex; gap: .6rem; align-items: center; background: #F8F4EA; border-radius: 12px; padding: .7rem .8rem; }
.hc-stat i { font-size: 1.5rem; color: #2e7d32; }
.hc-stat span { display: block; font-size: .75rem; color: #6c757d; }
.hc-stat strong { font-size: 1.05rem; color: #0a3d2a; }
.hc-outlook { border-left: 5px solid #f4a261; }
.hc-outlook-item { display: flex; gap: .7rem; padding: .55rem 0; border-top: 1px solid #f0ebe0; }
.hc-outlook-item:first-of-type { border-top: 0; }
.hc-outlook-item > i { font-size: 1.6rem; line-height: 1; }
.hc-outlook-item.is-hot > i { color: #e76f51; }
.hc-outlook-item.is-cold > i { color: #1e88e5; }
.hc-stepper { display: flex; align-items: stretch; gap: .5rem; }
.hc-stepper .btn { width: 64px; font-size: 1.6rem; border-radius: 14px; }
.hc-stepper-value { flex: 1; display: flex; align-items: center; justify-content: center; gap: .25rem; border: 1.5px solid #dfe5e2; border-radius: 14px; padding: .35rem .6rem; }
.hc-stepper-value input { border: 0; width: 100%; max-width: 140px; text-align: center; font-size: 2rem; font-weight: 800; color: #0a3d2a; background: transparent; outline: none; }
.hc-stepper-value span { font-size: 1.1rem; font-weight: 700; color: #6c757d; }
.hc-chips { display: flex; flex-wrap: wrap; gap: .45rem; }
.hc-chip { border: 1.5px solid #dfe5e2; background: #fff; border-radius: 999px; padding: .45rem .9rem; font-weight: 600; font-size: .9rem; color: #26465d; }
.hc-chip.active { background: #2e7d32; border-color: #2e7d32; color: #fff; }
.hc-preset-group { margin-bottom: .6rem; }
.hc-preset-group > span { display: block; font-size: .75rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: #6c757d; margin-bottom: .3rem; }
.hc-empty-icon { width: 76px; height: 76px; margin: 0 auto; border-radius: 50%; display: grid; place-items: center; background: #e8f5e9; color: #2e7d32; font-size: 2.4rem; }
body.theme-dark .hc-now > div, body.theme-dark .hc-stat { background: #232b33; }
body.theme-dark .hc-big, body.theme-dark .hc-stat strong, body.theme-dark .hc-stepper-value input { color: #e8eef3; }
body.theme-dark .hc-chip { background: #1d242d; color: #e8eef3; border-color: #36414b; }
.hc-search { display: flex; align-items: center; gap: .4rem; border: 1.5px solid #dfe5e2; border-radius: 999px; padding: .3rem .8rem; min-width: 240px; flex: 1 1 240px; max-width: 360px; }
.hc-search input { border: 0; outline: none; background: transparent; width: 100%; }
.hc-chip span { font-weight: 500; opacity: .75; }
/* Climate of the place an animal lives or a crop grows (zone-climate-chip.js) */
.zc-panel { display: flex; align-items: center; gap: .8rem; flex-wrap: wrap; border-radius: 14px; padding: .75rem 1rem; margin-bottom: 1rem; background: #F8F4EA; border-left: 5px solid #b0bec5; }
.zc-panel > i { font-size: 1.8rem; color: #2e7d32; }
.zc-panel > div:first-of-type { flex: 1 1 220px; }
.zc-panel strong { display: block; color: #0a3d2a; }
.zc-panel span { font-size: .9rem; color: #455a64; }
.zc-panel em { display: block; font-style: normal; font-size: .85rem; color: #b71c1c; font-weight: 600; }
.zc-panel .zc-actions { display: flex; gap: .4rem; }
.zc-ok { border-left-color: #2e7d32; }
.zc-alert { border-left-color: #c62828; background: #fff5f5; }
.zc-alert > i { color: #c62828; }
.zc-stale { border-left-color: #f4b942; }
body.theme-dark .zc-panel { background: #232b33; }
body.theme-dark .zc-panel strong { color: #e8eef3; }
body.theme-dark .zc-panel span { color: #b0bec5; }
#hc-detail-weather .hc-outlook { background: #fff8ef; border-radius: 12px; padding: .8rem 1rem; }
body.theme-dark #hc-detail-weather .hc-outlook { background: rgba(244, 162, 97, .12); }
/* Weather warnings: about three show, the rest scroll inside the box. */
.hc-outlook-list { max-height: 15.5rem; overflow-y: auto; overscroll-behavior: contain; padding-right: .35rem; }
@media (max-width: 575.98px) { .hc-outlook-list { max-height: 19rem; } }
/* Climate: Weather Forecast / Indoor Climate switch */
.climate-switch { display: flex; width: fit-content; gap: .25rem; padding: .25rem; background: #fff; border: 1px solid #e6dfcf; border-radius: 999px; max-width: 100%; }
.climate-switch a { display: inline-flex; align-items: center; gap: .35rem; padding: .45rem 1rem; border-radius: 999px; color: #4a5560; text-decoration: none; font-weight: 600; font-size: .9rem; white-space: nowrap; }
.climate-switch a:hover { background: #f3efe4; color: #1b5e20; }
.climate-switch a.active { background: #2e7d32; color: #fff; }
.climate-switch a i { font-size: 1.1rem; }
@media (max-width: 575.98px) { .climate-switch { width: 100%; } .climate-switch a { flex: 1; justify-content: center; padding: .45rem .5rem; font-size: .85rem; } }
body.theme-dark .climate-switch { background: #1d242d; border-color: #36414b; }
body.theme-dark .climate-switch a { color: #c9d3dc; }
body.theme-dark .climate-switch a:hover { background: #26303a; color: #fff; }
body.theme-dark .climate-switch a.active { background: #2e7d32; color: #fff; }
/* Batch weigh-in: weights typed one by one, and the live figures */
.wb-list { display: flex; flex-wrap: wrap; gap: .35rem; max-height: 9.5rem; overflow-y: auto; }
.wb-weight { border: 1px solid #d9e3d5; background: #f3f8f1; color: #1b5e20; border-radius: 999px; padding: .2rem .6rem; font-size: .85rem; font-weight: 600; }
.wb-weight i { opacity: .55; }
.wb-weight:hover { background: #fdecea; border-color: #f2b8b5; color: #b71c1c; }
.wb-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr)); gap: .5rem; }
.wb-stats > div { background: #f6f2e8; border-radius: 10px; padding: .5rem .7rem; }
.wb-stats strong { display: block; font-size: 1.1rem; color: #14391f; }
.wb-stats span { font-size: .75rem; color: #6c757d; }
body.theme-dark .wb-weight { background: #1d2a22; border-color: #2f4a37; color: #a5d6a7; }
body.theme-dark .wb-stats > div { background: #232b33; }
body.theme-dark .wb-stats strong { color: #e8eef3; }
/* Dashboard band headings (Farm Overview, Crops, Livestock, Platform Modules) in the dark theme, like the card titles */
body.theme-dark .viz-band-head h5 { color: #e8eef3; }
body.theme-dark .viz-band-icon { background: rgba(102, 187, 106, .16); color: #81c784; }

/* Dropdowns the same height and look as the text fields beside them. The theme gave select.form-control half the
   padding, no border and no arrow; Bootstrap's .form-select is smaller still. Small (-sm), multi-line and table
   filter selects keep their own size. */
select.form-control:not(.form-control-sm):not([multiple]):not([size]),
.form-select:not(.form-select-sm):not([multiple]):not([size]) {
  padding: calc(1.2rem + 2px) 2.75rem calc(1.2rem + 2px) 1.375rem;
  line-height: 1;
  height: auto;
  border: 1px solid #f3f3f3;
  outline: 0;
  color: var(--bs-body-color);
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%236c757d' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
  background-repeat: no-repeat;
  background-position: right 1.1rem center;
  background-size: 14px 10px;
}
body.theme-dark select.form-control:not(.form-control-sm):not([multiple]):not([size]),
body.theme-dark .form-select:not(.form-select-sm):not([multiple]):not([size]) {
  padding-top: calc(.875rem + 2px);
  padding-bottom: calc(.875rem + 2px);
  border-color: #414561;
  color: #e9e6e6;
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23aaa7a7' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
}

/* Pagination, everywhere: centred, "Showing 1 to 10 of 33 entries" above the rounded page pills (agricore-pagination.js
   and every DataTables table). */
.agx-pager { width: 100%; display: flex; flex-direction: column; align-items: center; gap: .6rem; padding-top: .5rem; }
.agx-pager .pagination, .dataTables_wrapper .dataTables_paginate .pagination { justify-content: center !important; flex-wrap: wrap; row-gap: .4rem; margin: 0; }
.dataTables_wrapper .row:has(> div > .dataTables_paginate) > div { flex: 0 0 100%; max-width: 100%; }
.dataTables_wrapper .dataTables_info, .dataTables_wrapper .dataTables_paginate { float: none !important; text-align: center !important; width: 100%; }
.dataTables_wrapper .dataTables_info { padding-top: .75rem !important; }
.dataTables_wrapper .dataTables_paginate { margin-top: .5rem !important; display: flex; justify-content: center; }
.pagination .page-link .mdi { font-size: 1.15rem; line-height: 1; vertical-align: middle; }
