/* ═══════════════════════════════════════════════════════════════════════
   THE BLUEPRINT

   A documentation figure that explains itself as you scroll past it.

   The plate — a piece of the app on grid paper — pins to the top of the
   sheet. The steps run underneath it. Whichever step you are reading is the
   one that is lit: its callout brightens in the margin and a highlighter
   band slides to the row it names. Scroll on and the band moves with you.

   A static figure with four numbers on it asks you to do the matching
   yourself, over and over, in both directions. This does the matching for
   you, one part at a time, in the order the explanation goes.

   NOTHING IS EVER HIDDEN TO DO IT. The first version of this lit one part by
   washing every other part back into the paper, and the callouts sat on the
   drawing — which put the "1" on top of the word "Research" and left the
   rest of the interface all but invisible. A figure that hides the thing it
   is a figure of has stopped being one. So the callouts stand in the margin
   with leader lines reaching in, and the emphasis is a translucent band,
   like a highlighter drawn across a printed page.

   WHAT IS INSIDE THE FRAME IS THE REAL THING. Not a screenshot and not a
   drawing of one — the app's own markup and the app's own stylesheets,
   rendered live. A screenshot is stale the day after it is taken, carries
   whoever's data was on screen, and ignores the theme. This cannot go
   stale: if .ce-field changes, the figure changes with it, in both themes,
   at any width. The only thing done to it is that it cannot be clicked.

     .bp-plate   the sheet: dimension line, drawing, highlighter bands
     .bp-pin     a numbered callout, in the margin, never on the drawing
     .bp-band    the highlighter, moving down the drawing as you read
     .bp-step    one line of the explanation, lit as you reach it
   ═══════════════════════════════════════════════════════════════════════ */

.bp {
  --bp-grid: var(--b1);
  --bp-major: var(--b2);
  --bp-ink: var(--t3);

  position: relative;
  margin: 24px 0;
  padding: 22px 18px 18px;
  border: 1px solid var(--b2);
  border-radius: var(--r-5, 12px);
  background-color: var(--bg1);
  background-image:
    linear-gradient(var(--bp-grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--bp-grid) 1px, transparent 1px),
    linear-gradient(var(--bp-major) 1px, transparent 1px),
    linear-gradient(90deg, var(--bp-major) 1px, transparent 1px);
  background-size: 15px 15px, 15px 15px, 75px 75px, 75px 75px;
  background-position: -1px -1px;
}

/* The corner mark every drawing has, so a figure can be named in words. */
.bp-no {
  position: absolute;
  top: 0; right: 0;
  z-index: 4;
  padding: 5px 10px;
  border-left: 1px solid var(--b2);
  border-bottom: 1px solid var(--b2);
  border-bottom-left-radius: var(--r-3, 8px);
  background: var(--bg2);
  font-family: var(--ff-mono, ui-monospace, monospace);
  font-size: 10.5px;
  letter-spacing: .06em;
  color: var(--t4);
}

/* ── THE PLATE ──
   NOT sticky. It was, so that the drawing would stay on screen while the
   steps scrolled past it — and a sticky element whose siblings scroll
   underneath covers them with its own background. "Short text became one
   line" rendered behind the white card. A figure whose two halves overlap
   is not a figure.

   So the drawing and its explanation sit still, one above the other, and
   the whole figure is made short enough that both are on screen together.
   That is what the scrolling was trying to buy, bought honestly. */

/* ── THE DIMENSION LINE ──
   A rule with a tick at each end and the measurement in a gap in the middle,
   which is how a drawing says how wide a thing is. */
.bp-dim {
  position: relative;
  height: 11px;
  margin: 0 0 12px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.bp-dim::before {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 50%;
  height: 1px;
  background: var(--bp-major);
}
.bp-dim > span {
  position: relative;
  padding: 0 9px;
  background: var(--bg1);
  font-family: var(--ff-mono, ui-monospace, monospace);
  font-size: 10.5px;
  letter-spacing: .04em;
  color: var(--bp-ink);
}
.bp-dim > i { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--bp-major); }
.bp-dim > i:first-of-type { left: 0; }
.bp-dim > i:last-of-type { right: 0; }

/* ── THE DRAWING ──
   The app itself, lifted off the grid by its shadow so the two read as
   separate things rather than one busy surface. */
.bp-ui {
  position: relative;
  border-radius: var(--r-4, 10px);
  background: var(--bg2);
  border: 1px solid var(--b2);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .06), 0 8px 22px rgba(0, 0, 0, .07);
  overflow: hidden;
  /* A picture of the app, not a second copy of it running in the docs. */
  pointer-events: none;
  user-select: none;
}
.bp-ui > .bp-inner { position: relative; z-index: 1; padding: 14px; }

