/*
  Kinetic Signal: About (about.html).
  Sections: #intro (fitted ABOUT), #story (SM7 signal trace portrait, four chapters, the self
  quote), #difference (four panels with receipts), #reach (the reach map), #start.
  Shared components and every token come from base.css.
  Order: page layout, components, sections, animations (hidden states), media queries.
*/

/* ==========================================================================
   #intro
   ========================================================================== */

.page-about .page-intro {
  padding-bottom: var(--s-8);
}

.page-about .h1-sub {
  max-width: 24ch;
  text-wrap: balance;
}

/* ==========================================================================
   Signal-path diagram parts (DESIGN.md 3.4), used by the reach map.
   Work has its own, larger set in work.css (two pages only, so the rules stay page-scoped).
   ========================================================================== */

.sp {
  width: 100%;
  height: auto;
  overflow: visible;
  fill: none;
}

.sp--wide {
  display: none;
}

.sp--compact {
  max-width: 27.5rem;
}

/* Butt caps: a square cap would leave a dot at the start of a path that is not drawn yet. */
.sp-signal path {
  stroke: var(--accent);
  stroke-width: 10;
  stroke-linejoin: round;
}

.sp-node {
  fill: var(--accent);
}

.sp-big {
  fill: var(--fg);
  font-stretch: 62%;
  font-weight: 900;
  letter-spacing: 0.02em;
}

.sp-small {
  fill: var(--fg-2);
  font-stretch: 75%;
  font-weight: 600;
  letter-spacing: 0.08em;
}

/* ==========================================================================
   #story: the portrait, the chapter index, the chapters, the self quote
   ========================================================================== */

.story {
  padding-bottom: var(--section-y);
}

.story-grid {
  row-gap: var(--s-7);
}

.portrait {
  display: grid;
  gap: var(--s-3);
  width: min(100%, 22rem);
}

/*
  The frame holds the fallback photo and, over it, the WebGL canvas.
  Fallback duotone (DESIGN.md 2.4): the gray photo multiplies onto paper, then a blue layer
  screens over it, so shadows turn blue and highlights stay paper.
*/
.portrait-frame {
  position: relative;
  isolation: isolate;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background: var(--paper);
}

.portrait-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 52% 30%;
  filter: grayscale(1) contrast(1.25);
  mix-blend-mode: multiply;
}

.portrait-frame::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--blue);
  mix-blend-mode: screen;
  pointer-events: none;
}

/* The canvas has the page ground, so the traces sit on the field with no frame edge. */
.portrait-canvas {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  background: var(--ground);
  opacity: 0;
  transition: opacity var(--dur-reveal) linear;
  pointer-events: none;
}

.portrait-frame.is-live .portrait-canvas {
  opacity: 1;
}

.portrait-caption {
  color: var(--fg-2);
}

/* The chapter index sits under the sticky portrait from 768px and beside it from 1024px. */
.story-index {
  display: none;
}

.story-index-link {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-height: var(--tap);
  color: var(--fg-2);
  transition: color var(--dur-tick) linear;
}

.story-index-link:hover {
  color: var(--fg);
}

.story-index-link[aria-current="true"] {
  color: var(--accent);
}

.story-index-num {
  font-variant-numeric: tabular-nums;
}

.chapter {
  display: grid;
  align-content: start;
  gap: var(--s-4);
  padding-block: var(--s-6) var(--s-7);
  border-top: 1px solid var(--line);
}

.chapter-num {
  color: var(--fg-2);
}

.chapter-text {
  max-width: 30em;
  font-size: var(--fs-lead);
  font-weight: 500;
  line-height: 1.4;
  text-wrap: pretty;
}

/* Amr's own words: the one quote on the site that is not a client review. */
.self-quote {
  display: grid;
  gap: var(--s-5);
  margin-top: var(--s-8);
}

.self-quote blockquote {
  max-width: 22em;
  font-size: clamp(2rem, 1rem + 3.5vw, 3.75rem);
  font-stretch: 112%;
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.self-quote figcaption {
  color: var(--fg-2);
}

/* ==========================================================================
   #difference: four panels, each with one receipt
   ========================================================================== */

.diff-grid {
  row-gap: var(--s-7);
}

/* No side inset: every panel starts on the column edge, like the section head. */
.diff-panel {
  display: grid;
  align-content: start;
  gap: var(--s-4);
  padding-inline: 0;
}

.diff-num {
  color: var(--fg-2);
}

.diff-line {
  max-width: 28em;
  font-size: var(--fs-lead);
  font-weight: 500;
  line-height: 1.35;
}

/* A receipt: the client's words under the claim, on an accent bar (the panel has the rule). */
.receipt {
  margin-top: var(--s-4);
  padding-top: 0;
  padding-inline-start: var(--s-4);
  border-top: 0;
  border-inline-start: 0.375rem solid var(--accent);
}

.diff-more {
  margin-top: var(--s-8);
  font-size: var(--fs-lead);
  font-weight: 600;
}

/* ==========================================================================
   #start: on the narrowest phones the title follows the width, so "exceptional." stays one word
   ========================================================================== */

.page-about .cta-title {
  font-size: min(var(--fs-d1), 10.4vw);
}

/* ==========================================================================
   Animations: hidden states (motion on, JS on; see base.css)
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {
  /* The three branches of the reach map leave the hub 150ms apart. */
  html.js:not(.motion-off) .reach .reach-b2 {
    transition-delay: 150ms;
  }

  html.js:not(.motion-off) .reach .reach-b3 {
    transition-delay: 300ms;
  }
}

/* ==========================================================================
   Media queries
   ========================================================================== */

@media (min-width: 768px) {
  .sp--wide {
    display: block;
  }

  .sp--compact {
    display: none;
  }

  /*
    The portrait and the index (3 of 8 columns) stay in view while the chapters (5 columns)
    scroll past. The portrait is never taller than the screen under the header, with the
    caption and the index (about 14rem) under it.
  */
  .story-aside {
    position: sticky;
    top: calc(var(--header-h) + var(--s-5));
    grid-column: 1 / 4;
    align-self: start;
    display: grid;
    gap: var(--s-4);
  }

  .portrait {
    width: min(100%, 20rem, calc((100svh - var(--header-h) - var(--s-5) - 16rem) * 0.8));
  }

  .story-index {
    display: block;
  }

  .story-chapters {
    grid-column: 4 / -1;
  }

  .chapter {
    min-height: 50vh;
  }

  .chapter:last-child {
    min-height: 0;
    padding-bottom: 0;
  }

  .diff-panel {
    grid-column: span 4;
  }
}

@media (min-width: 1024px) {
  .page-about .page-intro {
    padding-bottom: var(--s-9);
  }

  /* Half the grid: the portrait, with the index beside it. */
  .story-aside {
    top: calc(var(--header-h) + var(--s-6));
    grid-column: 1 / 7;
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: var(--gutter);
    align-items: start;
  }

  /* 30rem at most, and never taller than the screen under the header (caption included). */
  .portrait {
    width: min(100%, 30rem, calc((100svh - var(--header-h) - var(--s-6) - 5rem) * 0.8));
  }

  .story-index {
    min-width: 9rem;
  }

  .story-chapters {
    grid-column: 7 / -1;
    padding-inline-start: var(--s-6);
  }

  .chapter {
    min-height: 70vh;
  }

  /* Columns 2 to 11. */
  .self-quote {
    margin-top: var(--section-y);
    margin-inline: calc((100% - 11 * var(--gutter)) / 12 + var(--gutter));
  }

  .diff-panel {
    grid-column: span 6;
  }
}
