/* GLOBAL STYLE  */
@font-face {
  /* Font family name */
  font-family: "Cutive Mono";
  src: url("../assets/fonts/CutiveMono-Regular.ttf") format("truetype");
  font-weight: normal;
  font-style: normal;
}

html {
  font-family: "Cutive Mono", monospace;
  line-height: 1.2; /* compact lines everywhere (windows, Clippy's bubble) */
}

/* SCENE: plant, earth, spray and notebook stand in the room, same place on every page.
   .menu itself has no position, so each icon gets its own z-index */

/* the floor line: plant, spray, notebook and Clippy all stand on it (bigger = higher) */
:root {
  --floor: 3dvh;

  /* STAGE: the design was made on a 1480 x 953 screen. the stage keeps that shape and is as big
     as fits in the window, so everything in it grows and shrinks together, whatever the window's shape.
     --u = 1% of the stage width, --v = 1% of the stage height (for things outside the stage: plant, icons, Clippy) */
  --stage-w: min(100vw, 155.3dvh);
  --stage-h: calc(var(--stage-w) / 1.553);
  --u: calc(var(--stage-w) / 100);
  --v: calc(var(--stage-h) / 100);
}

/* the stage: main, centred in the window. everything inside is placed in stage units
   (cqw = 1% of its width, cqh = 1% of its height), fixed windows are placed inside it too */
#swup {
  position: fixed;
  left: calc((100vw - var(--stage-w)) / 2);
  top: calc((100dvh - var(--stage-h)) / 2);
  width: var(--stage-w);
  height: var(--stage-h);
  container-type: size;
  contain: layout; /* fixed windows inside are placed in the stage, not in the browser window */
  z-index: 5; /* above the room, below the floor objects and Clippy */
  pointer-events: none; /* the empty stage lets clicks through to the plant and icons */
}

#swup > * {
  pointer-events: auto;
}

/* the earth (home link): on the floor, left of Clippy */
.earth {
  position: fixed;
  bottom: 3%;
  right: calc(8vw + 9 * var(--u)); /* always just left of Clippy */
  z-index: 95; /* above the plant (90), so it can always be clicked (Clippy stays above at 100) */
  display: block;
}

/* spray and notebook: on the floor, right next to the pot.
   the plant starts at 5vw and is 24dvh wide; the pot ends at about 3/4 of that */
.spray-icon,
.notebook-icon {
  position: fixed;
  bottom: var(--floor);
  z-index: 95; /* above the plant (90): its picture box covers the spray, clicks must still reach it */
  display: block; /* the button wraps the icon, so it can have a shadow */
  /* no default button look: only the picture shows */
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  color: inherit;
}

/* HOVER (plant, earth, spray, notebook): no wiggle. they grow a little, once, smoothly,
   from their base, so they keep standing on the floor */
.spray-icon:hover,
.notebook-icon:hover {
  animation: none;
}

.earth .icon,
.spray-icon .icon,
.notebook-icon .icon {
  transform-origin: 50% 100%;
  transition: scale 300ms ease;
}

.earth:hover .icon,
.spray-icon:hover .icon,
.notebook-icon:hover .icon {
  scale: 1.08;
}

.plant:hover img {
  scale: 1.04;
}

.spray-icon .icon,
.notebook-icon .icon {
  display: block; /* no gap under the picture */
}

.spray-icon {
  left: calc(
    2vw + 18 * var(--v) - 0.5 * var(--u)
  ); /* right after the pot (the plant stands at 2vw); the png has empty space on the sides */
  rotate: 5deg;
}

/* the notebook: right after the spray, twice the size of before, so it reads as something to click */
.notebook-icon {
  left: calc(2vw + 18 * var(--v) + 4 * var(--u));
  bottom: calc(
    var(--floor) - 1.2 * var(--u)
  ); /* the png has empty space under the notebook */
}

.notebook-icon .icon {
  width: calc(10 * var(--u));
}

.icon {
  width: calc(6 * var(--u));
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: pointer;
  transition: all 0.3s ease-in-out;
}

.room {
  position: fixed;
  width: 100vw;
  height: 100dvh;
  box-sizing: border-box;
  overflow: hidden;
}

.room-lines {
  position: fixed; /* pinned to the viewport, doesn't scroll */
  inset: 0; /* stretch over the whole screen */
  width: 100%;
  height: 100%;
  pointer-events: none; /* clicks pass through to content */
  z-index: 0;
}

.room-lines rect,
.room-lines line {
  fill: none;
  stroke: #4a9a2a;
  stroke-width: 2;
  vector-effect: non-scaling-stroke; /* keeps lines 2px thick at any size */
}

/* floor squares (made in script.js): quieter than the room lines */
.room-lines .floor-line {
  stroke-width: 1;
  opacity: 0.4;
}