/* ── THE HIGHLIGHTER ──
   What replaced the spotlight, and why.

   The spotlight washed everything except a 58px circle back into the paper.
   On a drawing whose whole job is to show you an interface, that hid the
   interface — "Reference links", "Thumbnail draft" and "Packaging" were all
   but invisible while a number floated over the one label you could still
   read. A figure that hides the thing it is a figure of has stopped being
   one.

   So nothing is ever hidden now. A translucent band moves down the drawing
   like a highlighter being drawn across a printed page, with a solid rule at
   its leading edge. The row under it tints; it does not disappear, and
   neither does anything else. */
.bp-band {
  position: absolute;
  left: 0;
  right: 0;
  top: var(--by, 50%);
  height: var(--bh, 40px);
  transform: translateY(-50%);
  z-index: 2;
  pointer-events: none;
  background: var(--accent-bg);
  border-left: 2px solid var(--accent);
  opacity: 0;
  transition: opacity .2s ease;
}
.bp-band[data-n] { opacity: 0; }

/* The band belongs to one step. Point at that step — or at its callout in
   the margin — and the row it names tints. Nothing moves on its own, so
   nothing can be lit for a line you are not reading.

   Six rules rather than a loop: a figure with more than six parts is one
   figure doing two jobs. */
.bp:has(.bp-step[data-n="1"]:hover) .bp-band[data-n="1"],
.bp:has(.bp-pin[data-n="1"]:hover)  .bp-band[data-n="1"],
.bp:has(.bp-step[data-n="2"]:hover) .bp-band[data-n="2"],
.bp:has(.bp-pin[data-n="2"]:hover)  .bp-band[data-n="2"],
.bp:has(.bp-step[data-n="3"]:hover) .bp-band[data-n="3"],
.bp:has(.bp-pin[data-n="3"]:hover)  .bp-band[data-n="3"],
.bp:has(.bp-step[data-n="4"]:hover) .bp-band[data-n="4"],
.bp:has(.bp-pin[data-n="4"]:hover)  .bp-band[data-n="4"],
.bp:has(.bp-step[data-n="5"]:hover) .bp-band[data-n="5"],
.bp:has(.bp-pin[data-n="5"]:hover)  .bp-band[data-n="5"],
.bp:has(.bp-step[data-n="6"]:hover) .bp-band[data-n="6"],
.bp:has(.bp-pin[data-n="6"]:hover)  .bp-band[data-n="6"] { opacity: 1; }

/* ── THE CALLOUTS ──
   In the margin, never on the drawing.

   They used to be pinned at an x and a y over the plate, which put the "1"
   squarely on top of the word "Research". A callout that covers the thing it
   names is worse than no callout. They stand in a gutter now, outside the
   frame, with a leader line reaching in — which is where a drawing has
   always put them — so a number cannot cover anything, ever.

   Which gutter is decided by the part's own side: something on the left of
   the drawing is called out from the left. */
.bp-frame { position: relative; padding: 0 38px; }

.bp-pin {
  position: absolute;
  z-index: 4;
  top: var(--y, 50%);
  width: 22px;
  height: 22px;
  margin-top: -11px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .25);
  font-size: 11px;
  font-weight: 700;
  line-height: 22px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  opacity: .9;
  cursor: default;
  transition: transform .2s cubic-bezier(.2, .9, .3, 1), box-shadow .2s;
}
.bp-pin.l { left: 3px; }
.bp-pin.r { right: 3px; }

/* The leader: a hairline from the disc to the edge of the drawing. */
.bp-pin::after {
  content: '';
  position: absolute;
  top: 50%;
  width: 13px;
  height: 1px;
  background: var(--accent);
  opacity: .5;
}
.bp-pin.l::after { left: 100%; margin-left: 2px; }
.bp-pin.r::after { right: 100%; margin-right: 2px; }

/* Pointed at, from either end. */
.bp-pin:hover,
.bp:has(.bp-step[data-n="1"]:hover) .bp-pin[data-n="1"],
.bp:has(.bp-step[data-n="2"]:hover) .bp-pin[data-n="2"],
.bp:has(.bp-step[data-n="3"]:hover) .bp-pin[data-n="3"],
.bp:has(.bp-step[data-n="4"]:hover) .bp-pin[data-n="4"],
.bp:has(.bp-step[data-n="5"]:hover) .bp-pin[data-n="5"],
.bp:has(.bp-step[data-n="6"]:hover) .bp-pin[data-n="6"] {
  transform: scale(1.14);
  box-shadow: 0 0 0 5px var(--accent-glow), 0 1px 3px rgba(0, 0, 0, .25);
}

