/* Survey Console theme.
   Sits on top of Bootstrap 5. Identity comes from three things only:
   deep dairy-green, micro-caps field labels, and monospace identifiers. */

:root {
  --ink:        #0F211D;
  --ink-soft:   #4A5B55;
  --page:       #E9EDEA;
  --surface:    #FFFFFF;
  --line:       #C9D4CE;
  --primary:    #17594A;
  --primary-dk: #0E4437;
  --accent:     #9C6F0C;
  --danger:     #8E2B26;
  --ok:         #1F6B3A;

  --bs-body-bg: var(--page);
  --bs-body-color: var(--ink);
  --bs-border-color: var(--line);
  --bs-link-color: var(--primary);
  --bs-link-hover-color: var(--primary-dk);
}

body {
  background: var(--page);
  color: var(--ink);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
               "Helvetica Neue", Arial, "Noto Sans Devanagari", sans-serif;
  font-size: 15px;
}

/* Signature: every identifier is monospace and letter-spaced, so GS10001
   can never be misread as GS1O001. Applies to sample IDs, animal tags,
   farmer codes, mobile numbers. */
.id-code, input.id-code {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
               "Liberation Mono", monospace;
  letter-spacing: 0.08em;
  font-variant-numeric: tabular-nums;
  text-transform: uppercase;
}

/* Micro-caps field label, borrowed from a paper requisition slip. */
.field-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 0.35rem;
  display: block;
}

.slip {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 2px;
  box-shadow: 0 1px 0 var(--line);
}

/* Ruled header, like the tear-off strip on a lab form. */
.slip-head {
  border-bottom: 1px solid var(--line);
  padding: 1rem 1.25rem;
  background: linear-gradient(var(--surface), var(--surface)) padding-box;
}

.slip-head h1, .slip-head h2 { font-size: 1.05rem; margin: 0; font-weight: 600; }

.series-chip {
  display: inline-block;
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  padding: 0.4rem 0.6rem;
  font-size: 12px;
  background: #FBF8F1;
  color: var(--ink);
  border-radius: 0;
}

.btn-primary {
  --bs-btn-bg: var(--primary);
  --bs-btn-border-color: var(--primary);
  --bs-btn-hover-bg: var(--primary-dk);
  --bs-btn-hover-border-color: var(--primary-dk);
  --bs-btn-active-bg: var(--primary-dk);
  --bs-btn-active-border-color: var(--primary-dk);
  --bs-btn-disabled-bg: #7E948C;
  --bs-btn-disabled-border-color: #7E948C;
  border-radius: 2px;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.form-control {
  border-radius: 2px;
  border-color: var(--line);
  padding: 0.6rem 0.7rem;
  font-size: 16px; /* 16px stops iOS Safari zooming on focus */
}

/* A select is NOT a text input: the dropdown arrow is painted inside the
   right padding. The shorthand above used to apply here too, cutting that
   space from Bootstrap's 2.25rem to 0.7rem — so the arrow sat on top of the
   last character in every select in the app. Only obvious on narrow ones. */
.form-select {
  border-radius: 2px;
  border-color: var(--line);
  padding: 0.6rem 2.25rem 0.6rem 0.7rem;
  font-size: 16px;
}

.form-select-sm {
  padding-top: 0.35rem;
  padding-bottom: 0.35rem;
  padding-right: 2.25rem;
  font-size: 14px;
}

.form-control:focus, .form-select:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(23, 89, 74, 0.16);
}

:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

