/* Real 3D (WP8; core DESIGN §1, §3.7, §7.3): the grown-up's look before a cut-out leaves, and the portrait's ready glow.
   Forked from demo app.css L605-616 @7aafc93 (.review3d-pic on its checker, .r3-acts, "Trace it again", the narrow-phone
   stack). Changes: the retrace link sits in the sheet body; the batched look's grid of tiles is new (each the exact picture
   on the same checker, Keep or Send under it, a coral ring when marked Send) and its Keep / Send bar stays at the sheet's
   foot while the tiles scroll, so the safe choice is always in sight on a phone; the ready glow is new (D-34: a model that
   came and waits for its hatch; the --glow-ready token, a slow breath and a small sparkle; nothing is shown while a model is
   on its way, no progress and no spinner). Plain and adult in the sheet; reduced motion holds every animation still. */

/* The exact cut-out that would go, on a checker so what is see-through reads as see-through. */
.review3d-pic { margin: 8px 0 12px; padding: 12px; border-radius: 18px; display: grid; place-items: center;
  background: repeating-conic-gradient(var(--sand) 0 25%, var(--card) 0 50%) 0 0 / 24px 24px; }
.review3d-pic img { display: block; max-width: 100%; max-height: min(46dvh, 420px); width: auto; height: auto; }
.r3-acts { display: flex; gap: 12px; margin-top: 8px; }
.sheet .r3-acts > .btn { flex: 1 1 0; min-height: 52px; justify-content: center; margin: 0; white-space: nowrap; }
.sheet .r3-acts > .btn-primary { width: auto; min-height: 60px; font-size: var(--body); font-weight: 800; gap: 10px; padding: 0 18px; }
.sheet .r3-acts > .btn-primary .ico { width: 26px; height: 26px; }
/* "Trace it again": a quiet link above Keep / Send, which stay equal. */
.review3d .btn.link[data-retrace] { display: flex; margin: 0 auto 4px; }
@media (max-width: 479px) {
  .r3-acts { flex-direction: column-reverse; }
  .sheet .r3-acts > .btn { flex: none; }
  .review3d-pic img { max-height: min(34dvh, 420px); }
}

/* The batched look: Keep and Send stay at the sheet's foot while the tiles scroll under them (the sheet's own bottom padding
   moves into the bar, so the end of the scroll looks as before). */
.sheet.r3-look .r3-acts { position: sticky; z-index: 1; bottom: calc(-28px - env(safe-area-inset-bottom));
  margin: 8px -22px calc(-28px - env(safe-area-inset-bottom)); padding: 12px 22px calc(28px + env(safe-area-inset-bottom));
  background: var(--card); transition: box-shadow var(--t-micro); }
/* Its soft top edge only while tiles scroll under it (review3d.js sets data-under). */
.sheet.r3-look[data-under] .r3-acts { box-shadow: 0 -12px 14px -14px rgba(24, 22, 18, .4); }

/* The batched look: every waiting cut-out as a tile; a tap marks it Send (a coral ring) or back to Keep. */
.r3-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(148px, 1fr)); gap: 12px; margin: 12px 0 4px; }
.sheet .r3-tile { appearance: none; border: 0; margin: 0; font: inherit; color: var(--ink); cursor: pointer; touch-action: manipulation;
  user-select: none; -webkit-user-select: none; display: grid; grid-template-rows: auto auto; gap: 8px; padding: 8px; border-radius: 20px;
  background: var(--card); box-shadow: var(--shadow), inset 0 0 0 2px var(--hair); text-align: left;
  transition: transform var(--t-micro) var(--spring), box-shadow var(--t-micro); }
.sheet .r3-tile:active:not(:disabled) { transform: scale(.96); }
.sheet .r3-tile:disabled { cursor: default; }
.r3-tile .r3-pic { aspect-ratio: 1; border-radius: 14px; display: grid; place-items: center; overflow: hidden; padding: 8px;
  background: repeating-conic-gradient(var(--sand) 0 25%, var(--card) 0 50%) 0 0 / 18px 18px; }
