/* /metrics impact map: a tilted CSS-3D floor with one spend column per day standing on it, a
   bookings lane lying flat in front on its own scale, and change flags standing above. Same
   technique as the runway (desk-runway.css); flat 2D below 720px instead of hidden.
   Heights come from data-h / data-b via JS (--h / --b); the hq-N / bq-N classes below give a
   5-step approximation when JS doesn't run. The map is always dark, in both colour schemes. */
:root {
  --impact-spend: #93a4ff;
  --impact-bookings: #5fcad4;
  --impact-flag: #ffffff;
}

.impact {
  --plane-tilt: 58deg;
  --col-scale: 0.75; /* a full-height column is 75% of the floor's depth */
  --lane-scale: 0.3;
  position: relative;
  height: 360px;
  border-radius: var(--radius-board);
  overflow: hidden; /* the only overflow in the 3D chain: an ancestor would flatten preserve-3d */
  perspective: 1100px;
  perspective-origin: 50% 8%;
  background:
    radial-gradient(120% 90% at 50% 0%, rgb(90 112 255 / 0.3), transparent 60%),
    linear-gradient(180deg, #1a2a78 0%, #0e1845 58%, #0a1133 100%);
  box-shadow:
    var(--shadow-3),
    inset 0 1px 0 rgb(255 255 255 / 0.12);
  isolation: isolate;
  touch-action: none;
  cursor: grab;
  user-select: none;
}
.impact.is-dragging {
  cursor: grabbing;
}
.impact-stage {
  position: absolute;
  /* Extra top room (was 100px) so a lvl-2 flag head clears the board's top edge instead of
     clipping when several changes cluster in a short span. */
  inset: 132px 36px 26px;
  transform-style: preserve-3d;
  transform: rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg));
  pointer-events: none; /* its flat box sits in front of the tilted floor; only days and flags take the pointer */
}
.impact-plane {
  position: absolute;
  inset: 0;
  display: flex;
  transform-style: preserve-3d;
  transform: rotateX(var(--plane-tilt));
  transform-origin: 50% 100%;
  pointer-events: none;
  border-radius: 12px;
  background:
    linear-gradient(
      0deg,
      transparent 0 33%,
      rgb(255 255 255 / 0.28) 33% calc(33% + 1px),
      transparent calc(33% + 1px)
    ),
    linear-gradient(180deg, rgb(255 255 255 / 0.1), rgb(255 255 255 / 0.02));
  box-shadow:
    inset 0 0 0 1px rgb(255 255 255 / 0.14),
    0 40px 60px -20px rgb(0 0 0 / 0.6);
}
.impact-day {
  pointer-events: auto;
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  transform-style: preserve-3d;
}
.impact-col,
.impact-gap,
.impact-flag {
  position: absolute;
  bottom: 70%;
  transform-origin: 50% 100%;
  transform: rotateX(calc(-1 * var(--plane-tilt)));
}
.impact-col {
  left: 12%;
  right: 12%;
  height: calc(var(--h, 0%) * var(--col-scale));
  min-height: 1px;
  border-radius: 2px 2px 0 0;
  background: linear-gradient(
    180deg,
    var(--impact-spend),
    rgb(147 164 255 / 0.55)
  );
}
.is-restating .impact-col {
  background: repeating-linear-gradient(
    135deg,
    var(--impact-spend) 0 3px,
    rgb(147 164 255 / 0.25) 3px 6px
  );
}
.impact-gap {
  left: 50%;
  height: 40%;
  border-left: 1px dashed rgb(255 255 255 / 0.5);
}
.impact-lane-bar {
  position: absolute;
  left: 18%;
  right: 18%;
  bottom: 3%;
  height: calc(var(--b, 0%) * var(--lane-scale));
  border-radius: 1px;
  background: var(--impact-bookings);
}
.is-restating .impact-lane-bar {
  background: repeating-linear-gradient(
    0deg,
    var(--impact-bookings) 0 3px,
    rgb(95 202 212 / 0.3) 3px 6px
  );
}

