/* TESS case study (work/tess/). Shared values from css/tokens.css
   (DESIGN-TOKENS.md), shared blocks from css/case-base.css. Calm after
   CASE-STUDY-STANDARD.md 3.5: no boxes around content, no extra labels,
   one stage (05), one stretch of sticky text (06), one demo (radar label).
   Petrol is the project accent: hero, the dark chapters 03 and 06 and the
   exhibits. Radar and interface screens keep their own colours. */

.ts-page {
  --case-accent: #046786;
  --case-accent-on-dark: #82d9e5;
  --case-accent-surface: #f4f5f3;
  --case-accent-dark: #0d252d;
  margin: 0;
  background: var(--color-surface);
  color: var(--color-ink);
  font-family: var(--font-sans);
  overflow-x: clip;
}

.ts-page *,
.ts-page *::before,
.ts-page *::after {
  box-sizing: border-box;
}

.ts-page img,
.ts-page video {
  display: block;
  max-width: 100%;
}

.ts-page button,
.ts-page a {
  touch-action: manipulation;
}

:where(.ts-page) figure {
  margin: 0;
}

.ts-page figcaption {
  margin: var(--space-3) 0 0;
  color: var(--color-ink-muted);
  font-size: var(--text-caption);
  line-height: var(--leading-caption);
  text-align: left;
}

.ts-wrap {
  width: var(--content-width);
  margin-inline: auto;
}

/* One frame for every photo, film and screen: the same radius, films in
   their own 16 : 9. */
.ts-page figure img,
.ts-page figure video {
  width: 100%;
  height: auto;
  border-radius: var(--radius-md);
}

.ts-page figure video {
  aspect-ratio: 16 / 9;
  object-fit: cover;
  background: var(--case-accent-dark);
}

/* ---------- Without JavaScript ---------- */

/* main.js never colours the fixed navigation without JavaScript, and its
   white text would run over the light chapters: give it the chapter dark. */
@media (scripting: none) {
  .ts-page #main-nav {
    background: var(--case-accent-dark);
  }

  /* Loops get their poster from js/tess-story.js; without it the same
     picture stands behind the video as a still. */
  .ts-page video[data-poster] {
    background: var(--poster) center / cover no-repeat;
  }

  .ts-page video[data-poster]::-webkit-media-controls {
    display: none !important;
  }
}

/* ---------- Hero ---------- */

.ts-hero {
  position: relative;
  min-height: 760px;
  height: 100svh;
  max-height: 1100px;
  overflow: hidden;
  background: var(--case-accent-dark);
  color: #fff;
}

.ts-hero-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 48%;
  filter: saturate(0.78);
}

.ts-hero-scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg, rgba(5, 23, 31, 0.83) 0%, rgba(5, 23, 31, 0.5) 48%, rgba(5, 23, 31, 0.08) 100%),
    linear-gradient(0deg, rgba(5, 23, 31, 0.89) 0%, transparent 38%, rgba(5, 23, 31, 0.28) 100%);
}

.ts-hero-content {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  min-height: 100%;
  padding-block: 116px clamp(40px, 7vh, 88px);
}

.ts-hero-main {
  max-width: 1000px;
  margin-top: auto;
}

.ts-hero h1 {
  max-width: 1000px;
  font-size: var(--text-h1);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-h1);
  letter-spacing: var(--tracking-heading);
  text-wrap: balance;
}

.ts-hero h1 em {
  font-style: normal;
  color: var(--case-accent-on-dark);
}

.ts-hero-main > p:not(.case-eyebrow) {
  max-width: 680px;
  margin-top: 35px;
  color: var(--color-ink-on-dark-body);
  font-size: var(--text-lead);
  line-height: var(--leading-lead);
}

/* The global link rule in custom.css sets every a[href] to display:inline. */
.ts-hero-cta {
  display: inline-flex !important;
  align-items: center;
  gap: 34px;
  margin-top: 38px;
  padding: 16px 0;
  border-bottom: 1px solid #fff;
  color: #fff;
  font-size: 16px;
  font-weight: var(--weight-semibold);
  text-decoration: none;
  transition: gap var(--dur-fast);
}

.ts-hero-cta:hover {
  gap: 45px;
}

.ts-meta {
  padding-block: 12px 48px;
  background: var(--case-accent-dark);
  color: #fff;
}

.ts-meta .case-facts {
  margin-top: 0;
}

/* ---------- Sections and headings ---------- */

/* Jump targets: the shared rule .case-chapters ~ section[id] sets the offset. */
.ts-section {
  padding-block: var(--space-section);
}

.ts-section--white {
  background: var(--color-surface);
}

/* Project surface: 01 and 04. */
.ts-section--tint {
  background: var(--case-accent-surface);
}

.ts-section--grey {
  background: var(--color-surface-alt);
}

