/* Seed Database — theme tokens
   Two themes: "furrow" (light) and "loam" (dark). Every color in this file
   is a custom property; components below reference the properties, never a
   literal hex value, so the whole app's look swaps on data-theme. */

html[data-theme="furrow"] {
  --bg: #F3EFE3;
  --header-bg: #24352A;
  --header-text: #F3EFE3;
  --header-sub: #A9B8A6;
  --tab-bg: #E6E0CF;
  --tab-text: #5B5642;
  --accent: #B6752C;
  --accent-text: #FFFFFF;
  --card-bg: #FFFFFF;
  --thumb-bg: #D7C9A3;
  --text-primary: #24352A;
  --text-secondary: #8A8570;
  --badge-bg: #EFE0C6;
  --badge-text: #8A5A22;
  --nav-bg: #FFFFFF;
  --nav-border: #E5E0D2;
  --nav-inactive: #B4AF9C;
  --toggle-track-off: #D9D2BC;
  --toggle-track-on: #24352A;
  --danger: #A33B2C;
  --danger-text: #FFFFFF;
  --warning: #BF5E28;
  --warning-text: #FFFFFF;
  --accent-green-bg: #DCE8D6;
  --accent-green-text: #2F4A38;
  --tab-border: #D2C7A5;
  --accent-green-border: #BFD8B5;
  --badge-border: #DDC79C;
  --card-border-strong: rgba(0, 0, 0, 0.35);
  --card-border: rgba(0, 0, 0, 0.16);
  --btn-border: rgba(0, 0, 0, 0.18);
  --accent-tint-bg: rgba(182, 117, 44, 0.12);
  --table-header-bg: #A9C79A;
  --table-header-text: #24352A;
}

html[data-theme="loam"] {
  --bg: #1C1A15;
  --header-bg: #242019;
  --header-text: #EDE8DC;
  --header-sub: #8C8874;
  --tab-bg: rgba(237, 232, 220, 0.08);
  --tab-text: #C4BEAB;
  --accent: #C99A3E;
  --accent-text: #1C1A15;
  --card-bg: #26241D;
  --thumb-bg: #3A3728;
  --text-primary: #EDE8DC;
  --text-secondary: #8C8874;
  --badge-bg: rgba(107, 143, 90, 0.22);
  --badge-text: #9CC084;
  --nav-bg: #242019;
  --nav-border: rgba(237, 232, 220, 0.08);
  --nav-inactive: #8C8874;
  --toggle-track-off: #3A3728;
  --toggle-track-on: #C99A3E;
  --danger: #D97A62;
  --danger-text: #1C1A15;
  --warning: #D98F4A;
  --warning-text: #1C1A15;
  --accent-green-bg: rgba(107, 143, 90, 0.22);
  --accent-green-text: #9CC084;
  --tab-border: rgba(237, 232, 220, 0.2);
  --accent-green-border: rgba(107, 143, 90, 0.45);
  --badge-border: rgba(107, 143, 90, 0.45);
  --card-border-strong: rgba(237, 232, 220, 0.35);
  --card-border: rgba(237, 232, 220, 0.16);
  --btn-border: rgba(237, 232, 220, 0.22);
  --accent-tint-bg: rgba(201, 154, 62, 0.16);
  --table-header-bg: #4F6B45;
  --table-header-text: #EDE8DC;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  background: var(--bg);
  color: var(--text-primary);
  font-family: "Inter", system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

body.has-bottom-nav {
  padding-bottom: 4.5rem;
}

body,
.card,
.header,
.bottom-nav,
.badge,
.toggle-track,
input,
textarea,
select,
button {
  transition: background-color 0.35s ease, color 0.35s ease, border-color 0.35s ease;
}

h1,
h2,
h3,
.display {
  font-family: "Fraunces", Georgia, serif;
  font-weight: 600;
  letter-spacing: -0.01em;
}

a {
  color: inherit;
  text-decoration: none;
}

[x-cloak] {
  display: none !important;
}

button,
input,
select,
textarea {
  font-family: inherit;
  font-size: inherit;
}

/* Header */

.header {
  background: var(--header-bg);
  color: var(--header-text);
  padding: 1.25rem 1.25rem 1.5rem;
}

.header .brand {
  font-family: "Fraunces", Georgia, serif;
  font-size: 1.4rem;
  font-weight: 600;
}

.header .sub {
  color: var(--header-sub);
  font-size: 0.85rem;
  margin-top: 0.15rem;
}

.header nav {
  display: none;
}

@media (min-width: 900px) {
  .header {
    position: sticky;
    top: 0;
    z-index: 40;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1.25rem 2rem;
  }
  .header nav {
    display: flex;
    align-items: center;
    gap: 1.5rem;
  }
  .header nav a {
    color: var(--header-sub);
    font-size: 0.95rem;
  }
  .header nav a.active {
    color: var(--header-text);
    font-weight: 600;
  }
}

/* Site header / footer (public marketing pages) */

.site-header,
.site-footer {
  background: var(--header-bg);
  color: var(--header-text);
}

.site-header-inner,
.site-footer-inner {
  max-width: 1080px;
  margin: 0 auto;
  padding: 1.25rem 1.5rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}

.site-header .brand {
  font-family: "Fraunces", Georgia, serif;
  font-size: 1.3rem;
  font-weight: 600;
}

.site-header .sub {
  color: var(--header-sub);
  font-size: 0.85rem;
  margin-top: 0.15rem;
}

.site-footer {
  margin-top: 3rem;
}

.site-footer-inner {
  padding: 1.5rem;
  color: var(--header-sub);
  font-size: 0.85rem;
}

.site-footer-inner a {
  color: var(--header-text);
}

.back-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text-secondary);
  margin-bottom: 1.25rem;
}

