/* Reusable pieces: buttons, cards, chips, tags, forms, flashes.
 * Every interactive element is at least 44px tall — the smallest target a
 * finger hits reliably, and the figure Apple and Google both publish. */

/* ── Buttons ────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 44px;
  padding: 0.6rem 1.1rem;
  border: 1px solid var(--line-2);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-weight: 700;
  font-size: var(--t-base);
  cursor: pointer;
  text-align: center;
  transition: transform var(--ease), background var(--ease),
              border-color var(--ease), box-shadow var(--ease);
}
.btn:hover { background: var(--surface-2); }
.btn:active { transform: translateY(1px); }

.btn-primary {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--bg);
  box-shadow: var(--shadow-sm);
}
.btn-primary:hover { background: #163150; border-color: #163150; color: #fff; }

/* In dark mode --ink is near-white, so the label must be dark to read. In
 * light mode --bg is near-white, giving the original white-on-navy look. */
@media (prefers-color-scheme: dark) {
  .btn-primary:hover { background: var(--ink-2); border-color: var(--ink-2); color: var(--bg); }
}

.btn-gold { background: var(--gold); border-color: var(--gold); color: #fff; }
.btn-gold:hover { background: #b1740f; border-color: #b1740f; }

.btn-wa { background: var(--wa); border-color: var(--wa); color: #fff; }
.btn-wa:hover { background: var(--wa-dark); border-color: var(--wa-dark); }

.btn-danger { background: var(--danger-soft); border-color: transparent; color: var(--danger); }
.btn-danger:hover { background: #f8d7d4; }

.btn-ok { background: var(--ok-soft); border-color: transparent; color: var(--ok); }
.btn-ok:hover { filter: brightness(0.97); }

/* Secondary to a primary standing next to it: still a real target for a thumb,
 * but it does not compete with the button we actually want pressed. */
.btn-quiet { background: transparent; border-color: transparent; color: var(--ink-2); }
.btn-quiet:hover { background: var(--surface-2); color: var(--ink); }

.btn-block { width: 100%; }
.btn-sm { min-height: 38px; padding: 0.4rem 0.8rem; font-size: var(--t-sm); }
.btn svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 2; }

/* ── Chips (category filter) ────────────────────────────────────────────── */
/* A horizontal rail on a phone. Swiping a row of categories is the pattern
 * every marketplace uses; stacking them would push the listings off-screen. */
.chips {
  display: flex;
  gap: var(--s-2);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding: var(--s-1) var(--s-4) var(--s-3);
  margin-inline: calc(var(--s-4) * -1);     /* bleed to the screen edges */
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.chips::-webkit-scrollbar { display: none; }
@media (min-width: 64rem) {
  .chips { flex-wrap: wrap; overflow: visible; margin-inline: 0; padding-inline: 0; }
}

.chip {
  flex: none;
  scroll-snap-align: start;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  min-height: 38px;
  padding: 0.4rem 0.85rem;
  border-radius: var(--r-pill);
  background: var(--surface);
  border: 1px solid var(--line);
  color: var(--ink-2);
  font-size: var(--t-sm);
  font-weight: 600;
  white-space: nowrap;
  transition: background var(--ease), color var(--ease), border-color var(--ease);
}
.chip:hover { border-color: var(--line-2); }
.chip-on { background: var(--ink); border-color: var(--ink); color: #fff; }
.chip .count { opacity: .6; font-size: var(--t-xs); }
.chip-on .count { opacity: .8; }

/* A checkbox dressed as a chip, for the interest pickers. Unlike the filter
 * rail above these are a wrapping multi-select, so the container holding them
 * wraps rather than scrolls (the .field fieldset gives it a block context).
 * The native checkbox is hidden; the label is the whole hit target, and its
 * checked state is driven by :has() so no JavaScript is needed. */
.chip-check {
  display: inline-flex;
  align-items: center;
  min-height: 38px;
  margin: 0 var(--s-2) var(--s-2) 0;
  padding: 0.4rem 0.9rem;
  border-radius: var(--r-pill);
  background: var(--surface);
  border: 1px solid var(--line);
  color: var(--ink-2);
  font-size: var(--t-sm);
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--ease), color var(--ease), border-color var(--ease);
}
.chip-check input { position: absolute; opacity: 0; width: 0; height: 0; }
.chip-check:hover { border-color: var(--line-2); }
.chip-check:has(input:checked) {
  background: var(--ink); border-color: var(--ink); color: #fff;
}
/* Keyboard focus must be visible even though the box itself is hidden. */
.chip-check:has(input:focus-visible) { outline: 2px solid var(--ink); outline-offset: 2px; }
/* A wrapping container for the chip-checks — the opposite of the .chips rail,
 * which scrolls one row. Used on signup and the interests page. */
.chip-grid { display: flex; flex-wrap: wrap; margin-bottom: var(--s-3); }

/* ── Tags and badges ────────────────────────────────────────────────────── */
.tag {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.2rem 0.55rem;
  border-radius: var(--r-pill);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: .01em;
  background: var(--surface-2);
  color: var(--ink-2);
  white-space: nowrap;
}
.tag-goods    { background: #e7eefb; color: #1b4a8f; }
.tag-services { background: #eceaf9; color: #4b3c9a; }
/* Negosyo gets the warm one — a shop is the liveliest thing on the board. */
.tag-business { background: #fde9df; color: #9a4414; }
/* Palit is green: no money changes hands, and it reads as the odd one out. */
.tag-swap     { background: #e2f3e8; color: #14633c; }
.tag-verified { background: var(--gold-soft); color: var(--gold); }
@media (prefers-color-scheme: dark) {
  .tag-goods    { background: #16304f; color: #a9c9f5; }
  .tag-services { background: #272250; color: #c3b9f7; }
  .tag-business { background: #3d2015; color: #f3b48c; }
  .tag-swap     { background: #14321f; color: #8fd9ad; }
}

/* A palit's hook on a card, standing where the price would be. */
.card-swap {
  font-size: var(--t-sm);
  color: var(--ink-2);
  margin-top: 0.15rem;
  display: -webkit-box;
  -webkit-line-clamp: 2;        /* two lines, then ellipsis — cards stay level */
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.card-swap strong { color: var(--ink); }

/* ── Listing card ───────────────────────────────────────────────────────── */
/* Two to a row on a phone. One column wastes half the screen on a board whose
 * whole job is letting you scan quickly; three is too narrow to read a price. */
.grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-3);
}
@media (min-width: 40rem) { .grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-4); } }
@media (min-width: 64rem) { .grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* Search results: one column on mobile, widening on larger screens. */
.grid-one { grid-template-columns: 1fr; }
@media (min-width: 40rem) { .grid-one { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 64rem) { .grid-one { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.card {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: transform var(--ease), box-shadow var(--ease), border-color var(--ease);
}
@media (hover: hover) {
  .card:hover { transform: translateY(-2px); box-shadow: var(--shadow); border-color: var(--line-2); }
}

/* The box is reserved before the image arrives, so nothing jumps as photos
 * load — the single biggest cause of mis-taps on a slow connection. */
.card-media {
  position: relative;
  aspect-ratio: var(--card-ratio);
  background: var(--surface-2);
  overflow: hidden;
}
.card-media img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 300ms cubic-bezier(.2, .7, .3, 1);
}
@media (hover: hover) { .card:hover .card-media img { transform: scale(1.04); } }

/* More than one photo: the media becomes a swipeable strip. Pure CSS snap, so
 * it flicks on a phone with JavaScript off; a horizontal swipe scrolls the rail
 * and never counts as a tap, so the card still opens the ad on a real tap. */
.card-rail {
  display: flex;
  width: 100%; height: 100%;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  /* Let a vertical drag scroll the page and a horizontal one move the rail,
   * so the board still scrolls when a thumb lands on a photo. */
  touch-action: pan-x pan-y;
}
.card-rail::-webkit-scrollbar { display: none; }
.card-rail img {
  flex: none;
  width: 100%; height: 100%;
  scroll-snap-align: center;
  object-fit: cover;
}
/* The whole-card zoom-on-hover is for the single cover only — a strip that
 * scaled would clip its neighbours into view. */
@media (hover: hover) { .card:hover .card-rail img { transform: none; } }

.card-dots {
  position: absolute;
  left: 0; right: 0; bottom: var(--s-2);
  display: flex; justify-content: center; gap: 0.25rem;
  pointer-events: none;
}
.card-dots i {
  width: 5px; height: 5px; border-radius: 50%;
  background: rgba(255, 255, 255, .55);
  box-shadow: 0 0 2px rgba(13, 34, 55, .5);
  transition: background var(--ease), width var(--ease);
}
.card-dots i.on { background: #fff; width: 14px; border-radius: var(--r-pill); }

.card-media .no-photo {
  width: 100%; height: 100%;
  display: grid; place-items: center;
  color: var(--line-2);
}
.card-media .no-photo svg { width: 34%; height: auto; max-width: 56px; stroke: currentColor; fill: none; stroke-width: 1.5; }

.card-badges {
  position: absolute;
  inset: var(--s-2) var(--s-2) auto;
  display: flex;
  gap: var(--s-1);
  flex-wrap: wrap;
}
.card-badges .tag { box-shadow: var(--shadow-sm); }

.photo-count {
  position: absolute;
  right: var(--s-2); bottom: var(--s-2);
  display: inline-flex; align-items: center; gap: 0.2rem;
  padding: 0.15rem 0.45rem;
  border-radius: var(--r-pill);
  background: rgba(13, 34, 55, .72);
  color: #fff;
  font-size: var(--t-xs);
  font-weight: 700;
}
.photo-count svg { width: 13px; height: 13px; stroke: currentColor; fill: none; stroke-width: 2; }

.card-body { padding: var(--s-3); display: flex; flex-direction: column; gap: 0.15rem; flex: 1; }
.card-title {
  font-size: var(--t-base);
  font-weight: 700;
  color: var(--ink);
  line-height: 1.3;
  /* Two lines, then ellipsis — keeps every card in a row the same height. */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.card .price { font-size: var(--t-md); font-weight: 800; color: var(--ink); margin-top: 0.1rem; }
.card .price-free { color: var(--ok); }
.card-meta {
  margin-top: auto;
  padding-top: var(--s-2);
  display: flex; align-items: center; gap: 0.3rem;
  font-size: var(--t-xs); color: var(--muted);
}
.card-meta .dot { opacity: .5; }

/* ── Forms ──────────────────────────────────────────────────────────────── */
.field { display: block; margin-bottom: var(--s-4); }
.field > .label,
label > .label { display: block; font-weight: 700; color: var(--ink); font-size: var(--t-sm); margin-bottom: 0.3rem; }
.field .hint { display: block; font-size: var(--t-xs); color: var(--muted); margin-top: 0.3rem; }

input, select, textarea {
  width: 100%;
  font: inherit;
  /* 16px exactly: anything smaller makes iOS Safari zoom when it gets focus. */
  font-size: 16px;
  min-height: 48px;
  padding: 0.65rem 0.8rem;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  transition: border-color var(--ease), box-shadow var(--ease);
}
textarea { min-height: 7.5rem; resize: vertical; line-height: 1.5; }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 3px var(--gold-soft);
}
input::placeholder, textarea::placeholder { color: var(--muted); }
select {
  appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9'%3E%3Cpath d='M1 1l6 6 6-6' fill='none' stroke='%236b7f94' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.85rem center;
  padding-right: 2.2rem;
}

.row { display: grid; gap: var(--s-4); }
@media (min-width: 36rem) { .row { grid-template-columns: 1fr 1fr; } }

/* ── Flashes ────────────────────────────────────────────────────────────── */
.flashes { display: grid; gap: var(--s-2); margin-bottom: var(--s-4); }
.flash {
  display: flex; gap: 0.6rem; align-items: flex-start;
  padding: 0.7rem 0.9rem;
  border-radius: var(--r-sm);
  font-size: var(--t-sm);
  font-weight: 600;
  border: 1px solid transparent;
}
.flash-error { background: var(--danger-soft); color: var(--danger); }
.flash-ok    { background: var(--ok-soft); color: var(--ok); }

/* ── Empty state ────────────────────────────────────────────────────────── */
.empty {
  text-align: center;
  padding: var(--s-10) var(--s-4);
  background: var(--surface);
  border: 1px dashed var(--line-2);
  border-radius: var(--r-lg);
}
.empty h2 { margin-bottom: var(--s-2); }
.empty p { color: var(--muted); margin-bottom: var(--s-5); }
.empty .btn + .btn { margin-left: var(--s-2); }