/* wall glow (made in script.js): only the gradient, no green outline */
.room-lines .wall-glow {
  fill: url(#wall-glow);
  stroke: none;
}

.room-lines .wall-glow-left {
  fill: url(#wall-glow-left);
}

.room-lines .wall-glow-right {
  fill: url(#wall-glow-right);
}

/* ------ PROJECTS: ICONS MAIN SCREEN------ */

.project-card {
  position: absolute;
  z-index: 2;
}

.project-card:hover {
  animation: wiggle 0.5s ease-in-out infinite;
}

@keyframes wiggle {
  0% {
    rotate: 0deg;
    translate: 0 0;
  }

  25% {
    rotate: -2deg;
    translate: -5px 0;
  }

  80% {
    rotate: 2deg;
    translate: 5px 0;
  }
}

.project-card img {
  width: 100%;
  height: auto;
  display: block;
}

.margot {
  top: 72%;
  left: 55%;
  width: 21.2cqw; /* 314px on the design screen */
}

.rhetoric {
  top: 15%;
  left: 10%;
  width: 27.4cqw; /* 406px on the design screen */
}

.my-fragmented-self {
  height: 30cqh;
  top: 55%;
  left: 20%;
}

.body-input {
  height: 22cqh;
  top: 14%;
  left: 60%;
  rotate: 10deg;
}

.term-woman-objects {
  top: 30%;
  left: 45%;
  width: 27.03cqw;
  rotate: 5deg;
}

.posters {
  height: 20cqh; /* close to the other icons' size */
  top: 38%; /* middle of the screen, on the right */
  right: 11%;
  rotate: -6deg;
}

.plant {
  position: fixed;
  z-index: 90; /* always above everything, only Clippy (100) is higher */
  left: 2vw;
  bottom: var(--floor);
}

/* (the plant's size is in stage units, see .plant img) */

.plant img {
  height: calc(30 * var(--v));
  display: block;
  transform-origin: 44% 100%; /* tilts over the pot's bottom-left edge */
  transition:
    rotate 600ms ease,
    scale 300ms ease;
}

/* on a project page the plant tilts 30deg to the left (the shadow stays on the floor) */
.is-project .plant img {
  rotate: -10deg;
}

/* SHADOWS: a soft spot on the floor, right under the base of each object,
   a little wider than the base, so it looks like it stands there */
.plant::after,
.earth::after,
.clippy::after,
.spray-icon::after,
.notebook-icon::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 60%;
  height: 16px;
  translate: -50% 35%; /* mostly behind the base, a bit peeks out below */
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(0, 0, 0, 0.22), transparent);
  z-index: -1; /* behind the picture */
  pointer-events: none;
}

.plant::after {
  left: 56%; /* the pot is a bit right of the png's middle */
  width: 38%; /* just wider than the pot */
}

.earth::after {
  bottom: 13%; /* the globe ends above the bottom of the png */
  width: 55%;
}

.clippy::after {
  width: 80%;
}

.spray-icon::after {
  width: 45%; /* the can is thin */
}

.notebook-icon::after {
  /* the notebook lies at an angle: the shadow sits right under its front edge, turned the same way */
  left: 66%;
  bottom: 18%;
  width: 62%;
  rotate: -18deg;
}

/* ------ CLIPPY ------ */

.clippy {
  position: fixed;
  right: 8vw;
  bottom: var(--floor); /* stands on the same floor line as the plant */
  z-index: 100; /* Clippy + bubble always on top of everything */
}

.clippy svg {
  width: 100%;
  height: auto;
  display: block;
  width: calc(8 * var(--u));
}

.bubble {
  position: absolute;
  bottom: calc(
    100% + 16px
  ); /* sits above Clippy, the tail reaches down to his head */
  right: 50%;
  white-space: normal; /* text wraps onto the next line */
  box-sizing: border-box; /* padding + border stay inside the 20vw */
  padding: 8px 8px;
  background: #ffffff;
  border: 2px solid #0d00ff;
  color: #0d00ff;
  width: calc(20 * var(--u));
  font-size: max(11px, calc(1.08 * var(--u))); /* 16px on the design screen, grows and shrinks with it */
}

/* TAIL: a comic-style point under the bubble, towards Clippy.
   straight on the right, slanted on the left.
   drawn as one small SVG with a 2px line, so both lines are as thick as the bubble's border.
   the white part covers the bubble's bottom line there, so the tail opens into the bubble */
.bubble::after {
  content: "";
  position: absolute;
  top: 100%; /* starts on the bubble's bottom border */
  right: 14px; /* where along the bottom the tail sits (bigger = further left) */
  width: 24px;
  height: 24px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpolygon points='0,0 22,0 22,20' fill='white'/%3E%3Cpolyline points='0,1 23,21 23,0' fill='none' stroke='%230d00ff' stroke-width='2'/%3E%3C/svg%3E")
    no-repeat;
}

/* animation */

button:hover {
  animation: wiggle 0.2s ease-in-out infinite;
}

@keyframes wiggle {
  0% {
    rotate: 0deg;
    translate: 0 0;
  }

  25% {
    rotate: -2deg;
    translate: -5px 0;
  }

  80% {
    rotate: 2deg;
    translate: 5px 0;
  }

  100% {
    rotate: 0deg;
    translate: 0 0;
  }
}

/* WOBBLY LETTERS */

/* needed for every wobbly letter */
.word {
  display: inline-block;
  white-space: nowrap;
} /* words don't break apart */
.letter {
  display: inline-block;
} /* letters can rotate */

/* project titles: uppercase, wide spacing */
.projects li {
  text-transform: uppercase;
  letter-spacing: 0.15em;
  text-align: center;
  list-style: none;
  font-size: max(10px, 1.486cqw);
  margin-bottom: 14px;
}

/* ( news ), ( projects ) */
.label {
  letter-spacing: 0.3em;
  font-weight: normal;
  font-size: max(10px, 1.081cqw);
}

/* whole paragraph slightly tilted */
.tilt {
  transform: rotate(1deg);
}

/* vertical label: one letter per line */
.vertical .word {
  white-space: normal;
}
.vertical .letter {
  display: block;
  text-align: center;
}

/* PROJECT HOVER */
.project-card {
  transition:
    scale 250ms ease 0s,
    rotate 250ms ease 250ms,
    translate 250ms ease 500ms,
    /* All `transform` transitions will happen over 750ms and start immediately. */
    transform 750ms ease 0s;
  cursor: pointer;
}
.scale:is(.scale:is(:click, :focus), :focus) {
  scale: 2;
}

/* MARGOT PHOTO (only on projects/margot): just the photo, no frame */
.margot-photo {
  position: fixed;
  top: 15cqh;
  left: 10.81cqw;
  z-index: 2; /* above the fixed .room */
}

.margot-photo > img {
  height: 70cqh;
  display: block; /* removes the small gap under images */
  /* floats a little above the room, same shadow as the windows */
  filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.12)) drop-shadow(0 10px 28px rgba(0, 0, 0, 0.18));
}

/* the cursor shows where a click goes: left page = previous, right page = next */
.margot-photo > img.go-prev {
  cursor:
    url("../assets/icons/cursor-prev.png") 1 30,
    w-resize !important;
}

.margot-photo > img.go-next {
  cursor:
    url("../assets/icons/cursor-next.png") 68 31,
    e-resize !important;
}

/* WOMEN LAYOUT (only on projects/women-layout) */
/* every image looks like a selected frame in a layout program:
   blue outline, blue X from corner to corner, 8 white square handles */

/* the frame look (blue border, X, handles), shared by Term: Woman, the body.input photos
   and the 3 small poster photos */
.women-layout,
.bi-img,
.poster-small {
  --wl-blue: #1a8fe0;
  /* one little white square with a blue border, used 8 times below */
  --wl-handle: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'%3E%3Crect x='1' y='1' width='12' height='12' fill='white' stroke='%231a8fe0' stroke-width='2'/%3E%3C/svg%3E");
}

.women-layout {
  /* exactly the green back wall of the room (rect x=8 y=8 w=84 h=85) */
  position: fixed;
  top: 8cqh;
  left: 8cqw;
  width: 84cqw;
  height: 85cqh;
  overflow: hidden; /* nothing leaves the rectangle */
  z-index: 2; /* above the fixed .room */
}

/* every frame is placed freely inside the rectangle.
   --x and --y go from 0 to 1: 0 = left/top edge, 1 = right/bottom edge.
   the formula keeps the whole frame inside, whatever its size.
   .wl-frame  = the small, invisible hover area (never changes size)
   .wl-inner  = what you see: border, X, handles, image (this one grows) */
.wl-frame {
  --pad: 12px; /* keeps the handles off the green lines */
  --s: 14cqh; /* small frame height */
  --r: 1; /* image width / height (1 = square) */
  position: absolute;
  left: calc(var(--pad) + (100% - 2 * var(--pad) - var(--s)) * var(--x));
  top: calc(var(--pad) + (100% - 2 * var(--pad) - var(--s)) * var(--y));
  width: calc(var(--s) * var(--r) + 4px);
  height: calc(var(--s) + 4px);
  margin: 0;
}

.wl-inner {
  --h: var(--s); /* shown height: small, or big on hover */
  position: absolute;
  /* grows away from the rectangle edge it is close to, so it stays inside */
  left: calc((var(--s) - var(--h)) * var(--r) * var(--x));
  top: calc((var(--s) - var(--h)) * var(--y));
  border: 2px solid var(--wl-blue);
  pointer-events: none; /* the big image doesn't keep the hover */
  transition:
    left 300ms ease,
    top 300ms ease;
}

.wl-inner img {
  height: var(--h);
  width: auto; /* keeps each image's own shape */
  display: block;
  transition: height 300ms ease;
}

/* the blue X */
.wl-inner::before,
.bi-img::before,
.ps-inner::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(
      to top right,
      transparent calc(50% - 1px),
      var(--wl-blue) 50%,
      transparent calc(50% + 1px)
    ),
    linear-gradient(
      to bottom right,
      transparent calc(50% - 1px),
      var(--wl-blue) 50%,
      transparent calc(50% + 1px)
    );
  transition: opacity 200ms ease;
}

/* the 8 handles: 4 corners + 4 middles of each side */
.wl-inner::after,
.bi-img::after,
.ps-inner::after {
  content: "";
  position: absolute;
  inset: -8px; /* handles sit centred on the border */
  background-image:
    var(--wl-handle), var(--wl-handle), var(--wl-handle), var(--wl-handle),
    var(--wl-handle), var(--wl-handle), var(--wl-handle), var(--wl-handle);
  background-position:
    0 0,
    50% 0,
    100% 0,
    0 50%,
    100% 50%,
    0 100%,
    50% 100%,
    100% 100%;
  background-size: 14px 14px;
  background-repeat: no-repeat;
}

