/* ==========================================================================
   HOME — THE PLATFORM BAND  (css/home-platform.css)

   The full-screen light band that answers WHAT PULSAR IS. It sits between the
   thesis band, which ends "That is exactly what PULSAR does", and the
   how-it-works band. Mockup and full design notes: dev/home-platform-vision.html

   WHAT PULSAR IS — full-screen platform band for the homepage. LIGHT.
   Sits after The Challenge and The Thesis (both dark), before "Who benefits".

   THE PICTURE:

    ┌ ─ ─ ─ ─[ PULSAR PLATFORM ]─ ─ ─ ─ ┐
    ┆         PULSAR MODULES            ┆
    ┆  [   ] [   ] [   ] [   ] [   ]    ┆   modules
    ┆    ↑    ↑    ↑    ↑    ↑          ┆
    ┆        [    PULSAR engine     ]   ┆   the core
    └ ─ ─ ─ ─ ─ ─ ─ ─ ↑ ─ ─ ─ ─ ─ ─ ─ ─ ┘
              ┌───────┴───────┐
           [TRACES]  [LOGS]  [METRICS]     the data — outside the
                                           boundary, because it is
                                           the customer's, not ours

   THE ROLES USED TO SIT ON TOP OF THIS, and they have moved to their own
   section below the band. Two reasons. The diagram was carrying three
   arguments at once — what goes in, what we build, and who it serves — and
   the third is the one that needs room to say anything, because a role name
   alone says nothing without the question that role asks. And the picture
   was simply too full: the thing this band has to land is the module row
   over the engine, and every extra tier competed with it.

   A highlight wave travels the wiring bottom to top on a 5s loop. See the
   rule on the flash/ladder ratio near the animation block — it is the thing
   that makes the wave a wave rather than a global pulse.

   WHY IT IS BUILT THIS WAY (the Causely reference, and what we took)

   Causely's architecture diagram works because of four decisions, all of
   which this band adopts:

     a. CENTRED AND SYMMETRIC. The diagram is an object on the page, not a
        column of content. Everything is centre-aligned.
     b. OUTLINED BOXES WITH TWO TO FOUR WORDS IN THEM. No paragraphs live
        inside the diagram. Prose sits above it, in the head.
     c. DOTTED WIRING WITH NODE DOTS. Lines fan from each box into a bus and
        the bus runs to the product. It reads as a wiring diagram, so the
        direction of flow is never in question.
     d. A DASHED CONTAINER MARKS WHAT THE COMPANY BUILDS, with the product
        name straddling its top edge. Everything inside the boundary is
        ours; everything outside it is the customer's. That single device
        answers "what is PULSAR" better than any sentence.

   We invert their vertical order: their sources come in from the top, ours
   from the bottom, because the brief is "traces in at the bottom, modules on
   top".

   THE RULES THIS SECTION DEPENDS ON

   1. LIGHT BAND, DELIBERATELY. The challenge and thesis sections above are
      both dark. This is the first light surface after them, which is most
      of why it will feel like a new chapter rather than more of the same.

   2. A BOX HOLDS A NAME AND AT MOST ONE LINE OF VALUE — and the ENGINE BOX
      HOLDS ONLY ITS NAME. What the engine does is a sentence, and a
      sentence of that length inside a diagram box turns the box into a
      paragraph of the page. It now lives in the subheading, where the
      reader meets it before looking at the picture. The engine earns its
      weight instead by being the one SOLID object among outlines.

   3. EVERY MODULE CARRIES ITS PRODUCT NAME AND ITS KIND. An earlier pass
      named them as active verb phrases ("Find the root cause") on the
      argument that a verb is a value and a noun is a feature. That held
      while the diagram stood alone, but it left the homepage speaking a
      different language from /platform and from the nav, so nothing
      connected "Find the root cause" to Root-Cause Analysis. The names are
      now the canonical ones — System Explorer, Anomaly Detection, Change
      Detection, Root-Cause Analysis, Agent Builder — with ONE LINE OF VALUE
      under each, which is where the verb went. Three of the five already
      existed on /platform; the two views are new and must stay in sync.

      THE KIND IS DECLARED PER BOX, NOT PER GROUP. The old two-group split
      (VIEWS ──── AGENTS ────) could not express a module that is both, and
      Anomaly Detection and Change Detection both are: each draws something
      you explore AND reasons over it. A glyph pair on the box says so; a
      group label cannot. The glyphs are the same two the subheading
      defines, and each box carries a visually-hidden word ("view",
      "view + agent", "agent") so the tier is not five unlabelled boxes to
      a screen reader.

   4. THE TEAL TINT IS THE PLATFORM, AND ONLY THE PLATFORM. The bounded
      region carries the pale teal ground; the engine and the modules both
      sit on it in white. The engine is distinguished by its width, its
      solid teal border and its teal name — not by being greener, which made
      it read as the subject of a section whose subject is the platform. Tinting only the engine
      made the ENGINE the subject of the section when the PLATFORM is the
      subject — the tint is now coextensive with the thing being named.
      Everything outside the boundary, the customer's data below and the
      customer's teams above, stays greyscale: the moment an input box turns
      teal the boundary stops meaning anything.

   5. THE HEAD IS A CLAIM AND A MECHANISM, IN THAT ORDER. The headline
      answers the thesis section's closing line — "That is exactly what
      PULSAR does" — with a NOUN the reader can hold: structured system
      knowledge. Not "a model", which is our word for how it is built
      rather than what they get, and not "one model of the system", which
      the thesis coda and the Solutions heading have both already spent.

      The subheading then teaches the diagram bottom-up (data in, engine
      reconstructs, modules work from it) and defines the two kind glyphs
      inline. An earlier pass banned a subheading here on the grounds that
      a lone line over a diagram is a statement where a headline plus a
      paragraph is just another section. That is still true of a subheading
      that RESTATES the headline — the version that had to go said "your
      runs go in, the engine builds one model" directly under a headline
      that had just said the same thing. A subheading that does work the
      headline cannot do, such as defining two symbols at the moment they
      are introduced, earns its line. The test is whether removing it costs
      the reader something; here it costs them the glyphs.

      "No specs, no docs, no source code" stays under the input row, where
      it is a PROPERTY OF THE INPUT rather than prose above the picture.

   6. NO NUMBERED MARKERS. The three tiers are a structure, not a sequence
      of steps, and the wires already carry the order.

   7. THE DIAGRAM FITS ONE SCREEN. THE BAND NEED NOT. The thing that has to
      be takeable in at a glance is the picture — head, subheading and the
      read-more may fall outside the fold, and on a short laptop they will.
      An earlier pass forced the WHOLE band under 100svh and the result was
      correct and unreadable: every gap between the headline, the
      subheading, the diagram and the button had been squeezed to the
      minimum that still technically fit, so the section felt packed. The
      generous gaps are the point of a section that is mostly one object;
      only the diagram's own internals are held tight.

      NO PIN, NO JS. The thesis section above already spends the reader's
      scroll budget.

   8. THE PLATFORM IS THE WIDEST THING ON THE SCREEN. The input row is
      deliberately narrower than the boundary: it is the customer's data,
      not the product, and giving it equal width made eight rectangles all
      competing at the same weight. Narrower also lets the fan-out angles
      show, which is what makes the bottom wire read as wiring.

   9. AIR IS A FEATURE HERE, AND IT GOES *BETWEEN* THINGS, NOT INSIDE THEM.
      A pass that spent the freed space on box padding just made five tall
      rectangles; the row looked heavier, not calmer. Space between tiers,
      between columns and inside the boundary is what reads as composure. With the roles gone the band has room, and the
      right thing to do with it is to spend it on gaps rather than to make
      the objects bigger. A diagram of eight boxes that is mostly empty space
      reads as considered; the same eight boxes packed read as a schematic
      somebody exported. If a tier ever needs to grow, take the space from
      the band's own padding before taking it from between the tiers.

   9. THE SECTION NAMES ITSELF ONCE. An earlier pass had "PULSAR platform"
      in the eyebrow, in the lede and on the boundary tag — three times in
      the top third of one screen. The tag is the one that does structural
      work, so the eyebrow is gone and the lede is back to the single line
      that teaches the reading direction. Most of what felt "overloaded"
      was repetition, not density.

  10. THE WIRES ARE CSS, NOT SVG, AND THEY MIRROR THE GRID THEY CONNECT TO.
      Stretching an SVG to the diagram's width would distort its dashes.
      Each wire band is a grid with the same column count and gap as its
      tier, so every drop is centred in its own cell and lands exactly on a
      box centre. Hardcoded percentages cannot do this — with a column gap,
      box centres are not at even percentage steps, and the outer drops miss
      by a few pixels.
   ========================================================================== */

