/* Boom Balloon docs theme tweaks. */

/* Orange palette taken from the card artwork, matching the header weave.
   Primary drives links and nav highlights, accent their hover state, so the
   two are kept a step apart in depth. Each scheme gets its own pair: burnt
   orange on white, lighter orange on the dark background, so every colour
   here clears WCAG AA against the page it sits on. */
[data-md-color-primary="custom"] {
  --md-primary-fg-color: #b25306;
  --md-primary-fg-color--light: #d96507;
  --md-primary-fg-color--dark: #7f3a04;
  --md-primary-bg-color: #ffffff;
  --md-primary-bg-color--light: #ffffffb3;
}

[data-md-color-scheme="slate"][data-md-color-primary="custom"] {
  --md-primary-fg-color: #ff9d4f;
  --md-primary-fg-color--light: #ffb066;
  --md-primary-fg-color--dark: #d96507;
}

[data-md-color-accent="custom"] {
  --md-accent-fg-color: #8f4205;
  --md-accent-fg-color--transparent: #8f420519;
  --md-accent-bg-color: #ffffff;
  --md-accent-bg-color--light: #ffffffb3;
}

[data-md-color-scheme="slate"][data-md-color-accent="custom"] {
  --md-accent-fg-color: #ff7b12;
  --md-accent-fg-color--transparent: #ff7b1219;
  --md-accent-bg-color: #2b1400;
  --md-accent-bg-color--light: #2b1400b3;
}

/* Card-back weave pattern (cards/artwork/muster.svg) as the header backdrop.
   The tile (assets/img/muster-tile.png) is cut to whole pattern cells so it
   repeats seamlessly; the dark scrim layered over it keeps the title and
   icons legible. Regenerate the tile with media/generate-pngs.sh. */
.md-header {
  background-image:
    linear-gradient(rgba(60, 20, 0, 0.55), rgba(60, 20, 0, 0.55)),
    url(img/muster-tile.png);
  background-repeat: repeat, repeat;
  background-size: auto, 132px auto;
}

/* The header holds two topics: the site name and the page title. By default
   the theme stacks them and cross-fades to the page title on scroll. We want
   the wordmark to stay put and the page title to sit beside it, so the two
   are laid out as a centred flex row and the swap animation is switched off.
   !important is needed because the theme drives that animation through a
   class it toggles on the parent. */
.md-header__ellipsis {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.md-header__topic {
  position: static !important;
  opacity: 1 !important;
  transform: none !important;
  pointer-events: auto !important;
  z-index: auto !important;
  transition: none !important;
}

/* The page title: allowed to shrink and ellipsise, and dropped entirely on
   narrow screens where the wordmark alone already fills the bar. */
.md-header__topic + .md-header__topic {
  min-width: 0;
  overflow: hidden;
  font-weight: 400;
}

.md-header__topic + .md-header__topic .md-ellipsis {
  overflow: hidden;
  text-overflow: ellipsis;
}

@media screen and (max-width: 59.9375em) {
  .md-header__topic + .md-header__topic {
    display: none;
  }
}

/* Site name set as artwork in the logo's face. The name itself stays in the
   DOM and is pushed out of view, so screen readers and the page title still
   read it. */
.md-header__topic:first-child {
  flex: none;
}

.md-header__topic:first-child .md-ellipsis {
  display: block;
  height: 1.3rem;
  aspect-ratio: 883 / 101;
  max-width: 100%;
  background: url(img/wordmark.png) no-repeat left center;
  background-size: contain;
  text-indent: 110%;
  white-space: nowrap;
  overflow: hidden;
  /* Centring the wordmark's bounding box sits it too low beside the page
     title: Snap ITC has a very large lowercase (x-height is 71% of the cap
     height, against ~53% for the theme's Roboto) and "Boom Balloon" has tall
     capitals but no descenders, so its box centre falls well below its
     visual mass. Lifting it by a tenth of its height puts the lowercase on
     the header's centre line, which also lands within half a pixel of the
     page title's own lowercase. Percentages resolve against the element's
     height, so this holds at any font size. */
  transform: translateY(-10%);
}

/* Responsive gallery of individual card artworks. */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 1rem;
  margin: 1rem 0;
}

.card-grid figure {
  margin: 0;
  text-align: center;
}

.card-grid figure img {
  width: 100%;
  height: auto;
  border-radius: 4px;
}

.card-grid figcaption {
  margin-top: 0.35rem;
  font-size: 0.8rem;
  line-height: 1.25;
  color: var(--md-default-fg-color--light);
}

/* Top and bottom view of the same board, side by side. The PCB renders are
   tall narrow strips (roughly 1:3.5), so sized to the column width a single
   one runs well past a screenful. Capping the height instead keeps the pair
   compact, and since both renders are the same 1600px tall it also lines the
   two boards up with each other. */
.board-pair {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1.5rem;
  margin: 1rem 0;
}

.board-pair figure {
  margin: 0;
  text-align: center;
  /* Half the row minus half the gap, so the two boards always share one row.
     Without this the wider boards (the control board is nearly square) come
     out too broad at the height cap below, overflow the column, and wrap back
     into a stack. */
  max-width: calc(50% - 0.75rem);
}

.board-pair figure img {
  max-height: 24rem;
  width: auto;
  max-width: 100%;
  height: auto;
}

