/* ============================================================================
   JT RANK LADDER MODULE — v1.0.0

   Figma component "ranks · line-art" (506:24904). Read from the node tree.

   MEASURED
     row         HORIZONTAL, gap 0 — the connectors ARE the gaps
     rank        72 wide (rank-03's label is 81, and overhangs), VERTICAL gap 16
     insignia    72×78
     index       Tektur Regular 13 / +2 / upper / #f0a416 at 96%
     name        Tektur Medium 11 / +1.7 / upper / #8fa2b6
     connector   fills the space; a 1px #d06700 line, 34px down from the top of
                 the insignia block, inset 16 each side, with a FILLED ROUND CAP
                 at each end. Figma calls it strokeCap CIRCLE_FILLED; measured
                 from absoluteRenderBounds it is 5.3333px across — the geometric
                 line is 56.333 wide and renders 61.666, so 2.667 of cap per end.
                 The landing shipped without them before this module, so they are
                 a correction it brings rather than a change of design.

   IT RESIZES, AND THAT IS THE POINT. The same component is 1600 wide on the
   landing page and 1043 on the rank system page; the insignia stay at 72 and
   the connectors go 181 → 88. So the row is a grid of `auto` and `1fr` tracks
   and needs no width knob at all — give it a box and it fits.

   That is also why the connectors are real <li> elements rather than
   pseudo-elements: a pseudo-element cannot be a grid track, and the tracks are
   what stretch.

   SELF-CONTAINED, per MODULES.md — every colour and face is declared here. It
   used to live in landing.css and read --amber, --amber-deep, --body-dim and
   --display from it.

   NAMING
   Everything is --jt-ladder- prefixed and .jt-ladder scoped.
   ========================================================================== */