/* Flags: a stem and a head standing above the columns; three heights so neighbours don't collide. */
.impact-flag {
  --stem: 145px;
  left: 50%;
  width: 0;
  height: 0;
  bottom: 62%;
  transform-style: preserve-3d;
  color: #0f1a2b;
  text-decoration: none;
  z-index: 2;
  /* A press-and-drag that starts on a flag must rotate the map, not hijack into the browser's
     native link-drag (which stops delivering pointermove, silently breaking the custom
     rotate-drag JS). */
  -webkit-user-drag: none;
  user-select: none;
}
.impact-flag.lvl-1 {
  --stem: 172px;
}
.impact-flag.lvl-2 {
  --stem: 198px;
}
.impact-flag-stem {
  position: absolute;
  left: -1px;
  bottom: 0;
  width: 2px;
  height: var(--stem);
  background: linear-gradient(
    180deg,
    var(--impact-flag),
    rgb(255 255 255 / 0.2)
  );
}
.impact-flag-head {
  position: absolute;
  left: 0;
  bottom: var(--stem);
  display: grid;
  gap: 1px;
  max-width: 210px;
  padding: 5px 9px 6px;
  border-radius: 9px;
  background: var(--impact-flag);
  box-shadow: 0 10px 22px -8px rgb(0 0 0 / 0.55);
  transform: translateX(-50%);
  white-space: nowrap;
  font: 600 11.5px/1.2 var(--body);
}
.impact-flag.at-end .impact-flag-head {
  transform: translateX(-100%);
}
.impact-flag.at-start .impact-flag-head {
  transform: none;
}
.impact-flag-day {
  color: #46526a; /* 5.1:1 on the muted head (#c9d1de), 7.9:1 on white */
}
.impact-flag-label {
  overflow: hidden;
  text-overflow: ellipsis;
  font: 760 13px/1.15 var(--display);
}
.impact-flag-note {
  color: #46526a; /* 5.1:1 on the muted head (#c9d1de), 7.9:1 on white */
  font-style: italic;
}
.impact-flag-who {
  font-size: 11px;
}
.impact-flag.is-busy .impact-flag-head {
  box-shadow:
    0 10px 22px -8px rgb(0 0 0 / 0.55),
    0 0 0 3px rgb(147 164 255 / 0.7);
}
.impact-flag-muted .impact-flag-head {
  background: #c9d1de;
}
.impact-flag-muted .impact-flag-stem {
  opacity: 0.5;
}
.impact-flag:hover {
  z-index: 5;
}
.impact.hide-outside .impact-flag-muted {
  display: none;
}

/* Labels, readout, legend swatches. */
.impact-axis {
  position: absolute;
  left: 16px;
  color: rgb(255 255 255 / 0.75);
  font: 650 12.5px/1 var(--body);
  z-index: 3;
  pointer-events: none;
}
.impact-axis-spend {
  top: 14px;
}
.impact-axis-bookings {
  bottom: 10px;
}
.impact-readout {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 6;
  max-width: calc(100% - 24px);
  margin: 0;
  padding: 8px 12px;
  border-radius: 10px;
  background: #ffffff;
  color: #0f1a2b;
  font: 650 13.5px/1.3 var(--body);
  box-shadow: 0 12px 28px -10px rgb(0 0 0 / 0.6);
  opacity: 0;
  pointer-events: none;
}
.impact-readout.is-on {
  opacity: 1;
}
.impact-key {
  display: inline-block;
  flex: none;
  width: 14px;
  height: 10px;
  margin-right: 6px;
  border: 1px solid var(--ink-3);
  border-radius: 3px;
}
.impact-key-spend {
  background: var(--impact-spend);
}
.impact-key-bookings {
  background: var(--impact-bookings);
}
.impact-key-flag {
  width: 10px;
  border-radius: 50%;
  background: var(--impact-flag);
}
.impact-key-restating {
  background: repeating-linear-gradient(
    135deg,
    var(--impact-spend) 0 2px,
    transparent 2px 4px
  );
}

@media (hover: hover) {
  .impact-day:hover .impact-col,
  .impact-day:hover .impact-lane-bar {
    filter: brightness(1.25);
  }
  .impact-flag:hover .impact-flag-head {
    box-shadow:
      0 18px 30px -10px rgb(0 0 0 / 0.7),
      0 0 0 2px var(--impact-spend);
  }
}
@media (prefers-reduced-motion: no-preference) {
  .impact-stage {
    transition: transform 400ms var(--ease-out);
  }
  .impact.is-dragging .impact-stage {
    transition: none;
  }
  .impact-plane {
    animation: plane-settle 1000ms var(--ease-out) backwards;
  }
  .impact-readout {
    transition: opacity 160ms;
  }
}
@media (min-width: 720px) and (max-width: 1023px) {
  .impact {
    height: 300px;
  }
  .impact-stage {
    inset: 112px 24px 22px;
  }
  .impact {
    --col-scale: 0.6;
  }
  .impact-flag {
    --stem: 125px;
  }
  .impact-flag.lvl-1 {
    --stem: 145px;
  }
  .impact-flag.lvl-2 {
    --stem: 163px;
  }
}