/* Dark chapters: 03 and 06, no others (3.5). */
.ts-section--dark {
  background: var(--case-accent-dark);
  color: var(--color-ink-on-dark);
}

.ts-section--dark figcaption {
  color: var(--color-ink-on-dark-muted);
}

.ts-head {
  margin-bottom: var(--space-block);
}

.ts-h2 {
  max-width: 920px;
  margin: 0;
  font-size: var(--text-h2);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-h2);
  letter-spacing: var(--tracking-heading);
  text-wrap: balance;
}

.ts-head__intro {
  max-width: 560px;
  margin: var(--space-intro) 0 0;
  color: var(--color-ink-body);
  font-size: var(--text-lead);
  line-height: var(--leading-lead);
}

.ts-section--dark .ts-head__intro {
  color: var(--color-ink-on-dark-body);
}

.ts-head__intro a,
.ts-page .case-reflection a {
  color: var(--color-accent) !important;
  text-decoration: underline !important;
  text-underline-offset: 3px;
}

@media (min-width: 1024px) {
  .ts-head--split {
    display: grid;
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr);
    column-gap: clamp(40px, 6vw, 96px);
    align-items: end;
  }

  .ts-head--split .case-eyebrow {
    grid-column: 1 / -1;
  }

  .ts-head--split .ts-head__intro {
    margin-top: 0;
  }
}

.ts-h3 {
  margin: 0;
  font-size: var(--text-h3);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-h3);
  letter-spacing: var(--tracking-h3);
  text-wrap: balance;
}

/* Body text in the text columns of every chapter. */
.ts-copy p,
.ts-split__text p,
.ts-stepped__text p,
.ts-turn__text p,
.ts-change__text p,
.ts-radar__head p,
.ts-states p {
  max-width: var(--measure-narrow);
  margin: 0;
  color: var(--color-ink-body);
  font-size: var(--text-body);
  line-height: var(--leading-body);
}

.ts-h3 + p,
.ts-copy p + p,
.ts-split__text p + p,
.ts-change__text p + p {
  margin-top: var(--space-5);
}

/* ---------- 01 Starting point ---------- */

.ts-start {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-10) clamp(45px, 8vw, 125px);
  align-items: start;
}

.ts-copy .ts-copy__lead {
  color: var(--color-ink);
  font-size: var(--text-lead);
  line-height: var(--leading-lead);
}

/* The three roles as a plain list between hairlines. */
.ts-roles {
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--color-line-strong);
}

.ts-roles li {
  display: grid;
  grid-template-columns: minmax(130px, 0.4fr) minmax(0, 1fr);
  gap: var(--space-2) var(--space-6);
  align-items: baseline;
  padding-block: var(--space-6);
  border-bottom: 1px solid var(--color-line-strong);
}

.ts-roles strong {
  font-size: var(--text-h4);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-h4);
  letter-spacing: var(--tracking-h3);
}

.ts-roles p {
  margin: 0;
  color: var(--color-ink-body);
  font-size: var(--text-small);
  line-height: var(--leading-small);
}

/* ---------- 02 Fieldwork ---------- */

.ts-field {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: var(--space-10) var(--space-12);
  align-items: start;
}

.ts-field__photo img {
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.ts-systems > div {
  padding-block: var(--space-6) var(--space-8);
  border-bottom: 1px solid var(--color-line-strong);
}

.ts-systems > div:first-child {
  padding-top: 0;
}

.ts-systems h3 {
  margin: 0;
  font-size: var(--text-h4);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-h4);
  letter-spacing: var(--tracking-h3);
}

.ts-systems p {
  max-width: 490px;
  margin: var(--space-3) 0 0;
  color: var(--color-ink-body);
  font-size: var(--text-body);
  line-height: var(--leading-body);
}

.ts-affinity {
  display: grid;
  grid-template-columns: minmax(0, 9fr) minmax(0, 3fr);
  gap: var(--space-3) var(--space-8);
  align-items: end;
  margin-top: var(--space-block);
}

.ts-affinity img {
  max-height: 680px;
  object-fit: cover;
}

.ts-affinity figcaption {
  max-width: 300px;
  margin: 0;
}

/* ---------- 03 Insight ---------- */

.ts-target {
  display: grid;
  grid-template-columns: minmax(0, 8fr) minmax(0, 4fr);
  gap: var(--space-8) var(--space-12);
  align-items: end;
}

/* G1: the matrix stands free on the chapter, no panel of its own. */
.ts-matrix__plot {
  position: relative;
  aspect-ratio: 1.6;
}

.ts-axis {
  position: absolute;
  background: #819da3;
  opacity: 0.72;
}

.ts-axis-x {
  top: 53%;
  right: 8%;
  left: 8%;
  height: 1px;
}

