/* ==========================================================================
   Krishok Card — custom.css
   Design language: "field ledger" — a government farm register reimagined.
   Deep paddy green + rice-gold + indigo trust accent, warm paper surface.
   Every screen (auth + dashboard) pulls from the same token set below.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Design tokens
   -------------------------------------------------------------------------- */
:root {
  /* Brand */
  --color-primary: #1f4d3a;        /* deep paddy green — primary actions, sidebar */
  --color-primary-dark: #163a2b;
  --color-primary-light: #2f6b4f;
  --color-accent: #d4a017;         /* rice-gold — highlights, active states */
  --color-accent-dark: #b8860b;
  --color-secondary: #2c3e70;      /* indigo — links, secondary emphasis */

  /* Surfaces */
  --color-bg: #f6f4ee;             /* warm paper background */
  --color-surface: #ffffff;
  --color-surface-muted: #eef1ea;
  --color-border: #e1ddcd;

  /* Text */
  --color-text: #1c2321;
  --color-text-muted: #5b6660;
  --color-text-inverse: #f6f4ee;

  /* Status */
  --color-success: #3a7d5c;
  --color-success-bg: #e7f2ea;
  --color-warning: #c98a1f;
  --color-warning-bg: #fbf1de;
  --color-danger: #b3492d;
  --color-danger-bg: #fbebe5;
  --color-info: var(--color-secondary);
  --color-info-bg: #e8ebf5;

  /* Typography */
  --font-display: "Fraunces", "Noto Serif Bengali", Georgia, serif;
  --font-body: "Public Sans", "Noto Sans Bengali", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Scale */
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 18px;
  --shadow-sm: 0 1px 2px rgba(28, 35, 33, 0.06);
  --shadow-md: 0 6px 20px rgba(28, 35, 33, 0.08);
  --shadow-lg: 0 20px 48px rgba(22, 58, 43, 0.18);

  --sidebar-width: 264px;
  --topbar-height: 64px;
}

/* --------------------------------------------------------------------------
   1b. Dark theme
   Applied by setting `data-theme="dark"` on <html> (custom.js does this from a
   saved localStorage choice; an inline script in base.html applies it before
   first paint to avoid a light->dark flash). Almost every rule in this file
   reads its colour from the tokens above, so redefining the tokens here flips
   the whole dashboard automatically. A handful of targeted overrides follow
   for the few places that hard-code a light value or reuse a brand token in a
   way that would read wrong on a dark surface.

   The sidebar keeps its deep-green fill in both themes (it reads as the app's
   identity, not a surface), so --color-primary* stay green; only the neutral
   surfaces, text and status tints move.
   -------------------------------------------------------------------------- */
:root { color-scheme: light; }

[data-theme="dark"] {
  color-scheme: dark;

  /* Brand — kept green; sidebar + primary buttons look the same either way. */
  --color-primary: #2f6b4f;
  --color-primary-dark: #16241d;   /* sidebar fill */
  --color-primary-light: #3d8563;
  --color-accent: #e0b23c;
  --color-accent-dark: #c99a1e;
  --color-secondary: #91a6e6;      /* lighter indigo so links read on dark */

  /* Surfaces — dark slate with a faint green cast to echo the brand. */
  --color-bg: #10151a;
  --color-surface: #19212a;
  --color-surface-muted: #222c36;
  --color-border: #303c48;

  /* Text */
  --color-text: #e7ecef;
  --color-text-muted: #9aa8b4;
  --color-text-inverse: #f6f4ee;

  /* Status — muted fills that sit on a dark surface without glowing. */
  --color-success: #5cc08d;
  --color-success-bg: #16302a;
  --color-warning: #e0b04a;
  --color-warning-bg: #322815;
  --color-danger: #e07a5f;
  --color-danger-bg: #341f1a;
  --color-info: var(--color-secondary);
  --color-info-bg: #1c2438;

  /* Shadows read as depth against a dark backdrop only if deeper/darker. */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 6px 20px rgba(0, 0, 0, 0.45);
  --shadow-lg: 0 20px 48px rgba(0, 0, 0, 0.55);
}

/* Headings colour themselves with --color-primary-dark (a near-black green) in
   light mode; on a dark surface that is invisible, so read from body text. */
[data-theme="dark"] h1,
[data-theme="dark"] h2,
[data-theme="dark"] h3,
[data-theme="dark"] h4 {
  color: var(--color-text);
}

