/*
 * The pipeline map on the AI page.
 *
 * Loaded only by ai.html. It could have gone into section.css, which every section page
 * already fetches, but that would post the cost of one page's component to six pages that
 * never render it.
 */

.pipeline {
  margin: 1.5rem 0 2.5rem;
}

/* The tab strip is built by script, so it is styled but never assumed: without JavaScript
   this file simply has nothing to match. */
.pipeline-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 1.25rem;
}

.pipeline-tab {
  font: inherit;
  font-size: 0.85rem;
  letter-spacing: 0.02em;
  color: var(--muted-color);
  background: var(--panel-bg);
  border: 1px solid var(--border-color);
  border-radius: 999px;
  padding: 0.4rem 0.9rem;
  cursor: pointer;
  transition: color 160ms, background-color 160ms, border-color 160ms;
}

.pipeline-tab:hover {
  color: var(--text-color);
}

.pipeline-tab[aria-selected="true"] {
  color: #ffffff;
  background: var(--accent);
  border-color: var(--accent);
}

/* Focus has to survive the selected state, because keyboard arrows move selection and
   focus together - without this the visible ring vanishes exactly when it is being used. */
.pipeline-tab:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.pipeline-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.9rem;
  /* Two across wherever there is room. Seventeen identical cards in a single column read
     as a list to be skimmed; two columns read as a chart to be scanned. */
  counter-reset: discipline;
}

.pipeline-row {
  padding: 0.9rem 1rem;
  background: var(--panel-bg);
  border: 1px solid var(--border-color);
  border-radius: 0.5rem;
}

.pipeline-row {
  counter-increment: discipline;
}

/* Numbered, because a numbered set reads as a survey of a whole field rather than as a
   handful of examples someone happened to pick. */
.pipeline-row h4::before {
  content: counter(discipline, decimal-leading-zero);
  margin-right: 0.5rem;
  font-size: 0.75rem;
  font-weight: 400;
  color: var(--accent);
}

.pipeline-row h4 {
  margin: 0 0 0.5rem;
  font-size: 1rem;
}

.pipeline-row p {
  margin: 0 0 0.35rem;
  font-size: 0.92rem;
  line-height: 1.5;
}

.pipeline-row p:last-of-type {
  margin-bottom: 0;
}

.pipeline-copy {
  color: var(--muted-color);
}

/* --------------------------------------------------------------- the discipline pipes */

/* The sprite is definitions only; it must take no space and announce nothing. */
.pipe-sprite {
  display: none;
}

/*
 * One production pipeline per discipline, read left to right: where the work starts, the
 * tools that enter along the way, and the person who closes it. An ordered list because
 * that is what it is - the sequence carries the meaning, so it has to survive with the
 * stylesheet switched off.
 */
.pipe {
  list-style: none;
  display: flex;
  align-items: stretch;
  gap: 1.5rem;
  margin: 0.75rem 0 0;
  padding: 0.25rem 0 0.5rem;
  /* Long pipelines scroll rather than wrap: a flow chart that wraps to a second line stops
     reading as one sequence. */
  flex-wrap: wrap;
  row-gap: 1.5rem;
}

.pipe-node {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: 0 0 auto;
  width: 4.25rem;
  text-align: center;
}

/*
 * A stage's tools are alternatives, so they stack. Laid side by side with arrows between
 * them - which is how this read before - they claimed to be consecutive steps, and a
 * visitor would reasonably conclude that every logo went into every job.
 */
.pipe-marks {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.95rem;
}

/* "or", set once between stacked alternatives. */
[data-choice="or"] .pipe-dot + .pipe-dot::before {
  content: "or";
  position: absolute;
  left: 50%;
  top: -0.82rem;
  transform: translateX(-50%);
  font-size: 0.56rem;
  line-height: 1;
  letter-spacing: 0.04em;
  color: var(--muted-color);
}

/* The label sits under the tallest stack in the row, so every caption lines up. */
/* The shaft, drawn across the gap to the left of every stage but the first. */
.pipeline-row .pipe-node + .pipe-node::before {
  content: "";
  position: absolute;
  left: -1.5rem;
  top: 4.15rem;
  width: 1.5rem;
  border-top: 1px solid var(--border-color);
}

/* The head, at the end of that shaft. */
.pipeline-row .pipe-node + .pipe-node::after {
  content: "";
  position: absolute;
  left: -0.5rem;
  top: 3.9rem;
  width: 0.34rem;
  height: 0.34rem;
  border-top: 1px solid var(--border-color);
  border-right: 1px solid var(--border-color);
  transform: rotate(45deg);
}

.pipe-dot {
  position: relative;
  display: grid;
  place-items: center;
  width: 2.6rem;
  height: 2.6rem;
  flex: 0 0 auto;
  border-radius: 999px;
  background: var(--panel-bg);
  border: 1px solid var(--border-color);
}

