:root{--ink:#0E0B09;--surface:#191411;--raised:#211A16;--line:#2E2620;--text:#F2EBE3;--muted:#A2968A;--accent:#C9A227;--keep:#6E9B72;--cut:#A85A4E}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
[hidden]{display:none!important}
html,body{margin:0;height:100%;background:var(--ink);color:var(--text);font:17px/1.4 -apple-system,system-ui,sans-serif}
#app{min-height:100%;display:flex;flex-direction:column;padding:max(16px,env(safe-area-inset-top)) 16px max(16px,env(safe-area-inset-bottom))}
h1{font-family:Georgia,serif;font-weight:600;font-size:28px;margin:8px 0 4px}h2{font-size:15px;letter-spacing:.12em;text-transform:uppercase;color:var(--accent);margin:16px 0 8px}
p.muted{color:var(--muted);margin:0 0 12px}
.btn{display:block;width:100%;padding:18px;border:0;border-radius:14px;background:var(--accent);color:#1C1611;font-size:19px;font-weight:600;margin-top:12px}
.btn.ghost{background:transparent;border:1px solid var(--line);color:var(--text)}.btn:disabled{opacity:.45}
.grid{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.tile{background:var(--surface);border:1px solid var(--line);border-radius:14px;padding:14px;text-align:left;color:var(--text)}
.tile b{display:block;font-size:18px}.tile small{color:var(--muted)}.tile[aria-pressed=true]{outline:3px solid var(--accent)}
/* d36 — the couple's showcase: the tile IS that style's render of them, name over a scrim */
.tile.pic{position:relative;overflow:hidden;min-height:112px;display:flex;flex-direction:column;justify-content:flex-end}
.tile.pic img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.tile.pic::after{content:"";position:absolute;inset:0;background:linear-gradient(to top,rgba(14,11,9,.94),rgba(14,11,9,.5) 45%,rgba(14,11,9,.05))}
.tile.pic b,.tile.pic small{position:relative;z-index:1;text-shadow:0 1px 3px rgba(0,0,0,.85)}
.tile.pic small{color:var(--text);opacity:.85}
.showcase-strip{display:flex;gap:8px;overflow-x:auto;padding:2px 0 8px}
.showcase-strip img{flex:0 0 auto;width:64px;height:64px;object-fit:cover;border-radius:8px;border:1px solid var(--line)}
.confirm{border:1px solid var(--line);border-radius:14px;background:var(--surface);padding:14px;margin-top:12px}
.confirm p{margin:0 0 10px}
.stage{position:relative;width:100%;aspect-ratio:4/3;background:#000;border-radius:14px;overflow:hidden}
.stage img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;transition:opacity 1.2s ease}
.stage img.after{opacity:0}.stage.revealed img.after{opacity:1}
.chips{display:flex;flex-wrap:wrap;gap:8px;margin:10px 0}.chip{padding:12px 16px;border-radius:999px;border:1px solid var(--line);background:var(--raised);color:var(--text);font-size:16px}
.chip.crazy{border-color:var(--accent)}
/* a locked tile or chip must read as locked, not merely dim — .chip.crazy is overridden here on purpose */
.tile:disabled,.chip:disabled{opacity:.4;border-color:var(--line)}
.thumbs{display:flex;gap:8px;overflow-x:auto;padding:6px 0}.thumbs img{flex:0 0 auto;width:88px;height:66px;object-fit:cover;border-radius:8px;border:2px solid transparent}.thumbs img[aria-selected=true]{border-color:var(--accent)}
.thumbs .pending{flex:0 0 auto;width:88px;height:66px;border-radius:8px;border:2px solid var(--line);display:grid;place-items:center;color:var(--muted);font-size:20px}
.thumbs .pending .spin{width:22px;height:22px;border-width:3px;margin:0}.thumbs .pending.failed{border-color:var(--cut)}
.field{display:flex;flex-direction:column;gap:6px;margin:10px 0}.field input{font-size:20px;padding:14px;border-radius:12px;border:1px solid var(--line);background:var(--surface);color:var(--text)}
.toggle{display:flex;align-items:center;gap:12px;padding:12px;border:1px solid var(--line);border-radius:12px}.toggle input{width:28px;height:28px}
.spin{width:44px;height:44px;border:4px solid var(--line);border-top-color:var(--accent);border-radius:50%;animation:s 1s linear infinite;margin:24px auto}@keyframes s{to{transform:rotate(360deg)}}
.err{background:#3a1f1a;border:1px solid var(--cut);padding:12px;border-radius:12px;margin:10px 0}
.sheet{display:grid;gap:4px;background:#0E0B09;padding:4px;border-radius:8px;aspect-ratio:3/2}
.sheet img{width:100%;height:100%;object-fit:cover;background:#222}
/* d37 — the render lands without taking the screen: a corner pop and a small burst, never a takeover */
.field label{font-size:15px;color:var(--muted)}
section.ready{padding-bottom:132px}          /* the buttons never end up under the pop */
.ready-pop{position:fixed;z-index:4;right:max(14px,env(safe-area-inset-right));bottom:max(14px,env(safe-area-inset-bottom));width:96px;padding:0;border:2px solid var(--accent);border-radius:14px;background:var(--raised);color:var(--accent);overflow:hidden;box-shadow:0 10px 28px rgba(0,0,0,.55);animation:pop .45s cubic-bezier(.2,1.5,.4,1) both}
.ready-pop img{display:block;width:100%;height:72px;object-fit:cover}
.ready-pop .cap{display:block;padding:7px 4px;font-size:13px;font-weight:600;letter-spacing:.08em;text-transform:uppercase}
@keyframes pop{from{transform:scale(.35) translate(18px,26px);opacity:0}to{transform:none;opacity:1}}
canvas.confetti{position:fixed;inset:0;width:100%;height:100%;pointer-events:none;z-index:6}
/* A phone is 390x664 in a Safari tab, not 390x844, and 360x640 on a small Android. At those heights a
   bottom-right pop is one wrapped label away from covering the buttons — a margin that depends on how
   copy wraps is luck, not layout. So it moves to the TOP right and is positioned inside the section
   rather than the viewport: the top of #app's content is the same place in the booth and in the demo
   (whose toolbar sits above it), so no host needs its own rule. The heading and the helper line reserve
   the pop's column so nothing is ever under it.
   `short` is set by screens.mjs from the MEASURED height, not by a media query: iOS Safari evaluates
   media queries against the large viewport (the one without the URL bar), so a phone showing 664 px
   still matches a 745 px rule. `top` is a plain 14 px — #app's padding already carries the safe area,
   and adding env() again drops the pop into the first field on a notched phone. */
#app.short section.ready{position:relative;padding-bottom:24px}
#app.short section.ready h2,#app.short section.ready p.muted{padding-right:100px}   /* the pop's 76 px + 24 */
/* …and the heading block is kept at least as tall as the pop, so what follows can never rise into it
   however the copy wraps — in landscape the helper line is one line and the first label came up to
   meet it. Structure, not arithmetic on how a sentence happens to fold. */
#app.short section.ready p.muted{min-height:60px}
#app.short .ready-pop{position:absolute;top:14px;right:0;bottom:auto;width:76px;animation-name:pop-top}
#app.short .ready-pop img{height:56px}
#app.short .ready-pop .cap{padding:5px 3px;font-size:12px}
@keyframes pop-top{from{transform:scale(.35) translate(18px,-26px);opacity:0}to{transform:none;opacity:1}}
/* both selectors, so this still outranks #app.short's animation-name */
@media (prefers-reduced-motion:reduce){.ready-pop,#app.short .ready-pop{animation:none}}   /* the spinner keeps spinning: it is progress, not decoration */
/* iPad and up: one readable column, three style tiles across, a bigger pop that stays with the column */
@media (min-width:700px){
  #app{max-width:640px;margin:0 auto;padding-left:24px;padding-right:24px}
  .grid{grid-template-columns:1fr 1fr 1fr}
  .thumbs img,.thumbs .pending{width:112px;height:84px}
  section.ready{padding-bottom:184px}
  .ready-pop{width:140px;right:max(20px,calc(50vw - 320px + 20px))}
  .ready-pop img{height:105px}
}
/* A phone on its side is both wide and short. It needs no rule of its own: every `#app.short` selector
   above outranks the block's plain `.ready-pop` ones, so it keeps the 76 px top-right pop, anchored to
   the column's own edge (`right:0` is inside the section, not the viewport). The stub measures 844x390. */