/* each frame: its own size (--s) and spot (--x, --y) */
.wl-frame:nth-child(1) {
  --s: min(20cqh, 11.2cqw);
  --x: 0.73;
  --y: 0.81;
  --r: 0.503;
}
.wl-frame:nth-child(2) {
  --s: min(12cqh, 6.72cqw);
  --x: 0.02;
  --y: 0.3;
}
.wl-frame:nth-child(3) {
  --s: min(17cqh, 9.52cqw);
  --x: 0.36;
  --y: 0.47;
}
.wl-frame:nth-child(4) {
  --s: min(10.5cqh, 5.88cqw);
  --x: 0.57;
  --y: 0.02;
}
.wl-frame:nth-child(5) {
  --s: min(18.5cqh, 10.36cqw);
  --x: 0.85;
  --y: 0.99;
}
.wl-frame:nth-child(6) {
  --s: min(13cqh, 7.28cqw);
  --x: 0.06;
  --y: 0.06;
}
.wl-frame:nth-child(7) {
  --s: min(15.5cqh, 8.68cqw);
  --x: 0.31;
  --y: 0.02;
}
.wl-frame:nth-child(8) {
  --s: min(11.5cqh, 6.44cqw);
  --x: 0.4;
  --y: 0.7;
}
.wl-frame:nth-child(9) {
  --s: min(18cqh, 10.08cqw);
  --x: 0.74;
  --y: 0.47;
}
.wl-frame:nth-child(10) {
  --s: min(14.5cqh, 8.12cqw);
  --x: 0.15;
  --y: 0.28;
}
.wl-frame:nth-child(11) {
  --s: min(12.5cqh, 7cqw);
  --x: 0.01;
  --y: 0.5;
}
.wl-frame:nth-child(12) {
  --s: min(20.5cqh, 11.48cqw);
  --x: 0.56;
  --y: 0.45;
}
.wl-frame:nth-child(13) {
  --s: min(11cqh, 6.16cqw);
  --x: 1;
  --y: 0.47;
}
.wl-frame:nth-child(14) {
  --s: min(16.5cqh, 9.24cqw);
  --x: 0.72;
  --y: 0.18;
}
.wl-frame:nth-child(15) {
  --s: min(14cqh, 7.84cqw);
  --x: 1;
  --y: 0.23;
}
.wl-frame:nth-child(16) {
  --s: min(19cqh, 10.64cqw);
  --x: 0.56;
  --y: 0.87;
}
.wl-frame:nth-child(17) {
  --s: min(10cqh, 5.6cqw);
  --x: 0.57;
  --y: 0.19;
}
.wl-frame:nth-child(18) {
  --s: min(16cqh, 8.96cqw);
  --x: 0.86;
  --y: 0.08;
}
.wl-frame:nth-child(19) {
  --s: min(13cqh, 7.28cqw);
  --x: 0.98;
  --y: 0.01;
}
.wl-frame:nth-child(20) {
  --s: min(17.5cqh, 9.8cqw);
  --x: 0.45;
  --y: 0.13;
}
.wl-frame:nth-child(21) {
  --s: min(11.5cqh, 6.44cqw);
  --x: 0.12;
  --y: 0.5;
}
.wl-frame:nth-child(22) {
  --s: min(15cqh, 8.4cqw);
  --x: 0.18;
  --y: 0.03;
}
.wl-frame:nth-child(23) {
  --s: min(16.5cqh, 9.24cqw);
  --x: 0.9;
  --y: 0.48;
}

/* hover (only over the small frame): the image grows to almost the
   height of the rectangle and the blue X fades away */
.wl-frame:hover {
  z-index: 10; /* on top of the other frames */
}

.wl-frame:hover .wl-inner {
  --h: min(75cqh, 78cqw);
}

.wl-frame:hover .wl-inner::before,
.bi-img:hover::before,
.ps-frame:hover .ps-inner::before {
  opacity: 0;
}

/* VIDEO WINDOW (women-layout): bottom left inside the green rectangle */
/* bars are bright red, everything on them is light */
.wl-video {
  --red: #ff3939;
  --light: #ffe3e3;
  position: absolute;
  left: 12px;
  bottom: 12px;
  z-index: 5; /* above the frames (a hovered frame still goes on top) */
  border: 2px solid var(--red);
  background: var(--red);
  font-family: "Cutive Mono", monospace; /* your font */
}

.wl-video .card-bar {
  height: 20px;
  background: var(--red);
  display: flex;
  justify-content: space-between; /* title left, × right */
  align-items: center;
  padding: 0 6px;
  color: var(--light);
  font-size: max(10px, 0.811cqw);
}

.wl-video .card-close {
  background: none;
  border: none;
  color: var(--light);
  font-size: max(10px, 0.946cqw);
  cursor: pointer;
  padding: 0;
}

/* player */
.player {
  background: black;
}

.player-video {
  height: 25.5cqh; /* 30% of the rectangle (85dvh) */
  width: auto;
  aspect-ratio: 16 / 9;
  display: block;
  cursor: pointer;
}

.player-controls {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 8px;
  background: var(--red);
  color: var(--light);
  font-size: max(10px, 0.811cqw);
}

.player-controls button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  padding: 0;
  background: none;
  border: 1px solid var(--light);
  color: var(--light);
  cursor: pointer;
}

.player-controls button:hover {
  background: var(--light);
  color: var(--red);
  animation: none; /* no wiggle on player buttons */
}

/* small icons: filled shapes + thin lines, all in the button's colour */
.player-controls .icon {
  width: 12px;
  height: 12px;
  fill: currentColor;
}

.player-controls .icon .line {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
}

/* show ▶ when paused, ❚❚ when playing; crossed speaker when muted */
.player:not(.is-paused) .icon-play,
.player.is-paused .icon-pause,
.player.is-muted .icon-sound,
.player:not(.is-muted) .icon-muted {
  display: none;
}

.progress {
  flex: 1;
  height: 8px;
  border: 1px solid var(--light);
  background: none;
  cursor: pointer;
}

.progress-fill {
  height: 100%;
  width: 0%;
  background: var(--light);
}

