/* Departure Mono, under the SIL Open Font License: see fonts/. It is drawn on an 11px grid, so the sizes
   here are multiples of 5.5px: 11px, 22px and 33px stay crisp on every screen, 16.5px on high-density ones. */
@font-face {
  font-family: "Departure Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/departure-mono.woff2") format("woff2");
}

/* ---------- Platform: the layers of one platform, drawn as windows on a desktop ----------
   The deepest layer opens at the back, top left. Each layer above it opens one step lower and further
   right, in front of it, down to the control center at the front. */

.platform .section-head {
  container-type: inline-size;
}

/* "for your whole business." is 11.1em wide. The size keeps the heading on two lines at every width. */
.platform .title {
  font-size: min(50px, 100cqi / 11.25);
}

.desk {
  --desk: #9d94f2;
  --paper: #fff;
  --chip: #e9e7fb;
  --pixel: "Departure Mono", ui-monospace, Menlo, monospace;
  margin: 64px 0 0;
}

.desk-screen {
  /* One unit of the desktop's size. It is 1px when the whole desktop fits in the window under the
     navigation, and shrinks in shorter windows, down to 0.75px. Title bars, labels and borders keep their
     size; everything else is drawn in units. The desktop measures 247px plus 520 units, and gets the
     window's height less 92px for the navigation and some air. */
  --u: clamp(0.75px, (100svh - 339px) / 520, 1px);
  --pad: 48px; /* left and right margin of the windows */
  --top: calc(48 * var(--u)); /* room for the tab above the first window */
  --bottom: calc(40 * var(--u));
  --w: calc(520 * var(--u)); /* 46 characters of description */
  /* How far below the window behind it each layer's window opens: far enough to show that window's
     title bar, name and description. */
  --dy: calc(23px + 84 * var(--u));
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding: var(--top) var(--pad) var(--bottom);
  border: 1px solid var(--ink);
  /* A dot every 4px, like the pixel grid of an old screen. The mounds of dither come from platform.js. */
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4'%3E%3Crect width='1' height='1' fill-opacity='.22'/%3E%3C/svg%3E")
    var(--desk);
  color: var(--ink);
  font-family: var(--pixel);
  font-weight: 400;
}

.desk-dither {
  position: absolute;
  z-index: 0;
  inset: 0;
  width: 100%;
  height: 100%;
  image-rendering: pixelated;
  pointer-events: none;
}

.desk-tab {
  position: absolute;
  z-index: 1;
  top: 0;
  left: 0;
  margin: 0;
  padding: 0 8px;
  background: var(--ink);
  color: #fff;
  font-size: 11px;
  line-height: 22px;
}

/* ---------- Windows ---------- */

.window {
  --drag-x: 0px;
  --drag-y: 0px;
  position: relative;
  z-index: calc(var(--i) + 1);
  border: 1px solid var(--ink);
  background: var(--paper);
  box-shadow: 2px 2px 0 var(--ink);
  transform: translate(var(--drag-x), var(--drag-y));
}

/* A clicked or focused window comes to the front, the way it would on a desktop. */
.window.is-front,
.window:focus-within {
  z-index: 10;
}

.window.is-dragging,
.window.is-returning {
  z-index: 11;
}

.window-bar {
  margin: 0;
  padding: 0 8px;
  overflow: hidden;
  background: var(--ink);
  color: #fff;
  font-size: 11px;
  line-height: 22px;
  white-space: nowrap;
  text-overflow: ellipsis;
  -webkit-user-select: none;
  user-select: none;
}

@media (hover: hover) and (pointer: fine) {
  .window-bar {
    cursor: grab;
  }

  .window.is-dragging .window-bar {
    cursor: grabbing;
  }
}

.window-body {
  padding: calc(10 * var(--u)) calc(16 * var(--u)) calc(14 * var(--u));
}

/* ---------- Layers ----------
   Four rows one step tall, then the control center. Each window is taller than its row, so its lower
   part runs under the next layer's window, the way a stack of windows overlaps. */

.layers {
  display: grid;
  grid-template-rows: repeat(4, var(--dy)) auto;
  margin: 0;
  padding: 0;
  list-style: none;
}

.layer {
  align-self: start;
  width: var(--w);
  margin-left: calc(var(--i) * (100% - var(--w)) / 4);
}

.layer-name {
  display: inline-block;
  margin: 0;
  padding: 0 calc(6 * var(--u));
  background: var(--ink);
  color: #fff;
  font-size: calc(33 * var(--u));
  font-weight: 400;
  line-height: calc(38 * var(--u));
}

.layer-text {
  margin: calc(6 * var(--u)) 0 0;
  font-size: calc(16.5 * var(--u));
  line-height: calc(22 * var(--u));
}

.layer-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: calc(12 * var(--u)) 0 0;
  padding: 0;
  list-style: none;
}

.layer-tags li {
  padding: 0 6px;
  background: var(--chip);
  font-size: 11px;
  line-height: 22px;
}

/* The control center reports on every layer under it. */

.status {
  margin: calc(12 * var(--u)) 0 0;
  border-top: 1px solid var(--ink);
}

.status-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 4px 12px;
  min-height: 30px;
  padding: 3px 0;
  border-bottom: 1px solid var(--ink);
}

.status dt {
  padding: 0 6px;
  background: var(--ink);
  color: #fff;
  font-size: 11px;
  line-height: 22px;
}

