/* THE HEART in the album viewer, 2026-08-18. (The birthday line that shared
   this file was removed the same day on Daniel's order — no public birthday
   strip; a birthday-celebrations feature comes later, on his design.)
 *
 * WHY THEY ARE IN THEIR OWN FILE rather than appended to styles.css or
 * albums.css. Both of those sheets are shared: styles.css is on all fourteen
 * youth pages and albums.css on five, including the church-photos pages this
 * change is not allowed to touch. A versioned asset here is cached for a year,
 * so adding rules to a shared sheet without bumping ?v= on EVERY page that
 * loads it ships a feature that half the returning phones never see — and the
 * bump cannot be made on the pages that are off limits. A new file has a new
 * URL, so it has no cache to beat, and nav-swap's ensureStyles() appends it
 * when a visitor swaps into a page that wants it.
 *
 *   THE HEART — the Download pill's smaller sibling in the same viewer bar:
 *   outline while it is nobody's, brass and filled once it is yours. The number
 *   beside it is a count and never a name.
 */

/* ══ THE HEART ═══════════════════════════════════════════════════════════════
   Inside .shotbox-bar, immediately before the Download pill. The bar is a
   wrapping flex row: at 390px the date takes its own line and the counter, this
   pill and Download share the one below.

   The whole control is one of two things and never both — a BUTTON for a
   signed-in member, and a flat TALLY for everybody else. A visitor who cannot
   heart a photograph is not shown something that looks like they can. */

.shotbox-hearts {
  display: inline-flex;
  align-items: center;
  flex: none;
}
.shotbox-hearts[hidden] { display: none; }

/* ── the member's control ────────────────────────────────────────────────── */
.heart-btn {
  /* Same pill grammar as .shotbox-full one step quieter: it is a reaction, not
     the thing that saves a photograph to somebody's camera roll. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: 44px;           /* Apple HIG / WCAG AAA, never gated on pointer */
  min-width: 44px;
  padding: 0 15px;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: rgba(255, 255, 255, 0.78);
  background: var(--control-bg-dark);
  border: 1px solid var(--control-line-dark);
  border-radius: var(--radius-pill);
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  touch-action: manipulation;
  transition: background var(--t-fast) var(--ease),
              border-color var(--t-fast) var(--ease),
              color var(--t-fast) var(--ease),
              transform var(--press-up) var(--ease-press);
}
.heart-btn[hidden] { display: none; }

/* ON. Two simultaneous changes, which is the house contract for an active
   state: the glyph fills with brass AND the pill takes a brass edge and wash. */
.heart-btn[aria-pressed="true"] {
  color: var(--accent-glow);
  background: rgba(236, 195, 92, 0.16);
  border-color: rgba(236, 195, 92, 0.6);
}

/* Press feedback is mandatory on this site and it is the same 110ms everywhere.
   A heart is aimed at, so it shrinks rather than lifts. */
.heart-btn:active {
  transition-duration: var(--press-down);
  transform: scale(0.94);
}
@media (hover: hover) {
  .heart-btn:hover {
    background: rgba(255, 255, 255, 0.16);
    border-color: rgba(255, 255, 255, 0.6);
    color: #fff;
  }
  .heart-btn[aria-pressed="true"]:hover {
    background: rgba(236, 195, 92, 0.24);
    border-color: rgba(236, 195, 92, 0.85);
    color: var(--accent-glow);
  }
}
.heart-btn:focus-visible {
  outline: 2px solid var(--accent-glow);
  outline-offset: 3px;
}
/* While the toggle is in flight the pill still answers a finger — it simply
   stops taking a second tap. Never below the 40% floor. */
.heart-btn[aria-busy="true"] { opacity: 0.55; }

/* ── everybody else's count ──────────────────────────────────────────────── */
/* Same size and rhythm as .shotbox-count beside it, because that is what it is:
   a number about this photograph, in the bar where the numbers live. No border,
   no fill, nothing that suggests a target. */
.heart-tally {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 44px;
  padding: 0 4px;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: rgba(255, 255, 255, 0.72);
}
.heart-tally[hidden] { display: none; }

/* ── the mark and the number ─────────────────────────────────────────────── */
.heart-mark {
  font-size: 14px;
  line-height: 1;
  /* The glyph is the only thing in this control that moves, and only when the
     member turns their own heart on. */
  transition: transform var(--t-fast) var(--ease);
}
.heart-btn[aria-pressed="true"] .heart-mark { transform: scale(1.12); }

/* Zero hearts prints no number at all — an empty count on every photograph in a
   573-shot camp is noise, and a bare outline heart already says "nobody yet".
   albums.js writes '' in that case; this keeps the gap from showing. */
.heart-n:empty { display: none; }

@media (prefers-reduced-motion: reduce) {
  .heart-btn:active { transform: none; }
  .heart-btn[aria-pressed="true"] .heart-mark { transform: none; }
}
