/* ============================================================================
   fault — S2 · The Split and S3 · The 503 and the quiet (one 360vh pin, Gasp 2)
   CSS default = the still edition's key pose: INTEGRATION in the narrow cut,
   split into three labelled slabs with a gap between them, SYSTEM red, three
   rings drawn from the failure point (the stage centre), "It goes through."
   Panel B (the quiet delivery) stacks under it in the still edition and
   overlays it in motion. mount() moves everything away from this pose.

   Two editions of the word:
   - bands (landscape screens): one line, three clip-path bands of the cap height,
     the layer names in a column to the left of the ink, centred on each band.
   - stacked (portrait, < 1024px): INTE / GRA / TION, one whole line per layer,
     the layer names above each line. --fault-stacked tells the JS which one is on.
   ========================================================================== */

.scene--fault {
  /* Anybody 900, measured: INTEGRATION = 5.375em at wdth 75, cap 0.68em, cap top 0.10em from the
     line box top at line-height 1. The word is a message in transit, so it is set narrow and tall.
     JS refines --fault-fs, --fault-col, --fault-ink-l, --fault-gap and --fault-r after measuring. */
  --fault-stacked: 0;
  --fault-word-em: 5.375;
  --fault-shear-em: 0.12;
  --fault-tag-fs: 12px;
  /* the label column: EXPERIENCE in Plex Mono (0.6em advance) plus air */
  --fault-col: calc(var(--fault-tag-fs) * 6 + 16px);
  --fault-fs: min(
    calc((100vw - 2 * var(--gutter) - var(--fault-col)) / (var(--fault-word-em) + 2 * var(--fault-shear-em))),
    calc(30svh / 0.68)
  );
  --fault-cap-top-l: calc(var(--fault-fs) * 0.1);
  --fault-cap-l: calc(var(--fault-fs) * 0.68);
  --fault-band: calc(var(--fault-cap-l) / 3);
  --fault-shear: calc(var(--fault-fs) * var(--fault-shear-em));
  --fault-gap: calc(var(--fault-fs) * 0.11);
  /* where the ink starts inside the word box: the fit leaves one shear of slack on each side (JS measures) */
  --fault-ink-l: var(--fault-shear);
  /* the failure point: stage centre, on the SYSTEM slab */
  --fault-cy: calc(50% + var(--fault-band) + var(--fault-gap));
  --fault-r: min(7vw, 9svh);
  --fault-flash-r: 120vmax;
  --fault-code-fs: min(40vw, 60svh);
  --fault-retry-1: max(13px, calc(var(--fault-r) * 0.2));
  --fault-retry-2: max(18px, calc(var(--fault-r) * 0.4));
  --fault-retry-3: max(24px, calc(var(--fault-r) * 0.8));
}

/* ---------- the two panels ---------- */
.fault__a,
.fault__b {
  position: relative;
  min-height: 100svh;
  overflow: clip;
}
html.motion .scene--fault:not(.fault--still) .fault__a,
html.motion .scene--fault:not(.fault--still) .fault__b {
  position: absolute;
  inset: 0;
  min-height: 0;
}
html.motion .scene--fault:not(.fault--still) .fault__b {
  pointer-events: none;
}
.scene--fault .corner--tl,
.scene--fault .corner--tr,
.scene--fault .fault__thesis {
  z-index: 1;
}

/* ---------- the word: three clipped copies of INTEGRATION ---------- */
.fault__word {
  position: absolute;
  z-index: 1;
  left: calc(var(--gutter) + var(--fault-col));
  right: var(--gutter);
  top: calc(50% - var(--fault-cap-top-l) - var(--fault-cap-l) / 2);
  height: var(--fault-fs);
  font-size: var(--fault-fs);
  line-height: 1;
  white-space: nowrap;
}
.scene--fault .fault__slab {
  position: absolute;
  inset: 0;
  display: block;
  line-height: 1;
  text-align: center;
  color: var(--bone);
  font-variation-settings: "wdth" 75, "wght" 900;
  font-stretch: 75%;
}
.fault__slab--top {
  clip-path: inset(calc(var(--fault-cap-top-l) - 0.03em) 0 calc(1em - var(--fault-cap-top-l) - var(--fault-band)) 0);
  transform: translate(calc(-1 * var(--fault-shear)), calc(-1 * var(--fault-gap)));
}
.fault__slab--mid {
  clip-path: inset(calc(var(--fault-cap-top-l) + var(--fault-band)) 0 calc(1em - var(--fault-cap-top-l) - 2 * var(--fault-band)) 0);
}
.scene--fault .fault__slab--sys {
  clip-path: inset(calc(var(--fault-cap-top-l) + 2 * var(--fault-band)) 0 calc(1em - var(--fault-cap-top-l) - var(--fault-cap-l) - 0.03em) 0);
  transform: translate(var(--fault-shear), var(--fault-gap));
  color: var(--fault);
}
.fault__letters {
  display: inline-block;
  white-space: nowrap;
}
.fault__l {
  display: inline-block;
}

