/*
 * The photo product only. Shared furniture — tokens, type, tabs, pills, the toast, the size
 * chips, the green pill — is in shell.css, which every page loads first.
 *
 * The one idea worth reading: the stage holds TWO pictures of the same crop. `#poster-img`
 * is the rendered poster, and `.live` is a plain <img> of the master positioned by the same
 * arithmetic the renderer uses. The live layer exists so a drag feels like dragging a
 * photograph instead of like waiting for a server; the rendered one is what is true, and it
 * comes back the moment the hand comes off.
 */
.photoposter {
  position: relative; overflow: hidden; background: var(--sheet-2);
  aspect-ratio: var(--poster-aspect, 5 / 7);
  box-shadow: 0 2px 4px rgba(42, 42, 40, .07), 0 22px 50px -24px rgba(42, 42, 40, .42);
  margin-inline: auto;
  /* the pointer is ours: no browser panning, no text selection running out of the poster */
  touch-action: none; user-select: none; -webkit-user-select: none;
}
@media (min-width: 900px) {
  .photoposter { width: min(100%, calc(74vh * var(--poster-wh, 0.714))); }
}
/*
 * An <img> is draggable by default, and that default beats us to the gesture: pressing and
 * moving starts the browser's own drag-and-drop, the cursor picks up a ghost of the
 * photograph, and our pointer capture is cancelled before the first pointermove lands. The
 * poster is a thing to drag WITHIN, not a thing to drag AWAY, so the native drag is off —
 * in CSS, in the `draggable` attribute, and on `dragstart`, because which of the three a
 * given browser honours has never been something to rely on.
 */
.photoposter img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: fill;
  -webkit-user-drag: none; user-drag: none;
}

/* the picture is grabbable, and says so before it is grabbed */
.photoposter[data-state="ready"], .photoposter[data-state="live"] { cursor: grab; }
.photoposter[data-state="live"] { cursor: grabbing; }

/* ── the live layer ──────────────────────────────────────────────────────── */
/* Placed in percentages of the poster, from the SAME geometry the print uses — so the hole
   you drag the picture through is the hole it prints through. */