/* Phones: a flat 2D strip that fits the width. Flags become markers above it; tap one for its list row. */
@media (max-width: 719px) {
  .impact {
    height: 210px;
    perspective: none;
    touch-action: auto;
    cursor: default;
  }
  .impact-stage {
    inset: 56px 8px 8px;
    transform: none;
  }
  .impact-plane {
    transform: none;
    animation: none;
    background: linear-gradient(
      0deg,
      transparent 0 31%,
      rgb(255 255 255 / 0.28) 31% calc(31% + 1px),
      transparent calc(31% + 1px)
    );
    box-shadow: none;
  }
  .impact-col,
  .impact-gap {
    bottom: 34%;
    transform: none;
  }
  .impact-col {
    left: 8%;
    right: 8%;
    height: calc(var(--h, 0%) * 0.64);
  }
  .impact-gap {
    height: 30%;
  }
  .impact-lane-bar {
    left: 8%;
    right: 8%;
    bottom: 0;
    height: calc(var(--b, 0%) * 0.28);
  }
  .impact-flag {
    top: -16px;
    bottom: auto;
    transform: none;
  }
  .impact-flag-stem {
    display: none;
  }
  .impact-flag-head {
    bottom: auto;
    top: 0;
    width: 10px;
    height: 10px;
    padding: 0;
    border-radius: 50%;
  }
  .impact-flag-head > * {
    display: none;
  }
  .impact-flag.at-end .impact-flag-head,
  .impact-flag.at-start .impact-flag-head {
    transform: translateX(-50%);
  }
  .impact-axis-spend {
    top: 10px;
  }
  .impact-axis-bookings {
    bottom: auto;
    top: 10px;
    left: auto;
    right: 12px;
  }
  .impact-readout {
    top: auto;
    bottom: 8px;
    right: 8px;
  }
}

/* No-JS heights, in 5-step increments; JS replaces them with the exact data-h / data-b. */
.hq-0 {
  --h: 0%;
}
.hq-5 {
  --h: 5%;
}
.hq-10 {
  --h: 10%;
}
.hq-15 {
  --h: 15%;
}
.hq-20 {
  --h: 20%;
}
.hq-25 {
  --h: 25%;
}
.hq-30 {
  --h: 30%;
}
.hq-35 {
  --h: 35%;
}
.hq-40 {
  --h: 40%;
}
.hq-45 {
  --h: 45%;
}
.hq-50 {
  --h: 50%;
}
.hq-55 {
  --h: 55%;
}
.hq-60 {
  --h: 60%;
}
.hq-65 {
  --h: 65%;
}
.hq-70 {
  --h: 70%;
}
.hq-75 {
  --h: 75%;
}
.hq-80 {
  --h: 80%;
}
.hq-85 {
  --h: 85%;
}
.hq-90 {
  --h: 90%;
}
.hq-95 {
  --h: 95%;
}
.hq-100 {
  --h: 100%;
}
.bq-0 {
  --b: 0%;
}
.bq-5 {
  --b: 5%;
}
.bq-10 {
  --b: 10%;
}
.bq-15 {
  --b: 15%;
}
.bq-20 {
  --b: 20%;
}
.bq-25 {
  --b: 25%;
}
.bq-30 {
  --b: 30%;
}
.bq-35 {
  --b: 35%;
}
.bq-40 {
  --b: 40%;
}
.bq-45 {
  --b: 45%;
}
.bq-50 {
  --b: 50%;
}
.bq-55 {
  --b: 55%;
}
.bq-60 {
  --b: 60%;
}
.bq-65 {
  --b: 65%;
}
.bq-70 {
  --b: 70%;
}
.bq-75 {
  --b: 75%;
}
.bq-80 {
  --b: 80%;
}
.bq-85 {
  --b: 85%;
}
.bq-90 {
  --b: 90%;
}
.bq-95 {
  --b: 95%;
}
.bq-100 {
  --b: 100%;
}
