/* ─────────────────────────────────────────────────────────────
   flipboard — a split-flap board, the Ferry Building kind
   Tokens mirror the Figma "Flipboard" variable collection 1:1.
   Retune here; the whole board follows.
   ───────────────────────────────────────────────────────────── */

.flipboard {
  /* geometry */
  --cell-w: 34px;
  --cell-h: 48px;
  --gap-x: 3px;
  --gap-y: 4px;
  --radius-chrome: 18px;
  --radius-cell: 3px;
  --pad: 24px;
  --char-size: 24px;
  /* scales the chrome (plate, rail, spacing) alongside the cell tokens,
     so the board can be shrunk to fit a card without the type staying
     stranded at full size */
  --chrome-scale: 1;

  /* chassis */
  --chassis: #0b0910;
  --rail: #131019;
  --hairline: rgba(255, 255, 255, 0.07);
  /* the outline around the whole board — deliberately fainter than
     --hairline, which also draws the cell catchlight and chip seams */
  --chassis-stroke: rgba(255, 255, 255, 0.035);

  /* flap faces — the top half sits lighter, real flaps catch light */
  --flap-top: #1e1a24;
  --flap-bottom: #15121a;
  --seam: #08060b;
  --seam-light: #2a2532;
  --hinge: #322b3c;

  /* ink */
  --ink: #f2ecf7;
  --ink-dim: #8c8299;

  /* the About page family */
  --accent-purple: #bc4af0;
  --accent-orchid: #d56ee8;
  --accent-magenta: #d83fbe;
  --accent-red: #ff3354;

  /* one flap's fall, in ms. lower = frantic, higher = stately */
  --flip-ms: 110;

  /* Hidden until the board has been measured, fitted and had its font.
     Everything before that — building 156 cells at full-size tokens, then
     scaling them down to the container — is setup, and none of it should
     be watchable. The container's own dark background shows through in
     the meantime, which is the resting state anyway. */
  opacity: 0;

  display: inline-flex;
  flex-direction: column;
  gap: calc(20px * var(--chrome-scale));
  padding: var(--pad);
  background: var(--chassis);
  border: 0;
  border-radius: var(--radius-chrome);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.6);
  /* Ubuntu Sans Mono has no ✺ ❖ ◆ — the symbol fonts cover those glyphs
     only, so the ornaments stay full-size instead of falling back to
     whatever tiny dot the browser picks */
  font-family: "Ubuntu Sans Mono", "Apple Symbols", "Segoe UI Symbol",
    "Noto Sans Symbols 2", ui-monospace, monospace;
}

/* The board itself appears as soon as it's measured and fitted -- blank
   flaps, which is a real board's resting state. Only the CHARACTERS wait
   for the page to go idle. Hiding the whole thing meant an empty card for
   a second or two on a page this heavy. */
.flipboard.is-fitted {
  opacity: 1;
  transition: opacity 260ms ease;
}
.flipboard.is-ready { opacity: 1; }

/* no JS: never hide the board behind a class that will never be added */
.no-js .flipboard { opacity: 1; }

/* ── title plate ────────────────────────────────────────────── */

.fb-plate {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(24px * var(--chrome-scale));
  padding: calc(14px * var(--chrome-scale)) calc(16px * var(--chrome-scale));
  background: var(--rail);
  border-radius: calc(8px * var(--chrome-scale));
}

.fb-plate__title {
  margin: 0;
  font-size: calc(15px * var(--chrome-scale));
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--ink);
  text-transform: uppercase;
}

.fb-plate__index {
  font-size: calc(13px * var(--chrome-scale));
  font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--ink-dim);
  font-variant-numeric: tabular-nums;
}

/* the one red mark on the chrome — the heart suit, not the emoji */
.fb-plate__mark {
  color: var(--accent-red);
  font-size: calc(12px * var(--chrome-scale));
  /* the suit glyph sits high on its baseline; nudge it back onto the numerals */
  vertical-align: 1px;
}

/* ── grid ───────────────────────────────────────────────────── */

.fb-grid {
  display: flex;
  flex-direction: column;
  gap: var(--gap-y);
}

.fb-row {
  display: flex;
  gap: var(--gap-x);
}

/* ── one cell ───────────────────────────────────────────────── */

.fb-cell {
  position: relative;
  width: var(--cell-w);
  height: var(--cell-h);
  border-radius: var(--radius-cell);
  background: var(--flap-bottom);
  overflow: hidden;
  perspective: 260px;
  /* the catchlight on the top edge */
  box-shadow: inset 0 1px 0 var(--hairline);
}

/* every glyph carrier is a full-height box; the halves crop it */
.fb-glyph {
  display: block;
  height: var(--cell-h);
  line-height: var(--cell-h);
  font-size: var(--char-size);
  font-weight: 600;
  text-align: center;
  color: var(--ink);
  white-space: pre;
  user-select: none;
}

.fb-half,
.fb-leaf {
  position: absolute;
  left: 0;
  width: 100%;
  height: 50%;
  overflow: hidden;
  backface-visibility: hidden;
}

.fb-half--top,
.fb-leaf--a {
  top: 0;
  background: var(--flap-top);
}

.fb-half--bottom,
.fb-leaf--b {
  top: 50%;
  background: var(--flap-bottom);
}

