/* ---------- Design tokens ---------- */
:root {
  --radius: 0.75rem;
  --radius-sm: calc(var(--radius) - 4px);
  --radius-md: calc(var(--radius) - 2px);
  --radius-lg: var(--radius);
  --radius-xl: calc(var(--radius) + 4px);
  --radius-2xl: calc(var(--radius) + 8px);

  --font-sans: "Work Sans", ui-sans-serif, system-ui, sans-serif;
  --font-display: "Montserrat", "Work Sans", sans-serif;

  --color-estate-green: #066543;
  --color-estate-sage: #8ea96f;
  --color-estate-navy: #1A3357;
  --color-estate-ink: #1b1d27;
  --color-estate-cream: #F5FAF5;

  /* Converted from oklch to sRGB hex for universal browser support */
  --background: #fbfdfb;
  --foreground: #191b24;
  --card: #ffffff;
  --card-foreground: #191b24;
  --popover: #ffffff;
  --popover-foreground: #191b24;
  --primary: #1f5f42;
  --primary-foreground: #fbfdfb;
  --secondary: #eef4ee;
  --secondary-foreground: #23262f;
  --muted: #eef3ee;
  --muted-foreground: #6c7079;
  --accent: #bcd39a;
  --accent-foreground: #234a2c;
  --destructive: #cf3a34;
  --destructive-foreground: #fdfdfd;
  --success: #4f9d5f;
  --success-foreground: #fdfdfd;
  --border: #e2e8e1;
  --input: #dfe6dd;
  --ring: #1f5f42;
  --warning: #8a520b;         /* Reserved badge: white text on this hits ~5.3:1 */
  --warning-foreground: #fdfdfd;
}

html.dark {
  --background: #12161a;
  --foreground: #f2f5f2;
  --card: #191f24;
  --card-foreground: #f2f5f2;
  --popover: #191f24;
  --popover-foreground: #f2f5f2;
  --primary: #6fc496;
  --primary-foreground: #12161a;
  --secondary: #232b30;
  --secondary-foreground: #f2f5f2;
  --muted: #232b30;
  --muted-foreground: #a1abb0;
  --accent: #35492f;
  --accent-foreground: #cfe3c7;
  --destructive: #e0685f;
  --destructive-foreground: #12161a;
  --success: #7cd192;
  --success-foreground: #12161a;
  --border: rgba(255,255,255,0.1);
  --input: rgba(255,255,255,0.14);
  --ring: #6fc496;
  --warning: #e0a04a;         /* amber is light-luminance — dark text reads
                                  better here than white: ~7:1 vs the low
                                  contrast white gets against any amber */
  --warning-foreground: #12161a;
}

/* Smooth theme switches instead of a hard flash */
body, .card, .site-header, .btn, .input, .textarea, .select, .pill {
  transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}

/* ---------- Reset / base ---------- */
* { box-sizing: border-box; border-color: var(--border); }
html, body { margin: 0; padding: 0; }
body {
  background-color: var(--background);
  color: var(--foreground);
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
h1, h2, h3, h4 { font-family: var(--font-display); letter-spacing: -0.01em; margin: 0; }
a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
button { font-family: inherit; }
main { flex: 1; }

.container { margin-left: auto; margin-right: auto; max-width: 80rem; padding-left: 1rem; padding-right: 1rem; }
.container-md { margin-left: auto; margin-right: auto; max-width: 42rem; padding-left: 1rem; padding-right: 1rem; }
.container-sm { margin-left: auto; margin-right: auto; max-width: 28rem; padding-left: 1rem; padding-right: 1rem; }
.container-lg { margin-left: auto; margin-right: auto; max-width: 64rem; padding-left: 1rem; padding-right: 1rem; }

.muted { color: var(--muted-foreground); }
.text-sm { font-size: 0.875rem; }
.text-xs { font-size: 0.75rem; }
.text-center { text-align: center; }
.mt-1 { margin-top: .25rem; } .mt-2 { margin-top: .5rem; } .mt-3 { margin-top: .75rem; }
.mt-4 { margin-top: 1rem; } .mt-5 { margin-top: 1.25rem; } .mt-6 { margin-top: 1.5rem; }
.mb-1 { margin-bottom: .25rem; } .mb-2 { margin-bottom: .5rem; } .mb-3 { margin-bottom: .75rem; }
.mb-4 { margin-bottom: 1rem; } .mb-6 { margin-bottom: 1.5rem; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  font-size: 0.875rem; font-weight: 500;
  padding: 0.5rem 1rem;
  cursor: pointer;
  background: var(--primary);
  color: var(--primary-foreground);
  transition: opacity .15s ease, transform .1s ease;
}
.btn:hover { opacity: .9; }
.btn:active { transform: scale(0.98); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn-full { width: 100%; }
.btn-lg { padding: 0.7rem 1.25rem; font-size: 0.95rem; }
.btn-sm { padding: 0.35rem 0.75rem; font-size: 0.8rem; }
.btn-secondary { background: var(--secondary); color: var(--secondary-foreground); }
.btn-ghost { background: transparent; color: var(--foreground); }
.btn-ghost:hover { background: var(--secondary); opacity: 1; }
.btn-outline { background: transparent; color: var(--foreground); border-color: var(--border); }
.btn-destructive { background: var(--destructive); color: var(--destructive-foreground); }
.btn-icon { padding: 0.5rem; }
.btn-full-rounded { border-radius: 999px; }

/* ---------- Card ---------- */
.card {
  background: var(--card);
  color: var(--card-foreground);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}
.card-flush { border: 0; box-shadow: 0 0 0 1px var(--border); }

/* ---------- Form elements ---------- */
.field { margin-bottom: 0; }
label.field-label, .label {
  display: block; font-size: 0.8rem; font-weight: 500; margin-bottom: 0.35rem; color: var(--foreground);
}
.input, .textarea, .select { min-width: 0; }
.input, .textarea, .select {
  width: 100%;
  border: 1px solid var(--input);
  background: var(--background);
  color: var(--foreground);
  border-radius: var(--radius-md);
  padding: 0.55rem 0.75rem;
  font-size: 0.9rem;
  font-family: inherit;
  outline: none;
}
.input:focus, .textarea:focus, .select:focus {
  border-color: var(--ring);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--ring) 25%, transparent);
}
.textarea { resize: vertical; min-height: 6rem; }