.ts-axis-y {
  top: 10%;
  bottom: 11%;
  left: 51%;
  width: 1px;
}

.ts-axis-label {
  position: absolute;
  color: #a9c4c9;
  font-size: var(--text-micro);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}

.ts-axis-left { top: 55%; left: 5%; }
.ts-axis-right { top: 55%; right: 4%; }
.ts-axis-top { top: 4%; left: 53%; }
.ts-axis-bottom { bottom: 3%; left: 53%; }

.ts-point {
  position: absolute;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 9px;
  color: #e4f2f2;
  font-size: clamp(12px, 1vw, 15px);
  font-weight: var(--weight-semibold);
  white-space: nowrap;
}

.ts-point i {
  position: relative;
  flex: none;
  width: 13px;
  height: 13px;
  border-radius: var(--radius-round);
  background: #9aacb0;
  box-shadow: 0 0 0 5px var(--case-accent-dark);
}

.ts-point-radar { top: 23%; left: 12%; }
.ts-point-electronic { top: 43%; left: 48%; }
.ts-point-paper { top: 79%; left: 62%; }

.ts-point-tess {
  top: 19%;
  left: 68%;
  display: grid;
  grid-template-columns: 18px 1fr;
  gap: 2px 9px;
  color: var(--case-accent-on-dark);
  font-size: clamp(17px, 1.6vw, 25px);
}

.ts-point-tess i {
  grid-row: span 2;
  width: 18px;
  height: 18px;
  background: var(--case-accent-on-dark);
}

.ts-point-tess small {
  grid-column: 2;
  color: #c4e6e9;
  font-size: var(--text-micro);
  font-weight: var(--weight-medium);
  letter-spacing: 0.04em;
}

/* One ring round TESS after the points have appeared. */
.ts-point-tess i::after {
  content: "";
  position: absolute;
  inset: -6px;
  border: 2px solid var(--case-accent-on-dark);
  border-radius: var(--radius-round);
  opacity: 0;
}

/* The points appear one after another, once, in under three seconds:
   paper, electronic, radar, then the target. Only with JavaScript and
   without reduced motion (.ts-motion); otherwise the matrix stands. */
.ts-matrix .ts-point {
  transition: opacity var(--dur-reveal) var(--ease-out), transform var(--dur-reveal) var(--ease-out);
}

.ts-motion .ts-matrix:not(.is-played) .ts-point {
  opacity: 0;
  transform: translateY(10px);
}

.ts-matrix.is-played .ts-point-paper { transition-delay: 0.2s; }
.ts-matrix.is-played .ts-point-electronic { transition-delay: 0.7s; }
.ts-matrix.is-played .ts-point-radar { transition-delay: 1.2s; }
.ts-matrix.is-played .ts-point-tess { transition-delay: 1.9s; }

.ts-motion .ts-matrix.is-played .ts-point-tess i::after {
  animation: ts-ring 1.4s var(--ease-out) 2.4s 1 both;
}

@keyframes ts-ring {
  0% { opacity: 0.9; transform: scale(0.6); }
  100% { opacity: 0; transform: scale(2.4); }
}

.ts-target__line {
  margin: 0 0 var(--space-12);
  color: var(--color-ink-on-dark);
  font-size: var(--text-h3);
  font-weight: var(--weight-medium);
  line-height: var(--leading-h3);
  letter-spacing: var(--tracking-h3);
}

.ts-target__line em {
  font-style: normal;
  font-weight: var(--weight-semibold);
  color: var(--case-accent-on-dark);
}

.ts-theses-lead {
  max-width: var(--measure);
  margin: var(--space-block) 0 0;
  color: var(--color-ink-on-dark-body);
  font-size: var(--text-lead);
  line-height: var(--leading-lead);
}

.ts-theses {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-8) clamp(20px, 2.5vw, 36px);
  margin-top: var(--space-10);
}

.ts-thesis {
  padding-top: var(--space-6);
  border-top: 1px solid var(--color-line-on-dark);
}

.ts-thesis h3 {
  margin: 0;
  font-size: var(--text-h4);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-h4);
  letter-spacing: var(--tracking-h3);
  text-wrap: balance;
}

.ts-thesis p {
  margin: var(--space-3) 0 0;
  color: var(--color-ink-on-dark-body);
  font-size: var(--text-small);
  line-height: var(--leading-small);
}

.ts-thesis .ts-thesis__shaped {
  color: var(--color-ink-on-dark);
}

.ts-ideas {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--space-8) var(--space-12);
  align-items: end;
  margin-top: var(--space-block);
}

.ts-ideas__text {
  max-width: var(--measure-narrow);
  margin: 0 0 var(--space-12);
  color: var(--color-ink-on-dark-body);
  font-size: var(--text-body);
  line-height: var(--leading-body);
}

/* ---------- 04 Workstation ---------- */