.back-link svg {
  width: 16px;
  height: 16px;
}

.back-link:hover {
  color: var(--text-primary);
}

/* Layout */

.page {
  max-width: 1280px;
  margin: 0 auto;
  padding: 1.25rem;
  width: 100%;
  flex: 1 0 auto;
}

.desktop-only {
  display: none;
}

.icon-btn-desktop-only {
  display: none !important;
}

.btn-label-desktop-only {
  display: none !important;
}

.catalog-header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1rem;
}

@media (min-width: 900px) {
  .desktop-only {
    display: block;
  }
}

/* Catalog layout: sidebar filters (desktop) / sheet filters (mobile) + grid */

.catalog-layout {
  display: block;
}

.catalog-filters {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: rgba(0, 0, 0, 0.45);
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.catalog-filters-panel {
  background: var(--bg);
  width: 100%;
  max-width: 420px;
  max-height: 85vh;
  overflow-y: auto;
  border-radius: 20px 20px 0 0;
  padding: 1.5rem 1.25rem;
}

@media (min-width: 900px) {
  /* Pins the whole page body (title row + the two-column layout) directly
     to the viewport below the fixed site header, instead of trying to make
     it exactly tall enough to fit within the page's natural flow. That
     "exactly tall enough" version (a height: calc(100vh - Npx) on a normal
     flow element) is what this started as, and it silently failed: <body>
     is `min-height: 100vh` (not `height`), so if the subtracted pixel count
     is even slightly off from the real nav height, <body> just grows past
     100vh to fit and the whole page falls back to ordinary scrolling — the
     bounded panes never get a chance to matter. Taking the shell out of
     flow with position: fixed sidesteps that arithmetic entirely: a fixed
     element can't contribute to <body>'s height at all, so there's nothing
     left to get wrong. max-width/margin/padding are repeated here because
     fixed positioning breaks out of .page's own box, not just its flow. */
  .catalog-page-shell {
    position: fixed;
    top: 88px;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1;
    display: flex;
    flex-direction: column;
    max-width: 1280px;
    margin: 0 auto;
    padding: 1.25rem;
  }

  .catalog-header-row {
    flex-shrink: 0;
  }

  .catalog-layout {
    display: grid;
    grid-template-columns: 240px 1fr;
    gap: 2.5rem;
    align-items: stretch;
    flex: 1 1 auto;
    /* Without this, grid/flex items default to min-height: auto, which
       keeps them at least as tall as their content and defeats the whole
       point — they'd never actually shrink to fit the remaining space,
       so overflow-y: auto below would never have anything to do. */
    min-height: 0;
  }

  .catalog-filters {
    display: block !important;
    position: static;
    inset: auto;
    background: none;
    z-index: auto;
    /* The actual scroll boundary lives here, not on .catalog-filters-panel
       (its child) — a child resolving height: 100% off a grid-stretched
       parent is one more indirection than this needs, and it wasn't
       reliably producing a bounded box in practice. .catalog-filters is
       the real grid item .catalog-layout stretches, so give it the bounded
       height directly. */
    height: 100%;
    overflow-y: auto;
  }

  .catalog-filters-panel {
    background: none;
    width: auto;
    max-height: none;
    border-radius: 0;
    padding: 0 1.75rem 0 0;
    border-right: 1px solid var(--nav-border);
  }

  .catalog-main {
    height: 100%;
    overflow-y: auto;
    /* Breathing room between the rightmost column of content and the
       scrollbar track, so it doesn't sit flush against the card/table edge. */
    padding-right: 1rem;
  }

  /* The table's own sticky header (see the Lot table section) is normally
     relative to the page's scroll — but inside this bounded, independently
     scrolling results pane, .catalog-main itself is the nearest scrolling
     ancestor, so the sticky offset needs to be relative to *its* top edge
     (0), not the page's. */
  .catalog-main .lot-table th {
    top: 0;
  }

  .mobile-only {
    display: none !important;
  }

  .icon-btn-desktop-only {
    display: inline-flex !important;
  }

  .btn-label-desktop-only {
    display: inline !important;
  }
}

/* Filter accordion */

.catalog-search {
  display: block;
  width: 100%;
  border: 1px solid var(--nav-border);
  background: var(--card-bg);
  color: var(--text-primary);
  border-radius: 10px;
  padding: 0.6rem 0.75rem;
  font-size: 0.9rem;
  margin-bottom: 1.25rem;
}

.quick-search-wrap {
  position: relative;
}

.quick-search-wrap .catalog-search {
  margin-bottom: 0;
}

.quick-search-results {
  position: absolute;
  top: calc(100% + 0.4rem);
  left: 0;
  right: 0;
  z-index: 60;
  background: var(--card-bg);
  border: 1px solid var(--nav-border);
  border-radius: 14px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.28);
  overflow: hidden;
  max-height: 320px;
  overflow-y: auto;
}

.quick-search-results:empty {
  display: none;
}

.quick-search-result {
  display: block;
  padding: 0.65rem 0.9rem;
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid var(--nav-border);
}

.quick-search-result:last-child {
  border-bottom: none;
}

.quick-search-result:hover {
  background: var(--tab-bg);
}

.quick-search-result-name {
  font-weight: 600;
  display: block;
}

.quick-search-result-meta {
  color: var(--text-secondary);
  font-size: 0.8rem;
}

