/* ---------- tokens (ported from habit-tracker) ---------- */
:root {
  --page: #f9f9f7;
  --surface: #fcfcfb;
  --ink: #0b0b0b;
  --ink-2: #52514e;
  --muted: #898781;
  --hair: #e1e0d9;
  --border: rgba(11,11,11,0.10);
  --accent: #2a78d6;
  --accent-tint: #e7f0fb;
  --good: #0ca30c;
  --good-strong: #006300;
  --good-soft: #86d986;
  --good-tint: #e4f5e4;
  --fun: #c65fb0;
  --fun-tint: #f9e9f5;
  --bad: #d03b3b;
  --bad-tint: #fbe9e9;
  --cell-miss: #f0d9d9;
  --cell-off: #f1f0ec;
  --toast-bg: #0b0b0b;
  --toast-ink: #fcfcfb;
}
@media (prefers-color-scheme: dark) {
  :root {
    --page: #0d0d0d;
    --surface: #1a1a19;
    --ink: #ffffff;
    --ink-2: #c3c2b7;
    --muted: #898781;
    --hair: #2c2c2a;
    --border: rgba(255,255,255,0.10);
    --accent: #3987e5;
    --accent-tint: #16283d;
    --good: #0ca30c;
    --good-strong: #7ee07e;
    --good-soft: #0a6e0a;
    --good-tint: #12330f;
    --fun: #d476c0;
    --fun-tint: #3a1c33;
    --bad: #d03b3b;
    --bad-tint: #3a1717;
    --cell-miss: #3a2424;
    --cell-off: #232322;
    --toast-bg: #fcfcfb;
    --toast-ink: #0b0b0b;
  }
}

/* ---------- base ---------- */
* { box-sizing: border-box; }
html { height: 100%; }
body {
  margin: 0;
  min-height: 100%;
  background: var(--page);
  color: var(--ink);
  font: 16px/1.5 system-ui, -apple-system, "Segoe UI", sans-serif;
  -webkit-font-smoothing: antialiased;
  padding-bottom: 72px; /* room for tab bar */
}
main { max-width: 560px; margin: 0 auto; padding: 16px; }
h1 { font-size: 20px; margin: 0; }
h2 { font-size: 15px; margin: 0 0 8px; color: var(--ink-2); text-transform: uppercase; letter-spacing: 0.04em; }
button { font: inherit; cursor: pointer; }
input, textarea, select { font: inherit; color: var(--ink); }
.hidden { display: none !important; }
.muted { color: var(--muted); }
.small { font-size: 13px; }

/* ---------- header ---------- */
header.app {
  padding: 16px 16px 0;
  max-width: 560px;
  margin: 0 auto;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
}

.daynav {
  display: flex; align-items: center; justify-content: center; gap: 14px;
  margin: 0 0 10px;
}
.daynav span { font-weight: 600; }
.daynav .btn[disabled] { opacity: 0.3; }

/* ---------- cards ---------- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 14px;
  margin-bottom: 14px;
}
.card h2 { display: flex; align-items: center; gap: 6px; }

/* ---------- buttons & chips ---------- */
.btn {
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--ink);
  border-radius: 10px;
  padding: 8px 14px;
}
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn.good { background: var(--good); border-color: var(--good); color: #fff; }
.btn.big { width: 100%; padding: 14px; font-size: 17px; font-weight: 600; border-radius: 12px; }
.btn.ghost { background: transparent; }
.btn:disabled { opacity: 0.5; cursor: default; }

.chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0; }
.chip {
  border: 1px solid var(--border);
  background: var(--page);
  color: var(--ink-2);
  border-radius: 999px;
  padding: 6px 12px;
  font-size: 14px;
}
.chip.on { background: var(--accent-tint); border-color: var(--accent); color: var(--accent); font-weight: 600; }

input[type="text"], textarea {
  width: 100%;
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px;
  background: var(--page);
}

/* ---------- done states ---------- */
.done-banner {
  background: var(--good-tint);
  color: var(--good-strong);
  border-radius: 10px;
  padding: 10px 12px;
  font-weight: 600;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
}
.done-banner.fun { background: var(--fun-tint); color: var(--fun); }
.done-banner .btn { flex-shrink: 0; }