.ts-wide img {
  height: clamp(440px, 52vw, 740px);
  object-fit: cover;
  object-position: center 47%;
}

/* Text beside a picture; media first flips the sides. */
.ts-split {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--space-8) var(--space-12);
  align-items: center;
  margin-top: var(--space-block);
}

.ts-split--media-first {
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
}

/* Strip test: the pictures on the left, the steps beside them. */
.ts-kick {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  grid-template-areas:
    "stage steps"
    "cap   steps";
  gap: 0 var(--space-12);
  align-items: center;
  margin-top: var(--space-block);
}

.ts-kick__stage {
  grid-area: stage;
  position: relative;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  border-radius: var(--radius-md);
  background: #e9ecea;
}

.ts-kick > .ts-steps {
  grid-area: steps;
}

.ts-kick > figcaption {
  grid-area: cap;
  align-self: start;
}

.ts-kick__shot {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-standard);
}

.ts-kick__shot.is-active {
  opacity: 1;
}

.ts-page .ts-kick__shot img {
  position: absolute;
  inset: 0;
  height: 100%;
  object-fit: cover;
  border-radius: 0;
}

.ts-page .ts-kick__shot .ts-kick__pressed {
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-standard);
}

.ts-page .ts-kick__shot.is-active .ts-kick__pressed {
  opacity: 1;
  transition-delay: 1s;
}

.ts-stepped {
  margin-top: var(--space-block);
}

.ts-stepped__text {
  max-width: var(--measure-narrow);
  margin-bottom: var(--space-8);
}

/* Two pictures of one size side by side, one caption. */
.ts-pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
}

.ts-page .ts-pair > img,
.ts-page .ts-pair > video {
  aspect-ratio: 3 / 2;
  height: auto;
  object-fit: cover;
}

.ts-pair > figcaption {
  grid-column: 1 / -1;
  margin-top: 0;
}

/* 170°: text and the gesture loop on the left, the comparison beside them. */
.ts-turn {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--space-10) var(--space-12);
  align-items: start;
  margin-top: var(--space-block);
}

.ts-turn__text {
  display: grid;
  gap: var(--space-10);
}

.ts-angle__svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

.ts-angle__desk {
  fill: #fff;
  stroke: #b4b1ab;
  stroke-width: 1.5;
}

.ts-angle__person {
  fill: #f4f3f1;
  stroke: #1d1d1f;
  stroke-width: 2;
}

.ts-angle__wing {
  transform-box: view-box;
  transition: transform 0.9s cubic-bezier(0.65, 0, 0.35, 1);
}

.ts-angle__wing--left { transform-origin: 325px 160px; }
.ts-angle__wing--right { transform-origin: 395px 160px; }

.ts-angle[data-step="0"] .ts-angle__wing--left { transform: rotate(-11deg); }
.ts-angle[data-step="0"] .ts-angle__wing--right { transform: rotate(11deg); }
.ts-angle[data-step="1"] .ts-angle__wing--left { transform: rotate(20deg); }
.ts-angle[data-step="1"] .ts-angle__wing--right { transform: rotate(-20deg); }
.ts-angle[data-step="2"] .ts-angle__wing--left { transform: rotate(5deg); }
.ts-angle[data-step="2"] .ts-angle__wing--right { transform: rotate(-5deg); }

.ts-angle__sight {
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-standard);
}

.ts-angle[data-step="2"] .ts-angle__sight {
  opacity: 1;
  transition-delay: 0.8s;
}

.ts-angle__sight text {
  fill: var(--case-accent);
  font-family: var(--font-sans);
  font-size: 30px;
  font-weight: var(--weight-bold);
}

.ts-angle > .ts-steps {
  margin-top: var(--space-8);
}

/* ---------- Steps beside a sequence (strip test, 170°, strip change) ---------- */

/* The circles of the stage (.case-num). While a sequence runs, the current
   step is filled and the others are muted; without JavaScript and with
   reduced motion all of them read as plain text. */
.ts-steps {
  display: grid;
  gap: var(--space-6);
  margin: 0;
  padding: 0;
  list-style: none;
}

.ts-steps li {
  display: grid;
  grid-template-columns: var(--space-8) minmax(0, 1fr);
  gap: var(--space-1) var(--space-4);
  align-items: start;
}

.ts-steps .case-num {
  grid-row: span 2;
}

.ts-steps strong {
  padding-top: var(--space-1);
  color: var(--color-ink);
  font-size: var(--text-body);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-h4);
  transition: color var(--dur-base) var(--ease-out);
}

.ts-steps p {
  margin: 0;
  color: var(--color-ink-body);
  font-size: var(--text-small);
  line-height: var(--leading-small);
  transition: color var(--dur-base) var(--ease-out);
}