/* The alert borders were hand-tinted for light fills; soften them for dark. */
[data-theme="dark"] .alert-danger { border-color: #5a3128; }
[data-theme="dark"] .alert-success { border-color: #26543f; }
[data-theme="dark"] .alert-warning { border-color: #5a4620; color: var(--color-warning); }
[data-theme="dark"] .alert-info { border-color: #2c3760; }

/* zebra hover on survey tables uses a hard-coded pale green; invert it. */
[data-theme="dark"] .sv-table tbody tr:hover td { background: rgba(92, 192, 141, 0.08); }

/* --------------------------------------------------------------------------
   1c. Theme toggle button (topbar)
   Sun shows in light mode (click -> go dark); moon shows in dark mode.
   -------------------------------------------------------------------------- */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text);
  cursor: pointer;
  transition: background-color 120ms ease, color 120ms ease;
}
.theme-toggle:hover { background: var(--color-surface-muted); }
.theme-toggle svg { width: 18px; height: 18px; }
.theme-toggle .icon-moon { display: none; }
[data-theme="dark"] .theme-toggle .icon-sun { display: none; }
[data-theme="dark"] .theme-toggle .icon-moon { display: block; }

/* --------------------------------------------------------------------------
   2. Reset & base
   -------------------------------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family: var(--font-body);
  background: var(--color-bg);
  color: var(--color-text);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  margin: 0 0 0.4em;
  color: var(--color-primary-dark);
  letter-spacing: -0.01em;
}

a {
  color: var(--color-secondary);
  text-decoration: none;
}
a:hover { text-decoration: underline; }

img { max-width: 100%; display: block; }

button { font-family: inherit; }

/* Visible keyboard focus everywhere */
a:focus-visible,
button:focus-visible,
input:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid var(--color-accent);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* --------------------------------------------------------------------------
   3. Layout: field-row texture (signature motif)
   Thin repeating lines evoke tilled/paddy rows; used sparingly as a
   background accent on dark panels only.
   -------------------------------------------------------------------------- */
.field-rows {
  background-image: repeating-linear-gradient(
    115deg,
    rgba(246, 244, 238, 0.05) 0px,
    rgba(246, 244, 238, 0.05) 1px,
    transparent 1px,
    transparent 34px
  );
}

/* --------------------------------------------------------------------------
   4. Buttons
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 20px;
  font-size: 15px;
  font-weight: 600;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color 120ms ease, border-color 120ms ease, transform 120ms ease;
}
.btn:active { transform: translateY(1px); }

.btn-block { width: 100%; }

.btn-primary {
  background: var(--color-primary);
  color: var(--color-text-inverse);
}
.btn-primary:hover {
  background: var(--color-primary-dark);
  text-decoration: none;
}

.btn-outline {
  background: transparent;
  border-color: var(--color-border);
  color: var(--color-text);
}
.btn-outline:hover {
  border-color: var(--color-primary);
  text-decoration: none;
}

/* --------------------------------------------------------------------------
   5. Forms
   -------------------------------------------------------------------------- */
.form-group { margin-bottom: 18px; }

.form-label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 6px;
  color: var(--color-text);
}

.form-control {
  width: 100%;
  padding: 12px 14px;
  font-size: 15px;
  font-family: var(--font-body);
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.form-control::placeholder { color: #9aa39c; }
.form-control:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(31, 77, 58, 0.14);
}

/* Tick boxes and radios. Left as native controls — they keep every keyboard
   and screen-reader behaviour a hand-built replacement has to re-earn — but
   repainted from the brand token, because a browser's default blue is the one
   piece of chrome that ignores this file's palette entirely. `accent-color`
   colours the fill, and the dark theme redefines --color-primary to the
   lighter green, so both themes follow along with no second rule.

   This is deliberately an element selector, not a class: every checkbox in the
   app (Level filters, crop seasons, fertilizer providers, formset DELETE
   boxes, "Active") wants the same colour, and none of them would remember to
   opt in. --color-surface as the second value keeps the tick itself readable. */
input[type="checkbox"],
input[type="radio"] {
  accent-color: var(--color-primary);
  /* Native boxes render around 13px; the labels beside them sit at 14–15px,
     so a touch larger reads as intentional rather than cramped. */
  width: 16px;
  height: 16px;
  cursor: pointer;
}

input[type="checkbox"]:focus-visible,
input[type="radio"]:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

.form-error {
  color: var(--color-danger);
  font-size: 13px;
  margin-top: 6px;
}

.form-hint-row {
  display: flex;
  justify-content: flex-end;
  margin: -8px 0 18px;
  font-size: 13px;
}

.alert {
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  font-size: 14px;
  margin-bottom: 16px;
  border: 1px solid transparent;
}
.alert-danger { background: var(--color-danger-bg); color: var(--color-danger); border-color: #f0cfc2; }
.alert-success { background: var(--color-success-bg); color: var(--color-success); border-color: #cfe6d7; }
.alert-warning { background: var(--color-warning-bg); color: #8a5d10; border-color: #ecd9ac; }
.alert-info { background: var(--color-info-bg); color: var(--color-secondary); border-color: #d4dbef; }

/* --------------------------------------------------------------------------
   6. Auth screen — split card (login.html)
   -------------------------------------------------------------------------- */
.auth-screen {
  height: 100vh;
  overflow: hidden;
  display: grid;
  grid-template-columns: 1.05fr 1fr;
}

.auth-panel {
  position: relative;
  background: linear-gradient(160deg, var(--color-primary-light) 0%, var(--color-primary) 45%, var(--color-primary-dark) 100%);
  color: var(--color-text-inverse);
  padding: 56px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  overflow-x: hidden;
  overflow-y: auto;
  height: 100%;
}

/* soft "aurora" glows for a lighter, more contemporary feel than a flat fill */
.auth-panel__glow {
  position: absolute;
  border-radius: 50%;
  filter: blur(70px);
  opacity: 0.35;
  pointer-events: none;
}
.auth-panel__glow--gold {
  width: 340px;
  height: 340px;
  background: var(--color-accent);
  top: -80px;
  right: -100px;
}
.auth-panel__glow--indigo {
  width: 300px;
  height: 300px;
  background: var(--color-secondary);
  bottom: -60px;
  left: -80px;
  opacity: 0.4;
}
.auth-panel__texture {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.auth-panel > * { position: relative; z-index: 1; }

.auth-panel__brand {
  display: flex;
  align-items: center;
  gap: 12px;
}

.auth-panel__brand-mark {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--color-accent);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-primary-dark);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 18px;
  flex-shrink: 0;
  box-shadow: 0 0 0 6px rgba(212, 160, 23, 0.18);
}

.auth-panel__brand-text .eyebrow {
  display: block;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.75;
}

.auth-panel__headline {
  max-width: 420px;
}

.auth-panel__headline h1 {
  color: var(--color-text-inverse);
  font-size: 40px;
  line-height: 1.15;
  margin-bottom: 14px;
}

.auth-panel__headline p {
  opacity: 0.85;
  font-size: 16px;
}

/* the "card" visual — a stylised smart-card evoking the physical Krishok Card,
   rendered as a glass panel for a more modern, less flat look */
.id-card {
  width: 320px;
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.08);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid rgba(246, 244, 238, 0.28);
  box-shadow: var(--shadow-lg);
  padding: 20px;
  color: var(--color-text-inverse);
}

.id-card__row-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 26px;
}

.id-card__chip {
  width: 38px;
  height: 28px;
  border-radius: 5px;
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-dark));
}

.id-card__label {
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.75;
}

.id-card__number {
  font-family: var(--font-mono);
  font-size: 18px;
  letter-spacing: 0.08em;
  margin-top: 18px;
}

.auth-panel__hotline {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 14px;
}
.auth-panel__hotline strong {
  font-family: var(--font-mono);
  font-size: 18px;
  letter-spacing: 0.03em;
}

.auth-form-side {
  background: var(--color-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px;
  height: 100%;
  overflow-y: auto;
}

.auth-card {
  width: 100%;
  max-width: 400px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: 40px;
  position: relative;
  overflow: hidden;
  animation: auth-card-in 420ms ease both;
}

/* thin gradient accent bar across the top — a small "smart product" signature */
.auth-card::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 4px;
  background: linear-gradient(90deg, var(--color-primary), var(--color-accent) 55%, var(--color-secondary));
}

@keyframes auth-card-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

.auth-card__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  margin-bottom: 6px;
}

.auth-card__subtitle {
  font-size: 13px;
  color: var(--color-text-muted);
  margin: 0 0 26px;
}

.lang-toggle {
  display: inline-flex;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  padding: 3px;
  font-size: 12px;
  font-weight: 600;
}
.lang-toggle span {
  padding: 5px 12px;
  border-radius: 999px;
  color: var(--color-text-muted);
  cursor: pointer;
}
.lang-toggle span.active {
  background: var(--color-primary);
  color: var(--color-text-inverse);
}

/* input icon affixes (mail icon, password eye toggle) */
.input-icon-wrap { position: relative; display: flex; align-items: center; }
.input-icon-wrap .form-control { padding-right: 42px; }

.input-icon {
  position: absolute;
  right: 14px;
  display: flex;
  color: var(--color-text-muted);
  pointer-events: none;
}

.password-toggle {
  position: absolute;
  right: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  background: none;
  border: none;
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  cursor: pointer;
}
.password-toggle:hover { color: var(--color-text); background: var(--color-surface-muted); }
.password-toggle .icon-eye-off { display: none; }
.password-toggle.is-visible .icon-eye { display: none; }
.password-toggle.is-visible .icon-eye-off { display: block; }

.auth-card__secure {
  display: flex;
  align-items: center;
  gap: 6px;
  justify-content: center;
  font-size: 12px;
  color: var(--color-text-muted);
  margin-top: 16px;
}

.auth-card__divider {
  border: none;
  border-top: 1px solid var(--color-border);
  margin: 20px 0 16px;
}

.auth-card__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12px;
  color: var(--color-text-muted);
}

@media (max-width: 900px) {
  .auth-screen { grid-template-columns: 1fr; }
  .auth-panel { display: none; }
}

@media (max-height: 760px) {
  .auth-panel { padding: 32px; gap: 16px; }
  .auth-panel__headline h1 { font-size: 32px; }
  .id-card { padding: 16px; }
  .id-card__row-top { margin-bottom: 16px; }
  .auth-card { padding: 28px; }
  .auth-card__subtitle { margin-bottom: 18px; }
}


/* --------------------------------------------------------------------------
   7. Dashboard shell (base.html)
   -------------------------------------------------------------------------- */
.app-shell {
  display: grid;
  grid-template-columns: var(--sidebar-width) 1fr;
  min-height: 100vh;
  transition: grid-template-columns 160ms ease;
}

.sidebar {
  background: var(--color-primary-dark);
  color: var(--color-text-inverse);
  padding: 20px 16px;
  display: flex;
  flex-direction: column;
  gap: 20px;
  overflow-y: auto;
  overflow-x: hidden;
}
.sidebar::-webkit-scrollbar { width: 6px; }
.sidebar::-webkit-scrollbar-thumb { background: rgba(246, 244, 238, 0.18); border-radius: 999px; }

.sidebar-backdrop {
  display: none;
}

.sidebar__brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 8px 16px;
  border-bottom: 1px solid rgba(246, 244, 238, 0.12);
  white-space: nowrap;
}

.sidebar__brand-mark {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--color-accent);
  flex-shrink: 0;
}

/* The DAE crest (static/img/dae-logo.jpg). White plate behind it because the
   logo artwork is opaque and sits on the dark sidebar; `object-fit: contain`
   keeps the crest whole rather than cropping it to the circle. */
.sidebar__brand-logo {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  flex-shrink: 0;
  object-fit: contain;
  background: #fff;
  padding: 2px;
}

.sidebar__brand-text { font-family: var(--font-display); font-size: 15px; font-weight: 600; }

.nav-group { display: flex; flex-direction: column; gap: 2px; flex: 1; }

.nav-item { display: flex; flex-direction: column; }