.quick-search-empty {
  padding: 0.75rem 0.9rem;
  color: var(--text-secondary);
  font-size: 0.85rem;
}

.filter-section + .filter-section {
  margin-top: 1.25rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--nav-border);
}

.filter-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  background: none;
  border: none;
  padding: 0;
  font-family: "Fraunces", Georgia, serif;
  font-weight: 600;
  font-size: 1rem;
  color: var(--text-primary);
  cursor: pointer;
}

.chevron {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  transition: transform 0.2s ease;
}

[aria-expanded="false"] .chevron {
  transform: rotate(-90deg);
}

.filter-options {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  margin-top: 0.6rem;
}

.filter-option {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.4rem 0.5rem;
  border-radius: 8px;
  font-size: 0.9rem;
  color: var(--text-secondary);
  cursor: pointer;
}

.filter-option:hover {
  background: var(--tab-bg);
}

.filter-option input {
  accent-color: var(--accent);
  width: 15px;
  height: 15px;
  margin: 0;
  flex-shrink: 0;
}

.filter-option:has(input:checked) {
  color: var(--text-primary);
  font-weight: 600;
}

/* Cards / grid */

.variety-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 1rem;
}

.card {
  background: var(--card-bg);
  border-radius: 16px;
  overflow: hidden;
  display: block;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
  border: 1px solid var(--card-border);
}

a.card {
  transition: border-color 0.15s ease, border-width 0.15s ease, box-shadow 0.15s ease;
}

a.card:hover {
  border-width: 2px;
  border-color: var(--accent);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}

.grower-card {
  border: 1px solid var(--card-border-strong);
}

/* .card .body's own bottom padding is dropped here — when collapsed, the
   tinted .grower-card-header is the only thing in .body, so with no bottom
   padding left over its background now reaches the card's bottom edge
   too (clipped to the card's own rounded corners by .card's overflow:hidden)
   instead of leaving a blank strip of plain card background beneath it.
   The expanded detail area supplies its own bottom padding back (see
   .grower-card-details below) since it's no longer inherited from .body.
   Specificity bumped to .card.grower-card (three class selectors) rather
   than relying on source order against .card .body below — same equal-
   specificity/source-order tie CLAUDE.md already flags for .icon-btn-desktop-only,
   so this doesn't get silently re-broken by a future reorder of this file. */
.card.grower-card .body {
  padding-bottom: 0;
}

.grower-card-details {
  padding-bottom: 1rem;
}

/* Same full-bleed collapsed-header technique as .lot-card-header (extends
   the click hit area out to the card's own edges), plus a tinted background
   so the collapsed/header row reads as visually distinct from the dropped-
   down detail beneath it. --tab-bg is the same subtle section tint already
   used for tabs/filter rows elsewhere, reused here rather than inventing a
   new color. The card's own border-radius + overflow:hidden clips this to
   the card's rounded corners automatically — top corners always (header is
   always first), bottom corners too when collapsed (header is then also
   last, since the details div beneath is display:none from x-show).
   The bottom divider border only applies while expanded (.is-open, toggled
   via Alpine) — a collapsed card is meant to read as one solid color with
   no seam, not a color bar with a stray border floating above the card's
   own outer edge. */
.grower-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  width: calc(100% + 2rem);
  margin: -0.85rem -1rem 0;
  padding: 0.85rem 1rem;
  background: var(--tab-bg);
  border: none;
  text-align: left;
  color: inherit;
  font-family: inherit;
  cursor: pointer;
}

.grower-card-header.is-open {
  border-bottom: 1px solid var(--card-border);
}

.variety-card {
  border: 1px solid var(--card-border-strong);
}

.hero-banner {
  position: relative;
  background-size: cover;
  background-position: center;
  border-radius: 20px;
  overflow: hidden;
  margin: 1.5rem 0 0.5rem;
  padding: 5rem 1.25rem;
  min-height: 60vh;
  display: flex;
  align-items: center;
}

.hero-banner::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(20, 20, 15, 0.6);
}

.hero-banner-content {
  position: relative;
  max-width: 640px;
  margin: 0 auto;
  text-align: center;
  color: #fff;
  width: 100%;
}

.hero-banner-content p {
  color: rgba(255, 255, 255, 0.85);
}

.hero-banner-content h2 {
  color: #fff;
}

/* Cards keep their normal (non-white) text regardless of the banner's white copy */
.hero-banner-content .card {
  color: var(--text-primary);
  text-align: left;
}

.org-card-carousel {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.org-card-track {
  flex: 1;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  text-align: center;
}

.org-card-row {
  display: inline-flex;
  gap: 1rem;
  padding: 0.25rem;
}

.org-card-row .card {
  scroll-snap-align: start;
  min-width: 180px;
  flex-shrink: 0;
}

.carousel-arrow {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: 999px;
  border: none;
  background: rgba(255, 255, 255, 0.9);
  color: var(--text-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.carousel-arrow svg {
  width: 18px;
  height: 18px;
}

.card .thumb {
  position: relative;
  background: var(--thumb-bg);
  aspect-ratio: 4 / 3;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-secondary);
  font-size: 0.8rem;
}

.card .thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.thumb-badge {
  position: absolute;
  bottom: 0.5rem;
  right: 0.5rem;
  background: rgba(0, 0, 0, 0.65);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 600;
  padding: 0.2rem 0.55rem;
  border-radius: 999px;
}

.card .body {
  padding: 0.85rem 1rem 1rem;
}

.card .name {
  font-weight: 600;
  font-size: 1.05rem;
}

.card .meta {
  color: var(--text-secondary);
  font-size: 0.8rem;
  margin-top: 0.15rem;
}

.badge {
  display: inline-block;
  background: var(--badge-bg);
  color: var(--badge-text);
  border: 1px solid var(--badge-border);
  border-radius: 999px;
  padding: 0.2rem 0.6rem;
  font-size: 0.75rem;
  font-weight: 600;
  margin-top: 0.5rem;
}

.empty-state {
  color: var(--text-secondary);
  text-align: center;
  padding: 3rem 1rem;
}

/* Variety photo gallery */

.photo-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.6rem;
  margin-bottom: 1.5rem;
}

/* Fixed 2-column only on phone-sized screens, where the "add tile stretches
   when it's alone on its own row" trick below is calibrated to a known
   column count. Tablet and up get the same flexible column count as
   desktop so thumbnails don't balloon in size. */
@media (min-width: 600px) {
  .photo-grid {
    grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
  }
}

.photo-sortable {
  display: contents;
}

.photo-thumb {
  position: relative;
  aspect-ratio: 1;
  border-radius: 12px;
  overflow: hidden;
  background: var(--thumb-bg);
  cursor: grab;
}

.photo-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  cursor: pointer;
}