/* On a phone a half-width board is too small to read, so let them stack and
   use the full column instead. */
@media screen and (max-width: 30em) {
  .board-pair figure {
    max-width: 100%;
  }
}

/* Photo gallery of an assembled board: square thumbnails, five to a row,
   wrapping onto further rows. The count steps down on narrow screens, where a
   fifth of the column would be too small to make anything out. Clicking a
   thumbnail opens the full-size photo through the glightbox plugin. */
.gallery {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 0.5rem;
  margin: 1rem 0;
}

@media screen and (max-width: 45em) {
  .gallery {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media screen and (max-width: 30em) {
  .gallery {
    grid-template-columns: repeat(2, 1fr);
  }
}

.gallery img {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 4px;
  transition: transform 125ms;
}

.gallery a:hover img,
.gallery a:focus-visible img {
  transform: scale(1.04);
}

/* Stand-in tile for a board nobody has photographed yet. Drawn rather than
   shipped as an image so it follows the light and dark palettes. */
.gallery__empty {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1;
  padding: 0.5rem;
  border: 1px dashed var(--md-default-fg-color--lighter);
  border-radius: 4px;
  color: var(--md-default-fg-color--light);
  font-size: 0.7rem;
  line-height: 1.3;
  text-align: center;
}

/* Keep a leading column of identifiers on one line: both a single name
   (Displaymodu/l) and a range of them (LED1-/LED5) break badly, and the range
   breaks at the dash between two separate code spans, so the whole cell has
   to hold. Limited to cells that actually contain code, which leaves prose
   columns such as the bill of materials free to wrap as before. */
.md-typeset table:not([class]) td:first-child:has(code) {
  white-space: nowrap;
}

.board-pair figcaption {
  margin-top: 0.35rem;
  font-size: 0.8rem;
  line-height: 1.25;
  color: var(--md-default-fg-color--light);
}

/* Line-art diagrams (WireViz connector diagrams, hand-drawn schematics). The
   SVGs are black wires and text on white boxes, so on the dark (slate) theme
   they need a light panel behind them to stay legible — otherwise the
   connecting wires and any transparent gaps sit on a dark page. The panel is
   light in both themes for the same reason. */
.wiring-diagram {
  margin: 1rem 0;
  text-align: center;
}

.wiring-diagram img {
  width: auto;
  max-width: 100%;
  height: auto;
  padding: 0.75rem 1rem;
  background: #fff;
  border-radius: 6px;
}

.wiring-diagram figcaption {
  margin-top: 0.35rem;
  font-size: 0.8rem;
  line-height: 1.25;
  color: var(--md-default-fg-color--light);
}

/* Home: big visual jump cards into the enclosure/modules/wiring/card-deck
   chapters. Image fills the card, title+teaser sit in a scrim at the
   bottom, the whole card is the link. */
.md-typeset .jump-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.25rem;
  margin: 1.5rem 0;
}

@media screen and (max-width: 45em) {
  .md-typeset .jump-grid {
    grid-template-columns: 1fr;
  }
}

.md-typeset .jump-card {
  position: relative;
  display: block;
  aspect-ratio: 16 / 10;
  border-radius: 8px;
  overflow: hidden;
  color: #fff;
  text-decoration: none;
}

.jump-card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 200ms;
}

.jump-card:hover img,
.jump-card:focus-visible img {
  transform: scale(1.05);
}

.jump-card__label {
  position: absolute;
  inset: auto 0 0 0;
  padding: 0.5rem 1rem;
  /* Solid, not a gradient: a fade left the title (the first, larger line)
     sitting on the near-transparent end, which read fine over dark photos
     but lost contrast over light ones (the wiring diagram, enclosure
     renders). */
  background: rgba(0, 0, 0, 0.62);
}

.jump-card__label strong {
  display: block;
  font-size: 1.05rem;
}

.jump-card__label span {
  display: block;
  font-size: 0.82rem;
  opacity: 0.85;
}

/* Home: click-to-play YouTube facade (see assets/video-embed.js). Shows the
   thumbnail + a play button until clicked, sized to the 9:16 frame Shorts
   are shot in, so nothing loads from YouTube until the visitor opts in. */
.video-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1rem;
  margin: 1.5rem 0;
}

.video-embed {
  position: relative;
  display: block;
  width: 100%;
  max-width: 220px;
  aspect-ratio: 9 / 16;
  padding: 0;
  border: none;
  border-radius: 8px;
  overflow: hidden;
  background: #000;
  cursor: pointer;
}

.video-embed img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.video-embed iframe {
  width: 100%;
  height: 100%;
  border: none;
}

.video-embed__play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.6);
  transition: background 125ms, transform 125ms;
}

.video-embed__play::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 54%;
  transform: translate(-50%, -50%);
  border-style: solid;
  border-width: 0.7rem 0 0.7rem 1.1rem;
  border-color: transparent transparent transparent #fff;
}

.video-embed:hover .video-embed__play,
.video-embed:focus-visible .video-embed__play {
  background: var(--md-accent-fg-color);
  transform: scale(1.08);
}

.video-embed__caption {
  position: absolute;
  inset: auto 0 0 0;
  padding: 0.4rem 0.6rem;
  background: linear-gradient(transparent, rgba(0, 0, 0, 0.75));
  color: #fff;
  font-size: 0.8rem;
  text-align: left;
}