.nav-link {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px 12px;
  border: none;
  background: none;
  border-radius: var(--radius-sm);
  color: rgba(246, 244, 238, 0.78);
  font-size: 14px;
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
  text-align: left;
  white-space: nowrap;
}
.nav-link:hover {
  background: rgba(246, 244, 238, 0.08);
  color: var(--color-text-inverse);
  text-decoration: none;
}
.nav-link--active {
  background: var(--color-accent);
  color: var(--color-primary-dark);
  font-weight: 700;
}

.nav-link__icon { flex-shrink: 0; width: 18px; text-align: center; font-size: 15px; }
.nav-link__text { flex: 1; overflow: hidden; text-overflow: ellipsis; }
.nav-link__chevron {
  flex-shrink: 0;
  font-size: 11px;
  transition: transform 160ms ease;
  opacity: 0.7;
}
.nav-item--open > .nav-link--parent .nav-link__chevron { transform: rotate(-180deg); }
.nav-item--open > .nav-link--parent { color: var(--color-text-inverse); }

.nav-submenu {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 0;
  overflow: hidden;
  transition: max-height 220ms ease;
}
.nav-item--open .nav-submenu { max-height: 640px; }

.nav-sublink {
  display: block;
  padding: 8px 10px 8px 42px;
  font-size: 13px;
  color: rgba(246, 244, 238, 0.68);
  border-radius: var(--radius-sm);
  white-space: nowrap;
}
.nav-sublink:hover {
  background: rgba(246, 244, 238, 0.08);
  color: var(--color-text-inverse);
  text-decoration: none;
}
.nav-sublink--active {
  color: var(--color-accent);
  font-weight: 600;
}

.sidebar__footer {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-top: 12px;
  border-top: 1px solid rgba(246, 244, 238, 0.12);
}

/* Icon-rail collapsed state (desktop) */
.app-shell.is-collapsed { grid-template-columns: 76px 1fr; }
.app-shell.is-collapsed .sidebar__brand-text,
.app-shell.is-collapsed .nav-link__text,
.app-shell.is-collapsed .nav-link__chevron,
.app-shell.is-collapsed .nav-submenu {
  display: none;
}
.app-shell.is-collapsed .sidebar__brand { justify-content: center; padding-left: 0; padding-right: 0; }
.app-shell.is-collapsed .nav-link,
.app-shell.is-collapsed .nav-link--parent {
  justify-content: center;
  padding: 10px;
}
.app-shell.is-collapsed .topbar__menu-toggle { transform: scaleX(-1); }

.topbar__menu-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text);
  cursor: pointer;
  transition: background-color 120ms ease, transform 160ms ease;
}
.topbar__menu-toggle:hover { background: var(--color-surface-muted); }

.main {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.topbar {
  height: var(--topbar-height);
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px;
  gap: 16px;
}

.topbar__search {
  flex: 1;
  max-width: 420px;
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--color-surface-muted);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: 8px 12px;
  color: var(--color-text-muted);
  font-size: 14px;
}

.topbar__actions { display: flex; align-items: center; gap: 14px; }

.avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--color-secondary);
  color: var(--color-text-inverse);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 13px;
}

.content { padding: 24px; flex: 1 0 auto; }

/* Notification bell. Inert by design for now: the panel says there is nothing
   to show rather than inventing a count. Shares `.user-menu__panel` with the
   avatar dropdown, and the same `bindDropdown()` behaviour in custom.js. */
.icon-btn {
  position: relative;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--color-border);
  border-radius: 50%;
  background: var(--color-surface);
  color: var(--color-text-muted);
  cursor: pointer;
  padding: 0;
}
.icon-btn:hover { background: var(--color-surface-muted); color: var(--color-text); }
.icon-btn svg { width: 18px; height: 18px; }

.notif-menu { position: relative; }

.notif-empty {
  padding: 22px 18px;
  text-align: center;
  font-size: 13px;
  color: var(--color-text-muted);
}
.notif-empty strong { display: block; color: var(--color-text); margin-bottom: 4px; font-size: 14px; }

/* --- App footer -----------------------------------------------------------
   Sits below .content inside .main, so it scrolls with the page rather than
   floating. Left half identifies who is signed in and when; right half is the
   credit and build. Collapses to two stacked rows on narrow screens. */
.app-footer {
  border-top: 1px solid var(--color-border);
  background: var(--color-surface);
  padding: 12px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px 20px;
  flex-wrap: wrap;
  font-size: 12.5px;
  color: var(--color-text-muted);
}

.app-footer__who,
.app-footer__meta {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.app-footer__sep { opacity: 0.5; }
.app-footer__name { color: var(--color-text); font-weight: 600; }
.app-footer__credit { color: var(--color-primary-dark); font-weight: 600; text-decoration: none; }
.app-footer__credit:hover { text-decoration: underline; }
.app-footer__version { font-variant-numeric: tabular-nums; }


.breadcrumb { font-size: 13px; color: var(--color-text-muted); margin-bottom: 16px; }

@media (max-width: 900px) {
  .app-shell,
  .app-shell.is-collapsed {
    grid-template-columns: 1fr;
  }

  .sidebar {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    width: 280px;
    z-index: 50;
    transform: translateX(-100%);
    transition: transform 200ms ease;
    box-shadow: var(--shadow-lg);
  }
  .sidebar.sidebar--open { transform: translateX(0); }

  /* text/chevrons must stay visible on mobile even if desktop collapse ran before resize */
  .app-shell .sidebar__brand-text,
  .app-shell .nav-link__text,
  .app-shell .nav-link__chevron {
    display: block;
  }
  .app-shell .nav-link,
  .app-shell .nav-link--parent {
    justify-content: flex-start;
  }

  .sidebar-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(28, 35, 33, 0.45);
    z-index: 40;
    opacity: 0;
    pointer-events: none;
    transition: opacity 200ms ease;
  }
  .sidebar-backdrop.is-visible {
    opacity: 1;
    pointer-events: auto;
  }
}

/* --------------------------------------------------------------------------
   8. Dashboard cards & stats
   -------------------------------------------------------------------------- */
.panel {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 24px;
}

.panel-hero {
  background: linear-gradient(120deg, var(--color-success-bg), var(--color-surface) 60%);
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
  margin-bottom: 20px;
}

.panel-hero__meta p { color: var(--color-text-muted); margin: 4px 0 0; font-size: 14px; }

.panel-hero__actions { display: flex; gap: 12px; }

.chip {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 14px 18px;
  min-width: 190px;
  box-shadow: var(--shadow-sm);
}
.chip__label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--color-text-muted);
  margin-bottom: 6px;
}
.chip__value { font-family: var(--font-display); font-size: 20px; font-weight: 700; }

.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 16px;
  margin-top: 20px;
}

.stat {
  text-align: center;
  padding: 12px 8px;
}

.stat__ring {
  width: 68px;
  height: 68px;
  margin: 0 auto 10px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 13px;
  color: var(--color-primary-dark);
}

.stat__value { font-family: var(--font-display); font-size: 18px; font-weight: 700; }
.stat__label { font-size: 12px; color: var(--color-text-muted); margin-top: 2px; }

/* The Data Collection dashboard's level strip: the whole hierarchy
   (Division › Region › District › Upazila › Union › Block) with the level
   currently being listed highlighted, levels already picked as links back,
   and the ones below the current depth greyed out. Distinct from the
   breadcrumb next to it, which names places rather than levels. */
.level-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  font-size: 13px;
}

.level-strip__arrow { color: var(--color-text-muted); }

.level-strip__step {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 5px 12px;
  border-radius: 999px;
  border: 1px solid var(--color-border);
  color: var(--color-text-muted);
  text-decoration: none;
  background: var(--color-surface-muted);
}

a.level-strip__step:hover { border-color: var(--color-success); color: var(--color-success); }

.level-strip__step.is-current {
  background: var(--color-success-bg);
  border-color: var(--color-success);
  color: var(--color-success);
  font-weight: 600;
}

.level-strip__step.is-locked { opacity: 0.55; }

.level-strip__value { font-size: 12px; font-weight: 600; color: var(--color-text); }

/* "this number isn't in the source spreadsheet" — on a level step and on
   the matching tile. */
.derived-tag {
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  border: 1px dashed var(--color-border);
  border-radius: 4px;
  padding: 0 4px;
}

