/* ==================================================================
   AgriMind — styles.css  (v2.3 design system: "Premium Organic
   Intelligence")

   Brand: deep field green + warm cream, kept from v1, refined for a
   calm, premium, farmer-friendly look, plus one warm gold accent used
   sparingly for highlights. Visual balance across the app is meant to
   read as roughly 70% premium organic design (warm surfaces, soft
   depth, generous spacing), 20% smart agricultural dashboard (clear
   numbers, honest status labels, real data) and 10% friendly AI
   assistant (the chat avatar, the Living Farm Hero, gentle motion).
   - Fonts are self-hosted (Manrope, Noto Sans Bengali, Noto Sans SC),
     not loaded from a CDN, so the app still opens with no network and
     without a VPN; each file is subset to only the characters the app
     actually uses to keep it small. System fonts remain as a fallback
     for the instant before the cached files apply.
   - Mobile-first: designed at 360 to 430 px, a sidebar layout from
     960 px for laptops, and a widened ~1160px dashboard from 1200 px
     for larger desktop monitors.
   - Every animation is switched off for people who ask their phone
     for "reduced motion". See DESIGN_SYSTEM.md for the full motion
     timing table and usage rules.
   ================================================================== */

/* ---------- 1. Design tokens ---------- */
:root {
  --green-950: #123120;
  --green-900: #1C4835;
  --green-800: #24573F;
  --green-700: #2F6B4F; /* primary brand green (unchanged) */
  --green-600: #3B7F5D;
  --green-500: #4E9570;
  --green-200: #CFE5D6;
  --green-100: #E3F0E7;
  --green-50: #F0F7F2;

  --cream: #F7F5EF;     /* app background (unchanged) */
  --cream-200: #EFEBE0;
  --surface: #FFFFFF;
  --surface-tint: #FBFAF6;
  --line: #E6E1D5;
  --line-soft: #EFEBE1;

  --ink: #16211A;       /* main text, slightly deepened for contrast */
  --ink-2: #4A564D;     /* secondary text */
  --ink-3: #626C63;     /* muted text (still 4.5:1 on cream) */

  --amber-700: #9A5A0E; --amber-100: #FBE9CC; --amber-50: #FDF4E3;
  --blue-700: #2B65A8;  --blue-100: #E3EEFA;  --blue-50: #F1F6FD;
  --red-700: #B23B33;   --red-100: #FBE7E5;   --red-50: #FDF3F2;
  --purple-700: #6A3FA0; --purple-100: #EFE7FB;
  --sun: #C77B1E;

  /* Signature accent: warm harvest gold, used sparingly for one
     premium highlight per screen (never for large fills). */
  --gold-700: #96690E;
  --gold-500: #C9922C;
  --gold-100: #F5E6C6;
  --gold-50: #FAF1DE;

  /* Semantic status tokens: every status also carries an icon or text
     label elsewhere in the markup, so colour is never the only signal. */
  --status-success: var(--green-700);
  --status-success-bg: var(--green-100);
  --status-warning: var(--amber-700);
  --status-warning-bg: var(--amber-100);
  --status-danger: var(--red-700);
  --status-danger-bg: var(--red-100);
  --status-info: var(--blue-700);
  --status-info-bg: var(--blue-100);
  --status-live: #237A4B;
  --status-live-bg: var(--green-100);
  --status-saved: var(--blue-700);
  --status-saved-bg: var(--blue-100);
  --status-demo: var(--amber-700);
  --status-demo-bg: var(--amber-100);
  --status-offline: #6B6555;
  --status-offline-bg: var(--cream-200);

  --radius-sm: 10px;
  --radius: 16px;
  --radius-lg: 22px;
  --radius-xl: 28px;
  --shadow-sm: 0 1px 2px rgba(20, 30, 24, 0.07);
  --shadow: 0 2px 4px rgba(20, 30, 24, 0.05), 0 10px 28px rgba(20, 30, 24, 0.08);
  --shadow-lg: 0 24px 68px rgba(18, 28, 22, 0.2);
  --shadow-gold: 0 10px 26px rgba(150, 105, 14, 0.22);
  --shadow-press: 0 1px 1px rgba(20, 30, 24, 0.08) inset;

  --font: "Manrope", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-bn: "Noto Sans Bengali", "Hind Siliguri", "Kohinoor Bangla", "Bangla Sangam MN", "Nirmala UI", system-ui, sans-serif;
  --font-zh: "Noto Sans SC", "PingFang SC", "Microsoft YaHei", "Heiti SC", system-ui, sans-serif;

  /* Typography scale: a clearer step between display numbers, section
     headings, body text and small metadata (used across Home, Weather,
     Crop Scan and Market so the most important number always reads
     first). Line heights are tuned per script below (2.). */
  --fs-display: 34px;   /* one big number per screen: hero temp, hero title */
  --fs-h1: 20px;        /* screen/topbar title */
  --fs-h2: 17px;        /* card/section title */
  --fs-body: 15px;      /* default reading text */
  --fs-meta: 12.5px;    /* timestamps, source lines, captions */

  --nav-h: 68px;
  --dock-gap: 10px;     /* space between the floating nav dock and the screen edge */
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --ease: cubic-bezier(0.2, 0.8, 0.2, 1);
  --ease-spring: cubic-bezier(0.34, 1.35, 0.4, 1);

  /* Motion system: see DESIGN_SYSTEM.md for the full table.
     button 140ms · page 260ms · card 320ms · stagger 40ms · toast 220ms */
  --dur-fast: 0.14s;   /* button feedback, presses */
  --dur: 0.26s;        /* page/tab transitions */
  --dur-card: 0.32s;   /* card/result entrance */
  --dur-toast: 0.22s;  /* toast/notice entrance */
  --dur-slow: 0.42s;   /* splash-scale flourishes only */
  --stagger-step: 40ms;
}

/* Self-hosted fonts. Subset to the characters this app actually shows
   (Latin + Bengali + the Chinese used in translated content), so each
   file stays small; cached by the service worker for offline use. */