.ts-steps.is-live li:not(.is-current) strong,
.ts-steps.is-live li:not(.is-current) p {
  color: var(--color-ink-muted);
}

.ts-steps li.is-current .case-num {
  background: var(--color-accent);
  color: var(--color-ink-on-dark);
}

.ts-steps--row {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.ts-steps--grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: var(--space-8);
}

/* Caption with the pause control at its end. */
.ts-caption-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  column-gap: var(--space-4);
}

.ts-caption-row > span {
  max-width: var(--measure);
}

.ts-control {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  /* The same width for "Pause" and "Play", so the caption never reflows. */
  min-width: 76px;
  min-height: var(--tap-min);
  /* Centre the 44 px target on the first caption line. */
  margin: -12px calc(-1 * var(--space-2)) -12px 0;
  padding: 0 var(--space-2);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-ink-muted);
  font: var(--weight-semibold) var(--text-caption)/var(--leading-caption) var(--font-sans);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-standard);
}

.ts-control[hidden] {
  display: none;
}

.ts-control:hover {
  color: var(--case-accent);
}

/* Two bars for "Pause", a triangle for "Play". */
.ts-control__icon {
  flex: none;
  width: 10px;
  height: 10px;
  border-right: 3px solid currentColor;
  border-left: 3px solid currentColor;
}

.ts-control[data-action="play"] .ts-control__icon {
  border: 0;
  background: currentColor;
  clip-path: polygon(0 0, 100% 50%, 0 100%);
}

/* ---------- 05 One flight: the stage ---------- */

/* All media share 16 : 9; photos are cropped to it. */
.ts-page .ts-stage .case-stage__media img,
.ts-page .ts-stage .case-stage__media video {
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border: 0;
  border-radius: var(--radius-md);
}

.ts-page .case-stage__screen {
  aspect-ratio: 16 / 9;
  border: 0;
  background: var(--case-accent-dark);
}

.ts-page .case-stage__screen .case-stage__media img,
.ts-page .case-stage__screen .case-stage__media video {
  object-fit: cover;
  border-radius: 0;
}

/* From 1024 px the medium takes two thirds of the width and sticks in the
   middle of the window below navigation and chapter bar, never taller than
   the window. --ts-gap is the column gap; 48 px: gap and progress row. */
.ts-page .ts-stage.is-staged {
  --ts-gap: var(--space-8);
  container-type: inline-size;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  column-gap: var(--ts-gap);
}

.ts-page .ts-stage.is-staged > .case-stage__frame {
  --ts-frame-w: min((100cqi - var(--ts-gap)) * 2 / 3, (100vh - var(--scroll-offset) - var(--space-24)) * 16 / 9);
  width: var(--ts-frame-w);
  top: calc(var(--scroll-offset) + max(var(--space-6), (100vh - var(--scroll-offset) - var(--ts-frame-w) * 9 / 16 - var(--space-12)) / 2));
}

@media (min-width: 1280px) {
  .ts-page .ts-stage.is-staged {
    --ts-gap: var(--space-12);
  }
}

/* The bars under the frame show the position; no "02 / 04" counter. */
.ts-page .case-stage__count {
  display: none;
}

/* case-base.css dims inactive steps to 0.78; on the grey chapter 0.86
   keeps text and numbers above 4.5 : 1. */
.ts-page .case-stage.is-staged .case-stage__step:not(.is-active) .case-stage__text {
  opacity: 0.86;
}

/* ---------- 05 One flight: the changed value ---------- */

.ts-change {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--space-10) var(--space-12);
  align-items: start;
  margin-top: var(--space-section);
  scroll-margin-top: var(--scroll-offset);
}

/* The four interface states of one strip, shown one at a time. */
.ts-strips__stage {
  display: grid;
}

.ts-page .ts-strips__stage > img {
  grid-area: 1 / 1;
  border: 1px solid var(--color-line);
  background: #fff;
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-standard);
}

.ts-page .ts-strips__stage > img.is-active {
  opacity: 1;
}

.ts-strips > .ts-steps {
  margin-top: var(--space-8);
}

.ts-strips > figcaption {
  margin-top: var(--space-6);
}

/* Three paper prototypes in a row. */
.ts-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-4);
  margin-top: var(--space-block);
}

.ts-page .ts-row > img {
  aspect-ratio: 4 / 3;
  height: auto;
  object-fit: cover;
}

.ts-row > figcaption {
  grid-column: 1 / -1;
  margin-top: 0;
}

/* ---------- 05 One flight: the radar label (the demo) ---------- */

.ts-radar {
  margin-top: var(--space-section);
  scroll-margin-top: var(--scroll-offset);
}

.ts-radar__head {
  max-width: var(--measure-narrow);
  margin-bottom: var(--space-8);
}

