:root {
  --bg: #f7f1e8;
  --card: #fffaf3;
  --ink: #3b2416;
  --muted: #a08c78;
  --line: #e6d9c6;
  --watermelon: #f0607a;
  --turquoise: #36c2c0;
  --size: min(19vh, 23vw);
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: var(--bg);
  color: var(--ink);
  font-family: "Outfit", system-ui, sans-serif;
}

/* The title is carried in like a sign, then floats up to the top. Its
   position is set in pixels from main.js. */
.title {
  position: fixed;
  left: 0;
  top: 0;
  margin: 0;
  font-family: "Slackey", "Outfit", system-ui, sans-serif;
  font-size: clamp(70px, 13.5vw, 176px);
  font-weight: 400;
  line-height: 1;
  letter-spacing: 0.01em;
  color: var(--ink);
  white-space: nowrap;
  text-shadow: 0.04em 0.04em 0 var(--turquoise);
  transform-origin: 50% 100%;
  visibility: hidden;
  pointer-events: none;
}

.title.shown {
  visibility: visible;
}

/* Floating up eases out slowly, like a balloon coming to rest. */
.title.floating {
  transition: transform 2600ms cubic-bezier(0.22, 1, 0.36, 1);
}

.title-text {
  display: inline-block;
  transform-origin: 50% 0;
}

/* The laundry line along the top holds a photo of every mawilo. Photos of
   mawilos on the board are in colour, and all others are faded. */
.line {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: var(--line-h, 120px);
  z-index: 900;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  touch-action: pan-x;
  transform: translateY(-110%);
  transition: transform 1600ms cubic-bezier(0.5, 0, 0.3, 1.15);
}

.line::-webkit-scrollbar {
  display: none;
}

.line-shown .line {
  transform: none;
}

.line-inner {
  position: relative;
  height: 100%;
}