@font-face {
  font-family: "Manrope";
  src: url("fonts/manrope-var.woff2") format("woff2-variations"), url("fonts/manrope-var.woff2") format("woff2");
  font-weight: 400 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Noto Sans Bengali";
  src: url("fonts/noto-sans-bengali-var.woff2") format("woff2-variations"), url("fonts/noto-sans-bengali-var.woff2") format("woff2");
  font-weight: 400 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Noto Sans SC";
  src: url("fonts/noto-sans-sc-subset.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

/* ---------- 2. Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}
h1, h2, h3, p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }
a { color: inherit; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; padding: 0; }
img { max-width: 100%; display: block; }
[hidden] { display: none !important; }

/* Each language gets its own font and the line height it reads best at. */
:lang(bn) { font-family: var(--font-bn); line-height: 1.65; letter-spacing: 0; }
:lang(zh) { font-family: var(--font-zh); line-height: 1.6; letter-spacing: 0.2px; }

.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* One icon style everywhere (see the <symbol> set in index.html) */
.icon {
  width: 20px; height: 20px; flex-shrink: 0;
  fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}

/* Keyboard focus is always clearly visible */
:focus-visible { outline: 3px solid var(--green-500); outline-offset: 2px; border-radius: 8px; }
/* Headings get focus from code when a screen opens (for screen readers) — no ring needed there */
[tabindex="-1"]:focus { outline: none; }
.skip-link {
  position: fixed; left: 12px; top: -60px; z-index: 100;
  background: var(--ink); color: #fff; padding: 10px 14px; border-radius: 10px; font-weight: 700;
  transition: top 0.2s var(--ease);
}
.skip-link:focus { top: 12px; }

/* ---------- 3. App layout ---------- */
.app { min-height: 100vh; min-height: 100dvh; }
.app-main { outline: none; }

.screen { display: none; min-height: 100vh; min-height: 100dvh; padding-bottom: calc(var(--nav-h) + var(--dock-gap) * 2 + var(--safe-bottom) + 22px); }
.screen.active { display: block; animation: screen-in var(--dur-slow) var(--ease); }
@keyframes screen-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
/* Directional transition between tabs, set by app.js from the nav order
   (forward = moving right through Home -> Scan -> Ask -> Market -> Weather;
   back = the reverse). Falls back to the plain fade above when unset. */
.screen.active[data-dir="fwd"] { animation-name: screen-in-fwd; }
.screen.active[data-dir="back"] { animation-name: screen-in-back; }
@keyframes screen-in-fwd { from { opacity: 0; transform: translateX(18px); } to { opacity: 1; transform: none; } }
@keyframes screen-in-back { from { opacity: 0; transform: translateX(-18px); } to { opacity: 1; transform: none; } }

/* Staggered entrance for list items: app.js sets the --i custom property
   (0, 1, 2 ...) on each card/row as it renders the list. Only the first
   screenful staggers (app.js caps --i so a long list does not keep
   animating for seconds after it is visible). */
.stagger-in { animation: card-in var(--dur-card) var(--ease) both; animation-delay: calc(var(--i, 0) * var(--stagger-step)); }

.screen-body { padding: 16px 16px 8px; display: flex; flex-direction: column; gap: 16px; max-width: 760px; margin: 0 auto; }

/* Sticky top bar on inner screens */
.topbar {
  position: sticky; top: 0; z-index: 10;
  display: flex; align-items: center; gap: 12px;
  padding: calc(12px + env(safe-area-inset-top, 0px)) 16px 12px;
  background: rgba(247, 245, 239, 0.88);
  -webkit-backdrop-filter: saturate(160%) blur(12px);
  backdrop-filter: saturate(160%) blur(12px);
  border-bottom: 1px solid transparent;
}
.topbar-text { flex: 1; min-width: 0; }
.topbar-title { font-size: 19px; font-weight: 700; letter-spacing: -0.2px; line-height: 1.25; }
.topbar-sub { font-size: 12.5px; font-weight: 500; color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.icon-btn {
  width: 44px; height: 44px; border-radius: 14px; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--surface); border: 1px solid var(--line); color: var(--ink);
  transition: transform var(--dur-fast) var(--ease), background 0.2s;
}
.icon-btn:active { transform: scale(0.95); box-shadow: var(--shadow-press); }

/* Compact language button on inner-screen topbars, so switching
   language never requires going back to Home first (mobile has no
   room there for the full three-way switch used on Home/desktop).
   Tapping it cycles EN -> বাং -> 中文 -> EN; the aria-label always
   names the language it will switch TO next. */
.topbar-lang {
  width: 38px; height: 38px; border-radius: 12px; flex-shrink: 0;
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 0;
  background: var(--surface); border: 1px solid var(--line); color: var(--green-800);
  font-size: 9px; font-weight: 800; letter-spacing: 0.2px;
  transition: transform var(--dur-fast) var(--ease), background 0.2s;
}
.topbar-lang .icon { width: 15px; height: 15px; }
.topbar-lang:active { transform: scale(0.95); }
@media (max-width: 374px) { .topbar-lang .topbar-lang-code { display: none; } }
@media (min-width: 960px) { .topbar-lang { display: none; } }

/* Language switcher: a small three-way control (EN / বাং / 中文). */
.lang-switch {
  display: inline-flex; align-items: center; gap: 2px; flex-shrink: 0;
  background: var(--surface); border: 1px solid var(--line); border-radius: 999px; padding: 3px;
}
.lang-btn {
  min-width: 34px; min-height: 34px; padding: 0 9px; border-radius: 999px;
  font-size: 12.5px; font-weight: 700; color: var(--ink-3);
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.lang-btn:active { transform: scale(0.92); }
.lang-btn[aria-pressed="true"] { background: var(--green-700); color: #fff; }
.lang-switch-lg .lang-btn { min-width: 46px; min-height: 40px; font-size: 13.5px; }

/* Brief crossfade on the main content when the active language changes. */
.lang-swap { animation: lang-swap var(--dur) var(--ease); }
@keyframes lang-swap { from { opacity: 0.35; } to { opacity: 1; } }

/* ---------- 4. Navigation: premium floating dock on phones ----------
   A rounded, elevated bar with a visible gap to every edge (so it
   reads as an object floating over the content, not a flush system
   bar), lifted clear of the iPhone/Android home-indicator safe area.
   .screen padding-bottom above keeps content from ever running under
   it. app.js toggles .app-nav.is-kb-hidden while a text field has
   focus on a narrow viewport, so the dock never sits on top of the
   on-screen keyboard. */
.app-nav {
  position: fixed; left: var(--dock-gap); right: var(--dock-gap);
  bottom: calc(var(--dock-gap) + var(--safe-bottom)); z-index: 30;
  height: var(--nav-h);
  border-radius: 22px;
  background: rgba(255, 255, 255, 0.96);
  -webkit-backdrop-filter: saturate(180%) blur(16px);
  backdrop-filter: saturate(180%) blur(16px);
  border: 1px solid var(--line);
  box-shadow: 0 12px 30px rgba(18, 28, 22, 0.16), 0 2px 8px rgba(18, 28, 22, 0.08);
  display: flex; align-items: stretch;
  transition: transform 0.22s var(--ease), opacity 0.2s var(--ease);
}
.app.is-splash .app-nav { display: none; }
.app-nav.is-kb-hidden { transform: translateY(calc(100% + var(--dock-gap) + var(--safe-bottom) + 12px)); opacity: 0; pointer-events: none; }
.nav-brand, .nav-foot { display: none; }
.nav-items { flex: 1; display: flex; align-items: stretch; justify-content: space-around; padding: 0 6px; }
.nav-item {
  flex: 1; min-width: 0; min-height: 48px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  color: var(--ink-3); font-size: 11px; font-weight: 600; position: relative;
  transition: color 0.2s;
}
.nav-item .nav-icon {
  width: 50px; height: 30px; border-radius: 999px;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.25s var(--ease), transform var(--dur-fast) var(--ease);
}
.nav-item .icon { width: 22px; height: 22px; }
.nav-item[aria-current="page"] { color: var(--green-800); }
.nav-item[aria-current="page"] .nav-icon { background: var(--green-100); }
.nav-item:active .nav-icon { transform: scale(0.92); }
.nav-item.desktop-only { display: none; }

/* ---------- 5. Buttons, chips, pills ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 46px; padding: 10px 18px; border-radius: 14px;
  font-size: 15px; font-weight: 700; line-height: 1.2; text-align: center;
  border: 1px solid transparent;
  transition: transform 0.15s var(--ease), background 0.2s, box-shadow 0.2s, opacity 0.2s;
}
.btn:active { transform: scale(0.98); }
.btn:disabled { opacity: 0.55; cursor: not-allowed; transform: none; }
.btn-block { width: 100%; }
.btn-lg { min-height: 54px; font-size: 16px; border-radius: 16px; }
.btn-sm { min-height: 38px; padding: 6px 12px; font-size: 13.5px; border-radius: 12px; }
.btn-sm .icon { width: 17px; height: 17px; }
.btn-primary { background: var(--green-700); color: #fff; box-shadow: 0 6px 16px rgba(47, 107, 79, 0.25); }
.btn-primary:hover { background: var(--green-800); }
.btn-secondary { background: var(--green-100); color: var(--green-800); }
.btn-secondary:hover { background: var(--green-200); }
.btn-ghost { background: var(--surface); color: var(--ink); border-color: var(--line); }
.btn-ghost:hover { background: var(--cream-200); }
.btn-danger { background: var(--red-50); color: var(--red-700); border-color: var(--red-100); }
.btn-danger:hover { background: var(--red-100); }
.btn-cream { background: var(--cream); color: var(--green-900); box-shadow: var(--shadow-gold); }
.btn-row { display: flex; gap: 10px; flex-wrap: wrap; }
.btn-row > .btn { flex: 1 1 140px; }
.btn-row-wrap > .btn { white-space: nowrap; }

.text-btn {
  display: inline-flex; align-items: center; gap: 6px; min-height: 40px;
  color: var(--green-700); font-size: 14px; font-weight: 700;
}
.text-btn .icon { width: 17px; height: 17px; }
.link-btn {
  display: inline-flex; align-items: center; gap: 4px; margin-top: 10px; min-height: 40px;
  color: var(--green-700); font-size: 14px; font-weight: 700;
}
.link-btn .icon { width: 16px; height: 16px; transition: transform 0.2s var(--ease); }
.link-btn:hover .icon { transform: translateX(3px); }

/* A horizontally scrolling chip row gets a soft fade + chevron hint on
   its trailing edge whenever it actually overflows (app.js toggles
   .has-overflow after measuring scrollWidth vs clientWidth, and clears
   it once the user has scrolled at all, or the row fits). */
.chip-row-wrap { position: relative; }
.chip-row-wrap.has-overflow::after {
  content: ""; position: absolute; top: 0; right: 0; bottom: 4px; width: 34px;
  background: linear-gradient(to right, rgba(255, 255, 255, 0), var(--fade-bg, var(--cream)) 78%);
  pointer-events: none;
}
.card .chip-row-wrap { --fade-bg: var(--surface); }
.chip-row {
  display: flex; gap: 8px; overflow-x: auto; padding: 2px 2px 4px;
  scrollbar-width: none; scroll-snap-type: x proximity;
}
.chip-row::-webkit-scrollbar { display: none; }
.chip-row-tight { padding: 0 2px 2px; }
.chip {
  flex-shrink: 0; scroll-snap-align: start;
  min-height: 40px; padding: 8px 15px; border-radius: 999px;
  background: var(--surface); color: var(--ink-2); border: 1px solid var(--line);
  font-size: 14px; font-weight: 600; white-space: nowrap;
  transition: background 0.2s, color 0.2s, border-color 0.2s, transform 0.15s var(--ease);
}
.chip:active { transform: scale(0.96); }
.chip[aria-pressed="true"], .chip.active { background: var(--green-700); color: #fff; border-color: var(--green-700); }

.pill {
  display: inline-flex; align-items: center; gap: 5px; flex-shrink: 0;
  font-size: 12px; font-weight: 700; line-height: 1; padding: 6px 10px; border-radius: 999px; white-space: nowrap;
  background: var(--cream-200); color: var(--ink-2);
  transition: background 0.3s, color 0.3s;
}
.pill .icon { width: 14px; height: 14px; }
.pill-live { background: var(--green-100); color: var(--green-800); }
.pill-live::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%; background: #2F9D62;
  box-shadow: 0 0 0 0 rgba(47, 157, 98, 0.5); animation: live-pulse 2s infinite;
}
@keyframes live-pulse { 70% { box-shadow: 0 0 0 6px rgba(47, 157, 98, 0); } 100% { box-shadow: 0 0 0 0 rgba(47, 157, 98, 0); } }
.pill-saved { background: var(--blue-100); color: var(--blue-700); }
.pill-demo { background: var(--amber-100); color: var(--amber-700); }
.pill-error { background: var(--red-100); color: var(--red-700); }
.pill-checking { background: var(--cream-200); color: var(--ink-3); }
.pill-conf { background: var(--green-100); color: var(--green-800); }
.pill-sev { background: var(--amber-100); color: var(--amber-700); }
.pill-row { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
/* A live AI result's pills hold text AgriMind does not control (crop/disease
   name, severity label); keep any surprisingly long value from widening the
   page on a phone instead of wrapping in place. */
#resultPills .pill { max-width: 100%; white-space: normal; line-height: 1.25; overflow-wrap: anywhere; }

/* ---------- 6. Cards & common blocks ---------- */
.card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 16px; box-shadow: var(--shadow-sm);
  animation: card-in var(--dur-card) var(--ease) both;
  transition: box-shadow 0.2s, border-color 0.2s;
}
.card:hover { box-shadow: var(--shadow); }
@keyframes card-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
/* The one card on a screen that most deserves the farmer's attention
   right now (e.g. an urgent weather advisory) — stronger emphasis is
   reserved for this, never used on every card. */
.card-primary { border-color: var(--green-200); box-shadow: 0 2px 4px rgba(20,30,24,.05), 0 14px 32px rgba(47,107,79,.14); }
.card-head { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.card-head-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
.card-eyebrow { flex: 1; font-size: 13px; font-weight: 800; letter-spacing: 0.5px; text-transform: uppercase; color: var(--gold-700); }
.card-title { font-size: 17px; font-weight: 700; letter-spacing: -0.1px; }
.muted { color: var(--ink-2); font-size: 14px; margin-bottom: 12px; }

.section-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.section-title { font-size: 17px; font-weight: 700; letter-spacing: -0.1px; }

.icon-tile {
  width: 42px; height: 42px; border-radius: 13px; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
}
.icon-tile .icon { width: 21px; height: 21px; }
.tile-lg { width: 56px; height: 56px; border-radius: 18px; }
.tile-lg .icon { width: 26px; height: 26px; }
.tile-green { background: var(--green-100); color: var(--green-700); }
.tile-amber { background: var(--amber-100); color: var(--amber-700); }
.tile-blue { background: var(--blue-100); color: var(--blue-700); }
.tile-sky { background: #E2F1F8; color: #1F6A8A; }
.tile-red { background: var(--red-100); color: var(--red-700); }
.tile-purple { background: var(--purple-100); color: var(--purple-700); }

.note {
  display: flex; gap: 8px; align-items: flex-start;
  font-size: 13.5px; font-weight: 500; color: var(--ink-2); line-height: 1.45;
  background: var(--cream); border: 1px solid var(--line); border-radius: 12px; padding: 10px 12px;
}
.note .icon { width: 18px; height: 18px; margin-top: 1px; }
.note-info { background: var(--blue-50); border-color: var(--blue-100); color: #264F7E; }
.note-live { background: var(--green-50); border-color: var(--green-100); color: var(--green-800); }
.note-demo { background: var(--amber-50); border-color: var(--amber-100); color: #7A4608; }
.note-error { background: var(--red-50); border-color: var(--red-100); color: var(--red-700); }

/* Banner-style notice at the top of a screen (demo / offline / error) */
.notice {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 12px 14px; border-radius: var(--radius); font-size: 14px; font-weight: 500; line-height: 1.45;
  animation: card-in 0.35s var(--ease) both;
}
.notice .icon { width: 20px; height: 20px; margin-top: 1px; }
.notice strong { font-weight: 700; }

/* One consistent small "empty state" illustration style used
   everywhere the app has nothing to show yet: no crops, no scan
   history, no market data, no search result, offline, or an error.
   Always the same soft circular backdrop + one line icon, never a
   large unexplained blank area. */
.empty {
  display: flex; flex-direction: column; align-items: center; gap: 10px; text-align: center;
  padding: 30px 16px; color: var(--ink-3); font-size: 14px; font-weight: 500;
}
.empty-illo {
  width: 64px; height: 64px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--cream-200);
}
.empty-illo .icon { width: 28px; height: 28px; opacity: 0.85; color: var(--ink-3); stroke-width: 1.5; }
.empty-illo.tone-info { background: var(--blue-50); } .empty-illo.tone-info .icon { color: var(--blue-700); }
.empty-illo.tone-warn { background: var(--amber-50); } .empty-illo.tone-warn .icon { color: var(--amber-700); }
.empty-illo.tone-danger { background: var(--red-50); } .empty-illo.tone-danger .icon { color: var(--red-700); }
.empty-illo.tone-green { background: var(--green-50); } .empty-illo.tone-green .icon { color: var(--green-700); }
.empty .icon { width: 28px; height: 28px; opacity: 0.7; }
.empty-title { font-size: 15px; font-weight: 700; color: var(--ink); }
.empty .btn-row { flex-direction: column; width: 100%; margin-top: 6px; }
.empty .btn-row > .btn { flex: 0 0 auto; width: 100%; }

.app-foot { text-align: center; font-size: 12px; color: var(--ink-3); padding: 8px 0 4px; }

/* Loading skeletons (gentle shimmer) */
.skeleton {
  display: block; border-radius: 10px;
  background: linear-gradient(90deg, var(--cream-200) 25%, #F6F3EB 45%, var(--cream-200) 65%);
  background-size: 300% 100%; animation: shimmer 1.4s ease-in-out infinite;
}
@keyframes shimmer { from { background-position: 100% 0; } to { background-position: 0 0; } }
.skeleton-line { height: 14px; width: 100%; margin: 6px 0; }
.skeleton-line.short { width: 60%; }
.skeleton-card { height: 72px; border-radius: var(--radius); }
.skeleton-day { flex-shrink: 0; width: 76px; height: 118px; border-radius: var(--radius); }

.spinner {
  width: 30px; height: 30px; border-radius: 50%; flex-shrink: 0;
  border: 3px solid var(--green-100); border-top-color: var(--green-700);
  animation: spin 0.8s linear infinite;
}
.spinner-sm { width: 16px; height: 16px; border-width: 2px; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- 7. Forms ---------- */
.form { display: flex; flex-direction: column; gap: 14px; }
.field { display: flex; flex-direction: column; gap: 6px; flex: 1; min-width: 0; }
.field label { font-size: 14px; font-weight: 700; color: var(--ink); line-height: 1.35; }
.field label :lang(bn) { line-height: 1.35; }
.field-row { display: flex; gap: 12px; }
.optional { font-weight: 500; color: var(--ink-3); }
.input, .select {
  width: 100%; min-height: 48px; padding: 11px 14px;
  background: var(--surface); border: 1px solid #D9D3C4; border-radius: 12px;
  font-size: 16px; /* 16px stops iPhone from zooming into the field */
  transition: border-color 0.2s, box-shadow 0.2s;
}
.input:focus, .select:focus { outline: none; border-color: var(--green-600); box-shadow: 0 0 0 3px rgba(59, 127, 93, 0.18); }
.select {
  appearance: none; -webkit-appearance: none; padding-right: 38px;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-2) 50%), linear-gradient(135deg, var(--ink-2) 50%, transparent 50%);
  background-position: calc(100% - 20px) 21px, calc(100% - 15px) 21px;
  background-size: 5px 5px; background-repeat: no-repeat;
}
.textarea { min-height: 88px; resize: vertical; line-height: 1.45; }
.input-row { display: flex; gap: 8px; }
.input-row .input { flex: 1; }
.field-hint { font-size: 13px; color: var(--ink-3); font-weight: 500; }
.field-error {
  font-size: 13.5px; font-weight: 600; color: var(--red-700);
  background: var(--red-50); border: 1px solid var(--red-100); border-radius: 10px; padding: 8px 10px;
}

/* ---------- 8. Splash ---------- */
.screen-splash.active {
  display: flex; flex-direction: column; justify-content: space-between;
  padding: calc(56px + env(safe-area-inset-top, 0px)) 24px calc(32px + var(--safe-bottom));
  background: radial-gradient(120% 80% at 80% 0%, var(--green-600) 0%, var(--green-700) 45%, var(--green-900) 100%);
  color: #fff; position: relative; overflow: hidden;
}
.splash-glow { position: absolute; border-radius: 50%; filter: blur(2px); pointer-events: none; }
.splash-glow-1 { width: 260px; height: 260px; top: -80px; right: -90px; background: rgba(255, 255, 255, 0.08); }
.splash-glow-2 { width: 320px; height: 320px; bottom: 90px; left: -140px; background: rgba(201, 146, 44, 0.16); }
.splash-inner { position: relative; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 10px; margin-top: 4vh; }
.splash-logo {
  width: 92px; height: 92px; border-radius: 28px; background: var(--cream); color: var(--green-700);
  display: flex; align-items: center; justify-content: center; margin-bottom: 10px;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.22); animation: float-in 0.7s var(--ease) both;
}
.splash-logo .icon { width: 48px; height: 48px; stroke-width: 1.6; }
@keyframes float-in { from { opacity: 0; transform: translateY(14px) scale(0.94); } to { opacity: 1; transform: none; } }
.splash-title { font-size: 38px; font-weight: 800; letter-spacing: -0.8px; }
.splash-tagline { font-size: 17px; font-weight: 500; color: #DCEFE2; }
.splash-bn { font-size: 16px; color: #BFDCC9; }
.splash-points { margin-top: 22px; display: flex; flex-direction: column; gap: 10px; text-align: left; }
.splash-points li {
  display: flex; align-items: center; gap: 10px; font-size: 15px; font-weight: 600; color: #EAF5EE;
  background: rgba(255, 255, 255, 0.08); border: 1px solid rgba(255, 255, 255, 0.12);
  padding: 10px 14px; border-radius: 14px;
}
.splash-cta { position: relative; display: flex; flex-direction: column; gap: 12px; align-items: center; max-width: 420px; width: 100%; margin: 24px auto 0; }
.splash-foot { font-size: 12.5px; color: #B6D6C1; text-align: center; }

/* ---------- 9. Home: the Living Farm Hero ----------
   One hero, several quiet "scenes". app.js sets data-scene on this
   element from three honest inputs only: the hour of day, the
   already-fetched weather condition, and whether that weather is
   Live, Saved or Demo (never invented). Each scene is a different
   gradient plus one or two soft, static, lightweight shapes — never a
   photo or video, never something that keeps moving and distracting
   the farmer while they read the card underneath it. */
.home-hero {
  position: relative; overflow: hidden;
  background: radial-gradient(140% 90% at 90% 0%, var(--green-600) 0%, var(--green-700) 50%, var(--green-800) 100%);
  color: #fff; border-radius: 0 0 var(--radius-xl) var(--radius-xl);
  padding: calc(20px + env(safe-area-inset-top, 0px)) 18px 18px;
  display: flex; flex-direction: column; gap: 16px;
  transition: background 0.6s var(--ease);
}
.home-hero[data-scene="morning"] { background: radial-gradient(150% 90% at 85% -10%, #FBE9CC 0%, #4E9570 38%, var(--green-800) 100%); }
.home-hero[data-scene="sunny"] { background: radial-gradient(150% 95% at 88% -5%, #DDA83B 0%, var(--green-600) 42%, var(--green-800) 100%); }
.home-hero[data-scene="cloudy"] { background: radial-gradient(150% 95% at 85% 0%, #7C8A80 0%, var(--green-700) 46%, var(--green-900) 100%); }
.home-hero[data-scene="rain"] { background: radial-gradient(150% 95% at 85% 0%, #3E6E86 0%, var(--green-800) 46%, var(--green-950) 100%); }
.home-hero[data-scene="evening"] { background: radial-gradient(150% 95% at 85% -10%, #7A4A84 0%, var(--green-800) 42%, var(--green-950) 100%); }
.hero-scene-deco { position: absolute; inset: 0; pointer-events: none; overflow: hidden; opacity: 0.9; }
.hero-scene-deco .icon { position: absolute; stroke-width: 1.2; opacity: 0.16; }
.home-hero[data-scene="morning"] .hero-scene-deco .icon,
.home-hero[data-scene="sunny"] .hero-scene-deco .icon { top: -18px; right: -14px; width: 130px; height: 130px; color: #FFF3D6; }
.home-hero[data-scene="cloudy"] .hero-scene-deco .icon { top: -6px; right: -10px; width: 120px; height: 120px; color: #fff; }
.home-hero[data-scene="rain"] .hero-scene-deco .icon { top: -10px; right: -8px; width: 118px; height: 118px; color: #CFE7F5; }
.home-hero[data-scene="evening"] .hero-scene-deco .icon { top: -14px; right: -12px; width: 128px; height: 128px; color: #F1D9E6; }
.hero-priority {
  display: flex; align-items: flex-start; gap: 10px;
  background: rgba(255, 255, 255, 0.14); border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: var(--radius); padding: 12px 14px; position: relative;
}
.hero-priority .icon { width: 20px; height: 20px; margin-top: 1px; flex-shrink: 0; color: #FFF3D6; }
.hero-priority-text { font-size: 14px; font-weight: 600; line-height: 1.45; color: #F2FAF4; }
.hero-priority-label { display: block; font-size: 11.5px; font-weight: 800; letter-spacing: 0.4px; text-transform: uppercase; color: #CFE7D7; margin-bottom: 3px; }
.hero-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.hero-text { min-width: 0; }
.hero-kicker { font-size: 14px; font-weight: 600; color: #CFE7D7; }
.hero-title { font-size: 25px; font-weight: 800; letter-spacing: -0.4px; line-height: 1.2; overflow-wrap: anywhere; }
.hero-location { display: flex; align-items: center; gap: 5px; margin-top: 4px; font-size: 13.5px; font-weight: 500; color: #CFE7D7; }
.hero-location .icon { width: 15px; height: 15px; }
.avatar-btn {
  width: 48px; height: 48px; border-radius: 16px; flex-shrink: 0;
  background: rgba(255, 255, 255, 0.14); border: 1px solid rgba(255, 255, 255, 0.2); color: #fff;
  display: flex; align-items: center; justify-content: center; font-size: 19px; font-weight: 800;
}
.hero-weather {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  background: rgba(255, 255, 255, 0.12); border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: var(--radius); padding: 12px 14px; color: #fff;
  transition: background 0.2s;
}
.hero-weather:hover { background: rgba(255, 255, 255, 0.18); }
.hero-wx-icon { width: 44px; height: 44px; border-radius: 14px; background: rgba(255, 255, 255, 0.14); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.hero-wx-icon .icon { width: 26px; height: 26px; }
.hero-wx-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.hero-temp { font-size: 24px; font-weight: 800; line-height: 1.1; }
.hero-cond { font-size: 13.5px; font-weight: 600; color: #DCEFE2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hero-wx-meta { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; font-size: 12.5px; font-weight: 600; color: #CFE7D7; text-align: right; line-height: 1.3; flex-shrink: 0; }
.hero-wx-meta strong { color: #fff; font-weight: 700; }
.hero-wx-go { width: 18px; height: 18px; opacity: 0.8; }

.home-body { padding-top: 16px; }
.advisory-card { border-color: var(--green-100); }
.advisory-en { font-size: 16px; font-weight: 600; line-height: 1.5; color: var(--ink); }
.advisory-bn { font-size: 15.5px; color: var(--ink-2); margin-top: 6px; }
.advisory-bn:empty { display: none; }

.quick-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.action-card {
  display: flex; flex-direction: column; align-items: flex-start; gap: 12px; text-align: left;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 15px; min-height: 118px; box-shadow: var(--shadow-sm);
  transition: transform 0.18s var(--ease), box-shadow 0.2s, border-color 0.2s;
}
.action-card:hover { box-shadow: var(--shadow); border-color: #DCD5C5; }
.action-card:active { transform: scale(0.98); }
.action-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.action-title { font-size: 15.5px; font-weight: 700; }
.action-sub { font-size: 13px; font-weight: 500; color: var(--ink-3); }
.action-wide { grid-column: 1 / -1; flex-direction: row; align-items: center; min-height: 0; }
.action-wide .action-text { flex: 1; }
.action-go { width: 18px; height: 18px; color: var(--ink-3); }

.crop-strip { display: flex; gap: 12px; overflow-x: auto; padding: 2px 2px 6px; scrollbar-width: none; scroll-snap-type: x proximity; }
.crop-strip::-webkit-scrollbar { display: none; }
.crop-chip-card {
  flex-shrink: 0; width: 150px; scroll-snap-align: start; text-align: left;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 13px; display: flex; flex-direction: column; gap: 8px; box-shadow: var(--shadow-sm);
}
.crop-chip-card .crop-name { font-size: 15px; font-weight: 700; }
.crop-chip-card .crop-meta { font-size: 12.5px; color: var(--ink-3); font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.crop-empty {
  flex: 1; display: flex; flex-direction: column; gap: 12px; align-items: flex-start;
  background: var(--surface); border: 1.5px dashed #D6CFBF; border-radius: var(--radius-lg); padding: 16px;
}
.crop-empty p { font-size: 14.5px; color: var(--ink-2); font-weight: 500; }

.badge { align-self: flex-start; display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 700; padding: 4px 9px; border-radius: 999px; }
.badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.badge-healthy { color: var(--green-800); background: var(--green-100); }
.badge-attention { color: var(--amber-700); background: var(--amber-100); }
.badge-diseased { color: var(--red-700); background: var(--red-100); }
.badge-sample { color: var(--ink-2); background: var(--cream-200); }
.badge-sample::before { display: none; }

/* ---------- 10. Crop Scan ---------- */
.step-title { display: flex; align-items: center; gap: 10px; font-size: 16px; font-weight: 700; margin-bottom: 12px; flex-wrap: wrap; }
.step-num {
  width: 26px; height: 26px; border-radius: 50%; background: var(--green-700); color: #fff;
  display: inline-flex; align-items: center; justify-content: center; font-size: 13.5px; font-weight: 800; flex-shrink: 0;
}
.step-bn { font-size: 14px; font-weight: 600; color: var(--ink-3); }
.dropzone {
  width: 100%; font: inherit; color: inherit;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; text-align: center;
  min-height: 190px; padding: 20px; cursor: pointer;
  border: 2px dashed #C7D6C9; border-radius: var(--radius-lg); background: var(--green-50);
  transition: border-color 0.2s, background 0.2s, transform 0.15s var(--ease);
}
.dropzone:hover { border-color: var(--green-500); background: #E8F3EC; }
.dropzone:active { transform: scale(0.99); }
.dropzone-title { font-size: 16px; font-weight: 700; color: var(--green-800); margin-top: 4px; }
.dropzone-sub { font-size: 13.5px; font-weight: 500; color: var(--ink-3); }
.photo-preview { position: relative; border-radius: var(--radius-lg); overflow: hidden; background: #DDE8DF; animation: card-in 0.35s var(--ease) both; }
.photo-preview img { width: 100%; max-height: 320px; object-fit: cover; }
.photo-badge {
  position: absolute; left: 10px; top: 10px; display: inline-flex; align-items: center; gap: 5px;
  background: rgba(255, 255, 255, 0.94); color: var(--green-800); font-size: 12.5px; font-weight: 700;
  padding: 6px 10px; border-radius: 999px;
}
.photo-badge .icon { width: 14px; height: 14px; stroke-width: 2.6; }
.photo-change { position: absolute; right: 10px; bottom: 10px; box-shadow: var(--shadow); }
.analyzing { display: flex; align-items: center; gap: 14px; }
.analyzing-title { font-size: 15px; font-weight: 700; }
.analyzing-sub { font-size: 13px; color: var(--ink-3); transition: opacity 0.2s; }
/* Truthful processing stages (checking quality / analysing / preparing
   guidance) replace the single static sentence while a real request is
   in flight. No stage claims a percentage, because we do not have one. */
.analyzing-steps { display: flex; gap: 5px; margin-top: 6px; }
.analyzing-steps .step-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--green-200); transition: background 0.3s; }
.analyzing-steps .step-dot.is-done, .analyzing-steps .step-dot.is-active { background: var(--green-600); }

/* A non-blocking, honest heads-up about the photo itself (too dark,
   too small) — the farmer stays in control and can still continue. */
.quality-note { margin-top: 2px; }

.feedback-row { display: flex; align-items: center; gap: 8px; padding-top: 4px; }
.feedback-label { font-size: 13px; font-weight: 600; color: var(--ink-3); margin-right: 2px; }
.feedback-btn {
  width: 38px; height: 38px; border-radius: 12px;
  background: var(--surface); border: 1px solid var(--line); color: var(--ink-2);
  display: inline-flex; align-items: center; justify-content: center;
  transition: transform var(--dur-fast) var(--ease), background 0.2s, color 0.2s, border-color 0.2s;
}
.feedback-btn .icon { width: 17px; height: 17px; }
.feedback-btn:active { transform: scale(0.93); }
.feedback-btn[aria-pressed="true"] { background: var(--green-100); color: var(--green-800); border-color: var(--green-200); }

.result-card { display: flex; flex-direction: column; gap: 14px; }
.result-head { display: flex; gap: 12px; align-items: flex-start; }
.result-head-text { flex: 1; min-width: 0; }
.result-title { font-size: 19px; font-weight: 800; letter-spacing: -0.2px; line-height: 1.3; }
.result-title:focus { outline: none; }
.result-body { display: flex; flex-direction: column; gap: 10px; }
.group-title { font-size: 13px; font-weight: 800; letter-spacing: 0.4px; text-transform: uppercase; color: var(--ink-3); margin-top: 6px; }
.treatment-item { display: flex; gap: 10px; align-items: flex-start; }
.check-dot {
  flex-shrink: 0; width: 20px; height: 20px; border-radius: 50%; margin-top: 2px;
  background: var(--green-100); color: var(--green-700); display: flex; align-items: center; justify-content: center;
}
.check-dot .icon { width: 12px; height: 12px; stroke-width: 3; }
.treatment-text { font-size: 14.5px; font-weight: 500; color: #33403A; line-height: 1.5; }
.save-row { display: flex; gap: 8px; padding-top: 12px; border-top: 1px solid var(--line-soft); }
.save-row .select { flex: 1; min-width: 0; }

/* ---------- 11. Chat ---------- */
.screen-chat.active {
  display: flex; flex-direction: column;
  height: 100vh; height: 100dvh; min-height: 0;
  padding-bottom: calc(var(--nav-h) + var(--dock-gap) * 2 + var(--safe-bottom));
}
.chat-scroll { flex: 1; min-height: 0; overflow-y: auto; padding: 12px 16px 16px; display: flex; flex-direction: column; gap: 12px; }
.msg-row { display: flex; gap: 8px; align-items: flex-end; max-width: 92%; animation: msg-in 0.28s var(--ease) both; }
.bubble-user-row { display: flex; justify-content: flex-end; animation: msg-in 0.28s var(--ease) both; }
@keyframes msg-in { from { opacity: 0; transform: translateY(6px) scale(0.98); } to { opacity: 1; transform: none; } }
.msg-avatar {
  width: 32px; height: 32px; border-radius: 11px; flex-shrink: 0;
  background: var(--green-700); color: #fff; display: flex; align-items: center; justify-content: center;
}
.msg-avatar .icon { width: 17px; height: 17px; }
.bubble-ai, .bubble-user { font-size: 15px; font-weight: 500; line-height: 1.5; padding: 11px 14px; max-width: 520px; overflow-wrap: anywhere; }
.bubble-ai { background: var(--surface); border: 1px solid var(--line); color: var(--ink); border-radius: 18px 18px 18px 6px; box-shadow: var(--shadow-sm); }
.bubble-user { background: var(--green-700); color: #fff; border-radius: 18px 18px 6px 18px; max-width: 85%; }
.bubble-ai .bn { display: block; margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--line); color: var(--ink-2); font-size: 15px; }
.bubble-q { display: block; font-size: 12.5px; font-weight: 700; color: var(--green-700); margin-bottom: 4px; }

/* Honest per reply label: which one actually answered, Live AI or the
   curated FAQ — same idea as Crop Scan's per result Live/Demo pill. */
.msg-tag {
  display: table; /* its own line, above the reply text, sized to its content */
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.01em;
  padding: 3px 7px; border-radius: 999px; margin-bottom: 6px;
}
.msg-tag.tag-live { background: var(--green-100); color: var(--green-800); }
.msg-tag.tag-general { background: var(--amber-100); color: var(--amber-700); }
.msg-tag.tag-curated { background: var(--cream-200); color: var(--ink-3); }
.chat-dock { flex-shrink: 0; background: var(--surface); border-top: 1px solid var(--line); padding: 10px 12px 8px; display: flex; flex-direction: column; gap: 8px; }
.chat-form { display: flex; gap: 8px; align-items: center; }
.chat-input { flex: 1; min-width: 0; border-radius: 999px; padding-left: 18px; }
.send-btn {
  width: 48px; height: 48px; border-radius: 50%; flex-shrink: 0;
  background: var(--green-700); color: #fff; display: flex; align-items: center; justify-content: center;
  transition: transform 0.15s var(--ease), opacity 0.2s;
}
.send-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.send-btn:not(:disabled):active { transform: scale(0.92); }
.chat-note { font-size: 11.5px; color: var(--ink-3); text-align: center; }

/* ---------- 12. Market ---------- */
.price-list, .library-list, .crop-list { display: flex; flex-direction: column; gap: 10px; }
.price-card {
  display: flex; align-items: center; gap: 12px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 13px 14px; box-shadow: var(--shadow-sm); animation: card-in 0.35s var(--ease) both;
}
.price-main { flex: 1; min-width: 0; }
.price-name { font-size: 15.5px; font-weight: 700; }
.price-unit { font-size: 12.5px; color: var(--ink-3); font-weight: 500; }
/* A per-item sourced-snapshot date (v2.6.0): shown only when a price
   has no live feed behind it, so a farmer can see exactly how fresh
   (or not) that one figure is, instead of trusting a single "updated"
   stamp for the whole list. */
.price-date { font-size: 11.5px; color: var(--ink-3); font-style: italic; margin-top: 1px; }
.price-side { text-align: right; }
.price-value { font-size: 18px; font-weight: 800; letter-spacing: -0.2px; }
.trend { display: inline-flex; align-items: center; gap: 3px; font-size: 12.5px; font-weight: 700; }
.trend .icon { width: 14px; height: 14px; stroke-width: 2.4; }
.trend-up { color: #237A4B; }
.trend-down { color: var(--red-700); }
.trend-flat { color: var(--ink-3); }
/* v2.6.0 honesty design: a record with only one dated snapshot gets no
   trend percentage at all (never a fabricated 0.0%). Styled visibly
   different from .trend-flat (a real, confirmed "no change") so the two
   are never mistaken for each other. */
.trend-none { color: var(--ink-3); font-weight: 600; font-style: italic; }
.mine-dot { font-size: 11px; font-weight: 700; color: var(--green-800); background: var(--green-100); border-radius: 999px; padding: 2px 7px; margin-left: 6px; vertical-align: middle; }
/* Region switcher (Bangladesh / China, v2.6.0): a compact segmented
   pair above the category filter chips, sharing the .chip look but
   split evenly instead of scrolling. */
.chip-row-region { overflow-x: visible; padding: 2px 2px 8px; }
.chip-row-region .chip { flex: 1; text-align: center; }
/* A price card whose date is well past normal freshness (see
   PRICE_STALE_DAYS in app.js) is visibly muted, not just labelled in
   small print, so stale data cannot be mistaken for today's price. */
.price-card.is-stale { opacity: 0.72; }
.price-card.is-stale .price-value { color: var(--ink-2); }

/* ---------- 12b. About / app info (My farm screen) ----------
   The version number and technical detail live here, out of the way
   of the main app, instead of on the Home footer every farmer sees. */
.about-block { display: flex; flex-direction: column; gap: 6px; }
.about-row { display: flex; justify-content: space-between; gap: 10px; font-size: 13.5px; padding: 7px 0; border-bottom: 1px solid var(--line-soft); }
.about-row:last-child { border-bottom: 0; }
.about-row dt { color: var(--ink-3); font-weight: 600; }
.about-row dd { margin: 0; color: var(--ink); font-weight: 700; text-align: right; }

/* ---------- 12c. Service worker update banner ---------- */
.update-banner {
  position: fixed; left: 12px; right: 12px; z-index: 55;
  bottom: calc(var(--nav-h) + var(--dock-gap) * 2 + var(--safe-bottom) + 10px);
  display: flex; align-items: center; gap: 10px;
  background: var(--ink); color: #fff; border-radius: 16px;
  padding: 12px 12px 12px 16px; box-shadow: var(--shadow-lg);
  animation: toast-in var(--dur-toast) var(--ease);
}
.update-banner p { flex: 1; font-size: 13.5px; font-weight: 600; line-height: 1.4; }
@media (min-width: 960px) { .update-banner { left: auto; right: 24px; bottom: 24px; width: 340px; } }

/* ---------- 13. Weather ---------- */
.wx-hero {
  border-radius: var(--radius-xl); padding: 20px; color: #fff;
  background: radial-gradient(140% 120% at 100% 0%, var(--green-600) 0%, var(--green-700) 45%, var(--green-900) 100%);
  box-shadow: 0 16px 40px rgba(33, 78, 56, 0.25);
  display: flex; flex-direction: column; gap: 16px; animation: card-in 0.4s var(--ease) both;
}
.wx-hero-top { display: flex; justify-content: space-between; gap: 12px; }
.wx-place { display: flex; align-items: center; gap: 5px; font-size: 14px; font-weight: 600; color: #D3EADB; }
.wx-place .icon { width: 15px; height: 15px; }
.wx-temp { font-size: 52px; font-weight: 800; letter-spacing: -1.5px; line-height: 1.05; margin-top: 4px; }
.wx-cond { font-size: 15px; font-weight: 600; color: #E3F2E8; }
.wx-updated { font-size: 12.5px; font-weight: 500; color: #CFE7D7; margin-top: 2px; }
.wx-big-icon { width: 76px; height: 76px; border-radius: 24px; background: rgba(255, 255, 255, 0.12); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.wx-big-icon .icon { width: 44px; height: 44px; stroke-width: 1.5; }
.wx-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.wx-stat {
  display: flex; flex-direction: column; align-items: center; gap: 2px; text-align: center;
  background: rgba(255, 255, 255, 0.1); border-radius: 14px; padding: 10px 4px;
}
.wx-stat .icon { width: 18px; height: 18px; opacity: 0.9; }
.wx-stat-label { font-size: 12px; font-weight: 600; color: #CFE7D7; }
.wx-stat-value { font-size: 16px; font-weight: 800; }

/* Next few hours: a real, short strip from the same Open-Meteo call as
   the 7 day forecast (hourly temperature + rain chance). Only rendered
   when the app actually has live or saved hourly data — never faked. */
.hour-row { display: flex; gap: 8px; overflow-x: auto; padding: 2px 2px 6px; scrollbar-width: none; }
.hour-row::-webkit-scrollbar { display: none; }
.hour-card {
  flex-shrink: 0; width: 58px; text-align: center;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 9px 4px; display: flex; flex-direction: column; align-items: center; gap: 4px;
}
.hour-card.is-now { border-color: var(--green-500); background: var(--green-50); }
.hour-time { font-size: 11.5px; font-weight: 700; color: var(--ink-2); }
.hour-card .icon { width: 20px; height: 20px; }
.hour-temp { font-size: 13.5px; font-weight: 800; }
.hour-rain { font-size: 10.5px; font-weight: 700; color: var(--blue-700); }

.day-row { display: flex; gap: 10px; overflow-x: auto; padding: 2px 2px 6px; scrollbar-width: none; }
.day-row::-webkit-scrollbar { display: none; }
.day-card {
  flex-shrink: 0; width: 78px; text-align: center;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 12px 6px; display: flex; flex-direction: column; align-items: center; gap: 6px;
  animation: card-in 0.35s var(--ease) both;
}
.day-card.is-today { border-color: var(--green-500); background: var(--green-50); }
.day-name { font-size: 13px; font-weight: 700; }
.day-card .icon { width: 26px; height: 26px; }
.day-hi { font-size: 14.5px; font-weight: 800; }
.day-lo { font-size: 12.5px; font-weight: 600; color: var(--ink-3); }
.day-rain { font-size: 11.5px; font-weight: 700; color: var(--blue-700); display: inline-flex; align-items: center; gap: 2px; }
.day-rain .icon { width: 12px; height: 12px; }
.wx-sun { color: var(--sun); }
.wx-cloud { color: #6B7A72; }
.wx-rain { color: var(--blue-700); }
.hero-wx-icon .icon, .wx-big-icon .icon { color: #fff; }

.tip-list { display: flex; flex-direction: column; gap: 12px; }
.tip-item { display: flex; gap: 10px; align-items: flex-start; }
.tip-item .check-dot { background: var(--blue-100); color: var(--blue-700); }
.tip-en { font-size: 15px; font-weight: 600; line-height: 1.5; }
.tip-bn { font-size: 14.5px; color: var(--ink-2); }
.source-line { font-size: 12.5px; color: var(--ink-3); text-align: center; }

/* ---------- 14. Disease library ---------- */
.search-field { position: relative; }
.search-field > .icon { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--ink-3); pointer-events: none; }
.search-field .input { padding-left: 44px; border-radius: 999px; }
.result-count { font-size: 13px; font-weight: 600; color: var(--ink-3); }
.library-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-sm); overflow: hidden; animation: card-in 0.35s var(--ease) both; }
.library-head { width: 100%; display: flex; align-items: center; gap: 12px; padding: 13px 14px; text-align: left; }
.library-head .icon-tile { width: 38px; height: 38px; border-radius: 12px; }
.library-head-text { flex: 1; min-width: 0; }
.library-name { font-size: 15.5px; font-weight: 700; }
.library-meta { font-size: 12.5px; color: var(--ink-3); font-weight: 500; }
.library-chevron { width: 18px; height: 18px; color: var(--ink-3); transition: transform 0.25s var(--ease); }
.library-head[aria-expanded="true"] .library-chevron { transform: rotate(180deg); }
.library-detail { padding: 0 14px 14px; display: flex; flex-direction: column; gap: 10px; animation: card-in 0.3s var(--ease) both; }
.sci-name { font-size: 13px; font-style: italic; color: var(--ink-3); }

/* ---------- 15. My farm ---------- */
.crop-row-card {
  display: flex; gap: 12px; align-items: flex-start;
  border: 1px solid var(--line); border-radius: var(--radius); padding: 13px; background: var(--surface);
  animation: card-in 0.3s var(--ease) both;
}
.crop-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.crop-row-title { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 15.5px; font-weight: 700; }
.crop-row-meta { font-size: 13px; color: var(--ink-2); font-weight: 500; }
.crop-row-notes { font-size: 13px; color: var(--ink-3); overflow-wrap: anywhere; }
.crop-row-scan { font-size: 12.5px; color: var(--ink-2); background: var(--cream); border-radius: 8px; padding: 5px 8px; margin-top: 2px; }
.crop-row-actions { display: flex; flex-direction: column; gap: 6px; }
.crop-row-actions .icon-btn { width: 40px; height: 40px; border-radius: 12px; }
.crop-row-actions .icon { width: 18px; height: 18px; }

/* Dialog (bottom sheet on phones, centred card on larger screens) */
.sheet {
  width: min(560px, 100vw); max-width: 100vw; max-height: 92dvh;
  margin: auto auto 0; padding: 18px 16px calc(18px + var(--safe-bottom));
  border: 0; border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  background: var(--surface); color: var(--ink); box-shadow: var(--shadow-lg);
  overflow-y: auto;
}
.sheet[open] { animation: sheet-up 0.3s var(--ease); }
@keyframes sheet-up { from { transform: translateY(40px); opacity: 0; } to { transform: none; opacity: 1; } }
.sheet::backdrop { background: rgba(23, 56, 38, 0.45); }
.sheet-head { display: flex; align-items: center; justify-content: space-between; }
.sheet-sm { width: min(420px, 100vw); }

/* ---------- 16. Toast & offline bar ---------- */
.toast {
  position: fixed; left: 50%; bottom: calc(var(--nav-h) + var(--dock-gap) + var(--safe-bottom) + 14px); z-index: 60;
  transform: translateX(-50%); max-width: calc(100vw - 32px);
  background: var(--ink); color: #fff; font-size: 14px; font-weight: 600;
  padding: 11px 16px; border-radius: 14px; box-shadow: var(--shadow-lg);
  animation: toast-in var(--dur-toast) var(--ease);
}
@keyframes toast-in { from { opacity: 0; transform: translate(-50%, 10px); } to { opacity: 1; transform: translate(-50%, 0); } }
.offline-bar {
  position: sticky; top: 0; z-index: 50;
  display: flex; align-items: center; justify-content: center; gap: 8px; text-align: center;
  padding: 8px 12px calc(8px); padding-top: calc(8px + env(safe-area-inset-top, 0px));
  background: #3A3A2E; color: #FFF6DA; font-size: 13px; font-weight: 600;
}
.offline-bar .icon { width: 16px; height: 16px; }
.bn-inline { display: inline; opacity: 0.85; }

/* ---------- 17. Larger phones & tablets ---------- */
@media (min-width: 400px) {
  .screen-body { padding-left: 18px; padding-right: 18px; }
}
@media (max-width: 359px) {
  .hero-title { font-size: 22px; }
  .wx-temp { font-size: 44px; }
  .field-row { flex-direction: column; gap: 14px; }
  .topbar .pill { font-size: 11px; padding: 5px 8px; }
  .topbar { gap: 8px; }
}
@media (min-width: 600px) {
  .screen-body { padding: 20px 24px 12px; }
  .home-hero { border-radius: 0 0 36px 36px; padding-left: 28px; padding-right: 28px; }
  .quick-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .action-wide { grid-column: 1 / -1; }
  .sheet { margin: auto; border-radius: var(--radius-xl); padding-bottom: 20px; }
}

/* ---------- 18. Desktop: sidebar navigation ---------- */
@media (min-width: 960px) {
  body { font-size: 15.5px; }
  .app { display: grid; grid-template-columns: 252px minmax(0, 1fr); background: linear-gradient(to right, var(--surface) 252px, var(--cream) 252px); }
  .app.is-splash { display: block; }
  .app-nav {
    position: sticky; top: 0; bottom: auto; left: auto; right: auto;
    height: 100vh; height: 100dvh; padding: 22px 14px;
    flex-direction: column; gap: 18px; border-radius: 0; box-shadow: none;
    background: var(--surface); border-top: 0; border-right: 1px solid var(--line); border-left: 0; border-bottom: 0;
    -webkit-backdrop-filter: none; backdrop-filter: none;
    transform: none !important; opacity: 1 !important; pointer-events: auto !important;
  }
  .nav-brand { display: flex; align-items: center; gap: 10px; padding: 4px 10px 10px; }
  .brand-mark { width: 38px; height: 38px; border-radius: 12px; background: var(--green-700); color: #fff; display: flex; align-items: center; justify-content: center; }
  .brand-name { font-size: 19px; font-weight: 800; letter-spacing: -0.3px; color: var(--green-900); }
  .nav-items { flex: 0; flex-direction: column; gap: 4px; padding: 0; justify-content: flex-start; }
  .nav-item, .nav-item.desktop-only {
    display: flex; flex: 0 0 auto; flex-direction: row; justify-content: flex-start; gap: 12px;
    min-height: 46px; padding: 0 10px; border-radius: 12px; font-size: 15px; color: var(--ink-2);
    transition: background 0.2s, color 0.2s;
  }
  .nav-item .nav-icon { width: auto; height: auto; background: none !important; }
  .nav-item:hover { background: var(--cream); }
  .nav-item[aria-current="page"] { background: var(--green-100); color: var(--green-800); font-weight: 700; box-shadow: inset 3px 0 0 var(--green-700); }
  .nav-foot { display: block; margin-top: auto; padding: 0 10px; font-size: 12px; color: var(--ink-3); }

  .screen { padding-bottom: 40px; }
  .screen-chat.active { height: 100vh; height: 100dvh; padding-bottom: 0; }
  .back-btn { display: none; }
  .topbar { padding: 20px max(32px, calc((100% - 816px) / 2)) 14px; }
  .day-row { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); overflow: visible; }
  .day-card { width: auto; }
  .topbar-title { font-size: 24px; }
  .screen-body { max-width: 880px; padding: 20px 32px 12px; }
  .chat-scroll { padding: 16px 32px; }
  .chat-scroll > *, .chat-dock > * { width: 100%; max-width: 816px; margin-left: auto; margin-right: auto; }
  .msg-row { max-width: 816px; }
  .toast { bottom: 24px; }

  .home-hero { border-radius: 0 0 36px 36px; padding: 32px 40px 28px; }
  .home-hero > * { width: 100%; max-width: 816px; margin-left: auto; margin-right: auto; }
  .hero-title { font-size: 30px; }
  .quick-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .price-list, .library-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; align-items: start; }
  .splash-inner { margin-top: 10vh; }
  .screen-splash.active { align-items: center; }
}

/* ---------- 18a. Tablet dashboard (960px to 1199px) ----------
   A lighter two-column pass for tablets, between the phone's single
   stacked column and the full named-area desktop grid below. Uses the
   same .dash-* classes as the desktop grid (never fragile nth-of-type
   positional selectors, which is what silently fought the desktop grid
   here before and forced every card into one column). */
@media (min-width: 960px) and (max-width: 1199.98px) {
  .home-body {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas:
      "advisory crops"
      "quick    crops";
    align-items: start; gap: 20px;
  }
  .dash-advisory { grid-area: advisory; }
  .dash-crops { grid-area: crops; }
  .dash-quick { grid-area: quick; }
  .home-body > .app-foot { grid-column: 1 / -1; }
  /* Recent scan / crop health / market movers are new, dashboard-only
     sections that did not exist in the old two-column tablet layout;
     when a farmer's real data makes one visible, it spans full width
     below rather than fighting the two named columns above for room. */
  .dash-health, .dash-scan, .dash-market { grid-column: 1 / -1; }
}

/* ---------- 18b. Wide desktop dashboard (>=1200px) ----------
   Laptop/desktop monitors get more intentional use of the extra width:
   a ~1160px dashboard instead of the ~880px single column used on
   tablets, with the Living Farm Hero, today's priority, weather, crops,
   recent scan, crop health and market movement arranged in a grid.
   Nothing here is new data — the same honestly-labelled Live/Saved/
   Demo information as the phone layout, just laid out with more room. */
@media (min-width: 1200px) {
  .topbar { padding-left: max(32px, calc((100% - 1160px) / 2)); padding-right: max(32px, calc((100% - 1160px) / 2)); }
  .screen-body { max-width: 1160px; padding-left: 32px; padding-right: 32px; }
  .chat-scroll { padding-left: 32px; padding-right: 32px; }
  .chat-scroll > *, .chat-dock > * { max-width: 1040px; }
  .msg-row { max-width: 1040px; }
  .price-list, .library-list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* The Home dashboard's "Market movement" tile reuses .price-card/.price-list
     for consistency, but it lives in the narrow ~0.85fr grid column (roughly
     490px), not the Market screen's full ~1160px width the 3-column rule
     above was written for. Squeezing 3 columns into that narrow tile crushed
     the price badge into the crop name (worst on a longer name that wraps to
     two lines, e.g. "Chili (Green)"), so this dashboard tile stays one
     column regardless of the generic price-list rule. */
  .dash-market .price-list { grid-template-columns: 1fr; }

  .home-hero { padding: 34px 44px 30px; }
  .home-hero > * { max-width: 1160px; }
  .hero-title { font-size: 32px; }

  .home-body {
    max-width: 1160px;
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
    grid-template-areas:
      "advisory crops"
      "quick    health"
      "scan     market"
      "foot     foot";
    align-items: start; gap: 20px;
  }
  .dash-advisory { grid-area: advisory; }
  .dash-crops { grid-area: crops; }
  .dash-quick { grid-area: quick; }
  .dash-health { grid-area: health; }
  .dash-scan { grid-area: scan; }
  .dash-market { grid-area: market; }
  .home-body > .app-foot { grid-area: foot; }
  .quick-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* ---------- 19. Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; scroll-behavior: auto !important; }
}