.photo-thumb-hero {
  box-shadow: 0 0 0 2px var(--accent);
}

.photo-hero-badge {
  position: absolute;
  top: 6px;
  left: 6px;
  width: 22px;
  height: 22px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}

.photo-hero-badge svg {
  width: 12px;
  height: 12px;
}

.photo-delete {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 26px;
  height: 26px;
  border-radius: 999px;
  border: none;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.photo-delete svg {
  width: 14px;
  height: 14px;
}

.photo-add-tile {
  align-self: stretch;
  aspect-ratio: 1;
  border-radius: 12px;
  border: 1.5px dashed var(--nav-border);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
  color: var(--text-secondary);
  font-size: 0.75rem;
  cursor: pointer;
}

.photo-add-tile-alone {
  grid-column: 1 / -1;
  align-self: start;
  aspect-ratio: auto;
  padding: 0.65rem 0;
  flex-direction: row;
  gap: 0.4rem;
}

.photo-add-tile svg {
  width: 20px;
  height: 20px;
}

@media (min-width: 600px) {
  .photo-add-tile-alone {
    grid-column: auto;
    align-self: stretch;
    aspect-ratio: 1;
    padding: 0;
    flex-direction: column;
    gap: 0.3rem;
  }

  .photo-add-tile svg {
    width: 22px;
    height: 22px;
  }
}

.sortable-ghost {
  opacity: 0.4;
}

.sortable-drag {
  cursor: grabbing;
}

/* Photo lightbox */

.lightbox-backdrop {
  align-items: center;
  padding: 1rem;
  background: rgba(0, 0, 0, 0.96);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

.lightbox-image {
  max-width: 100%;
  max-height: 85vh;
  border-radius: 12px;
  object-fit: contain;
}

.lightbox-close,
.lightbox-nav {
  position: absolute;
  border: none;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.15);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.lightbox-close {
  top: 1rem;
  right: 1rem;
  width: 40px;
  height: 40px;
}

.lightbox-close svg {
  width: 20px;
  height: 20px;
}

.lightbox-nav {
  top: 50%;
  transform: translateY(-50%);
  width: 44px;
  height: 44px;
}

.lightbox-nav svg {
  width: 22px;
  height: 22px;
}

.lightbox-prev {
  left: 1rem;
}

.lightbox-next {
  right: 1rem;
}

/* Toasts */

.toast-container {
  position: fixed;
  bottom: 5.5rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 200;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  width: calc(100% - 2rem);
  max-width: 360px;
  align-items: center;
}

@media (min-width: 900px) {
  .toast-container {
    bottom: 1.5rem;
    left: auto;
    right: 1.5rem;
    transform: none;
    align-items: flex-end;
  }
}

.toast {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  width: 100%;
  padding: 0.75rem 1rem;
  border-radius: 12px;
  background: var(--card-bg);
  color: var(--text-primary);
  border: 1px solid var(--nav-border);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
  font-size: 0.9rem;
}

.toast-success {
  background: var(--accent-green-bg);
  color: var(--accent-green-text);
  border-color: var(--accent-green-border);
}

.toast-error {
  background: var(--danger);
  color: var(--danger-text);
  border-color: var(--danger);
}

.toast-warning {
  background: var(--warning);
  color: var(--warning-text);
  border-color: var(--warning);
}

.toast-info {
  background: var(--tab-bg);
  color: var(--tab-text);
  border-color: var(--tab-border);
}

.toast button {
  display: flex;
  flex-shrink: 0;
  background: none;
  border: none;
  color: inherit;
  cursor: pointer;
  opacity: 0.7;
}

.toast button:hover {
  opacity: 1;
}

.toast button svg {
  width: 14px;
  height: 14px;
}

/* Buttons */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  border: 1px solid var(--btn-border);
  border-radius: 999px;
  padding: 0.65rem 1.25rem;
  font-size: 0.9rem;
  font-weight: 500;
  letter-spacing: 0;
  cursor: pointer;
  background: var(--accent);
  color: var(--accent-text);
  transition: filter 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease,
    background-color 0.35s ease, color 0.35s ease, border-color 0.35s ease;
}

.btn:hover:not(:disabled) {
  filter: brightness(0.92);
  transform: translateY(-1px);
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.15);
}

.btn.secondary {
  background: var(--tab-bg);
  color: var(--tab-text);
}

.btn.danger {
  background: var(--danger);
  color: var(--danger-text);
}