/* ---------- Badge ---------- */
.badge {
  display: inline-flex; align-items: center; border-radius: 999px;
  padding: 0.15rem 0.6rem; font-size: 0.7rem; font-weight: 600;
  background: var(--secondary); color: var(--secondary-foreground);
  border: 1px solid transparent;
}
.badge-outline { background: transparent; border-color: var(--border); color: var(--foreground); }
.badge-destructive { background: var(--destructive); color: var(--destructive-foreground); }

/* ---------- Header ---------- */
.site-header {
  position: sticky; top: 0; z-index: 40;
  border-bottom: 1px solid var(--border);
  background: color-mix(in srgb, var(--background) 85%, transparent);
  backdrop-filter: blur(10px);
}
.site-header-inner {
  margin: 0 auto; max-width: 80rem;
  display: flex; flex-direction: column; gap: 0.6rem;
  padding: 0.85rem 1rem;
}
.header-top-row { display: flex; align-items: center; gap: 1rem; }
.brand { display: flex; align-items: center; gap: 0.7rem; flex-shrink: 0; }
.brand svg { height: 2.75rem; width: 2.75rem; transition: transform .15s ease; }
.brand:hover svg { transform: scale(1.05); }
.brand-text-1 { font-family: var(--font-display); font-size: 0.95rem; font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase; color: var(--color-estate-green); }
.brand-text-2 { font-size: 0.72rem; letter-spacing: 0.22em; text-transform: uppercase; color: var(--muted-foreground); margin-top: -2px; }

.home-search { display: flex; justify-content: center; }
.home-search-wrap { position: relative; width: 100%; max-width: 40rem; }
.home-search-wrap svg { position: absolute; left: 1rem; top: 50%; transform: translateY(-50%); width: 1.25rem; height: 1.25rem; color: var(--muted-foreground); }
.home-search-wrap input {
  height: 3.25rem; width: 100%; border-radius: 999px; border: 1px solid var(--border);
  background: var(--card); color: var(--muted-foreground);
  padding-left: 3rem; padding-right: 1.25rem; font-size: 1.05rem; outline: none;
  box-shadow: 0 1px 2px rgba(0,0,0,0.04);
}
.home-search-wrap input:focus { box-shadow: 0 0 0 2px var(--ring); }

.input::placeholder, .textarea::placeholder, .home-search-wrap input::placeholder {
  color: var(--muted-foreground);
  opacity: 1;
}

.header-nav { margin-left: auto; display: flex; align-items: center; gap: 0.5rem; }

/* Desktop nav row (icon+label buttons) vs. mobile bar (theme + hamburger
   only) is a pure CSS split — no resize listener, nothing to double-wire. */
.brand-text { display: none; }
.header-nav-desktop { display: none; align-items: center; gap: 0.5rem; }
.mobile-bar-btn { display: inline-flex; }
.mobile-menu-panel {
  display: none; flex-direction: column; gap: .15rem;
  border-top: 1px solid var(--border); margin-top: .1rem; padding-top: .6rem;
}
.mobile-menu-panel.open { display: flex; }
@media (min-width: 640px) {
  .brand-text { display: block; }
  .header-nav-desktop { display: flex; }
  .mobile-bar-btn { display: none !important; }
  .mobile-menu-panel { display: none !important; }
}
.mobile-menu-row {
  display: flex; align-items: center; gap: .75rem;
  padding: .7rem .6rem; border-radius: var(--radius-md);
  font-size: .9rem; font-weight: 500; color: var(--foreground);
  text-decoration: none; border: none; background: none; width: 100%;
  text-align: left; cursor: pointer; position: relative;
}
.mobile-menu-row:hover { background: var(--secondary); }
.mobile-menu-row .notif-badge { position: static; margin-left: auto; }
.mobile-menu-divider { border-top: 1px solid var(--border); margin: .35rem 0; }

