/* Farmdrop.shop — design system
   Green/earth palette matching the existing farmdrop.shop direction.
   Accessibility rule for this project: status is NEVER carried by colour alone.
   Every flagged state also gets an icon and a word. */

:root {
  --green-900: #1c3b2a;
  --green-700: #2f6b45;
  --green-600: #3d8557;
  --green-500: #4fa06a;
  --green-100: #e4f1e8;
  --green-050: #f2f8f4;

  --earth-800: #4a3728;
  --earth-500: #9c7a52;
  --earth-100: #f2ebe1;

  --sun: #d99b28;
  --clay: #b4472e;
  --blue: #2f6f9f;
  --blue-100: #e3eef6;

  --ink: #22271f;
  --ink-60: #5d6459;
  --ink-30: #9aa196;
  --line: #dfe4dc;
  --paper: #ffffff;
  --bg: #f7f9f5;

  --radius: 12px;
  --radius-sm: 8px;
  --shadow: 0 1px 2px rgba(28, 59, 42, .06), 0 4px 14px rgba(28, 59, 42, .07);
  --shadow-lg: 0 8px 30px rgba(28, 59, 42, .12);
  --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --serif: "Iowan Old Style", "Palatino Linotype", Georgia, serif;
}

* { box-sizing: border-box; }
body {
  margin: 0; font-family: var(--font); color: var(--ink);
  background: var(--bg); font-size: 15px; line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--green-700); }
