/* ═══════════════════════════════════════════════════════════════════════════
   SOCIAL: social.css
   Shared by leaderboard.html and feed.html. Loaded after shared.css (tokens)
   and app.css (header, toast, page ground).

   WHY ONE FILE FOR TWO PAGES
   They are the same object seen twice. A leaderboard is people ordered by a
   number; a feed is people ordered by a time. Both are a vertical list of
   rows, each row a person, an avatar, a line of text and a figure on the
   right, so they get one row component rather than two that drift.

   The one rule that shapes everything below: a row must be readable at a
   glance, in a dark pub, held at arm's length. That means the person's name is
   the largest thing in the row, the number is tabular so the column lines up,
   and nothing is a colour that has to be decoded.
   ═══════════════════════════════════════════════════════════════════════════ */

body.social-page {
  padding: calc(var(--header-h) + 8px) 0 calc(var(--tabbar-h) + 28px);
}

.so-main {
  max-width: 620px;
  margin: 0 auto;
  padding: 0 14px;
}

/* ── SEGMENTED CONTROL ──────────────────────────────────────────────────────
   Friends / Ireland, and Town / Ireland. Two options, always, because a third
   would make it a menu and this has to be answerable without reading. */

.so-seg {
  display: flex;
  gap: 4px;
  padding: 4px;
  margin: 12px 0 4px;
  border-radius: 12px;
  background: var(--panel-2);
  border: 1px solid var(--border);
}
.so-seg-btn {
  flex: 1;
  min-height: 40px;
  padding: 9px 12px;
  border: none;
  border-radius: 9px;
  background: none;
  color: var(--text-3);
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  transition: background var(--dur, .18s) ease, color var(--dur, .18s) ease;
}
.so-seg-btn:hover { color: var(--text-2); }
.so-seg-btn[aria-selected="true"] {
  background: var(--panel);
  color: var(--text);
  box-shadow: var(--shadow-1);
}
.so-seg-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* ── SCOPE BAR ──────────────────────────────────────────────────────────── */

.so-scope {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 2px 8px;
}
.so-scope-title {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 700;
  color: var(--text);
  margin: 0;
  overflow-wrap: anywhere;
}
.so-scope-sub { font-size: 13px; color: var(--text-3); margin: 2px 0 0; }
.so-scope-pick {
  flex: none;
  padding: 8px 12px;
  border-radius: 10px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  color: var(--text-2);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  max-width: 45%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.so-scope-pick:hover { border-color: var(--accent); color: var(--text); }

/* ── THE ROW ────────────────────────────────────────────────────────────── */

.so-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.so-list[hidden] { display: none; }

.so-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-radius: 14px;
  background: var(--panel);
  border: 1px solid var(--border);
  text-decoration: none;
  color: inherit;
  transition: background var(--dur, .18s) ease, border-color var(--dur, .18s) ease;
}
a.so-row:hover { background: var(--hover); border-color: var(--border-strong); }
a.so-row:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* The row for the person reading it. Marked rather than moved: a leaderboard
   that reorders itself so you are always in the middle is not a leaderboard. */
.so-row.is-you {
  border-color: var(--accent);
  background: var(--brand-ghost);
}
.so-row.is-you .so-row-name::after {
  content: ' · you';
  color: var(--accent);
  font-weight: 600;
}

.so-rank {
  flex: none;
  width: 30px;
  text-align: center;
  font-family: var(--font-num);
  font-size: 17px;
  font-weight: 700;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}
/* The top three get their medal instead of their number. The medal says
   this is a place rather than a count; the metal says which place. One
   without the other is either three identical marks or a colour nobody
   can read without a legend. */
.so-rank-medal { font-size: 20px; line-height: 1; }
.so-rank-medal.is-gold   { color: var(--brass-400); }
.so-rank-medal.is-silver { color: var(--text-3); }
.so-rank-medal.is-bronze { color: var(--brass-600); }