.btn.green {
  background: var(--accent-green-bg);
  color: var(--accent-green-text);
  width: 34px;
  height: 34px;
  padding: 0;
}

.btn.warning {
  background: var(--warning);
  color: var(--warning-text);
}

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  flex-shrink: 0;
  border: 1px solid var(--tab-border);
  border-radius: 999px;
  background: var(--tab-bg);
  color: var(--tab-text);
  cursor: pointer;
  transition: filter 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease,
    background-color 0.35s ease, color 0.35s ease, border-color 0.35s ease;
}

.icon-btn:hover:not(:disabled) {
  filter: brightness(0.92);
  transform: translateY(-1px);
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.15);
}

.icon-btn svg {
  width: 20px;
  height: 20px;
}

.icon-btn.active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-text);
}

.icon-btn.small {
  width: 30px;
  height: 30px;
}

.icon-btn.small svg {
  width: 15px;
  height: 15px;
}

.icon-btn-info {
  width: 22px;
  height: 22px;
}

.icon-btn-info svg {
  width: 13px;
  height: 13px;
}

.icon-btn-box {
  border-radius: 10px;
}

.danger-zone {
  margin-top: 1.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--nav-border);
}

/* Lot cards */

.lot-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  /* Extend the clickable hit area out to the card's edges, covering the
     surrounding .card .body padding, so the whole collapsed card responds
     to a click/tap — not just the text or chevron. */
  width: calc(100% + 2rem);
  margin: -0.85rem -1rem 0;
  padding: 0.85rem 1rem 0;
  background: none;
  border: none;
  text-align: left;
  color: inherit;
  font-family: inherit;
  cursor: pointer;
}

.badge-retired {
  background: var(--danger);
  color: var(--danger-text);
  border-color: var(--card-border);
  margin-top: 0;
}

.badge-active {
  background: var(--accent-green-bg);
  color: var(--accent-green-text);
  border-color: var(--card-border);
  margin-top: 0;
}

.badge-toggle {
  cursor: pointer;
  transition: filter 0.15s ease, opacity 0.15s ease;
}

.badge-toggle:hover {
  filter: brightness(0.94);
}

.badge-toggle.is-off {
  opacity: 0.5;
}

/* Active/retired lot visibility on the variety detail page — driven by a class
   toggled on the ancestor (Alpine, reliable since that element is never itself
   swapped) combined with plain static data-attributes on each lot card (not
   Alpine, so hiding doesn't depend on Alpine re-initializing a freshly
   htmx-swapped card's own x-show, which proved unreliable). */

.hide-active-lots [data-lot-status="active"] {
  display: none;
}

.hide-retired-lots [data-lot-status="retired"] {
  display: none;
}

[data-has-active][data-has-retired] {
  display: none;
}

.hide-active-lots.hide-retired-lots [data-has-active="true"][data-has-retired="true"],
.hide-active-lots [data-has-active="true"][data-has-retired="false"],
.hide-retired-lots [data-has-active="false"][data-has-retired="true"] {
  display: block;
}

/* Product cards — same collapsible card shell as lot cards, plus a leading
   print icon button, so the two sit at equal height side by side. */

.product-card-header {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: calc(100% + 2rem);
  margin: -0.85rem -1rem 0;
  padding: 0.85rem 1rem 0;
  background: none;
  border: none;
  text-align: left;
  color: inherit;
  font-family: inherit;
  cursor: pointer;
}

.product-card-header-main {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.lot-section {
  margin-top: 1.25rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--nav-border);
}

.list-row {
  display: block;
  font-size: 0.9rem;
  cursor: pointer;
  padding: 0.65rem 0.75rem;
}

.note-body {
  min-width: 0;
}

.note-body p {
  margin: 0;
}

.list-row:hover {
  background: var(--tab-bg);
}

.list-row + .list-row {
  border-top: 1px solid var(--nav-border);
}

.taxonomy-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.65rem 0;
}

.taxonomy-row + .taxonomy-row {
  border-top: 1px solid var(--nav-border);
}

.taxonomy-row-indent {
  padding-left: 1rem;
}

.taxonomy-row-inactive {
  opacity: 0.55;
}

.taxonomy-row-clickable {
  cursor: pointer;
  border-radius: 8px;
  padding-left: 0.5rem;
  padding-right: 0.5rem;
  margin: 0 -0.5rem;
}

.taxonomy-row-clickable:hover {
  background: var(--tab-bg);
}

.taxonomy-category + .taxonomy-category {
  border-top: 1px solid var(--nav-border);
}

.taxonomy-crops {
  padding-bottom: 0.5rem;
}

.filter-subsection + .filter-subsection {
  margin-top: 0.5rem;
}

.filter-subheader {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  background: none;
  border: none;
  padding: 0.3rem 0.5rem;
  margin-top: 0.4rem;
  font-family: "Fraunces", Georgia, serif;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text-secondary);
  cursor: pointer;
}

.filter-category-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.1rem 0.5rem 0.1rem 0.1rem;
}

.filter-category-row .filter-subheader {
  margin-top: 0;
  padding: 0.2rem 0;
}

.lot-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.6rem;
}

@media (min-width: 900px) {
  .lot-grid {
    display: none;
  }
}

