/* ---- Site footer modules (js/site-footer.js) ----
 * The CD player, the guest book postcard and the pocket of links. The
 * footer's place under the page (the reveal) is in css/footer.css, which
 * every page links; this file is loaded by js/site-footer.js before it
 * builds the footer, so it doesn't hold up the page's first paint. The
 * guest book page links it too, for its postcards.
 *
 * Each module is drawn at its Figma frame's size (322×503, 960×503) in
 * `--u` units (1u = one Figma px at the module's current width), so the
 * whole thing scales with the window. Images are in images/footer/.
 */

.ft-row {
  display: grid;
  grid-template-columns: 322fr 960fr 322fr;
  gap: 1.25vw;
}

.ft-mod {
  position: relative;
  container-type: inline-size;
  overflow: hidden;
  border-radius: var(--radius, .75rem);
  --u: calc(100cqw / 322);
  aspect-ratio: 322 / 503;
}

/* Everything inside a module is placed by its Figma position */
.ft-mod * {
  box-sizing: border-box;
}

.ft-abs {
  position: absolute;
  display: block;
}

/* ---- Music player ---- */

.mp {
  background: url("../images/footer/music-body-light.avif") center / 100% 100% no-repeat;
}

html.is-dark .mp {
  background-image: url("../images/footer/music-body-dark.avif");
}

/* SoundCloud logo: links to the mix that's in */
.mp_logo {
  left: calc(272 * var(--u));
  top: calc(16 * var(--u));
  width: calc(36 * var(--u));
  height: calc(16 * var(--u));
  color: #f1f1f1;
  transition: color .6s ease, opacity .2s ease;
}

html.is-dark .mp_logo {
  color: #757575;
}

.mp_logo:hover {
  opacity: .7;
}

.mp_logo svg {
  display: block;
  width: 100%;
  height: 100%;
}

/* The round slot the CDs sit in. Its shape is the mask: a CD swinging in
   or out only shows inside it. */
.mp_well {
  left: calc(33.5 * var(--u)); /* centered: (322 - 255) / 2 */
  top: calc(49 * var(--u));
  width: calc(255 * var(--u));
  height: calc(255 * var(--u));
  border-radius: 50%;
  background-color: #262626;
  box-shadow: inset 0 calc(-5 * var(--u)) calc(4.2 * var(--u)) calc(2 * var(--u)) rgba(0, 0, 0, .25);
  overflow: hidden;
  clip-path: circle(50%);
}

/* One per CD. It swings in and out round a point well below the slot,
   like a wheel; the disc inside spins on its own. */
.mp_disc {
  position: absolute;
  left: calc(18.5 * var(--u));
  top: calc(18.5 * var(--u));
  width: calc(218 * var(--u));
  height: calc(218 * var(--u));
  transform-origin: 50% 210%;
  visibility: hidden;
}

.mp_disc.is-in {
  visibility: visible;
}

.mp_disc img {
  display: block;
  width: 100%;
  height: 100%;
  will-change: transform;
  -webkit-user-drag: none;
  user-select: none;
}

.mp_controls {
  left: calc(25 * var(--u));
  top: calc(335 * var(--u));
  width: calc(272 * var(--u));
  height: calc(120 * var(--u));
  pointer-events: none;
}

/* Status light: red while stopped, green while playing */
.mp_led {
  left: calc(212 * var(--u));
  top: calc(338 * var(--u));
  width: calc(12 * var(--u));
  height: calc(12 * var(--u));
  border-radius: 50%;
  background: radial-gradient(circle at 50% 42%, #5a5a5a, #999);
  pointer-events: none;
}

.mp_led::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background-color: #ff0000;
  filter: blur(calc(3 * var(--u)));
  transition: background-color .4s ease;
}

.mp.is-playing .mp_led::after {
  background-color: #9dff00;
  animation: mp-led-blink 1.2s ease-in-out infinite;
}