.so-avatar {
  flex: none;
  width: 40px; height: 40px;
  border-radius: 50%;
  background: var(--panel-2);
  border: 1px solid var(--border-strong);
  display: flex; align-items: center; justify-content: center;
  font-size: 14px; font-weight: 700;
  color: var(--text-3);
  overflow: hidden;
}
.so-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ── display:block, and why every one of these needs it ──────────────────
   These are <span>s, and the two boxes above them (.so-row-body, .so-row-val)
   are flex items, which the browser blockifies for us. Their children it does
   not: a span stays inline unless told otherwise.

   Two things break as a result, and the second is the one that shows.

   The name and the sub sit on ONE line, "Aoife Mullen @aoifemullen", because
   inline boxes flow. And `text-overflow: ellipsis` has no effect at all on an
   inline box: it needs a block container to clip against. So instead of
   ellipsising at the edge of the row, the name simply ran out of it, which on
   a phone is a name printed over the number beside it.

   The pair on the right had it worse: "41" and "pubs" rendered as "41pubs".

   The nowrap and the ellipsis were always right. They were being written on
   elements that could not use them. */
.so-row-body { flex: 1; min-width: 0; }
.so-row-name {
  display: block;
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.so-row-sub {
  display: block;
  font-size: 13px;
  color: var(--text-3);
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.so-row-val {
  flex: none;
  text-align: right;
  /* A ceiling, so the figure can never take so much of a 320px row that the
     name is left with nothing to ellipsise into. */
  max-width: 34%;
}
.so-row-num {
  display: block;
  font-family: var(--font-num);
  font-size: 20px;
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.so-row-unit {
  display: block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .6px;
  text-transform: uppercase;
  color: var(--text-3);
  white-space: nowrap;
}

/* The dividing line above "you", when you are not in the visible top. Says
   "there is a gap here" without inventing the rows that fill it. */
.so-gap {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 14px;
  color: var(--text-3);
  font-size: 12px;
  letter-spacing: 2px;
}
.so-gap::before, .so-gap::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--border);
}

/* ── THE FEED ROW ───────────────────────────────────────────────────────── */

/* A feed row is the same object with a verb in it, so it shares .so-row and
   changes only what sits in the rank column. */
.so-kind {
  flex: none;
  width: 30px;
  text-align: center;
  font-size: 18px;
  line-height: 1;
}
/* Same reason as .so-row-num above: these are spans stacked in .so-row-val,
   and without display:block a priced row read "€5.4020 min". */
.so-when {
  display: block;
  font-size: 12px;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* A price in a feed row is the product's own data, so it wears the price ink
   rather than the neutral one. */
.so-price {
  display: block;
  font-family: var(--font-num);
  font-size: 18px;
  font-weight: 700;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
}

/* A followed pub with no price on record yet. An em dash rather than €0.00,
   because nought is a claim and this is an absence. */
.so-row-num-quiet { color: var(--text-3); font-weight: 600; }

/* The movement chip sits in the row's sub-line, so it steps down to that
   line's size rather than competing with the pub's name above it. The chip
   itself is defined once, in index.css, beside the price hero it was drawn
   for, this only says how big it is here. */
.so-row-sub .price-move { font-size: 11.5px; padding: 2px 6px; vertical-align: -1px; }
.so-row-sub .price-move .ic { font-size: 12px; }

/* A day heading. The feed is read as "today, then yesterday", not as a
   continuous stream, so it is grouped that way. */
.so-day {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--text-3);
  margin: 20px 2px 8px;
}
.so-day:first-child { margin-top: 8px; }

/* ── EMPTY, LOADING, END ────────────────────────────────────────────────── */

.so-empty {
  text-align: center;
  padding: 42px 22px;
  background: var(--panel);
  border: 1px dashed var(--border-strong);
  border-radius: 16px;
  margin-top: 8px;
}
.so-empty[hidden] { display: none; }
.so-empty-glyph { font-size: 40px; line-height: 1; opacity: .5; }
.so-empty-title {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 700;
  color: var(--text);
  margin: 12px 0 6px;
}
.so-empty-text {
  font-size: 14px;
  line-height: 1.5;
  color: var(--text-3);
  margin: 0 auto 18px;
  max-width: 34ch;
}
.so-empty .so-btn { max-width: 300px; margin: 0 auto; }

.so-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  padding: 12px 18px;
  border-radius: 12px;
  border: 1px solid var(--accent);
  background: var(--accent-solid);
  color: var(--on-accent);
  font-family: var(--font-sans);
  font-size: 15px;
  font-weight: 700;
  text-decoration: none;
  cursor: pointer;
}
.so-btn[hidden] { display: none; }
.so-btn:hover { background: var(--brand-500); }
.so-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.so-btn-ghost {
  background: transparent;
  color: var(--text-2);
  border-color: var(--border-strong);
}
.so-btn-ghost:hover { color: var(--text); border-color: var(--accent); background: transparent; }