/* Lot table — same card/border language as the mobile lot-row cards, just
   laid out as real columns. Swaps in for .lot-grid at the same 900px
   breakpoint the rest of this page's layout already uses.

   .lot-table uses overflow: clip (not hidden) to clip its content to the
   rounded corners. clip and hidden look identical visually, but per the CSS
   Overflow spec only hidden/auto/scroll establish a "scroll container" —
   clip deliberately doesn't (it has no scroll port at all, not even via
   JS), so it's excluded from the ancestor walk position: sticky uses to
   find its containing block. Concretely: overflow: hidden here silently
   broke the header's position: sticky (the header would just sit pinned to
   this element's own top edge instead of following the page's actual
   scroll), while overflow: clip gives the same rounded-corner clipping
   without that side effect — for the BOTTOM corners and the sides, which
   never move relative to .lot-table's own box.

   The TOP corners need their own separate treatment on top of that: once
   the header is actually stuck, it's visually detached from .lot-table's
   box (staying put in the viewport while the table scrolls past behind
   it) — so .lot-table's own rounded clip, tied to .lot-table's current
   (scrolled) position, no longer lines up with where the header is
   rendering, and the corner reads as square the moment you scroll at all.
   Fixed by rounding the two top header cells' own backgrounds directly
   (a "corner mask" — see below) so the rounding travels with the sticky
   header itself instead of staying behind with the table. */

.lot-table-wrap {
  overflow: visible;
}

.lot-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  background: var(--card-bg);
  border-radius: 14px;
  /* Left/right sides only (no full border): a left/right border here is
     what was showing through as a hairline seam next to the sticky header
     once scrolled — some sticky/compositing interaction that box-shadow
     masking on the header didn't fully cover. Dropping the sides removes
     the conflicting element outright rather than continuing to chase an
     exact pixel-level cause. Top/bottom + the rounded corners still read
     as a clearly boxed table. */
  border-top: 1px solid var(--card-border-strong);
  border-bottom: 1px solid var(--card-border-strong);
  overflow: clip;
}

.lot-table th {
  text-align: left;
  font-family: "Fraunces", Georgia, serif;
  font-weight: 600;
  font-size: 0.8rem;
  letter-spacing: 0.02em;
  color: var(--table-header-text);
  background: var(--table-header-bg);
  padding: 0.65rem 1rem;
  border-bottom: 1px solid var(--card-border-strong);
  white-space: nowrap;
  position: sticky;
  top: 88px;
  z-index: 10;
}

/* Corner masks — see the note above .lot-table. Each is a tiny square sat
   exactly over the header cell's own corner, with a radial-gradient that's
   transparent within the corner's own radius (revealing the header's own
   rounded background underneath, unchanged) and opaque page-background
   color outside it (covering the square leftover notch a rounded corner
   always leaves, so scrolled rows can't show through there). Plain solid
   masks the notch, and both move with the sticky header automatically. */

.lot-table thead tr:first-child th:first-child {
  border-top-left-radius: 13px;
}

.lot-table thead tr:first-child th:first-child::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 13px;
  height: 13px;
  background: radial-gradient(circle at bottom right, transparent 13px, var(--bg) 13px);
}

.lot-table thead tr:first-child th:last-child {
  border-top-right-radius: 13px;
}

.lot-table thead tr:first-child th:last-child::before {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  width: 13px;
  height: 13px;
  background: radial-gradient(circle at bottom left, transparent 13px, var(--bg) 13px);
}

.lot-table td {
  padding: 0.65rem 1rem;
  border-bottom: 1px solid var(--nav-border);
  font-size: 0.9rem;
  vertical-align: middle;
}

.lot-table th.lot-table-status,
.lot-table td.lot-table-status {
  text-align: center;
}

.lot-table tbody tr {
  cursor: pointer;
  transition: background-color 0.15s ease;
}

.lot-table tbody tr:hover {
  background: var(--tab-bg);
}

.lot-table tbody tr:hover .lot-table-code {
  color: var(--accent);
}

.lot-table tbody tr:last-child td {
  border-bottom: none;
}

.lot-table-code {
  font-family: "Fraunces", Georgia, serif;
  font-weight: 700;
  color: var(--text-primary);
}

.lot-table-crop {
  color: var(--text-secondary);
  font-size: 0.8rem;
}

.lot-row {
  display: flex;
  flex-direction: column;
  color: inherit;
  background: var(--card-bg);
  border-radius: 14px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
  border: 1px solid var(--card-border-strong);
  overflow: hidden;
}

.lot-row:hover {
  border-width: 2px;
  border-color: var(--accent);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}

.lot-row-header {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  background: var(--accent-tint-bg);
  padding: 0.55rem 1rem;
  border-bottom: 1px solid var(--card-border-strong);
}

.lot-row-code {
  flex-shrink: 0;
  font-family: "Fraunces", Georgia, serif;
  font-weight: 700;
  font-size: 1.15rem;
  color: var(--accent);
}

.lot-row-crop {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
  font-size: 0.85rem;
  color: var(--text-secondary);
}

.lot-row-body {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.75rem 1rem;
}

.lot-row-info {
  min-width: 0;
  flex: 1;
}

@media (max-width: 899px) {
  .lot-row-year-line {
    display: flex;
    align-items: baseline;
    gap: 0.3rem;
    min-width: 0;
  }

  .lot-row-grower {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
    flex: 1;
  }

  .lot-row-stats-line {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.1rem;
  }

  .lot-row-stats-line .lot-row-sep {
    display: none;
  }
}

.lot-row svg {
  width: 18px;
  height: 18px;
  color: var(--text-secondary);
  transition: transform 0.15s ease;
}

.lot-row:hover svg {
  transform: translateX(2px);
  color: var(--accent);
}

/* Settings layout */