/* Target vs registered, one row of the achievement report. The bar is
   capped at 100% so an over-achieving row doesn't overflow the cell; the
   number printed beside it is the real figure, which is why they are one
   component and not two independent bits of markup. */
.achievement-bar {
  height: 8px;
  border-radius: 999px;
  background: var(--color-surface-muted);
  border: 1px solid var(--color-border);
  overflow: hidden;
}

.achievement-bar__fill {
  display: block;
  height: 100%;
  background: var(--color-warning);
  transition: width 200ms ease;
}

.achievement-bar__fill.is-met { background: var(--color-success); }

.achievement-bar__value {
  display: inline-block;
  margin-top: 4px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--color-warning);
}

.achievement-bar__value.is-met { color: var(--color-success); }

.grid-2 {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 20px;
  margin-top: 20px;
}

@media (max-width: 900px) {
  .grid-2 { grid-template-columns: 1fr; }
}

.queue-card {
  background: var(--color-success-bg);
  border-radius: var(--radius-md);
  padding: 18px;
}
.queue-card__label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--color-primary-dark);
  margin-bottom: 8px;
}
.queue-card__value { font-family: var(--font-display); font-size: 24px; font-weight: 700; }

/* A queue card that is also a link — used for the "accounts waiting for a
   role" tile, the one number on this panel with a single obvious next click.
   Inherits the tile look and only has to undo the anchor defaults. */
a.queue-card {
  display: block;
  color: inherit;
  text-decoration: none;
  border: 1.5px solid transparent;
  transition: border-color 0.18s ease, transform 0.18s ease;
}
a.queue-card:hover {
  border-color: var(--color-primary);
  transform: translateY(-1px);
}
/* Something is actually waiting: warm the tile so it reads before the rest. */
a.queue-card--alert {
  background: var(--color-warning-bg);
  border-color: var(--color-accent);
}

.queue-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
}

.quick-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 4px;
  border-bottom: 1px solid var(--color-border);
}
.quick-link:last-child { border-bottom: none; }
.quick-link h4 { margin: 0 0 2px; font-size: 14px; color: var(--color-text); }
.quick-link p { margin: 0; font-size: 12px; color: var(--color-text-muted); }

/* --- Home dashboard -------------------------------------------------------
   The donut. A template can't compute a gradient stop, so the share arrives as
   `--ring-pct` in a style attribute and the hue as a `.ring--<tone>` class; the
   hole is an inset pseudo-element so one element draws the whole thing. The
   second stop is `0` on purpose — that clamps the track to start exactly where
   the fill ends, whatever the percentage. */
.ring {
  position: relative;
  width: 88px;
  height: 88px;
  margin: 0 auto 12px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: conic-gradient(
    var(--ring-color, var(--color-primary)) calc(var(--ring-pct, 0) * 1%),
    var(--color-surface-muted) 0
  );
}

.ring::after {
  content: "";
  position: absolute;
  inset: 10px;
  border-radius: 50%;
  background: var(--color-surface);
}

.ring__pct {
  position: relative;
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 700;
  color: var(--ring-color, var(--color-primary));
}

.ring--crop { --ring-color: var(--color-primary); }
.ring--pattern { --ring-color: var(--color-secondary); }
.ring--fertilizer { --ring-color: var(--color-warning); }
.ring--area { --ring-color: var(--color-primary-dark); }
.ring--officer { --ring-color: var(--color-info, var(--color-secondary)); }

/* A ring tile is a link, so it must not pick up link styling. */
.stat-tile {
  display: block;
  text-decoration: none;
  color: inherit;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  transition: border-color 150ms ease, background 150ms ease;
}
.stat-tile:hover {
  border-color: var(--color-border);
  background: var(--color-surface-muted);
}

/* The suggested next step. One card, deliberately loud. */
.next-step {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--color-primary);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  padding: 18px 20px;
}
.next-step__eyebrow {
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.next-step h3 { margin: 4px 0 2px; font-size: 16px; }
.next-step p { margin: 0; font-size: 13px; color: var(--color-text-muted); max-width: 62ch; }

.dash-scopes { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.dash-scope {
  font-size: 12px;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  color: var(--color-text-muted);
}

.dash-links {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 0 24px;
}

.dash-feed { list-style: none; margin: 0; padding: 0; }
.dash-feed li {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 11px 0;
  border-bottom: 1px solid var(--color-border);
  font-size: 13px;
}
.dash-feed li:last-child { border-bottom: none; }
.dash-feed__where { font-weight: 600; }
.dash-feed__meta { color: var(--color-text-muted); font-size: 12px; }
.dash-feed__area { font-variant-numeric: tabular-nums; font-weight: 700; white-space: nowrap; }


/* --------------------------------------------------------------------------
   9. Modal (forgot-password overlay)
   -------------------------------------------------------------------------- */
.modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(20, 26, 24, 0.55);
  backdrop-filter: blur(2px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 160ms ease;
}
.modal-overlay.is-open {
  opacity: 1;
  pointer-events: auto;
}

.modal {
  width: 100%;
  max-width: 460px;
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: 32px;
  position: relative;
  transform: translateY(8px) scale(0.98);
  transition: transform 180ms ease;
}
.modal-overlay.is-open .modal {
  transform: translateY(0) scale(1);
}

.modal__close {
  position: absolute;
  top: 18px;
  right: 18px;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  cursor: pointer;
}
.modal__close:hover { background: var(--color-surface-muted); color: var(--color-text); }

.modal__title {
  font-size: 22px;
  margin: 0 0 8px;
  padding-right: 24px;
}

.modal__subtitle {
  font-size: 14px;
  color: var(--color-text-muted);
  margin: 0 0 22px;
  line-height: 1.5;
}

.modal__actions {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  margin-top: 20px;
}
.modal__actions .btn { min-width: 128px; }

.modal__success-icon {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--color-success-bg);
  color: var(--color-success);
  display: flex;
  align-items: center;
  justify-content: center;
}
.modal__success-icon--warning {
  background: var(--color-warning-bg);
  color: var(--color-warning);
}
.modal__success-icon .icon-not-found { display: none; }
.modal__success-icon.is-not-found { background: var(--color-warning-bg); color: var(--color-warning); }
.modal__success-icon.is-not-found .icon-found { display: none; }
.modal__success-icon.is-not-found .icon-not-found { display: block; }

@media (max-width: 520px) {
  .modal__actions { flex-direction: column-reverse; }
  .modal__actions .btn { width: 100%; }
}

/* Add Geo Location modal — a whole form rather than one email box, so it is
   wider and its body scrolls instead of pushing the footer off screen. */
.modal--form { max-width: 560px; padding: 28px; }
.modal--form .modal__subtitle { margin-bottom: 18px; }
.modal--form .modal__body {
  max-height: min(60vh, 520px);
  overflow-y: auto;
  /* Room for the focus ring on the right-hand edge of the inputs. */
  padding-right: 6px;
  margin-right: -6px;
}
.modal--form .modal__actions {
  border-top: 1px solid var(--color-border);
  padding-top: 18px;
}

/* Parent-picker chain. auto-fit keeps it to two columns at the modal's width
   (Division + District for an Upazila, say) and wraps deeper chains. */
.geo-parent-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 14px;
}

/* The level select drives every other field in the form, so it is tinted to
   read as the starting point rather than just another dropdown. */
.geo-level-select {
  background: var(--color-success-bg);
  border-color: var(--color-success);
  font-weight: 600;
}

.form-help {
  font-size: 12px;
  color: var(--color-text-muted);
  margin: 2px 0 8px;
  line-height: 1.5;
}

.geo-extras {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: 0 14px;
  margin-bottom: 18px;
}
.geo-extras > summary {
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  padding: 12px 0;
  list-style-position: inside;
}
.geo-extras > summary span { font-weight: normal; color: var(--color-text-muted); }
.geo-extras[open] > summary { border-bottom: 1px solid var(--color-border); margin-bottom: 14px; }
.geo-extras[open] { padding-bottom: 14px; }

.geo-form-actions {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  margin-top: 20px;
}

/* --------------------------------------------------------------------------
   9b. Cropping-pattern builder rows (Add/Edit Cropping Pattern)

   Each row is one crop slot in the sequence: a position badge, the season and
   crop selects, and the remove control. Collapses to a stacked card on narrow
   screens. A row flagged for deletion (its DELETE checkbox ticked) is dimmed
   and struck through rather than hidden, so the change is visible before save.
   -------------------------------------------------------------------------- */