.live { position: absolute; inset: 0; opacity: 0; pointer-events: none; background: var(--paper, #FBF3E4); }
.photoproduct[data-live="on"] .live { opacity: 1; }
.photoproduct[data-live="on"] #poster-img { opacity: 0; }

.live-window {
  position: absolute; overflow: hidden;
  left: var(--win-x, 0%); top: var(--win-y, 0%);
  width: var(--win-w, 100%); height: var(--win-h, 100%);
}
/* straightening turns the picture under a window that stays square to the paper */
.live-spin {
  position: absolute; inset: 0;
  transform: rotate(var(--straighten, 0deg));
  transform-origin: 50% 50%;
}
.live-spin img {
  /* The shell's `img { max-width: 100% }` reset would clamp this to the window's width
     while the height went on scaling — a zoomed picture squashed sideways in the live
     layer while the rendered poster beside it was correct. Zoomed past the frame is the
     whole point of this element, so both caps come off. */
  max-width: none; max-height: none;
  position: absolute; inset: auto; object-fit: fill;
  left: var(--img-x, 0%); top: var(--img-y, 0%);
  width: var(--img-w, 100%); height: var(--img-h, 100%);
}

/* ── nothing to print yet ────────────────────────────────────────────────── */
.drop {
  position: absolute; inset: 0; display: none; place-content: center; justify-items: center;
  gap: var(--s2); padding: var(--s6); text-align: center; cursor: pointer;
  background: var(--sheet-2); border: 2px dashed var(--rule); border-radius: 2px;
}
.photoposter[data-state="empty"] .drop { display: grid; }
.photoposter[data-state="over"] .drop { display: grid; border-color: var(--forest); background: var(--butter); }
.drop-mark { font-size: 34px; line-height: 1; color: var(--muted); font-weight: 300; }
.drop-lede { font-size: 17px; font-weight: 600; }
.drop-sub { font-size: 13px; color: var(--muted); max-width: 30ch; line-height: 1.45; }

/* ── under the poster, never on it ───────────────────────────────────────── */
.poster-busy {
  height: 3px; margin-top: 3px; border-radius: 2px; background: var(--tomato);
  transform-origin: left; animation: photobusy 900ms ease-in-out infinite;
}
@keyframes photobusy {
  0% { transform: scaleX(0); } 60% { transform: scaleX(1); } 100% { transform: scaleX(1); opacity: 0; }
}
.poster-error {
  margin: var(--s3) 0 0; padding: 10px 12px; font-size: 14px;
  background: var(--butter); color: var(--ink); border-radius: var(--r-chip);
}
.grab { margin: var(--s3) 0 0; font-size: 12px; color: var(--muted); text-align: center; }

/* ── the honesty badge ───────────────────────────────────────────────────── */
/* Sits in the controls, not on the picture: it is a fact about the print, and a fact that
   covers the thing it describes is not much use. */
.dpi {
  display: flex; align-items: center; gap: var(--s2);
  margin: 0 0 var(--s4); padding: 9px 13px; border-radius: var(--r-pill);
  font-size: 13px; line-height: 1.35; background: var(--sheet-2);
}
.dpi .dot { flex: 0 0 auto; width: 9px; height: 9px; border-radius: 50%; background: var(--muted); }
.dpi[data-grade="good"] { background: #E8F1E6; color: #2C4A2C; }
.dpi[data-grade="good"] .dot { background: var(--forest); }
.dpi[data-grade="soft"] { background: var(--butter); color: #6A4E12; }
.dpi[data-grade="soft"] .dot { background: #C9922B; }
.dpi[data-grade="poor"] { background: #F7E3DE; color: #7A2E1C; }
.dpi[data-grade="poor"] .dot { background: var(--tomato); }

/* ── the photo tab ───────────────────────────────────────────────────────── */
.ghostbtn.wide { display: block; width: 100%; padding: 12px 16px; }

.recents { display: grid; grid-template-columns: repeat(auto-fill, minmax(64px, 1fr)); gap: var(--s2); }
.recent {
  padding: 0; border: 2px solid transparent; border-radius: var(--r-chip);
  background: var(--sheet-2); cursor: pointer; overflow: hidden; aspect-ratio: 1;
}
.recent img { width: 100%; height: 100%; object-fit: cover; display: block; }
.recent[aria-pressed="true"] { border-color: var(--tomato); }
.recent:focus-visible { outline: 2px solid var(--tomato); outline-offset: 2px; }

.pillbtn {
  flex: 1; font: inherit; font-size: 13px; font-weight: 500; cursor: pointer;
  padding: 9px 8px; border: 0; border-radius: var(--r-pill);
  background: transparent; color: var(--muted); white-space: nowrap;
}
.pillbtn:hover { color: var(--ink); background: var(--sheet-2); }
.pillbtn[aria-pressed="true"] { background: var(--forest); color: var(--sheet); font-weight: 600; }
.pillbtn:focus-visible { outline: 2px solid var(--tomato); outline-offset: 2px; }

input[type="range"] { width: 100%; accent-color: var(--tomato); margin: var(--s1) 0 0; }

/* a size this photograph cannot carry is switched off, and the hint says which it can */
.size:has(input:disabled) { opacity: .45; cursor: not-allowed; }
.size:has(input:disabled) .size-price::after { content: ' · too small'; color: var(--tomato); }

.toggle { display: flex; align-items: center; gap: var(--s3); cursor: pointer; font-size: 15px; }
.toggle input { accent-color: var(--tomato); width: 18px; height: 18px; margin: 0; }

/* the little circled i, so a hint reads as guidance rather than as an error */
.note { display: flex; gap: var(--s2); align-items: flex-start; }
.i {
  flex: 0 0 auto; display: grid; place-items: center; width: 15px; height: 15px; margin-top: 2px;
  border: 1px solid currentColor; border-radius: 50%;
  font-size: 10px; font-weight: 700; font-style: italic; line-height: 1;
}