.string {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.string path {
  stroke: var(--muted);
  stroke-width: 1.5;
}

.polaroid {
  position: absolute;
  padding: 0;
  border: 0;
  background: none;
  transform: translateX(-50%);
  transform-origin: 50% 0;
  cursor: pointer;
}

.polaroid-frame {
  position: relative;
  display: block;
  padding: 4px 4px 12px;
  background: #fff;
  box-shadow: 0 2px 5px rgb(59 36 22 / 0.18);
  transform: rotate(var(--pr, 0deg));
  transform-origin: 50% 0;
  transition: box-shadow 400ms ease;
}

.polaroid img {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  object-fit: contain;
  background: #f3ebde;
  transition: filter 700ms ease, opacity 700ms ease;
}

.polaroid.offstage img {
  filter: grayscale(1) contrast(0.8) brightness(1.08);
}

/* A wooden clothes peg holds each photo on the line. */
.peg {
  position: absolute;
  z-index: 2;
  top: calc(var(--photo, 60px) * -0.22);
  left: 50%;
  width: calc(var(--photo, 60px) * 0.2);
  height: calc(var(--photo, 60px) * 0.46);
  transform: translateX(-50%);
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 32'%3E%3Cdefs%3E%3ClinearGradient id='w' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='%23e8c08a'/%3E%3Cstop offset='0.55' stop-color='%23d39f62'/%3E%3Cstop offset='1' stop-color='%23a9733d'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath d='M1.6 1.2h5v27.3c0 1.6-1.1 2.3-2.5 2.3S1.6 30.1 1.6 28.5z' fill='url(%23w)' stroke='%23946232' stroke-width='0.5'/%3E%3Cpath d='M7.4 1.2h5v27.3c0 1.6-1.1 2.3-2.5 2.3S7.4 30.1 7.4 28.5z' fill='url(%23w)' stroke='%23946232' stroke-width='0.5'/%3E%3Cpath d='M3 6.5c1 .3 2 .3 3 0M8.8 6.5c1 .3 2 .3 3 0M3 22c1 .3 2 .3 3 0M8.8 22c1 .3 2 .3 3 0' fill='none' stroke='%23b07a43' stroke-width='0.4'/%3E%3Crect x='0.6' y='11' width='12.8' height='5' rx='2.2' fill='%23c9ced4' stroke='%2378808a' stroke-width='0.6'/%3E%3Cpath d='M2.6 11.4v4.2M4.6 11.4v4.2M6.6 11.4v4.2M8.6 11.4v4.2M10.6 11.4v4.2' stroke='%238a929c' stroke-width='0.55'/%3E%3C/svg%3E") center / contain no-repeat;
  filter: drop-shadow(0 1px 1px rgb(0 0 0 / 0.25));
}

/* The photo of the mawilo being handled or pointed at lifts, grows a
   little and glows turquoise. */
.polaroid-frame {
  transition:
    scale 300ms cubic-bezier(0.34, 1.4, 0.64, 1),
    translate 300ms ease,
    filter 300ms ease;
}

.polaroid.active,
.polaroid.selected {
  z-index: 1;
}

.polaroid.active .polaroid-frame,
.polaroid.selected .polaroid-frame {
  scale: 1.15;
  translate: 0 4px;
  filter: drop-shadow(0 0 7px rgb(54 194 192 / 0.85)) saturate(1.2);
}

.polaroid:focus-visible .polaroid-frame {
  outline: 2px solid var(--turquoise);
  outline-offset: 3px;
}

.board {
  position: fixed;
  inset: 0;
  touch-action: none;
}

/* Registered so that the waddle can grow and shrink smoothly. */
@property --amp {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}

/* A mawilo is placed by its centre point, stored as a fraction of the
   board in --x and --y. */
.mawilo {
  --turn-cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 28 28'%3E%3Cpath d='M21 9a9 9 0 1 0 1.5 8' fill='none' stroke='%23fff' stroke-width='5' stroke-linecap='round'/%3E%3Cpath d='M21 9a9 9 0 1 0 1.5 8' fill='none' stroke='%233b2416' stroke-width='2' stroke-linecap='round'/%3E%3Cpath d='M23 3v7h-7' fill='none' stroke='%23fff' stroke-width='5' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M23 3v7h-7' fill='none' stroke='%233b2416' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") 14 14;
  position: absolute;
  left: calc(var(--x) * 100%);
  top: calc(var(--y) * 100%);
  height: calc(var(--size) * var(--s, 1));
  transform: translate(-50%, -50%) rotate(var(--r, 0deg)) scale(1);
  transition: transform 500ms cubic-bezier(0.34, 1.4, 0.64, 1);
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
}

/* Lift a little under the mouse. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .mawilo:hover:not(.lifted, .turning, .walking, .marching, .popping, .sinking) {
    transform: translate(-50%, -50%) rotate(var(--r, 0deg)) scale(1.025);
  }

  .mawilo:hover:not(.lifted) img {
    filter: drop-shadow(0 5px 5px rgb(59 36 22 / 0.2));
  }
}

.mawilo.edge-zone {
  cursor: var(--turn-cursor), alias;
}

.mawilo img {
  display: block;
  height: 100%;
  width: auto;
  transform-origin: 50% 90%;
  filter: drop-shadow(0 3px 3px rgb(59 36 22 / 0.18));
  transition:
    filter 250ms ease,
    --amp 700ms ease-out;
  pointer-events: none;
  -webkit-user-drag: none;
}

.mawilo.lifted {
  cursor: grabbing;
  transform: translate(-50%, -50%) rotate(calc(var(--r, 0deg) + var(--tilt, 0deg))) scale(1.06);
  transition: transform 120ms ease-out;
}

/* A figure pulled in from the edge keeps its size and angle. */
.mawilo.lifted.from-edge {
  transform: translate(-50%, -50%) rotate(var(--r, 0deg)) scale(1);
}

.mawilo.lifted img {
  filter: drop-shadow(0 14px 12px rgb(59 36 22 / 0.22));
}

.mawilo.turning {
  cursor: var(--turn-cursor), alias;
  transform: translate(-50%, -50%) rotate(var(--r, 0deg)) scale(1.02);
  transition: transform 60ms linear;
}

/* Walking in or out from a side. The figure eases into and out of each
   move while its image rocks gently from foot to foot. The rocking grows
   at the start and dies away at the end through --amp. */
.mawilo.walking {
  transition:
    left var(--dur) cubic-bezier(0.45, 0.05, 0.4, 1),
    top var(--dur) cubic-bezier(0.45, 0.05, 0.4, 1),
    transform 500ms ease;
}

.mawilo.walking img {
  --amp: 3;
  animation: waddle 520ms ease-in-out infinite alternate;
}

.mawilo.walking.slowing img {
  --amp: 0;
}

@keyframes waddle {
  from {
    transform: rotate(calc(var(--amp) * -1deg)) translateY(0);
  }
  to {
    transform: rotate(calc(var(--amp) * 1deg)) translateY(calc(var(--amp) * -0.6%));
  }
}

/* Marching: a steady climb with short, firm up-and-down steps. */
.mawilo.marching {
  transition:
    top var(--dur) linear,
    transform 500ms ease;
}

.mawilo.marching img {
  --amp: 5;
  animation: march 240ms ease-in-out infinite alternate;
}

.mawilo.marching.slowing img {
  --amp: 0;
}

@keyframes march {
  from {
    transform: translateY(0) rotate(calc(var(--amp) * -0.3deg));
  }
  to {
    transform: translateY(calc(var(--amp) * -1%)) rotate(calc(var(--amp) * 0.3deg));
  }
}

/* Popping up from or down to the bottom edge, with a small overshoot. */
.mawilo.popping {
  transition:
    top var(--dur) cubic-bezier(0.34, 1.3, 0.64, 1),
    transform 500ms ease;
}

.mawilo.sinking {
  transition:
    top var(--dur) cubic-bezier(0.55, 0, 0.75, 0.3),
    transform 500ms ease;
}

/* Card */

.card {
  position: fixed;
  left: 50%;
  bottom: 24px;
  z-index: 2000;
  width: min(820px, calc(100% - 32px));
  max-height: calc(100dvh - 48px);
  overflow-y: auto;
  display: grid;
  grid-template-columns: 40% 1fr;
  align-items: center;
  gap: 28px;
  padding: 32px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 20px;
  box-shadow: 0 20px 50px rgb(59 36 22 / 0.18);
  transform: translate(-50%, calc(100% + 40px));
  transition: transform 550ms cubic-bezier(0.65, 0, 0.35, 1);
}

.card[hidden] {
  display: grid;
  visibility: hidden;
}

/* The card starts slowly, speeds up, and slows down again as it stops. */
.card.open {
  transform: translate(-50%, 0);
  transition: transform 800ms cubic-bezier(0.65, 0, 0.35, 1);
}

/* The picture is a stack of two big instant photos with the name written
   on their wide bottom edge: the cut-out, and behind it the original photo,
   tilted the other way so it peeks out. */
.card-picture {
  padding: 10px 16px 14px 6px;
}

.card-flip {
  position: relative;
}

.card-photo {
  position: relative;
  margin: 0;
  padding: 12px 12px 0;
  background: #fff;
  box-shadow:
    0 1px 2px rgb(59 36 22 / 0.12),
    0 10px 24px rgb(59 36 22 / 0.18);
  transform: translate(14px, -8px) rotate(5deg);
}

.card-photo.back {
  position: absolute;
  inset: 0;
}

.card-photo.on-top {
  z-index: 1;
  transform: rotate(-2.5deg);
}

.card-photo img {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  object-fit: contain;
  background: #f3ebde;
}

.card-photo.back img {
  object-fit: cover;
}

.card-photo h2,
.card-photo-name {
  display: block;
  margin: 0;
  padding: 10px 4px 14px;
  text-align: center;
  white-space: nowrap;
  font-family: "Slackey", "Outfit", system-ui, sans-serif;
  font-size: 30px;
  font-weight: 400;
  line-height: 1.2;
  color: var(--ink);
}

.card-description {
  margin: 0 0 8px;
  font-size: 18px;
  line-height: 1.4;
}

.card-description:empty {
  display: none;
}

.card-fabrics {
  margin: 0 0 12px;
  color: var(--muted);
  font-size: 17px;
  line-height: 1.4;
}

.card-story {
  margin: 0 0 14px;
  font-size: 18px;
  line-height: 1.55;
}

.card-story:empty {
  display: none;
}

.card-toggle {
  padding: 6px 14px;
  border: 2px solid var(--turquoise);
  border-radius: 999px;
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: 15px;
  cursor: pointer;
}

.card-toggle:hover {
  background: var(--turquoise);
  color: var(--card);
}

.card-close {
  position: absolute;
  top: 8px;
  right: 10px;
  width: 36px;
  height: 36px;
  border: 0;
  background: none;
  color: var(--muted);
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
}

.card-close:hover {
  color: var(--watermelon);
}

@media (max-width: 520px) {
  .card {
    grid-template-columns: 1fr;
    gap: 16px;
    bottom: 16px;
    max-height: calc(100dvh - 32px);
    padding: 24px;
  }

  .card-picture {
    width: min(62%, 30vh);
    justify-self: center;
  }

  .card-photo h2,
  .card-photo-name {
    font-size: 21px;
    padding: 8px 4px 10px;
  }

    .card-story {
    font-size: 17px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .mawilo,
  .mawilo.lifted,
  .mawilo.walking,
  .mawilo.marching,
  .mawilo.popping,
  .mawilo.sinking,
  .mawilo.turning,
  .card,
  .card.open,
  .title.floating,
  .line {
    transition: none;
  }

  .mawilo.walking img,
  .mawilo.marching img {
    animation: none;
  }
}
