/* Jim's 40th — surprise party invitation
   Figma: Untitled — "MacBook Pro 16' - 1" (2:34) and "iPhone 16 - 1" (13:46)

   Fixed-coordinate posters. Every element is pinned at the coordinate it was
   drawn at on its artboard, and the whole artboard is scaled to the window
   width (--vw, set by script.js). Nothing reflows. Desktop's artboard is
   1728 wide, the phone's 393; the photo wall below is its own artboard too. */

:root {
  /* palette, straight off the artboard */
  --ink:    #1c1c1c;
  --white:  #ffffff;
  --blue:   #3044a6;
  --paper:  #f0eee8;
  --olive:  #36360d;
  --butter: #fcf1c4;

  --serif: "Instrument Serif", Georgia, "Times New Roman", serif;
  --cond:  "Sofia Sans Extra Condensed", "Arial Narrow", Impact, sans-serif;

  --vw: 1728; /* window width in px, set by script.js */

  color-scheme: dark;
}

* { box-sizing: border-box; }

html, body { margin: 0; padding: 0; }

/* Polaroids bleeding past the edges must never add a horizontal scrollbar.
   This has to sit on <html>: overflow on <body> is propagated to the viewport
   instead of clipping anything. */
html {
  overflow-x: hidden;
  overflow-x: clip;
  background: var(--ink);
}

body {
  background: var(--ink);
  color: var(--white);
  -webkit-text-size-adjust: 100%;
}

/* --------------------------------------------------------------- artboards -- */

/* Each artboard is drawn at --design-w x --design-h (the Figma frame, down to
   just under the RSVP) and scaled by --s to the window width. .page holds the
   scaled size so the document gets its real height — .stage is scaled with a
   transform, which doesn't affect layout. */
.page--desk  { --design-w: 1728; --design-h: 2300; }
.page--phone { --design-w: 393;  --design-h: 2200; display: none; }

@media (max-width: 599.98px) {
  .page--desk  { display: none; }
  .page--phone { display: block; }
}

.page {
  --s: calc(var(--vw) / var(--design-w));
  position: relative;
  width: calc(var(--design-w) * var(--s) * 1px);
  height: calc(var(--design-h) * var(--s) * 1px);
  overflow: hidden;
}

.stage {
  position: relative;
  width: calc(var(--design-w) * 1px);
  height: calc(var(--design-h) * 1px);
  transform: scale(var(--s));
  transform-origin: 0 0;
  /* The Figma frame clips its contents; so does this. */
  overflow: hidden;
}

.stage > *,
.wall__stage > * { position: absolute; margin: 0; }

/* ------------------------------------------------------------- shared type -- */

.title {
  font: 400 160px/normal var(--serif);
  text-align: center;
}

.kicker {
  font: 400 40px/normal var(--serif);
  text-transform: lowercase;
  text-align: center;
}

/* Blue highlighter bars, pinned where Figma drew them behind the words. */
.mark { background: var(--blue); }

.blurb { font: 400 36px/normal var(--serif); }

.date {
  font: 900 60px/normal var(--cond);
  text-transform: uppercase;
}

.details {
  padding: 0;
  list-style: disc;
  font: 400 36px/normal var(--serif);
}

.rsvp {
  color: var(--white);
  text-decoration: none;
  cursor: pointer;
}

.rsvp__blob {
  position: absolute;
  transform: rotate(-8.97deg);
}

.rsvp__text {
  position: absolute;
  left: 0;
  width: 640px;
  font: 900 130px/normal var(--cond);
  text-transform: uppercase;
  text-align: center;
  white-space: nowrap;
  transition: color 0.2s ease;
}

.rsvp:hover .rsvp__text,
.rsvp:focus-visible .rsvp__text { color: var(--butter); }

.rsvp:focus-visible { outline: 4px solid var(--blue); outline-offset: 8px; }

/* ----------------------------------------------------------------- desktop -- */

.page--desk .title   { left: 226px; top: 264px; width: 1276px; }

.page--desk .mark--surprise { left: 955px; top: 721px; width: 222px; height: 27px; }
.page--desk .kicker  { left: 265px; top: 695px; width: 1197px; height: 48px; letter-spacing: 1.2px; }

/* The paragraph, date and details sit 27px above Figma's positions, so the
   block (now with the extra "Surprise at 6:30!" line) stays centred top to
   bottom on the polaroid beside it. */
.page--desk .blurb   { left: 771px; top: 1011px; width: 627px; }