.jt-ladder {
  /* --- knobs -------------------------------------------------------------
     The insignia's drawn size. Everything else follows from it, so a page that
     needs a smaller ladder changes this one value. */
  --jt-ladder-insignia-w: 72px;
  --jt-ladder-insignia-h: 78px;

  /* The smallest a connector may get before the row starts scrolling instead
     of squeezing. The comp's narrowest is 88; below ~16 the line has no room
     left once its 16px insets are taken. */
  --jt-ladder-link-min: 24px;

  /* THE INDEX IS A LITERAL AND THE NAME IS A TOKEN, and the difference is the
     comp's, not a slip. Re-read from `ranks · line-art` 2026-09-09: the index's
     fill is unbound in Figma — a one-off amber that belongs to this drawing —
     while the name's fill is bound to the "Paragraph - bright" variable, which
     is this site's --text-paragraph-bright. A bound fill should arrive here as
     the token, so that a change to the collection reaches the ladder.

     The name was #8fa2b6 and had been since before the tokens existed: a grey
     that no longer appears anywhere in the design. It is #e8f4fd. */
  --jt-ladder-index: rgba(240, 164, 22, 0.96);  /* #f0a416 at the comp's 96% */
  --jt-ladder-name:  var(--text-paragraph-bright, #e8f4fd);
  --jt-ladder-line:  #d06700;

  /* THE CONNECTOR'S TWO ENDS ARE NOT THE SAME SHAPE. Figma draws the line as a
     single vector with a different cap on each vertex — DIAMOND_FILLED where it
     leaves a rank, ARROW_EQUILATERAL where it arrives at the next — so the row
     reads as a direction of travel rather than a chain. Measured off the export:
     the diamond is 5.7734 across, the arrowhead 5 long and 5.7735 tall, and the
     arrow's TIP (not its base) lands on the vertex. */
  --jt-ladder-diamond: 5.7734px;
  --jt-ladder-arrow-w: 5px;
  --jt-ladder-arrow-h: 5.7735px;

  /* Whether the connector draws at all. The rank system page's comp hides them
     below 768, where the row is too tight for a line to read as anything but
     clutter; the ranks still sit apart, because the track stays and only its ink
     goes. `visibility`, never `display` — the connector is a grid track, and
     collapsing it would close the gaps it exists to hold open. */
  --jt-ladder-link-ink: visible;

  /* The label block's offset under the insignia. The comp's 16px gap applies
     once, above the block, so the default pulls the name back up under its
     index. The rank system page opens it out at its small breakpoint, where the
     insignia shrink to 54 and the labels need the air — which is a knob rather
     than that page reaching into .jt-ladder__index. */
  --jt-ladder-label-lift: -12px;

  /* THE LABEL TYPE SCALES WITH THE INSIGNIA, and it is drawn, not derived.
     `ranks · line-art` sets index 13 / name 11 in its 1025 frame and index
     9.75 / name 8.25 in all three frames below it — the same step the insignia
     take from 72 to 54.

     They were fixed at 13/11 at every width while the insignia shrank, so on a
     phone the names were about a third wider than drawn and ran into each
     other. Sizes, not a scale factor, because that is how the comp states
     them. */
  --jt-ladder-index-size: 13px;
  --jt-ladder-name-size:  11px;
  --jt-ladder-font:  "Tektur", ui-monospace, "SFMono-Regular", Menlo, monospace;

  /* The comp draws the whole row; on a narrow screen it scrolls rather than
     wrapping, because a ladder that wraps is no longer a ladder. */
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: thin;
}

.jt-ladder__row {
  display: grid;
  /* auto 1fr auto 1fr … auto — seven ranks and six stretching connectors.
     Written out rather than generated, because it is the component's own
     structure and reading it here is the point. */
  grid-template-columns:
    auto minmax(var(--jt-ladder-link-min), 1fr)
    auto minmax(var(--jt-ladder-link-min), 1fr)
    auto minmax(var(--jt-ladder-link-min), 1fr)
    auto minmax(var(--jt-ladder-link-min), 1fr)
    auto minmax(var(--jt-ladder-link-min), 1fr)
    auto minmax(var(--jt-ladder-link-min), 1fr)
    auto;
  align-items: start;
  min-width: min-content;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* THE COLUMN CAN BE TOLD TO HUG ITS LABEL, and that is what stops the names
   colliding where the connectors are hidden.

   A rank name is `white-space: nowrap` and centred on a column that is normally
   the insignia's width — 54px at the small sizes. Most names are wider than
   that: RU's "ПОСЛЕДОВАТЕЛЬ" is 108. While the connectors are drawn the columns
   sit far enough apart for the overhang to be harmless, which is why the comp
   tolerates it and why MODULE.md filed it as a known limitation. Take the
   connectors away and the tracks close to ~14px, and the overhang stops being
   an overhang: at 375 the RU labels overlapped by 7 and 11px, and EN and PL by
   7 and 3.

   `--jt-ladder-rank-w: auto` makes each track as wide as its own label, so the
   names cannot collide in ANY language — which a hand-picked gap cannot
   promise, because the next translation is always longer than the last.
   `min-width` keeps the insignia at its drawn size regardless. */
.jt-ladder__rank {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  width: var(--jt-ladder-rank-w, var(--jt-ladder-insignia-w));
  min-width: var(--jt-ladder-insignia-w);
}

.jt-ladder__insignia {
  display: block;
  width: var(--jt-ladder-insignia-w);
  height: var(--jt-ladder-insignia-h);
}

.jt-ladder__svg { display: block; width: 100%; height: 100%; overflow: visible; }

.jt-ladder__index {
  color: var(--jt-ladder-index);
  opacity: 0.96;
  font-family: var(--jt-ladder-font);
  font-size: var(--jt-ladder-index-size);
  font-weight: 400;
  letter-spacing: 2px;
  line-height: 1.3;
  text-transform: uppercase;
}

/* The 16px gap applies once, above the label block; the name sits directly
   under its index rather than a second gap down. --jt-ladder-label-lift is what
   a page adjusts when its insignia are smaller than the comp's. */
.jt-ladder__name {
  margin-top: var(--jt-ladder-label-lift);
  /*color: var(--jt-ladder-name);*/
  font-family: var(--jt-ladder-font);
  font-size: var(--jt-ladder-name-size);
  font-weight: 500;
  letter-spacing: 1.7px;
  line-height: 1.27;
  text-transform: uppercase;
  text-align: center;
  white-space: nowrap;
}

/* The connector. Its <li> is the stretching track; the line inside it is inset
   16 each side and sits 34 down, level with the middle of the insignia. */
.jt-ladder__link {
  position: relative;
  height: var(--jt-ladder-insignia-h);
  visibility: var(--jt-ladder-link-ink);
}

.jt-ladder__link::before {
  content: "";
  position: absolute;
  left: 16px;
  right: 16px;
  top: 34px;
  height: 1px;
  background: var(--jt-ladder-line);
  transform-origin: left center;
}

/* The two caps — a diamond leaving, an arrowhead arriving.

   BOTH ON ONE ELEMENT, still, and for the original reason: ::before IS the
   line, and the landing's reveal scales it from scaleX(0). A cap riding that
   transform would arrive squashed and grow into shape, which is not what a
   stroke cap does. This element is left alone by the reveal.

   MASKS, NOT DATA-URI IMAGES. The shapes have to be paintable with
   --jt-ladder-line, and an <svg> in a url() cannot read a custom property — it
   would freeze the colour and quietly ignore any page that retints the ladder.
   So the element is a solid rectangle of the line colour, and the mask decides
   where that colour survives.

   THE GEOMETRY IS THE EXPORT'S, NOT AN APPROXIMATION. In the exported vector
   the two vertices sit at the connector's 16px insets. The diamond is CENTRED
   on the first, so this box starts half a diamond early; the arrow's TIP is on
   the second, so the box ends exactly at the inset and the arrow is pulled
   right against it. Getting that backwards puts the arrowhead a whole 5px past
   where the line stops. */
.jt-ladder__link::after {
  content: "";
  position: absolute;
  left: calc(16px - var(--jt-ladder-diamond) / 2);
  right: 16px;
  /* Centred on the line: its own 1px sits at 34, so the centre is 34.5. */
  top: calc(34.5px - var(--jt-ladder-arrow-h) / 2);
  height: var(--jt-ladder-arrow-h);
  background: var(--jt-ladder-line);

  --jt-ladder-cap-diamond: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 5.7734 5.7734'%3E%3Cpath d='M0 2.8867 2.8867 5.7734 5.7734 2.8867 2.8867 0Z' fill='%23000'/%3E%3C/svg%3E");
  --jt-ladder-cap-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 5 5.7735'%3E%3Cpath d='M5 2.88675 0 0v5.7735Z' fill='%23000'/%3E%3C/svg%3E");

  -webkit-mask-image: var(--jt-ladder-cap-diamond), var(--jt-ladder-cap-arrow);
          mask-image: var(--jt-ladder-cap-diamond), var(--jt-ladder-cap-arrow);
  -webkit-mask-position: left center, right center;
          mask-position: left center, right center;
  -webkit-mask-size: var(--jt-ladder-diamond) var(--jt-ladder-diamond),
                     var(--jt-ladder-arrow-w) var(--jt-ladder-arrow-h);
          mask-size: var(--jt-ladder-diamond) var(--jt-ladder-diamond),
                     var(--jt-ladder-arrow-w) var(--jt-ladder-arrow-h);
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  pointer-events: none;
}

/* ---------------------------------------------------------------------------
   Narrow viewports

   Derived, not drawn — the comp gives two widths and both are wide. Below
   700px the whole row no longer fits even at the minimum connector, so the
   module scrolls it; the insignia keep their drawn size, which is what makes
   them legible at all.
   ------------------------------------------------------------------------- */
@media (max-width: 700px) {
  .jt-ladder { --jt-ladder-link-min: 16px; }
}
@media (max-width: 1024px) {
  .ladder-hero__stage .jt-ladder__rank { gap: 5px; }
}