/* ---------- suggestions ---------- */
.suggestion {
  border: 1px solid var(--hair);
  border-radius: 10px;
  padding: 10px;
  margin-top: 8px;
  display: flex;
  gap: 10px;
  align-items: flex-start;
  justify-content: space-between;
}
.suggestion b { display: block; }
.suggestion .meta { font-size: 12px; color: var(--muted); }
.suggestion .btn { flex-shrink: 0; }

/* ---------- friends strip ---------- */
.friends { display: flex; flex-direction: column; gap: 6px; }
.friend-row { display: flex; align-items: center; gap: 8px; }
.friend-row .name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.friend-row .marks { font-size: 18px; letter-spacing: 2px; }

/* ---------- board ---------- */
.board-user { margin-bottom: 18px; }
.board-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; margin-bottom: 6px; }
.grid30 { display: grid; grid-template-columns: repeat(10, 1fr); gap: 4px; }
.cell {
  aspect-ratio: 1;
  border-radius: 6px;
  background: var(--cell-off);
  border: 1px solid transparent;
  position: relative;
  padding: 0;
  font-size: 10px;
  color: var(--muted);
}
.cell.hit { background: var(--good); color: #fff; }
.cell.miss { background: var(--cell-miss); color: var(--bad); }
.cell.pending { background: var(--surface); border: 1.5px dashed var(--muted); }
.cell.future { background: var(--cell-off); opacity: 0.55; }
.cell .fun-dot {
  position: absolute; top: 2px; right: 2px;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--fun);
  border: 1px solid var(--surface);
}

/* ---------- action rows ---------- */
.actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }

/* ---------- photos ---------- */
.photo-wrap { margin-top: 10px; position: relative; }
.photo-thumb {
  width: 100%;
  max-height: 260px;
  object-fit: cover;
  border-radius: 10px;
  background: var(--cell-off);
  display: block;
}
.photo-thumb.uploading { opacity: 0.55; }
.photo-meta { font-size: 12px; color: var(--muted); margin: 6px 0 0; }
.photo-error {
  color: var(--bad);
  background: var(--bad-tint);
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 13px;
  margin: 10px 0;
}
.photo-wrap.failed::after {
  content: "🚫"; position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center; font-size: 24px;
}

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: 4px;
}
/* The tile is a wrapper, not a control: it holds two buttons, the image and
   the like. A button inside a button is invalid and browsers drop the inner
   one, which is why these are siblings. */
.gtile {
  position: relative;
  aspect-ratio: 1;
  border-radius: 8px;
  overflow: hidden;
  background: var(--cell-off);
}
.gopen {
  display: block;
  width: 100%; height: 100%;
  padding: 0; border: 0;
  background: none;
  cursor: pointer;
}
.gtile img { width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity 0.2s; }
.gtile img.ready { opacity: 1; }
.gtile.failed::after {
  content: "🚫"; position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center; font-size: 20px;
}
.gcap {
  position: absolute; left: 0; right: 0; bottom: 0;
  font-size: 11px; color: #fff;
  background: linear-gradient(transparent, rgba(0,0,0,0.6));
  padding: 12px 4px 3px;
}