/* the tags: one column to the left of the ink, each centred on its band */
.fault__tag {
  position: absolute;
  right: calc(100% - var(--fault-ink-l) + var(--fault-shear) + 14px);
  margin-top: calc(-0.5 * var(--fault-tag-fs));
  font-size: var(--fault-tag-fs);
  line-height: 1;
  white-space: nowrap;
  text-align: right;
  color: var(--fg-2);
}
.fault__tag--top {
  top: calc(var(--fault-cap-top-l) + var(--fault-band) / 2);
  transform: translateY(calc(-1 * var(--fault-gap)));
}
.fault__tag--mid {
  top: calc(var(--fault-cap-top-l) + var(--fault-band) * 1.5);
}
.fault__tag--sys {
  top: calc(var(--fault-cap-top-l) + var(--fault-band) * 2.5);
  transform: translateY(var(--fault-gap));
}

/* ---------- the veil, the 503, the rings ---------- */
.fault__veil {
  position: absolute;
  inset: 0;
  z-index: 2;
  background: var(--veil);
  opacity: 0;
  pointer-events: none;
}
.fault__503 {
  position: absolute;
  z-index: 3;
  left: 0;
  right: 0;
  top: var(--fault-cy);
  transform: translateY(calc(-0.42 * var(--fault-code-fs)));
  text-align: center;
  pointer-events: none;
}
html:not(.motion) .fault__503,
.fault--still .fault__503 {
  z-index: 0;
}
.fault__code {
  display: block;
  font-family: var(--mono);
  font-weight: 500;
  font-size: var(--fault-code-fs);
  line-height: 0.8;
  letter-spacing: -0.04em;
  color: var(--bone);
  opacity: 0.08;
}
.fault__meta {
  display: block;
  margin-top: 14px;
  color: var(--bone);
  opacity: 0.55;
}
.fault__rings {
  position: absolute;
  z-index: 3;
  left: 50%;
  top: var(--fault-cy);
  width: 0;
  height: 0;
  pointer-events: none;
}
.fault__ring,
.fault__flash {
  position: absolute;
  display: block;
  border-radius: 50%;
  border: 1px solid var(--bone);
  transform-origin: 50% 50%;
}
.fault__ring--1 {
  --r: var(--fault-r);
}
.fault__ring--2 {
  --r: calc(var(--fault-r) * 2);
}
.fault__ring--3 {
  --r: calc(var(--fault-r) * 4);
}
.fault__ring {
  left: calc(-1 * var(--r));
  top: calc(-1 * var(--r));
  width: calc(2 * var(--r));
  height: calc(2 * var(--r));
}
html:not(.motion) .fault__ring,
.fault--still .fault__ring {
  opacity: 0.4;
}
.fault__flash {
  left: calc(-1 * var(--fault-flash-r));
  top: calc(-1 * var(--fault-flash-r));
  width: calc(2 * var(--fault-flash-r));
  height: calc(2 * var(--fault-flash-r));
  border-width: 3px;
  opacity: 0;
  transform: scale(0);
}
/* "Back off. Retry." hangs from each ring's 60° point, larger each time */
.fault__retry {
  position: absolute;
  max-width: none;
  line-height: 1.05;
  white-space: nowrap;
  color: var(--bone);
}
.fault__retry--1 {
  left: calc(var(--fault-r) * 0.5 + 8px);
  top: calc(var(--fault-r) * 0.87 + 6px);
  font-size: var(--fault-retry-1);
}
.fault__retry--2 {
  left: calc(var(--fault-r) * 1 + 10px);
  top: calc(var(--fault-r) * 1.74 + 8px);
  font-size: var(--fault-retry-2);
}
.fault__retry--3 {
  left: calc(var(--fault-r) * 2 + 12px);
  top: calc(var(--fault-r) * 3.48 + 10px);
  font-size: var(--fault-retry-3);
}
/* the still edition keeps one retry: the diagram is the rings */
html:not(.motion) .fault__retry--1,
html:not(.motion) .fault__retry--3,
.fault--still .fault__retry--1,
.fault--still .fault__retry--3 {
  display: none;
}