/* ---------- Hero ---------- */
.hero {
  position: relative; overflow: hidden; border-radius: 0 0 2rem 2rem; margin-bottom: 2.5rem;
  height: min(86vh, 720px);
}
.hero-bg {
  position: absolute; inset: 0; background-size: cover; background-position: center;
  transform: scale(1.05);
}
.hero-gradient {
  position: absolute; inset: 0;
  background: linear-gradient(to bottom, rgba(11,20,16,0.7), rgba(11,20,16,0.3) 45%, rgba(11,20,16,0.95));
}
.hero-content {
  position: relative; z-index: 10; margin: 0 auto; max-width: 80rem; height: 100%;
  display: flex; flex-direction: column; justify-content: flex-end; padding: 0 1.5rem 4rem;
}
/*.hero-eyebrow { font-family: var(--font-display); font-size: 0.7rem; letter-spacing: 0.4em; text-transform: uppercase; color: #cfe3c7; margin-bottom: 1rem; }*/
.hero-title { font-family: var(--font-display); color: #fff; font-size: 2.5rem; font-weight: 300; line-height: 1.05; letter-spacing: -0.02em; max-width: 48rem; }
.hero-title .accent { display: block; font-style: italic; font-family: Georgia, serif; color: var(--color-estate-sage); margin-top: 0.25rem; }
/*.hero-sub { margin-top: 1.5rem; max-width: 34rem; color: rgba(255,255,255,0.75); font-size: 0.95rem; }
.hero-scroll {
  position: absolute; bottom: 1.25rem; left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; color: rgba(255,255,255,0.7);
  font-size: 0.62rem; letter-spacing: 0.3em; text-transform: uppercase;
}*/
@media (min-width: 768px) { .hero-title { font-size: 4.5rem; } }

/* ---------- Category pills ---------- */
.pill-row { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.pill {
  display: inline-flex; align-items: center;
  border-radius: 999px; padding: 0.4rem 0.9rem; font-size: 0.85rem; line-height: 1.2;
  border: 1px solid var(--border); background: var(--card); cursor: pointer;
  transition: background .15s ease; white-space: nowrap; color: var(--foreground);
}
.pill:hover { background: var(--secondary); }
.pill.active { background: var(--foreground); color: var(--background); border-color: var(--foreground); }
/* Live count per category. currentColor so it inherits the pill's own state
   (dark text normally, light text when the pill is active) and stays legible
   in both themes without a second set of tokens. */
.pill-count {
  margin-left: .4rem; font-size: .72rem; font-weight: 600;
  font-variant-numeric: tabular-nums; opacity: .55; color: currentColor;
}
.pill.active .pill-count { opacity: .75; }

/* ---------- Listing grid ---------- */
.listing-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1rem; }
@media (min-width: 640px) { .listing-grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 768px) { .listing-grid { grid-template-columns: repeat(4, 1fr); } }
@media (min-width: 1024px) { .listing-grid { grid-template-columns: repeat(5, 1fr); } }

.listing-card-wrap { position: relative; }
.listing-card { overflow: hidden; box-shadow: 0 0 0 1px var(--border); border: 0; transition: box-shadow .25s ease, transform .25s ease; display: block; }
.listing-card:hover { box-shadow: 0 0 0 1px color-mix(in srgb, var(--primary) 40%, transparent), 0 10px 24px -8px rgba(0,0,0,0.15); transform: translateY(-2px); }
.listing-thumb { aspect-ratio: 1/1; background: var(--secondary); position: relative; overflow: hidden; }
.listing-thumb img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s ease; }
.listing-card:hover .listing-thumb img { transform: scale(1.08); }
.listing-thumb .badge { position: absolute; top: 0.5rem; left: 0.5rem; background: var(--secondary); }
.listing-thumb .placeholder { height: 100%; width: 100%; display: grid; place-items: center; color: var(--muted-foreground); }
.listing-body { padding: 0.75rem; }
.listing-title { font-size: 0.875rem; color: var(--foreground); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.listing-price { font-size: 1rem; font-weight: 700; margin-top: 0.15rem; }
.listing-time { font-size: 0.72rem; margin-top: 0.15rem; }
.listing-seller { font-size: 0.75rem; color: var(--muted-foreground); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.wishlist-btn {
  position: absolute; top: 0.5rem; right: 0.5rem; z-index: 2;
  width: 2rem; height: 2rem; border-radius: 999px;
  background: color-mix(in srgb, var(--card) 85%, transparent);
  display: flex; align-items: center; justify-content: center;
  border: none; cursor: pointer; color: var(--muted-foreground);
  transition: transform .15s ease, color .15s ease;
}
.wishlist-btn:hover { transform: scale(1.08); }
.wishlist-btn.active { color: var(--destructive); }
.wishlist-btn:disabled { opacity: 0.6; cursor: default; }

/* ---------- Empty state ---------- */
.empty-state { padding: 3rem; text-align: center; color: var(--muted-foreground); }

/* ---------- Intro loader ---------- */
.intro-overlay {
  position: fixed; inset: 0; z-index: 100; display: grid; place-items: center;
  /* Fade must match FADE_MS in js/intro.js, which removes the node. */
  background: #0b1410; transition: opacity .25s ease, transform .25s ease;
}
.intro-overlay.hide { opacity: 0; transform: translateY(-30px); pointer-events: none; }
.intro-glow {
  position: absolute; inset: 0; opacity: 0.6;
  background:
    radial-gradient(60% 60% at 50% 40%, rgba(142,169,111,0.25), transparent 60%),
    radial-gradient(40% 40% at 70% 70%, rgba(6,101,67,0.4), transparent 60%);
}
.intro-inner { position: relative; display: flex; flex-direction: column; align-items: center; gap: 1.25rem; }
.intro-inner svg { height: 4rem; width: 4rem; filter: drop-shadow(0 0 24px rgba(142,169,111,0.45)); }
.intro-label-1 { font-family: var(--font-display); color: #fff; letter-spacing: 0.3em; font-size: 0.7rem; text-transform: uppercase; text-align: center; }
.intro-label-2 { font-size: 0.62rem; letter-spacing: 0.4em; text-transform: uppercase; color: rgba(255,255,255,0.5); margin-top: 0.25rem; text-align: center; }
.intro-dots { display: flex; gap: 0.4rem; margin-top: 0.5rem; }
.intro-dots span { height: 0.4rem; width: 0.4rem; border-radius: 999px; background: var(--color-estate-sage); animation: introBounce 1s infinite; }
.intro-dots span:nth-child(2) { animation-delay: .15s; }
.intro-dots span:nth-child(3) { animation-delay: .3s; }
@keyframes introBounce { 0%,100% { transform: translateY(0); opacity: .4; } 50% { transform: translateY(-6px); opacity: 1; } }

/* ---------- Toasts ---------- */
.toast-container { position: fixed; bottom: 1.25rem; right: 1.25rem; z-index: 200; display: flex; flex-direction: column; gap: 0.5rem; }
.toast {
  background: var(--card); color: var(--card-foreground); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: 0.7rem 1rem; font-size: 0.85rem;
  box-shadow: 0 8px 24px -6px rgba(0,0,0,0.2);
  animation: toastIn .2s ease;
  max-width: 22rem;
}
.toast.success { border-left: 3px solid var(--success); }
.toast.error { border-left: 3px solid var(--destructive); }
@keyframes toastIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }

/* ---------- Confirm dialog (replaces window.confirm) ---------- */
.dialog-overlay {
  position: fixed; inset: 0; z-index: 300;
  display: flex; align-items: center; justify-content: center; padding: 1rem;
  background: rgba(0,0,0,0.45);
  animation: dialogOverlayIn .15s ease;
}
.dialog-box {
  background: var(--card); color: var(--card-foreground);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: 0 12px 32px -8px rgba(0,0,0,0.3);
  max-width: 24rem; width: 100%; padding: 1.25rem;
  animation: dialogBoxIn .18s ease;
}
.dialog-title { font-weight: 700; margin-bottom: .35rem; }
.dialog-body { font-size: .875rem; color: var(--muted-foreground); margin-bottom: 1.1rem; line-height: 1.5; }
.dialog-actions { display: flex; justify-content: flex-end; gap: .5rem; }
@keyframes dialogOverlayIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes dialogBoxIn { from { opacity: 0; transform: translateY(6px) scale(.98); } to { opacity: 1; transform: translateY(0) scale(1); } }
/* ---------- Order review (ECT s43(2)) ---------- */
.review-line {
  display: flex; justify-content: space-between; gap: 1rem;
  padding: .4rem 0; font-size: .875rem;
  border-bottom: 1px solid var(--border);
}
.review-line > span:first-child { color: var(--muted-foreground); flex-shrink: 0; }
.review-line > span:last-child { text-align: right; font-variant-numeric: tabular-nums; }
.review-total {
  border-bottom: 0; font-weight: 700; font-size: 1rem;
  padding-top: .6rem; margin-top: .2rem; border-top: 2px solid var(--foreground);
}

/* ---------- Open-reports ring (admin) ---------- */
.reports-ring { display: inline-flex; position: relative; width: 1.5rem; height: 1.5rem; margin-left: .35rem; }
.reports-ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.reports-ring circle { fill: none; stroke-width: 2.5; }
.reports-ring-track { stroke: var(--border); }
.reports-ring-fill {
  stroke-linecap: round;
  transition: stroke-dashoffset .9s cubic-bezier(.85,0,.15,1);
}
.reports-ring b {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: .6rem; font-weight: 700; font-variant-numeric: tabular-nums;
  color: var(--foreground);
}

/* ---------- Swipe-to-action rows (touch) ---------- */
.swipe-row { position: relative; overflow: hidden; touch-action: pan-y; }
.swipe-row-actions {
  position: absolute; inset: 0 0 0 auto; display: flex; align-items: stretch;
}
.swipe-row-actions button {
  border: 0; cursor: pointer; font-size: .8rem; font-weight: 600;
  padding: 0 1.1rem; color: #fff;
}
.swipe-row-action-edit { background: var(--primary); }
.swipe-row-action-delete { background: var(--destructive); }
.swipe-row-surface {
  position: relative; background: var(--card);
  transition: transform .22s cubic-bezier(.2,.8,.2,1);
  will-change: transform;
}
.swipe-row.dragging .swipe-row-surface { transition: none; }
/* Pointer devices get the normal buttons instead; swipe is a touch idiom. */
@media (hover: hover) and (pointer: fine) {
  .swipe-row-actions { display: none; }
}
/* .listing-row is the flex container, but the surface now sits between it and
   .lr-main / .lr-actions. Move the layout down one level so the row still
   lays out the same, with or without swipe. */
.listing-row.swipe-row { display: block; padding: 0; }
.listing-row.swipe-row .swipe-row-surface {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
}

/* ---------- Focus ----------
   Keyboard focus only (:focus-visible), so mouse users never see a ring.
   The outline is drawn OUTSIDE the element thanks to outline-offset, so it
   lands on the page or card surface rather than on a button's own fill.
   That is why one colour works everywhere: --ring measures 7.41:1 on the
   light background and 8.67:1 on the dark one, and 7.6:1 / 7.9:1 on cards.
   Inputs keep their existing box-shadow ring and are excluded. */
:where(a, button, [role="button"], [tabindex]:not([tabindex="-1"])):focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
  border-radius: var(--radius-md);
}
/* Checkboxes and native controls sit tight against their labels, so the
   offset ring would collide with the text. Keep it snug instead. */
input[type="checkbox"]:focus-visible,
input[type="radio"]:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 1px;
}

