/*
  Design direction: "field-collection ledger", the visual language of a
  naturalist's specimen catalogue. Ant queens are cataloged like specimens:
  mono-spaced tag labels, a corner-notched card modeled on museum specimen
  tags. The accent colour is AntsCanada's own brand green, sampled directly
  from their logo (#6c8218) rather than invented. This is their palette,
  not a generic brand colour.
*/

/* Fonts are loaded via a <link rel="stylesheet"> in each page's <head>, not
   an @import here — @import inside an external stylesheet isn't discovered
   by the browser's preload scanner until this file itself has already been
   fetched and parsed, adding a full extra round-trip before the font CSS
   (and then the font files) even start downloading.

   That same Google Fonts link also requests display=optional (not the
   default swap): swap always paints the fallback serif first and reflows
   into Fraunces whenever it finishes downloading, which visibly jumps the
   hero heading on every load. optional gives the webfont a ~100ms window
   to be ready (which it will be, from cache, after the first visit) and
   otherwise commits to the fallback for that render instead of swapping
   into it later. */

:root {
  /* Color: deep soil (already close to AntsCanada's brown wordmark) +
     AntsCanada brand green as the primary accent + moss for
     "available/active" states */
  --soil-950: #15110b;
  --soil-900: #1b160e;
  --soil-800: #241d13;
  --soil-700: #322818;
  --soil-600: #453723;
  --brand-300: #bace6e;
  --brand-500: #6c8218;
  --brand-600: #475412;
  --brand-brown: #3d2b11;
  --moss-400: #8fa37e;
  --moss-600: #64775a;
  --rust-500: #c1552c;
  --rust-600: #a3411f;
  --parchment-050: #f7f2e6;
  --parchment-100: #ece3cd;
  --parchment-300: #c8bc9e;
  --parchment-500: #9c917a;

  --font-display: 'Fraunces', Georgia, serif;
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, monospace;

  --radius-sm: 4px;
  --radius-md: 8px;
  --shadow-card: 0 1px 0 rgba(0, 0, 0, 0.4), 0 8px 24px -12px rgba(0, 0, 0, 0.6);
}

* {
  box-sizing: border-box;
}

html {
  color-scheme: dark;
}

