/* Threads board. Inherits the existing theme tokens (--text, --muted, --line, --accent,
   --action-text, --canvas); it introduces no colour of its own. */
.threads { display: grid; justify-items: center; gap: 1.25rem; width: 100%; color: inherit; }
/* Cells never shrink below a full-size target: a wider board scrolls inside this frame
   instead, so the page itself never scrolls sideways. */
.threads-frame { width: 100%; max-width: 100%; overflow-x: auto; overscroll-behavior-x: contain; }
/* One square track per column, each holding the 44px floor on both axes. The renderer sets
   --columns and --rows for the board in hand. */
.threads-layout { display: grid; grid-template-columns: repeat(var(--columns, 5), minmax(44px, 1fr)); grid-template-rows: repeat(var(--rows, 5), minmax(44px, auto)); width: min(100%, calc(var(--columns, 5) * 3.4rem)); margin-inline: auto; border: 2px solid currentColor; background: color-mix(in srgb, currentColor 3%, transparent); touch-action: none; }
.threads-cell { --thread: .3rem; --reach: 0rem; position: relative; box-sizing: border-box; width: 100%; min-width: 0; aspect-ratio: 1; min-height: 44px; display: grid; place-items: center; margin: 0; padding: 0; font: inherit; font-size: clamp(1rem, 4vw, 1.4rem); font-variant-numeric: tabular-nums; line-height: 1; color: inherit; background: transparent; border: 0; border-right: 1px solid color-mix(in srgb, var(--line, currentColor) 70%, transparent); border-bottom: 1px solid color-mix(in srgb, var(--line, currentColor) 70%, transparent); cursor: pointer; -webkit-user-select: none; user-select: none; }
.threads-cell.is-last-column { border-right: 0; }
.threads-cell.is-last-row { border-bottom: 0; }
.threads-cell.is-endpoint { --reach: .95em; }
/* Each arm is anchored on its own outer edge and reaches in to the centre, so two arms in a
   cell read as one unbroken corner and a numbered cell's thread stops at the number. */
.threads-arm { position: absolute; background: var(--accent, currentColor); border-radius: 1px; opacity: 0; }
.threads-arm.is-up { top: 0; left: 50%; width: var(--thread); height: calc(50% - var(--reach)); transform: translateX(-50%); }
.threads-arm.is-down { bottom: 0; left: 50%; width: var(--thread); height: calc(50% - var(--reach)); transform: translateX(-50%); }
.threads-arm.is-left { left: 0; top: 50%; height: var(--thread); width: calc(50% - var(--reach)); transform: translateY(-50%); }
.threads-arm.is-right { right: 0; top: 50%; height: var(--thread); width: calc(50% - var(--reach)); transform: translateY(-50%); }
.threads-arm.is-on { opacity: 1; }
/* A small cap where a thread ends, so a single link never looks like a stray tick. */
.threads-node { position: absolute; width: var(--thread); height: var(--thread); border-radius: 50%; background: var(--accent, currentColor); opacity: 0; }
.threads-cell.is-used:not(.is-endpoint) .threads-node { opacity: 1; }
.threads-mark { position: relative; display: none; }
.threads-cell.is-endpoint .threads-mark { display: grid; place-items: center; width: 1.9em; height: 1.9em; border: 2px solid currentColor; border-radius: 50%; background: color-mix(in srgb, currentColor 10%, transparent); font-weight: 650; }
/* A pair that already reads as joined marks its own two ends and nothing else. */
.threads-cell.is-joined .threads-mark { border-color: var(--accent, currentColor); }
.threads[data-state="playing"] .threads-cell:hover { background: color-mix(in srgb, currentColor 7%, transparent); }
.threads-cell[aria-current="true"] { box-shadow: inset 0 0 0 3px var(--accent, currentColor); }
.threads-cell:focus-visible { outline: 3px solid currentColor; outline-offset: -5px; }
.threads-tally { display: flex; flex-wrap: wrap; justify-content: center; gap: .4rem 1.75rem; margin: 0; font-size: .875rem; }
.threads-metric { display: inline-flex; align-items: baseline; gap: .5rem; }
.threads-metric[hidden] { display: none; }
.threads-label { color: var(--muted, currentColor); }
.threads-value { font-size: 1.1rem; font-variant-numeric: tabular-nums; }
.threads-pad { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: .5rem; width: min(100%, 24rem); }
.threads-key { min-height: 48px; min-width: 0; width: 100%; padding: .5rem .35rem; font: inherit; color: inherit; background: transparent; border: 1px solid currentColor; border-radius: 3px; cursor: pointer; }
.threads-key:hover:not(:disabled) { background: color-mix(in srgb, currentColor 8%, transparent); }
.threads-key:disabled { opacity: .55; cursor: default; }
.threads-key:focus-visible { outline: 3px solid currentColor; outline-offset: 4px; }
.threads-hint { max-width: 34rem; margin: 0; font-size: .875rem; line-height: 1.5; text-align: center; color: var(--muted, currentColor); }
.threads[data-state="solved"] .threads-layout { border-color: var(--accent, currentColor); }
.threads[data-state="blocked"] .threads-cell, .threads[data-state="waiting"] .threads-cell { cursor: default; }
@media (prefers-reduced-motion: no-preference) {
  .threads-arm, .threads-node { transition: opacity .16s ease; }
  .threads-mark { transition: border-color .18s ease; }
}
@media (max-width: 380px) {
  .threads { gap: 1rem; }
  .threads-layout { width: 100%; max-width: 100%; }
  .threads-pad { width: 100%; max-width: 100%; }
  .threads-key { padding: .5rem .1rem; font-size: .875rem; }
  .threads-tally { gap: .3rem 1.1rem; }
}
@media (forced-colors: active) {
  .threads-layout, .threads-cell { border-color: CanvasText; }
  .threads-arm, .threads-node { background: Highlight; }
  .threads-cell .threads-mark { border-color: CanvasText; background: Canvas; }
  .threads-cell.is-joined .threads-mark { border-color: Highlight; }
  .threads-cell[aria-current="true"] { outline: 3px solid Highlight; outline-offset: -3px; }
}