.pipe-dot svg {
  width: 1.15rem;
  height: 1.15rem;
  fill: var(--muted-color);
}

/* Tool marks sit on a white disc: several of these logos are solid black and would
   otherwise disappear against the page. */
.pipe-dot.is-tool {
  background: #ffffff;
  border-color: transparent;
  padding: 0.3rem;
}

.pipe-dot.is-tool img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Marks carrying their own background fill the disc instead of sitting on the white. */
.pipe-dot.is-solid {
  padding: 0;
}

.pipe-dot.is-solid img {
  border-radius: 999px;
}

/* Every pipeline ends with a person deciding, so that node carries the accent. */
.pipe-dot.is-end {
  border-color: var(--accent);
}

.pipe-dot.is-end svg {
  fill: var(--accent);
}

.pipe-label {
  order: -1;
  box-sizing: border-box;
  height: 2.85rem;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding-bottom: 0.45rem;
  font-size: 0.62rem;
  line-height: 1.25;
  color: var(--muted-color);
  overflow-wrap: normal;
  hyphens: none;
}

.is-tool .pipe-label {
  color: var(--text-color);
}

/* ------------------------------------------------------------------------- tooltips */

/* Defined here because this page does not load workbench.css, where the site's other
   copy of this helper lives. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/*
 * Attached to the stage rather than stated once above the diagrams, so the explanation is
 * there at the moment a reader wonders what kind of step they are looking at. Reachable by
 * keyboard as well as pointer - a hover-only tooltip is one half the visitors cannot open.
 */
.pipe-node {
  cursor: help;
}

.pipe-tip {
  position: absolute;
  top: calc(100% + 0.4rem);
  left: 50%;
  transform: translateX(-50%);
  z-index: 5;
  width: 15rem;
  padding: 0.55rem 0.7rem;
  border-radius: 0.4rem;
  background: #10161d;
  color: #eafaff;
  border: 1px solid var(--accent);
  font-size: 0.7rem;
  line-height: 1.45;
  text-align: left;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 140ms;
}

/* :focus as well as :focus-visible. A touch device has no hover at all, and tapping a
   focusable element does not usually satisfy :focus-visible - browsers reserve that for
   keyboard intent - so on a phone these tooltips could not be opened by any means. */
.pipe-node:hover > .pipe-tip,
.pipe-node:focus > .pipe-tip,
.pipe-node:focus-visible > .pipe-tip {
  opacity: 1;
  visibility: visible;
}

.pipe-node:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 0.3rem;
}

/* The outer stages would push their tooltip past the edge of the card, so they anchor to
   their own side rather than centring on the node. */
.pipe-node:first-child > .pipe-tip {
  left: 0;
  transform: none;
}

.pipe-node:last-child > .pipe-tip {
  left: auto;
  right: 0;
  transform: none;
}

/*
 * On a phone a node-anchored tooltip cannot fit. It is 15rem wide, the row wraps, and a
 * node near the right edge carries its tooltip off the screen - measured 27px past the
 * edge at 375px. The first-child and last-child anchoring above cannot catch that,
 * because those are DOM positions while the overflow depends on where a node WRAPS to,
 * so the node that ends up visually last on a line is usually neither of them.
 *
 * Below 600px the tooltip stops being anchored to its node and becomes a bar pinned
 * across the bottom of the screen - a width that always exists, whatever the row did.
 * Only one tooltip is ever open, so they cannot collide with each other.
 */
@media (max-width: 600px) {
  .pipe-tip,
  .pipe-node:first-child > .pipe-tip,
  .pipe-node:last-child > .pipe-tip {
    position: fixed;
    top: auto;
    bottom: 1rem;
    left: 1rem;
    right: 1rem;
    width: auto;
    transform: none;
    font-size: 0.8rem;
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.55);
  }
}

@media (prefers-reduced-motion: reduce) {
  .pipe-tip {
    transition: none;
  }
}

/* --------------------------------------------------------------------- the strips */

/*
 * Same nodes, no arrows: these are sets of guarantees and services, not steps in an
 * order. The label carries the promise so it reads without hovering; the tooltip carries
 * the detail that used to be a paragraph.
 */
.strip-title {
  margin: 2rem 0 0;
  font-size: 1rem;
}

.pipe-strip {
  gap: 1.75rem;
  margin-top: 0.5rem;
  padding-bottom: 0.5rem;
}

.pipe-strip .pipe-node {
  width: 5.25rem;
}

.pipe-strip .pipe-label {
  font-size: 0.7rem;
  color: var(--text-color);
}

.pipe-strip .pipe-dot {
  border-color: var(--accent);
}

.pipe-strip .pipe-dot svg {
  fill: var(--accent);
}