/* ---------- the lines ---------- */
.fault__asleep,
.fault__through {
  position: absolute;
  z-index: 3;
  left: var(--gutter);
  right: var(--gutter);
  max-width: none;
  text-align: center;
  pointer-events: none;
}
/* the hold line under the word; the release above it */
.fault__asleep {
  top: calc(50% + var(--fault-cap-l) / 2 + var(--fault-gap) + 28px);
  opacity: 0;
}
.fault__through {
  bottom: calc(50% + var(--fault-cap-l) / 2 + var(--fault-gap) + 40px);
}
html:not(.motion) .fault__asleep,
.fault--still .fault__asleep {
  display: none;
}
.fault__thesis {
  max-width: 24ch;
}
/* the thesis takes the bottom-right corner (DELIVERED arrives there after it leaves); phones keep it bottom-left */
@media (min-width: 768px) {
  .fault__thesis {
    left: auto;
    right: var(--gutter);
    text-align: right;
  }
}

/* ---------- the hidden layer ---------- */
.fault__dlq {
  position: absolute;
  z-index: 4;
  left: calc(var(--gutter) - 12px);
  bottom: max(calc(var(--gutter) - 12px), 12px);
}
.fault__dlq-btn {
  display: inline-flex;
  align-items: center;
  min-height: 48px;
  padding: 0 12px;
  color: var(--fg-2);
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--bone) 35%, transparent);
  text-underline-offset: 4px;
  transition: color 0.25s, text-decoration-color 0.25s;
}
.fault__dlq-btn:hover,
.fault__dlq-btn:focus-visible,
.fault__dlq-btn[aria-expanded="true"] {
  color: var(--bone);
  text-decoration-color: var(--bone);
}
/* keyboard focus or an open card always shows it at full strength, whatever the scrub says */
html.motion .scene--fault:not(.fault--still) .fault__dlq:focus-within {
  opacity: 1 !important;
  visibility: visible !important;
  pointer-events: auto !important;
}
.fault__dlq .card {
  left: 12px;
  bottom: calc(100% + 4px);
  text-align: left;
}

/* ---------- panel B: the quiet delivery ---------- */
.fault__quiet {
  position: absolute;
  left: var(--gutter);
  right: var(--gutter);
  top: 50%;
  transform: translateY(-50%);
  max-width: none;
  text-align: center;
}
.fault__q1,
.fault__q2 {
  display: block;
}
.fault__q2 {
  margin-top: 0.35em;
}

/* ---------- motion edition: layers for the 33 letters on desktop ---------- */
@media (min-width: 1024px) {
  html.motion .scene--fault:not(.fault--still) .fault__l {
    will-change: transform;
  }
}
@media (min-width: 1600px) {
  .scene--fault {
    --fault-tag-fs: 14px;
  }
}

/* ---------- the stacked edition (portrait phones and tablets): one word on three lines ----------
   INTE / GRA / TION, one line per layer. The lines are the slabs: no clipping, the whole letters of each
   line, so the word stays legible at 320px. The mid line (PROCESS) sits on the route line; the split opens
   the leading and shears the lines a little; the failure point is the middle of TION (the stage centre). */