.status dd {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 0 auto;
  font-size: calc(16.5 * var(--u));
  line-height: 22px;
}

.status-text::before {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: 8px;
  background: var(--mint);
  vertical-align: 1px;
}

.is-waiting .status-text::before {
  background: var(--gold);
}

.status-action {
  margin: 0;
  padding: 0 8px;
  border: 1px solid var(--ink);
  border-radius: 0;
  background: var(--paper);
  box-shadow: 1px 1px 0 var(--ink);
  color: var(--ink);
  font: 400 11px/20px var(--pixel);
  cursor: pointer;
}

.status-action:hover {
  background: var(--ink);
  color: #fff;
}

.status-action:active {
  transform: translate(1px, 1px);
  box-shadow: none;
}

/* ---------- Widgets in the free corners of the desktop ---------- */

.desk-widgets {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.widget {
  position: absolute;
  z-index: 1;
  pointer-events: auto;
}

.crew {
  top: var(--top);
  right: var(--pad);
  width: calc(248 * var(--u));
}

.crew-link {
  display: block;
  color: inherit;
  text-decoration: none;
}

.crew-faces {
  display: flex;
  gap: calc(4 * var(--u));
}

.crew-faces > span {
  width: calc(30 * var(--u));
  height: calc(30 * var(--u));
  overflow: hidden;
  border: 1px solid var(--ink);
  background: var(--chip);
}

.crew-faces img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.55);
  transform-origin: 50% 40%;
}

.crew-label {
  display: inline-block;
  margin-top: calc(10 * var(--u));
  font-size: calc(16.5 * var(--u));
  line-height: calc(22 * var(--u));
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}

.crew-link:hover .crew-label {
  background: var(--ink);
  color: #fff;
  text-decoration: none;
}

.migrate {
  bottom: var(--bottom);
  left: var(--pad);
  width: calc(320 * var(--u));
}

.migrate-text {
  margin: 0;
  font-size: calc(16.5 * var(--u));
  line-height: calc(22 * var(--u));
}

/* One segment for each layer: three moved, one moving, one to go. */
.migrate-bar {
  display: flex;
  gap: calc(4 * var(--u));
  margin-top: calc(12 * var(--u));
}

.migrate-bar > span {
  flex: 1;
  height: calc(14 * var(--u));
  border: 1px solid var(--ink);
}

.migrate-bar > span:nth-child(-n + 3) {
  background: var(--ink);
}

.migrate-bar > span:nth-child(4) {
  background: repeating-conic-gradient(var(--ink) 0 25%, transparent 0 50%) 0 0 / 2px 2px;
}

.migrate-count {
  margin: 8px 0 0;
  font-size: 11px;
  line-height: 14px;
}

.desk-caption {
  margin-top: 20px;
  color: var(--muted);
  font-size: 14px;
  text-align: center;
}

/* ---------- Opening: the desktop scans in, then each window opens in turn, deepest layer first ---------- */

/* Transparent rather than hidden, so the windows stay readable to screen readers and reachable by keyboard
   before they open. */
.desk.will-boot .desk-dither,
.desk.will-boot .window {
  opacity: 0;
}

.desk.is-booted .desk-dither {
  animation: desk-scan 0.48s steps(12, end) backwards;
}

.desk.is-booted .window {
  animation: window-open 0.28s steps(4, end) backwards;
  animation-delay: calc(0.5s + var(--order, var(--i)) * 0.13s);
}

@keyframes desk-scan {
  from {
    clip-path: inset(0 0 100% 0);
  }
  to {
    clip-path: inset(0);
  }
}

@keyframes window-open {
  from {
    clip-path: inset(50% 50% 50% 50%);
  }
  to {
    clip-path: inset(0 -3px -3px 0);
  }
}

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

/* Without room in the corners, the widgets sit in a row under the layers. The desktop is then taller
   than most windows anyway, so it keeps its full size. */
@media (max-width: 1100px) {
  .desk-screen {
    --u: 1px;
  }

  .desk-widgets {
    position: static;
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 24px;
    margin-top: 40px;
    pointer-events: auto;
  }

  .widget {
    position: relative;
    inset: auto;
  }
}

/* On phones the windows stack straight down, each covering only the bottom edge of the one behind. */
@media (max-width: 720px) {
  .platform .title {
    font-size: min(46px, 100cqi / 11.25);
  }

  .desk {
    margin-top: 48px;
  }

  .desk-screen {
    --pad: 12px;
    --top: 40px;
    --bottom: 20px;
  }

  .layers {
    grid-template-rows: none;
  }

  /* The step narrows on the smallest phones, so "Control center" still fits on one line. */
  .layer {
    width: auto;
    margin-left: calc(var(--i) * min(6px, 1.4vw));
  }

  .layer + .layer {
    margin-top: -10px;
  }

  .layer:not(.layer-top) .window-body {
    padding-bottom: 26px;
  }

  .layer-name {
    font-size: 22px;
    line-height: 30px;
  }

  /* Small enough that a waiting row keeps its status and button on one line under the layer's name. */
  .status dd {
    font-size: 11px;
  }

  .desk-widgets {
    gap: 16px;
    margin-top: 24px;
  }

  .crew,
  .migrate {
    width: 100%;
  }

  .desk-caption {
    text-align: left;
  }
}

@media (prefers-reduced-motion: reduce) {
  .desk.is-booted .desk-dither,
  .desk.is-booted .window {
    animation: none;
  }
}