body {
  margin: 0;
  background: var(--soil-950);
  background-image:
    radial-gradient(ellipse 900px 500px at 15% -10%, rgba(226, 160, 61, 0.08), transparent),
    radial-gradient(ellipse 700px 500px at 100% 0%, rgba(143, 163, 126, 0.06), transparent);
  background-repeat: no-repeat;
  color: var(--parchment-100);
  font-family: var(--font-body);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

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

a {
  color: var(--brand-300);
}

/* A <button> that needs to read as an inline text link (e.g. triggering
   JS navigation rather than a real href) — same color/weight as `a`
   above, none of the default button chrome. */
.link-button {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: var(--brand-300);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.link-button:hover {
  color: var(--brand-500);
}

p {
  margin: 0 0 1em;
  color: var(--parchment-300);
}

label {
  display: block;
  font-size: 0.78rem;
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--parchment-500);
  margin-bottom: 6px;
}

input, select, textarea, button {
  font-family: var(--font-body);
  font-size: 0.95rem;
}

input, select, textarea {
  width: 100%;
  background: var(--soil-900);
  border: 1px solid var(--soil-600);
  color: var(--parchment-050);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

/* <select>'s native dropdown arrow and input[list]'s native datalist
   indicator are both drawn by the browser's own form-control chrome, which
   ignores padding/margin in inconsistent, browser-specific ways — that's
   what made every dropdown arrow site-wide sit crammed against the edge no
   matter how much spacing was added around it. Turning off native chrome
   entirely and drawing one consistent chevron ourselves is the only way to
   actually control its position. */
select, input[list] {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  padding-right: 38px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%239c917a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 15px;
}
input[list]::-webkit-calendar-picker-indicator {
  opacity: 0;
}

input:focus-visible, select:focus-visible, textarea:focus-visible, button:focus-visible, a:focus-visible {
  outline: none;
  border-color: var(--brand-500);
  box-shadow: 0 0 0 3px rgba(226, 160, 61, 0.25);
}

textarea {
  resize: vertical;
  min-height: 90px;
}

/* .btn-primary/-secondary/-danger/-ghost are also used on <a> tags styled
   to look like buttons (e.g. external links). Only *button* gets these
   shape/spacing rules for free, so without this class list an <a class=
   "btn-primary"> renders as a bare block of color with text jammed against
   its own edges: no padding, no border-radius, no border. */
button, .btn-primary, .btn-secondary, .btn-danger, .btn-ghost {
  cursor: pointer;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  padding: 10px 16px;
  font-weight: 600;
  transition: transform 0.08s ease, filter 0.15s ease, background 0.15s ease;
}
button:active, .btn-primary:active, .btn-secondary:active, .btn-danger:active, .btn-ghost:active {
  transform: translateY(1px);
}

.btn-primary {
  background: var(--brand-500);
  color: var(--soil-950);
}
.btn-primary:hover {
  filter: brightness(1.08);
}
.btn-secondary {
  background: transparent;
  border-color: var(--soil-600);
  color: var(--parchment-100);
}
.btn-secondary:hover {
  border-color: var(--brand-500);
  color: var(--brand-300);
}
.btn-danger {
  background: transparent;
  border-color: var(--rust-500);
  color: var(--rust-500);
}
.btn-danger:hover {
  background: var(--rust-500);
  color: var(--parchment-050);
}
.btn-ghost {
  background: transparent;
  border-color: transparent;
  color: var(--parchment-300);
  padding: 6px 10px;
  font-weight: 500;
}
.btn-ghost:hover {
  color: var(--brand-300);
}
button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.tag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  padding: 3px 8px;
  border-radius: 3px;
  border: 1px solid currentColor;
}
.tag-available { color: var(--moss-400); }
.tag-sold { color: var(--parchment-500); }
.tag-suspended { color: var(--rust-500); }
.tag-active { color: var(--moss-400); }
.tag-pending { color: var(--brand-300); }
.tag-admin { color: var(--brand-300); }
.tag-farmer { color: var(--parchment-300); }
/* Deliberately not brand-300 (already used for .tag-admin) — this needs to
   read as its own distinct status, not a shade of "admin," on a row that
   already shows an admin-role tag right next to it. */
.tag-owner { color: var(--parchment-050); border-color: var(--parchment-050); margin-left: 6px; }

/* A secondary, lower-emphasis signal riding along a cell that already has
   its own primary tag (e.g. "location changed" next to a listing's real
   status) — colored text, no border/box, so it reads as context rather
   than competing with the primary tag for attention. */
.inline-note {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--rust-500);
}

/* Inline warning tied to a single field (e.g. typing "Philippines" into a
   country field that will never resolve since it's excluded entirely, or a
   country dropdown that just won't list it as an option). Shared by the
   marketplace locator form and the dashboard registration form. */
.field-note {
  margin: 6px 0 0;
  font-size: 0.78rem;
  line-height: 1.4;
}
.field-note-warning {
  color: var(--rust-500);
}

/* ---- Checkbox fields (terms acceptance, per-listing/enquiry certifications) ---- */
input[type="checkbox"] {
  accent-color: var(--brand-500);
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  margin-top: 2px;
}
.checkbox-field {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  width: auto;
}
.checkbox-field label {
  text-transform: none;
  font-family: var(--font-body);
  letter-spacing: normal;
  font-size: 0.85rem;
  color: var(--parchment-300);
  margin-bottom: 0;
  cursor: pointer;
}
.checkbox-field a {
  color: var(--brand-300);
}

/* ---- Icons ---- */
.icon {
  width: 1em;
  height: 1em;
  flex-shrink: 0;
  vertical-align: -0.15em;
}
.icon-lg { width: 1.3em; height: 1.3em; }

.brand-logo {
  height: 26px;
  width: auto;
  max-width: 160px;
  object-fit: contain;
  display: block;
}
.brand-logo-lg {
  height: 34px;
  max-width: 220px;
}

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
}

.banner {
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  font-size: 0.88rem;
  margin-bottom: 16px;
  border: 1px solid;
}
.banner-error {
  background: rgba(193, 85, 44, 0.12);
  border-color: var(--rust-500);
  color: #f0b8a1;
}
.banner-success {
  background: rgba(143, 163, 126, 0.12);
  border-color: var(--moss-400);
  color: var(--moss-400);
}