/* Blinks while playing, like a stereo's activity light */
@keyframes mp-led-blink {
  0%, 45% { opacity: 1; }
  60%, 85% { opacity: .2; }
  100% { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .mp.is-playing .mp_led::after {
    animation: none;
  }
}

/* The three buttons: see-through, over the buttons in the image. Pressing
   one shades its face, as if it's pushed in. */
.mp_btn {
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.mp_btn::after {
  content: "";
  position: absolute;
  inset: 9.5%;
  border-radius: 50%;
  background-color: rgba(0, 0, 0, 0);
  box-shadow: inset 0 0 0 rgba(0, 0, 0, 0);
  transition: background-color .25s ease, box-shadow .25s ease;
}

.mp_btn:active::after {
  background-color: rgba(0, 0, 0, .06);
  box-shadow: inset 0 calc(3 * var(--u)) calc(7 * var(--u)) rgba(0, 0, 0, .3);
  transition-duration: .06s;
}

.mp_btn:focus-visible {
  outline: 2px solid var(--gundam-blue, #2519ab);
  outline-offset: 2px;
}

.mp_prev {
  left: calc((68 - 34) * var(--u));
  top: calc((396 - 34) * var(--u));
  width: calc(68 * var(--u));
  height: calc(68 * var(--u));
}

.mp_play {
  left: calc((161 - 47) * var(--u));
  top: calc((397 - 47) * var(--u));
  width: calc(94 * var(--u));
  height: calc(94 * var(--u));
}

.mp_next {
  left: calc((254 - 34) * var(--u));
  top: calc((396 - 34) * var(--u));
  width: calc(68 * var(--u));
  height: calc(68 * var(--u));
}

/* The hidden SoundCloud player that does the playing */
.mp_widget {
  position: absolute;
  left: -9999px;
  top: 0;
  width: 300px;
  height: 166px;
  border: 0;
  opacity: 0;
  pointer-events: none;
}

/* ---- Postcard module ---- */

.ft-pc {
  --stage-w: 960; /* how much of the 960-wide Figma frame shows */
  --u: calc(100cqw / var(--stage-w));
  /* The text stays on its two lines: once it stops shrinking at 11px,
     its box stops shrinking too (each line is about 31 letters' widths).
     Small desktop windows and iPads in landscape need it as much as
     tablets do. */
  --head-px: max(calc(435 * var(--u)), 352px);
  aspect-ratio: 960 / 503;
  background-color: #fff;
  box-shadow: inset 0 1px 4px rgba(185, 182, 249, .25);
  transition: background-color .6s ease;
}

/* The archive (dark mode): Figma "guest-note-module-darkmode". Only the
   module goes dark; the card, stamps and gray text stay as they are. */
html.is-dark .ft-pc {
  background-color: #313131;
}

/* The full 960×503 frame, centered (phones crop its sides) */
.pc-stage {
  position: absolute;
  top: calc(var(--stage-top, 0) * var(--u));
  left: calc((var(--stage-w) - 960) / 2 * var(--u));
  width: calc(960 * var(--u));
  height: calc(503 * var(--u));
}

/* The text and the dashed line from it down to the postcard. Together
   they fill the space above the card (to 28 short of it, as in Figma):
   the line takes what the text leaves, so it always ends above the card,
   however many lines the text wraps to. */
.pc-head {
  --head-w: 435; /* text width */
  left: calc(480 * var(--u) - var(--head-px, var(--head-w) * var(--u)) / 2);
  top: calc((39 - var(--stage-top, 0)) * var(--u));
  width: var(--head-px, calc(var(--head-w) * var(--u)));
  height: calc((128 + var(--stage-top, 0)) * var(--u));
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(28 * var(--u));
}

.pc-blurb {
  flex: none;
  margin: 0;
  color: #b2b2b2;
  font-family: Geist, sans-serif;
  font-size: var(--pc-font, max(11px, calc(14 * var(--u))));
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: calc(-.25 * var(--u));
  text-align: center;
  text-wrap: balance;
}

.pc-string {
  flex: 1 1 auto;
  width: 1px;
  min-height: calc(12 * var(--u));
  max-height: calc(58 * var(--u));
  background: repeating-linear-gradient(to bottom, #b2b2b2 0 calc(3 * var(--u)), transparent 0 calc(6 * var(--u)));
}

.pc-blurb,
.pc-string {
  transition: opacity .45s ease, translate .6s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Loose stamps around the card. Their size and angle are measured from
   the card's own stamp image (stamp-*.avif). */
.pc-loose {
  width: calc(107.7 * var(--u));
  height: calc(127.3 * var(--u));
  margin: calc(-63.65 * var(--u)) 0 0 calc(-53.85 * var(--u));
  transition: translate .7s cubic-bezier(0.22, 1, 0.36, 1), rotate .7s cubic-bezier(0.22, 1, 0.36, 1);
  pointer-events: none;
  /* A firmer edge than the image's own faint shadow, so the white scallops
     show on the white module (Figma: 20% black, y 1, blur 1.1; the blur
     means the same in CSS). At least a pixel, so it doesn't fade out when
     the footer is drawn smaller than in Figma. */
  filter: drop-shadow(0 max(1px, calc(1 * var(--u))) max(1.1px, calc(1.1 * var(--u))) rgba(0, 0, 0, .2));
}

.pc-loose.is-green { left: calc(112.5 * var(--u)); top: calc(292.1 * var(--u)); rotate: -16.2deg; }
.pc-loose.is-yellow { left: calc(116.2 * var(--u)); top: calc(474.4 * var(--u)); rotate: 20.1deg; }
.pc-loose.is-red { left: calc(861.7 * var(--u)); top: calc(463.5 * var(--u)); rotate: -24.4deg; }

/* The postcard: peeks up from the bottom; hovering lifts it into view */
.ft-pc .pc-card {
  left: calc(202 * var(--u));
  top: calc(195 * var(--u));
  width: calc(556 * var(--u));
  height: calc(393.17 * var(--u));
  cursor: pointer;
  transition: translate .7s cubic-bezier(0.22, 1, 0.36, 1);
  -webkit-tap-highlight-color: transparent;
}

.ft-pc .pc-card:focus-visible {
  outline: none;
}

.ft-pc .pc-card:focus-visible .pc-face {
  outline: 2px solid var(--gundam-blue, #2519ab);
  outline-offset: 3px;
}

.ft-pc.is-lifted .pc-card { translate: 0 calc(-140 * var(--u)); }
/* Hovered, the loose stamps fly up and turn (Figma: guest-note-hover) */
.ft-pc.is-lifted .pc-loose.is-green { translate: calc(-17.9 * var(--u)) calc(-155.4 * var(--u)); rotate: 20.8deg; }
.ft-pc.is-lifted .pc-loose.is-yellow { translate: calc(30.9 * var(--u)) calc(-142.7 * var(--u)); rotate: -25deg; }
.ft-pc.is-lifted .pc-loose.is-red { translate: calc(-8.6 * var(--u)) calc(-170.6 * var(--u)); rotate: 12.7deg; }
.ft-pc.is-lifted .pc-loose.is-yellow { transition-delay: .03s; }
.ft-pc.is-lifted .pc-loose.is-red { transition-delay: .05s; }
.ft-pc.is-lifted .pc-blurb,
.ft-pc.is-lifted .pc-string {
  opacity: 0;
  translate: 0 calc(-12 * var(--u));
}

/* While the card is open in the middle of the screen, the footer's copy
   of it is hidden */
.ft-pc.is-out .pc-card {
  visibility: hidden;
}

/* ---- The postcard itself ----
   Used in the footer, opened in the middle of the screen
   (js/footer-postcard.js) and on the guest book page (guestbook.html).
   Laid out in --u units of its 556×393 Figma frame. */
.pc-face {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: calc(10.6 * var(--u));
  background-color: #fff;
  box-shadow: 0 calc(5.3 * var(--u)) calc(17.9 * var(--u)) rgba(0, 0, 0, .09);
  color: #555;
  text-align: left;
  --tint-blue: #dce7ff;
  --tint-red: #ffdcdc;
  --tint-yellow: #fff3dc;
  --tint-green: #e7ffdc;
  --post-blue: #e6eeff;
}

/* One tinted layer per color; the chosen one shows */
.pc-tint {
  position: absolute;
  inset: 0;
  opacity: 0;
  pointer-events: none;
}

.pc-tint.is-on {
  opacity: 1;
}

.pc-tint[data-color="blue"] { background: linear-gradient(199deg, var(--tint-blue) 1%, #fff 57%); }
.pc-tint[data-color="red"] { background: linear-gradient(199deg, var(--tint-red) 1%, #fff 57%); }
.pc-tint[data-color="yellow"] { background: linear-gradient(199deg, var(--tint-yellow) 1%, #fff 57%); }
.pc-tint[data-color="green"] { background: linear-gradient(199deg, var(--tint-green) 1%, #fff 57%); }

/* Paper grain */
.pc-grain {
  position: absolute;
  inset: 0;
  pointer-events: none;
  /* No blend mode: over the card's near-white it looks the same, and a
     blend mode inside the guest book carousel's 3D turn made it lag */
  opacity: .32;
  /* A ready-made tile rather than an SVG noise filter: the filter is slow
     to redraw, and the guest book carousel redraws cards as they turn.
     Made at 2x (360px shown at 180), so the grain stays fine on Retina. */
  background-image: url("../images/footer/grain.avif");
  background-size: 180px 180px;
}

.pc-divider {
  left: calc(375.5 * var(--u));
  top: calc(27.5 * var(--u));
  width: max(1px, calc(.66 * var(--u)));
  height: calc(336 * var(--u));
  background: repeating-linear-gradient(to bottom, #a9a9a9 0 calc(2 * var(--u)), transparent 0 calc(4 * var(--u)));
}

/* Small labels ("Message", "From"...): placed by their middle */
.pc-label {
  margin: 0;
  font-family: Geist, sans-serif;
  font-size: calc(11.9 * var(--u));
  font-weight: 600;
  line-height: 1;
  letter-spacing: calc(-.33 * var(--u));
  white-space: nowrap;
  translate: 0 -50%;
}

/* Handwriting: the message, names and "Pedro" */
.pc-hand {
  font-family: Caveat, cursive;
  font-size: calc(23.8 * var(--u));
  font-weight: 700;
  line-height: calc(27.8 * var(--u));
  letter-spacing: calc(-.33 * var(--u));
  color: #130f0f;
}

.pc-hand.is-empty,
.pc-hand::placeholder {
  color: #d1d1d1;
  opacity: 1;
}

.pc-guest,
.pc-date { left: calc(19.5 * var(--u)); top: calc(41 * var(--u)); }
.pc-msg-label { left: calc(19.5 * var(--u)); top: calc(110 * var(--u)); }

/* Message: four ruled lines, the writing sits on them */
.pc-msg {
  left: calc(19.5 * var(--u));
  top: calc(130.2 * var(--u));
  width: calc(336.2 * var(--u));
  height: calc(111.2 * var(--u));
  margin: 0;
  padding: 0 0 0 calc(1 * var(--u));
  border: 0;
  outline: 0;
  resize: none;
  overflow: hidden;
  overflow-wrap: break-word;
  background: repeating-linear-gradient(to bottom, transparent 0 calc(27.14 * var(--u)), #a9a9a9 calc(27.14 * var(--u)) calc(27.8 * var(--u)));
}

.pc-from-label { left: calc(19.5 * var(--u)); top: calc(333.5 * var(--u)); }
.pc-from {
  left: calc(19.5 * var(--u));
  top: calc((355 - 13.9) * var(--u));
  width: calc(336 * var(--u));
  height: calc(27.8 * var(--u));
  margin: 0;
  padding: 0;
  border: 0;
  outline: 0;
  background: transparent;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pc-to-label { left: calc(395 * var(--u)); top: calc(333.5 * var(--u)); }
.pc-to { left: calc(395 * var(--u)); top: calc((355 - 13.9) * var(--u)); color: #555; }

/* .pc-face in front so the carousel's own image rule (.hcar_media img,
   css/home.css) doesn't stretch it on the guest book page */
.pc-face .pc-stamp {
  left: calc((479.2 - 53.85) * var(--u));
  top: calc((88.2 - 63.65) * var(--u));
  width: calc(107.7 * var(--u));
  height: calc(127.3 * var(--u));
  object-fit: fill;
  border-radius: 0;
  opacity: 0;
  pointer-events: none;
  -webkit-user-drag: none;
}

.pc-stamp.is-on {
  opacity: 1;
}

/* Form-only parts: the date, colors, buttons and the guest book link.
   They only show once the card is opened to write one. */
.pc-date,
.pc-colors,
.pc-back,
.pc-post,
.pc-view {
  opacity: 0;
  visibility: hidden;
}

.pc-colors {
  left: calc(19 * var(--u));
  top: calc(63 * var(--u));
  display: flex;
  gap: calc(12 * var(--u));
}

.pc-dot {
  width: calc(28 * var(--u));
  height: calc(28 * var(--u));
  margin: 0;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 50%;
  cursor: pointer;
  transition: border-color .3s ease, scale .3s cubic-bezier(0.34, 1.56, 0.64, 1);
  -webkit-tap-highlight-color: transparent;
}

.pc-dot[data-color="blue"] { background-color: var(--tint-blue); }
.pc-dot[data-color="red"] { background-color: var(--tint-red); }
.pc-dot[data-color="yellow"] { background-color: var(--tint-yellow); }
.pc-dot[data-color="green"] { background-color: var(--tint-green); }

.pc-dot[aria-pressed="true"] {
  border-color: #a7a7a7;
}

.pc-dot:hover {
  scale: 1.08;
}

.pc-dot:focus-visible,
.pc-back:focus-visible,
.pc-post:focus-visible {
  outline: 2px solid var(--gundam-blue, #2519ab);
  outline-offset: 2px;
}

.pc-back,
.pc-post,
.pc-view {
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  color: #555;
  font-family: Geist, sans-serif;
  font-size: calc(11.9 * var(--u));
  font-weight: 600;
  letter-spacing: calc(-.33 * var(--u));
  cursor: pointer;
}

.pc-back {
  left: calc(21 * var(--u));
  top: calc((353 - 11.5) * var(--u));
  height: calc(23 * var(--u));
  display: flex;
  align-items: center;
  gap: calc(4 * var(--u));
}

.pc-back svg {
  width: calc(22 * var(--u));
  height: calc(8 * var(--u));
  transition: translate .3s cubic-bezier(0.22, 1, 0.36, 1);
}

.pc-back:hover svg {
  translate: calc(-3 * var(--u)) 0;
}

.pc-post {
  left: calc(250 * var(--u));
  top: calc(341.5 * var(--u));
  width: calc(106 * var(--u));
  height: calc(23 * var(--u));
  /* Centered by flex, not the browser's own button centering, which sits
     the text off-center on phones where the card is small */
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  white-space: nowrap;
  border-radius: calc(6 * var(--u));
  background-color: var(--post-color, var(--post-blue));
  transition: background-color .5s ease, filter .2s ease, opacity .45s ease, translate .6s cubic-bezier(0.22, 1, 0.36, 1);
}

.pc-post:hover {
  filter: brightness(.97);
}

/* "View guest book", top right of the message side */
.pc-view {
  left: calc(256 * var(--u));
  top: calc(30.7 * var(--u));
  width: calc(106 * var(--u));
  height: calc(18 * var(--u));
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
}

.pc-view:hover {
  color: var(--black, #130f0f);
}

.pc-post:disabled {
  cursor: default;
}

/* Spam trap: people never see or fill it */
.pc-trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
}

/* Opening the card turns its footer layout into the form: "Guest book"
   gives way to the date and colors, "From" moves up, the buttons come in */
.pc-guest,
.pc-from-label,
.pc-from {
  transition: opacity .35s ease, translate .6s cubic-bezier(0.22, 1, 0.36, 1);
}

.pc-date,
.pc-colors,
.pc-back,
.pc-post,
.pc-view {
  transition: opacity .45s ease, visibility 0s .45s, translate .6s cubic-bezier(0.22, 1, 0.36, 1);
  translate: 0 calc(6 * var(--u));
}

.pc-date {
  translate: 0 calc(-50% + 6 * var(--u));
}

.pc-face.is-form .pc-guest {
  opacity: 0;
}

.pc-face.is-form .pc-date,
.pc-face.is-form .pc-colors,
.pc-face.is-form .pc-back,
.pc-face.is-form .pc-post,
.pc-face.is-form .pc-view {
  opacity: 1;
  visibility: visible;
  translate: 0 0;
  transition: opacity .45s ease .12s, visibility 0s, translate .6s cubic-bezier(0.22, 1, 0.36, 1) .12s, background-color .5s ease, filter .2s ease;
}

.pc-face.is-form .pc-date {
  translate: 0 -50%;
}

.pc-face.is-form .pc-colors { transition-delay: .18s, 0s, .18s; }
.pc-face.is-form .pc-back,
.pc-face.is-form .pc-post { transition-delay: .24s, 0s, .24s, 0s, 0s; }

.pc-face.is-form .pc-from-label,
.pc-face.is-form .pc-from {
  translate: 0 calc(-54.5 * var(--u));
}

.pc-face.is-form .pc-from-label {
  translate: 0 calc(-50% - 54.5 * var(--u));
}

/* A finished note (guest book page): date instead of "Guest book", "From"
   up where the form has it, no buttons */
.pc-face.is-note .pc-guest { opacity: 0; }
.pc-face.is-note .pc-date { opacity: 1; visibility: visible; translate: 0 -50%; }
.pc-face.is-note .pc-from { translate: 0 calc(-54.5 * var(--u)); }
.pc-face.is-note .pc-from-label { translate: 0 calc(-50% - 54.5 * var(--u)); }

/* ---- The open postcard, in the middle of the screen ---- */
.pc-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: grid;
  place-items: center;
  visibility: hidden;
}

.pc-overlay.is-open {
  visibility: visible;
}

/* Just a dim, no blur: Chrome redraws a blur whenever something on the
   card animates, so it flickered while switching colors */
.pc-dim {
  position: absolute;
  inset: 0;
  background-color: rgba(19, 15, 15, .4);
  opacity: 0;
  transition: opacity .5s ease;
}

.pc-overlay.is-open .pc-dim {
  opacity: 1;
}

.pc-overlay .pc-card {
  position: relative;
  width: min(92vw, 780px, calc(86vh * 556 / 393.17));
  aspect-ratio: 556 / 393.17;
  container-type: inline-size;
}

.pc-overlay .pc-face {
  --u: calc(100cqw / 556);
}

/* At least 16px, or iPhones zoom in on tapping them */
.pc-overlay .pc-msg,
.pc-overlay .pc-from {
  font-size: max(16px, calc(23.8 * var(--u)));
}

/* A posted note can have line breaks */
span.pc-msg {
  white-space: pre-wrap;
}

.pc-face,
.pc-face * {
  box-sizing: border-box;
}

/* A little shake when Post is pressed with no message */
.pc-msg.is-nudged {
  animation: pc-nudge .4s ease;
}

@keyframes pc-nudge {
  20% { translate: calc(-4 * var(--u)) 0; }
  40% { translate: calc(4 * var(--u)) 0; }
  60% { translate: calc(-2 * var(--u)) 0; }
  80% { translate: calc(2 * var(--u)) 0; }
}

/* ---- Links module ---- */

.lk {
  background: #2c2c2c url("../images/footer/links-leather.avif") center / 100% 100% no-repeat;
  /* A 2x copy for most screens, the 3x one past that (-2x.avif) */
  background-image: image-set(url("../images/footer/links-leather-2x.avif") 2x, url("../images/footer/links-leather.avif") 3x);
  box-shadow: inset 0 1px 4px rgba(185, 182, 249, .25);
}

.lk a {
  -webkit-tap-highlight-color: transparent;
}

.lk a:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 3px;
}

/* Tucked in the pocket at rest; hovering pulls them out and straightens
   them (js/site-footer.js adds is-open for touch screens) */
.lk-email,
.lk-insta,
.lk-arena {
  transition: transform .5s cubic-bezier(0.22, 1, 0.36, 1);
}

.lk-email {
  left: calc((144.8 - 91.75) * var(--u));
  top: calc((242.8 - 118.8) * var(--u));
  width: calc(183.5 * var(--u));
  height: calc(237.6 * var(--u));
  transform: rotate(-13.4deg);
  border-radius: calc(12 * var(--u));
  background-color: #fff;
  overflow: hidden;
  color: #000;
  text-decoration: none;
}

.lk-insta,
.lk-arena {
  width: calc(124.5 * var(--u));
  height: calc(124.5 * var(--u));
  filter: drop-shadow(0 calc(4 * var(--u)) calc(6.75 * var(--u)) rgba(0, 0, 0, .09));
}

.lk-insta {
  left: calc((256 - 62.25) * var(--u));
  top: calc((201 - 62.25) * var(--u));
  transform: rotate(-9.8deg);
}

.lk-arena {
  left: calc((71.7 - 62.25) * var(--u));
  top: calc((364.7 - 62.25) * var(--u));
  transform: rotate(14.3deg);
}

.lk-insta img,
.lk-arena img {
  display: block;
  width: 100%;
  height: 100%;
  -webkit-user-drag: none;
}

.lk-pocket {
  left: 0;
  top: calc(114.7 * var(--u));
  width: calc(322 * var(--u));
  height: calc(388.3 * var(--u));
  pointer-events: none;
  transition: translate .55s cubic-bezier(0.22, 1, 0.36, 1);
}

.lk.is-open .lk-email { transform: translate(calc(-45.1 * var(--u)), calc(-115 * var(--u))); transition-duration: .65s; }
.lk.is-open .lk-insta { transform: translate(calc(2.8 * var(--u)), calc(-137.2 * var(--u))) scale(.8795); transition-duration: .65s; transition-delay: .04s; }
.lk.is-open .lk-arena { transform: translate(calc(-8.9 * var(--u)), calc(-51.9 * var(--u))) scale(.8795); transition-duration: .65s; transition-delay: .08s; }
.lk.is-open .lk-pocket { translate: 0 calc(53 * var(--u)); transition-duration: .65s; }

/* Each pulled-out item lifts a little more under the mouse */
.lk.is-open .lk-insta:hover,
.lk.is-open .lk-arena:hover {
  transition-delay: 0s;
}

.lk.is-open .lk-insta:hover { transform: translate(calc(2.8 * var(--u)), calc(-140 * var(--u))) scale(.9); }
.lk.is-open .lk-arena:hover { transform: translate(calc(-8.9 * var(--u)), calc(-54.7 * var(--u))) scale(.9); }

/* Notebook paper: blue rules and a red margin line */
.lk-paper {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to right, transparent calc(24 * var(--u)), #ff8484 calc(24 * var(--u)) calc(24.7 * var(--u)), transparent 0),
    repeating-linear-gradient(to bottom, transparent 0 calc(16.2 * var(--u)), #e4ebf7 calc(16.2 * var(--u)) calc(16.9 * var(--u)));
  background-position: 0 0, 0 calc(3.7 * var(--u));
}

/* Three punched holes, cut out of the paper so what's behind shows
   through. Each layer is opaque except one hole; intersecting them leaves
   all three. */
.lk-email {
  --hole: calc(4.7 * var(--u)); /* radius */
  --hole-x: calc(12.5 * var(--u));
  -webkit-mask-image:
    radial-gradient(circle at var(--hole-x) calc(28.2 * var(--u)), transparent var(--hole), #000 calc(var(--hole) + .5px)),
    radial-gradient(circle at var(--hole-x) calc(119.2 * var(--u)), transparent var(--hole), #000 calc(var(--hole) + .5px)),
    radial-gradient(circle at var(--hole-x) calc(214.1 * var(--u)), transparent var(--hole), #000 calc(var(--hole) + .5px));
  mask-image:
    radial-gradient(circle at var(--hole-x) calc(28.2 * var(--u)), transparent var(--hole), #000 calc(var(--hole) + .5px)),
    radial-gradient(circle at var(--hole-x) calc(119.2 * var(--u)), transparent var(--hole), #000 calc(var(--hole) + .5px)),
    radial-gradient(circle at var(--hole-x) calc(214.1 * var(--u)), transparent var(--hole), #000 calc(var(--hole) + .5px));
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}

.lk-dear,
.lk-q {
  position: absolute;
  margin: 0;
  font-family: Caveat, cursive;
  font-size: calc(21 * var(--u));
  font-weight: 700;
  line-height: calc(18 * var(--u));
  letter-spacing: calc(-.25 * var(--u));
}

.lk-dear {
  left: calc(28.5 * var(--u));
  top: calc(18.4 * var(--u));
  white-space: nowrap;
}

.lk-q {
  left: calc(26 * var(--u));
  top: calc(51 * var(--u));
  width: calc(139 * var(--u));
}

/* The question writes itself in, letter by letter (js/site-footer.js) */
.lk-q .ch {
  display: inline-block;
  white-space: pre;
}

.lk-q .w {
  display: inline-block;
  white-space: nowrap;
}

.lk-q.is-leaving {
  opacity: 0;
  transition: opacity .25s ease;
}

/* ---- Smaller screens ---- */

/* Tablets: the postcard across the top, the player and links under it,
   from the Figma section "Tablet" (postcard-module-tablet 744×503,
   music-player-module-*-tablet and links-module-tablet 366×420). The
   three line up: two 366s and the gap make 744. */
@media screen and (max-width: 991px) {
  .site-footer {
    padding: 12px;
  }

  .ft-row {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 12px;
  }

  .ft-pc {
    flex: 1 1 100%;
    order: -1; /* across the top */
  }

  .ft-music,
  .ft-links {
    flex: 0 0 auto;
    width: calc((100% - 12px) / 2);
    --u: calc(100cqw / 366);
    aspect-ratio: 366 / 420;
  }

  /* Music player: the same parts, moved for the wider, shorter body */
  .mp {
    background-image: url("../images/footer/music-body-light-tablet.avif");
  }

  html.is-dark .mp {
    background-image: url("../images/footer/music-body-dark-tablet.avif");
  }

  .mp_logo { left: calc(309 * var(--u)); }
  /* The slot and CDs at 90%, lower down, to make room for the speaker
     grills along the top (drawn into the body image) */
  .mp_well {
    left: calc(68.25 * var(--u)); /* centered: (366 - 229.5) / 2 */
    top: calc(47 * var(--u));
    width: calc(229.5 * var(--u));
    height: calc(229.5 * var(--u));
  }
  .mp_disc {
    left: calc(16.65 * var(--u));
    top: calc(16.65 * var(--u));
    width: calc(196.2 * var(--u));
    height: calc(196.2 * var(--u));
  }
  .mp_controls { left: calc(47 * var(--u)); top: calc(285.5 * var(--u)); }
  .mp_led { left: calc(234 * var(--u)); top: calc(288.5 * var(--u)); }
  .mp_prev { left: calc((90 - 34) * var(--u)); top: calc((346.5 - 34) * var(--u)); }
  .mp_play { left: calc((183 - 47) * var(--u)); top: calc((347.5 - 47) * var(--u)); }
  .mp_next { left: calc((276 - 34) * var(--u)); top: calc((346.5 - 34) * var(--u)); }

  /* Links: a deeper pocket, cut on a slant (its image is swapped in the
     markup's <picture>). Pulled out as in links-module-tablet-hover. */
  .lk {
    background-image: url("../images/footer/links-leather-tablet.avif");
    background-image: image-set(url("../images/footer/links-leather-tablet-2x.avif") 2x, url("../images/footer/links-leather-tablet.avif") 3x);
  }

  .lk-email { left: calc((150.8 - 91.75) * var(--u)); top: calc((163.85 - 118.8) * var(--u)); }
  .lk-insta { left: calc((280 - 62.25) * var(--u)); top: calc((121 - 62.25) * var(--u)); }
  .lk-arena { left: calc((71.7 - 62.25) * var(--u)); top: calc((286.7 - 62.25) * var(--u)); }

  .lk-pocket {
    top: calc(44.67 * var(--u));
    width: calc(366 * var(--u));
    height: calc(375.33 * var(--u));
  }

  .lk.is-open .lk-email { transform: translate(calc(-51.05 * var(--u)), calc(-36.05 * var(--u))); }
  .lk.is-open .lk-insta { transform: translate(calc(-29 * var(--u)), calc(-62.5 * var(--u))) scale(.79); }
  .lk.is-open .lk-arena { transform: translate(calc(-14.2 * var(--u)), calc(19.8 * var(--u))) scale(.795); }
  .lk.is-open .lk-pocket { translate: 0 calc(56 * var(--u)); }
  .lk.is-open .lk-insta:hover { transform: translate(calc(-29 * var(--u)), calc(-65.3 * var(--u))) scale(.81); }
  .lk.is-open .lk-arena:hover { transform: translate(calc(-14.2 * var(--u)), calc(17 * var(--u))) scale(.815); }
}

/* Tablets (not phones): the postcard module is 744 wide, the 960 frame
   with its sides cut off, and the loose stamps tucked in closer */
@media screen and (min-width: 480px) and (max-width: 991px) {
  .ft-pc {
    --stage-w: 744;
    aspect-ratio: 744 / 503;
  }

  /* In the 960 frame's units: Figma's tablet positions plus the 108 cut
     off each side */
  .pc-loose.is-green { left: calc(172.6 * var(--u)); }
  .pc-loose.is-yellow { left: calc(187.2 * var(--u)); }
  .pc-loose.is-red { left: calc(792.7 * var(--u)); }

  /* Hovered (postcard-module-tablet-hover): the card lifts as on desktop;
     green and red fly up. Figma leaves yellow where it is, but it lifts
     like on desktop, as far left of the card as it is there. */
  .ft-pc.is-lifted .pc-loose.is-green { translate: calc(-16 * var(--u)) calc(-200 * var(--u)); rotate: -16.2deg; }
  .ft-pc.is-lifted .pc-loose.is-yellow { translate: calc(-40 * var(--u)) calc(-142.7 * var(--u)); rotate: -25deg; }
  .ft-pc.is-lifted .pc-loose.is-red { translate: 0 calc(-187.05 * var(--u)); rotate: 26.7deg; }
}

/* Phones: one column, each module from the Figma section "Mobile"
   (all 366 wide: postcard 248 tall, player 209, links 248). Positions
   are in that frame's px (--u = 1/366 of the module's width). */
@media screen and (max-width: 479px) {
  .site-footer {
    padding: 8px;
  }

  .ft-row {
    gap: 8px;
  }

  .ft-music,
  .ft-links {
    width: 100%;
  }

  .ft-music {
    aspect-ratio: 366 / 209;
  }

  .ft-links {
    aspect-ratio: 366 / 248;
  }

  /* Music player (music-player-module-mobile): a wide body, the CD on
     the left and the controls on the right, at 0.694 of their desktop
     size. The speaker grills are drawn into the body image. */
  .mp {
    background-image: url("../images/footer/music-body-light-mobile.avif");
  }

  html.is-dark .mp {
    background-image: url("../images/footer/music-body-dark-mobile.avif");
  }

  .mp_logo { left: calc(298 * var(--u)); top: calc(11 * var(--u)); width: calc(47 * var(--u)); height: calc(21 * var(--u)); }
  .mp_well {
    left: calc(13 * var(--u));
    top: calc(46 * var(--u));
    width: calc(141 * var(--u));
    height: calc(141 * var(--u));
    box-shadow: inset 0 calc(-2.8 * var(--u)) calc(2.3 * var(--u)) calc(1.1 * var(--u)) rgba(0, 0, 0, .25);
  }
  .mp_disc {
    left: calc(10.23 * var(--u));
    top: calc(10.23 * var(--u));
    width: calc(120.54 * var(--u));
    height: calc(120.54 * var(--u));
  }
  .mp_controls { left: calc(164 * var(--u)); top: calc(75 * var(--u)); width: calc(188.78 * var(--u)); height: calc(83.29 * var(--u)); }
  .mp_led { left: calc(293.79 * var(--u)); top: calc(77.08 * var(--u)); width: calc(8.33 * var(--u)); height: calc(8.33 * var(--u)); }
  .mp_led::after { filter: blur(calc(2.1 * var(--u))); }
  .mp_prev { left: calc(170.24 * var(--u)); top: calc(93.74 * var(--u)); width: calc(47.2 * var(--u)); height: calc(47.2 * var(--u)); }
  .mp_play { left: calc(225.77 * var(--u)); top: calc(85.41 * var(--u)); width: calc(65.25 * var(--u)); height: calc(65.25 * var(--u)); }
  .mp_next { left: calc(299.34 * var(--u)); top: calc(93.74 * var(--u)); width: calc(47.2 * var(--u)); height: calc(47.2 * var(--u)); }

  /* Links (links-module-mobile): a wide pocket cut on a slant (its image
     is swapped in the markup's <picture>). The note is the desktop one at
     0.761. Pulled out (links-module-mobile-hover), the three line up
     across the top and the pocket drops. */
  .lk {
    background-image: url("../images/footer/links-leather-mobile.avif");
    background-image: image-set(url("../images/footer/links-leather-mobile-2x.avif") 2x, url("../images/footer/links-leather-mobile.avif") 3x);
  }

  .lk-email { left: calc(44.18 * var(--u)); top: calc(-4.62 * var(--u)); transform: rotate(-13.4deg) scale(.7613); }
  .lk-insta { left: calc(205.12 * var(--u)); top: calc(22.12 * var(--u)); width: calc(94.78 * var(--u)); height: calc(94.78 * var(--u)); transform: rotate(8deg); }
  .lk-arena { left: calc(13.23 * var(--u)); top: calc(119.23 * var(--u)); width: calc(94.78 * var(--u)); height: calc(94.78 * var(--u)); transform: rotate(14.3deg); }

  /* The image has the shadow around the shape: the shape itself is at
     (-3.1, -21), 373 x 319 */
  .lk-pocket {
    left: calc(-24.14 * var(--u));
    top: calc(-44 * var(--u));
    width: calc(415.67 * var(--u));
    height: calc(361.33 * var(--u));
    max-width: none; /* wider than the module; the site's img cap squeezed it */
  }

  .lk.is-open .lk-email { transform: translate(calc(-51.08 * var(--u)), calc(-7.73 * var(--u))) scale(.7613); }
  .lk.is-open .lk-insta { transform: translate(calc(54 * var(--u)), calc(-8.23 * var(--u))) scale(.939); }
  .lk.is-open .lk-arena { transform: translate(calc(147.88 * var(--u)), calc(-104.12 * var(--u))) scale(.939); }
  .lk.is-open .lk-pocket { translate: 0 calc(119 * var(--u)); }
  .lk.is-open .lk-insta:hover { transform: translate(calc(54 * var(--u)), calc(-10.5 * var(--u))) scale(.96); }
  .lk.is-open .lk-arena:hover { transform: translate(calc(147.88 * var(--u)), calc(-106.4 * var(--u))) scale(.96); }

  /* Postcard (the mobile postcard frames): the 960 stage scaled so the
     card is 297 wide (--stage-w is how much of the stage the 366 module
     shows), the card's top at 97, the blurb on three lines above it. */
  .ft-pc {
    --stage-w: 685.17;
    --stage-top: -13.41;
    --head-px: calc(557.9 * var(--u));
    --pc-font: calc(22.46 * var(--u)); /* 12px in the 366 frame */
    aspect-ratio: 366 / 248;
  }

  .pc-head {
    top: calc((41.2 - var(--stage-top)) * var(--u));
    height: auto;
  }

  .pc-blurb {
    line-height: 1.25;
    text-wrap: wrap;
  }

  .pc-string,
  .pc-br {
    display: none;
  }

  .ft-pc.is-lifted .pc-card {
    translate: 0 calc(-146.02 * var(--u));
  }

  /* The loose stamps wait below the module and fly up into place as the
     card lifts (none show at rest in the mobile design) */
  .pc-loose {
    width: calc(100.7 * var(--u));
    height: calc(120.75 * var(--u));
    margin: calc(-60.38 * var(--u)) 0 0 calc(-50.35 * var(--u));
  }

  .pc-loose.is-green { left: calc(173.27 * var(--u)); top: calc(167.67 * var(--u)); rotate: -19.6deg; translate: 0 calc(400 * var(--u)); }
  .pc-loose.is-red { left: calc(792.12 * var(--u)); top: calc(364.95 * var(--u)); rotate: -20.9deg; translate: 0 calc(220 * var(--u)); }
  .pc-loose.is-yellow { left: calc(158.94 * var(--u)); top: calc(373.39 * var(--u)); rotate: 23.4deg; translate: 0 calc(220 * var(--u)); }

  .ft-pc.is-lifted .pc-loose.is-green { translate: 0 0; rotate: -19.6deg; }
  .ft-pc.is-lifted .pc-loose.is-red { translate: 0 0; rotate: -20.9deg; }
  .ft-pc.is-lifted .pc-loose.is-yellow { translate: 0 0; rotate: 23.4deg; }
}

@media (prefers-reduced-motion: reduce) {
  .ft-pc .pc-card,
  .pc-loose,
  .pc-blurb,
  .pc-string,
  .lk-email,
  .lk-insta,
  .lk-arena,
  .lk-pocket {
    transition-duration: .01s !important;
    transition-delay: 0s !important;
  }
}
