/* ============================================================================
   mockup.css — phone-scale Instagram feed post.

   Lifted from the ICB campaign demo site
   (PROJECTS/ICB/Working/campaign-creative/demo-site/index.html, the .phone /
   .feed / .car / .caption block) and adapted for crit:
     · every `vw`/`vh` unit replaced with a literal px (laptop-only, §8);
     · the carousel is driven by the router rather than by scroll-snap, because
       paging a set here must move BOTH panes — a slide IS a design;
     · the post image is 4:5 (1080x1350), not the demo's ad ratio.

   This file styles the SURROUND only. The frame inside it is never restyled,
   tinted, shadowed or filtered: judging the artwork is the whole point.
   ========================================================================= */

.phone {
  width: 372px;
  height: 785px;            /* 372 * 19/9, written out so no aspect-ratio/vh maths is involved */
  background: #0b0b10;
  border-radius: 50px;
  padding: 10px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, .55);
  position: relative;
  flex: 0 0 auto;
}

.phone-screen {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 40px;
  overflow: hidden;
  background: #fff;
  display: flex;
  flex-direction: column;
  color: #111;
}

.notch {
  position: absolute;
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
  width: 96px;
  height: 26px;
  background: #0b0b10;
  border-radius: 999px;
  z-index: 60;
}

.statusbar {
  height: 46px;
  flex: 0 0 auto;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  padding: 0 26px 4px;
  font-size: 13.5px;
  font-weight: 600;
  z-index: 50;
  position: relative;
  color: #111;
  font-family: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
}

.homebar {
  position: absolute;
  bottom: 7px;
  left: 50%;
  transform: translateX(-50%);
  width: 112px;
  height: 4px;
  border-radius: 999px;
  background: #111;
  opacity: .85;
  z-index: 60;
}

/* ---------------------------------------------------------- IG feed post ---- */

.feed {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  font-family: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
}

.ig-app-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 14px 6px;
  flex: 0 0 auto;
}
.ig-wordmark { font-size: 20px; font-weight: 700; letter-spacing: -.02em; color: #111; }

.post-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  flex: 0 0 auto;
}
.avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: #181e44;               /* ICB navy */
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  flex: 0 0 auto;
  color: #fff;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .03em;
}
.post-id { flex: 1; min-width: 0; line-height: 1.25; }
.post-id b { display: block; font-size: 13.5px; font-weight: 600; color: #111; }
.post-id span { display: block; font-size: 12px; color: #737373; }

.carousel-wrap { position: relative; flex: 0 0 auto; background: #fff; overflow: hidden; }
/* The track holds every slide of a set side by side and is translated by
   -pos * 100% to page (modal, §4b). A single design is a one-slide track. */
.car-track {
  display: flex;
  flex-wrap: nowrap;
  width: 100%;
  transform: translateX(0);
  transition: transform 320ms ease;
}
.carousel-wrap img {
  display: block;
  width: 100%;
  flex: 0 0 100%;
  aspect-ratio: 4 / 5;      /* the row's own ratio is set inline per slide (§4d) */
  object-fit: contain;
  background: #fff;
}
.car-count {
  position: absolute;
  top: 12px;
  right: 12px;
  background: rgba(0, 0, 0, .62);
  color: #fff;
  font-size: 12px;
  font-weight: 500;
  border-radius: 999px;
  padding: 4px 9px;
  z-index: 2;
  font-family: "IBM Plex Mono", ui-monospace, Menlo, monospace;
}
.car-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .92);
  border: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .25);
  z-index: 2;
  color: #333;
  padding: 0;
}
.car-arrow[hidden] { display: none; }
.car-prev { left: 10px; }
.car-next { right: 10px; }

.cta-band {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 14px;
  color: #0095f6;
  font-size: 14px;
  font-weight: 600;
  border-bottom: 1px solid rgba(0, 0, 0, .06);
  flex: 0 0 auto;
}