/* fullscreen: make the video fill the screen */
.player:fullscreen {
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.player:fullscreen .player-video {
  flex: 1;
  height: auto;
  width: 100%;
  aspect-ratio: auto;
  object-fit: contain;
}

/* RHETORIC SLIDESHOW (only on projects/rhetorics) */
/* sits in the green rectangle, left of Clippy's bubble */
.rhetoric-slideshow {
  position: fixed;
  top: 8cqh;
  left: 8cqw;
  width: 60cqw;
  height: 85cqh;
  z-index: 2; /* above the fixed .room */
  display: flex;
  align-items: center;
  justify-content: center;
}

.rhetoric-slideshow img {
  position: absolute; /* all images in the same spot, new ones on top */
  top: 50%;
  left: 50%;
  translate: -50% -50%; /* centred (script.js adds a small random shift) */
  max-width: 90%; /* a bit bigger than before (80% / 65cqh) */
  max-height: 75cqh;
  display: block;
}

/* RHETORIC: pause / play, a thin circle on the images (like the instagram circle) */
.rh-pause {
  position: fixed;
  top: 73cqh; /* lower: on the bottom-right corner of the images */
  left: 57cqw;
  width: 9cqw;
  aspect-ratio: 1; /* always round */
  z-index: 3; /* above the images */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid #ff3939;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.85); /* readable over the images */
  color: #ff3939;
  font-family: "Cutive Mono", monospace;
  font-size: 1.4cqw;
  cursor: pointer;
  transition:
    scale 300ms ease,
    background 300ms ease;
}

/* hover: no shaking, it only grows a little, once, smoothly */
.rh-pause:hover {
  animation: none;
  scale: 1.08;
  background: #ffe3e3;
}

/* ERROR POP-UP (posters): same colours as the video player */
.error-popup {
  --red: #ff3939;
  --light: #ffe3e3;
  position: fixed;
  top: 50%;
  left: 50%;
  translate: -50% -50%; /* centred (copies get shifted by script.js) */
  z-index: 60; /* above the room and the menu, below Clippy */
  width: 280px;
  border: 2px solid var(--red);
  background: var(--red);
  color: var(--light);
  font-family: "Cutive Mono", monospace;
}

.error-bar {
  height: 20px;
  display: flex;
  justify-content: space-between; /* title left, × right */
  align-items: center;
  padding: 0 6px;
  border-bottom: 1px solid var(--light);
  font-size: max(10px, 0.811cqw);
}

.error-close {
  background: none;
  border: none;
  color: var(--light);
  font-size: max(10px, 0.946cqw);
  cursor: pointer;
  padding: 0;
}

.error-body {
  padding: 16px 12px 12px;
  font-size: max(10px, 0.946cqw);
  text-align: center;
}

.error-buttons {
  display: flex;
  justify-content: center;
  gap: 12px;
  margin-top: 16px;
}

.error-buttons button {
  background: none;
  border: 1px solid var(--light);
  color: var(--light);
  font-family: inherit;
  font-size: max(10px, 0.811cqw);
  padding: 3px 14px;
  cursor: pointer;
}

.error-buttons button:hover,
.error-close:hover {
  background: var(--light);
  color: var(--red);
  animation: none; /* no wiggle, like the player buttons */
}

/* POSTERS PAGE: windows in the same style as the video player */
.poster-window {
  --red: #ff3939;
  --light: #ffe3e3;
  position: absolute;
  border: 2px solid var(--red);
  background: var(--red);
  font-family: "Cutive Mono", monospace;
}

/* title bar: × on the left, name on the right (like the reference) */
.poster-bar {
  height: 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 6px;
  color: var(--light);
  font-size: max(10px, 0.811cqw);
}

.poster-close {
  width: 16px;
  height: 16px;
  padding: 0;
  background: none;
  border: 1px solid var(--light);
  color: var(--light);
  font-size: max(10px, 0.811cqw);
  line-height: 1;
  cursor: pointer;
}

.poster-close:hover {
  background: var(--light);
  color: var(--red);
  animation: none; /* no wiggle, like the player buttons */
}

.poster-window > img {
  display: block;
}

/* description windows: light text on red, scrolls if the text is long */
.poster-desc {
  height: calc(100% - 20px);
  overflow-y: auto;
  padding: 10px 14px;
  box-sizing: border-box;
  color: var(--light);
  font-size: max(10px, 0.946cqw);
  line-height: 1.2;
  scrollbar-color: var(--light) transparent;
}

/* positions, taken from the reference layout */
.poster-photo {
  position: absolute;
  z-index: 2; /* above the fixed .room */
}
.poster-photo-1 {
  left: 16cqw;
  top: 22cqh;
  height: 13cqh;
  rotate: -3deg;
}
.poster-photo-2 {
  left: 22cqw;
  top: 26cqh;
  height: 13cqh;
  rotate: -9deg;
}
.poster-photo-3 {
  left: 28.5cqw;
  top: 24cqh;
  height: 12cqh;
}

.poster-schwerelos {
  left: 36cqw;
  top: 15cqh;
  z-index: 3;
}
.poster-schwerelos > img {
  height: 36cqh;
}

.poster-anna {
  left: 45cqw;
  top: 38cqh;
  z-index: 4;
  rotate: -20deg;
}
.poster-anna > img {
  height: 42cqh;
}

.poster-text-schwerelos {
  left: 12cqw;
  top: 45cqh;
  width: 27cqw;
  height: 25cqh;
  z-index: 5;
}
.poster-text-anna {
  left: 61cqw;
  top: 33cqh;
  width: 21cqw;
  height: 20cqh;
  z-index: 5;
  rotate: -3deg;
}

/* POSTERS PAGE: windows in the same style as the video player */
.poster-window {
  --red: #ff3939;
  --light: #ffe3e3;
  position: fixed;
  z-index: 5; /* above the room */
  border: 2px solid var(--red);
  background: var(--red);
  font-family: "Cutive Mono", monospace;
}

.poster-window .card-bar {
  height: 20px;
  display: flex;
  justify-content: space-between; /* title left, × right */
  align-items: center;
  padding: 0 6px;
  color: var(--light);
  font-size: max(10px, 0.811cqw);
}

.poster-window .card-close {
  background: none;
  border: none;
  color: var(--light);
  font-size: max(10px, 0.946cqw);
  cursor: pointer;
  padding: 0;
}

.poster-window > img {
  display: block;
  width: auto;
}

/* description windows: light text on red */
.poster-desc {
  width: 20cqw;
}

.poster-desc p {
  padding: 10px;
  color: var(--light);
  font-size: max(10px, 1.014cqw);
  line-height: 1.2;
  max-height: 34cqh; /* long texts scroll instead of running off the screen */
  overflow-y: auto;
  scrollbar-color: var(--light) transparent;
}

/* positions (inside the green rectangle, clear of Clippy) */
/* layout: Schwerelos poster left-middle with its text below-left,
   Anna Blume poster in the middle-top (over Schwerelos) with its text on the right,
   tags at the bottom, under the Anna Blume poster */
.poster-1 {
  top: 11cqh;
  left: 44cqw;
  rotate: 2deg;
}
.poster-1 > img {
  height: 52cqh;
}

.desc-1 {
  top: 24.5cqh; /* right of the poster, ends above Clippy's bubble */
  left: 69cqw;
  width: 22cqw;
  max-width: 22cqw;
}
.desc-1 p {
  max-height: 26cqh; /* shorter window: the long text scrolls */
}

.poster-2 {
  top: 36cqh;
  left: 26.5cqw;
  z-index: 4; /* under the Anna Blume poster */
}
.poster-2 > img {
  height: 40cqh;
}

.desc-2 {
  top: 58cqh;
  left: 9cqw;
  width: 22cqw;
  max-width: 22cqw;
}

/* tags: at the bottom, under the Anna Blume poster (only on this page) */
.poster-window ~ .tag-window {
  top: 79cqh;
  right: auto;
  left: 57.5cqw;
}

/* 3 small images scattered left of the Schwerelos poster, a bit chaotic like the Term: Woman frames.
   .poster-small covers the stage, each photo is placed on its own */
.poster-small {
  position: fixed;
  inset: 0;
  z-index: 5;
  pointer-events: none; /* only the photos catch the mouse, not the empty stage */
}

/* .ps-frame = the small hover area (never changes size), turned like the photo in its png
   .ps-inner = what you see: border, X, handles, image (this one grows)
   .ps-crop  = cuts the photo out of its png, so the blue frame sits exactly on the photo's edges
   per photo: top / left / --w = place and size, --ar = the photo's shape,
   --tilt = how the photo is turned inside the png, --zoom = png width / photo width */
.ps-frame {
  position: absolute;
  top: var(--top);
  left: var(--left);
  width: var(--w);
  aspect-ratio: var(--ar);
  rotate: var(--tilt);
  transform-origin: top left;
  pointer-events: auto;
}

.ps-frame:nth-child(1) {
  --top: 13cqh;
  --left: 11cqw;
  --w: 7cqw;
  --ar: 918 / 1224;
  --tilt: 8.5deg;
  --zoom: 120%;
}
.ps-frame:nth-child(2) {
  --top: 25cqh;
  --left: 18.5cqw;
  --w: 5.5cqw;
  --ar: 912 / 1212;
  --tilt: -11.9deg;
  --zoom: 127%;
}
.ps-frame:nth-child(3) {
  --top: 38cqh;
  --left: 11.5cqw;
  --w: 8cqw;
  --ar: 910 / 1225;
  --tilt: 0.5deg;
  --zoom: 103%;
}

.ps-inner {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  border: 2px solid var(--wl-blue);
  box-sizing: border-box;
  pointer-events: none; /* the big image doesn't keep the hover */
  transition: width 250ms ease;
}

/* X and handles above the photo */
.ps-inner::before,
.ps-inner::after {
  z-index: 1;
}

.ps-crop {
  position: relative;
  display: block;
  aspect-ratio: var(--ar);
  overflow: hidden;
}

/* the png turned back, so the photo lies straight in the crop (the frame's tilt turns it again) */
.ps-crop img {
  position: absolute;
  top: 50%;
  left: 50%;
  width: var(--zoom);
  height: auto;
  translate: -50% -50%;
  rotate: calc(-1 * var(--tilt));
  display: block;
}

/* description windows: frame hugs the text, red frame, light inside, red text */
.poster-desc {
  width: fit-content;
  max-width: 22cqw;
  height: auto; /* overrides the older .poster-desc rule above */
  overflow: visible;
  padding: 0;
}

.poster-desc p {
  margin: 0;
  padding: 8px 10px;
  background: var(--light);
  color: var(--red);
}

/* schwerelos: the poster is tilted ~8deg inside the png.
   the window gets the same tilt, the image is turned back inside it
   and cropped, so frame and poster share one angle */
.poster-2 {
  rotate: -8deg;
}

.poster-crop {
  height: 36cqh;
  aspect-ratio: 0.707; /* A-format poster */
  overflow: hidden;
  position: relative;
}

.poster-crop img {
  position: absolute;
  top: 50%;
  left: 50%;
  height: 42cqh; /* a bit bigger than the crop, so no empty corners */
  width: auto;
  translate: -50% -50%;
  rotate: 8deg; /* undoes the tilt inside the png */
}

/* small images: grow on hover */
.poster-small:hover {
  z-index: 6; /* above the poster windows while hovering */
}

/* grows to the right, into the room; the X fades away (like Term: Woman) */
.ps-frame:hover {
  z-index: 1; /* above the other two small photos */
}

.ps-frame:hover .ps-inner {
  width: 30cqw;
}

/* INTRO (homepage, first visit): Clippy says hello, then the icons pop in */
.intro .bubble,
.intro .menu > *,
.intro .plant,
.intro .project-card {
  opacity: 0; /* hidden until script.js pops them in */
}

.intro .shown,
.intro .menu .shown {
  opacity: 1; /* stays visible after popping in (.intro .menu > * would win otherwise) */
}

.pop-in {
  animation: pop 350ms ease-out both;
}

@keyframes pop {
  0% {
    opacity: 0;
    scale: 0.6;
  }
  70% {
    opacity: 1;
    scale: 1.08;
  }
  100% {
    opacity: 1;
    scale: 1;
  }
}

/* TAG WINDOW (every project page): small window top right inside the room,
   same red style as the video/poster windows */
.tag-window {
  --red: #ff3939;
  --light: #ffe3e3;
  position: fixed;
  top: calc(8cqh + 12px); /* just inside the green back wall */
  right: calc(8cqw + 12px);
  z-index: 60; /* above every project window, below Clippy */
  border: 2px solid var(--red);
  background: var(--red);
  font-family: "Cutive Mono", monospace;
  rotate: 1.5deg;
}

.tag-window .card-bar {
  height: 20px;
  display: flex;
  justify-content: space-between; /* title left, × right */
  align-items: center;
  gap: 24px;
  padding: 0 6px;
  color: var(--light);
  font-size: max(10px, 0.811cqw);
}

.tag-window .card-close {
  background: none;
  border: none;
  color: var(--light);
  font-size: max(10px, 0.946cqw);
  cursor: pointer;
  padding: 0;
}

.tag-list {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  max-width: 16cqw;
  min-width: 160px;
  margin: 0;
  padding: 8px;
  list-style: none;
  background: var(--light);
}

.tag-list li {
  padding: 2px 6px;
  border: 1px solid var(--red);
  color: var(--red);
  font-size: max(10px, 0.946cqw);
}

/* margot: the tags in 2 rows (2 on top, 1 below), whatever the window width */
.tag-list-2rows {
  display: grid;
  grid-template-columns: auto auto;
  justify-content: start;
  justify-items: start; /* each tag only as wide as its word */
  max-width: none; /* the window grows to fit the 2 tags side by side */
}

/* DRAG: grab cursor on the parts you can drag windows by */
.wl-video .card-bar,
.poster-window .card-bar,
.tag-window .card-bar,
.yt-window .card-bar,
.fs-text-window .card-bar,
.spray-window .card-bar,
.readme-window .card-bar,
.email-window .card-bar,
.note-window .card-bar,
.error-bar {
  cursor: grab;
  user-select: none;
  touch-action: none; /* dragging works on touch screens too */
}

/* MY FRAGMENTED SELF: YouTube window, same style as the video player, 2x bigger */
.yt-window {
  --red: #ff3939;
  --light: #ffe3e3;
  position: fixed;
  top: 18.5cqh;
  left: 11.5cqw;
  rotate: 3deg; /* tilted a little to the right */
  z-index: 5; /* above the room */
  border: 2px solid var(--red);
  background: var(--red);
  font-family: "Cutive Mono", monospace;
}

.yt-window .card-bar {
  height: 20px;
  display: flex;
  justify-content: space-between; /* title left, × right */
  align-items: center;
  padding: 0 6px;
  color: var(--light);
  font-size: max(10px, 0.811cqw);
}

.yt-window .card-close {
  background: none;
  border: none;
  color: var(--light);
  font-size: max(10px, 0.946cqw);
  cursor: pointer;
  padding: 0;
}

.yt-video {
  height: 53cqh; /* about 2x the women-layout video */
  width: auto;
  aspect-ratio: 16 / 10; /* the screen recording is 1152 x 720 */
  display: block;
  border: 0;
}

/* MY FRAGMENTED SELF: text window right of the video, 2.5x slimmer than the video, a bit tilted.
   red frame, light inside, red text; scrolls because the text is long */
.fs-text-window {
  --red: #ff3939;
  --light: #ffe3e3;
  position: fixed;
  top: 22.5cqh; /* below the tags window, over the video's right edge */
  left: 66.5cqw;
  width: 24.5cqw;
  rotate: -2deg; /* tilted a little to the left */
  z-index: 5;
  border: 2px solid var(--red);
  background: var(--red);
  font-family: "Cutive Mono", monospace;
}

.fs-text-window .card-bar {
  height: 20px;
  display: flex;
  justify-content: space-between; /* title left, × right */
  align-items: center;
  padding: 0 6px;
  color: var(--light);
  font-size: max(10px, 0.811cqw);
}

.fs-text-window .card-close {
  background: none;
  border: none;
  color: var(--light);
  font-size: max(10px, 0.946cqw);
  cursor: pointer;
  padding: 0;
}

.fs-text {
  max-height: 30cqh; /* ends above Clippy's bubble */
  overflow-y: auto;
  padding: 8px 12px;
  background: var(--light);
  color: var(--red);
  font-size: max(10px, 1.014cqw);
  line-height: 1.2;
  scrollbar-color: var(--red) transparent;
}

.fs-text p + p {
  margin-top: 0.8em;
}

/* MARGOT: the same text window, right of the photo, below the tags window */
/* RHETORIC: the same text window, right of the image pile, below the tags window */
.rh-text,
.margot-text {
  top: 30cqh; /* ends above Clippy's bubble */
  left: auto;
  right: calc(8cqw + 12px);
  width: 20cqw;
  rotate: -2deg;
}

/* TERM: WOMAN: the same text window, right side: below the tags, above Clippy's bubble, away from the video */
.wl-text {
  top: 24cqh;
  left: auto;
  right: calc(8cqw + 12px);
  width: 20cqw;
  z-index: 6; /* above the frames */
  rotate: 1.5deg;
}

/* MARGOT + RHETORIC: a bit lower, more space under the tags;
   the text is a bit shorter so it still ends above Clippy's bubble */
.rh-text,
.margot-text {
  top: 34cqh;
}

.rh-text .fs-text,
.margot-text .fs-text {
  max-height: 26cqh;
}

/* WINDOW TITLES: bigger, easier to read (all window title bars) */
.wl-video .card-bar,
.poster-window .card-bar,
.tag-window .card-bar,
.yt-window .card-bar,
.fs-text-window .card-bar,
.spray-window .card-bar,
.error-bar {
  height: 26px;
  font-size: max(10px, 1.081cqw);
}

.wl-video .card-close,
.poster-window .card-close,
.tag-window .card-close,
.yt-window .card-close,
.fs-text-window .card-close,
.spray-window .card-close,
.error-close {
  font-size: max(10px, 1.351cqw);
}

/* SPRAY: the layer the letters are sprayed on, over the whole page (clicks go through it) */
.spray-canvas {
  position: fixed;
  inset: 0;
  z-index: 44; /* above windows, below the menu and Clippy */
  pointer-events: none;
}

/* while a pattern is chosen, the cursor is a spray can (click point = the nozzle) */
.spray-mode,
.spray-mode * {
  cursor:
    url("../assets/spray-cursor.png") 24 4,
    crosshair !important;
}

/* the menu and the spray window keep the hand cursor */
.spray-mode .menu,
.spray-mode .menu *,
.spray-mode .spray-window,
.spray-mode .spray-window * {
  cursor:
    url("../assets/icons/cursor-hand.png") 11 4,
    pointer !important;
}

/* the spray window: same style as the other windows */
.spray-window {
  --red: #ff3939;
  --light: #ffe3e3;
  position: fixed;
  z-index: 96; /* above the plant and the icons, below Clippy */
  rotate: -5deg;
  border: 2px solid var(--red);
  background: var(--red);
  font-family: "Cutive Mono", monospace;
}

.spray-window .card-bar {
  display: flex;
  justify-content: space-between; /* title left, × right */
  align-items: center;
  gap: 12px;
  padding: 0 6px;
  color: var(--light);
}

.spray-window .card-close {
  background: none;
  border: none;
  color: var(--light);
  cursor: pointer;
  padding: 0;
}

/* 4 small tool icons in a row */
.spray-tools {
  display: grid;
  grid-template-columns: 32px 32px; /* 2 x 2 */
  gap: 8px;
  padding: 10px;
  background: var(--light);
}

/* every tool always a little tilted, each its own way */
.spray-tool:nth-child(1) {
  rotate: -4deg;
}
.spray-tool:nth-child(2) {
  rotate: 3deg;
}
.spray-tool:nth-child(3) {
  rotate: 2deg;
}
.spray-tool:nth-child(4) {
  rotate: -3deg;
}

.spray-tool {
  width: 32px;
  height: 32px;
  padding: 0;
  border: 1px solid var(--red);
  background: none;
  color: var(--red);
  font-family: inherit;
  font-size: 18px;
  cursor: pointer;
}

.spray-tool:hover:not(:disabled),
.spray-tool.is-active {
  background: var(--red);
  color: var(--light);
  animation: none; /* no wiggle */
}

.spray-tool:disabled {
  opacity: 0.4; /* coming later */
  cursor: default;
  animation: none;
}

/* PLANT: looks clickable (Clippy tells you off) */
.plant {
  cursor: pointer;
}

/* CURSOR: the pixel hand (icon-1, turned 10deg left) everywhere on the site.
   click point = the fingertip. the spray can still takes over in spray mode */
*,
*::before,
*::after {
  cursor:
    url("../assets/icons/cursor-hand.png") 11 4,
    auto !important;
}

/* small tool icons: filled shapes + thin lines, in the button's colour */
.spray-tool svg {
  width: 18px;
  height: 18px;
  display: block;
  margin: auto;
  fill: currentColor;
}

.spray-tool svg .line {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linejoin: round;
}

/* ERROR POP-UP: pops in 1.5s after the page opens */
.error-popup {
  animation: pop 350ms ease-out 1.5s both;
}

/* BODY INPUT: the 4 photos on the left.
   each one: top = from the top, left = from the left, width = size (the height follows) */
.bi-img {
  position: fixed;
  z-index: 3; /* above the room, below the text window */
  display: block;
  border: 2px solid var(--wl-blue); /* X + handles: .wl-inner::before / ::after */
  transform-origin: left center;
  transition: scale 300ms ease;
}

.bi-img img {
  display: block;
  width: 100%;
  height: auto;
}

/* hover: like Term: Woman, the photo grows and the blue X fades away */
.bi-img:hover {
  z-index: 10; /* on top of the other photos and the text window */
  scale: 1.8;
}

.bi-img-1 {
  top: 10cqh;
  left: 10cqw;
  width: 15cqw;
}

.bi-img-2 {
  top: 25cqh;
  left: 18cqw;
  width: 15cqw;
}

.bi-img-3 {
  top: 40cqh;
  left: 10cqw;
  width: 15cqw;
}

.bi-img-4 {
  top: 55cqh;
  left: 18cqw;
  width: 15cqw;
}

/* BODY INPUT: the text window (red, like the posters), a bit wider for the longer text */
.bi-text {
  top: 15cqh;
  left: 38.5cqw;
  rotate: -2deg;
}

.bi-text.poster-desc {
  max-width: 32cqw;
}

.bi-text p + p {
  padding-top: 0; /* paragraphs sit close, like one text */
}

/* BODY INPUT: tags top right like on the other pages
   (the posters rule ".poster-window ~ .tag-window" would put them at the bottom, the text window is a poster-window) */
.bi-text ~ .tag-window {
  top: calc(8cqh + 12px);
  right: calc(8cqw + 12px);
  left: auto;
}

/* BODY INPUT: big green outlined circle under the text window, opens the website in a new tab */
.bi-try {
  position: fixed;
  top: 62cqh; /* under the text window, a bit left of its middle */
  left: 44cqw;
  width: 12cqw; /* size of the circle */
  aspect-ratio: 1; /* always round */
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1cqw;
  box-sizing: border-box;
  border-radius: 50%;
  border: 2px solid #4a9a2a; /* the room's green, outline only */
  background: #ffffff; /* so the shadow doesn't show through */
  color: #4a9a2a;
  font-family: "Cutive Mono", monospace;
  font-size: 1.5cqw;
  text-align: center;
  text-transform: uppercase;
  text-decoration: none;
  rotate: 4deg;
  box-shadow:
    0 2px 6px rgba(0, 0, 0, 0.12),
    0 10px 28px rgba(0, 0, 0, 0.18); /* same shadow as the windows */
  transition: rotate 300ms ease;
}


.bi-try:hover {
  rotate: -8deg; /* turns a little when you point at it, like the instagram circle */
}

/* SWUP ANIMATION */
/* DROP: things fall out downwards, new things fall in from the top */
html.is-changing .transition-drop {
  transition:
    transform 500ms ease,
    opacity 500ms;
}
html.is-animating .transition-drop {
  opacity: 0;
  transform: translateY(-100vh) rotate(-8deg);
}
html.is-leaving .transition-drop {
  transform: translateY(100vh) rotate(12deg);
}

/* SLIDE: tag window comes from the right */
html.is-changing .transition-slide {
  transition: transform 400ms ease;
}
html.is-animating .transition-slide {
  transform: translateX(130%);
}

/* POP: small windows grow in */
html.is-changing .transition-pop {
  transition:
    transform 300ms ease,
    opacity 300ms;
}
html.is-animating .transition-pop {
  opacity: 0;
  transform: scale(0.5);
}

/* FADE: for text */
html.is-changing .transition-fade {
  transition: opacity 400ms;
}
html.is-animating .transition-fade {
  opacity: 0;
}

/* BUBBLE: Clippy stays; his bubble shrinks into him, and the new one pops out */
html.is-changing .transition-bubble {
  transition:
    transform 250ms ease,
    opacity 250ms;
  transform-origin: bottom right;
}
html.is-animating .transition-bubble {
  opacity: 0;
  transform: scale(0);
}
html.is-rendering .transition-bubble {
  transition-delay: 200ms; /* after the page content has started coming in */
}

/* README: click the notebook -> readme.txt. the same window as the others, only white */
.readme-window {
  --frame: #7738e3; /* border, bar text, text */
  --inside: #ffffff;
  position: fixed;
  top: 30cqh;
  left: 22cqw;
  width: 26cqw;
  z-index: 96; /* above the plant and the icons, below Clippy */
  rotate: -2deg;
  border: 2px solid var(--frame);
  background: var(--inside);
  font-family: "Cutive Mono", monospace;
  animation: pop 350ms ease-out both;
}

.readme-window .card-bar {
  height: 26px;
  display: flex;
  justify-content: space-between; /* title left, × right */
  align-items: center;
  padding: 0 6px;
  border-bottom: 2px solid var(--frame);
  color: var(--frame);
  font-size: max(10px, 1.081cqw);
}

.readme-window .card-close {
  background: none;
  border: none;
  color: var(--frame);
  font-size: max(10px, 1.081cqw);
  cursor: pointer;
  padding: 0;
}

.readme-window p {
  margin: 0;
  padding: 10px 12px;
  color: var(--frame);
  font-size: max(10px, 1.014cqw);
  line-height: 1.2;
}

/* ABOUT PAGE: readme.txt on the left */
.about-readme {
  top: 53.5cqh; /* bottom left, under the email window, right of the plant */
  left: 17.5cqw;
}

.about-readme p + p {
  padding-top: 0; /* 3 short paragraphs, one line of space between them */
}

/* ABOUT PAGE: the email form, a letter in a red window (same as the others) */
.email-window {
  --red: #ff3939;
  --light: #ffe3e3;
  position: fixed;
  top: 10.5cqh; /* top left */
  left: 10cqw;
  width: 30cqw;
  z-index: 5; /* above the room */
  rotate: 1deg;
  margin: 0;
  border: 2px solid var(--red);
  background: var(--red);
  font-family: "Cutive Mono", monospace;
  font-size: max(10px, 1.014cqw);
  line-height: 1.2;
  color: var(--red);
}

.email-window .card-bar {
  height: 26px;
  display: flex;
  justify-content: space-between; /* title left, × right */
  align-items: center;
  padding: 0 6px;
  color: var(--light);
  font-size: max(10px, 1.081cqw);
}

.email-window .card-close {
  background: none;
  border: none;
  color: var(--light);
  font-size: max(10px, 1.081cqw);
  cursor: pointer;
  padding: 0;
}

/* From / To / Subject: two columns, a line under them */
.email-head {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 2px 20px;
  padding: 10px 12px;
  background: var(--light);
  border-bottom: 2px solid var(--red);
}

.email-body {
  padding: 10px 12px 12px;
  background: var(--light);
}

.email-body p {
  margin: 0 0 1em;
}

/* the inputs: no boxes, just a dashed underline in the text, like a blank in a letter */
.email-window input,
.email-window textarea {
  font: inherit;
  color: var(--red);
  background: transparent;
  border: none;
  border-bottom: 1px dashed var(--red);
  padding: 0;
  outline: none;
}

.email-window input:focus,
.email-window textarea:focus {
  border-bottom-style: solid;
}

.email-window ::placeholder {
  color: var(--red);
  opacity: 0.45;
}

.email-blank {
  width: 11em; /* "I liked ___________." */
}

.email-window textarea {
  display: block;
  width: 100%;
  margin-bottom: 1em;
  resize: none;
  overflow: hidden; /* it grows with the text instead (script.js) */
}

/* send: same look as the tool buttons */
.email-send {
  display: block;
  margin-left: auto;
  padding: 2px 12px;
  border: 2px solid var(--red);
  background: var(--light);
  color: var(--red);
  font: inherit;
  cursor: pointer;
}

.email-send:hover {
  background: var(--red);
  color: var(--light);
  animation: none;
}

.email-send:disabled {
  opacity: 0.5;
}

/* no email: the field turns red, the window shakes */
.email-window input.is-wrong {
  background: var(--red);
  color: var(--light);
  border-bottom-color: var(--red);
}

.email-window input.is-wrong::placeholder {
  color: var(--light);
  opacity: 0.8;
}

.email-window.shake {
  animation: shake 400ms ease-in-out;
}

@keyframes shake {
  0%,
  100% {
    translate: 0 0;
  }
  20% {
    translate: -10px 0;
  }
  40% {
    translate: 9px 0;
  }
  60% {
    translate: -6px 0;
  }
  80% {
    translate: 3px 0;
  }
}

/* ABOUT PAGE: instagram, a thin circle with the word turned, like a sticker on the wall */
.insta-circle {
  position: fixed;
  top: 40cqh; /* right side, just above Clippy's bubble */
  left: 70cqw;
  width: 16cqw; /* size of the circle */
  aspect-ratio: 1; /* always round */
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid #ff8000;
  border-radius: 50%;
  color: #ff8000;
  font-family: "Cutive Mono", monospace;
  font-size: 1.8cqw;
  text-decoration: none;
  transition: rotate 300ms ease;
}

/* only the word itself turns (> = not the wobbly letters inside, or they would turn too) */
.insta-circle > span {
  display: inline-block;
  white-space: nowrap; /* one line, even with the wobbly letters */
  rotate: 25deg; /* the word goes down to the right */
}

.insta-circle:hover {
  rotate: -8deg; /* turns a little when you point at it */
}

/* ABOUT PAGE: a note, like a text editor window. blue like Clippy, white inside */
.note-window {
  --blue: #0d00ff; /* the "russia is a terrorist state" note: Clippy's blue */
  position: fixed;
  top: 10cqh; /* top right */
  left: 64.5cqw;
  width: 20cqw;
  z-index: 5;
  rotate: 2deg;
  border: 2px solid var(--blue);
  background: #ffffff;
  color: var(--blue);
  font-family: "Cutive Mono", monospace;
}

.note-window .card-bar {
  height: 26px;
  display: flex;
  justify-content: space-between; /* title left, × right */
  align-items: center;
  padding: 0 6px;
  border-bottom: 2px solid var(--blue);
  font-size: max(10px, 1.081cqw);
}

.note-window .card-close {
  background: none;
  border: none;
  color: var(--blue);
  font-size: max(10px, 1.081cqw);
  cursor: pointer;
  padding: 0;
}

/* the toolbar: small outlined boxes, they only look like buttons */
.note-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 5px 6px;
  border-bottom: 1px solid var(--blue);
  font-size: max(10px, 0.743cqw);
  line-height: 1;
}

