/* ============================================================
   components/tablature.css — a tab, drawn from its own text (#267)

   A tab is stored as the text somebody pasted, and it is shown as
   that text: every character stays in the page, on a monospace
   grid, so copying a tab gives the text back. What this sheet adds
   is the drawing underneath it. The dashes of a string are made
   transparent and redrawn as a hairline through their middle, so a
   run of dashes reads as one unbroken string; a fret or a technique
   mark draws no line, which is what cuts the string where the
   number sits on it.

   Three things the drawing depends on, and all three are this
   sheet's:

     - Every character is one cell of the same width (the mono font).

     - THE RUNS STAY INLINE. Never flex items, grid items or inline-
       blocks: a browser copies a block-level child as a line of its
       own, and a tab copied one run per line is not a tab. An inline
       box's background covers the height of its glyphs, which sit
       centred in the row, so the string still lands on the row's
       middle.

     - A BAR LINE EVERY STRING SHARES IS ONE ELEMENT PER STAFF
       (`__barline`), placed by its column and drawn from the middle
       of the top string to the middle of the bottom one. Drawn a row
       at a time, the same line picks up each row's sub-pixel rounding
       differently and steps sideways — 0.66px across a 200-character
       staff, measured. The `|` glyph under it stays in the text,
       transparent, for copying. A `|` only some strings carry is not
       a bar line (tablature.py) and is shown as the glyph it is.

   Markup (partials/_song_tablature.html; the context comes from
   features/dashboards/songs/tablature.py, which has already decided
   what every character is and where the shared bar lines are):

     <figure class="dd-tablature">
       <figcaption class="dd-tablature__caption">
         <span class="dd-tablature__instrument">guitar</span>
         <span class="dd-tablature__part">the riff</span>
       </figcaption>
       <div class="dd-scroll-fade" data-dd-scroll-fade="x">
         <div class="dd-tablature__scroller" data-dd-scroll-fade-scroller>
           <div class="dd-tablature__body">
             <div class="dd-tablature__text">
               <div class="dd-tablature__line">[riff]</div>
             </div>
             <div class="dd-tablature__staff" role="img" aria-label="…">
               <div class="dd-tablature__row"><span
                 class="dd-tablature__label">e</span><span
                 class="dd-tablature__bar dd-tablature__bar--joined
                 dd-tablature__bar--opens">|</span><span
                 class="dd-tablature__string">---</span><span
                 class="dd-tablature__fret">12</span>…</div>
               …
               <span class="dd-tablature__barline"
                 style="--dd-tablature-column: 1" aria-hidden="true"></span>
             </div>
           </div>
         </div>
       </div>
     </figure>

   Run kinds: __gap, __label (the string name, which is also the
   tuning), __string, __bar (--joined where every string shares it;
   --opens / --closes where it has no string on that side), __fret,
   __mark. The spans in a row are written with nothing between them:
   a row is `white-space: pre`, so template whitespace would be a
   column the paste never had.

   A wide tab scrolls sideways — one scroller per tab — with the edge
   fade (design-language §4.1). Re-breaking bars to fit a phone is
   not built.

   Knobs, all optional:
     --dd-tablature-row    the height of one row  (default var(--space-5))
     --dd-tablature-wire   what strings and bar lines are drawn in
                           (default var(--text-muted))
   ============================================================ */

.dd-tablature {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-label);
}

.dd-tablature__caption {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}

.dd-tablature__instrument {
  color: var(--text-muted);
  letter-spacing: var(--tracking-label);
  text-transform: lowercase;
}

.dd-tablature__part {
  color: var(--text);
}

.dd-tablature__scroller {
  overflow-x: auto;
  overflow-y: hidden;
}

/* As wide as the longest line, so every row shares one left edge and the
   scroller measures the whole tab — and never narrower than its host. */
.dd-tablature__body {
  width: max-content;
  min-width: 100%;
  padding-block: var(--space-2);
}

.dd-tablature__row,
.dd-tablature__line {
  height: var(--dd-tablature-row, var(--space-5));
  line-height: var(--dd-tablature-row, var(--space-5));
  white-space: pre;
}

/* The shared bar lines are placed against the staff's own box. */
.dd-tablature__staff {
  position: relative;
}

.dd-tablature__line {
  color: var(--text-soft);
}

.dd-tablature__label,
.dd-tablature__bar {
  color: var(--text-muted);
}

.dd-tablature__fret {
  color: var(--text);
}

.dd-tablature__mark {
  color: var(--text-soft);
}

/* The string: a hairline through the middle of each dash, and through the
   cell of a shared bar line, whose own vertical is the __barline below. */
.dd-tablature__string,
.dd-tablature__bar--joined {
  color: transparent;
  background-image: linear-gradient(
    var(--dd-tablature-wire, var(--text-muted)),
    var(--dd-tablature-wire, var(--text-muted))
  );
  background-repeat: no-repeat;
  background-size: var(--dd-tablature-across, 100%) 1px;
  background-position: var(--dd-tablature-across-at, 0%) 50%;
}

/* A bar line that opens or closes a string carries only the half of the
   string on the tab's side of it, so nothing runs on into the string name
   or past the end of the line. */
.dd-tablature__bar--joined.dd-tablature__bar--opens {
  --dd-tablature-across: 50%;
  --dd-tablature-across-at: 100%;
}

.dd-tablature__bar--joined.dd-tablature__bar--closes {
  --dd-tablature-across: 50%;
  --dd-tablature-across-at: 0%;
}

.dd-tablature__bar--joined.dd-tablature__bar--opens.dd-tablature__bar--closes {
  --dd-tablature-across: 0%;
}

.dd-tablature__barline {
  position: absolute;
  top: calc(var(--dd-tablature-row, var(--space-5)) / 2);
  bottom: calc(var(--dd-tablature-row, var(--space-5)) / 2);
  left: calc((var(--dd-tablature-column) + 0.5) * 1ch);
  width: 1px;
  margin-left: -0.5px;
  background: var(--dd-tablature-wire, var(--text-muted));
  pointer-events: none;
}