/* They draw themselves in as the figure arrives, one after the other. */
@keyframes bpPinIn {
  from { opacity: 0; transform: scale(.4); }
  to   { opacity: .9; transform: scale(1); }
}
.bp-pin { animation: bpPinIn .45s backwards cubic-bezier(.2, .9, .3, 1); animation-delay: calc(var(--i, 0) * 90ms); }

/* ── THE EXPLANATION ──
   Tight. The steps used to be 92px apart to make room for a scroll that
   needed the distance, which left a column of empty paper between one line
   and the next and read as a broken layout. The reveal does not need the
   gap, so it does not get it. */
.bp-steps {
  margin: 16px 0 0;
  padding: 0;
  list-style: none;
  counter-reset: bpstep;
}
.bp-step {
  position: relative;
  padding: 6px 8px 6px 34px;
  margin: 0;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--t2);
  cursor: default;
  border-radius: var(--r-2, 6px);
  transition: background .18s ease;
}
.bp-step::before {
  counter-increment: bpstep;
  content: counter(bpstep);
  position: absolute;
  left: 0;
  top: 7px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--bg4);
  color: var(--t3);
  font-size: 11px;
  font-weight: 700;
  line-height: 22px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  transition: background .28s, color .28s, box-shadow .28s;
}
/* The rail the numbers hang on, the way a legend is ruled off on a drawing. */
.bp-step::after {
  content: '';
  position: absolute;
  left: 10px;
  top: 34px;
  bottom: 0;
  width: 1px;
  background: var(--b2);
}
.bp-step:last-child::after { display: none; }

.bp-step:hover { background: var(--accent-bg); }
.bp-step:hover::before { background: var(--accent); color: #fff; }
.bp-step b { color: var(--tx); font-weight: 600; }

/* ── THE CAPTION ── */
.bp-cap {
  margin: 14px 0 0;
  padding-top: 13px;
  border-top: 1px solid var(--b1);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--t3);
}
.bp-cap b { color: var(--t2); font-weight: 600; }

/* ── FRAGMENT HELPERS ──
   Neutral pieces for the parts of a figure that are not a component in their
   own right: a column heading, a run of body text. Token-driven, so they
   follow the theme like everything else. */
.bp-bar { height: 8px; border-radius: 99px; background: var(--bg4); }
.bp-bar.w90 { width: 90%; } .bp-bar.w70 { width: 70%; } .bp-bar.w55 { width: 55%; }
.bp-bar.w40 { width: 40%; } .bp-bar.w25 { width: 25%; }
.bp-bar.ac { background: var(--accent); opacity: .5; }
.bp-stack { display: grid; gap: 9px; }
.bp-row { display: flex; align-items: center; gap: 9px; }
.bp-col { display: grid; gap: 9px; align-content: start; }
.bp-lbl {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--t4);
}

/* ── LEARN MORE ──
   The link a feature's own header carries to the figure that explains it. It
   lives here rather than in utils.css because it is one half of a pair: this
   and .bp are the whole of "the header says what, the docs show how".

   Quiet by default — a header is not the place for a second call to action —
   and it takes the accent only on hover, where the arrow steps forward. */
.learn-more {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-left: 10px;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--t3);
  text-decoration: none;
  white-space: nowrap;
  vertical-align: baseline;
  border-bottom: 1px solid transparent;
  transition: color .14s, border-color .14s;
}
.learn-more svg { transition: transform .16s cubic-bezier(.2, .8, .3, 1); }
.learn-more:hover { color: var(--accent); border-bottom-color: var(--accent-line); }
.learn-more:hover svg { transform: translateX(2px); }
.learn-more:focus-visible {
  outline: none;
  color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-line);
  border-radius: 3px;
}

/* ── WHEN MOTION IS NOT WANTED ──
   The reveal is a nicety; the content is not. Everything is shown at once,
   with no transitions and no highlighter, and the figure still reads as a
   drawing with a numbered legend. */
@media (prefers-reduced-motion: reduce) {
  .bp-pin { animation: none; }
  .bp-pin, .bp-step, .bp-step::before, .bp-band { transition: none; }
}

@media (max-width: 560px) {
  .bp { padding: 22px 11px 16px; }
  .bp-frame { padding: 0 30px; }
}