.pattern-row {
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr) minmax(0, 1fr) auto;
  gap: 14px;
  align-items: end;
  padding: 14px;
  margin-bottom: 12px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.pattern-row__index {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  margin-bottom: 6px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 700;
  color: var(--color-primary-dark);
  background: var(--color-success-bg);
  border: 1px solid var(--color-primary);
}

.pattern-row__actions {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-bottom: 4px;
}

.pattern-row__remove { padding: 8px 14px; font-size: 13px; }

.pattern-row__delete {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--color-danger);
  cursor: pointer;
  white-space: nowrap;
}

.pattern-row--removed { opacity: 0.55; }
.pattern-row--removed .form-label,
.pattern-row--removed .pattern-row__index { text-decoration: line-through; }

@media (max-width: 720px) {
  .pattern-row { grid-template-columns: 1fr; align-items: stretch; }
  .pattern-row__index { margin-bottom: 0; }
  .pattern-row__actions { justify-content: flex-end; }
}

/* --------------------------------------------------------------------------
   10. OTP verification boxes
   -------------------------------------------------------------------------- */
.otp-boxes {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin-bottom: 22px;
}

.otp-box {
  width: 46px;
  height: 56px;
  text-align: center;
  font-size: 22px;
  font-family: var(--font-mono);
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.otp-box:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(31, 77, 58, 0.14);
}

@media (max-width: 420px) {
  .otp-boxes { gap: 8px; }
  .otp-box { width: 40px; height: 50px; font-size: 19px; }
}

/* --------------------------------------------------------------------------
   11. Social login (Google, etc.)
   -------------------------------------------------------------------------- */
.btn-social {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  padding: 11px 16px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
}
.btn-social:hover {
  background: var(--color-surface-muted);
  text-decoration: none;
}
.btn-social svg { flex-shrink: 0; }

.auth-divider {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 20px 0;
  color: var(--color-text-muted);
  font-size: 12px;
}
.auth-divider::before,
.auth-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--color-border);
}

/* --------------------------------------------------------------------------
   12. Profile page
   -------------------------------------------------------------------------- */
.profile-photo-row {
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
}

.profile-photo {
  width: 84px;
  height: 84px;
  border-radius: 50%;
  overflow: hidden;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-surface-muted);
  border: 2px solid var(--color-border);
  color: var(--color-primary-dark);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 26px;
}
.profile-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }

.profile-photo-input { display: none; }

.profile-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 20px;
}
@media (max-width: 640px) {
  .profile-grid { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   13. Topbar user menu (avatar dropdown)
   -------------------------------------------------------------------------- */
.user-menu { position: relative; }

.avatar-btn {
  display: block;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  border-radius: 50%;
}
.avatar-btn:hover .avatar,
.avatar-btn:hover .avatar-img { filter: brightness(0.94); }

.avatar-img {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  object-fit: cover;
  display: block;
}

.user-menu__panel {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  width: 224px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  padding: 8px;
  z-index: 70;
}

.user-menu__header {
  padding: 8px 10px 12px;
  margin-bottom: 6px;
  border-bottom: 1px solid var(--color-border);
}
.user-menu__header strong { display: block; font-size: 14px; color: var(--color-text); }
.user-menu__header span { font-size: 12px; color: var(--color-text-muted); }

.user-menu__item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 9px 10px;
  border-radius: var(--radius-sm);
  font-size: 14px;
  font-family: inherit;
  color: var(--color-text);
  background: none;
  border: none;
  text-align: left;
  cursor: pointer;
}
.user-menu__item:hover {
  background: var(--color-surface-muted);
  text-decoration: none;
}
.user-menu__item--danger { color: var(--color-danger); }

/* --------------------------------------------------------------------------
   14. Enumerator forms — photo/NID upload circles, status badges
   -------------------------------------------------------------------------- */
.required-mark { color: var(--color-danger); }

.upload-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}
@media (max-width: 900px) {
  .upload-grid { grid-template-columns: 1fr; }
}

.upload-field__hint {
  font-size: 12px;
  color: var(--color-text-muted);
  margin: 0 0 14px;
}

.upload-input { display: none; }

.upload-zone {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  margin: 0 auto;
  background: var(--color-surface-muted);
  border: 2px dashed var(--color-border);
  color: var(--color-text-muted);
  cursor: pointer;
  overflow: hidden;
  transition: border-color 120ms ease, background-color 120ms ease;
}
.upload-zone:hover { border-color: var(--color-primary); background: var(--color-success-bg); }
.upload-zone img { width: 100%; height: 100%; object-fit: cover; display: block; }
.upload-zone.has-image { border-style: solid; }

/* Photo — circular, like a profile headshot */
.upload-zone--circle {
  aspect-ratio: 1;
  max-width: 220px;
  border-radius: 50%;
}

/* NID front/back — rectangular, closer to a real ID card's proportions */
.upload-zone--rect {
  aspect-ratio: 1.6 / 1;
  max-width: 320px;
  border-radius: 14px;
}

.upload-field__status {
  text-align: center;
  margin-top: 14px;
}
.upload-field__status strong { display: block; font-size: 14px; color: var(--color-text); }
.upload-field__status span { display: block; font-size: 12px; color: var(--color-text-muted); margin-top: 2px; }

.upload-field__actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 10px;
  font-size: 13px;
}
.upload-field__browse {
  color: var(--color-secondary);
  font-weight: 600;
  cursor: pointer;
}
.upload-field__browse:hover { text-decoration: underline; }
.upload-field__required { color: var(--color-text-muted); }

.status-badge {
  display: inline-flex;
  align-items: center;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}
.status-badge--pending_approval { background: var(--color-warning-bg); color: var(--color-warning); }
.status-badge--approved,
.status-badge--active { background: var(--color-success-bg); color: var(--color-success); }
.status-badge--rejected,
.status-badge--disabled { background: var(--color-danger-bg); color: var(--color-danger); }
.status-badge--neutral { background: var(--color-surface-muted); color: var(--color-text-muted); }

/* --------------------------------------------------------------------------
   15. Location cascade grids (Division -> Region -> District -> Upazila -> Union)
   -------------------------------------------------------------------------- */
.location-grid,
.location-filter-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 20px;
}

/* --------------------------------------------------------------------------
   15b. Geolocation summary strip (Geolocation Management)

   How many Divisions, Regions, Districts … exist, read at a glance above the
   search form. Each tile is a link that searches that one level, so the strip
   doubles as the shortcut the Level checkboxes used to be when they all
   arrived pre-ticked.

   Tiles are sized by content rather than a fixed column count: eight levels
   across a wide screen, wrapping to two or three per row on a laptop, without
   a media query.
   -------------------------------------------------------------------------- */
.geo-summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
  gap: 12px;
  margin-top: 16px;
}

.geo-summary__tile {
  display: block;
  padding: 12px 14px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  text-decoration: none;
  color: inherit;
  transition: border-color 150ms ease, background 150ms ease;
}
.geo-summary__tile:hover {
  border-color: var(--color-primary);
  background: var(--color-surface-muted);
}

/* The grand total is the one tile that is not a level, so it reads as the
   summary of the others rather than a ninth sibling. */
.geo-summary__tile--total {
  background: var(--color-success-bg);
  border-color: transparent;
}

.geo-summary__label {
  font-size: 12px;
  color: var(--color-text-muted);
  margin-bottom: 4px;
}

.geo-summary__value {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 700;
  line-height: 1.1;
  color: var(--color-primary);
}

/* Only rendered when something is switched off — an all-active level says
   nothing here, which is exactly the signal worth noticing. */
.geo-summary__note {
  margin-top: 4px;
  font-size: 11.5px;
  color: var(--color-text-muted);
}

/* --------------------------------------------------------------------------
   15c. Level tick boxes (Geolocation Management search)

   A wrapping row of box+label pairs. They start empty — see the template
   comment — so the row needs to read as an invitation, not as a set of
   switches someone has just cleared.
   -------------------------------------------------------------------------- */
.level-picker {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 20px;
  margin-top: 6px;
}

