/* Shutter — a camera whose chassis is a moulded plastic object and whose film is
   the 2010 Instagram filter set.

   Every length inside the phone is in `cqw` off a size-container (#device), so
   the framed desktop view and a real phone get ONE layout and nothing has to be
   measured twice. The exceptions are tap targets, which take a max(44px, …):
   the one measurement that must not scale is the one about a thumb.

   The whole surface is lit from ONE place — up and to the left — so every raised
   thing carries a light top edge, a shaded bottom edge, and a shadow that falls
   down and slightly right. Nothing here contradicts that. */

*, *::before, *::after { box-sizing: border-box; }

:root {
  color-scheme: light;
  --chassis:   #eeedeb;
  --chassis-2: #e6e5e2;
  --face-hi:   #fefefe;
  --face-lo:   #f2f1ef;
  --edge:      rgba(0,0,0,.145);
  --edge-soft: rgba(0,0,0,.09);
  --ink:       #4a4a4a;
  --dim:       #8f8e8b;
  --amber:     #efa33c;
  --amber-hi:  #f7c377;
  --amber-lo:  #dd851f;
  --amber-ink: #3d2a0d;
  --paper:     #ffffff;

  /* one light, declared once */
  --lift: inset 0 .18cqw 0 rgba(255,255,255,.9), inset 0 -.18cqw 0 rgba(0,0,0,.045);
  --drop: 0 .35cqw .8cqw rgba(0,0,0,.07), 0 1.4cqw 2.6cqw rgba(0,0,0,.055);
  --drop-lo: 0 .25cqw .55cqw rgba(0,0,0,.06), 0 .8cqw 1.6cqw rgba(0,0,0,.045);
}

html, body {
  margin: 0; height: 100%;
  background: #f0f0f0;
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior: none;
}
body { display: grid; place-items: center; }

/* ── the device ──────────────────────────────────────────────────────────── */

#device {
  position: relative;
  width: 100vw; height: 100dvh;
  container-type: size; container-name: app;
  overflow: hidden;
  background: linear-gradient(180deg, var(--chassis) 0%, var(--chassis) 46%, var(--chassis-2) 100%);
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  user-select: none; -webkit-user-select: none;
}

/* On a desk the app stands in a drawn iPhone 17 Pro. The frame is a CLASS, not a
   media query, because a query cannot promise never to fire on a real phone —
   app.js gates the class on `pointer: fine` and re-checks it when that changes. */
body.framed #device {
  width: min(402px, calc((100dvh - 40px) * 402 / 874));
  height: calc(min(402px, calc((100dvh - 40px) * 402 / 874)) * 874 / 402);
  border-radius: 13.4%/6.2%;
  /* a box-shadow SPREAD cannot be a percentage — written that way the whole
     bezel is dropped silently and the app floats on the desk with no phone */
  box-shadow:
    0 0 0 3px #17181a,
    0 0 0 6px #7c7e82,
    0 0 0 9px #303236,
    0 0 0 10px #17181a,
    0 8px 18px rgba(0,0,0,.24), 0 38px 76px rgba(0,0,0,.32);
}
body.framed { background: #dcdbd8; }
#island { display: none; }
body.framed #device #island {
  position: absolute; display: block;
  top: 1.55cqh; left: 50%; transform: translateX(-50%);
  width: 30cqw; height: 3.9cqh; border-radius: 99px; background: #101012; z-index: 90;
  pointer-events: none;
}

#stage {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  padding:
    calc(var(--safe-t, 0px) + 2.2cqh) 3.6cqw calc(var(--safe-b, 0px) + 2.6cqh);
}

/* ── top plate ───────────────────────────────────────────────────────────── */

.plate {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 1.4cqw 0 2cqw;
  height: 5.4cqh;
}
.mark {
  font-size: 3.1cqw; font-weight: 700; letter-spacing: .34em;
  color: #a3a29e; text-transform: uppercase;
}
.counter {
  display: flex; align-items: center; gap: 1.4cqw;
  font-size: 2.9cqw; font-weight: 600; letter-spacing: .18em; color: var(--dim);
  font-variant-numeric: tabular-nums;
}
.counter b { color: var(--ink); font-weight: 700; }
.led {
  width: 1.5cqw; height: 1.5cqw; border-radius: 50%; background: #cbcac6;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.12);
}
.led.on { background: var(--amber); box-shadow: 0 0 .9cqw rgba(239,163,60,.75); }