.actions {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 9px 14px 3px;
  position: relative;
  flex: 0 0 auto;
}
.actions .spacer { flex: 1; }
.dots {
  display: flex;
  gap: 4px;
  justify-content: center;
  position: absolute;
  left: 0;
  right: 0;
  top: 14px;
  pointer-events: none;
}
.dots i { width: 6px; height: 6px; border-radius: 50%; background: #c7c7cc; }
.dots i.on { background: #0095f6; }

.caption {
  padding: 10px 14px 12px;
  font-size: 13.5px;
  line-height: 1.45;
  color: #262626;
  margin: 0;
  flex: 0 1 auto;
  overflow: hidden;
}
.caption b { font-weight: 600; color: #111; }
.caption .cap-cta { font-weight: 600; color: #111; }
.caption .more { color: #8e8e93; }

/* ============================================================================
   modal — the screening room (round 2, spec §4). Owned by mockup-modal.js.

   The room is deliberately the same in both themes, so its greys are literals:
   #26262a scrim, #131316 phone back. Controls reuse the site's .btn and .label
   (app.css tokens), because they are chrome, not scenery.

   Timeline on open (t from the trigger, ms):
     0     scrim starts fading in (2000, ease-in-out); phone present, back face
           toward the viewer, scale .7
     500   flip starts: rotateY 180 -> 0 over 1500, cubic-bezier(.2,.7,.2,1);
           scale .7 -> 1 over the same 1500, cubic-bezier(.16,.84,.3,1)
     2000  scrim opaque, phone at rest, full size, front face
   Close: scrim out over 600; phone back over and down to .7 over 500.

   The two curves live on two registered custom properties so ONE element's
   transform carries both: getComputedStyle(.phone).transform is a matrix of
   rotateY x scale throughout, identity at rest. No per-frame JS anywhere.
   ========================================================================= */

@property --mm-ry {
  syntax: '<angle>';
  inherits: false;
  initial-value: 180deg;
}
@property --mm-sc {
  syntax: '<number>';
  inherits: false;
  initial-value: .7;
}

.mockup-modal {
  position: fixed;
  inset: 0;
  z-index: 400;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  outline: none;
  --mm-fit: 1;
}

/* ---- scrim: an opaque, textured dark grey surface, never a gradient */
.mm-scrim {
  position: absolute;
  inset: 0;
  background-color: #26262a;
  opacity: 0;
  /* ease-out, not ease-in-out: the room must start darkening on the very first
     frame (Jordan, 04Sep26f), and still land at the same moment as the phone */
  transition: opacity 2000ms cubic-bezier(.22, .61, .36, 1);
}
.mm-scrim::before {
  /* fine monochrome grain: fractalNoise, desaturated, tiled */
  content: "";
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='g'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/></filter><rect width='220' height='220' filter='url(%23g)'/></svg>");
  background-size: 220px 220px;
  opacity: .085;
  mix-blend-mode: normal;
}
.mm-scrim::after {
  /* a soft fall-off toward the edges so the phone reads as lit; the centre
     stays the flat grey, the corners a shade deeper, nothing near black */
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 70% 70% at 50% 46%, rgba(0, 0, 0, 0) 45%, rgba(0, 0, 0, .28) 100%);
}
.mockup-modal.is-open .mm-scrim { opacity: 1; }
.mockup-modal.is-closing .mm-scrim { opacity: 0; transition-duration: 600ms; }

/* ---- stage: the phone, centred, fitted to the viewport height */
.mm-stage {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 28px;
  zoom: var(--mm-fit);
}
.mm-flip {
  perspective: 1400px;
  perspective-origin: 50% 50%;
}

/* the phone: ONE face, one element's transform. There is no back face any more:
   with backface-visibility hidden the phone is simply absent until its rotation
   passes 90deg, so the first frame it is seen is the edge-on one where the least
   of it shows (Jordan, 04Sep26f). */
.mockup-modal .phone {
  --mm-ry: 180deg;
  --mm-sc: .7;
  transform: rotateY(var(--mm-ry)) scale(var(--mm-sc));
  transform-style: preserve-3d;
  backface-visibility: hidden;
  transition:
    --mm-ry 1500ms cubic-bezier(.2, .7, .2, 1) 500ms,
    --mm-sc 1500ms cubic-bezier(.16, .84, .3, 1) 500ms;
}
.mockup-modal .phone-screen { backface-visibility: hidden; }
.mockup-modal.is-open .phone { --mm-ry: 0deg; --mm-sc: 1; }
.mockup-modal.is-closing .phone {
  --mm-ry: 180deg;
  --mm-sc: .7;
  transition:
    --mm-ry 500ms cubic-bezier(.4, 0, .6, 1) 0ms,
    --mm-sc 500ms cubic-bezier(.4, 0, .6, 1) 0ms;
}

/* ---- close button, top right of the room */
.mm-close {
  position: absolute;
  top: 20px;
  right: 24px;
  z-index: 2;
}

/* ---- under the phone */
.mm-foot {
  position: relative;
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.mm-foot p { margin: 0; }
.mm-note {
  font-family: var(--sans);
  font-size: 0.8125rem;
  color: #b3b3b8;
}
.mm-hint { color: #7d7d84; }

/* The room's chrome (chevrons, close, foot copy) arrives WITH the room: it is
   invisible while the scrim is still translucent and fades up as the phone
   lands, so no Close button ever floats over the viewer's actor chip. On close
   it fades with the room, so nothing hangs in space after the scrim has gone. */
.mm-foot,
.mm-close {
  opacity: 0;
  transition: opacity 300ms ease;
}
.mm-stage { transition: opacity 300ms ease; }
.mockup-modal.is-open .mm-foot,
.mockup-modal.is-open .mm-close {
  opacity: 1;
  transition: opacity 500ms ease 1500ms;
}
.mockup-modal.is-open.is-closing .mm-foot,
.mockup-modal.is-open.is-closing .mm-close { transition: opacity 300ms ease; }
.mockup-modal.is-closing .mm-foot,
.mockup-modal.is-closing .mm-close { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .mm-scrim,
  .mockup-modal .phone,
  .mockup-modal.is-closing .phone,
  .mockup-modal.is-closing .mm-scrim,
  .car-track,
  .mm-stage,
  .mm-foot,
  .mm-close {
    transition-duration: 0s;
    transition-delay: 0s;
  }
}