.ts-radar-explorer {
  display: grid;
  grid-template-columns: minmax(0, 8fr) minmax(0, 4fr);
  gap: var(--space-8) var(--space-12);
  align-items: center;
}

/* The radar screen is the exhibit: its own dark and colours. */
.ts-radar-scene {
  --radar-accent: #7fbc71;
  --radar-callsign: #7fbc71;
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
  border-radius: var(--radius-md);
  background: #1b2329;
}

.ts-radar-scene[data-status="sector"] { --radar-accent: #67bbff; --radar-callsign: #67bbff; }
.ts-radar-scene[data-status="handoff"] { --radar-accent: #67bbff; --radar-callsign: #dfe06d; }
.ts-radar-scene[data-status="warning"] { --radar-accent: #f8ac2c; --radar-callsign: #f8ac2c; }

.ts-radar-map-wrap {
  position: relative;
}

.ts-radar-map {
  display: block;
  width: 100%;
  height: auto;
}

.ts-radar-other-route {
  fill: none;
  stroke: #6c7c82;
  stroke-width: 1.3;
  opacity: 0.5;
}

.ts-radar-route {
  fill: none;
  stroke: var(--radar-accent);
  stroke-width: 3;
  stroke-dasharray: 10 7;
  filter: drop-shadow(0 0 5px var(--radar-accent));
  transition: stroke var(--dur-fast) var(--ease-standard), opacity var(--dur-fast) var(--ease-standard);
}

.ts-radar-forecast {
  fill: var(--radar-accent);
  opacity: 0.65;
}

.ts-radar-range {
  fill: rgba(255, 255, 255, 0.025);
  stroke: var(--radar-accent);
  stroke-width: 1.3;
  opacity: 0.75;
}

.ts-radar-aircraft {
  fill: var(--radar-accent);
  filter: drop-shadow(0 0 9px var(--radar-accent));
}

.ts-radar-leader {
  fill: none;
  stroke: var(--radar-accent);
  stroke-width: 1.5;
}

.ts-radar-label {
  position: absolute;
  top: 23%;
  left: 52%;
  z-index: 1;
  display: grid;
  gap: 5px;
  min-width: 155px;
  padding: 10px 12px;
  border: 1px solid var(--radar-accent);
  background: rgba(21, 32, 39, 0.94);
  color: var(--radar-accent);
  font-family: Menlo, Consolas, monospace;
  font-size: 12px;
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-standard), color var(--dur-fast) var(--ease-standard), border-color var(--dur-fast) var(--ease-standard);
}

.ts-radar-label:hover {
  background: #304148;
}

.ts-radar-callsign {
  color: var(--radar-callsign);
  font-size: 15px;
  font-weight: var(--weight-bold);
}

.ts-radar-label-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.ts-radar-label-row strong {
  font-size: 14px;
}

.ts-radar-label-row small {
  display: none;
  color: #b7cacf;
  font-size: 8px;
  white-space: nowrap;
}

.ts-radar-scene.is-updated .ts-radar-label-row small {
  display: block;
}

.ts-radar-label-row:last-child {
  padding-top: 5px;
  border-top: 1px solid currentColor;
  font-size: 10px;
  letter-spacing: 0.05em;
}

.ts-radar-direction {
  font-size: 16px;
}

.ts-radar-scene[data-selected="false"] .ts-radar-route,
.ts-radar-scene[data-selected="false"] .ts-radar-range,
.ts-radar-scene[data-selected="false"] .ts-radar-forecast,
.ts-radar-scene[data-selected="false"] .ts-radar-leader {
  opacity: 0.16;
}

.ts-radar-scene[data-selected="false"] .ts-radar-label {
  opacity: 0.6;
}

.ts-radar-scene-bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  min-height: 84px;
  padding: 18px 24px;
  border-top: 1px solid #3d4c53;
  color: #b2c8cc;
  font-size: 10px;
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-label);
}

.ts-radar-scene-bottom > span {
  max-width: 230px;
  line-height: 1.4;
  text-align: right;
  text-transform: uppercase;
}

.ts-radar-strip {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 3px 12px;
  min-width: 150px;
  padding: 9px 12px;
  border: 1px solid #8ba4aa;
  background: #e9e7de;
  color: #23353b;
  font-family: Menlo, Consolas, monospace;
  text-align: left;
  cursor: pointer;
  transition: opacity var(--dur-fast), transform var(--dur-fast);
}

.ts-radar-strip:hover {
  transform: translateY(-2px);
}

.ts-radar-strip span,
.ts-radar-strip strong {
  font-size: 12px;
  white-space: nowrap;
}

.ts-radar-strip small {
  grid-column: 1 / -1;
  color: #52676a;
  font-size: 8px;
  letter-spacing: 0.08em;
}

.ts-radar-scene[data-selected="false"] .ts-radar-strip {
  opacity: 0.45;
}

