/* ==========================================================================
   diagram.css — the ADTech product diagram.

   Three panels: the networks that feed the platform, the platform, the people
   who read it. What the picture is *about* is the convergence — twenty-odd
   incompatible sources becoming one system — so that is the only thing that
   moves: a packet runs down each network's own line into the hub, and one runs
   out of the hub to its readers. The boxes stay still; they are text to read.

   Every network's line carries that network's own brand colour, which is what
   makes the fan legible as nine separate feeds rather than decoration.

   Under prefers-reduced-motion nothing moves and the lines are simply drawn.
   ========================================================================== */

.adt {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.46fr) minmax(0, 1.06fr);
  align-items: center;
  margin: var(--s-5) 0 var(--s-6);
}
.adt, .adt figure { margin-inline: 0; }

/* The list and the fan share a subgrid so the list decides the height of both
   and every line ends level with its own row. */
.adt__feed {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(52px, 7vw, 104px);
  align-items: stretch;
}
.adt__fanbox { position: relative; }

/* --- the networks --------------------------------------------------------- */
.adt__srcs { list-style: none; margin: 0; padding: 0; display: grid; }
.adt-src {
  display: flex; align-items: center; gap: var(--s-2);
  min-height: 0; padding: 5px var(--s-3) 5px var(--s-2);
  border: 1px solid var(--line); border-left: 0;
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  background: var(--surface);
  font-size: var(--fs-2xs); color: var(--ink-2);
  white-space: nowrap;
}
/* Stepped inset, as in the deck: the list reads as a stack of feeds rather than
   a table, and the steps leave the fan room to fan out. */
