/* Reflex Chess -- the blindfold trainer's own stylesheet.
 *
 * Loads on top of seo.css (page chrome, palette, type), board.css (board
 * geometry) and pieces.css (the artwork). It owns exactly three things those
 * files do not: the square stage the board and the tap grid share, the reserved
 * space that stops the page moving, and the controls.
 *
 * THE ONE RULE THIS FILE EXISTS TO ENFORCE: NOTHING MOVES.
 *
 * A visualisation trainer that reflows when the pieces disappear is worse than
 * useless, because the instant the layout jumps is the instant you were holding
 * the position. So:
 *   - the stage is a fixed square (aspect-ratio), and the board and the grid are
 *     both absolutely positioned inside it, so hiding either changes nothing;
 *   - pieces are hidden with `visibility`, never removed and never display:none,
 *     so they occupy the same geometry the whole time;
 *   - the note, the brief, the prompt and the feedback line all have reserved
 *     height, sized for the longest string each of them can hold, because every
 *     one of them changes length between positions.
 * The only deliberate reflow on the page is switching mode, which is a thing
 * the reader asked for and is looking at.
 *
 * The square colours are copied from styles.css rather than imported, for the
 * reason given at the top of seo.css: a content page renders with its own
 * stylesheets and must not inherit the app shell's layout.
 */

/* ---------- the tool block ---------- */

.bf {
  margin: 1.4rem 0 2rem;
  padding: 1rem .9rem 1.1rem;
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
}

.bf-sr {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

.bf-dead {
  padding: 1.2rem; background: var(--card); border: 1px solid var(--rule);
  border-radius: var(--radius); color: var(--dim);
}

/* ---------- mode tabs ---------- */

.bf-modes {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: .35rem;
  padding: .3rem;
  background: var(--bg);
  border-radius: .85rem;
}

.bf-mode {
  font: inherit;
  font-size: .95rem;
  font-weight: 600;
  padding: .55rem .3rem;
  color: var(--dim);
  background: none;
  border: 0;
  border-radius: .6rem;
  cursor: pointer;
}

.bf-mode[aria-pressed="true"] {
  color: #fff;
  background: var(--brand);
  box-shadow: 0 2px 0 var(--brand-dk);
}

/* Three lines reserved. The three notes are different lengths and the tallest
   is three lines at 360px, so the tabs below never shift when you change rung. */
.bf-note {
  min-height: 3.9rem;
  margin: .7rem 0 .8rem;
  font-size: .86rem;
  line-height: 1.45;
  color: var(--dim);
}

/* ---------- piece-count bands ---------- */

.bf-bandlabel {
  margin: 0 0 .3rem;
  font-size: .72rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--dim);
}

.bf-bands {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: .3rem;
}

.bf-band {
  font: inherit;
  display: block;
  padding: .45rem .15rem .4rem;
  text-align: center;
  color: var(--dim);
  background: var(--bg);
  border: 1px solid var(--rule);
  border-radius: .6rem;
  cursor: pointer;
}

.bf-band b { display: block; font-size: .82rem; font-weight: 600; }
.bf-band em { display: block; font-style: normal; font-size: .7rem; line-height: 1.25; margin-top: .1rem; }

.bf-band[aria-pressed="true"] {
  color: var(--ink);
  background: var(--card-2);
  border-color: var(--brand);
}

/* ---------- score line ---------- */

.bf-stats {
  display: flex;
  justify-content: space-between;
  gap: .5rem;
  margin: .85rem 0 .55rem;
  font-size: .82rem;
  color: var(--dim);
  min-height: 1.3rem;
}

.bf-stats b { color: var(--ink); font-weight: 600; }

/* ---------- the brief ----------
   Whatever the current rung needs to say about the position: the sentence in
   Follow, the countdown in Glance, the piece list in Blind, the solution in all
   three once the position is done with.

   Blind gets a FIXED height and its own scrollbar rather than a minimum,
   because a piece list runs from two lines at four pieces to seven at
   twenty-six and every one of those would move the board. */
.bf-brief {
  min-height: 6.2rem;
  padding: .7rem .8rem;
  background: var(--bg);
  border-radius: .8rem;
  font-size: .87rem;
  line-height: 1.5;
}

/* Sized off the band, not off the position. The longest piece list a band can
   produce is fixed by its piece count, so every position inside a band gets the
   same box and the board underneath never moves. Switching band is a deliberate
   act and is allowed to reflow. */