.topbar {
  background: var(--primary-dk);
  color: #EAF1EE;
  border-bottom: 3px solid var(--accent);
}
.topbar a { color: #EAF1EE; text-decoration: none; }
.topbar .role-tag {
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.85;
}

.alert { border-radius: 2px; border-width: 0 0 0 3px; font-size: 14px; }
.alert-error   { background: #FBEDEC; border-left-color: var(--danger); color: #5E1A16; }
.alert-success { background: #EDF5EF; border-left-color: var(--ok);     color: #14401F; }

.table-slip { font-size: 14px; }
.table-slip th {
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-soft);
  font-weight: 600;
  border-bottom: 1px solid var(--line);
}
.table-slip td { border-bottom: 1px solid #E4EAE7; }

.status-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; }
.status-dot.ok   { background: var(--ok); }
.status-dot.fail { background: var(--danger); }

.login-wrap { min-height: 100vh; display: flex; align-items: center; }

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* Form field states */
.form-control.is-invalid { border-color: var(--danger); }
.form-control.is-invalid:focus { box-shadow: 0 0 0 3px rgba(142, 43, 38, 0.15); }
.field-error { color: var(--danger); font-size: 13px; margin-top: 0.3rem; }
.field-hint  { color: var(--ink-soft); font-size: 12px; margin-top: 0.3rem; }
.required-star { color: var(--danger); font-weight: 600; }

/* --- User management --- */
.stat-number {
  font-size: 1.7rem;
  font-weight: 600;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

.badge-state {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.22rem 0.5rem;
  border-radius: 2px;
  border: 1px solid transparent;
  white-space: nowrap;
}
.badge-state.active   { background: #E7F2EA; color: #14401F; border-color: #BFDCC7; }
.badge-state.inactive { background: #EEEFEE; color: #5A5F5C; border-color: #D6DAD8; }
.badge-state.pending  { background: #FBF4E4; color: #5A4208; border-color: #E6D5A8; }
.badge-state.locked   { background: #FBEDEC; color: #5E1A16; border-color: #E3BDBA; }

.role-select { min-width: 130px; font-size: 13px; padding: 0.3rem 0.5rem; }

.btn-success-soft {
  background: #E7F2EA;
  border: 1px solid #BFDCC7;
  color: #14401F;
  border-radius: 2px;
  font-weight: 600;
}
.btn-success-soft:hover { background: #D8E9DD; color: #0E2E16; }

.table-slip td { vertical-align: middle; }

/* --- Projects and multi-role --- */
.badge-state.admin { background: #EDE9F5; color: #35235E; border-color: #CFC4E4; }

.role-tag-inline {
  display: inline-block;
  font-size: 11px;
  padding: 0.15rem 0.4rem;
  margin: 0 0.15rem 0.15rem 0;
  background: #EDF1EF;
  border: 1px solid var(--line);
  border-radius: 2px;
  color: var(--ink-soft);
  white-space: nowrap;
}

.project-chip {
  font-size: 12px;
  padding: 0.25rem 0.6rem;
  background: rgba(255,255,255,0.12);
  border-radius: 2px;
  white-space: nowrap;
}
.project-chip a { text-decoration: underline; opacity: 0.85; margin-left: 0.4rem; }

.project-block {
  border: 1px solid var(--line);
  border-left: 3px solid var(--primary);
  padding: 0.85rem 1rem;
  background: #FCFDFC;
}

.role-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.role-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 13px;
  padding: 0.3rem 0.6rem;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: var(--surface);
  cursor: pointer;
  user-select: none;
}
.role-chip:hover { border-color: var(--primary); }
.role-chip input { margin: 0; cursor: pointer; }
.role-chip:has(input:checked) {
  background: #E7F2EA;
  border-color: var(--primary);
  font-weight: 600;
}

.project-choice {
  display: block;
  padding: 0.85rem 1rem;
  border: 1px solid var(--line);
  border-left: 3px solid var(--primary);
  background: var(--surface);
  border-radius: 2px;
  cursor: pointer;
}
.project-choice:hover { background: #F4F8F6; border-left-color: var(--accent); }

/* --- Landing page and project activity cards --- */
.project-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 3px solid var(--primary);
  border-radius: 2px;
  padding: 1.1rem 1.25rem;
}
.project-card:hover { border-left-color: var(--accent); }

.activity-card {
  display: block;
  height: 100%;
  background: var(--surface);
  border: 1px solid var(--line);
  border-top: 3px solid var(--primary);
  border-radius: 2px;
  padding: 1.1rem 1.25rem;
  text-decoration: none;
  color: var(--ink);
  transition: border-color .12s ease, background .12s ease;
}
.activity-card:hover {
  border-top-color: var(--accent);
  background: #FCFDFC;
  color: var(--ink);
}
.activity-card .activity-title {
  font-size: 1.05rem;
  font-weight: 600;
  margin: 0.2rem 0 0.4rem;
}
.activity-card p {
  margin: 0;
  font-size: 13px;
  color: var(--ink-soft);
  line-height: 1.45;
}

/* --- Census browser --- */
.census-col { max-height: 62vh; overflow-y: auto; }
.census-row {
  display: flex; align-items: stretch;
  border-bottom: 1px solid #E4EAE7;
}
.census-row:last-child { border-bottom: none; }
.census-row.selected { background: #E7F2EA; }
.census-row:hover { background: #F4F8F6; }
.census-row.selected:hover { background: #DEEDE3; }

.census-link {
  flex: 1 1 auto; display: block;
  padding: 0.6rem 0.85rem;
  text-decoration: none; color: var(--ink);
  min-width: 0;
}
.census-name  { display: block; font-size: 14px; font-weight: 500; }
.census-local { display: block; font-size: 12px; color: var(--ink-soft); }
.census-meta  { display: block; font-size: 11px; color: var(--ink-soft); margin-top: 0.15rem; }

.census-edit {
  flex: 0 0 auto; display: flex; align-items: center;
  padding: 0 0.75rem;
  color: var(--ink-soft); text-decoration: none;
  border-left: 1px solid #E4EAE7;
}
.census-edit:hover { color: var(--primary); background: var(--surface); }

/* Faint placeholders, so an example ID never reads as a real value. */
.form-control::placeholder { color: #A9B4AF; opacity: 1; }
.form-control.id-code::placeholder { color: #B8C2BD; letter-spacing: 0.08em; }

/* Progress towards a survey-eligibility minimum. */
.gate-bar {
  height: 5px;
  background: #E4EAE7;
  border-radius: 2px;
  overflow: hidden;
}
.gate-bar-fill {
  height: 100%;
  background: var(--primary);
  transition: width .2s ease;
}

/* --- Searchable dropdown -------------------------------------------------
   A native <select> cannot be searched, so this is an explicit panel: a
   toggle button, a search box inside the panel, and a scrollable option
   list. Keeps working with thousands of villages. */

.combo { position: relative; }

.combo-toggle {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.6rem 0.7rem;
  font-size: 16px;              /* 16px stops iOS zooming on focus */
  text-align: left;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 2px;
  color: var(--ink);
  cursor: pointer;
}
.combo-toggle:disabled {
  background: #F2F4F3;
  color: var(--ink-soft);
  cursor: not-allowed;
}
.combo.open .combo-toggle,
.combo-toggle:focus-visible {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(23, 89, 74, 0.16);
  outline: none;
}
.combo.is-invalid-combo .combo-toggle { border-color: var(--danger); }

.combo-caret { color: var(--ink-soft); font-size: 12px; flex: 0 0 auto; }
.combo.open .combo-caret { transform: rotate(180deg); }

.combo-panel {
  position: absolute;
  z-index: 20;
  top: calc(100% + 2px);
  left: 0;
  right: 0;
  background: var(--surface);
  border: 1px solid var(--primary);
  border-radius: 2px;
  box-shadow: 0 6px 18px rgba(15, 33, 29, 0.12);
}

.combo-search {
  width: 100%;
  padding: 0.55rem 0.7rem;
  font-size: 15px;
  border: none;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  outline: none;
}

.combo-options { max-height: 240px; overflow-y: auto; }

.combo-option {
  display: block;
  width: 100%;
  padding: 0.5rem 0.7rem;
  font-size: 14px;
  text-align: left;
  background: none;
  border: none;
  border-bottom: 1px solid #EDF1EF;
  color: var(--ink);
  cursor: pointer;
}
.combo-option:last-child { border-bottom: none; }
.combo-option:hover, .combo-option:focus-visible {
  background: #F4F8F6;
  outline: none;
}
.combo-option.selected { background: #E7F2EA; font-weight: 600; }

.combo-empty {
  padding: 0.7rem;
  font-size: 13px;
  color: var(--ink-soft);
}

/* Read-only coordinate boxes: filled by the device, never typed. */
input[readonly].id-code { background: #F7F9F8; color: var(--ink-soft); }

/* Two-way choice: new survey, or another sample against an existing one. */
.choice-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 3px solid var(--primary);
  border-radius: 2px;
  padding: 1.1rem 1.25rem;
}
.choice-card:hover { border-left-color: var(--accent); }

/* --- Created / modified footer --- */
.audit-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.5rem;
  margin-top: 1rem;
  padding-top: 0.75rem;
  border-top: 1px solid #E4EAE7;
  font-size: 12px;
  color: var(--ink-soft);
}
.audit-item { white-space: nowrap; }
.audit-label {
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-size: 10px;
  margin-right: 0.3rem;
}

/* --- Narrow-screen navigation ------------------------------------------
   Below the lg breakpoint the inline links are replaced by one menu, so
   Users, Projects and Masters stay reachable on a phone instead of simply
   disappearing. */

.nav-burger {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  width: 40px;
  height: 36px;
  padding: 0 8px;
  background: rgba(255, 255, 255, 0.12);
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 2px;
  cursor: pointer;
}
.nav-burger:hover { background: rgba(255, 255, 255, 0.2); }
.nav-burger:focus-visible {
  outline: 2px solid #FFFFFF;
  outline-offset: 2px;
}

.nav-burger-bar {
  display: block;
  height: 2px;
  width: 100%;
  background: #EAF1EE;
  border-radius: 1px;
}

.nav-menu {
  min-width: 260px;
  max-height: 80vh;
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: 2px;
  box-shadow: 0 8px 24px rgba(15, 33, 29, 0.16);
  padding-top: 0;
}

.nav-menu-head {
  padding: 0.75rem 1rem;
  background: #F4F8F6;
  border-bottom: 1px solid var(--line);
}

.nav-menu-section { padding: 0.6rem 1rem; }

.nav-menu .dropdown-header {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding: 0.5rem 1rem 0.25rem;
}

.nav-menu .dropdown-item {
  font-size: 14px;
  padding: 0.5rem 1rem;
  color: var(--ink);
}
.nav-menu .dropdown-item:hover,
.nav-menu .dropdown-item:focus {
  background: #F4F8F6;
  color: var(--primary);
}

.nav-menu .dropdown-divider { margin: 0.35rem 0; border-color: var(--line); }

/* The app name can be long; never let it push the menu button off screen. */
.topbar .fw-semibold { max-width: 60vw; }
@media (min-width: 992px) { .topbar .fw-semibold { max-width: none; } }

/* Sample delete: a red button in the row's top-right corner. Disabled with
   the reason when it is not the newest sample. */
.sample-del-btn {
  --bs-btn-bg: var(--danger);
  --bs-btn-border-color: var(--danger);
  --bs-btn-hover-bg: #74221E;
  --bs-btn-hover-border-color: #74221E;
  --bs-btn-disabled-bg: #C9B4B2;
  --bs-btn-disabled-border-color: #C9B4B2;
  border-radius: 2px;
  font-size: 12px;
  padding: 0.25rem 0.6rem;
  white-space: nowrap;
}

.modal-content { border-radius: 2px; border-color: var(--line); }
.modal-header, .modal-footer { border-color: var(--line); }
.modal-title { font-size: 1rem; }

/* --- Animal photographs -------------------------------------------------
   Small boxes rather than a gallery: the point is recognising the animal at
   a glance, not viewing the image. Clicking opens the full version. */

.photo-slot {
  border: 1px solid var(--line);
  border-radius: 2px;
  padding: 0.75rem;
  background: var(--surface);
  height: 100%;
}
.photo-slot-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}

.photo-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 130px;
  margin-bottom: 0.6rem;
  background: #F2F5F3;
  border: 1px dashed var(--line);
  border-radius: 2px;
  overflow: hidden;
}
.photo-preview img { max-width: 100%; max-height: 100%; object-fit: contain; }

.photo-empty { font-size: 12px; color: var(--ink-soft); text-align: center; }

.photo-card {
  border: 1px solid var(--line);
  border-radius: 2px;
  overflow: hidden;
  background: var(--surface);
  height: 100%;
  display: flex;
  flex-direction: column;
}
.photo-card-img {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 140px;
  background: #EDF1EF;
  overflow: hidden;
}
.photo-card-img img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform .15s ease;
}
.photo-card-img:hover img { transform: scale(1.04); }
.photo-card-img.empty {
  border-bottom: 1px dashed var(--line);
  background: #F7F9F8;
}
.photo-card-body { padding: 0.6rem 0.7rem; }

/* --- Photo card actions -------------------------------------------------
   Navy for upload, amber for replace. Distinct from the green primary and
   the red delete, so at a glance an empty slot reads differently from one
   already filled. */

.btn-photo-upload {
  --bs-btn-bg: #1F3864;
  --bs-btn-border-color: #1F3864;
  --bs-btn-color: #FFFFFF;
  --bs-btn-hover-bg: #16294A;
  --bs-btn-hover-border-color: #16294A;
  --bs-btn-hover-color: #FFFFFF;
  --bs-btn-active-bg: #16294A;
  --bs-btn-active-border-color: #16294A;
  --bs-btn-active-color: #FFFFFF;
  border-radius: 2px;
  font-weight: 600;
}

.btn-photo-replace {
  --bs-btn-bg: #C8931A;
  --bs-btn-border-color: #C8931A;
  /* Dark text on amber: white on this yellow fails contrast badly, and the
     screen is read in daylight. */
  --bs-btn-color: #2B1F00;
  --bs-btn-hover-bg: #AE7F12;
  --bs-btn-hover-border-color: #AE7F12;
  --bs-btn-hover-color: #2B1F00;
  --bs-btn-active-bg: #AE7F12;
  --bs-btn-active-border-color: #AE7F12;
  --bs-btn-active-color: #2B1F00;
  border-radius: 2px;
  font-weight: 600;
}

/* --- Laboratory receipt -------------------------------------------------- */

/* The list is long, so the decision controls follow it down the page. */
.lab-actionbar {
  position: sticky;
  top: 0;
  z-index: 5;
  border-left: 3px solid var(--primary);
  box-shadow: 0 2px 10px rgba(15, 33, 29, 0.08);
}

.lab-row.selected { background: #E7F2EA; }
.lab-row td { transition: background .1s ease; }

/* A solid green, distinct from the outline buttons, so accepting reads
   differently from rejecting at the moment of clicking. */
.btn-success-solid {
  --bs-btn-bg: #1D6B4F;
  --bs-btn-border-color: #1D6B4F;
  --bs-btn-color: #FFFFFF;
  --bs-btn-hover-bg: #15523C;
  --bs-btn-hover-border-color: #15523C;
  --bs-btn-hover-color: #FFFFFF;
  --bs-btn-disabled-bg: #A9BDB3;
  --bs-btn-disabled-border-color: #A9BDB3;
  border-radius: 2px;
  font-weight: 600;
}

.badge-count {
  display: inline-block;
  min-width: 18px;
  padding: 0 5px;
  margin-left: 4px;
  font-size: 11px;
  line-height: 16px;
  text-align: center;
  background: var(--primary);
  color: #FFFFFF;
  border-radius: 8px;
}

/* --- Storage: the well grid ---------------------------------------------
   Drawn as the box sits on the bench: rows A-J down, columns 1-10 across. */

.well-grid { border-collapse: separate; border-spacing: 3px; }
.well-grid th {
  font-size: 11px;
  font-weight: 600;
  color: var(--ink-soft);
  text-align: center;
  padding: 2px;
}
.well-grid td { padding: 0; }

.well {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 58px;
  height: 46px;
  border-radius: 2px;
  border: 1px solid var(--line);
  background: #F7F9F8;
  padding: 0;
}
.well-label  { font-size: 9px; color: var(--ink-soft); letter-spacing: .04em; }
.well-sample { font-family: ui-monospace, Menlo, Consolas, monospace;
               font-size: 11px; font-weight: 600; }

.well.empty { border-style: dashed; }
.well.filled {
  background: #E7F2EA;
  border-color: var(--primary);
  color: var(--ink);
  cursor: pointer;
}
.well.filled:hover { background: #D8EADE; }
.well.filled .well-label { color: var(--primary); }

.box-card {
  display: block;
  padding: 0.75rem;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: var(--surface);
  color: var(--ink);
  text-decoration: none;
  height: 100%;
}
.box-card:hover { border-color: var(--primary); color: var(--ink); }

.location-chip {
  display: inline-block;
  padding: 0.25rem 0.6rem;
  background: #E7F2EA;
  border-radius: 2px;
  font-size: 13px;
}

/* Breed selection: a tick target big enough for a whole row, so the label
   is clickable rather than only the small checkbox. */
.breed-pick {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--line);
  border-radius: 2px;
  cursor: pointer;
  height: 100%;
}
.breed-pick:hover { border-color: var(--primary); }
.breed-pick.picked { background: #E7F2EA; border-color: var(--primary); }
.breed-pick input { margin-top: 2px; flex: 0 0 auto; }

/* --- Wider wells ---------------------------------------------------------
   Sample IDs are seven characters (GS10210). Truncating them defeats the
   purpose of the grid, which is matching a tube in the hand to a position. */

.well {
  width: 92px;
  height: 50px;
  gap: 0;
}

.well-tick {
  display: flex;
  align-items: center;
  gap: 4px;
  width: 100%;
  padding: 2px 4px 0;
  cursor: pointer;
}
.well-tick input { width: 12px; height: 12px; margin: 0; flex: 0 0 auto; }

.well-open {
  width: 100%;
  padding: 0 2px 3px;
  background: none;
  border: none;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
  cursor: pointer;
}
.well-open:hover { color: var(--primary); text-decoration: underline; }

.well.filled { flex-direction: column; align-items: stretch; }
.well.picked { background: #FBE9C7; border-color: var(--accent); }

/* Report chooser: four tabs, each stating which date it filters on — the
   distinction that actually separates them. */
.report-tab {
  display: block;
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--line);
  border-left: 3px solid var(--line);
  border-radius: 2px;
  background: var(--surface);
  color: var(--ink);
  text-decoration: none;
  height: 100%;
}
.report-tab:hover { border-color: var(--primary); color: var(--ink); }
.report-tab.active {
  border-left-color: var(--primary);
  background: #E7F2EA;
}
.report-tab-name { display: block; font-size: 13px; font-weight: 600; }
.report-tab-date { display: block; font-size: 11px; color: var(--primary); margin-top: 1px; }
.report-tab-cols { display: block; font-size: 10px; color: var(--ink-soft); }

/* --- Lab section buttons -------------------------------------------------
   A dark slate that sits beside the green primary without competing with it.
   The outline style these replaced was near-white, which made a row of
   section links read as disabled. White text gives 11.3:1. */

.btn-lab {
  --bs-btn-bg: #2C3E37;
  --bs-btn-border-color: #2C3E37;
  --bs-btn-color: #FFFFFF;
  --bs-btn-hover-bg: #1F2D28;
  --bs-btn-hover-border-color: #1F2D28;
  --bs-btn-hover-color: #FFFFFF;
  --bs-btn-active-bg: #1F2D28;
  --bs-btn-active-border-color: #1F2D28;
  --bs-btn-active-color: #FFFFFF;
  --bs-btn-disabled-bg: #9AA8A2;
  --bs-btn-disabled-border-color: #9AA8A2;
  border-radius: 2px;
  font-weight: 600;
}
.btn-lab:focus-visible {
  box-shadow: 0 0 0 3px rgba(44, 62, 55, 0.28);
}

/* ==========================================================================
   Outline buttons — darkened
   ==========================================================================
   Bootstrap's default outline-secondary sits at 4.6:1 on our surface. That
   technically passes, but a table row full of them reads as inactive, which
   is the opposite of what an Open or Edit button should convey.

   Darkened to 11.1:1 and given a visible border. They stay OUTLINE rather
   than solid on purpose: making 97 buttons solid dark would compete with the
   green primary on every page, and the main action would stop standing out.

   CSS only. Bootstrap 5.3 drives buttons through custom properties, so
   redefining the class here changes every one of them without touching a
   single template.
   ========================================================================== */

.btn-outline-secondary {
  --bs-btn-color: #2C3E37;
  --bs-btn-border-color: #7E8F88;
  --bs-btn-bg: transparent;

  --bs-btn-hover-bg: #2C3E37;
  --bs-btn-hover-border-color: #2C3E37;
  --bs-btn-hover-color: #FFFFFF;

  --bs-btn-active-bg: #1F2D28;
  --bs-btn-active-border-color: #1F2D28;
  --bs-btn-active-color: #FFFFFF;

  --bs-btn-disabled-color: #9AA8A2;
  --bs-btn-disabled-border-color: #C8D2CE;

  border-radius: 2px;
  font-weight: 600;
}

.btn-outline-secondary:focus-visible {
  box-shadow: 0 0 0 3px rgba(44, 62, 55, 0.24);
}

/* Danger outlines get the same treatment, or they end up looking lighter
   than the neutral buttons beside them — which reads as less serious, the
   wrong signal for a delete. */
.btn-outline-danger {
  --bs-btn-color: #8C2A24;
  --bs-btn-border-color: #C08A85;
  --bs-btn-hover-bg: #8C2A24;
  --bs-btn-hover-border-color: #8C2A24;
  --bs-btn-hover-color: #FFFFFF;
  --bs-btn-active-bg: #74221E;
  --bs-btn-active-border-color: #74221E;
  --bs-btn-active-color: #FFFFFF;
  --bs-btn-disabled-color: #C9B4B2;
  --bs-btn-disabled-border-color: #E2D2D0;
  border-radius: 2px;
  font-weight: 600;
}

/* On the dark top bar the outline must go the other way — light on dark. */
.topbar .btn-outline-light {
  --bs-btn-color: #EAF1EE;
  --bs-btn-border-color: rgba(255, 255, 255, 0.45);
  --bs-btn-hover-bg: #FFFFFF;
  --bs-btn-hover-border-color: #FFFFFF;
  --bs-btn-hover-color: #17594A;
  border-radius: 2px;
  font-weight: 600;
}

/* Small buttons in table rows: the weight above makes them heavy at 12px,
   so the padding is tightened to keep rows compact. */
.table-slip .btn-sm,
.btn-sm.btn-outline-secondary,
.btn-sm.btn-outline-danger {
  padding: 0.25rem 0.6rem;
  font-size: 12px;
}

/* --- Access tree: state > district > centre ------------------------------
   Collapsed by default. With a full census loaded an expanded tree runs to
   thousands of rows, so the closed state is the useful one. */

.tree-row {
  display: flex;
  align-items: flex-start;
  gap: 0.4rem;
  padding: 0.35rem 0.4rem;
  border-radius: 2px;
}
.tree-row:hover { background: #F2F6F4; }

.tree-row-state    { border-left: 3px solid var(--primary); }
.tree-row-district { border-left: 3px solid var(--line); margin-left: 1.25rem; }
.tree-row-centre   { margin-left: 2.5rem; }

.tree-toggle {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: var(--surface);
  color: var(--ink-soft);
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
}
.tree-toggle:hover { border-color: var(--primary); color: var(--primary); }
.tree-spacer { flex: 0 0 auto; width: 20px; }

.tree-label {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  flex-wrap: wrap;
  cursor: pointer;
  font-size: 14px;
  margin: 0;
}
.tree-label input { margin: 0; flex: 0 0 auto; }

/* A row already covered by a broader grant. Greyed rather than hidden, so it
   is clear the access exists and where it comes from. */
.tree-label.implied { opacity: 0.5; }
.tree-label.implied::after {
  content: "covered";
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.tree-meta {
  font-size: 11px;
  color: var(--ink-soft);
}

.tree-children { padding-left: 0.2rem; }

/* A collapsed state that holds a grant somewhere inside it. */
.tree-state.has-grant > .tree-row-state { background: #E7F2EA; }

/* --- Records panel -------------------------------------------------------
   One row per record type kept against an animal. A list rather than a single
   link, because more join it as their modules are built. */

.record-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  padding: 0.65rem 0.8rem;
  border: 1px solid var(--line);
  border-left: 3px solid var(--primary);
  border-radius: 2px;
  background: var(--surface);
  color: var(--ink);
  text-decoration: none;
}
.record-link:hover {
  background: #E7F2EA;
  border-color: var(--primary);
  color: var(--ink);
}

/* --- Compact selects ------------------------------------------------------
   A <select> sized by its content leaves no room for the dropdown arrow, so
   the arrow lands on top of the last letter.

   Two things were wrong in the first attempt:

     padding-right: 2rem   was LOWER than Bootstrap's own 2.25rem, so it made
                           the gap smaller rather than larger
     .select-compact       ties on specificity with .form-select-sm, leaving
                           the outcome to source order

   Both fixed by qualifying with .form-select — two classes always win — and
   by giving the arrow more room than the default, not less. */

.form-select.select-compact {
  width: auto;
  min-width: 8.5rem;      /* fits "Available" plus the arrow at .875rem */
  padding-right: 2.5rem;
  background-position: right 0.65rem center;
}

/* Row and Column hold one letter or one number, so they need far less width —
   but they must match each other, or the pair looks broken even when both are
   readable. */
.well-picker .form-select.select-compact {
  min-width: 5.5rem;
  flex: 1 1 0;
}

/* --- Combo toggle sized like a native select ------------------------------
   The picker button stands in for a <select>, so it has to match one exactly
   or a row holding both is visibly uneven. Bootstrap's .form-select is the
   reference: same padding, same font, same border and height. */

.combo-toggle {
  min-height: calc(1.5em + 1.2rem + 2px);   /* .form-select box model */
  padding: 0.6rem 2.25rem 0.6rem 0.7rem;
  font-size: 16px;
  line-height: 1.5;
}

/* A row of label + control where one control is a combo: the label heights
   already match, so aligning the controls at the end is enough — provided no
   column carries an extra line of its own. Hints belong below the row. */
.place-row > [class*="col-"] > .combo {
  width: 100%;
}

/* --- A well whose sample passed post-box QC -------------------------------
   No checkbox, because the bulk remove is the only thing a tick feeds and
   that sample cannot be removed. Tinted and marked so the missing control
   reads as deliberate rather than broken. */

.well.well-locked {
  border-color: var(--primary);
  background: #E7F2EA;
}

.well-lock {
  font-size: 10px;
  line-height: 1;
  opacity: 0.65;
}

/* --- Species chip ---------------------------------------------------------
   Lab tables are ordered by species then sample ID, so the same word repeats
   down a run of rows. A quiet chip lets the eye read those as one band
   instead of re-reading the word on every line. */

.species-chip {
  display: inline-block;
  padding: 0.1rem 0.4rem;
  border-radius: 2px;
  background: var(--surface-2, #EEF3F0);
  border: 1px solid var(--line);
  font-size: 11px;
  color: var(--ink-soft);
  white-space: nowrap;
}

/* --- Dashboard ------------------------------------------------------------
   Charts are inline SVG, so they scale with their container and need no
   fixed sizing. */

.chart-card {
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: 0.75rem;
  background: var(--surface);
  height: 100%;
}

.chart-card svg { width: 100%; height: auto; display: block; }

.chart-title {
  font-size: 12px;
  font-weight: 700;
  color: var(--ink-soft);
  margin-bottom: 0.35rem;
  text-transform: uppercase;
  letter-spacing: 0.3px;
}

/* The expand control on the two roll-up tables. Sized for a fingertip: this
   is read on tablets as well as desktops. */
.drill-toggle {
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink-soft);
  width: 22px;
  height: 22px;
  line-height: 1;
  border-radius: 3px;
  font-size: 13px;
  margin-right: 0.5rem;
  padding: 0;
}

.drill-toggle:hover:not(:disabled) {
  border-color: var(--primary);
  color: var(--primary);
}

.drill-toggle:disabled { opacity: 0.5; }

.drill-leaf {
  display: inline-block;
  width: 22px;
  color: var(--line);
  margin-right: 0.5rem;
  text-align: center;
}

/* A child row is tinted so the hierarchy is visible without reading the
   indentation, which disappears on a narrow screen. */
.drill-child > td { background: var(--surface-2, #F7F9F8); }

.legend-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  margin-right: 0.35rem;
  vertical-align: middle;
}

/* Leaflet draws above sticky table headers unless told otherwise. */
.leaflet-container { z-index: 1; }


/* --- Map layer panel ------------------------------------------------------
   Expanded by default, so it needs to read as part of the page rather than
   as a floating box. */

.leaflet-control-layers {
  border: 1px solid var(--line);
  border-radius: 3px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12);
  font-size: 12px;
  padding: 0.15rem 0.1rem;
}

.leaflet-control-layers-list { padding: 0.35rem 0.55rem; }

.leaflet-control-layers label {
  margin-bottom: 0.2rem;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  cursor: pointer;
}

.leaflet-control-layers-separator {
  border-top: 1px solid var(--line);
  margin: 0.4rem 0;
}