@media (prefers-reduced-motion: reduce) {
  .dialog-overlay, .dialog-box { animation: none; }
  /* Anything that moves, stops. Card lifts, button presses, the intro
     splash, the report and terms dialogs. Colour and opacity changes are
     left alone: they carry state, and removing them would lose meaning. */
  .listing-card, .listing-card:hover { transition: none; transform: none; }
  .btn:active { transform: none; }
  .intro-overlay, .intro-glow, .intro-dots span, .intro-inner { animation: none !important; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------- Misc utility ---------- */
.grid-2 { display: grid; gap: 1.5rem; }
@media (min-width: 768px) { .grid-2 { grid-template-columns: 1fr 1fr; } }
.grid-form-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
@media (max-width: 640px) { .grid-form-2 { grid-template-columns: 1fr; } }
.grid-form-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.75rem; }
@media (max-width: 640px) { .grid-form-4 { grid-template-columns: 1fr; } }
.flex { display: flex; } .items-center { align-items: center; } .justify-between { justify-content: space-between; }
.gap-2 { gap: 0.5rem; } .gap-3 { gap: 0.75rem; } .gap-4 { gap: 1rem; }
.spinner-text { color: var(--muted-foreground); padding: 2rem 0; }

.photo-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.5rem; margin-top: 0.5rem; }
@media (min-width: 640px) { .photo-grid { grid-template-columns: repeat(4, 1fr); } }
.photo-thumb { position: relative; aspect-ratio: 1/1; border-radius: var(--radius-md); overflow: hidden; border: 1px solid var(--border); }
.photo-thumb img { width: 100%; height: 100%; object-fit: cover; }
.photo-remove { position: absolute; top: 0.25rem; right: 0.25rem; background: rgba(255,255,255,0.85); border-radius: 999px; padding: 0.25rem; border: none; cursor: pointer; }
.photo-upload {
  aspect-ratio: 1/1; border-radius: var(--radius-md); border: 2px dashed var(--border);
  display: grid; place-items: center; cursor: pointer; color: var(--muted-foreground);
}
.photo-upload:hover { background: var(--secondary); }

