/*
  The two scroll-driven illustrations on the Constat page: the working week
  that fills up (section 01) and the overlay of the role as designed against
  the week as worked (section 02).

  This file holds their mechanics and their geometry: the tall tracks, the
  pinned stage, the calendar grid, and what each scroll stage hides or moves.
  What a chip, a bar, a legend entry, a caption or a button looks like comes
  from the design system and is not restated here. Every colour in this file
  is a design-system variable, and the file sets no font and no font size.
  scripts/check-design-system.sh fails if that stops being true.

  How a stage works. The markup is the end state: the overrun week, the
  labelled findings. Without an attribute on <html> the rules below draw
  exactly that, so a reader without JavaScript sees both illustrations
  complete. A script in the head sets data-stage="0" and data-xf="0" before
  the first paint, and the script at the foot of the page counts both up
  while the reader scrolls through a track, then removes them. A stage rule
  only ever takes something back from the end state.

  Keep it this way round. A stage rule that adds something the markup lacks
  breaks the page for everyone whose script did not run.
*/

/* ---------- Track and pinned stage, both illustrations ---------- */

/* The track is several screens tall and the stage inside it stays pinned, so
   scrolling moves through the stages and not through the picture. A phone
   gets shorter tracks: the same number of stages in less thumb travel. */
.scene {
  position: relative;
  height: 330vh;
}
.scene--overlay {
  height: 300vh;
}
.scene__pin {
  position: sticky;
  top: 0;
  display: flex;
  align-items: center;
  min-height: 100svh;
  padding-block: var(--spacing-break);
}
/* 860px is the design system's md breakpoint. A media query cannot read a
   variable, so the number is repeated here. */
@media (min-width: 860px) {
  .scene {
    height: 400vh;
  }
  .scene--overlay {
    height: 360vh;
  }
}

/* One caption per stage, all in the markup. Room for two lines is reserved,
   so the stage does not jump when a caption wraps. */
.scene__caption {
  min-height: 2.6em;
}
.scene__caption > span {
  display: none;
}
html[data-stage="0"] .scene--week [data-cap="0"],
html[data-stage="1"] .scene--week [data-cap="1"],
html[data-stage="2"] .scene--week [data-cap="2"],
html[data-stage="3"] .scene--week [data-cap="3"],
html:not([data-stage]) .scene--week [data-cap="end"],
html[data-xf="0"] .scene--overlay [data-cap="0"],
html[data-xf="1"] .scene--overlay [data-cap="1"],
html[data-xf="2"] .scene--overlay [data-cap="2"],
html:not([data-xf]) .scene--overlay [data-cap="end"] {
  display: block;
}

/* ---------- 01 The week ---------- */

/* The bar under the caption is full at the end of the week. */
.scene--week .progress {
  --value: 100%;
}
html[data-stage="0"] .scene--week .progress {
  --value: 8%;
}
html[data-stage="1"] .scene--week .progress {
  --value: 33%;
}
html[data-stage="2"] .scene--week .progress {
  --value: 58%;
}
html[data-stage="3"] .scene--week .progress {
  --value: 84%;
}

/* The calendar: a narrow column for the hours and five days. The glow of
   the band shows through the sheet. */
.week {
  overflow: hidden;
  /* Five squeezed columns would make the chips unreadable on a phone, so the
     calendar keeps this width and its wrapper scrolls sideways. */
  min-width: 560px;
  border: 1px solid var(--lw-line);
  background: var(--lw-scrim);
  backdrop-filter: blur(3px);
}
.week__head,
.week__body {
  display: grid;
  grid-template-columns: 46px repeat(5, 1fr);
}
.week__head {
  border-bottom: 1px solid var(--lw-line);
}
.week__head > * {
  padding: 9px 8px;
}
.week__hours {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 9px 5px;
  border-right: 1px solid var(--lw-line);
}
.week__day {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-height: 200px;
  padding: 8px 6px;
  border-right: 1px solid var(--lw-line);
}
.week__day:last-child {
  border-right: 0;
}
@media (min-width: 860px) {
  .week__day {
    min-height: 270px;
  }
}

/* A chip fades and settles in when it arrives. The three colour transitions
   are the design system's own, repeated because a transition list replaces
   the whole list and does not add to it. */