.settings-layout {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.settings-account {
  order: 1;
}

.settings-taxonomy {
  order: 2;
}

.settings-footer {
  order: 3;
}

@media (min-width: 900px) {
  .settings-layout {
    display: grid;
    grid-template-columns: minmax(320px, 420px) 1fr;
    /* min-content (not auto) caps the first row at settings-account's own
       height — otherwise the tall right-hand taxonomy card (which spans
       both rows) inflates row 1 too, pushing settings-footer down with it. */
    grid-template-rows: min-content 1fr;
    gap: 2rem;
    align-items: start;
  }

  .settings-account {
    grid-column: 1;
    grid-row: 1;
  }

  .settings-taxonomy {
    grid-column: 2;
    grid-row: 1 / span 2;
  }

  .settings-footer {
    grid-column: 1;
    grid-row: 2;
  }
}

/* Variety detail: Lots / Products side-by-side on wide screens */

.variety-columns {
  display: block;
}

@media (min-width: 900px) {
  .variety-columns {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 2.5rem;
    align-items: start;
  }
}

/* Variety detail header: search bar spans the top on mobile, moves inline
   with the edit button on wide screens. */

.variety-header {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas:
    "search edit"
    "info   info";
  gap: 0.75rem 1rem;
  align-items: start;
  margin-bottom: 1rem;
}

.variety-header-info {
  grid-area: info;
}

.variety-header-search {
  grid-area: search;
  width: 100%;
}

.variety-header-edit {
  grid-area: edit;
}

@media (min-width: 600px) {
  .variety-header {
    grid-template-columns: 1fr auto auto;
    grid-template-areas: "info search edit";
  }

  .variety-header-search {
    width: clamp(140px, 30vw, 220px);
  }
}

/* Notes + usage button: stacked on mobile, side by side on wide screens. */

.variety-notes-row {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.75rem;
  margin-bottom: 1.5rem;
}

@media (min-width: 600px) {
  .variety-notes-row {
    flex-direction: row;
    align-items: flex-start;
    gap: 1rem;
  }
}

/* Planning header: title row, then action buttons on their own line on
   mobile — side by side on wide screens, same breakpoint the table/card
   swap on this page already uses. */

.planning-header {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-bottom: 1rem;
}

@media (min-width: 900px) {
  .planning-header {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }

  /* Same fixed-shell approach as .catalog-page-shell (see that block for
     the full reasoning): pins the header/filter row/suggestions in place
     below the nav and makes #planning-content the one scrolling pane, with
     its own table header locked at the top of *that* pane instead of the
     page's scroll. */
  .planning-page-shell {
    position: fixed;
    top: 88px;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1;
    display: flex;
    flex-direction: column;
    max-width: 1280px;
    margin: 0 auto;
    padding: 1.25rem;
  }

  .planning-header,
  .planning-filters-row {
    flex-shrink: 0;
  }

  #planning-content {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding-right: 1rem;
  }

  #planning-content .lot-table th {
    top: 0;
  }
}

@media (max-width: 899px) {
  #variety-products {
    margin-top: 2rem;
  }
}

.settings-header-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1rem;
  margin-bottom: 0.25rem;
}

.taxonomy-name-group {
  min-width: 0;
  flex: 1 1 auto;
}

.taxonomy-actions {
  flex-shrink: 0;
}

.truncate {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.badge-count-desktop {
  display: none;
}

.badge-count-mobile {
  display: inline;
}

@media (min-width: 900px) {
  .badge-count-desktop {
    display: inline;
  }

  .badge-count-mobile {
    display: none;
  }
}

@media (max-width: 399px) {
  .taxonomy-actions {
    gap: 0.1rem !important;
  }

  .icon-btn.small {
    width: 26px;
    height: 26px;
  }
}

.stock-seed-usage {
  margin-top: 1.25rem;
  padding: 0.85rem;
  border: 1px solid var(--nav-border);
  border-radius: 12px;
}

.usage-summary {
  padding: 0.85rem;
  border: 1px solid var(--nav-border);
  border-radius: 12px;
}

.stock-seed-usage-header {
  background: var(--accent-green-bg);
  color: var(--accent-green-text);
  margin: -0.85rem -0.85rem 0.6rem;
  padding: 0.5rem 0.85rem;
  border-radius: 12px 12px 0 0;
}

/* Forms */

form .field {
  margin-bottom: 1rem;
}

form label {
  display: block;
  font-size: 0.85rem;
  font-weight: 600;
  margin-bottom: 0.3rem;
  color: var(--text-secondary);
}

form input,
form textarea,
form select,
.datepicker-display {
  width: 100%;
  padding: 0.6rem 0.75rem;
  border-radius: 10px;
  border: 1px solid var(--nav-border);
  background: var(--card-bg);
  color: var(--text-primary);
  font-size: 1rem;
  font-family: inherit;
}

form select:disabled,
form input:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

/* Password show/hide toggle (static/js/password-toggle.js) */

.password-field-wrap {
  position: relative;
}

.password-field-wrap input {
  padding-right: 2.5rem;
}

.password-toggle-btn {
  position: absolute;
  top: 50%;
  right: 0.6rem;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  padding: 0;
  color: var(--text-secondary);
  cursor: pointer;
}

.password-toggle-btn svg {
  width: 18px;
  height: 18px;
}

.password-toggle-btn:hover {
  color: var(--text-primary);
}

form input[type="checkbox"] {
  width: 16px;
  height: 16px;
  padding: 0;
  border-radius: 4px;
  accent-color: var(--accent);
  flex-shrink: 0;
}

form .errorlist {
  color: var(--danger);
  font-weight: 600;
  font-size: 0.8rem;
  list-style: none;
  padding: 0;
  margin: 0.25rem 0 0.75rem;
}

.no-spinner {
  -moz-appearance: textfield;
}

.no-spinner::-webkit-outer-spin-button,
.no-spinner::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* Date picker */

.datepicker-wrapper {
  position: relative;
}

.datepicker-display {
  text-align: left;
  cursor: pointer;
}

.datepicker-display.is-placeholder {
  color: var(--text-secondary);
}

.datepicker-popover {
  position: fixed;
  z-index: 100;
  width: 280px;
  background: var(--card-bg);
  border: 1px solid var(--nav-border);
  border-radius: 14px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.28);
  padding: 0.9rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
}