/* ── the film-box tab ─────────────────────────────────────────────────────
   Everything else on this body is a RAISED thing: lit along its top edge,
   shaded along its bottom, casting down. This one is a GROOVE cut into the
   chassis, so it is lit the other way round — shaded at the top inside, lit at
   the bottom — which is the only reason it reads as recessed rather than as a
   panel somebody forgot to raise. The height is fixed at three lines so that
   turning the dial cannot move the picture underneath it. */

.stock {
  flex: 0 0 auto;
  margin: 2.6cqh .6cqw 0;
  padding: 2.4cqw 3cqw 2.6cqw;
  border-radius: 3.2cqw;
  background: linear-gradient(180deg, #e6e5e2, #edecea);
  box-shadow:
    inset 0 .35cqw .7cqw rgba(0,0,0,.11),
    inset 0 -.2cqw 0 rgba(255,255,255,.8),
    0 1px 0 rgba(255,255,255,.85);
}
.stock-top {
  display: flex; align-items: baseline; justify-content: space-between; gap: 2cqw;
  margin-bottom: 1.2cqw;
}
.stock-top b {
  font-size: 3.4cqw; font-weight: 700; letter-spacing: .2em; text-transform: uppercase;
  color: #6d6b67;
}
.stock-top span {
  font-size: 2.5cqw; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  color: var(--amber-lo); white-space: nowrap;
}
.stock p {
  margin: 0; height: 11.4cqw;              /* three lines, fixed, so nothing moves */
  font-size: 2.75cqw; line-height: 1.38; color: #a29f9a;
  overflow: hidden;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;
}

/* ── viewfinder ──────────────────────────────────────────────────────────── */

.finder-wrap { flex: 1 1 auto; display: grid; align-items: end; justify-items: center; min-height: 0; }

/* The print: a white card with the square image in it and a chin under it, the
   way a Polaroid puts its chin under the picture. The chin is not decoration —
   it is where the frame counter and the retired-in-2012 mark live. */
.finder {
  /* width is written by fit(): the print is square, so on a short window the
     picture has to be sized by the HEIGHT that is left rather than by the width,
     or the card runs off the bottom of a landscape desktop. */
  width: 100%;
  padding: 2.2cqw 2.2cqw 0;
  border-radius: 5.4cqw;
  background: linear-gradient(170deg, #fff, #fbfaf9);
  box-shadow:
    0 0 0 1px rgba(0,0,0,.075),
    inset 0 .2cqw 0 rgba(255,255,255,.9),
    0 .5cqw 1.1cqw rgba(0,0,0,.06), 0 2.2cqw 4cqw rgba(0,0,0,.07);
}
.print {
  position: relative;
  aspect-ratio: 1;
  border-radius: 3.4cqw;
  overflow: hidden;
  background: #17181a;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.16);
}
#view { display: block; width: 100%; height: 100%; }

.grid3 {
  position: absolute; inset: 0; pointer-events: none; opacity: 0;
  transition: opacity .18s;
  background:
    linear-gradient(90deg, transparent calc(33.333% - .5px), rgba(255,255,255,.34) calc(33.333% - .5px) calc(33.333% + .5px), transparent calc(33.333% + .5px)),
    linear-gradient(90deg, transparent calc(66.666% - .5px), rgba(255,255,255,.34) calc(66.666% - .5px) calc(66.666% + .5px), transparent calc(66.666% + .5px)),
    linear-gradient(180deg, transparent calc(33.333% - .5px), rgba(255,255,255,.34) calc(33.333% - .5px) calc(33.333% + .5px), transparent calc(33.333% + .5px)),
    linear-gradient(180deg, transparent calc(66.666% - .5px), rgba(255,255,255,.34) calc(66.666% - .5px) calc(66.666% + .5px), transparent calc(66.666% + .5px));
}
body.grid-on .grid3 { opacity: 1; }

/* the focus square, drawn where you tapped */
.focus {
  position: absolute; width: 17cqw; height: 17cqw; margin: -8.5cqw 0 0 -8.5cqw;
  border: 1.5px solid #f5c451; border-radius: 1.6cqw;
  opacity: 0; pointer-events: none;
  box-shadow: 0 0 0 1px rgba(0,0,0,.25), inset 0 0 0 1px rgba(0,0,0,.2);
}
.focus.hit { animation: focusPop .9s ease-out; }
@keyframes focusPop {
  0%   { opacity: 0; transform: scale(1.5); }
  14%  { opacity: 1; transform: scale(1); }
  62%  { opacity: 1; }
  70%  { opacity: .45; }
  78%  { opacity: 1; }
  100% { opacity: 0; }
}

/* a glass circle in the corner of the picture — the one control that belongs to
   the lens rather than to the body */
.flip {
  position: absolute; right: 2.6cqw; bottom: 2.6cqw;
  width: clamp(44px, 10.4cqw, 62px); height: clamp(44px, 10.4cqw, 62px);
  display: grid; place-items: center;
  border: 0; border-radius: 50%; padding: 0; cursor: pointer;
  background: rgba(24,24,26,.42);
  backdrop-filter: blur(10px) saturate(1.3);
  -webkit-backdrop-filter: blur(10px) saturate(1.3);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.24);
  color: #fff;
  transition: transform .32s cubic-bezier(.3,1.4,.5,1);
}
.flip svg { width: 52%; height: 52%; }
.flip.turn { transform: rotate(180deg); }

/* the whole picture goes white for a beat when there is no torch to fire */
.blast { position: absolute; inset: 0; background: #fff; opacity: 0; pointer-events: none; }
.blast.fire { animation: blast .42s ease-out; }
@keyframes blast { 0% { opacity: 0 } 8% { opacity: .96 } 100% { opacity: 0 } }

/* the shutter closing over the picture */
.curtain { position: absolute; inset: 0; background: #101012; opacity: 0; pointer-events: none; }
.curtain.fire { animation: curtain .2s ease-in-out; }
@keyframes curtain { 0%,100% { opacity: 0 } 40%,60% { opacity: 1 } }

.chin {
  height: 6.6cqw; display: flex; align-items: center; justify-content: space-between;
  padding: 0 1.4cqw;
  font-size: 2.55cqw; font-weight: 600; letter-spacing: .2em; text-transform: uppercase;
  color: #b3b1ac; font-variant-numeric: tabular-nums;
}
.chin .retired { color: var(--amber-lo); }

/* what the app says when it has no camera, or when a control cannot do the
   thing it names. It is a state, not an error. */
.notice {
  /* at the TOP of the picture: at the bottom it lands on the flip button, which
     on a 320-wide phone is most of the corner it sits in */
  position: absolute; left: 3cqw; right: 3cqw; top: 3cqw;
  padding: 2cqw 2.6cqw; border-radius: 2.2cqw;
  background: rgba(16,16,18,.62);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  color: #f3f2f0; font-size: 2.75cqw; line-height: 1.4;
  opacity: 0; transform: translateY(-1cqw); transition: opacity .22s, transform .22s;
  pointer-events: none;
}
.notice.up { opacity: 1; transform: none; }

/* ── controls ────────────────────────────────────────────────────────────── */

.controls { flex: 0 0 auto; display: flex; flex-direction: column; gap: 5cqh; padding-top: 4.6cqh; }
.row { display: flex; align-items: center; justify-content: space-between; }
.row-1 { padding: 0 .6cqw; }
.row-2 { padding: 0 1.2cqw; }

/* a moulded key: white face, one lit top edge, one shaded bottom edge, a shadow
   below it, and a hairline so it has an edge against the chassis */
.key {
  position: relative; border: 0; padding: 0; cursor: pointer;
  background: linear-gradient(180deg, var(--face-hi), var(--face-lo));
  box-shadow: 0 0 0 1px var(--edge), var(--lift), var(--drop-lo);
  color: var(--ink);
  transition: transform .09s ease-out, box-shadow .12s;
}
.key:active { transform: translateY(.3cqw) scale(.985); box-shadow: 0 0 0 1px var(--edge), var(--lift), 0 .2cqw .4cqw rgba(0,0,0,.07); }

.circ {
  width: max(44px, 11.2cqw); height: max(44px, 11.2cqw);
  border-radius: 50%; display: grid; place-items: center;
}
.circ svg { width: 44%; height: 44%; }
.circ.lit { color: var(--amber-lo); }
.circ.lit svg { filter: drop-shadow(0 0 .6cqw rgba(239,163,60,.5)); }

/* the zoom bar: one pill cut into four by hairlines that run its full height */
.seg {
  display: flex; align-items: stretch;
  width: 55.6cqw; height: max(44px, 11.2cqw);
  border-radius: 99px; overflow: hidden;
  background: linear-gradient(180deg, var(--face-hi), var(--face-lo));
  box-shadow: 0 0 0 1px var(--edge), var(--lift), var(--drop-lo);
}
.seg button {
  flex: 1 1 0; min-width: 0; border: 0; background: none; cursor: pointer;
  font: inherit; font-size: 5cqw; font-weight: 500; letter-spacing: -.015em;
  color: var(--dim); padding: 0; white-space: nowrap;
  display: flex; align-items: center; justify-content: center;
  transition: color .14s;
}
.seg button + button { border-left: 1px solid var(--edge-soft); }
.seg button.on { color: var(--amber); font-weight: 700; }
.seg button[disabled] { color: #cfcecb; cursor: default; }
.seg button:active:not([disabled]) { background: rgba(0,0,0,.03); }

/* the last frame, in a paper mount */
.thumb {
  width: max(44px, 15.2cqw); height: max(44px, 15.2cqw);
  border-radius: 50%; border: 1.1cqw solid var(--paper); padding: 0; cursor: pointer;
  background: #ddd center/cover no-repeat;
  box-shadow: 0 0 0 1px rgba(0,0,0,.11), var(--drop-lo);
  transition: transform .12s;
}
.thumb:active { transform: scale(.94); }
.thumb.empty { background: repeating-linear-gradient(45deg, #e9e8e5 0 5px, #e3e2df 5px 10px); }
.thumb.load { animation: land .5s cubic-bezier(.2,1.5,.4,1); }
@keyframes land { 0% { transform: scale(1.9); } 100% { transform: scale(1); } }

/* the shutter — a white disc with a dark ring cut into it */
.shutter {
  position: relative;
  width: 24cqw; height: 24cqw; border-radius: 50%;
  border: 0; padding: 0; cursor: pointer;
  background: linear-gradient(180deg, #fff, #f3f2f0);
  box-shadow: 0 0 0 1px rgba(0,0,0,.10), var(--lift), var(--drop);
  transition: transform .08s ease-out;
}
.shutter::after {
  content: ''; position: absolute; inset: 5.6%;
  border-radius: 50%; border: 1cqw solid #2c2c2e;
}
.shutter:active { transform: scale(.955); }
.shutter[disabled] { opacity: .5; cursor: default; }

/* the film dial — the orange pill. Drag it to run through the filters, tap it to
   see all sixteen at once. Its label reads bottom-to-top, as a lens barrel does. */
.dial {
  position: relative;
  width: max(44px, 10.2cqw); height: 20.2cqw;
  border-radius: 99px; border: 0; padding: 0; cursor: grab;
  background: linear-gradient(152deg, var(--amber-hi) 0%, var(--amber) 42%, var(--amber-lo) 100%);
  box-shadow:
    0 0 0 1.1cqw var(--paper),
    0 0 0 calc(1.1cqw + 1px) rgba(0,0,0,.10),
    inset 0 .3cqw 0 rgba(255,255,255,.55),
    inset 0 -.3cqw .3cqw rgba(120,60,0,.22),
    var(--drop-lo);
  touch-action: none;
  overflow: hidden;
}
.dial:active { cursor: grabbing; }
.dial span {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  writing-mode: vertical-rl; transform: rotate(180deg);
  /* the size is written by fitDial(): 'Lord Kelvin' is eleven characters and at
     the natural size it runs off the end of the barrel, which reads as a broken
     label rather than as a long name */
  font-size: 3.15cqw; font-weight: 700; letter-spacing: .12em;
  color: var(--amber-ink); text-transform: uppercase;
  white-space: nowrap;
  text-shadow: 0 1px 0 rgba(255,255,255,.28);
}
/* the detent flash as a filter clicks past */
.dial.click::before {
  content: ''; position: absolute; inset: 0; background: rgba(255,255,255,.5);
  animation: det .16s ease-out;
}
@keyframes det { from { opacity: .8 } to { opacity: 0 } }

/* ── sheets ──────────────────────────────────────────────────────────────── */

.scrim {
  position: absolute; inset: 0; z-index: 50;
  background: rgba(28,28,30,.34);
  backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px);
  opacity: 0; transition: opacity .26s;
}
.scrim.up { opacity: 1; }
.scrim[hidden] { display: none !important; }

.sheet {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 60;
  max-height: 88cqh;
  display: flex; flex-direction: column;
  padding: 2.2cqw 3.6cqw calc(var(--safe-b, 0px) + 3.4cqh);
  border-radius: 7cqw 7cqw 0 0;
  background: linear-gradient(180deg, #f7f6f4, var(--chassis));
  box-shadow: 0 -1px 0 rgba(0,0,0,.09), 0 -2cqw 6cqw rgba(0,0,0,.16);
  transform: translateY(100%);
  transition: transform .34s cubic-bezier(.22,.9,.26,1);
}
.sheet.up { transform: none; }
.sheet[hidden] { display: none !important; }
.grip {
  width: 12cqw; height: 1.1cqw; border-radius: 99px; background: #cdccc8;
  margin: 0 auto 2.4cqw; flex: 0 0 auto;
}
.sheet h2 {
  margin: 0 0 2.6cqw; padding: 0 1cqw;
  font-size: 3.2cqw; font-weight: 700; letter-spacing: .22em; text-transform: uppercase;
  color: #9d9b97;
  display: flex; justify-content: space-between; align-items: baseline;
}
.sheet h2 em { font-style: normal; letter-spacing: .06em; color: #b9b7b2; text-transform: none; font-weight: 600; }
.sheet .body { overflow-y: auto; -webkit-overflow-scrolling: touch; min-height: 0; }

/* the sixteen, live */
.tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 2.4cqw; padding: 0 1cqw 1cqw; }
.tile { border: 0; padding: 0; background: none; cursor: pointer; display: block; text-align: center; }
.tile canvas {
  display: block; width: 100%; aspect-ratio: 1; border-radius: 2.6cqw;
  background: #ddd;
  box-shadow: 0 0 0 1px rgba(0,0,0,.10), 0 .3cqw .8cqw rgba(0,0,0,.07);
}
.tile b {
  display: block; margin-top: 1.3cqw;
  font-size: 2.4cqw; font-weight: 600; letter-spacing: .04em; color: var(--dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tile.on canvas { box-shadow: 0 0 0 .8cqw var(--amber), 0 0 0 calc(.8cqw + 1px) rgba(0,0,0,.12); }
.tile.on b { color: var(--amber-lo); font-weight: 700; }
.tile .dagger { color: var(--amber-lo); }
.note {
  margin: 2.4cqw 1cqw 0; padding: 2.6cqw 3cqw; border-radius: 3cqw;
  background: rgba(0,0,0,.035); box-shadow: inset 0 0 0 1px rgba(0,0,0,.05);
  font-size: 2.85cqw; line-height: 1.5; color: #75736f;
}
.note b { color: var(--amber-lo); }

/* the roll */
.roll { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.6cqw; padding: 0 1cqw 1cqw; }
.roll img {
  display: block; width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 2cqw;
  background: #e6e5e2; box-shadow: 0 0 0 1px rgba(0,0,0,.08); cursor: pointer;
}
.blank { padding: 9cqw 4cqw; text-align: center; color: #a5a39f; font-size: 3cqw; line-height: 1.6; }

/* settings */
.set { padding: 0 1cqw 1cqw; }
.item {
  display: flex; align-items: center; justify-content: space-between; gap: 3cqw;
  padding: 3cqw 3.4cqw; margin-bottom: 1.6cqw;
  border-radius: 3.4cqw;
  background: linear-gradient(180deg, #fff, #fbfaf9);
  box-shadow: 0 0 0 1px rgba(0,0,0,.07), var(--drop-lo);
}
.item .lab { min-width: 0; }
.item .lab b { display: block; font-size: 3.3cqw; font-weight: 600; color: #38383a; }
.item .lab i { display: block; font-style: normal; font-size: 2.7cqw; color: #a09e9a; margin-top: .5cqw; line-height: 1.35; }
.sw {
  flex: 0 0 auto; width: 13cqw; height: 7.6cqw; border-radius: 99px; border: 0; padding: 0; cursor: pointer;
  background: #dcdbd7; box-shadow: inset 0 .2cqw .4cqw rgba(0,0,0,.12);
  transition: background .18s;
}
.sw i { display: block; width: 6.2cqw; height: 6.2cqw; margin: .7cqw; border-radius: 50%; background: #fff;
  box-shadow: 0 .2cqw .5cqw rgba(0,0,0,.22); transition: transform .18s cubic-bezier(.3,1.3,.5,1); }
.sw.on { background: var(--amber); }
.sw.on i { transform: translateX(5.4cqw); }
.pickrow { display: flex; gap: 1.4cqw; flex: 0 0 auto; }
.pick {
  border: 0; cursor: pointer; padding: 1.5cqw 2.8cqw; border-radius: 99px;
  font: inherit; font-size: 2.8cqw; font-weight: 600; color: var(--dim);
  background: #e9e8e5; box-shadow: inset 0 0 0 1px rgba(0,0,0,.05);
}
.pick.on { background: var(--amber); color: #fff; box-shadow: inset 0 -.2cqw .3cqw rgba(120,60,0,.2); }

.credits { font-size: 2.5cqw; line-height: 1.6; color: #a5a39f; padding: 2cqw 3.4cqw 0; }
.credits a { color: #8f8e8b; }

/* the viewer */
.viewer {
  position: absolute; inset: 0; z-index: 70;
  display: flex; flex-direction: column;
  padding: calc(var(--safe-t, 0px) + 3cqh) 4cqw calc(var(--safe-b, 0px) + 3cqh);
  background: rgba(20,20,22,.92);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  opacity: 0; transition: opacity .24s;
}
.viewer.up { opacity: 1; }
.viewer[hidden] { display: none !important; }
.viewer .pic { flex: 1 1 auto; display: grid; place-items: center; min-height: 0; }
.viewer img { max-width: 100%; max-height: 100%; border-radius: 2cqw; box-shadow: 0 2cqw 5cqw rgba(0,0,0,.5); }
.vbar { display: flex; align-items: center; justify-content: space-between; gap: 3cqw; padding-top: 3cqw; }
.vbar .meta { color: #cfcdc9; font-size: 2.8cqw; letter-spacing: .12em; text-transform: uppercase; }
.vbar .meta i { display: block; font-style: normal; color: #85837f; letter-spacing: .06em; text-transform: none; margin-top: .6cqw; }
.vbtn {
  border: 0; cursor: pointer; padding: 2.4cqw 4cqw; border-radius: 99px;
  font: inherit; font-size: 3cqw; font-weight: 600; color: #1c1c1e; background: #f2f1ef;
}
.vbtn.ghost { background: rgba(255,255,255,.13); color: #f2f1ef; }
.vtop { display: flex; justify-content: space-between; padding-bottom: 3cqw; }

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* the shelf card is shot at a square viewport, where a phone frame would make the
   picture a picture of a desk */
body.cover #device { width: 100vw; height: 100dvh; }
body.cover .plate { opacity: 1; }

.vacts { display: flex; gap: 2cqw; }

/* The shelf crops its cards SQUARE. At a square viewport the top plate and the
   film tab squeeze the picture down to a third of the frame, which makes a card
   about a layout rather than about a camera — so the cover shows the app's face:
   the viewfinder and the six controls, and nothing else. */
body.cover .plate, body.cover .stock, body.cover .flip { display: none; }
body.cover #stage { padding-top: 4cqh; }