.lightbox {
  position: fixed; inset: 0; z-index: 20;      /* above the toast */
  background: rgba(0,0,0,0.88);
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 12px;
  padding: 16px calc(16px + env(safe-area-inset-right)) calc(16px + env(safe-area-inset-bottom));
  /* With a thread open the photo and the comments together can be taller than
     the screen. Centred content overflows in both directions and the box at
     the bottom becomes unreachable, so let it scroll instead. */
  overflow-y: auto;
}
.lightbox img { max-width: 100%; max-height: 78vh; border-radius: 10px; }
/* The photo gives up height when there are comments to read. */
.lightbox:has(.thread) img { max-height: 46vh; }
.lightbox .cap { color: #fff; font-size: 14px; text-align: center; }
.lb-actions { display: flex; align-items: center; gap: 12px; }

/* ---- comments ---- */
/* Inside the lightbox, so it sits on the dark ground and sets its own colours
   rather than inheriting the page's. Capped and scrollable: a long thread must
   never push the photo off screen, and on a phone in landscape there isn't
   much height to give away. */
.thread {
  width: min(520px, 100%);
  max-height: 34vh; overflow-y: auto;
  background: rgba(255,255,255,0.08);
  border: 1px solid rgba(255,255,255,0.16);
  border-radius: 10px;
  padding: 10px 12px;
  display: flex; flex-direction: column; gap: 8px;
  color: #fff;
}
.thread .muted { color: rgba(255,255,255,0.6); }
.cmt {
  display: flex; align-items: baseline; gap: 7px;
  font-size: 13.5px; line-height: 1.45;
}
.cmt .who { font-weight: 600; white-space: nowrap; }
.cmt .body { flex: 1; overflow-wrap: anywhere; }
.cmt-x {
  flex: none; width: 22px; height: 22px; border: 0; border-radius: 50%;
  background: transparent; color: rgba(255,255,255,0.5);
  font-size: 17px; line-height: 1; cursor: pointer;
}
.cmt-x:hover { background: rgba(255,255,255,0.14); color: #fff; }
.cmt-add { display: flex; gap: 8px; margin-top: 2px; }
.cmt-add input {
  flex: 1; min-width: 0;                       /* or it overflows the flex row */
  font: inherit; font-size: 15px;              /* 16px-ish: smaller zooms on iOS */
  padding: 7px 10px; border-radius: 8px;
  border: 1px solid rgba(255,255,255,0.22);
  background: rgba(0,0,0,0.3); color: #fff;
}
.cmt-add input::placeholder { color: rgba(255,255,255,0.45); }
.cmt-add input:focus { outline: 2px solid rgba(255,255,255,0.5); outline-offset: 1px; }
.thread .err { color: #ffb4ab; }

/* ---- likes ---- */
/* 34px square is the smallest comfortable thumb target, and the tiles are
   only ~104px wide, so it cannot grow much beyond that. */
.like {
  display: inline-flex; align-items: center; justify-content: center; gap: 4px;
  min-width: 34px; height: 30px;
  padding: 0 8px;
  border: 0; border-radius: 15px;
  background: rgba(0, 0, 0, 0.55);
  color: #fff; font-size: 13px; font-variant-numeric: tabular-nums;
  cursor: pointer;
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
}
.gtile .like { position: absolute; right: 4px; bottom: 4px; z-index: 1; }
.like .heart { font-size: 14px; line-height: 1; transition: transform 0.15s ease; }
.like.on .heart { transform: scale(1.15); }
.like:disabled { opacity: 0.45; cursor: default; }
.like:focus-visible { outline: 2px solid var(--accent, #2a78d6); outline-offset: 2px; }
.like.big { height: 38px; min-width: 52px; font-size: 15px; padding: 0 14px; }
.like.big .heart { font-size: 18px; }
@media (prefers-reduced-motion: reduce) {
  .like .heart { transition: none; }
}

/* ---- board ranking ---- */
.medal { font-size: 15px; margin-left: auto; }
.board-user.leader { box-shadow: inset 3px 0 0 var(--accent, #2a78d6); }

.panel-photo {
  width: 100%; max-height: 220px; object-fit: cover;
  border-radius: 8px; margin-top: 8px; background: var(--cell-off);
}
.cell .fun-dot.photo { background: var(--surface); border: 2px solid var(--fun); }

.streaks { display: flex; flex-wrap: wrap; gap: 4px 10px; margin-bottom: 8px; }
.streaks .stats { font-size: 13px; color: var(--ink-2); white-space: nowrap; }
.streaks .stats.fun { color: var(--fun); }
.streaks .stats.photo { color: var(--fun); }

/* ---------- popover / panel ---------- */
.panel {
  border: 1px solid var(--accent);
  border-radius: 10px;
  padding: 12px;
  margin-top: 10px;
  background: var(--surface);
}
.panel .row { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; }

/* ---------- onboarding ---------- */
.onboard { text-align: center; padding-top: 8vh; }
.onboard .members { display: flex; flex-direction: column; gap: 8px; margin: 16px 0; }
.onboard .members .btn { text-align: left; }
.field { text-align: left; margin: 12px 0; }
.field label { display: block; font-size: 13px; color: var(--ink-2); margin-bottom: 4px; }

.splash { padding-top: 4vh; }
.splash h2 { font-size: 22px; text-transform: none; letter-spacing: 0; color: var(--ink); }
.splash > p { color: var(--ink-2); }
.splash-list { list-style: none; padding: 0; margin: 18px 0; text-align: left; }
.splash-list li { padding: 5px 0; font-size: 15px; }
.splash .btn.big { margin-top: 4px; }

/* ---------- tab bar ---------- */
nav.tabs {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  background: var(--surface);
  border-top: 1px solid var(--border);
  display: flex;
  padding-bottom: env(safe-area-inset-bottom);
}
nav.tabs button {
  flex: 1;
  background: none;
  border: none;
  padding: 10px 0 8px;
  color: var(--muted);
  font-size: 12px;
}
nav.tabs button .ico { display: block; font-size: 20px; }
nav.tabs button.on { color: var(--accent); font-weight: 600; }

/* ---------- toast ---------- */
#toast {
  position: fixed;
  bottom: 84px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--toast-bg);
  color: var(--toast-ink);
  padding: 10px 18px;
  border-radius: 999px;
  font-size: 14px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s;
  max-width: 90vw;
  text-align: center;
  z-index: 10;
}
#toast.show { opacity: 1; }

/* ---------- idea pool list ---------- */
.pool { margin: 8px 0 0; padding: 0; list-style: none; }
.pool li { padding: 6px 0; border-bottom: 1px solid var(--hair); font-size: 14px; }
.pool li:last-child { border-bottom: none; }

@media (max-width: 380px) {
  .grid30 { gap: 3px; }
  main { padding: 12px; }
}

/* ---- progress ---- */
.card.lead .big { font-size: 17px; line-height: 1.5; margin: 6px 0 4px; }
.card .big { font-size: 16px; margin: 6px 0 4px; }
.months { display: flex; flex-direction: column; gap: 7px; }
/* Name, bar, number. The bar is the only flexible column so the two text
   columns stay aligned down the list however long a month name is. */
.mrow {
  display: grid; grid-template-columns: 8.5em 1fr auto;
  align-items: center; gap: 10px; font-size: 13px;
}
.mname { color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mbar {
  height: 8px; border-radius: 99px; background: rgba(127,127,127,0.18);
  overflow: hidden;
}
.mbar i { display: block; height: 100%; background: var(--good, #0ca30c); border-radius: 99px; }
.mnum { color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ---- month pager ---- */
.monthnav {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 4px 0 10px; font-size: 15px;
}
.monthnav button[disabled] { opacity: 0.3; pointer-events: none; }
.card.quiet { background: none; border-style: dashed; }
/* an inline "show the quiet ones" that reads as text, not a button */
.linkish {
  background: none; border: 0; padding: 0; font: inherit;
  color: var(--accent); text-decoration: underline; cursor: pointer;
}

/* The thread styles are written for the dark lightbox; inside a card it needs
   the page's own colours instead. */
.thread-inline .thread {
  max-height: none; width: 100%;
  background: var(--page); border-color: var(--border); color: var(--ink);
}
.thread-inline .thread .muted { color: var(--muted); }
.thread-inline .cmt-x { color: var(--muted); }
.thread-inline .cmt-x:hover { background: var(--border); color: var(--ink); }
.thread-inline .cmt-add input {
  background: var(--surface); color: var(--ink); border-color: var(--border);
}
.thread-inline .cmt-add input::placeholder { color: var(--muted); }

/* Comment badge on a gallery tile. Top-left, opposite the like button in the
   bottom-right, so the two never collide on a ~104px tile. */
.gcmt {
  position: absolute; top: 4px; left: 4px;
  font-size: 11px; line-height: 1; font-variant-numeric: tabular-nums;
  padding: 3px 5px; border-radius: 99px;
  background: rgba(0,0,0,0.6); color: #fff;
  backdrop-filter: blur(2px);
}
/* A day with comments on it. Ringed rather than recoloured, so it reads as
   "there is more here" without competing with the fun and photo states. */
.cell .fun-dot.talked { box-shadow: 0 0 0 2px var(--accent); }