.adt-src--0 { margin-left: 0; }
.adt-src--1 { margin-left: 6%; }
.adt-src--2 { margin-left: 12%; }
.adt-src--3 { margin-left: 18%; }
.adt-src--4 { margin-left: 24%; }
.adt-src--5 { margin-left: 24%; }
.adt-src--6 { margin-left: 18%; }
.adt-src--7 { margin-left: 12%; }
.adt-src--8 { margin-left: 6%; }
.adt-src--more {
  margin-left: 0; margin-top: 6px;
  border: 1px dashed var(--line); border-radius: var(--r-sm);
  color: var(--ink-3); font-family: var(--font-mono); font-size: var(--fs-3xs);
  justify-content: center;
}
.adt-src__bar { flex: 0 0 3px; align-self: stretch; border-radius: 2px; background: var(--c, var(--accent)); }
.adt-src--0 .adt-src__bar { --c: #1877F2; }
.adt-src--1 .adt-src__bar { --c: #0077FF; }
.adt-src--2 .adt-src__bar { --c: #FE2C55; }
.adt-src--3 .adt-src__bar { --c: #4285F4; }
.adt-src--4 .adt-src__bar { --c: #5B6B7C; }
.adt-src--5 .adt-src__bar { --c: #3E3ADB; }
.adt-src--6 .adt-src__bar { --c: #7B61FF; }
.adt-src--7 .adt-src__bar { --c: #00B37E; }
.adt-src--8 .adt-src__bar { --c: #F5851F; }

/* --- the fan -------------------------------------------------------------- */
.adt__fan { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
/* The connector: one solid stroke, visible in its own right. Nine feeds have
   to read as nine lines, and a dash pattern turns them into broken ones. */
.adt-trace {
  fill: none; stroke-width: 1.25; stroke-linecap: round; opacity: .42;
}

/* Cargo grows out of nothing at the start of its run and shrinks back into it
   at the end, so nothing pops in or out at the ends of a line. The scale lives
   on the glyph and the motion on the <g> around it — one element cannot carry
   both a motion transform and a CSS one. */
/* The glyphs, not `> *`: the <animateMotion> beside them is a child too, and
   there is nothing to scale on an element that never renders. */
.adt-carry > .adt-dot,
.adt-carry > .adt-bars,
.adt-carry > .adt-num,
.adt-carry > .adt-cash {
  transform-box: fill-box; transform-origin: 50% 50%;
  /* `backwards` is not optional here. Every marker but the first waits out an
     animation-delay, and during that wait an element without a fill mode shows
     its own base style — full size, full opacity — while animateMotion has not
     started either, so it sits at the SVG's origin. That is the bright scrap in
     the corner at the top of the run. Holding the 0% frame instead keeps it at
     scale 0 until its turn. */
  animation: adt-pop 4.6s linear infinite backwards;
}
.adt-carry--fan > .adt-dot { animation-duration: 4.6s; }
.adt__fan .adt-carry:nth-of-type(1) > .adt-dot { animation-delay: 0.00s; }
.adt__fan .adt-carry:nth-of-type(2) > .adt-dot { animation-delay: 0.42s; }
.adt__fan .adt-carry:nth-of-type(3) > .adt-dot { animation-delay: 0.84s; }
.adt__fan .adt-carry:nth-of-type(4) > .adt-dot { animation-delay: 1.26s; }
.adt__fan .adt-carry:nth-of-type(5) > .adt-dot { animation-delay: 1.68s; }
.adt__fan .adt-carry:nth-of-type(6) > .adt-dot { animation-delay: 2.10s; }
.adt__fan .adt-carry:nth-of-type(7) > .adt-dot { animation-delay: 2.52s; }
.adt__fan .adt-carry:nth-of-type(8) > .adt-dot { animation-delay: 2.94s; }
.adt__fan .adt-carry:nth-of-type(9) > .adt-dot { animation-delay: 3.36s; }
.adt__fan .adt-carry:nth-of-type(10) > .adt-dot { animation-delay: 3.78s; }
.adt-wire .adt-carry > .adt-dot { animation-duration: 2.6s; }
.adt-wire--bars .adt-carry > .adt-bars { animation-duration: 2.8s; }
.adt-wire--money .adt-carry > .adt-cash { animation-duration: 3s; }
.adt-wire--numbers .adt-carry > .adt-num { animation-duration: 2.4s; }
.adt-wire--numbers .adt-carry--n0 > .adt-num { animation-delay: 0.00s; }
.adt-wire--numbers .adt-carry--n1 > .adt-num { animation-delay: 0.80s; }
.adt-wire--numbers .adt-carry--n2 > .adt-num { animation-delay: 1.60s; }
/* A quarter of the run to grow and a quarter to shrink. The first version held
   full size for seven-tenths of the way, which reads as a marker that simply
   appears and disappears — the growing is the part that has to be visible. */
@keyframes adt-pop {
  0%   { transform: scale(0);   opacity: 0; }
  26%  { transform: scale(1);   opacity: 1; }
  74%  { transform: scale(1);   opacity: 1; }
  100% { transform: scale(0);   opacity: 0; }
}

/* What moves is a dot, carried along the very same path by animateMotion. The
   stroke does not scale with the stretched box, so it stays round and the same
   size on every screen. */
.adt-dot {
  fill: none; stroke-width: 5; stroke-linecap: round;
  filter: drop-shadow(0 0 5px currentColor);
  opacity: .95;
}
.adt-dot--out { stroke: var(--c-blue); }

/* --- the platform --------------------------------------------------------- */
.adt__hub {
  padding: var(--s-4);
  border: 1px solid var(--line); border-radius: var(--r-lg);
  background:
    radial-gradient(ellipse 80% 120% at 8% 50%, rgba(71, 144, 212, .10), transparent 70%),
    var(--surface);
}
.adt__eyebrow {
  display: block; margin-bottom: var(--s-2);
  font-family: var(--font-mono); font-size: var(--fs-3xs);
  letter-spacing: .14em; text-transform: uppercase; color: var(--c-blue);
}
.adt__h {
  margin: 0 0 var(--s-3); font-weight: 700;
  font-size: clamp(17px, 1.4vw, 23px); letter-spacing: -.015em;
}
.adt__cells { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-2); }
.adt-cell {
  padding: var(--s-3);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: rgba(9, 14, 26, .5);
}
.adt-cell__h { margin: 0 0 4px; font-weight: 640; font-size: var(--fs-xs); letter-spacing: -.01em; color: var(--ink); }
.adt-cell p  { margin: 0; font-size: var(--fs-3xs); line-height: 1.45; color: var(--ink-3); }

/* --- the readers, and how each one touches the platform ------------------- */
/* One wire per role, and the wire is the content: a buyer both writes and
   reads, so it has two lanes running opposite ways; a team lead only reads; an
   analyst reads figures, so figures are what travel; management reads money. */
/* One width for the wire column, so the label over the list can be indented by
   exactly as much as the wires take and sit flush with the role names. */
.adt__users {
  --wire: clamp(46px, 4.8vw, 68px);
  display: grid; gap: var(--s-3); align-content: center;
}
.adt__users .adt__eyebrow { padding-left: calc(var(--wire) + var(--s-3)); }
.adt-user {
  display: grid; grid-template-columns: var(--wire) minmax(0, 1fr);
  gap: var(--s-3); align-items: center;
}
.adt-wire { width: 100%; height: auto; display: block; overflow: visible; }
.adt-wire__line, .adt-wire__head {
  fill: none; stroke: var(--c-blue); stroke-width: 1.1;
  stroke-linecap: round; stroke-linejoin: round;
  opacity: .5;
}
.adt-wire__head { opacity: .8; }
.adt-wire__dot { stroke: var(--c-blue); stroke-width: 4.5; }

/* The team lead's cargo: three bars, stroked at screen width so they stay
   legible at eight units across. */
.adt-bars {
  fill: none; stroke: var(--c-blue); stroke-width: 1.6;
  stroke-linecap: round;
  filter: drop-shadow(0 0 4px currentColor); color: var(--c-blue);
}

/* The analyst's figures and management's currency ride the same wire a dot
   rides on the other rows, so the eye reads them as the same flow carrying
   different cargo. */
.adt-num, .adt-cash {
  font-family: var(--font-mono); font-weight: 600;
  fill: var(--c-blue); stroke: none;
}
.adt-num  { font-size: 9px; }
.adt-cash { font-size: 12px; fill: var(--c-teal); }

.adt-user__h { margin: 0 0 2px; font-weight: 640; font-size: var(--fs-xs); color: var(--ink); }
.adt-user p:last-child { margin: 0; font-size: var(--fs-3xs); line-height: 1.4; color: var(--ink-3); }

/* --- narrow: a layout, not a diagram ------------------------------------- */
/* On a phone the picture stops being a picture: there is no room for a fan to
   converge across, and wires pointing sideways at a stacked list say nothing.
   So below the breakpoint every moving part goes away and what is left is the
   same information, laid out to be read — sources, then the platform, then who
   reads it, each a plain labelled list. */
@media (max-width: 1000px) {
  .adt { grid-template-columns: minmax(0, 1fr); gap: var(--s-4); }
  .adt__feed { grid-template-columns: minmax(0, 1fr); }
  .adt__fanbox, .adt-wire, .adt-carry { display: none; }

  .adt__srcs { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; }
  .adt-src { border-left: 1px solid var(--line); border-radius: var(--r-sm); }
  .adt-src, .adt-src--more { margin-left: 0; }

  /* The roles become a list with the same left edge as everything else, in the
     order they are written. */
  .adt__users { grid-template-columns: minmax(0, 1fr); gap: var(--s-3); }
  .adt__users .adt__eyebrow { padding-left: 0; }
  .adt-user {
    grid-template-columns: minmax(0, 1fr);
    gap: 2px;
    padding-left: var(--s-3);
    border-left: 2px solid var(--c-blue);
  }
}
@media (max-width: 620px) {
  .adt__cells, .adt__srcs { grid-template-columns: minmax(0, 1fr); }
}

@media (prefers-reduced-motion: reduce) {
  .adt-carry { display: none; }
}