.note-toolbar > span {
  padding: 2px 4px;
  border: 1px solid var(--blue);
  white-space: nowrap;
}

.note-toolbar .note-swatch {
  width: 18px;
  background: var(--blue);
}

.note-style {
  display: flex;
  gap: 5px;
}

/* the ruler: a tick every 1/8, numbers under the long ticks */
.note-ruler {
  display: flex;
  height: 16px;
  margin: 0 6px;
  border-bottom: 1px solid var(--blue);
  background:
    repeating-linear-gradient(
        to right,
        var(--blue) 0 1px,
        transparent 1px calc(100% / 7)
      )
      top / 100% 8px no-repeat,
    repeating-linear-gradient(
        to right,
        var(--blue) 0 1px,
        transparent 1px calc(100% / 28)
      )
      top / 100% 4px no-repeat;
  font-size: max(10px, 0.608cqw);
}

.note-ruler > span {
  flex: 1;
  padding: 7px 0 0 2px;
}

.note-text {
  margin: 0;
  padding: 10px 12px 18px;
  font-size: 1.9cqw;
  line-height: 1.15;
  cursor: text; /* you can write in it (contenteditable) */
  outline: none; /* no browser focus frame, the blinking caret is enough */
  caret-color: var(--blue);
}

/* MINIMISE: the – in every title bar, just before the ×, same colour as the bar text */
.card-min {
  margin-left: auto; /* title left, – and × together on the right */
  margin-right: 10px;
  padding: 0 0 0 16px; /* a gap to the title, also when a window shrinks */
  border: none;
  background: none;
  color: inherit;
  font: inherit;
  line-height: 1;
  cursor: pointer;
}