.datepicker-popover.position-below {
  transform: translateY(-8px);
}

.datepicker-popover.position-above {
  transform: translateY(8px);
}

.datepicker-popover.open {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
}

.datepicker-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.7rem;
}

.datepicker-label {
  font-family: "Fraunces", Georgia, serif;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--text-primary);
}

.datepicker-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: none;
  border-radius: 999px;
  background: none;
  color: var(--text-primary);
  cursor: pointer;
}

.datepicker-nav svg {
  width: 16px;
  height: 16px;
}

.datepicker-nav:hover:not(:disabled) {
  background: var(--tab-bg);
}

.datepicker-nav:disabled {
  color: var(--nav-inactive);
  cursor: not-allowed;
}

.datepicker-weekdays,
.datepicker-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
}

.datepicker-weekdays {
  color: var(--text-secondary);
  font-size: 0.7rem;
  font-weight: 600;
  text-align: center;
  margin-bottom: 0.3rem;
}

.datepicker-grid {
  gap: 2px;
}

.datepicker-day {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 999px;
  background: none;
  color: var(--text-primary);
  font-size: 0.85rem;
  font-family: inherit;
  cursor: pointer;
}

.datepicker-day.filler {
  cursor: default;
}

.datepicker-day:hover:not(:disabled):not(.filler) {
  background: var(--tab-bg);
}

.datepicker-day.today {
  box-shadow: inset 0 0 0 1px var(--accent);
}

.datepicker-day.selected {
  background: var(--accent);
  color: var(--accent-text);
  font-weight: 600;
}

.datepicker-day.disabled {
  color: var(--nav-inactive);
  cursor: not-allowed;
}

/* Bottom nav (mobile) */

.bottom-nav {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: var(--nav-bg);
  border-top: 1px solid var(--nav-border);
  display: flex;
  z-index: 40;
}

.bottom-nav a,
.bottom-nav button {
  flex: 1;
  text-align: center;
  padding: 0.6rem 0 0.75rem;
  color: var(--nav-inactive);
  font-size: 0.7rem;
  font-weight: 600;
  background: none;
  border: none;
  font-family: inherit;
  cursor: pointer;
}

.bottom-nav a.active,
.bottom-nav button.active {
  color: var(--accent);
}

.bottom-nav .icon {
  width: 22px;
  height: 22px;
  display: block;
  margin: 0 auto 0.2rem;
}

@media (min-width: 900px) {
  .bottom-nav {
    display: none;
  }
  body {
    padding-bottom: 0;
  }
}

/* "More" bottom sheet (mobile only — desktop has room for plain nav links) */

.more-sheet {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: rgba(0, 0, 0, 0.45);
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.more-sheet-panel {
  background: var(--bg);
  width: 100%;
  max-width: 420px;
  border-radius: 20px 20px 0 0;
  padding: 1.25rem;
  padding-bottom: calc(1.25rem + env(safe-area-inset-bottom));
}

.more-sheet-row {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.75rem 0.25rem;
  color: var(--text-primary);
  font-weight: 600;
}

.more-sheet-row + .more-sheet-row {
  border-top: 1px solid var(--nav-border);
}

.more-sheet-row .icon {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  color: var(--text-secondary);
}

@media (min-width: 900px) {
  .more-sheet {
    display: none !important;
  }
}

/* Modal / sheet */

.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  z-index: 50;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

@media (min-width: 900px) {
  .modal-backdrop {
    align-items: center;
  }
}

.modal-sheet {
  background: var(--bg);
  width: 100%;
  max-width: 520px;
  border-radius: 20px 20px 0 0;
  padding: 1.5rem;
  max-height: 90vh;
  overflow-y: auto;
}

@media (min-width: 900px) {
  .modal-sheet {
    border-radius: 20px;
  }
}

.modal-sheet-wide {
  max-width: 640px;
}

.chart-toggle {
  display: inline-flex;
  gap: 0.3rem;
  background: var(--tab-bg);
  border-radius: 999px;
  padding: 0.25rem;
}

.chart-toggle-btn {
  border: none;
  border-radius: 999px;
  padding: 0.35rem 0.9rem;
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--tab-text);
  background: transparent;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.chart-toggle-btn.active {
  background: var(--accent);
  color: var(--accent-text);
}

/* Toggle switch */

.toggle {
  position: relative;
  display: inline-block;
  width: 46px;
  height: 26px;
}

.toggle-track {
  position: absolute;
  inset: 0;
  background: var(--toggle-track-off);
  border-radius: 999px;
  cursor: pointer;
}

.toggle-track.on {
  background: var(--toggle-track-on);
}

.toggle-thumb {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #fff;
  transition: transform 0.2s ease;
}

.toggle-track.on .toggle-thumb {
  transform: translateX(20px);
}

.toggle-track.disabled {
  cursor: not-allowed;
  opacity: 0.55;
}

/* Utility */

.text-secondary {
  color: var(--text-secondary);
}

.stack {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.space-between {
  justify-content: space-between;
}