.level-picker__option {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 14px;
  font-weight: normal;
  cursor: pointer;
  padding: 4px 10px 4px 6px;
  border: 1px solid transparent;
  border-radius: 999px;
}
.level-picker__option:hover { border-color: var(--color-border); }

/* :has() is what lets the ticked pill light up without a line of JavaScript.
   Unsupported in older browsers, where the box itself still shows the state —
   this is decoration on top of a working control, not the control. */
.level-picker__option:has(input:checked) {
  border-color: var(--color-primary);
  background: var(--color-success-bg);
  font-weight: 600;
}

.level-picker__count { color: var(--color-text-muted); font-size: 12.5px; }

/* --------------------------------------------------------------------------
   16. Public data-collection form (surveys app)

   Its own shell rather than base_app.html: the person filling this in has no
   account, so there is no sidebar, no topbar and nothing to navigate to — one
   readable column on the warm paper background, and it has to work on a phone
   held in a field.
   -------------------------------------------------------------------------- */
.public-shell {
  max-width: 720px;
  margin: 0 auto;
  padding: 32px 20px 56px;
}

.public-shell__header { margin-bottom: 20px; }

.public-shell__eyebrow {
  margin: 0 0 6px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.public-shell__title {
  font-family: var(--font-display);
  font-size: 30px;
  line-height: 1.2;
  font-weight: 600;
  margin: 0;
}

.public-shell__title-bn {
  font-family: var(--font-display);
  font-size: 20px;
  margin: 6px 0 0;
  color: var(--color-text-muted);
}

.public-shell__lede {
  margin: 12px 0 0;
  font-size: 15px;
  line-height: 1.6;
  color: var(--color-text-muted);
}

.public-shell__footer {
  margin-top: 28px;
  text-align: center;
  font-size: 12px;
  color: var(--color-text-muted);
}

.public-form__section-title {
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 600;
  margin: 0 0 4px;
}

.public-form__section-note {
  font-size: 14px;
  line-height: 1.6;
  color: var(--color-text-muted);
  margin: 0 0 18px;
}

.public-form__label-bn {
  margin: -4px 0 6px;
  font-size: 14px;
  color: var(--color-text-muted);
}

/* The line under the postal-code box: "Filled in Bogura, Rajshahi" or "That
   code isn't in our list — please choose below." Never an error state; an
   unknown code is not a reason to stop. */
.public-form__postal-status {
  margin: -6px 0 16px;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  font-size: 14px;
  background: var(--color-success-bg);
  color: var(--color-success);
}

.public-form__postal-status[data-state="unknown"] {
  background: var(--color-warning-bg);
  color: #8a5d10;
}

.public-form__postal-choices {
  margin: -6px 0 18px;
  padding: 14px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface-muted);
}

.public-form__postal-choice {
  display: block;
  width: 100%;
  text-align: left;
  margin: 0 0 8px;
  padding: 10px 12px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  font-family: var(--font-body);
  font-size: 14px;
  cursor: pointer;
}

.public-form__postal-choice:last-child { margin-bottom: 0; }
.public-form__postal-choice:hover { border-color: var(--color-success); }

/* Radio and checkbox questions: Django renders these as a <ul>. */
.public-form ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.public-form ul li {
  margin: 0 0 6px;
  font-size: 15px;
}

.public-form ul li label {
  display: flex;
  gap: 8px;
  align-items: baseline;
  cursor: pointer;
}

/* --------------------------------------------------------------------------
   17. Data-collection workspace (surveys app)

   `.panel` carries no margin of its own — pages that stack several of them
   have always added `style="margin-top:20px"` by hand, and the surveys pages
   didn't, so five cards fused into one slab with hairlines through it. Rather
   than give `.panel` a margin globally (it is also used as a grid item in
   `.grid-2`, where a margin would knock the second card out of line), the
   stack owns the spacing: one `.sv-stack` per page, `gap` between its cards.

   Everything else here exists to get the inline styles out of the templates.
   The two tables, the four card headers and the six "title + muted lede"
   pairs were each written out by hand with slightly different numbers; below
   they are components, so the padding and type scale are declared once and a
   sixth screen cannot drift from the other five.

   Prefixed `sv-` because this section is deliberately scoped to one app: no
   other template is being restyled in the same pass.
   -------------------------------------------------------------------------- */
.sv-stack {
  display: grid;
  gap: 20px;
  align-content: start;
}

/* Slightly roomier than the dashboard's 24px, and lifted off the paper — a
   form builder is a working surface, not a summary tile. */
.sv-stack > .panel {
  padding: 26px 28px;
  box-shadow: var(--shadow-sm);
}

/* An alert sitting between two cards is spaced by the stack's own gap; its
   built-in bottom margin would add to it and open a hole in the column. */
.sv-stack > .alert { margin-bottom: 0; }

/* -- card header: title, optional lede, actions on the right -------------- */
.sv-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
  margin-bottom: 20px;
}

/* A header that *is* the whole card (the Responses hero) shouldn't carry a
   trailing gap with nothing under it. */
.sv-head:only-child { margin-bottom: 0; }

.sv-head__text { flex: 1 1 320px; min-width: 0; }

.sv-head__actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  align-items: center;
}

.sv-title {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--color-primary-dark);
  margin: 0;
}

.sv-title__bn {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 500;
  color: var(--color-text-muted);
  margin: 4px 0 0;
}

.sv-lede {
  margin: 8px 0 0;
  max-width: 68ch;
  font-size: 14px;
  line-height: 1.6;
  color: var(--color-text-muted);
}

.sv-eyebrow {
  margin: 0 0 6px;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

/* -- fields (surveys/_field.html) ----------------------------------------- */
/* A checkbox reads the other way round: box first, label beside it, help text
   under the label rather than under the row. */
.sv-check {
  display: flex;
  gap: 10px;
  align-items: flex-start;
}

.sv-check__text { min-width: 0; }

.sv-check__label {
  margin: 0;
  font-weight: 500;
  cursor: pointer;
}

.sv-help { margin: 6px 0 0; }
.sv-help--tight { margin: 2px 0 0; }

/* -- fact strip: the form's shape at a glance ----------------------------- */
/* Questions · Responses · how deep it asks · access code. A row of small
   label/value pairs rather than one long sentence of dot-separated text: the
   numbers are what someone came to the page to read. */
.sv-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 1px;
  margin: 0;
  padding: 0;
  list-style: none;
  background: var(--color-border);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.sv-facts__item {
  background: var(--color-surface-muted);
  padding: 12px 16px;
  min-width: 0;
}

.sv-facts__label {
  display: block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: 3px;
}

.sv-facts__value {
  display: block;
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 700;
  line-height: 1.3;
  color: var(--color-text);
  overflow-wrap: anywhere;
}

.sv-facts__value--code {
  font-family: var(--font-mono);
  font-size: 14px;
  letter-spacing: 0.04em;
}

/* -- a row of controls parked at the foot of a card ----------------------- */
.sv-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--color-border);
}

.sv-toolbar form { margin: 0; }

.sv-toolbar__note {
  font-size: 13px;
  color: var(--color-text-muted);
}

/* -- tables --------------------------------------------------------------- */
/* The project has no table class — every table so far was inline-styled, so
   the questions list and the responses grid had different header tints and
   cell padding. One component now, `border-collapse: separate` so the header
   corners can be rounded inside the card. */
.sv-table-scroll {
  overflow-x: auto;
  /* Bleed a few pixels so a focus ring on a first-column link isn't clipped
     by the scroll container. */
  margin: 0 -4px;
  padding: 0 4px;
}

.sv-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 14px;
}