/* minimised: only the title bar is left */
.is-min > :not(.card-bar) {
  display: none !important;
}

/* PAPER NOTE (about page, next to Clippy): a sheet of paper with a folded corner and a hatched shadow.
   .paper-note = placement + shadow, .paper = the white sheet (so the shadow can sit behind it) */
.paper-note {
  --green: #4a9a2a; /* the room's green */
  --fold: 0.8cqw; /* size of the folded corner */
  position: fixed;
  top: 76.5cqh; /* under Clippy's bubble, next to Clippy */
  left: 73.5cqw;
  width: 6.75cqw; /* half the size of before */
  z-index: 5;
  rotate: -4deg;
  cursor: grab;
  user-select: none;
  touch-action: none; /* dragging works on touch screens too */
}

/* the hatched shadow, a bit to the left and down */
.paper-note::after {
  content: "";
  position: absolute;
  inset: 0;
  translate: -4px 4px;
  z-index: -1;
  background: repeating-linear-gradient(
    -45deg,
    var(--green) 0 1px,
    transparent 1px 4px
  );
  opacity: 0.6;
}

.paper {
  position: relative;
  padding: 0.55cqw 0.55cqw 0.35cqw;
  border: 1.5px solid var(--green);
  background: #ffffff;
  color: var(--green);
  font-family: "Cutive Mono", monospace;
}