.r3-tile .r3-pic img { display: block; max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; animation: r3-in var(--t-card) ease both; }
.r3-tile .r3-pic > .ico { width: 44px; height: 44px; color: var(--muted); }
.r3-tile .r3-choice { min-height: 44px; display: flex; align-items: center; padding: 0 4px; font-weight: 750; font-size: 15px; line-height: 1.25; }
.r3-tile .r3-c { display: none; align-items: center; gap: 8px; }
.r3-tile .r3-c .ico { width: 24px; height: 24px; flex: none; }
.r3-tile[data-state="wait"] .r3-c-keep, .r3-tile[data-state="ready"][aria-pressed="false"] .r3-c-keep { display: flex; }
.r3-tile[data-state="ready"][aria-pressed="true"] .r3-c-send, .r3-tile[data-state="sending"] .r3-c-send { display: flex; }
.r3-tile[data-state="sent"] .r3-c-sent, .r3-tile[data-state="refused"] .r3-c-why, .r3-tile[data-state="nocut"] .r3-c-why { display: flex; }
/* While its picture is being made: the checker breathes once a second (no ring, no spinner). */
.r3-tile[data-state="wait"] .r3-pic { animation: r3-wait 1.2s ease-in-out infinite alternate; }
.r3-tile[data-state="wait"] .r3-choice { opacity: .45; }
/* Marked Send: the coral ring, the label on a coral field. */
.sheet .r3-tile[aria-pressed="true"], .sheet .r3-tile[data-state="sending"] { box-shadow: var(--shadow-lift), inset 0 0 0 4px var(--coral); }
.r3-tile[aria-pressed="true"] .r3-choice, .r3-tile[data-state="sending"] .r3-choice { background: var(--coral-field); border-radius: 12px; }
.r3-tile[data-state="sending"] .r3-c-send .ico { animation: r3-up .9s ease-in-out infinite; }
/* Sent: a green ring and its word on a green field. Refused (it stays here): quiet, the picture faded. */
.sheet .r3-tile[data-state="sent"] { box-shadow: var(--shadow), inset 0 0 0 4px var(--green); }
.r3-tile[data-state="sent"] .r3-choice { color: var(--green); background: color-mix(in srgb, var(--green) 10%, var(--card)); border-radius: 12px; }
.r3-tile[data-state="refused"] .r3-pic img { opacity: .55; }
.r3-tile[data-state="refused"] .r3-choice, .r3-tile[data-state="nocut"] .r3-choice { color: var(--muted); font-weight: 650; }
/* Not a cut-out: greyed, a pictogram instead of the picture, never choosable. */
.r3-tile[data-state="nocut"] .r3-pic { background: var(--paper); }
.r3-tile[data-state="nocut"] .r3-pic::before { content: ''; width: 44px; height: 44px; border-radius: 12px; border: 3px dashed var(--line); opacity: .7; }
.r3-look .g-real3d:empty { display: none; }
@keyframes r3-in { from { opacity: 0; transform: scale(.94); } }
@keyframes r3-wait { to { opacity: .55; } }
@keyframes r3-up { 50% { transform: translateY(-3px); } }

/* The ready glow (D-34): on any portrait that carries .r3-glow (real3d.glow(member)); the hatch at the next seam ends it. */
.r3-glow { position: relative; box-shadow: var(--glow-ready), var(--shadow); animation: r3-breathe 1.8s ease-in-out infinite alternate; }
.r3-glow::after { content: ''; position: absolute; right: -6px; top: -6px; width: 22px; height: 22px; pointer-events: none;
  background: radial-gradient(circle, var(--card) 0 24%, var(--butter) 62%);
  clip-path: polygon(50% 0, 61% 39%, 100% 50%, 61% 61%, 50% 100%, 39% 61%, 0 50%, 39% 39%);
  filter: drop-shadow(0 0 1.5px rgba(120, 76, 8, .75)); animation: r3-twinkle 1.4s ease-in-out infinite alternate; }
@keyframes r3-breathe { to { box-shadow: 0 0 0 7px color-mix(in srgb, var(--signal) 32%, transparent), var(--shadow); } }
@keyframes r3-twinkle { from { opacity: .6; transform: scale(.75) rotate(-12deg); } }

@media (prefers-reduced-motion: reduce) {
  .r3-tile[data-state="wait"] .r3-pic, .r3-tile .r3-pic img, .r3-tile[data-state="sending"] .r3-c-send .ico, .r3-glow, .r3-glow::after { animation: none; }
  .sheet .r3-tile, .sheet.r3-look .r3-acts { transition: none; }
}