/* —— the section ————————————————————————————————————————————————————— */
.home-platform{--g:clamp(12px,1.7vw,22px);--ink:#2b2d42;--soft:#5c677d;--faint:#8d99ae;
  --box:#ffffff;--edge:#c3cbd8;--wire:#bcc5d2;--lit:#0f8f86;--wave:5s;
  --teal:#0a5c56;--teal-line:rgba(42,143,136,.55);--teal-dot:#2a8f88;
  min-height:100svh;display:flex;align-items:center;color:var(--ink);
  background:
    radial-gradient(ellipse 70% 52% at 50% 42%, rgba(78,205,196,.10) 0%, transparent 58%),
    radial-gradient(ellipse 54% 44% at 92% 96%, rgba(239,131,84,.05) 0%, transparent 52%),
    #fbfcfd}
.home-platform__inner{max-width:min(100%,980px);margin:0 auto;width:100%;text-align:center;
  padding:clamp(48px,7vh,104px) clamp(16px,3vw,32px)}

/* head ---------------------------------------------------------------- */
.home-platform__eyebrow{font-family:var(--mono);font-size:.72rem;font-weight:600;
  letter-spacing:.16em;text-transform:uppercase;color:var(--teal);margin:0 0 16px}
/* The head is ONE object. With no subheading under it the headline has to
   carry the whole definition, so it is set larger and given the full measure
   it needs to land as two lines. */
.home-platform__title{margin:0 auto clamp(22px,3vh,38px);color:var(--ink);
  font-size:clamp(27px,3vw,41px);font-weight:700;
  letter-spacing:-.035em;line-height:1.12;max-width:31ch;text-wrap:balance}

/* The subheading. Measure is deliberately wider than the title's 26ch: it is
   read as prose, not as a statement, and a narrow measure would make it look
   like a second headline. */
/* 62ch, not 86. The ch unit is the width of "0", which in this face is well
   under the average character, so 86ch measured 109 real characters per line
   on a 2560 display — half again the ~75 that reads comfortably. */
.home-platform__sub{margin:0 auto clamp(64px,8.5vh,116px);max-width:62ch;
  font-size:clamp(14.5px,1.02vw,16.5px);line-height:1.58;color:var(--soft)}
/* The glyph definitions inside the sentence. Kept on one line each so a
   symbol never separates from the words that define it. */
.home-platform__kindref{display:inline-flex;align-items:center;gap:.34em;
  font-weight:600;color:var(--ink);white-space:nowrap}

/* the one claim the subheading used to carry, kept as a property of the
   input row rather than as prose above the diagram */
.home-platform__inSay{margin:26px 0 0;font-family:var(--mono);font-size:.68rem;font-weight:600;
  letter-spacing:.11em;text-transform:uppercase;color:var(--faint)}

/* —— the diagram ——————————————————————————————————————————————————————
   Three tiers, two wire bands. Tier boxes are a grid so the wire stubs can
   be positioned at exact column centres. -------------------------------- */
.home-platform__dia{display:flex;flex-direction:column;align-items:stretch}

.home-platform__tier{display:grid;gap:var(--g)}
.home-platform__tier--out{grid-template-columns:repeat(var(--n),minmax(0,1fr))}
.home-platform__tier--in{grid-template-columns:repeat(3,minmax(0,1fr));
  max-width:min(100%,720px);margin:0 auto;width:100%}

/* The tier label names the row once, centred, in the boundary's own voice.
   It replaces the two group labels: the kind now lives on each box. */
.home-platform__tierlabel{margin:0 0 20px;text-align:center;font-family:var(--mono);
  font-size:.7rem;font-weight:600;letter-spacing:.16em;text-transform:uppercase;
  color:var(--teal);padding-bottom:12px;border-bottom:1px solid var(--teal-line)}
.home-platform__gkind{flex:none;width:13px;height:11px;fill:var(--teal-dot)}
/* The kind sits in a fixed-height slot at the top of the box so all five
   names start on the same line, exactly as the role marker did before it. */
.home-platform__kind{display:flex;align-items:center;gap:4px;margin:0 0 7px;min-height:11px}

/* EVERY box has the same skeleton — marker slot, name, rule, role — and both
   ends of it are pinned: the marker sits in a fixed-height slot at the top so
   all five names start on the same line, and the role is pushed to the bottom
   by margin-top:auto so all five rules land on the same line too. Only the
   NAME is allowed to breathe in the middle. Without this the two kinds of
   module had different internal layouts and the row read as restless. */
.home-platform__box{position:relative;display:flex;flex-direction:column;
  background:var(--box);border:1px solid var(--edge);border-radius:9px;
  padding:clamp(12px,1.35vw,16px) clamp(12px,1.3vw,16px);text-align:left;
  box-shadow:0 1px 2px rgba(43,45,66,.06),0 6px 18px rgba(43,45,66,.04)}
/* The role sits at the TOP of the box, marked with a person. In an
   architecture diagram an actor is drawn as a figure and the system serves
   it, so a person glyph says "this is a who" with no label needed — where
   "For integration" in body text just looked like more description. Reading
   order is now who, then what they get. Roles are single words so the row
   never wraps and every name starts on the same line. */
.home-platform__box b{display:block;font-size:clamp(13.5px,1.1vw,15px);
  font-weight:600;letter-spacing:-.015em;line-height:1.32;color:var(--ink)}
/* One line of value per box — the verb the module name gave up (rule 3).
   Pushed to the bottom so all five rules land on the same line. */
.home-platform__does{display:block;margin-top:auto;padding-top:7px;
  font-size:clamp(11px,.88vw,12.2px);line-height:1.36;color:var(--soft)}

/* Views versus agents is declared ONCE PER GROUP, on the group label: a chart
   glyph for the views, a chat bubble for the agents. Putting the kind glyph
   on every box meant five glyphs saying what two could say. The label is
   where the kind is named, so it is where the kind is drawn. */
/* Views and agents are both plain white. The agent tint is gone: with the
   whole platform tinted teal there is no tint left to distinguish them with,
   and white now reads as an object sitting ON the platform. The kind is
   carried by the group labels and their glyphs, which is enough. */
.home-platform__box--in{font-family:var(--mono);font-size:clamp(11.5px,.9vw,12.5px);font-weight:600;
  letter-spacing:.11em;text-transform:uppercase;color:var(--soft);
  border-style:dashed;border-color:var(--wire);box-shadow:none;background:transparent;
  text-align:center}

/* —— the wire bands ———————————————————————————————————————————————————
   A wire band mirrors the grid of the tier it connects to, so each stub is
   centred in its own column CELL. Hardcoded percentages cannot do this: with
   a column gap, box centres are not at even percentage steps, and the outer
   stubs miss their boxes by a few pixels. --n is the column count.
     .home-platform__cell   one column; draws the vertical drop and its node dot
     .home-platform__bus    the horizontal run, inset by half a column at each end
     .home-platform__trunk  the vertical run into / out of the boundary            -- */
.home-platform__wire{position:relative;display:grid;gap:var(--g);
  grid-template-columns:repeat(var(--n),minmax(0,1fr));
  height:clamp(58px,7vh,96px)}
.home-platform__wire--narrow{max-width:min(100%,720px);margin:0 auto;width:100%}
.home-platform__cell{position:relative}
.home-platform__cell::before{content:"";position:absolute;left:50%;top:0;bottom:50%;width:0;
  border-left:1.5px dotted var(--wire);transform:translateX(-50%)}
.home-platform__cell::after{content:"";position:absolute;left:50%;top:-2.5px;width:5px;height:5px;
  border-radius:50%;background:var(--teal-dot);transform:translateX(-50%)}
.home-platform__wire--down .home-platform__cell::before{top:50%;bottom:0}
.home-platform__wire--down .home-platform__cell::after{top:auto;bottom:-2.5px}

/* half a column at each end lands the bus exactly on the outer box centres */
.home-platform__bus{position:absolute;top:50%;height:0;border-top:1.5px dotted var(--wire);
  left:calc((100% - (var(--n) - 1) * var(--g)) / var(--n) / 2);
  right:calc((100% - (var(--n) - 1) * var(--g)) / var(--n) / 2)}
.home-platform__bus::after{content:"";position:absolute;left:50%;top:-3.5px;width:5px;height:5px;
  border-radius:50%;background:var(--teal-dot);transform:translateX(-50%)}
.home-platform__trunk{position:absolute;left:50%;width:0;transform:translateX(-50%);
  border-left:1.5px dotted var(--teal-line)}
/* FLOW ARROWHEADS. Every arrow in this diagram points UP, because everything
   in it moves one way: from the data at the bottom, through the platform, to
   the people at the top. Heads are placed where flow ARRIVES — at each module
   and each person, and where the input wire enters the boundary. Junctions
   that are sources or splits keep their round node dot, so a dot never has to
   be read as a direction. */
.home-platform__wire--up .home-platform__cell::after{
  top:-5px;width:0;height:0;background:none;border-radius:0;
  border-left:3.5px solid transparent;border-right:3.5px solid transparent;
  border-bottom:5px solid var(--teal-dot)}
.home-platform__wire--down .home-platform__trunk::after{content:"";position:absolute;top:-5px;left:50%;
  transform:translateX(-50%);width:0;height:0;
  border-left:3.5px solid transparent;border-right:3.5px solid transparent;
  border-bottom:5px solid var(--teal-dot)}

/* Both trunks span the FULL band, not half of it. Visually this changes
   nothing — the centre column's own drop already draws the other half at the
   same x — but it doubles the distance the pulse travels, so the signal reads
   as a rise through the diagram rather than a blink at a junction. */
.home-platform__wire--up .home-platform__trunk,
.home-platform__wire--down .home-platform__trunk{top:0;bottom:0}

/* —— the boundary: what we build ——————————————————————————————————————— */
.home-platform__boundary{position:relative;border:1.5px dashed var(--teal-line);border-radius:18px;
  padding:clamp(46px,5.4vw,76px) clamp(26px,4.2vw,60px) clamp(36px,4.2vw,58px);
  background:
    radial-gradient(ellipse 74% 100% at 50% 0%, rgba(78,205,196,.13) 0%, transparent 72%),
    rgba(78,205,196,.06)}

/* The engine is the one SOLID object in a diagram of outlines. It carries its
   name and nothing else — what it does is now the section's subheading, which
   is where a sentence of that length always belonged. */
.home-platform__engineBar{margin:0;border-radius:12px;text-align:center;
  padding:clamp(16px,1.85vw,23px) clamp(20px,3vw,36px);
  border:1.5px solid var(--teal-line);
  background:var(--box);
  color:var(--teal);font-size:clamp(18px,1.95vw,25px);font-weight:700;letter-spacing:-.022em;
  box-shadow:0 1px 2px rgba(43,45,66,.06),0 6px 18px rgba(43,45,66,.04)}
/* Top edge, centred. The middle actor's wire passes BEHIND it — the tag is
   opaque, and a label occluding a line is ordinary diagram convention. Tried
   left-anchored and bottom-left to dodge the wire; both read worse. The tag
   is kept short and the actor wire band tall enough that the interruption is
   a small fraction of the line. */
.home-platform__nametag{position:absolute;top:0;left:50%;transform:translate(-50%,-50%);z-index:2;
  background:var(--box);border:1.5px solid var(--teal-line);border-radius:8px;box-shadow:0 2px 10px rgba(43,45,66,.06);
  padding:.5rem 1.1rem;font-family:var(--mono);font-size:clamp(12px,1.05vw,14px);
  font-weight:600;letter-spacing:.16em;color:var(--teal);white-space:nowrap}



/* —— THE WAVE ————————————————————————————————————————————————————————
   The wiring AND the boxes light up in sequence, bottom to top: input boxes,
   their drops, the input bus, into the boundary, the engine, out of the
   engine, the module bus, the module drops, the modules, then the drops to
   the people and the people themselves. Nothing travels along the wiring —
   each element brightens and fades in turn, so the highlight propagates as a
   wave rather than as an object moving through a pipe. With the roles gone
   the ladder now ends at the module row, which is also where the diagram
   ends — the wave still runs the full height of the picture.

   RECOGNISABILITY IS THE WHOLE POINT, and an earlier pass failed it: the lit
   teal and the base grey were close in lightness and the highlight held for
   about a third of a second, so the wave was measurable but not visible.
   Three things fixed it — the base lines are PALER (--wire), the lit colour
   is STRONGER (--lit) and carries a glow, and the boxes join in so the wave
   reads as one motion rather than as flickering wires.

   THE RATIO IS WHAT MAKES IT A WAVE AT ALL, and it is the thing to protect.
   Each element flashes for ~0.45s while the delay ladder spans ~2.25s, so
   roughly a fifth of the diagram is lit at any instant and the highlight is
   plainly travelling. An earlier pass had a 1.2s swell over a 1.36s ladder:
   every element was lit at once, which reads as a single global pulse and is
   exactly why the wave could not be seen. Lengthening the flash or
   compressing the ladder breaks it again.

   Direction matches the arrowheads: bottom to top. The delay ladder at the
   end is the ONLY thing encoding direction — invert it to reverse the wave.
   Duration is one token, --wave.

   All of it sits inside prefers-reduced-motion: no-preference. With motion
   reduced the diagram is exactly the static drawing it already is; no
   information lives only in the wave. */
@media (prefers-reduced-motion:no-preference){

  .home-platform__cell::before,.home-platform__bus,.home-platform__trunk{
    animation:hpLineV var(--wave) ease-in-out infinite}
  .home-platform__bus{animation-name:hpLineH}
  /* the trunks are drawn in the teal line colour at rest, so they get their
     own keyframes that return to it — otherwise their resting colour differs
     depending on whether motion is enabled. */
  .home-platform__trunk{animation-name:hpLineTrunk}
  .home-platform__wire--up .home-platform__cell::after{
    animation:hpHead var(--wave) ease-in-out infinite}
  .home-platform__box{animation:hpBox var(--wave) ease-in-out infinite}
  .home-platform__box--in{animation-name:hpBoxIn}
  .home-platform__engineBar{animation:hpCore var(--wave) ease-in-out infinite .78s}

  @keyframes hpLineV{
    0%,2%    {border-left-color:var(--wire);filter:none}
    5%,7%    {border-left-color:var(--lit);
              filter:drop-shadow(0 0 3px rgba(78,205,196,.85))}
    14%,100% {border-left-color:var(--wire);filter:none}
  }
  @keyframes hpLineTrunk{
    0%,2%    {border-left-color:var(--teal-line);filter:none}
    5%,7%    {border-left-color:var(--lit);
              filter:drop-shadow(0 0 3px rgba(78,205,196,.85))}
    14%,100% {border-left-color:var(--teal-line);filter:none}
  }
  @keyframes hpLineH{
    0%,2%    {border-top-color:var(--wire);filter:none}
    5%,7%    {border-top-color:var(--lit);
              filter:drop-shadow(0 0 3px rgba(78,205,196,.85))}
    14%,100% {border-top-color:var(--wire);filter:none}
  }
  @keyframes hpHead{
    0%,2%    {border-bottom-color:var(--teal-dot);filter:none;transform:translateX(-50%) scale(1)}
    5%,7%    {border-bottom-color:var(--lit);
              filter:drop-shadow(0 0 5px rgba(78,205,196,.95));
              transform:translateX(-50%) scale(1.3)}
    14%,100% {border-bottom-color:var(--teal-dot);filter:none;transform:translateX(-50%) scale(1)}
  }
  @keyframes hpBox{
    0%,2%    {border-color:var(--edge);
              box-shadow:0 1px 2px rgba(43,45,66,.06),0 6px 18px rgba(43,45,66,.04)}
    5%,7%    {border-color:rgba(15,143,134,.72);
              box-shadow:0 1px 2px rgba(43,45,66,.06),0 0 0 4px rgba(78,205,196,.17)}
    14%,100% {border-color:var(--edge);
              box-shadow:0 1px 2px rgba(43,45,66,.06),0 6px 18px rgba(43,45,66,.04)}
  }
  /* The input row needs a HARDER flash than the boxes inside the platform.
     Its boxes are dashed and unfilled, so a border colour change alone was
     almost invisible and the wave looked like it began at the engine — the
     background and the glow are what make the start of the wave readable. */
  @keyframes hpBoxIn{
    0%,2%    {border-color:var(--wire);color:var(--soft);
              background:transparent;box-shadow:none}
    5%,7%    {border-color:var(--lit);color:var(--lit);
              background:rgba(78,205,196,.13);
              box-shadow:0 0 0 4px rgba(78,205,196,.13)}
    14%,100% {border-color:var(--wire);color:var(--soft);
              background:transparent;box-shadow:none}
  }
  @keyframes hpCore{
    0%,2%    {border-color:var(--teal-line);
              box-shadow:0 1px 2px rgba(43,45,66,.06),0 6px 18px rgba(43,45,66,.04)}
    5%,7%    {border-color:var(--lit);
              box-shadow:0 1px 2px rgba(43,45,66,.06),0 0 0 5px rgba(78,205,196,.18)}
    14%,100% {border-color:var(--teal-line);
              box-shadow:0 1px 2px rgba(43,45,66,.06),0 6px 18px rgba(43,45,66,.04)}
  }

  /* ── the delay ladder: this, and only this, is the wave ── */
  .home-platform__tier--in .home-platform__box:nth-child(1){animation-delay:0s}
  .home-platform__tier--in .home-platform__box:nth-child(2){animation-delay:.07s}
  .home-platform__tier--in .home-platform__box:nth-child(3){animation-delay:.14s}
  .home-platform__wire--down .home-platform__cell:nth-child(1)::before{animation-delay:.18s}
  .home-platform__wire--down .home-platform__cell:nth-child(2)::before{animation-delay:.25s}
  .home-platform__wire--down .home-platform__cell:nth-child(3)::before{animation-delay:.32s}
  .home-platform__wire--down .home-platform__bus                     {animation-delay:.42s}
  .home-platform__wire--down .home-platform__trunk                   {animation-delay:.56s}
  /* engine at .78s */
  .home-platform__wire--up .home-platform__trunk                     {animation-delay:1.02s}
  .home-platform__wire--up .home-platform__bus                       {animation-delay:1.16s}
  .home-platform__wire--up .home-platform__cell:nth-child(1)::before,
  .home-platform__wire--up .home-platform__cell:nth-child(1)::after  {animation-delay:1.30s}
  .home-platform__wire--up .home-platform__cell:nth-child(2)::before,
  .home-platform__wire--up .home-platform__cell:nth-child(2)::after  {animation-delay:1.37s}
  .home-platform__wire--up .home-platform__cell:nth-child(3)::before,
  .home-platform__wire--up .home-platform__cell:nth-child(3)::after  {animation-delay:1.44s}
  .home-platform__wire--up .home-platform__cell:nth-child(4)::before,
  .home-platform__wire--up .home-platform__cell:nth-child(4)::after  {animation-delay:1.51s}
  .home-platform__wire--up .home-platform__cell:nth-child(5)::before,
  .home-platform__wire--up .home-platform__cell:nth-child(5)::after  {animation-delay:1.58s}
  .home-platform__tier--out .home-platform__box:nth-child(1){animation-delay:1.40s}
  .home-platform__tier--out .home-platform__box:nth-child(2){animation-delay:1.47s}
  .home-platform__tier--out .home-platform__box:nth-child(3){animation-delay:1.54s}
  .home-platform__tier--out .home-platform__box:nth-child(4){animation-delay:1.61s}
  .home-platform__tier--out .home-platform__box:nth-child(5){animation-delay:1.68s}
}

/* —— read more ————————————————————————————————————————————————————————
   The link out to the Platform page, below the diagram, in the brand orange
   (.btn--primary). Orange is the only action colour on the site and teal is
   never used for actions here — the whole band is teal, so a teal or ghost
   button would read as part of the diagram rather than as the way out of
   it. */
.home-platform__more{display:flex;justify-content:center;
  margin-top:clamp(40px,5.2vh,68px)}

/* —— responsive ——————————————————————————————————————————————————————— */
@media (max-width:760px){
  .home-platform{min-height:0}
  .home-platform__tier--out{grid-template-columns:repeat(2,minmax(0,1fr))}
  .home-platform__tierlabel{margin-bottom:10px}
  /* two rows of two: the four-stub fan no longer maps to the boxes, so the
     wire collapses to a single trunk rather than lying about the wiring. */
  .home-platform__wire--up .home-platform__bus,.home-platform__wire--up .home-platform__cell{display:none}
  .home-platform__wire--up .home-platform__trunk{top:0;bottom:0}
  /* Five boxes in two columns leave the fifth stranded in the left column,
     which reads as a layout that ran out rather than as a set of five. Spanning
     both columns and centring it at one column's width makes the tier a 2-2-1
     pointing at the trunk below it — the same shape the wire already draws. */
  .home-platform__tier--out .home-platform__box:nth-child(5){
    grid-column:1 / -1;justify-self:center;
    width:calc(50% - var(--g) / 2)}
}
@media (max-width:520px){
  .home-platform__tier--in{grid-template-columns:1fr}
  .home-platform__wire--down .home-platform__bus,.home-platform__wire--down .home-platform__cell{display:none}
  .home-platform__wire--down .home-platform__trunk{top:0;bottom:0}
}


/* The band had no eyebrow while the three around it did (The Challenge, Why
   PULSAR, Get started), so the page's one architectural diagram was the only
   chapter that did not announce itself. */
.home-platform__eyebrow{margin-bottom:16px}