/* ---- Toast: non-blocking replacement for window.alert() ---- */
.toast {
  position: fixed;
  left: 50%;
  bottom: 26px;
  transform: translateX(-50%) translateY(10px);
  min-width: 240px;
  max-width: min(90vw, 420px);
  padding: 12px 18px;
  border-radius: var(--radius-md);
  border: 1px solid;
  font-size: 0.88rem;
  font-weight: 500;
  box-shadow: var(--shadow-card);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
  z-index: 90;
}
.toast.visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
  pointer-events: auto;
}
.toast-error {
  background: var(--soil-900);
  border-color: var(--rust-500);
  color: #f0b8a1;
}
.toast-success {
  background: var(--soil-900);
  border-color: var(--moss-400);
  color: var(--moss-400);
}

/* ---- Motion: fade-in utility ----
   Applied via JS (see fadeIn() in dashboard.js) whenever a container's
   content is replaced wholesale (a new view, a filtered table body, a
   fresh screen), so the swap reads as a soft transition rather than an
   instant, jarring cut. */
@keyframes fade-in-up {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: translateY(0); }
}
.fade-in { animation: fade-in-up 0.22s ease; }

/* ---- Motion: busy-button spinner ----
   Swapped into a submit button's label while an async request is in
   flight (see setButtonBusy() in marketplace.js/dashboard.js), so a
   request that takes a noticeable beat (e.g. a modest droplet under load)
   reads as "working" rather than a dead click. */
@keyframes spin { to { transform: rotate(360deg); } }
.btn-spinner {
  display: inline-flex;
  animation: spin 0.7s linear infinite;
}

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

/* ---- Modal (shared by marketplace + dashboard) ---- */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(10, 8, 5, 0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  z-index: 50;
  animation: modal-backdrop-in 0.15s ease;
}
@keyframes modal-backdrop-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes modal-pop-in {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
.modal {
  animation: modal-pop-in 0.18s cubic-bezier(0.2, 0.8, 0.4, 1);
  background: var(--soil-900);
  border: 1px solid var(--soil-700);
  border-radius: var(--radius-md);
  padding: 24px;
  width: 100%;
  max-width: 440px;
  box-shadow: var(--shadow-card);
}
.modal h3 { margin-bottom: 4px; }
.modal .sub { font-size: 0.85rem; margin-bottom: 18px; color: var(--parchment-300); }
.modal .form-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 16px; }

@media (max-width: 480px) {
  .modal { padding: 18px; }
  .modal .form-actions { flex-direction: column-reverse; }
  .modal .form-actions button { width: 100%; justify-content: center; }
}

/* Confirm dialogs (see confirmDialog() in dashboard.js) can be triggered
   from inside an already-open modal, so this needs to stack visually above
   the regular .modal-backdrop (z-index 50) rather than replace it. */
.confirm-backdrop { z-index: 80; }
.confirm-backdrop .modal { max-width: 400px; }

/* ---- Shared components: card panel + icon-prefixed muted text line ---- */
.panel {
  background: var(--soil-900);
  border: 1px solid var(--soil-700);
  border-radius: var(--radius-md);
  padding: 20px;
  margin-bottom: 20px;
}
.panel h3 {
  font-size: 1rem;
  margin-bottom: 14px;
}
.muted-line {
  display: flex;
  align-items: center;
  gap: 4px;
  color: var(--parchment-500);
  font-size: 0.8rem;
}

/* ---- Callout: a highlighted panel for important notes/warnings ---- */
.callout {
  background: var(--soil-900);
  border: 1px solid var(--soil-700);
  border-left: 3px solid var(--brand-500);
  border-radius: var(--radius-md);
  padding: 16px 18px;
  margin-bottom: 16px;
}
.callout p, .callout li { color: var(--parchment-100); }
.callout p:last-child, .callout ul:last-child, .callout ol:last-child { margin-bottom: 0; }
.callout-warning { border-left-color: var(--rust-500); }
.callout h4 { font-size: 0.95rem; margin-bottom: 8px; display: flex; align-items: center; gap: 7px; }

/* ---- FAQ accordion (native <details>/<summary>, no JS needed) ---- */
.faq-item {
  border: 1px solid var(--soil-700);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  margin-bottom: 8px;
  background: var(--soil-900);
}
.faq-item summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--parchment-050);
  list-style: none;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::before { content: '+ '; color: var(--brand-300); font-family: var(--font-mono); }
.faq-item[open] summary::before { content: '\2013 '; }
.faq-item p { margin: 10px 0 0; }