.so-more {
  width: 100%;
  margin-top: 12px;
  padding: 11px;
  border-radius: 12px;
  background: none;
  border: 1px dashed var(--border-strong);
  color: var(--text-3);
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}
.so-more[hidden] { display: none; }
.so-more:hover { color: var(--text); border-color: var(--accent); }

.so-skel { display: flex; flex-direction: column; gap: 8px; padding-top: 8px; }
.so-skel[hidden] { display: none; }
.so-skel-row { height: 66px; border-radius: 14px; }

/* ── TOWN PICKER ────────────────────────────────────────────────────────── */

.so-picker[hidden] { display: none; }
.so-picker {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal, 900);
  background: rgba(0,0,0,.6);
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
@supports (backdrop-filter: blur(1px)) {
  .so-picker { -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); }
}
.so-picker-card {
  width: 100%;
  max-width: 520px;
  max-height: 78dvh;
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 18px 18px 0 0;
  padding: 16px 16px calc(16px + env(safe-area-inset-bottom));
}
@media (min-width: 560px) {
  .so-picker { align-items: center; }
  .so-picker-card { border-radius: 18px; }
}
.so-picker-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}
.so-picker-title {
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 700;
  color: var(--text);
  margin: 0;
}
.so-picker-close {
  background: none;
  border: none;
  color: var(--text-3);
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  padding: 4px 8px;
}
.so-picker-close:hover { color: var(--text); }
.so-picker-search {
  width: 100%;
  padding: 11px 14px;
  margin-bottom: 10px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--panel-2);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 15px;
  box-sizing: border-box;
}
.so-picker-search:focus { outline: none; border-color: var(--accent); }
.so-picker-list {
  list-style: none;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.so-picker-opt {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  padding: 11px 14px;
  border-radius: 10px;
  background: var(--panel-2);
  border: 1px solid transparent;
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 15px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}
.so-picker-opt:hover { border-color: var(--accent); }
.so-picker-opt-count { color: var(--text-3); font-size: 13px; font-weight: 500; }

/* ── CHEERS ───────────────────────────────────────────────────────────────
   The reaction on a feed row (migration 029).

   .so-item exists because .so-row is an <a> and the button cannot go inside
   it: a <button> nested in an anchor is invalid, and browsers resolve it by
   guessing, usually by following the link on the way to the button. They are
   siblings, and the wrapper is what keeps them on one line so the feed does
   not double in height for a control most rows will not have pressed. */
.so-item {
  display: flex;
  align-items: stretch;
  gap: 8px;
}
.so-item > .so-row { flex: 1; min-width: 0; }

.so-cheer {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  /* 48px, not the 44 floor. This sits beside a full-width link that is very
     easy to hit by accident on the way past, and the cost of a mis-tap here is
     a notification sent to somebody else. */
  min-width: 48px;
  padding: 6px 8px;
  border-radius: 14px;
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--text-3);
  font-family: var(--font-sans);
  cursor: pointer;
  transition: background var(--dur, .18s) ease,
              border-color var(--dur, .18s) ease,
              transform var(--dur, .18s) ease;
}
.so-cheer:hover { background: var(--hover); border-color: var(--border-strong); }
.so-cheer:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.so-cheer:active { transform: scale(.94); }

.so-cheer-ico {
  font-size: 17px;
  line-height: 1;
  /* Unpressed it is a suggestion, not a state. Greyed rather than faded to
     near-nothing, so it still reads as a thing you can press. */
  filter: grayscale(1);
  opacity: .6;
}
.so-cheer-n {
  /* The face comes from the one numbers rule in shared.css, which every
     figure in this app goes through. */
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  min-height: 11px;      /* holds its line when the count is empty */
}

.so-cheer.is-mine {
  background: var(--brand-ghost);
  border-color: var(--accent);
  color: var(--accent);
}
.so-cheer.is-mine .so-cheer-ico { filter: none; opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .so-cheer { transition: none; }
  .so-cheer:active { transform: none; }
}