/* bottom halves show the lower portion of the same glyph box */
.fb-half--bottom .fb-glyph,
.fb-leaf--b .fb-glyph {
  margin-top: calc(var(--cell-h) / -2);
}

/* the two moving leaves */
.fb-leaf {
  z-index: 2;
  will-change: transform;
}

.fb-leaf--a {
  transform-origin: 50% 100%;
}

.fb-leaf--b {
  transform-origin: 50% 0%;
  transform: rotateX(90deg);
}

/* leaves stay out of the way until a flip is running */
.fb-cell:not(.is-flipping) .fb-leaf {
  visibility: hidden;
}

/* ── seam + hinges, drawn on top of everything ──────────────── */

.fb-seam {
  position: absolute;
  left: 0;
  top: calc(50% - 1px);
  width: 100%;
  height: 2px;
  z-index: 3;
  pointer-events: none;
  /* 1px dark hairline, then 1px light directly beneath it */
  background: linear-gradient(
    to bottom,
    var(--seam) 0 1px,
    color-mix(in srgb, var(--seam-light) 55%, transparent) 1px 2px
  );
}

.fb-hinge {
  position: absolute;
  top: calc(50% - 3.5px);
  width: 2px;
  height: 7px;
  z-index: 4;
  background: var(--hinge);
  pointer-events: none;
}

.fb-hinge--l { left: 0; }
.fb-hinge--r { right: 0; }

/* ── accent chips ───────────────────────────────────────────── */

.fb-cell[data-accent] .fb-half--top,
.fb-cell[data-accent] .fb-half--bottom {
  background: var(--chip);
}

.fb-cell[data-accent] .fb-seam {
  background: linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0.35) 0 1px,
    var(--hairline) 1px 2px
  );
}

/* ── bottom rail ────────────────────────────────────────────── */

.fb-rail {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(24px * var(--chrome-scale));
  font-size: calc(12px * var(--chrome-scale));
  font-weight: 500;
  letter-spacing: 0.1em;
  color: var(--ink-dim);
  text-transform: uppercase;
}

.fb-rail button {
  appearance: none;
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: var(--ink-dim);
  cursor: pointer;
  transition: color 160ms ease;
  display: inline-flex;
  align-items: center;
  gap: calc(7px * var(--chrome-scale));
}

/* the heart in front of "next" — same mark as the plate, same red */
.fb-rail__mark {
  color: var(--accent-red);
  font-size: calc(11px * var(--chrome-scale));
  line-height: 1;
}

/* speaker icon, ported from the About page commits toggle */
.fb-rail__icon {
  width: calc(14px * var(--chrome-scale));
  height: calc(14px * var(--chrome-scale));
  flex: none;
}
.fb-rail__waves {
  opacity: 0;
  transition: opacity 300ms ease;
}
.fb-rail__slash {
  opacity: 1;
  transition: opacity 300ms ease;
}
.fb-rail button.is-on .fb-rail__waves { opacity: 1; }
.fb-rail button.is-on .fb-rail__slash { opacity: 0; }

/* "off" and NBSP+"on" are the same character count, so the mono label
   keeps its width and the rail never reflows on toggle */
.fb-rail__label em {
  font-style: normal;
}

/* "next" is the board's one action, so it gets real button affordance —
   a strokeless pill filled with --rail (the same material as the title
   plate behind "…"), against the sound toggle's plain text. The element
   is in the selector to outrank `.fb-rail button` above. */
.fb-rail button.fb-rail__next {
  position: relative;
  isolation: isolate;
  /* words are the board's black -- at rest AND on hover */
  color: var(--chassis);
  padding: calc(8px * var(--chrome-scale)) calc(15px * var(--chrome-scale));
  border: 0;
  border-radius: 999px;
  background: var(--rail);
  /* the filled gradient IS the resting look now, lightly dimmed; hover lifts
     it to full strength. */
  opacity: 0.86;
  transition: opacity 220ms ease;
}
/* the four accent chips as a gradient fill, sitting behind the label
   (z-index -1: over the rail fill, under the text + heart). always on. */
.fb-rail button.fb-rail__next::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(90deg,
    var(--accent-purple), var(--accent-orchid), var(--accent-magenta), var(--accent-red));
  z-index: -1;
  pointer-events: none;
}
.fb-rail button.fb-rail__next:hover,
.fb-rail button.fb-rail__next:focus-visible {
  opacity: 1;
  /* re-assert black to outrank the global `.fb-rail button:hover` red */
  color: var(--chassis);
}
/* heart is the board's black at rest AND on hover -- red didn't read against
   the bright gradient fill */
.fb-rail button.fb-rail__next .fb-rail__mark {
  color: var(--chassis);
}

.fb-rail button:hover,
.fb-rail button:focus-visible {
  color: var(--accent-red);
}

.fb-rail button[aria-pressed="true"] {
  color: var(--accent-red);
}

.fb-rail__group {
  display: flex;
  align-items: center;
  gap: calc(34px * var(--chrome-scale));
}

/* the plain-text mirror for screen readers */
.fb-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ── nobody should get motion sickness from a fun fact ──────── */

@media (prefers-reduced-motion: reduce) {
  .fb-leaf { display: none; }
}
