/* The reactions sheet — ticket 09.
 *
 * Ground truth is brief/IMG_2632.PNG, and the whole component is accent-free
 * (map decision 75), so geometry AND palette come straight off that still with
 * no translation — nothing here changes between the themed and default looks.
 *
 * The still is a 667-tall screen and we own 647 (decision 66). The card keeps
 * its MEASURED HEIGHT and pins 8 above OUR bottom, exactly as the composer
 * pins to 647 rather than 667. Decision 67's one-line hand-edit moves both.
 *
 * A/B — and NOT with ?x2. Ticket 09 found ?x2's CSS scale(2) snaps a box's
 * origin to a whole CSS px, which put this card's 325.5 top edge on 326 and the
 * close glyph half a pixel right. Grab at a true DPR 2 instead; the stage then
 * sits at x 187.5 in a 750-wide viewport, so subtract that when you scan. This
 * is the same class of ?x2 lie as decision 104's unpainted textarea.
 *
 *   python3 app/serve.py
 *   'Google Chrome' --headless --force-device-scale-factor=2 \
 *      --window-size=750,1334 --screenshot=out.png \
 *      'http://localhost:8850/?config=dev/sheet-cal.txt&scene=sh&sheet=last&stage=667'
 *   python3 .scratch/messenger-prop/reference/scan.py out.png --rect X0 X1 Y0 Y1
 */

.sheet-layer {
  position: absolute;
  inset: 0;
  z-index: 60; /* over the thread and the composer, under .fatal and .overlay */
  visibility: hidden;
  pointer-events: none;
}
.sheet-layer.is-open {
  visibility: visible;
  pointer-events: auto;
}

/* Exactly 40% black, solved from the still rather than eyeballed (decision 34).
 * It covers the whole stage, status-bar strip included — which is right: the
 * still shows Messenger's own header dimmed with iOS's glyphs undimmed on top,
 * because iOS draws those and we cannot reach them. */
.sheet-scrim {
  position: absolute;
  inset: 0;
  background: var(--c-scrim);
  opacity: 0;
  transition: opacity var(--sheet-fall-ms) linear;
}
.sheet-layer.is-open .sheet-scrim {
  opacity: 1;
  transition-duration: var(--sheet-rise-ms);
}

/* A floating card, inset on three sides — not a flush-bottom sheet, and with no
 * drag handle. 18 flagged that Messenger evidently ships both treatments and
 * asked for this to be confirmed by overlay rather than taken on trust; it
 * overlays at 8/8/8 and there is no handle anywhere in the card. */
.sheet {
  position: absolute;
  left: var(--sheet-inset);
  right: var(--sheet-inset);
  /* Positioned by BOTH edges rather than bottom + height: the card's top lands
   * on a half pixel (325.5 of a 667 screen, 305.5 of our 647) and a box sized
   * by `height` gets that half rounded away. */
  top: calc(var(--stage-h) - var(--sheet-inset) - var(--sheet-h));
  bottom: var(--sheet-inset);
  border-radius: var(--sheet-radius);
  background: var(--c-thread-bg);
  transform: translateY(calc(var(--sheet-h) + var(--sheet-inset)));
  transition: transform var(--sheet-fall-ms) var(--sheet-ease);
}
/* `none`, not `translateY(0)`: a transformed box gets its own layer and Chrome
 * snaps that layer's origin to a whole CSS px, which put the card's 325.5 top
 * edge on 326 in the A/B. At rest the card must be an ordinary box. */
.sheet-layer.is-open .sheet {
  transform: none;
  transition-duration: var(--sheet-rise-ms);
}

/* ------------------------------------------------------------------- head */

/* The title's ink centre and the close circle's centre are the same line —
 * card top + 26 — which is what fixes both without fitting them separately. */
.sheet-title {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(var(--sheet-head-cy) - 10px); /* half of the 20 line box */
  font: var(--t-sheet-title);
  color: var(--c-text);
  text-align: center;
}

.sheet-close {
  position: absolute;
  top: var(--sheet-close-inset);
  right: var(--sheet-close-inset);
  width: var(--sheet-close);
  height: var(--sheet-close);
  border-radius: 50%;
  background: var(--c-sheet-close);
  color: var(--c-text);
  display: flex;
  align-items: center;
  justify-content: center;
}
/* The actor may go for the ✕ instead of the backdrop, on camera, one take.
 * 48 x 48 of target around a 28 circle. */
.sheet-close::after {
  content: '';
  position: absolute;
  inset: -10px;
}

/* -------------------------------------------------------------------- rows */

.sheet-rows {
  position: absolute;
  left: 0;
  right: 0;
  top: var(--sheet-row-top);
}

.sheet-row {
  height: var(--sheet-row-h);
  display: flex;
  align-items: center;
  padding-left: var(--sheet-avatar-left);
  padding-right: var(--sheet-emoji-right);
}

.avatar--sheet {
  width: var(--avatar-sheet-row);
  height: var(--avatar-sheet-row);
}

.sheet-name {
  /* Ink lands 13 after the avatar — 77 on the stage, 69 into the card. */
  margin-left: calc(var(--sheet-name-left) - var(--sheet-avatar-left) - var(--avatar-sheet-row));
  font: var(--t-sheet-name);
  color: var(--c-text);
  white-space: nowrap;
}

.sheet-emoji {
  margin-left: auto;
  font-size: var(--sheet-row-emoji);
  line-height: 1;
}

/* ------------------------------------------------------------------- pills */

.sheet-pills {
  position: absolute;
  left: 0;
  right: 0;
  bottom: var(--sheet-pills-bottom);
  height: var(--pill-h);
  display: flex;
  justify-content: center;
  gap: var(--pill-gap);
}

.pill {
  height: var(--pill-h);
  border-radius: var(--pill-radius);
  padding: 0 var(--pill-pad-x);
  display: flex;
  align-items: center;
  font: var(--t-pill);
  color: var(--c-text);
}
/* Only the selected pill has a fill; the other is bare, which is why its box
 * could not be measured directly and the gap had to be fitted. */
.pill.is-selected {
  background: var(--c-surface-alt);
}

.pill--emoji {
  /* Asymmetric, and not a whim: the ALL pill's 58 box is measurable and the
   * bare one's is not, so this pill's padding is whatever makes the emoji ink
   * land on 203.5 and the count's on 229 while the centred row puts ALL back on
   * 129. Three measured landmarks, two unknowns. */
  padding-left: var(--pill-emoji-pad-l);
  padding-right: var(--pill-emoji-pad-r);
}

.pill-emoji {
  font-size: var(--pill-emoji);
  line-height: 1;
  margin-right: var(--pill-emoji-gap);
}
