/* ==========================================================================
   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; }
/* Both fans travel with the page and one is shown: across on a desk, down on
   a phone. The same curve with x and y exchanged, the same colours, the same
   dots on the same clock.

   A role's wire is doubled too, and turned the same way — but the role
   itself keeps its row: the guide drops, and the name it arrives at is
   written beside it, on one line. */
.adt__fan.adt__fan--down, .adt-wire.adt-wire--down { display: none; }
/* 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) {
  /* The same picture, turned. The networks stack, the fan gathers them
     downwards into the platform, and every role's wire drops into the role
     instead of running at it. Nothing is hidden that was moving before. */
  .adt { grid-template-columns: minmax(0, 1fr); gap: var(--s-4); }
  .adt__feed { grid-template-columns: minmax(0, 1fr); }
  .adt__fanbox { height: 84px; margin-top: var(--s-2); }
  .adt__fan { display: none; }
  .adt__fan.adt__fan--down { display: block; }

  .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; }

  /* A role keeps its row — the guide drops, the name stands beside it. The
     column is narrower than the wide wire's because a drop is narrow. */
  .adt__users { --wire: 34px; }
  .adt__users .adt__eyebrow { padding-left: calc(var(--wire) + var(--s-3)); }
  .adt-wire { display: none; }
  .adt-wire.adt-wire--down { display: block; width: 100%; height: 46px; }
}

@media (max-width: 620px) {
  .adt__cells, .adt__srcs { grid-template-columns: minmax(0, 1fr); }
}

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