.sv-table thead th {
  background: var(--color-surface-muted);
  border-bottom: 1px solid var(--color-border);
  padding: 11px 14px;
  text-align: left;
  white-space: nowrap;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.sv-table thead th:first-child { border-top-left-radius: var(--radius-sm); }
.sv-table thead th:last-child { border-top-right-radius: var(--radius-sm); }

.sv-table td {
  padding: 13px 14px;
  border-bottom: 1px solid var(--color-border);
  vertical-align: top;
}

.sv-table tbody tr:last-child td { border-bottom: none; }
.sv-table tbody tr:hover td { background: rgba(231, 242, 234, 0.5); }

.sv-table .is-num {
  text-align: right;
}

/* Figures line up column-wise; the header above them stays in the body face. */
.sv-table td.is-num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

.sv-table .is-mono {
  font-family: var(--font-mono);
  font-size: 13px;
}

.sv-table .is-actions {
  width: 1%;
  white-space: nowrap;
}

.sv-table__primary { font-weight: 600; }

.sv-table__sub {
  margin: 2px 0 0;
  font-size: 12.5px;
  color: var(--color-text-muted);
}

.sv-table__tags {
  margin: 5px 0 0;
  font-size: 12px;
  color: var(--color-text-muted);
}

/* -- per-row controls (move up/down, edit, delete) ------------------------ */
/* Four separate <form>s and an <a>, so the gaps used to come from whatever
   whitespace the template happened to leave. */
.sv-row-actions {
  display: flex;
  gap: 6px;
  align-items: center;
  justify-content: flex-end;
}

.sv-row-actions form { margin: 0; display: inline-flex; }

.btn-sm {
  padding: 7px 12px;
  font-size: 13px;
  font-weight: 600;
}

.btn-icon {
  width: 32px;
  height: 32px;
  padding: 0;
  font-size: 14px;
  line-height: 1;
}

.sv-row-actions .btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.sv-row-actions .btn:disabled:hover { border-color: var(--color-border); }

/* -- a read-only URL with a Copy button beside it ------------------------- */
.sv-linkbox {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
}

.sv-linkbox .form-control {
  flex: 1 1 320px;
  min-width: 0;
  font-family: var(--font-mono);
  font-size: 13px;
  background: var(--color-surface-muted);
  color: var(--color-text-muted);
}

/* -- "nothing here yet" --------------------------------------------------- */
.sv-empty {
  border: 1px dashed var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-muted);
  padding: 30px 24px;
  text-align: center;
  font-size: 14px;
  line-height: 1.6;
  color: var(--color-text-muted);
}

.sv-empty__title {
  display: block;
  margin: 0 0 4px;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 600;
  color: var(--color-text);
}

.sv-empty p { margin: 0; }

/* -- pager under a table -------------------------------------------------- */
.sv-pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--color-border);
  font-size: 14px;
}

.sv-pager__status { color: var(--color-text-muted); }

/* -- save / cancel bar at the foot of a multi-card form ------------------- */
.sv-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
  flex-wrap: wrap;
}

.sv-actions__note {
  margin: 0;
  margin-right: auto;
  font-size: 13px;
  color: var(--color-text-muted);
}

/* -- an inline stable key ("crop", "farmer_name") ------------------------- */
.sv-code {
  font-family: var(--font-mono);
  font-size: 13px;
  background: var(--color-surface-muted);
  border: 1px solid var(--color-border);
  border-radius: 4px;
  padding: 1px 6px;
  white-space: nowrap;
}

/* Off the screen but still in the tab order for a browser that autofills it —
   the field nobody should see. Deliberately not named after what it catches.
   Clipped in place rather than pushed to left:-9999px, because one of these
   sits inside .sv-table-scroll, which has overflow-x: auto — a far-away child
   there is a scrollbar waiting to happen. */
.sv-offscreen {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* -- the public form's own cards ------------------------------------------ */
/* Same stack, tighter padding: this is read on a phone held in a field, and
   the column is only 720px wide to begin with. */
.public-shell .sv-stack > .panel { padding: 22px 24px; }

/* "1 Where are you?" — a numbered step tells a respondent how much form is
   left, which a plain heading does not. */
.public-step {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  margin-bottom: 18px;
}

.public-step__num {
  flex: 0 0 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--color-primary);
  color: var(--color-text-inverse);
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

.public-step__text { min-width: 0; }

/* The step heading and its note already have their own type; inside a step
   they only need their margins collapsing into the flex row. */
.public-step .public-form__section-title { margin-bottom: 2px; }
.public-step .public-form__section-note { margin-bottom: 0; }

.public-form__closer {
  margin: 14px 0 0;
  text-align: center;
  font-size: 13px;
  line-height: 1.6;
  color: var(--color-text-muted);
}

/* The one sentence a respondent came to this page to read — the thank-you, or
   the reason a form is shut. Set above body copy so it does not read as fine
   print next to the notes underneath it. */
.public-form__thanks {
  margin: 0;
  font-size: 16px;
  line-height: 1.6;
}

.public-form__section-title + .public-form__thanks { margin-top: 8px; }

/* -- "Picture" / "File" questions: what was chosen, and how big ------------- */
/* Filled in by initSurveyUploadPreview() and hidden until a file is picked, so
   a phone with JS off simply shows the file input on its own. The strip sits
   directly under the input inside the same .form-group, which is why it borrows
   the surface-muted fill rather than drawing its own card. */
.sv-filepreview {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 10px;
  padding: 10px 12px;
  background: var(--color-surface-muted);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

/* Fixed box, cover fit: a portrait phone photograph and a wide scan have to
   line up the same way down a column of questions. */
.sv-filepreview__thumb {
  flex: 0 0 56px;
  width: 56px;
  height: 56px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
}

.sv-filepreview__meta {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* Ellipsis rather than wrap: "scan-of-my-land-record-2026-final.pdf" would
   otherwise push the size onto a third line on a narrow screen. */
.sv-filepreview__name {
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sv-filepreview__size {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--color-text-muted);
}

/* Over the limit. Only a warning — the server is what rejects it — so the
   colour changes and the row stays put. */
.sv-filepreview.is-over {
  border-color: var(--color-danger);
  background: var(--color-danger-bg);
}

.sv-filepreview.is-over .sv-filepreview__size {
  color: var(--color-danger);
  font-family: var(--font-body);
}

/* -- the review step ------------------------------------------------------- */
/* Answers read back before anything is stored. A definition list, because that
   is what this is — a label and the value belonging to it — and because a
   screen reader then announces the pair rather than two loose lines. */
.public-review {
  margin: 0;
  border-top: 1px solid var(--color-border);
}

.public-review__row {
  display: grid;
  grid-template-columns: minmax(140px, 38%) 1fr;
  gap: 8px 16px;
  padding: 11px 2px;
  border-bottom: 1px solid var(--color-border);
}

/* Zebra striping is deliberately absent: the borders already separate the rows,
   and a respondent checking their own answers reads down the values, not
   across. */
.public-review__label {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text-muted);
}

.public-review__label-bn {
  display: block;
  font-weight: 400;
  font-size: 13px;
}

.public-review__value {
  margin: 0;
  font-size: 15px;
  line-height: 1.55;
  color: var(--color-text);
  overflow-wrap: anywhere;
}

/* An optional question nobody answered. Muted and italic rather than hidden: a
   respondent should be able to see what they skipped while they still can. */
.public-review__value--missing {
  color: var(--color-text-muted);
  font-style: italic;
}

/* "attached" beside a filename — the bytes are held server-side and there is no
   thumbnail to show at this point, so the word does the reassuring. */
.public-review__attached {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--color-surface-muted);
  border: 1px solid var(--color-border);
  font-size: 11px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  vertical-align: 1px;
}

/* The confirmation. Big hit area and a real border, because this is the one
   control on the page that has to be pressed on purpose. */
.public-review__confirm {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 16px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-muted);
  cursor: pointer;
}

.public-review__confirm input {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin: 1px 0 0;
  accent-color: var(--color-primary);
}

.public-review__confirm-text {
  font-size: 15px;
  line-height: 1.5;
  color: var(--color-text);
}

/* Submit first in the source, so a keyboard and a screen reader meet the
   ordinary action before the escape hatch. */
.public-review__actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 14px;
}

/* Held across an Edit: the file box below it is empty because no browser can
   repopulate one, so this line is the only thing telling the respondent their
   photograph is still there. */
.public-form__held {
  margin: 8px 0 0;
  font-size: 13px;
  line-height: 1.6;
  color: var(--color-text-muted);
}

/* -- phones --------------------------------------------------------------- */
@media (max-width: 640px) {
  .sv-stack { gap: 14px; }
  .sv-stack > .panel,
  .public-shell .sv-stack > .panel { padding: 18px 16px; }
  .sv-title { font-size: 18px; }
  .sv-head { gap: 14px; }
  .sv-head__actions .btn { flex: 1 1 auto; }
  .sv-table { font-size: 13px; }
  .sv-table thead th { padding: 10px 12px; }
  .sv-table td { padding: 11px 12px; }
  .sv-actions { flex-direction: column-reverse; align-items: stretch; }
  .sv-actions .btn { width: 100%; }
  .sv-actions__note { margin-right: 0; text-align: center; }
  .public-step__num { flex-basis: 30px; height: 30px; font-size: 15px; }
  .sv-filepreview__thumb { flex-basis: 44px; width: 44px; height: 44px; }
  /* One column: 38% of a 360px screen is not a column, it is a word per line. */
  .public-review__row { grid-template-columns: 1fr; gap: 2px; padding: 10px 2px; }
}