h1, h2, h3 { line-height: 1.2; margin: 0 0 .5rem; }
h1 { font-size: 1.9rem; letter-spacing: -.02em; }
h2 { font-size: 1.3rem; letter-spacing: -.01em; }
h3 { font-size: 1.05rem; }
.serif { font-family: var(--serif); }
.wrap { max-width: 1180px; margin: 0 auto; padding: 0 20px; }
.muted { color: var(--ink-60); }
.small { font-size: .82rem; }
.tiny { font-size: .74rem; }
.tiny.good { color: var(--green-700); }
.tiny.warn { color: #8c331f; }
.right { text-align: right; }
.center { text-align: center; }
.nowrap { white-space: nowrap; }
.mono { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; font-size: .8rem; }
.stack > * + * { margin-top: 1rem; }
.row { display: flex; gap: 1rem; align-items: center; }
.row.between { justify-content: space-between; }
.row.wrap-row { flex-wrap: wrap; }
.grow { flex: 1; }

/* ------------------------------------------------------------- masthead */
.masthead {
  background: var(--green-900); color: #fff; position: sticky; top: 0; z-index: 40;
}
.masthead .wrap { display: flex; align-items: center; gap: 1.25rem; height: 62px; }
.brand {
  font-weight: 700; font-size: 1.15rem; color: #fff; text-decoration: none;
  display: flex; align-items: center; gap: .5rem; letter-spacing: -.02em;
}
.brand .leaf { font-size: 1.3rem; }
.masthead nav { display: flex; gap: 1.1rem; margin-left: auto; align-items: center; }
.masthead nav a {
  color: #cfe3d6; text-decoration: none; font-size: .9rem; font-weight: 500;
  padding: .35rem 0; border-bottom: 2px solid transparent;
}
.masthead nav a:hover { color: #fff; }
.masthead nav a.on { color: #fff; border-bottom-color: var(--sun); }
.cart-pill {
  background: var(--sun); color: #3a2a06; border-radius: 999px;
  padding: .15rem .55rem; font-weight: 700; font-size: .78rem; margin-left: .3rem;
}
.mast-right { display: flex; align-items: center; gap: .9rem; }
.mast-right .cart-link { color: #cfe3d6; text-decoration: none; font-size: .9rem; font-weight: 500; }
.mast-right .cart-link:hover { color: #fff; }
.nav-toggle {
  display: none; background: transparent; border: 1px solid rgba(255,255,255,.35);
  color: #fff; border-radius: 8px; width: 34px; height: 30px; font-size: 1rem;
  line-height: 1; cursor: pointer; flex: none;
}

/* Nav bar needs to resize to fit the phone screen; the cart must stay reachable
   even when the rest of the links collapse behind a hamburger (Ben, 2026-08-09).
   The cart link lives OUTSIDE <nav id="siteNav">, so it is never hidden by the
   collapse below — only the secondary links (Shop/Farms/Account/etc.) do. */
@media (max-width: 680px) {
  .masthead .wrap { flex-wrap: wrap; height: auto; padding-top: .55rem; padding-bottom: .55rem; row-gap: .4rem; }
  .masthead nav {
    order: 3; flex-basis: 100%; margin-left: 0; display: none;
    flex-direction: column; align-items: stretch; gap: 0;
    border-top: 1px solid rgba(255,255,255,.15); padding-top: .3rem;
  }
  .masthead nav.open { display: flex; }
  .masthead nav a { padding: .6rem .2rem; border-bottom: 1px solid rgba(255,255,255,.08); }
  .mast-right { order: 2; margin-left: auto; }
  .nav-toggle { display: inline-flex; align-items: center; justify-content: center; }
}

/* subbar: zone + week */
.subbar {
  background: var(--green-700); color: #dff0e5; font-size: .85rem;
}
.subbar .wrap {
  display: flex; align-items: center; gap: 1rem; padding-top: .5rem; padding-bottom: .5rem;
  flex-wrap: wrap;
}
.subbar .wrap > form, .subbar .wrap > span {
  flex: 0 0 auto; white-space: nowrap;
}
.subbar select {
  background: rgba(255,255,255,.14); color: #fff; border: 1px solid rgba(255,255,255,.28);
  border-radius: 6px; padding: .2rem .45rem; font: inherit;
}
.subbar select option { color: #222; }
.subbar .sep { opacity: .8; }
.subbar-when { display: flex; align-items: center; gap: 1rem; }

/* Ben, 2026-08-09: on a phone every item in this bar wrapped onto its own
   line — four rows and 148px of green before any content. Below 680px the two
   selectors share a row and the two dates share the next. The vertical
   separators go with them: they only mean anything on a single line. */
@media (max-width: 680px) {
  .subbar .wrap { gap: .4rem .6rem; font-size: .8rem; }
  /* All of them, including the one between the two dates: once anything here
     wraps, a trailing "|" is left dangling at the end of a line. */
  .subbar .sep { display: none; }
  /* flex-wrap here matters: min-width:0 lets these shrink narrower than their
     own label + select, and both are nowrap, so without it the contents spill
     out of the form and the page scrolls sideways. Wrapping puts the label
     above its select instead of off the edge. */
  .subbar .wrap > form { flex: 1 1 8rem; min-width: 0; flex-wrap: wrap; }
  .subbar select { min-width: 0; flex: 1 1 auto; }
  /* Selector must be `.subbar .wrap > .subbar-when`, not `.subbar-when`: a
     media query adds no specificity, so the plain class loses to the
     `.subbar .wrap > span` rule above and silently does nothing.
     min-width:0 is load-bearing too — as a flex item this inherits
     min-width:auto, and its children are nowrap, so its min-content width is
     both dates on ONE line: it would refuse to shrink and push the page
     sideways. Children keep nowrap so a date never breaks mid-phrase. */
  .subbar .wrap > .subbar-when {
    flex: 1 1 100%; flex-wrap: wrap; gap: .3rem .5rem;
    min-width: 0; white-space: normal;
  }
  .subbar .wrap > .subbar-when > span { white-space: nowrap; }
}

/* ---------------------------------------------------------------- cards */
.card {
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow);
}
.card.pad { padding: 1.15rem 1.25rem; }
.card h2, .card h3 { margin-top: 0; }
.card-head {
  padding: .9rem 1.25rem; border-bottom: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
.card-body { padding: 1.15rem 1.25rem; }

.grid { display: grid; gap: 1rem; }
.grid.c2 { grid-template-columns: repeat(2, 1fr); }
.grid.c3 { grid-template-columns: repeat(3, 1fr); }
.grid.c4 { grid-template-columns: repeat(4, 1fr); }
.grid.shelf { grid-template-columns: repeat(auto-fill, minmax(198px, 1fr)); }
.grid.sidebar { grid-template-columns: 250px 1fr; align-items: start; }
.grid.checkout { grid-template-columns: 1fr 350px; align-items: start; }
@media (max-width: 900px) {
  .grid.c3, .grid.c4, .grid.sidebar, .grid.checkout { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------- product card */
.product {
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; display: flex; flex-direction: column; position: relative;
  transition: box-shadow .15s, transform .15s;
}
.product:hover { box-shadow: var(--shadow-lg); transform: translateY(-2px); }
.product .thumb {
  height: 116px; display: grid; place-items: center; font-size: 3rem;
  background: var(--green-050); border-bottom: 1px solid var(--line);
}
.product .body { padding: .7rem .8rem .8rem; display: flex; flex-direction: column; flex: 1; }
.product .name { font-weight: 600; font-size: .95rem; }
.product .from { font-size: .76rem; color: var(--ink-60); }
.product .price { font-weight: 700; font-size: 1.08rem; margin-top: .35rem; }
.product .price small { font-weight: 500; color: var(--ink-60); font-size: .74rem; }
/* Sale price UX: the regular price shown struck through, never colour alone
   (the 🏷 badge/word carries the "on sale" meaning). */
.price-was {
  text-decoration: line-through; color: var(--ink-30); font-weight: 500;
  font-size: .82em; margin-right: .35rem;
}
.product .actions { margin-top: auto; padding-top: .6rem; }

/* Availability. Faded = in stock elsewhere. Also labelled, never colour alone. */
.product.adjacent, .product.far { opacity: .55; filter: saturate(.35); }
.product.adjacent:hover, .product.far:hover { opacity: .95; filter: none; }
.avail-tag {
  position: absolute; top: .5rem; left: .5rem; z-index: 2;
  border-radius: 999px; padding: .12rem .5rem; font-size: .68rem; font-weight: 700;
  background: var(--blue-100); color: var(--blue); border: 1px solid #bcd8ea;
}
.avail-tag.far { background: var(--earth-100); color: var(--earth-800); border-color: #e2d3bd; }
.avail-tag.local { background: var(--green-100); color: var(--green-700); border-color: #bfe0c4; }
.sale-tag {
  position: absolute; top: .5rem; right: .5rem; z-index: 2;
  background: var(--sun); color: #3a2a06; border-radius: 999px;
  padding: .12rem .5rem; font-size: .68rem; font-weight: 700;
}

/* --------------------------------------------------------------- badges */
.badge {
  display: inline-flex; align-items: center; gap: .3rem; border-radius: 999px;
  padding: .16rem .55rem; font-size: .74rem; font-weight: 600;
  background: var(--green-100); color: var(--green-900); border: 1px solid #cfe3d6;
}
.badge.blue  { background: var(--blue-100); color: var(--blue); border-color: #bcd8ea; }
.badge.sun   { background: #fbf0d8; color: #7a5410; border-color: #ecd6a4; }
.badge.clay  { background: #fbe6e1; color: #8c331f; border-color: #f0c7bc; }
.badge.grey  { background: #eef0ed; color: var(--ink-60); border-color: var(--line); }

/* -------------------------------------------------------------- buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  background: var(--green-700); color: #fff; border: 1px solid var(--green-700);
  border-radius: var(--radius-sm); padding: .5rem .9rem; font: inherit;
  font-weight: 600; font-size: .88rem; cursor: pointer; text-decoration: none;
}
.btn:hover { background: var(--green-600); }
.btn.full { width: 100%; }
.btn.sm { padding: .3rem .6rem; font-size: .8rem; }
.btn.ghost { background: transparent; color: var(--green-700); border-color: var(--line); }
.btn.ghost:hover { background: var(--green-050); }
.btn.warn { background: var(--clay); border-color: var(--clay); }
.btn.warn:hover { filter: brightness(1.08); }
.btn.blue { background: var(--blue); border-color: var(--blue); }
.btn[disabled] { opacity: .5; cursor: not-allowed; }

/* --------------------------------------------------------------- inputs */
label.field { display: block; margin-bottom: .8rem; }
label.field span { display: block; font-size: .8rem; font-weight: 600; margin-bottom: .25rem; }
input[type=text], input[type=email], input[type=number], input[type=date],
input[type=tel], select, textarea {
  width: 100%; padding: .48rem .6rem; border: 1px solid var(--line);
  border-radius: var(--radius-sm); font: inherit; background: #fff; color: var(--ink);
}
input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--green-500); outline-offset: 1px; border-color: var(--green-500);
}
textarea { min-height: 90px; resize: vertical; }
.qty { width: 68px; }

/* --------------------------------------------------------------- tables */
table.data { width: 100%; border-collapse: collapse; font-size: .88rem; }
table.data th {
  text-align: left; font-size: .72rem; text-transform: uppercase; letter-spacing: .05em;
  color: var(--ink-60); padding: .5rem .6rem; border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
table.data td { padding: .55rem .6rem; border-bottom: 1px solid #eef1ed; vertical-align: middle; }
table.data tr:last-child td { border-bottom: 0; }
table.data tbody tr:hover { background: var(--green-050); }
table.data td.num, table.data th.num { text-align: right; font-variant-numeric: tabular-nums; }

/* Payout exception rows: colour + left bar + icon + word. */
tr.flag-over td { background: #fdf1ee; }
tr.flag-over td:first-child { box-shadow: inset 3px 0 0 var(--clay); }
tr.flag-hold td { background: #fbf6e9; }
tr.flag-hold td:first-child { box-shadow: inset 3px 0 0 var(--sun); }
tr.excluded td { opacity: .45; text-decoration: line-through; }

/* --------------------------------------------------------------- alerts */
.alert {
  border-radius: var(--radius-sm); padding: .7rem .9rem; font-size: .88rem;
  border: 1px solid; display: flex; gap: .55rem; align-items: flex-start;
}
.alert.info  { background: var(--blue-100); border-color: #bcd8ea; color: #1d4c70; }
.alert.good  { background: var(--green-100); border-color: #cfe3d6; color: var(--green-900); }
.alert.warn  { background: #fbf0d8; border-color: #ecd6a4; color: #6b4a0e; }
.alert.error { background: #fbe6e1; border-color: #f0c7bc; color: #8c331f; }

/* ------------------------------------------------------------- banners */
.banner-slider { position: relative; margin-top: 1.25rem; }
.banner-viewport { overflow: hidden; border-radius: var(--radius); }
.banner-track { display: flex; transition: transform .4s ease; }
.banner-slide { flex: 0 0 100%; min-width: 0; }
.banner-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 2.2rem; height: 2.2rem; border-radius: 50%; border: none;
  background: rgba(0,0,0,.45); color: #fff; font-size: 1.3rem; line-height: 1;
  cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.banner-nav.prev { left: .6rem; }
.banner-nav.next { right: .6rem; }
.banner-nav:hover { background: rgba(0,0,0,.65); }
.banner-dots {
  position: absolute; left: 0; right: 0; bottom: .6rem;
  display: flex; justify-content: center; gap: .4rem;
}
.banner-dot {
  width: .55rem; height: .55rem; border-radius: 50%; border: 1px solid #fff;
  background: rgba(255,255,255,.5); padding: 0; cursor: pointer;
}
.banner-dot.active { background: #fff; width: 1.5rem; border-radius: 4px; }

.site-banner {
  position: relative; display: block; height: 100%; border-radius: var(--radius); overflow: hidden;
  background: linear-gradient(135deg, var(--green-700), var(--green-600));
  color: #fff; text-decoration: none;
}
.site-banner-img { display: block; width: 100%; max-height: 320px; object-fit: cover; }
.site-banner-text {
  display: flex; flex-direction: column; gap: .2rem; padding: 1rem 1.25rem; color: #fff;
}
.site-banner-text strong { font-size: 1.15rem; }
.site-banner-text .muted { color: #dff0e5; }
.site-banner:has(.site-banner-img) .site-banner-text {
  position: absolute; left: 0; bottom: 0; right: 0;
  background: linear-gradient(0deg, rgba(0,0,0,.55), transparent);
}

/* Framed style (Ben, 2026-08-18): image contained inside an admin-chosen
   background color, text shown below it in normal ink rather than overlaid —
   an arbitrary chosen background can't be relied on to contrast with white. */
.site-banner.framed { background: var(--paper); border: 1px solid var(--line); }
.site-banner-frame {
  display: flex; align-items: center; justify-content: center;
  padding: 1.5rem; min-height: 160px;
}
.site-banner-frame-img { max-width: 100%; max-height: 260px; object-fit: contain; display: block; }
.site-banner-text.plain {
  position: static; background: none; padding: 0 1.25rem 1.25rem; color: var(--ink);
}
.site-banner-text.plain .muted { color: var(--ink-60); }

/* ---------------------------------------------------------------- misc */
.hero {
  background: linear-gradient(135deg, var(--green-900), var(--green-600));
  color: #fff; border-radius: var(--radius); padding: 2.2rem 2rem; margin: 1.25rem 0;
}
.hero h1 { font-size: 2.3rem; margin-bottom: .5rem; }
.hero p { max-width: 62ch; color: #dff0e5; margin: 0 0 1.2rem; }
.section { margin: 1.75rem 0; }
.section > h2 { display: flex; align-items: baseline; gap: .6rem; }
.section > h2 .muted { font-size: .82rem; font-weight: 500; }

.catnav { display: flex; flex-direction: column; gap: .1rem; }
.catnav a {
  padding: .45rem .6rem; border-radius: var(--radius-sm); text-decoration: none;
  color: var(--ink); font-size: .9rem; display: flex; gap: .5rem; align-items: center;
}
.catnav a:hover { background: var(--green-050); }
.catnav a.on { background: var(--green-100); font-weight: 600; }

.stat { padding: .9rem 1rem; }
.stat .k { font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-60); }
.stat .v { font-size: 1.6rem; font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.stat .sub { font-size: .78rem; color: var(--ink-60); }

.stars { color: var(--sun); letter-spacing: .04em; }
.avatar {
  width: 44px; height: 44px; border-radius: 50%; background: var(--green-100);
  display: grid; place-items: center; font-size: 1.4rem; flex: none;
}
.favatar { position: relative; overflow: hidden; }
/* An uploaded photo lies on top of the emoji and is revealed once it has really
   loaded; the <img> removes itself on 404 and the emoji stays put.
   Hidden with opacity, NOT display:none — a display:none image counts as "not
   rendered", and a not-rendered loading="lazy" image is never fetched at all,
   so the photo request was never made and the emoji was never replaced
   (Ben, 2026-08-13: "product photos seem to upload, but they do not replace
   the emoji"). Anything changed here must keep the <img> in the render tree. */
.favatar-img {
  opacity: 0; position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
}
.favatar-img.loaded { opacity: 1; }

/* Multi-photo farm gallery (Ben, 2026-08-11) — the farmer's upload grid and
   the public strip on the farm page share this. */
.photo-gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: .6rem; }
.photo-gallery .thumb {
  position: relative; aspect-ratio: 1; border-radius: var(--radius-sm); overflow: hidden;
  border: 1px solid var(--line); background: var(--green-050);
}
.photo-gallery .thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo-strip { display: flex; gap: .6rem; overflow-x: auto; padding-bottom: .3rem; }
.photo-strip .thumb {
  flex: none; width: 150px; height: 150px; border-radius: var(--radius-sm); overflow: hidden;
  border: 1px solid var(--line);
}
.photo-strip .thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

.chat { display: flex; flex-direction: column; gap: .6rem; max-height: 340px; overflow-y: auto; }
.chat .msg { max-width: 78%; padding: .5rem .75rem; border-radius: 12px; font-size: .88rem; }
.chat .msg.farmer { align-self: flex-end; background: var(--green-100); }
.chat .msg.support { align-self: flex-start; background: #eef0ed; }

.timeline { list-style: none; padding: 0; margin: 0; }
.timeline li {
  padding: .55rem 0 .55rem 1.1rem; border-left: 2px solid var(--line);
  position: relative; font-size: .88rem;
}
.timeline li::before {
  content: ""; position: absolute; left: -5px; top: .85rem; width: 8px; height: 8px;
  border-radius: 50%; background: var(--green-500);
}

footer.site {
  margin-top: 3rem; padding: 2rem 0; background: var(--green-900); color: #9dbcaa;
  font-size: .84rem;
}
footer.site a { color: #cfe3d6; }

.demo-bar {
  background: var(--earth-800); color: #f0e6d8; font-size: .8rem;
  padding: .4rem 0;
}
.demo-bar .wrap { display: flex; gap: .6rem; align-items: center; flex-wrap: wrap; }
.demo-bar a {
  color: #f0e6d8; text-decoration: none; border: 1px solid rgba(255,255,255,.25);
  border-radius: 999px; padding: .1rem .6rem;
}
.demo-bar a:hover, .demo-bar a.on { background: rgba(255,255,255,.16); }

.flash-wrap { margin: 1rem 0; display: grid; gap: .5rem; }