.page--desk .mark--date { left: 765.1px; top: 1360px; width: 332px; height: 38px; }
.page--desk .date    { left: 771px; top: 1333px; width: 360px; }
.page--desk .details { left: 751.1px; top: 1423px; width: 690px; }
.page--desk .details li { margin-left: 54px; }

/* The ellipse is 472 x 159, rotated -8.97deg, centred in a 491 x 230.6 box at
   x=618 — i.e. 74px in from the link's left edge. */
.page--desk .rsvp       { left: 544px; top: 1886px; width: 640px; height: 231px; }
.page--desk .rsvp__blob { left: calc(74px + 9.5px); top: calc(115.3px - 79.5px); width: 472px; height: 159px; }
.page--desk .rsvp__text { top: 46px; }

/* ------------------------------------------------------------------- phone -- */

.page--phone .title  { left: 16px; top: 144px; width: 361px; font-size: 100px; line-height: 90px; }

.page--phone .mark--surprise { left: 147px; top: 614px; width: 196px; height: 27px; }
.page--phone .kicker { left: 49px; top: 545px; width: 294px; font-size: 36px; letter-spacing: 1.08px; }

.page--phone .blurb  { left: 55px; top: 1281px; width: 282px; font-size: 28px; }

.page--phone .mark--date { left: 52px; top: 1690px; width: 272px; height: 33px; }
.page--phone .date    { left: 55.9px; top: 1667px; width: 360px; font-size: 50px; }
.page--phone .details { left: 36px; top: 1747px; width: 299px; font-size: 28px; }
.page--phone .details li { margin-left: 42px; }

/* The ellipse is 220 x 74 rotated the same -8.97deg, centred in a 229 x 107.6
   box at x=81 — 205px in from the link's left edge (the link is 640 wide and
   centred on the frame, so it hangs past both sides, clipped). */
.page--phone .rsvp       { left: -124px; top: 2005px; width: 640px; height: 107.57px; }
.page--phone .rsvp__blob { left: 209.47px; top: 16.7px; width: 220.157px; height: 74.163px; }
.page--phone .rsvp__text { top: 24.47px; font-size: 60px; }
.page--phone .rsvp:focus-visible { outline-width: 3px; outline-offset: 4px; }

/* ----------------------------------------------------------------- wall -- */

/* The photo wall, laid out once per screen size by build-gallery.py. Each is
   a fixed artboard (--wall-w x --wall-h) scaled to the window like .stage;
   narrower artboards hold fewer prints across, so photos stay big on small
   screens. Only the one for this screen shows, and since its photos are
   lazy-loaded, the hidden walls never download anything. */
.wall {
  display: none;
  position: relative;
  height: calc(var(--wall-h) * var(--vw) / var(--wall-w) * 1px);
  /* Clip the sideways bleed, but let the staggered top row overhang upward
     into the space under the RSVP. */
  overflow-x: clip;
  overflow-y: visible;
}

.wall__stage {
  position: relative;
  width: calc(var(--wall-w) * 1px);
  height: calc(var(--wall-h) * 1px);
  transform: scale(calc(var(--vw) / var(--wall-w)));
  transform-origin: 0 0;
}

@media (min-width: 1024px) { .wall--desk { display: block; } }
@media (min-width: 600px) and (max-width: 1023.98px) { .wall--tab { display: block; } }
@media (max-width: 599.98px) { .wall--phone { display: block; } }

/* ------------------------------------------------------------ polaroids -- */

.snap {
  left:   calc(var(--x) * 1px);
  top:    calc(var(--y) * 1px);
  width:  calc(var(--w) * 1px);
  height: calc(var(--h) * 1px);
  /* A slight random tilt (--r degrees), set per print. */
  transform: rotate(calc(var(--r, 0) * 1deg));
  background: var(--paper);
  border-radius: 10px;
}

.snap__photo {
  position: absolute;
  left:   calc(var(--px) * 1px);
  top:    calc(var(--py) * 1px);
  width:  calc(var(--pw) * 1px);
  height: calc(var(--ph) * 1px);
  overflow: hidden;
  background: #2a2a2a;
}

.snap__photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
}

/* Figma's crop on photo 001. */
.snap__photo img.snap__crop-001 {
  left: -43.9%;
  top: -26.4%;
  width: 175.95%;
  height: 165.14%;
}

/* The inset shadow sits over the photo, as in Figma. */
.snap__photo::after {
  content: "";
  position: absolute;
  inset: 0;
  box-shadow: inset 0 4px 34px 0 rgba(0, 0, 0, 0.4);
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .rsvp__text { transition: none; }
}