.ts-radar-scene.is-confirming .ts-radar-label {
  animation: ts-radar-confirm 0.8s var(--ease-standard);
}

@keyframes ts-radar-confirm {
  0%, 100% { background: rgba(21, 32, 39, 0.94); color: var(--radar-accent); }
  35%, 70% { background: var(--radar-accent); color: #101e24; }
}

/* The controls sit on the chapter itself: plain text and outlined buttons. */
.ts-radar-controls {
  display: grid;
  gap: var(--space-10);
}

.ts-radar-group p {
  margin: 0;
  color: var(--color-ink-body);
  font-size: var(--text-small);
  line-height: var(--leading-small);
}

.ts-radar-statuses {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-2);
  margin-top: var(--space-4);
}

/* Outline at least 3 : 1 against the grey chapter (WCAG 1.4.11). */
.ts-radar-statuses button,
.ts-radar-change {
  min-height: var(--tap-min);
  padding: 10px 14px;
  border: 1px solid var(--color-ink-muted);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-ink);
  font: var(--weight-semibold) var(--text-caption)/1.3 var(--font-sans);
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-fast), color var(--dur-fast), border-color var(--dur-fast);
}

.ts-radar-statuses button:hover,
.ts-radar-change:hover {
  border-color: var(--case-accent);
}

.ts-radar-statuses button[aria-pressed="true"],
.ts-radar-change[aria-pressed="true"] {
  border-color: var(--case-accent);
  background: var(--case-accent);
  color: #fff;
}

.ts-radar-change {
  width: 100%;
  margin-top: var(--space-4);
}

.ts-states {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: var(--space-10) var(--space-12);
  align-items: start;
  margin-top: var(--space-block);
}

.ts-states__text,
.ts-states__side {
  display: grid;
  gap: var(--space-8);
  align-content: start;
}

.ts-states__stack {
  display: grid;
  gap: var(--space-3);
}

.ts-page .ts-states__stack img {
  border: 1px solid var(--color-line);
  background: #fff;
}

.ts-states__stack figcaption {
  margin-top: var(--space-1);
}

/* ---------- 06 Model: sticky text beside the build ---------- */

.ts-pin {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--space-10) var(--space-12);
  align-items: start;
}

.ts-pin__text p {
  max-width: var(--measure-narrow);
  margin: 0;
  color: var(--color-ink-on-dark-body);
  font-size: var(--text-body);
  line-height: var(--leading-body);
}

.ts-pin__text .ts-pin__lead {
  color: var(--color-ink-on-dark);
  font-size: var(--text-lead);
  line-height: var(--leading-lead);
}

.ts-pin__text p + p {
  margin-top: var(--space-6);
}

.ts-film-link {
  display: inline-flex !important;
  gap: 35px;
  margin-top: var(--space-8);
  padding: 16px 0;
  border-bottom: 1px solid currentColor;
  color: var(--color-ink-on-dark);
  font-size: 16px;
  font-weight: var(--weight-semibold);
  text-decoration: none;
}

.ts-pin__media {
  display: grid;
  gap: var(--space-12);
}

/* Only on windows tall enough for the whole text. */
@media (min-width: 1024px) and (min-height: 720px) {
  .ts-pin__text {
    position: sticky;
    top: calc(var(--scroll-offset) + var(--space-8));
  }
}

/* ---------- 07 What remains ---------- */

.ts-page .case-reflection {
  margin-top: 0;
}

/* ---------- Reveal on scroll (only with JS and without reduced motion) ---------- */

.ts-motion .ts-reveal {
  opacity: 0;
  transform: translateY(var(--reveal-distance));
  transition: opacity var(--dur-reveal) var(--ease-out), transform var(--dur-reveal) var(--ease-out);
}

.ts-motion .ts-reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* ---------- Responsive ---------- */

@media (max-width: 1023.98px) {
  .ts-hero {
    min-height: 700px;
  }

  .ts-hero-photo {
    object-position: 58% center;
  }

  .ts-hero-scrim {
    background:
      linear-gradient(90deg, rgba(5, 23, 31, 0.85), rgba(5, 23, 31, 0.2)),
      linear-gradient(0deg, rgba(5, 23, 31, 0.85), transparent 60%);
  }

  .ts-start,
  .ts-field,
  .ts-target,
  .ts-ideas,
  .ts-split,
  .ts-split--media-first,
  .ts-turn,
  .ts-change,
  .ts-states,
  .ts-pin,
  .ts-radar-explorer,
  .ts-affinity {
    grid-template-columns: minmax(0, 1fr);
  }

  .ts-affinity figcaption {
    max-width: var(--measure);
  }

  .ts-target__line,
  .ts-ideas__text {
    margin-bottom: 0;
  }

  /* One column: the caption stays under the pictures, the steps follow. */
  .ts-kick {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "stage"
      "cap"
      "steps";
  }

  .ts-kick > .ts-steps {
    margin-top: var(--space-8);
  }

  .ts-radar-controls {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-8);
  }
}