/* Area Management ==========================================================

   Three shapes. `.area-picker` is the responsive band of filter controls shared
   by the entry screen and the register — auto-fit rather than a fixed column
   count so it reads the same whether it holds two controls or four.

   `.loc-picker` is the level-first location picker: a level select beside one
   combobox whose results are fetched per keystroke. Its list is absolutely
   positioned inside `.loc-picker__unit`, which is why that cell is the
   containing block and the picker itself never clips.

   `.area-grid*` dresses the hectare entry form: a sticky summary bar carrying
   the chosen place and the running total, and right-aligned number boxes so a
   column of figures lines up on the decimal point the way the paper DAE area
   statement does.
   -------------------------------------------------------------------------- */
.area-picker {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 14px;
}

/* The unit box earns more room than the level select or the year: it holds a
   place name, not a word from a list of six. */
.loc-picker {
  display: grid;
  grid-template-columns: minmax(170px, 1fr) minmax(240px, 2fr) minmax(150px, 1fr);
  gap: 14px;
  align-items: start;
}

.loc-picker__unit { position: relative; }

.loc-picker__list {
  position: absolute;
  z-index: 20;
  left: 0;
  right: 0;
  top: calc(100% + 4px);
  margin: 0;
  padding: 4px;
  list-style: none;
  max-height: 280px;
  overflow-y: auto;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 10px;
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.14);
}

.loc-picker__list li {
  padding: 8px 10px;
  border-radius: 8px;
  cursor: pointer;
}

.loc-picker__list li.is-active,
.loc-picker__list li:hover {
  background: var(--color-success-bg);
}

.loc-picker__name {
  display: block;
  font-weight: 600;
  font-size: 14px;
  color: var(--color-text);
}

.loc-picker__meta {
  display: block;
  margin-top: 2px;
  font-size: 12px;
  color: var(--color-text-muted);
}

.loc-picker__hint {
  margin: 6px 0 0;
  min-height: 16px;
  font-size: 12px;
  color: var(--color-text-muted);
}

.loc-picker__error {
  margin: 6px 0 0;
  font-size: 12px;
  color: var(--color-danger);
}

.area-grid__bar {
  display: flex;
  gap: 16px;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  position: sticky;
  top: 12px;
  z-index: 3;
}

.area-grid__level {
  display: inline-block;
  margin-left: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  color: var(--color-primary-dark);
  background: var(--color-success-bg);
  border: 1px solid var(--color-primary);
}

.area-grid__chain {
  margin: 0;
  font-size: 13px;
  color: var(--color-text-muted);
}

.area-grid__total {
  font-size: 13px;
  color: var(--color-text-muted);
  text-align: right;
  white-space: nowrap;
}

.area-grid__total span { display: block; }

.area-grid__total strong {
  font-size: 22px;
  color: var(--color-primary-dark);
}

/* Figures read as a column, so they are right-aligned and tabular — 1.00 and
   11.00 keep the same digit width. */
.area-grid__input {
  max-width: 160px;
  margin-left: auto;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.area-totals {
  display: flex;
  gap: 28px;
  align-items: baseline;
  flex-wrap: wrap;
}

.area-totals__stat span {
  display: block;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}

.area-totals__stat strong {
  font-size: 20px;
  color: var(--color-text);
}

@media (max-width: 640px) {
  .area-grid__bar { position: static; }
  .area-grid__total { text-align: left; }
  .area-grid__input { max-width: none; }
  .loc-picker { grid-template-columns: 1fr; }
}

/* Reports ==================================================================

   Four screens share this handful of shapes:

   `.rpt-tabs` switches between them while keeping the filter query string.
   `.rpt-stats` is the dashboard's headline grid. `.rpt-scroll` + `.rpt-table`
   carry the wide statement — the header row and the first column are sticky,
   because a location × pattern table is read by scrolling sideways and losing
   either one makes the numbers meaningless. `.rpt-bar` draws proportions with a
   plain div width, so no chart library is loaded for four bars.

   The print block at the end is the point of the whole module: a DAE office
   prints these tables, so everything that is chrome on screen (sidebar,
   topbar, filters, buttons) is dropped and the table is allowed the full page.
   -------------------------------------------------------------------------- */
.rpt-tabs {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 20px;
}

.rpt-tab {
  padding: 9px 16px;
  border-radius: 999px;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text-muted);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
}

.rpt-tab:hover { border-color: var(--color-primary); color: var(--color-primary-dark); }

.rpt-tab--active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}

.rpt-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 18px;
}

.rpt-stat span {
  display: block;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}

.rpt-stat strong {
  font-size: 26px;
  color: var(--color-primary-dark);
  font-variant-numeric: tabular-nums;
}

.rpt-stat small { display: block; font-size: 12px; color: var(--color-text-muted); }

.rpt-scroll { overflow-x: auto; }

/* Table captions carry the report's scope for screen readers; sighted users
   already have it in the hero and the filter bar. */
.rpt-caption {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.rpt-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}

.rpt-table th,
.rpt-table td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--color-border);
  white-space: nowrap;
}

.rpt-table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--color-success-bg);
  text-align: right;
  vertical-align: bottom;
  font-size: 13px;
}

.rpt-table thead th:first-child,
.rpt-table tbody th {
  position: sticky;
  left: 0;
  z-index: 3;
  background: var(--color-surface);
  text-align: left;
  font-weight: 600;
  max-width: 260px;
  white-space: normal;
}

.rpt-table thead th:first-child { background: var(--color-success-bg); }
.rpt-table td { text-align: right; }
.rpt-table td.rpt-num--empty { color: var(--color-border); }
.rpt-table tbody tr:hover td { background: var(--color-success-bg); }
.rpt-table tfoot th,
.rpt-table tfoot td {
  background: var(--color-surface);
  font-weight: 700;
  border-top: 2px solid var(--color-primary);
  position: sticky;
  bottom: 0;
}

.rpt-group th {
  background: var(--color-success-bg);
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--color-primary-dark);
}

.rpt-flag {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  color: #8a5300;
  background: #fff4e0;
  border: 1px solid #f0c07a;
}

.rpt-bar {
  display: grid;
  grid-template-columns: minmax(120px, 1fr) 3fr auto;
  gap: 12px;
  align-items: center;
  padding: 7px 0;
  font-size: 14px;
}

.rpt-bar__track {
  height: 10px;
  border-radius: 999px;
  background: var(--color-success-bg);
  overflow: hidden;
}

.rpt-bar__fill { height: 100%; background: var(--color-primary); border-radius: 999px; }
.rpt-bar__value { font-variant-numeric: tabular-nums; font-weight: 600; }

.rpt-up { color: var(--color-primary-dark); font-weight: 600; }
.rpt-down { color: var(--color-danger); font-weight: 600; }

@media (max-width: 640px) {
  .rpt-bar { grid-template-columns: 1fr auto; }
  .rpt-bar__track { grid-column: 1 / -1; }
}

@media print {
  .sidebar,
  .sidebar-backdrop,
  .topbar,
  .rpt-tabs,
  .rpt-noprint,
  .panel-hero__actions { display: none !important; }

  .app-shell, .main, .content { display: block; margin: 0; padding: 0; }
  .panel { box-shadow: none; border: none; padding: 0 0 12px; }
  .rpt-scroll { overflow: visible; }
  .rpt-table { font-size: 10pt; }
  .rpt-table th, .rpt-table td { padding: 4px 6px; white-space: normal; }
  .rpt-table thead th, .rpt-table tbody th, .rpt-table tfoot th, .rpt-table tfoot td {
    position: static;
  }
  .rpt-table thead { display: table-header-group; }
  .rpt-table tr { page-break-inside: avoid; }
  a[href]::after { content: ""; }
  @page { size: landscape; margin: 12mm; }
}