/* the folded corner: the top-right triangle is cut away (white), the flap has an outline */
.paper::before {
  content: "";
  position: absolute;
  top: -1.5px;
  right: -1.5px;
  width: var(--fold);
  height: var(--fold);
  border-left: 1.5px solid var(--green);
  border-bottom: 1.5px solid var(--green);
  background: linear-gradient(
    to bottom left,
    #ffffff calc(50% - 1px),
    var(--green) calc(50% - 1px) calc(50% + 1px),
    #ffffff calc(50% + 1px)
  );
}

.paper p {
  margin: 0;
}

.paper-title {
  padding-right: var(--fold); /* not under the folded corner */
  font-size: max(7px, 0.675cqw);
  font-weight: 700;
  text-transform: uppercase;
  line-height: 1.1;
}

.paper-sub {
  margin-top: 0.25cqw !important;
  font-size: max(5px, 0.425cqw);
}

/* footer: NOTE ------------ 00001 */
.paper-foot {
  display: flex;
  align-items: center;
  gap: 0.2cqw;
  margin-top: 0.6cqw;
  font-size: max(4px, 0.275cqw);
  text-transform: uppercase;
}

.paper-line {
  flex: 1;
  border-bottom: 1px dashed var(--green);
}

/* WINDOW SHADOWS: every window floats a little above the room, like windows on a desktop */
.wl-video,
.poster-window,
.tag-window,
.yt-window,
.fs-text-window,
.spray-window,
.readme-window,
.email-window,
.note-window {
  box-shadow:
    0 2px 6px rgba(0, 0, 0, 0.12),
    0 10px 28px rgba(0, 0, 0, 0.18);
}