/* Beside the text, the comparison is too narrow for three columns. */
@media (min-width: 1024px) and (max-width: 1279.98px) {
  .ts-angle .ts-steps--row {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 767.98px) {
  .ts-steps--row,
  .ts-steps--grid,
  .ts-radar-controls {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 639.98px) {
  .ts-hero {
    height: auto;
    min-height: 740px;
  }

  .ts-hero-content {
    padding-block: 110px 48px;
  }

  .ts-hero-main > p:not(.case-eyebrow) {
    margin-top: 25px;
  }

  .ts-hero-photo {
    object-position: 61% center;
  }

  .ts-hero-scrim {
    background:
      linear-gradient(90deg, rgba(5, 23, 31, 0.76), rgba(5, 23, 31, 0.2)),
      linear-gradient(0deg, rgba(5, 23, 31, 0.91), transparent 80%);
  }

  .ts-meta {
    padding-block: 8px 36px;
  }

  .ts-roles li,
  .ts-theses,
  .ts-pair,
  .ts-row {
    grid-template-columns: minmax(0, 1fr);
  }

  /* The build stays in pairs, so chapter 06 does not run on for screens. */
  .ts-pin__media .ts-pair {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-2);
  }

  .ts-wide img {
    height: 420px;
  }

  .ts-matrix__plot {
    aspect-ratio: 1.15;
  }

  .ts-axis-left,
  .ts-axis-right {
    top: 57%;
    font-size: 9px;
  }

  .ts-axis-top,
  .ts-axis-bottom {
    font-size: 9px;
  }

  .ts-point {
    gap: 4px;
    max-width: 100px;
    font-size: 11px;
    white-space: normal;
  }

  .ts-point i {
    width: 9px;
    height: 9px;
  }

  .ts-point-radar { top: 23%; left: 10%; }
  .ts-point-electronic { top: 43%; left: 36%; }
  .ts-point-paper { top: 78%; left: 61%; }

  .ts-point-tess {
    top: 14%;
    left: 66%;
    grid-template-columns: 13px 1fr;
    font-size: 17px;
  }

  .ts-point-tess i {
    width: 13px;
    height: 13px;
  }

  .ts-point-tess small {
    font-size: 9px;
  }

  .ts-radar-scene-bottom {
    min-height: 72px;
    padding: 14px;
    font-size: 9px;
  }

  .ts-radar-label {
    top: 20%;
    left: 47%;
    min-width: 128px;
    padding: 7px 8px;
    font-size: 10px;
  }

  .ts-radar-callsign {
    font-size: 12px;
  }

  .ts-radar-label-row strong {
    font-size: 11px;
  }

  .ts-radar-label-row small {
    font-size: 7px;
  }

  .ts-radar-strip {
    min-width: 115px;
    padding: 7px 8px;
  }

  .ts-radar-strip span,
  .ts-radar-strip strong {
    font-size: 10px;
  }
}

/* ---------- Without JavaScript and with reduced motion: no sequences ---------- */

/* The strip test shows the three models side by side, pressed, the strip
   change its four states one under another. The 170° comparison rests on
   170° (data-step="2" in the markup). Reduced motion may also come on after
   loading: js/tess-story.js then ends a running sequence. */
@media (scripting: none), (prefers-reduced-motion: reduce) {
  .ts-kick,
  .ts-page .ts-kick {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "stage"
      "steps"
      "cap";
  }

  .ts-kick__stage {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-4);
    aspect-ratio: auto;
    overflow: visible;
    border-radius: 0;
    background: none;
  }

  .ts-kick__shot {
    position: relative;
    aspect-ratio: 3 / 2;
    overflow: hidden;
    border-radius: var(--radius-md);
    background: #e9ecea;
    opacity: 1;
  }

  .ts-page .ts-kick__shot .ts-kick__pressed {
    opacity: 1;
  }

  .ts-kick > .ts-steps {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    margin-top: var(--space-6);
  }

  .ts-kick > figcaption {
    margin-top: var(--space-6);
  }

  .ts-strips__stage {
    gap: var(--space-3);
  }

  .ts-page .ts-strips__stage > img {
    grid-area: auto;
    opacity: 1;
  }
}

@media (scripting: none) and (max-width: 767.98px), (prefers-reduced-motion: reduce) and (max-width: 767.98px) {
  .ts-kick > .ts-steps {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (prefers-reduced-motion: reduce) {
  .ts-page *,
  .ts-page *::before,
  .ts-page *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0s !important;
  }

  .ts-reveal,
  .ts-matrix .ts-point {
    opacity: 1 !important;
    transform: none !important;
  }
}