.thumb-strip { display: flex; gap: 0.5rem; overflow-x: auto; margin-top: 0.75rem; }
.thumb-strip button { height: 4rem; width: 4rem; border-radius: var(--radius-md); overflow: hidden; border: 2px solid transparent; padding: 0; cursor: pointer; background: none; }
.thumb-strip button.active { border-color: var(--primary); }
.thumb-strip img { width: 100%; height: 100%; object-fit: cover; }

/* ---------- Messaging ---------- */
.messages-layout { display: grid; grid-template-columns: 1fr; gap: 1rem; height: calc(100vh - 4rem - 2rem); min-height: 28rem; }
@media (min-width: 768px) { .messages-layout { grid-template-columns: 20rem 1fr; } }

.conversation-list { border: 1px solid var(--border); border-radius: var(--radius-lg); overflow-y: auto; background: var(--card); }
.conversation-list.has-active-thread { display: none; }
@media (min-width: 768px) { .conversation-list.has-active-thread { display: block; } }

.conversation-row {
  display: flex; align-items: center; gap: .75rem; padding: .75rem 1rem;
  border-bottom: 1px solid var(--border); cursor: pointer; text-decoration: none; color: inherit;
}
.conversation-row:last-child { border-bottom: 0; }
.conversation-row:hover { background: var(--secondary); }
.conversation-row.active { background: var(--secondary); }
.conversation-row img, .conversation-row .thumb-placeholder {
  width: 2.75rem; height: 2.75rem; border-radius: var(--radius-md); object-fit: cover; flex-shrink: 0;
  background: var(--secondary); display: grid; place-items: center; color: var(--muted-foreground);
}
.conv-title { font-weight: 600; font-size: .875rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.conversation-row .conv-preview { font-size: .8rem; color: var(--muted-foreground); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.chat-thread { display: none; flex-direction: column; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--card); overflow: hidden; }
.chat-thread.active { display: flex; }
@media (min-width: 768px) { .chat-thread { display: flex; } }

.chat-header { display: flex; align-items: center; gap: .75rem; padding: .75rem 1rem; border-bottom: 1px solid var(--border); flex-shrink: 0; }
.chat-header img, .chat-header .thumb-placeholder {
  width: 2.5rem; height: 2.5rem; border-radius: var(--radius-md); object-fit: cover; flex-shrink: 0;
  background: var(--secondary); display: grid; place-items: center; color: var(--muted-foreground);
}
.chat-back { display: inline-flex; }
@media (min-width: 768px) { .chat-back { display: none; } }

.chat-messages { flex: 1; overflow-y: auto; padding: 1rem; display: flex; flex-direction: column; gap: .5rem; }
.chat-bubble { max-width: 75%; padding: .5rem .8rem; border-radius: 1rem; font-size: .875rem; line-height: 1.4; }
.chat-bubble.mine { align-self: flex-end; background: var(--primary); color: var(--primary-foreground); border-bottom-right-radius: .3rem; }
.chat-bubble.theirs { align-self: flex-start; background: var(--secondary); color: var(--secondary-foreground); border-bottom-left-radius: .3rem; }
.chat-bubble-time { font-size: .65rem; opacity: .7; margin-top: .2rem; }

.chat-composer { display: flex; gap: .5rem; padding: .75rem; border-top: 1px solid var(--border); flex-shrink: 0; }
.chat-composer input { flex: 1; }
.chat-empty { flex: 1; display: grid; place-items: center; color: var(--muted-foreground); text-align: center; padding: 2rem; }

/* ---------- Responsive row layouts (My Listings, Admin Categories) ---------- */
.listing-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.listing-row .lr-main { flex: 1; min-width: 12rem; }
.listing-row .lr-actions { flex-shrink: 0; }
.admin-cat-row { flex-wrap: wrap; }

/* ---------- Small-screen tweaks ---------- */
@media (max-width: 640px) {
  .header-nav { gap: 0.3rem; }
  .btn-sm { padding: 0.32rem 0.65rem; }
  .hero-content { padding: 0 1rem 2.75rem; }
  .hero-eyebrow { font-size: 0.6rem; letter-spacing: 0.28em; margin-bottom: 0.75rem; }
  .hero-sub { font-size: 0.85rem; }
}

@media (max-width: 480px) {
  .listing-row .lr-actions { width: 100%; margin-top: 0.5rem; justify-content: flex-start; }
  .admin-cat-row .cat-slug { display: none; }
  .grid-form-4 > div:has(#cat-icon) { display: none; } /* icon field is optional, hide to save space */
}

/* Mobile browsers report 100vh taller than the visible area because of the
   address bar; dvh accounts for that where supported. */
.messages-layout {
  height: calc(100dvh - 4rem - 2rem);
}

/* ---------- Footer ---------- */
.site-footer { border-top: 1px solid var(--border); margin-top: 3rem; background: var(--card); }
.site-footer-inner {
  max-width: 80rem; margin: 0 auto; padding: 2.5rem 1rem 1.5rem;
  display: grid; gap: 2rem; grid-template-columns: 1fr;
}
@media (min-width: 768px) { .site-footer-inner { grid-template-columns: repeat(3, 1fr); } }
.footer-heading { font-family: var(--font-display); font-size: 0.8rem; font-weight: 700; letter-spacing: 0.04em; margin-bottom: 0.4rem; }
.footer-col a { color: var(--primary); }
.site-footer-bottom {
  border-top: 1px solid var(--border); padding: 1rem;
  display: flex; flex-wrap: wrap; gap: .75rem 1.5rem; align-items: center; justify-content: center;
}
.footer-donate { color: var(--destructive); text-decoration: underline; }

/* ---------- Sell form buyer-option toggles ---------- */
.toggle-list { display: flex; flex-direction: column; gap: .6rem; margin-top: .35rem; }
.toggle-row {
  display: flex; align-items: flex-start; gap: .6rem; padding: .65rem .75rem;
  border: 1px solid var(--border); border-radius: var(--radius-md); cursor: pointer;
  font-size: .85rem; font-weight: 400;
}
.toggle-row:hover { background: var(--secondary); }
.toggle-row input { margin-top: .2rem; accent-color: var(--primary); }

/* ---------- Notifications ---------- */
.notif-wrap { position: relative; }
.notif-badge {
  position: absolute; top: 0; right: 0;
  min-width: 1.05rem; height: 1.05rem; padding: 0 .25rem;
  border-radius: 999px; background: var(--destructive); color: var(--destructive-foreground);
  font-size: .6rem; font-weight: 700; display: flex; align-items: center; justify-content: center;
  pointer-events: none;
}
.notif-panel {
  position: absolute; right: 0; top: calc(100% + .5rem); width: 20rem; max-width: 85vw;
  background: var(--popover); color: var(--popover-foreground);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: 0 12px 32px -8px rgba(0,0,0,0.25); z-index: 60; overflow: hidden;
}
.notif-panel-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: .5rem .5rem .5rem .9rem; border-bottom: 1px solid var(--border);
}
.notif-list { max-height: 22rem; overflow-y: auto; }
.notif-item { display: block; padding: .6rem .9rem; border-bottom: 1px solid var(--border); }
.notif-item:last-child { border-bottom: 0; }
.notif-item:hover { background: var(--secondary); }
.notif-item.unread { background: color-mix(in srgb, var(--primary) 7%, transparent); }
.notif-item-title { font-size: .82rem; font-weight: 600; }
.notif-item-body { font-size: .78rem; color: var(--muted-foreground); margin-top: .1rem; }
.notif-item-time { font-size: .68rem; color: var(--muted-foreground); margin-top: .2rem; }

/* ---------- Star rating picker ---------- */
.star-btn { background: none; border: none; padding: .1rem; cursor: pointer; color: var(--muted-foreground); }
.star-btn.active { color: #e8a33d; }
.star-btn:hover { transform: scale(1.1); }
.footer-brand svg { height: 1.75rem; width: 1.75rem; flex-shrink: 0; }

/* Branded no-photo placeholder */
.placeholder-nice {
  height: 100%; width: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .45rem;
  color: var(--muted-foreground);
  background:
    radial-gradient(circle at 28% 18%, color-mix(in srgb, var(--primary) 12%, transparent), transparent 60%),
    radial-gradient(circle at 75% 82%, color-mix(in srgb, var(--primary) 8%, transparent), transparent 55%),
    var(--secondary);
}
.placeholder-nice .ph-label {
  font-size: .7rem; font-weight: 500; letter-spacing: .05em; text-transform: uppercase;
}

/* Icon size utilities (used by icons.js — were Tailwind classes pre-conversion) */
.h-3\.5 { height: .875rem; } .w-3\.5 { width: .875rem; }
.h-4  { height: 1rem; }     .w-4  { width: 1rem; }
.h-5  { height: 1.25rem; }  .w-5  { width: 1.25rem; }
.h-6  { height: 1.5rem; }   .w-6  { width: 1.5rem; }
.h-8  { height: 2rem; }     .w-8  { width: 2rem; }
.h-10 { height: 2.5rem; }   .w-10 { width: 2.5rem; }
.h-3 { height: .75rem; } .w-3 { width: .75rem; }
.btn svg { flex-shrink: 0; }

.btn-header-cta { background: transparent; color: var(--foreground); border-color: var(--primary); }
.btn-header-cta:hover { background: var(--secondary); opacity: 1; }

/* Grid children may shrink below their content's natural width —
   prevents long titles/buttons from forcing horizontal overflow */
.grid-2 > * { min-width: 0; }
img { max-width: 100%; }
html, body { overflow-x: hidden; }
#listing-description, .chat-bubble { overflow-wrap: break-word; }

.photo-remove { line-height: 0; }
.photo-remove svg { width: .75rem; height: .75rem; }

#seller-house { padding-top: 0.5rem; }
#seller-house svg { width: 1.25rem; height: 1.25rem; }

.status-badge { color: #fff; }
.status-badge.status-sold { background: rgba(192, 57, 43, .92); }
.status-badge.status-reserved { background: var(--warning); color: var(--warning-foreground); }
.status-badge.status-hidden { background: var(--foreground); color: var(--background); }

input[type="checkbox"] {
	margin-top: .2rem;
    accent-color: var(--primary);
}

/* ---------- Admin stats dashboard (admin-stats.html) ---------- */
/* Charts here are single-series by design. The dark palette puts --primary
   (#6fc496) and --success (#7cd192) only ~4 deltaE apart, so those two are
   never used to mean different things in the same view: series marks are
   --primary, and --success appears only as a "target cleared" state next to
   a tick and a number, never as a second series. */

.flex-wrap { flex-wrap: wrap; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

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

/* Demo-mode banner. Deliberately loud: mistaking demo figures for real ones
   is the single worst thing this page could do. */
.demo-banner {
  display: flex; align-items: flex-start; gap: .6rem;
  border: 1px solid var(--warning);
  background: color-mix(in srgb, var(--warning) 12%, var(--card));
  border-radius: var(--radius-lg);
  padding: .8rem 1rem; margin-bottom: 1.5rem;
}
.demo-banner svg { flex-shrink: 0; margin-top: .1rem; color: var(--warning); }
.demo-banner-title { font-weight: 700; font-size: .875rem; }
/* Full-strength ink, not muted: muted-foreground only reaches 4.2:1 against
   the tinted banner, and this is the one message on the page that must not be
   skimmed past. */
.demo-banner-body { font-size: .8rem; color: var(--foreground); margin-top: .15rem; line-height: 1.5; }
/* A rule down the page edge, so demo mode stays obvious after scrolling past
   the banner. */
body.is-demo main { border-left: 3px solid var(--warning); }

/* ---------- Milestone cards ---------- */
.milestone-card { padding: 1rem 1.1rem; }
.milestone-head { display: flex; align-items: baseline; justify-content: space-between; gap: .75rem; flex-wrap: wrap; }
.milestone-title { font-family: var(--font-display); font-weight: 700; }
.milestone-deadline { font-size: .75rem; color: var(--muted-foreground); font-variant-numeric: tabular-nums; }

/* Each measure is a ring plus its numbers, side by side. */
.measure-row {
  display: flex; align-items: center; gap: 1rem;
  border-top: 1px solid var(--border); padding-top: .9rem; margin-top: .9rem;
}
.measure-row:first-of-type { border-top: 0; padding-top: .4rem; margin-top: .4rem; }
.measure-body { min-width: 0; flex: 1; }
.measure-name { font-size: .875rem; font-weight: 500; }
.measure-value {
  font-family: var(--font-display); font-size: 1.5rem; font-weight: 700;
  line-height: 1.15; margin-top: .1rem; font-variant-numeric: tabular-nums;
}
.measure-target { font-size: .8rem; color: var(--muted-foreground); font-weight: 400; }
.measure-note { font-size: .72rem; color: var(--muted-foreground); margin-top: .2rem; line-height: 1.45; }

/* Progress ring: stroke-dasharray/dashoffset, the same technique already
   ported for the open-reports indicator in js/reportsRing.js. Cleared rings
   are --success; everything else stays neutral rather than taking a second
   green (see the note at the top of this block). The percentage inside the
   ring and the tick beside the value say the same thing, so colour is never
   carrying it alone. */
.ring { position: relative; width: 3.5rem; height: 3.5rem; flex-shrink: 0; }
.ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.ring circle { fill: none; stroke-width: 3.5; }
.ring-track { stroke: var(--secondary); }
.ring-fill {
  stroke: var(--muted-foreground); stroke-linecap: round;
  transition: stroke-dashoffset .9s cubic-bezier(.85, 0, .15, 1);
}
.ring-fill.is-met { stroke: var(--success); }
.ring-label {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: .7rem; font-weight: 700; font-variant-numeric: tabular-nums;
}
.ring-label.is-empty { color: var(--muted-foreground); font-weight: 500; }

/* "Held for N of 4 consecutive weeks". Four segments filled from the left,
   with the count spelled out beside them. */
.streak { display: flex; align-items: center; gap: .5rem; margin-top: .9rem; flex-wrap: wrap; }
.streak-dots { display: inline-flex; gap: .2rem; }
.streak-seg {
  width: 1.4rem; height: .3rem; border-radius: 999px;
  background: var(--secondary); box-shadow: inset 0 0 0 1px var(--border);
}
.streak-seg.on { background: var(--success); box-shadow: none; }
.streak-label { font-size: .75rem; color: var(--muted-foreground); }

/* A milestone that cannot be measured yet. Dashed, so it reads as pending
   rather than as a zero. */
.milestone-card.is-locked { border-style: dashed; background: transparent; }
.milestone-locked-head { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.milestone-locked-head svg { color: var(--muted-foreground); flex-shrink: 0; }
.locked-badge {
  font-size: .68rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .06em; color: var(--muted-foreground);
  border: 1px solid var(--border); border-radius: 999px; padding: .1rem .5rem;
}
.milestone-locked-note {
  font-size: .8rem; color: var(--muted-foreground); line-height: 1.55;
  border-left: 2px solid var(--border); padding-left: .7rem; margin: .6rem 0 0;
}
.locked-targets { font-size: .8rem; margin: .6rem 0 0; padding-left: 1.1rem; line-height: 1.6; }
.locked-targets li { margin-bottom: .1rem; }

/* ---------- Stat tiles ---------- */
.stat-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: .75rem; }
@media (min-width: 640px)  { .stat-grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1024px) { .stat-grid { grid-template-columns: repeat(4, 1fr); } }
.stat-grid > * { min-width: 0; }

.stat-tile { padding: .85rem .9rem; display: flex; flex-direction: column; }
.stat-tile-top { display: flex; align-items: flex-start; justify-content: space-between; gap: .5rem; }
.stat-tile-label { font-size: .75rem; color: var(--muted-foreground); line-height: 1.3; }
.stat-tile-value {
  font-family: var(--font-display); font-size: 1.55rem; font-weight: 700;
  line-height: 1.1; margin-top: .2rem; font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.stat-tile-value.is-empty { color: var(--muted-foreground); font-size: 1.05rem; font-weight: 500; }
.stat-tile-note { font-size: .72rem; color: var(--muted-foreground); margin-top: .2rem; line-height: 1.45; }

/* The headline health metric gets a heavier frame, because the brief says it
   is the one that matters most. */
.stat-tile.is-headline { box-shadow: inset 0 0 0 1px var(--primary); }
.stat-tile.is-headline .stat-tile-label { color: var(--primary); font-weight: 600; }

/* Trend badge: sign, arrow and number, so it never relies on colour. */
.trend-badge {
  display: inline-flex; align-items: center; gap: .15rem;
  font-size: .7rem; font-weight: 600; white-space: nowrap;
  padding: .1rem .4rem; border-radius: 999px;
  border: 1px solid var(--border); color: var(--muted-foreground);
}
.trend-badge svg { width: .7rem; height: .7rem; }
/* --success is tuned for fills, not for 11px text: on a white card it only
   reaches 3.3:1, under the 4.5 needed. The darker estate green clears it at
   ~8:1. In dark mode --success is already light enough (5:1) and the estate
   green would be far too dark, so the token stays there. */
.trend-badge.is-up { color: var(--color-estate-green); border-color: color-mix(in srgb, var(--success) 40%, transparent); }
html.dark .trend-badge.is-up { color: var(--success); }
.trend-badge.is-down { color: var(--destructive); border-color: color-mix(in srgb, var(--destructive) 40%, transparent); }

/* ---------- Sparkline ---------- */
/* 2px stroke over a fading fill, with a dot on the last point. Hovering a
   week moves the readout in the tile above to that week and back again on
   leave, rather than opening a tooltip that would cover a 40px-tall chart.
   Keyboard users get the same behaviour through focus. */
.spark { margin-top: .5rem; position: relative; }
.spark svg { display: block; width: 100%; height: 2.5rem; overflow: visible; }
.spark-line { fill: none; stroke: var(--primary); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.spark-hit { position: absolute; inset: 0; display: flex; }
.spark-hit button {
  flex: 1; background: none; border: 0; padding: 0; cursor: pointer;
  border-radius: var(--radius-sm);
}
.spark-hit button:hover, .spark-hit button:focus-visible {
  background: color-mix(in srgb, var(--primary) 12%, transparent);
}
.spark-empty {
  height: 2.5rem; display: grid; place-items: center;
  font-size: .7rem; color: var(--muted-foreground);
  border: 1px dashed var(--border); border-radius: var(--radius-sm); margin-top: .5rem;
}

/* ---------- Bar chart rows ---------- */
/* Wide charts scroll inside their own container, never the page body. */
.chart-card { padding: .95rem 1rem; }
.chart-head { display: flex; align-items: baseline; justify-content: space-between; gap: .75rem; flex-wrap: wrap; }
.chart-name { font-size: .875rem; font-weight: 600; }
.chart-sub { font-size: .72rem; color: var(--muted-foreground); font-variant-numeric: tabular-nums; }
.chart-scroll { overflow-x: auto; margin-top: .7rem; }
.chart-bars { display: flex; align-items: flex-end; gap: 2px; height: 4rem; min-width: 15rem; }
.chart-bar-hit {
  flex: 1; min-width: 10px; height: 100%; background: none; border: 0; padding: 0;
  display: flex; align-items: flex-end; cursor: default; border-radius: var(--radius-sm);
}
.chart-bar {
  width: 100%; background: var(--primary); border-radius: 4px 4px 0 0;
  min-height: 2px; transition: opacity .15s ease;
}
.chart-bar.is-zero { background: var(--border); }
.chart-bar-hit:hover .chart-bar,
.chart-bar-hit:focus-visible .chart-bar { opacity: .7; }
.chart-axis {
  display: flex; justify-content: space-between;
  font-size: .7rem; color: var(--muted-foreground); margin-top: .35rem;
}

/* ---------- Table ---------- */
.table-scroll { overflow-x: auto; }
.stat-table { width: 100%; border-collapse: collapse; font-size: .875rem; min-width: 22rem; }
.stat-table th, .stat-table td { padding: .55rem .9rem; text-align: right; white-space: nowrap; }
.stat-table th:first-child, .stat-table td:first-child { text-align: left; white-space: normal; }
.stat-table thead th { font-size: .75rem; color: var(--muted-foreground); font-weight: 500; border-bottom: 1px solid var(--border); }
.stat-table tbody tr + tr td { border-top: 1px solid var(--border); }
.stat-table td { font-variant-numeric: tabular-nums; }
/* Share-of-total bar under the category name. One series, one colour: never a
   darker shade for a bigger number, which would double-encode the value the
   row already states. */
.cat-bar { height: .3rem; border-radius: 999px; background: var(--primary); opacity: .8; margin-top: .3rem; min-width: 2px; }

.empty-note { padding: 1.25rem; text-align: center; font-size: .8rem; color: var(--muted-foreground); }

.method-list { margin: 0; }
.method-list dt { font-size: .875rem; font-weight: 600; margin-top: .9rem; }
.method-list dt:first-child { margin-top: 0; }
.method-list dd { margin: .2rem 0 0; font-size: .8rem; color: var(--muted-foreground); line-height: 1.55; }

@media (prefers-reduced-motion: reduce) {
  .ring-fill { transition: none; }
  .chart-bar { transition: none; }
}