.bf[data-mode="blind"] .bf-brief { min-height: 0; overflow-y: auto; height: 10rem; }
.bf[data-mode="blind"][data-band="b1"] .bf-brief { height: 5.4rem; }
.bf[data-mode="blind"][data-band="b2"] .bf-brief { height: 6.6rem; }
.bf[data-mode="blind"][data-band="b3"] .bf-brief { height: 8rem; }
.bf[data-mode="blind"][data-band="b4"] .bf-brief { height: 9.6rem; }
.bf[data-mode="blind"][data-band="b5"] .bf-brief { height: 11.2rem; }

.bf-brief p { margin: 0 0 .4rem; }
.bf-brief p:last-child { margin-bottom: 0; }
.bf-brieftext { color: var(--dim); }
.bf-brieftext b { color: var(--ink); }

.bf-list { font-family: var(--mono); font-size: .85rem; letter-spacing: .01em; }
.bf-list b { font-family: var(--sans); font-weight: 600; }
.bf-extra { color: var(--dim); font-family: var(--sans); font-size: .8rem; }

.bf-solution .bf-head { font-weight: 600; color: var(--good); }
.bf-line {
  font-family: var(--mono);
  font-size: .95rem;
  overflow-x: auto;
  white-space: nowrap;
}
.bf-line .key { color: var(--good); font-weight: 600; }
.bf-meta { font-size: .78rem; color: var(--dim); }
.bf-tag {
  display: inline-block;
  margin-left: .3rem;
  padding: .05rem .4rem;
  border: 1px solid var(--rule);
  border-radius: 999px;
  font-size: .72rem;
}

/* ---------- the countdown ---------- */

.bf-clock { display: flex; align-items: center; gap: .6rem; }

.bf-secs {
  font-family: var(--mono);
  font-size: 1.5rem;
  font-weight: 600;
  min-width: 1.6rem;
  text-align: center;
}

.bf-track {
  flex: 1 1 auto;
  height: .5rem;
  background: var(--rule);
  border-radius: 999px;
  overflow: hidden;
}

/* Width is written once a second by blindfold.js; the transition only smooths
   between those steps, so the bar is still correct when seo.css strips every
   transition on the page for a reader who has reduced motion on. */
.bf-bar {
  display: block; height: 100%; width: 100%;
  background: var(--brand);
  transition: width 1s linear;
}

/* ---------- prompt ---------- */

.bf-prompt {
  min-height: 3.2rem;
  margin: .8rem 0 .55rem;
  font-size: .95rem;
  line-height: 1.45;
  color: var(--dim);
}
.bf-prompt b { color: var(--ink); font-weight: 600; }

/* ---------- the stage ----------
   One square box. The board sits in it, the tap grid sits on top of it, and
   neither of them can ever change its size. */

.bf-stage {
  position: relative;
  width: 100%;
  max-width: min(24rem, 100%);
  margin: 0 auto;
  aspect-ratio: 1 / 1;
  border-radius: .7rem;
  box-shadow: 0 0 0 4px var(--bg);
}

.bf-stage.wobble { animation: bfWobble .45s ease-in-out; }

@keyframes bfWobble {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-5px); }
  75% { transform: translateX(5px); }
}

.bf-board, .bf-grid { position: absolute; inset: 0; }

/* Geometry and colour for the board component, copied from styles.css. */
.bf-board .cg-wrap { width: 100%; aspect-ratio: 1 / 1; height: auto; }

.bf-board cg-board {
  border-radius: .7rem;
  background-color: var(--sq-light);
  background-image: conic-gradient(
    var(--sq-dark) 0 25%, var(--sq-light) 0 50%,
    var(--sq-dark) 0 75%, var(--sq-light) 0);
  background-size: 25% 25%;
  background-position: 0 0;
  background-repeat: repeat;
}

.bf-board cg-board square.last-move { background-color: rgba(155, 199, 0, .41); }
.bf-board cg-board square.check {
  background: radial-gradient(ellipse at center, rgba(255, 0, 0, 1) 0%, rgba(231, 0, 0, 1) 25%,
    rgba(169, 0, 0, 0) 89%, rgba(158, 0, 0, 0) 100%);
}

/* THE HIDE. visibility, not display and not removal: the elements keep their
   boxes, the board keeps its checker pattern, and showing them again is one
   attribute rather than a re-render. The highlights go too, because the
   last-move square is a very large hint about where to look. */
.bf[data-show="off"] .bf-board piece,
.bf[data-show="off"] .bf-board square { visibility: hidden; }

/* ---------- the tap grid ---------- */

.bf-grid {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  grid-template-rows: repeat(8, 1fr);
  border-radius: .7rem;
  overflow: hidden;
}