/* CLIPPY ANIMATION */
.clippy svg {
  animation: clippy-idle 3s ease-in-out infinite;
  transform-origin: bottom center;
}
@keyframes clippy-idle {
  0%,
  100% {
    transform: translateY(0) rotate(0deg);
  }
  50% {
    transform: translateY(-4px) rotate(-2deg);
  }
}

/* blink and jump: script.js adds .is-blinking (every 3-7s) and .is-jumping (new line, or every 15-30s).
   they use scale / translate, so the idle sway (transform) keeps running underneath */
#eye-left,
#eye-right {
  transform-box: fill-box;
  transform-origin: center;
}

.clippy.is-blinking #eye-left,
.clippy.is-blinking #eye-right {
  animation: clippy-blink 150ms ease-in-out;
}
@keyframes clippy-blink {
  50% {
    scale: 1 0.1;
  }
}

.clippy.is-jumping svg {
  animation:
    clippy-idle 3s ease-in-out infinite,
    clippy-jump 400ms ease-out;
}
@keyframes clippy-jump {
  0% {
    translate: 0 0;
    scale: 1 1;
  }
  35% {
    translate: 0 -12px;
    scale: 0.96 1.04;
  }
  70% {
    translate: 0 0;
    scale: 1.08 0.9; /* squash on landing */
  }
  100% {
    translate: 0 0;
    scale: 1 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .clippy.is-blinking #eye-left,
  .clippy.is-blinking #eye-right {
    animation: none;
  }
  .clippy.is-jumping svg {
    animation: clippy-idle 3s ease-in-out infinite;
  }
}

.bubble {
  transition: scale 200ms ease;
}
.bubble:hover {
  scale: 1.01 0.98;
}

.bubble {
  animation: bubble-float 4s ease-in-out infinite;
}
/* off during a page change: swup waits for every animation on .transition-bubble,
   and an endless one made each page change hang for 4s + 4s */
html.is-changing .bubble {
  animation: none;
}
@keyframes bubble-float {
  0%,
  100% {
    translate: 0 0;
  }
  50% {
    translate: 0 -5px;
  }
}

/* ------ MOBILE (under 768px) ------ */

/* the warning: a white layer over the page, only Clippy (z-index 100) stays above it */
.mobile-overlay {
  position: fixed;
  inset: 0;
  z-index: 99;
  background: rgba(255, 255, 255, 0.8);
}

/* "still continue": inside the bubble, under the text, like the other small buttons */
.bubble-continue {
  display: block;
  margin: 10px 0 2px auto; /* right side of the bubble */
  padding: 2px 10px;
  border: 1px solid #0d00ff;
  background: #ffffff;
  color: #0d00ff;
  font-family: "Cutive Mono", monospace;
  font-size: 14px;
  cursor: pointer; /* no own tilt: it follows the bubble's tilt, parallel to the frame */
}

.bubble-continue:hover {
  background: #0d00ff;
  color: #ffffff;
}

@media (max-width: 767px) {
  /* the page scrolls: everything in main goes in one column, full width */
  #swup {
    position: relative;
    left: auto;
    top: auto;
    width: auto;
    height: auto;
    container-type: normal; /* no stage on a phone: one column that scrolls */
    contain: none;
    pointer-events: auto;
    z-index: 5;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 28px;
    padding: 12dvh 16px 45dvh; /* the floor objects and Clippy stay free at the bottom */
    box-sizing: border-box;
  }

  #swup > a:not(.insta-circle, .bi-try) {
    display: block; /* the project icon links (the instagram circle stays a flex circle) */
  }

  /* main page: the project icons one under the other */
  .project-card {
    position: relative;
    inset: auto;
    width: 70vw;
    height: auto;
  }

  /* every window and picture: in the column, not placed on the screen */
  .poster-window,
  .tag-window,
  .yt-window,
  .fs-text-window,
  .readme-window,
  .email-window,
  .note-window,
  .paper-note,
  .margot-photo,
  .rhetoric-slideshow,
  .poster-small,
  .bi-img,
  .women-layout {
    position: relative !important;
    inset: auto !important;
    width: 100% !important;
    max-width: none !important;
    margin: 0 !important;
    rotate: 0deg;
    box-sizing: border-box;
  }

  .poster-window > img,
  .poster-1 > img,
  .poster-2 > img,
  .margot-photo > img {
    width: 100%;
    height: auto;
  }

  .poster-crop {
    width: 100%;
    height: auto;
  }

  .poster-desc p,
  .desc-1 p,
  .fs-text {
    max-height: none; /* the page scrolls, not the window */
  }

  .yt-video {
    width: 100%;
    height: auto;
  }

  .rhetoric-slideshow {
    height: 55dvh;
  }

  .rhetoric-slideshow img {
    max-width: 100%;
    max-height: 100%;
  }

  .rh-pause {
    position: relative;
    inset: auto;
    width: 26vw;
    font-size: 4.5vw;
  }

  /* posters: the 3 small photos in a row, no zoom on tap */
  .poster-small {
    display: flex;
    flex-direction: row;
    justify-content: center;
    gap: 3vw;
    pointer-events: auto;
  }

  .ps-frame {
    position: relative;
    top: auto;
    left: auto;
    width: 22vw;
  }

  .ps-frame:hover .ps-inner {
    width: 100%;
  }

  .women-layout {
    height: 140dvh !important; /* room for the frames to spread out */
  }

  .note-text {
    font-size: 8vw;
  }

  .insta-circle,
  .bi-try {
    position: relative;
    inset: auto;
    width: 45vw;
    font-size: 5vw;
  }

  /* tags: the list uses the whole window width */
  .tag-list {
    max-width: none;
  }

  /* term: woman: the video window inside the frames, as wide as the screen column */
  .wl-video {
    left: 0;
    right: 0;
    bottom: 0;
  }

  .wl-video .player,
  .wl-video .player-video {
    width: 100%;
    height: auto;
  }

  /* schwerelos: the poster fills its crop again */
  .poster-crop img {
    height: 118%;
  }

  /* the floor: smaller plant, bigger icons, no spray (spraying needs a mouse) */
  .spray-icon,
  .spray-window,
  .spray-canvas {
    display: none !important;
  }

  .plant img {
    height: 18dvh;
  }

  .icon {
    width: 13vw;
  }

  .notebook-icon {
    left: calc(2vw + 18dvh * 0.75);
  }

  .notebook-icon .icon {
    width: 20vw;
    max-width: none;
  }

  .earth {
    right: 26vw;
  }

  /* Clippy: smaller, his bubble wider */
  .clippy {
    right: 4vw;
  }

  .clippy svg {
    width: 16vw;
  }

  .bubble {
    width: 62vw;
    font-size: 14px;
  }
}
