/* ════════════════════════════════════════════════════════════════════════
   css/components/folio.css — THE RUNNING HEAD
   service.tnaado.ca · reusable · pairs with js/folio.js

   PORTED from the old live site's .mflow__folio rules in css/mediaroom.css,
   including a bug that file had already found and fixed the hard way. Read
   the note on the chip below before removing the background.

   WHAT IT IS. One fixed marginal in the left gutter, rotated to read up the
   page, naming the section you are currently in. Desktop only. Never
   interactive, never in the tab order, never over content — it lives in
   margin this layout already leaves empty at 1180px and above.

   ── THE CHIP IS NOT DECORATION ─────────────────────────────────────────
   The rail is position:fixed, which makes it a SIBLING of every band on the
   page rather than a child of one. So it cannot inherit a band's token
   remap. On the old site it painted a pale cream over a cream band and went
   invisible on exactly the pages that were light. It carries its own dark
   ground for that reason, which is legible over both the bone bands and the
   ink ones, and costs one background. Do not "simplify" it to a bare colour.

   ── WHY IT IS NOT IN THE TAB ORDER ─────────────────────────────────────
   pointer-events: none and no focusable child, on purpose. It duplicates
   information a keyboard user already has in better form — the headings —
   and a screen reader gets nothing from a label that changes under it as
   the page scrolls. aria-hidden in the markup says the same thing to AT.
   ════════════════════════════════════════════════════════════════════════ */

.folio {
  /* Local tokens, bridged to the site's with fallbacks, so this file can be
     linked on a page that has not loaded every global sheet. */
  --fo-mono: var(--font-mono, 'JetBrains Mono', ui-monospace, Menlo, monospace);
  --fo-red:  var(--red, #c8102e);
  --fo-ink:  #f5f1e8;
  --fo-ease: var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1));

  position: fixed;

  /* ── PHYSICAL `left`/`top`, NOT `inset-inline-start`/`inset-block-start`.
     This is not an oversight and it must not be "modernised" back.

     Logical inset properties resolve against THE ELEMENT'S OWN writing mode.
     This element sets `writing-mode: vertical-rl`, which turns its inline
     axis vertical and its block axis horizontal — so on this element
     `inset-inline-start` means TOP and `inset-block-start` means RIGHT.
     Written logically, the rail lands centre-top, rotated, sitting across the
     page heading. Verified in a browser, which is the only reason it was
     caught: it looks perfectly correct in source.

     The rail is pinned to a physical screen edge, so it wants physical
     properties. Logical properties are right when a box should flip with the
     document's direction; this one should not. ─────────────────────────── */
  left: clamp(.9rem, 2.2vw, 1.8rem);
  top: 50%;
  z-index: 40;

  /* rotate(180deg) on top of vertical-rl reads BOTTOM-TO-TOP, which is the
     spine direction a reader expects on a left margin. */
  transform: translateY(-50%) rotate(180deg);
  writing-mode: vertical-rl;

  /* display:none until js/folio.js adds .is-live. Without script there is no
     label to show, and an empty chip in the margin is worse than no chip. */
  display: none;
  align-items: center;
  gap: .9rem;

  padding: .85rem .38rem;
  border-radius: 2px;
  background: rgba(10, 10, 10, .78);
  color: var(--fo-ink);

  font-family: var(--fo-mono);
  font-size: .58rem;
  line-height: 1;
  letter-spacing: .28em;
  text-transform: uppercase;

  pointer-events: none;
  opacity: 0;
  transition: opacity 320ms var(--fo-ease);
}

.folio.is-live { display: flex; }
.folio.is-on   { opacity: 1; }

/* The red tail. A gradient rather than a solid rule so it reads as the rail
   fading into the page rather than as a second element beside the label. */
.folio::after {
  content: '';
  width: 1px;
  height: 42px;
  background: linear-gradient(to bottom, var(--fo-red), transparent);
  flex: none;
}

/* ── the crossfading label ────────────────────────────────────────────────
   Both labels occupy the same grid cell, so the chip is sized by the LONGER
   of the two during a swap and never jitters in width as the text changes.
   A stacking context of two absolutely-positioned spans would collapse the
   chip to nothing; a one-cell grid will not. */
.folio__slot {
  display: grid;
  grid-template-areas: 'lab';
  align-items: center;
  justify-items: start;
}

.folio__lab {
  grid-area: lab;
  white-space: nowrap;

  /* Enter and exit are both a fade with a hair of blur. The blur is doing
     real work: without it a crossfade shows two legible strings overlapping
     and reads as a mistake, and at this size and letter-spacing that is very
     visible. 1.5px is enough to blend them and cheap enough for Safari. */
  transition: opacity 260ms var(--fo-ease), filter 260ms var(--fo-ease);
}

/* First label visible by default; the flip is which one is transparent. */
.folio__lab:nth-child(1) { opacity: 1; filter: blur(0); }
.folio__lab:nth-child(2) { opacity: 0; filter: blur(1.5px); }
.folio.is-b .folio__lab:nth-child(1) { opacity: 0; filter: blur(1.5px); }
.folio.is-b .folio__lab:nth-child(2) { opacity: 1; filter: blur(0); }

/* Below this there is no gutter to sit in. js/folio.js checks the same
   breakpoint and does not start, so the two can never disagree. */
@media (max-width: 1179px) {
  .folio.is-live { display: none; }
}

/* Reduced motion keeps the rail and keeps the label changing — that is
   information — and removes only the fades. */
@media (prefers-reduced-motion: reduce) {
  .folio,
  .folio__lab { transition: none; }
  .folio__lab { filter: none; }
  .folio.is-b .folio__lab:nth-child(1),
  .folio.is-b .folio__lab:nth-child(2),
  .folio__lab:nth-child(1),
  .folio__lab:nth-child(2) { filter: none; }
}

/* Printing a fixed marginal puts it on every sheet. */
@media print { .folio { display: none !important; } }
