/* ==========================================================================================
   DATA HUB. The tab strip and the full-page stage.

   style.css already owns everything this page borrows: the masthead, the section rhythm, the
   .research-stage plate, and the .research-widget cover that keeps a failing board off the
   screen. This file is only what a page of tabbed, full-height boards needs on top, and it is
   a separate stylesheet rather than an addition to style.css for one reason: style.css is the
   source chrome.css is GENERATED from (live-site/tools/extract_chrome_css.py), so every rule
   added there has to be reasoned about twice.

   Every colour is a token. No hex, no rgba literal: the page has a light theme and a hard
   coded charcoal is how a page ends up readable in one theme and not the other.
   ========================================================================================== */

/* ---- the head, tightened ----------------------------------------------------------------
   The boards are the page. The heading above them earns one screen-third, not a full section
   of vertical rhythm, so the stage is in view without scrolling on a laptop. */
.boards-head { padding-top: var(--s6); padding-bottom: var(--s4); }
.boards-head .section-head { margin-bottom: 0; }
.boards-head h1 { margin: 0; }
/* The two column head is gone, and so are its rules: there is no second column to place any
   more, only the title and a note that is empty until something goes wrong. */
.boards-head__title .research-sports-line { margin-bottom: var(--s2); }
.boards-note { margin: var(--s3) 0 0; max-width: 64ch; }
/* It is empty until boards.js has a reason to fill it, and an empty paragraph still takes its
   margin, which is the space this section was stripped of on purpose. */
.boards-note:empty { display: none; }

/* ---- the tab strip ----------------------------------------------------------------------
   STICKY, and that is not decoration. A board is a viewport tall, so a strip that scrolls
   away means scrolling back up to change board, every time. --masthead is style.css's own
   token and the masthead is sticky at that height, so the strip sits directly under it.

   It scrolls sideways on a phone rather than wrapping to three rows: seven boards wrapped
   would push the board itself off the screen, which is the one thing this page must not do. */
.boards-bar {
  position: sticky;
  top: var(--masthead);
  z-index: 3;
  background: var(--panel);
  border-top: 1px solid var(--line-soft);
  border-bottom: 1px solid var(--line);
}
.boards-bar[hidden] { display: none; }
.boards-tabs {
  display: flex;
  gap: var(--s2);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  padding: var(--s3) 0;
  /* A thin scrollbar under a row of tabs reads as a rule that is not one. The row is still
     reachable by wheel, drag, arrow key and touch. */
  scrollbar-width: none;
}
.boards-tabs::-webkit-scrollbar { display: none; }

.boards-tab {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
  align-items: flex-start;
  padding: var(--s2) var(--s4);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  background: transparent;
  color: var(--muted);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color 160ms ease, color 160ms ease, background-color 160ms ease;
}
.boards-tab__sport {
  font-family: var(--ui);
  font-size: var(--t-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--brass);
  transition: color 160ms ease;
}
.boards-tab__name {
  font-family: var(--ui);
  letter-spacing: 0.01em;
  white-space: nowrap;
}
.boards-tab:hover {
  border-color: var(--line);
  color: var(--parchment);
  background: var(--panel-2);
}
.boards-tab:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
/* The open board. A gold edge and a gold underline, because the strip sits on a rule and the
   selected tab has to read as part of the board below it rather than as one more chip. */
.boards-tab[aria-selected="true"] {
  border-color: var(--line);
  background: var(--panel-2);
  color: var(--parchment);
  box-shadow: inset 0 -2px 0 var(--brass);
}
.boards-tab[aria-selected="true"] .boards-tab__sport { color: var(--brass-bright); }
/* A board that is not available loses its tab entirely (boards.js explains why there).
   THE EXPLICIT RULE IS REQUIRED: `.boards-tab` sets display: flex, and a class selector beats
   the user agent's own `[hidden] { display: none }`, so without this line a hidden tab stays
   on screen and the whole failover is invisible. */
.boards-tab[hidden] { display: none; }

/* ---- the stage --------------------------------------------------------------------------
   Full bleed at desktop width. The plate style style.css gives .research-stage__board keeps
   its border and its inner light, and loses the radius on a phone where the board is edge to
   edge and a rounded corner over a vendor iframe reads as a rendering fault. */
.boards-stage { padding: var(--s5) 0 var(--s6); }
.boards-stage[hidden] { display: none; }
/* The SAME measure as .wrap, written out rather than reusing the class, because the stage is
   a plate with its own padding and nesting .wrap inside it would indent the board twice. The
   heading, the tab strip and the board all start on one line down the page; they did not on
   the first pass and the misalignment was the first thing the screenshot showed. */
.boards-stage__inner {
  width: 100%;
  max-width: calc(var(--wrap) + 2 * var(--gutter));
  margin: 0 auto;
  padding: 0 var(--gutter);
}
.boards-stage .research-stage__board { padding: var(--s4); }
@media (min-width: 60rem) {
  .boards-stage .research-stage__board { padding: var(--s5); }
}

/* ONE PANEL AT A TIME, BY CLASS AND NOT BY [hidden], and the reason is worth the line:
   statyx.js sets and clears the `hidden` ATTRIBUTE on a board's slot as its way of saying
   dead or alive. If tab switching used the same attribute on the same elements, a board
   coming alive would reveal a tab nobody opened. Two mechanisms, two switches, no argument. */
.boards-panel { display: none; }
.boards-panel.is-active { display: block; }
.boards-panel__about {
  margin: 0 0 var(--s4);
  max-width: 76ch;
  color: var(--muted);
}
.boards-panel__state {
  margin: 0 0 var(--s4);
  color: var(--muted);
  font-family: var(--ui);
  font-size: var(--t-micro);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.boards-panel__state[hidden] { display: none; }

/* The vendor element sizes its own iframe from a height attribute boards.js measures. All
   this has to do is stop it being narrower than the plate it sits in. */
.boards-stage statyx-widget {
  display: block;
  width: 100%;
  min-width: 0;
}

.boards-foot { padding-top: 0; }
.boards-foot .block-note { max-width: 76ch; }

@media (prefers-reduced-motion: reduce) {
  .boards-tab,
  .boards-tab__sport { transition: none; }
}