.bf-cell {
  position: relative;
  padding: 0;
  font: inherit;
  background: none;
  border: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* Edge labels, inside the square, so they survive the pieces being hidden and
   still read over a piece when they are not. White with a shadow is the same
   trick styles.css uses on the app's coordinates, and it is legible on both
   square colours. */
.bf-cell i {
  position: absolute;
  font-style: normal;
  font-family: var(--mono);
  font-size: clamp(.52rem, 2vw, .7rem);
  font-weight: 700;
  pointer-events: none;
}
.bf-cell.dk i { color: rgb(255 255 255 / .92); }
.bf-cell.lt i { color: rgb(20 22 31 / .6); }
/* Both on the left. The file letter was on the right and the h-file one was
   being clipped by the board's own rounded corner. */
.bf-cell .bf-r { top: 4%; left: 7%; }
.bf-cell .bf-f { bottom: 3%; left: 7%; }

.bf-cell.from { box-shadow: inset 0 0 0 3px var(--brand); border-radius: 3px; }
.bf-cell.to { box-shadow: inset 0 0 0 3px var(--good); border-radius: 3px; }

.bf[data-phase="look"] .bf-grid,
.bf[data-phase="done"] .bf-grid { pointer-events: none; }

/* ---------- the answer bar ---------- */

.bf-answerbar {
  display: flex;
  align-items: center;
  gap: .6rem;
  margin: .7rem 0 .1rem;
  min-height: 2.4rem;
}

.bf-picked {
  font-family: var(--mono);
  font-size: .95rem;
  font-weight: 600;
  min-width: 6.4rem;
}

.bf-typed { flex: 1 1 auto; }

.bf-typed input {
  width: 100%;
  font: inherit;
  font-size: .9rem;
  padding: .5rem .65rem;
  color: var(--ink);
  background: var(--bg);
  border: 1px solid var(--rule);
  border-radius: .6rem;
}

.bf-typed input:focus { outline: 2px solid var(--brand); outline-offset: 1px; }

.bf[data-phase="look"] .bf-answerbar,
.bf[data-phase="done"] .bf-answerbar { opacity: .45; pointer-events: none; }

/* ---------- feedback ---------- */

.bf-feedback {
  min-height: 2.7rem;
  margin: 0 0 .7rem;
  font-size: .88rem;
  line-height: 1.4;
  color: var(--dim);
}
.bf-feedback.bad { color: var(--bad); }
.bf-feedback.warn { color: var(--ink); }
.bf-feedback b { font-weight: 600; }

/* ---------- actions ---------- */

.bf-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: .5rem;
}

.bf-btn {
  font: inherit;
  font-size: .88rem;
  font-weight: 600;
  padding: .68rem .4rem;
  color: #fff;
  background: var(--brand);
  border: 0;
  border-radius: .7rem;
  box-shadow: 0 3px 0 var(--brand-dk);
  cursor: pointer;
}

.bf-btn:active { transform: translateY(2px); box-shadow: 0 1px 0 var(--brand-dk); }

.bf-btn.ghost {
  color: var(--dim);
  background: var(--bg);
  box-shadow: inset 0 0 0 1px var(--rule);
}

.bf-btn.tiny {
  font-size: .78rem;
  padding: .35rem .6rem;
  box-shadow: 0 2px 0 var(--brand-dk);
}

#bfNext { grid-column: 1 / -1; }

.bf[data-phase="done"] .bf-btn.ghost,
.bf[data-phase="look"] #bfShowBoard { opacity: .4; pointer-events: none; }

/* ---------- the book note ----------
   Deliberately quiet, deliberately below the trainer. */

.bf-books {
  margin: 2.2rem 0 1.4rem;
  padding: 1rem 1.05rem;
  background: var(--card);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--sec, var(--brand));
  border-radius: .8rem;
  font-size: .93rem;
}

.bf-books p { margin: 0 0 .6rem; }
.bf-books p:last-child { margin-bottom: 0; }
.bf-books h2 { font-size: 1.02rem; margin: 0 0 .5rem; }

@media (min-width: 34rem) {
  .bf { padding: 1.3rem 1.3rem 1.4rem; }
  .bf-note { min-height: 2.6rem; }
  .bf-brief { min-height: 5.4rem; }
  .bf-prompt { min-height: 2.6rem; }
  /* Wider lines mean fewer of them, so the reserved boxes shrink. Written at
     the same specificity as the mobile band rules or they would not win. */
  .bf[data-mode="blind"][data-band="b1"] .bf-brief { height: 4.6rem; }
  .bf[data-mode="blind"][data-band="b2"] .bf-brief { height: 5.4rem; }
  .bf[data-mode="blind"][data-band="b3"] .bf-brief { height: 6.2rem; }
  .bf[data-mode="blind"][data-band="b4"] .bf-brief { height: 7rem; }
  .bf[data-mode="blind"][data-band="b5"] .bf-brief { height: 7.8rem; }
}

@media (prefers-reduced-motion: reduce) {
  .bf-stage.wobble { animation: none; }
}