@media (orientation: portrait) and (max-width: 1023px) {
  .scene--fault {
    --fault-stacked: 1;
    --fault-col: 0px;
    /* TION is the widest line: 2.0em at wdth 75 */
    --fault-word-em: 2;
    --fault-shear-em: 0.06;
    --fault-fs: min(
      calc((100vw - 2 * var(--gutter)) / (var(--fault-word-em) + 2 * var(--fault-shear-em))),
      22svh
    );
    --fault-lead: calc(var(--fault-fs) * 0.1);
    --fault-gap: max(calc(var(--fault-fs) * 0.16), calc(var(--fault-tag-fs) + 12px));
    --fault-pitch: calc(var(--fault-cap-l) + var(--fault-lead) + var(--fault-gap));
    --fault-cy: calc(50% + var(--fault-pitch));
    --fault-r: min(12vw, 9svh);
    --fault-code-fs: min(46vw, 24svh);
  }
  .scene--fault .fault__slab {
    clip-path: none;
  }
  .scene--fault .fault__slab--top {
    transform: translate(calc(-1 * var(--fault-shear)), calc(-1 * var(--fault-pitch)));
  }
  .scene--fault .fault__slab--sys {
    transform: translate(var(--fault-shear), var(--fault-pitch));
  }
  .fault__slab--top .fault__l:nth-child(n + 5),
  .fault__slab--mid .fault__l:nth-child(-n + 4),
  .fault__slab--mid .fault__l:nth-child(n + 8),
  .fault__slab--sys .fault__l:nth-child(-n + 7) {
    display: none;
  }
  /* each tag sits just above its own line, in one column at the left edge of the widest line */
  .fault__tag {
    right: auto;
    left: calc(var(--fault-ink-l) - var(--fault-shear));
    margin-top: 0;
    text-align: left;
  }
  .fault__tag--top,
  .fault__tag--mid,
  .fault__tag--sys {
    top: calc(var(--fault-cap-top-l) - var(--fault-tag-fs) - 6px);
  }
  .fault__tag--top {
    transform: translateY(calc(-1 * var(--fault-pitch)));
  }
  .fault__tag--mid {
    transform: none;
  }
  .fault__tag--sys {
    transform: translateY(var(--fault-pitch));
  }
  /* the hold line under TION; the release above INTE */
  .fault__asleep {
    top: calc(50% + var(--fault-pitch) + var(--fault-cap-l) / 2 + 24px);
  }
  .fault__through {
    bottom: calc(50% + var(--fault-pitch) + var(--fault-cap-l) / 2 + var(--fault-tag-fs) + 30px);
  }
  /* the retries hang centred under each ring */
  .fault__retry--1,
  .fault__retry--2,
  .fault__retry--3 {
    left: 0;
    transform: translateX(-50%);
  }
  .fault__retry--1 {
    top: calc(var(--fault-r) + 6px);
  }
  .fault__retry--2 {
    top: calc(var(--fault-r) * 2 + 6px);
  }
  .fault__retry--3 {
    top: calc(var(--fault-r) * 4 + 8px);
  }
}

/* ---------- phones ---------- */
@media (max-width: 767px) {
  .scene--fault {
    --fault-tag-fs: 11px;
    --fault-retry-1: 14px;
    --fault-retry-2: 20px;
    --fault-retry-3: 30px;
  }
  .fault__thesis {
    max-width: calc(100vw - 2 * var(--gutter));
  }
  /* phones: the thesis owns bottom-left, the disclosure bottom-right */
  .fault__dlq {
    left: auto;
    right: calc(var(--gutter) - 12px);
  }
  .fault__dlq .card {
    left: auto;
    right: 12px;
  }
  .fault__dlq-btn {
    font-size: 12px;
  }
  html:not(.motion) .fault__thesis,
  .fault--still .fault__thesis {
    bottom: calc(max(var(--gutter), 24px) + 56px);
  }
}

/* ---------- landscape phones ---------- */
@media (max-height: 500px) and (orientation: landscape) {
  .scene--fault {
    --fault-fs: min(
      calc((100vw - 2 * var(--gutter) - var(--fault-col)) / (var(--fault-word-em) + 2 * var(--fault-shear-em))),
      calc(24svh / 0.68)
    );
    --fault-tag-fs: 10px;
    --fault-gap: max(calc(var(--fault-fs) * 0.11), 10px);
    --fault-r: min(6vw, 9svh);
    --fault-code-fs: min(40vw, 52svh);
    --fault-retry-1: 14px;
    --fault-retry-2: 20px;
    --fault-retry-3: 28px;
  }
  /* no room below the rings: each retry replaces the last, to the right of its ring */
  .fault__retry--1,
  .fault__retry--2,
  .fault__retry--3 {
    transform: translateY(-50%);
  }
  .fault__retry--1 {
    left: calc(var(--fault-r) + 12px);
    top: 0;
  }
  .fault__retry--2 {
    left: calc(var(--fault-r) * 2 + 12px);
    top: 0;
  }
  .fault__retry--3 {
    left: calc(var(--fault-r) * 4 + 12px);
    top: 0;
  }
  .fault__through {
    bottom: auto;
    top: calc(50% + var(--fault-cap-l) / 2 + var(--fault-gap) + 24px);
  }
  .fault__asleep {
    top: calc(50% + var(--fault-cap-l) / 2 + var(--fault-gap) + 24px);
  }
  .fault__thesis {
    font-size: 20px;
  }
  .fault__dlq-btn {
    min-height: 44px;
  }
}