.week .event {
  transition:
    opacity var(--duration-scene) ease,
    transform var(--duration-scene) var(--ease-brand),
    background-color var(--duration-scene) ease,
    border-color var(--duration-scene) ease,
    color var(--duration-scene) ease;
}
/* data-in="n": the chip arrives at stage n, so every stage below n hides it. */
html[data-stage="0"] .week [data-in],
html[data-stage="1"] .week [data-in="2"],
html[data-stage="1"] .week [data-in="3"],
html[data-stage="2"] .week [data-in="3"] {
  opacity: 0;
  transform: translateY(-7px) scale(0.97);
  pointer-events: none;
}
/* data-dies="n": the chip is crowded out at stage n. In the markup it is
   already .event--dropped, so below n it is given back the fill, the text
   colour and the plain text of the role work it still is. */
html[data-stage="0"] .week [data-dies],
html[data-stage="1"] .week [data-dies="2"],
html[data-stage="1"] .week [data-dies="3"],
html[data-stage="2"] .week [data-dies="3"] {
  background-color: var(--lw-surface-2);
  color: var(--lw-text);
  text-decoration-line: none;
}

/* The hint only makes sense while there are stages to scroll through, and
   the replay button only once the week is over. Each keeps its place while
   hidden, so nothing moves when they swap. */
.scene__hint {
  opacity: 0;
  transition: opacity var(--duration-scene) ease;
}
html[data-stage] .scene__hint {
  opacity: 1;
}
.replay {
  transition:
    opacity var(--duration-scene) ease,
    color var(--duration-fast) ease;
}
html[data-stage] .replay {
  opacity: 0;
}

/* ---------- 02 The overlay ---------- */

/* The longest caption of this illustration runs to three lines. */
.scene--overlay .scene__caption {
  min-height: 3.75em;
}

/* Each row carries its lengths as custom properties in the markup, as the
   design system's bar encoding asks for, plus --tilt for stage 1.

   The script uses four thresholds here, so data-xf also takes the value "3".
   That stage is a pause before the findings: it looks like stage 2, and it
   has no caption. */
.scene--overlay .bars__row > * {
  transition:
    opacity var(--duration-scene) ease,
    transform var(--duration-scene) var(--ease-brand),
    width var(--duration-scene) var(--ease-brand),
    left var(--duration-scene) var(--ease-brand);
}
.scene--overlay .bars__label,
.scene--overlay .bars__delta > span {
  transition: opacity var(--duration-scene) ease;
}

/* The end state: each deviation is a finding with its code in the bar and
   its name above the row. The plan is a faint outline and the worked week
   is gone, so the findings are what is left. */
.scene--overlay .bars__expected {
  opacity: 0.12;
}
.scene--overlay .bars__actual {
  opacity: 0;
}

/* Every stage before the end: no finding has a name or a code yet. */
html[data-xf] .scene--overlay .bars__label,
html[data-xf] .scene--overlay .bars__delta > span {
  opacity: 0;
}
html[data-xf] .scene--overlay .bars__expected,
html[data-xf] .scene--overlay .bars__actual {
  opacity: 1;
}
/* Stage 0: only the role as designed. */
html[data-xf="0"] .scene--overlay .bars__actual {
  opacity: 0;
  transform: translateY(20px) rotate(-0.8deg);
}
html[data-xf="0"] .scene--overlay .bars__delta,
html[data-xf="1"] .scene--overlay .bars__delta {
  opacity: 0;
}
/* Stage 1: the week as worked appears underneath and slightly tilted, as a
   second and separate source. The last row needs room below it for that. */
html[data-xf="1"] .scene--overlay .bars__actual {
  transform: translateY(38px) rotate(var(--tilt, -1deg));
}
html[data-xf="1"] .scene--overlay .bars {
  padding-bottom: 44px;
}
/* Stages 2 and 3: laid over each other. What matches fades, what sticks out
   stays. The outline of the plan is drawn on top of the other bars, so at
   full strength it would cover the dashed edge of a shortfall. */
html[data-xf="2"] .scene--overlay .bars__expected,
html[data-xf="3"] .scene--overlay .bars__expected {
  opacity: 0.3;
}
html[data-xf="2"] .scene--overlay .bars__actual,
html[data-xf="3"] .scene--overlay .bars__actual {
  opacity: 0.34;
}

/* The legend entry of the current stage is lit. */
.scene--overlay .legend__item {
  transition: color var(--duration-scene) ease;
}
html[data-xf="0"] .scene--overlay .legend__item:nth-child(1),
html[data-xf="1"] .scene--overlay .legend__item:nth-child(2),
html[data-xf="2"] .scene--overlay .legend__item:nth-child(3),
html:not([data-xf]) .scene--overlay .legend__item:nth-child(4) {
  color: var(--lw-accent-text);
}
