/* ===========================================================================
   CIRCLE — the harmonic glyph, and the cipher table.
   ---------------------------------------------------------------------------
   Four rings showing at once needs a hierarchy, or it is a wall. The keys are
   the brightest and largest; the degrees are lighter; the chords lighter
   still; the letters are the quietest thing on the figure. Read it from the
   outside in and it goes from "where am I" to "what is here" to "what does my
   word do here", which is the order somebody actually asks those questions.

   The word layer is the only thing allowed to be bright. Everything the rings
   do is reference; the path is the answer.

   Every state has a shape as well as a colour — the tonic has a heavier edge,
   a place outside the scale has no fill, a played node has a ring around it.
   Turn the colour off and the map still reads.
   =========================================================================== */

.circle-intro { border-top: 0; margin-bottom: 4px; }
.circle-intro .fold-body { padding-bottom: 10px; }

.circle-input {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0 clamp(12px, 2vw, 22px);
}
.circle-input .field-wide { flex: 1 1 260px; }
.circle-input #cr-word {
  font-family: var(--f-mono);
  font-size: clamp(15px, 2.4vw, 19px);
  letter-spacing: .08em;
  text-transform: uppercase;
}
.circle-input .act { margin-bottom: 12px; }

.circle-controls { align-items: center; gap: 10px clamp(14px, 2.6vw, 26px); }
.circle-controls .sys { margin-left: auto; }
.circle-controls .act { margin-bottom: 0; }
.circle-controls .act[aria-pressed="true"] { color: var(--green); border-color: var(--green-2); }

.circle-layers { display: flex; flex-wrap: wrap; gap: 4px 16px; }
.circle-layers .check { margin-bottom: 0; }

/* Two columns where there is room, one where there is not. The glyph keeps its
   own square and the rail takes what is left, so the map never squashes into
   an ellipse to make space for text. */
.circle-layout {
  display: grid;
  grid-template-columns: minmax(300px, 1.05fr) minmax(280px, 1fr);
  gap: clamp(18px, 3vw, 40px);
  align-items: start;
  margin-top: 6px;
}

.circle-stage { position: sticky; top: 12px; }
.circle-ring { max-width: 560px; margin: 0 auto; }

.circle-readout {
  margin: 8px auto 0;
  max-width: 560px;
  min-height: 2.6em;
  font-family: var(--f-mono);
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--fg-3);
}

/* --------------------------------------------------------------- legend */

.circle-legend {
  list-style: none;
  margin: 4px auto 0;
  padding: 0;
  max-width: 560px;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
  font-family: var(--f-sans);
  font-size: 9.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--fg-3);
}
.circle-legend li { display: flex; align-items: center; gap: 6px; }
.lg { width: 10px; height: 10px; flex: none; }
.lg-key    { border: 1px solid var(--fg-2); }
.lg-degree { border: 1px solid var(--green-dim); transform: rotate(45deg); width: 8px; height: 8px; }
.lg-chord  { border: 1px solid var(--flat); border-radius: 2px; }
.lg-letter { border-bottom: 1px solid var(--fg-3); height: 5px; }
.lg-node   { background: var(--green); border-radius: 50%; }
.lg-join   { border-top: 1px dashed var(--fg-3); height: 0; width: 14px; }

/* ------------------------------------------------------------- the rings */

.circle-svg { display: block; width: 100%; height: auto; overflow: visible; }
.circle-spoke { stroke: var(--line-hair); stroke-width: 1; }

.circle-cell { cursor: pointer; }
.circle-cell .circle-face {
  fill: var(--bg-1);
  stroke: var(--line-hair);
  stroke-width: 1;
  transition: fill .16s var(--ease), stroke .16s var(--ease);
}
.circle-cell:hover .circle-face { fill: var(--bg-2); stroke: var(--line-soft); }

/* Depth by ring: the keys sit forward, the letters sit back. */
.circle-degrees .circle-face { fill: var(--bg); }
.circle-chords  .circle-face { fill: var(--bg-1); }
.circle-letters .circle-face { fill: var(--bg); }

/* A place the current scale does not contain. No fill at all — the scale is
   the thing being read, and a pitch outside it is genuinely absent. */
.circle-cell.is-outside .circle-face { fill: transparent; stroke: var(--line-hair); }
.circle-cell.is-outside .circle-key-label { fill: var(--fg-3); }
.circle-cell.is-outside .circle-key-rel { fill: var(--fg-3); opacity: .5; }

/* The tonic: a lighter face and a bright edge, on every ring, so the spoke
   reads as one column rather than four coincidences. */
.circle-cell.is-tonic .circle-face {
  fill: rgba(86, 217, 138, .14);
  stroke: var(--green);
  stroke-width: 1.5;
}
.circle-keys.is-tonic .circle-face { fill: rgba(86, 217, 138, .2); }

/* One fifth either side — a single accidental away. Dashed, because "nearly
   the same key" is a different claim from "the same key". */
.circle-keys.is-neighbour .circle-face {
  stroke: var(--green-dim);
  stroke-dasharray: 4 3;
}

.circle-cell.is-selected .circle-face {
  stroke: var(--flat);
  stroke-width: 1.8;
  fill: rgba(111, 184, 216, .14);
}

.circle-cell.is-sounding .circle-face {
  stroke: var(--accent-hot);
  stroke-width: 2.4;
}

/* --- labels, brightest outside to quietest inside --------------------- */

.circle-key-label {
  fill: var(--fg);
  font-family: var(--f-mono);
  font-size: 17px;
  font-weight: 500;
  pointer-events: none;
}
.circle-key-rel {
  fill: var(--fg-3);
  font-family: var(--f-mono);
  font-size: 10px;
  pointer-events: none;
}
.circle-cell.is-tonic .circle-key-label { fill: var(--green); }

.circle-degrees-label {
  fill: var(--green-2);
  font-family: var(--f-mono);
  font-size: 13px;
  pointer-events: none;
}
.circle-cell.is-tonic .circle-degrees-label { fill: var(--accent-hot); }

.circle-chords-label {
  fill: var(--flat);
  font-family: var(--f-mono);
  font-size: 12.5px;
  pointer-events: none;
}

.circle-letters-label {
  fill: var(--fg-3);
  font-family: var(--f-mono);
  font-size: 10.5px;
  letter-spacing: .06em;
  pointer-events: none;
}

.circle-cell:focus { outline: none; }
.circle-cell:focus-visible .circle-face {
  stroke: var(--accent-hot);
  stroke-width: 2.6;
  stroke-dasharray: none;
}

/* ------------------------------------------------------------- the word */

.circle-field { pointer-events: auto; }

.circle-step {
  fill: none;
  stroke: var(--green);
  stroke-width: 1.6;
  stroke-linecap: round;
  opacity: .78;
}

/* A boundary crossed, not a step taken — so it is drawn as a different kind
   of line rather than a fainter version of the same one. */
.circle-join {
  fill: none;
  stroke: var(--fg-3);
  stroke-width: 1.1;
  stroke-dasharray: 3 5;
  opacity: .6;
}

.circle-word { cursor: pointer; }
.circle-word.is-muted { opacity: .26; }
.circle-word.is-active .circle-step { stroke: var(--accent-hot); stroke-width: 2.1; opacity: 1; }

.circle-node-hit { fill: transparent; }
.circle-node-dot {
  fill: var(--bg);
  stroke: var(--green);
  stroke-width: 1.7;
  transition: fill .14s var(--ease), stroke .14s var(--ease);
}
.circle-node-letter {
  fill: var(--fg);
  font-family: var(--f-mono);
  font-size: 10px;
  font-weight: 600;
  pointer-events: none;
}
.circle-node:hover .circle-node-dot { fill: rgba(86, 217, 138, .3); }
.circle-node.is-selected .circle-node-dot { fill: var(--green); stroke: var(--accent-hot); }
.circle-node.is-selected .circle-node-letter { fill: var(--bg); }
.circle-node.is-playing .circle-node-dot {
  fill: var(--accent-hot);
  stroke: var(--accent-hot);
  stroke-width: 3;
}
.circle-node.is-playing .circle-node-letter { fill: var(--bg); }
.circle-node:focus-visible .circle-node-dot { stroke: var(--accent-hot); stroke-width: 3; }

/* --------------------------------------------------------------- the hub */

.circle-hub { fill: var(--bg); stroke: var(--line-hair); }

.circle-hub-word {
  fill: var(--fg);
  font-family: var(--f-mono);
  font-size: 21px;
  font-weight: 500;
  letter-spacing: .06em;
}
.circle-hub-key { fill: var(--fg); font-family: var(--f-mono); font-size: 30px; }
.circle-hub-key-small { fill: var(--green); font-family: var(--f-mono); font-size: 16px; }
.circle-hub-cipher {
  fill: var(--fg-3);
  font-family: var(--f-sans);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
}
.circle-hub-sig { fill: var(--green-2); font-family: var(--f-mono); font-size: 12px; }

/* -------------------------------------------------------------- the rail */

.circle-rail .block { margin-bottom: clamp(16px, 2.4vw, 26px); }

.circle-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.circle-head .check { margin-bottom: 0; }

.circle-key { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 14px; }
.circle-key-name {
  font-family: var(--f-mono);
  font-size: clamp(18px, 2.6vw, 23px);
  color: var(--fg);
}
.circle-key-sig { font-family: var(--f-mono); font-size: 12px; color: var(--green-2); }

.circle-scale { display: flex; flex-wrap: wrap; gap: 2px 16px; margin: 8px 0 0; }
.circle-scale-notes { font-family: var(--f-mono); font-size: 14px; color: var(--fg); }
.circle-scale-mark { font-family: var(--f-mono); font-size: 12px; color: var(--green-2); }

.circle-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 2px 18px;
  margin-top: 12px;
}
.circle-fact { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.circle-fact-role {
  font-family: var(--f-sans);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--fg-3);
}
.circle-fact-go {
  background: none;
  border: 0;
  border-bottom: 1px solid transparent;
  padding: 3px 0;
  font-family: var(--f-mono);
  font-size: 13px;
  color: var(--fg-2);
  cursor: pointer;
  transition: color .14s var(--ease), border-color .14s var(--ease);
}
.circle-fact-go:hover { color: var(--green); border-bottom-color: var(--green-2); }

/* ---------------------------------------------------------------- words */

.circle-words { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.circle-word-chip {
  background: var(--bg-1);
  border: 1px solid var(--line-soft);
  padding: 7px 11px;
  min-height: 34px;
  font-family: var(--f-mono);
  font-size: 12.5px;
  letter-spacing: .06em;
  color: var(--fg-2);
  cursor: pointer;
  transition: border-color .14s var(--ease), color .14s var(--ease);
}
.circle-word-chip:hover { border-color: var(--line); color: var(--fg); }
.circle-word-chip.is-on { border-color: var(--green); color: var(--green); }
.circle-overview-note {
  font-family: var(--f-sans);
  font-size: 11.5px;
  color: var(--fg-3);
  flex-basis: 100%;
}

/* --------------------------------------------------------------- chords */

.circle-chords { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }

.circle-chord {
  display: grid;
  gap: 1px;
  min-width: 62px;
  min-height: 44px;                      /* a real touch target */
  padding: 5px 9px;
  background: var(--bg-1);
  border: 1px solid var(--line-soft);
  cursor: pointer;
  transition: border-color .14s var(--ease), background .14s var(--ease);
}
.circle-chord:hover { border-color: var(--green-2); background: var(--bg-2); }
.circle-chord.is-on { border-color: var(--green); background: rgba(86, 217, 138, .1); }
/* A stack the vocabulary has no name for. Marked, not hidden. */
.circle-chord.is-unnamed { border-style: dashed; }
.circle-chord.is-unnamed .circle-chord-sym { font-size: 11.5px; color: var(--fg-2); }

.circle-chord-num {
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: .06em;
  color: var(--green-2);
}
.circle-chord-sym { font-family: var(--f-mono); font-size: 13.5px; color: var(--fg); }

/* ---------------------------------------------------------- what is picked */

.circle-detail { min-height: 60px; margin-bottom: 12px; }

.circle-detail-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 14px; }
.circle-detail-symbol { font-family: var(--f-mono); font-size: 22px; color: var(--fg); }
.circle-detail-numeral { font-family: var(--f-mono); font-size: 13px; color: var(--green); }
.circle-detail-key { font-family: var(--f-mono); font-size: 12px; color: var(--fg-3); }

/* The chain the whole feature exists to show: letter to value to note to
   chord, in that order, with the arrows implied by the layout. */
.circle-chain { display: flex; flex-wrap: wrap; gap: 6px 0; margin: 12px 0 0; }
.circle-chain-step {
  display: grid;
  gap: 2px;
  padding: 0 14px 0 0;
  margin-right: 14px;
  border-right: 1px solid var(--line-hair);
}
.circle-chain-step:last-child { border-right: 0; margin-right: 0; }
.circle-chain-label {
  font-family: var(--f-sans);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--fg-3);
}
.circle-chain-value { font-family: var(--f-mono); font-size: 14px; color: var(--fg); }

.circle-move {
  margin: 8px 0 0;
  font-family: var(--f-mono);
  font-size: 12px;
  color: var(--green-2);
}

.circle-detail-role {
  margin: 8px 0 0;
  font-family: var(--f-sans);
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--fg-2);
}
.circle-detail-notes { margin: 8px 0 0; font-family: var(--f-mono); font-size: 13px; color: var(--fg); }
.circle-detail-label {
  display: inline-block;
  margin-right: 10px;
  font-family: var(--f-sans);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--fg-3);
}

/* ------------------------------------------------------------ instruments */

.circle-instruments {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  gap: clamp(16px, 3vw, 34px);
  align-items: start;
  margin-top: 14px;
}
.circle-piano { overflow-x: auto; }
.circle-guitar { max-width: 190px; }

/* ===========================================================================
   CIPHER SHEET
   ---------------------------------------------------------------------------
   A reference sheet, not a table. One question — what does each letter equal —
   answered twenty-six times in as little space as it takes, so the whole
   cipher is on screen at once with nothing to scroll.

   The columns fill to whatever width is available rather than being counted
   out at breakpoints: eleven across a desktop, three on a phone, and the same
   markup either way.
   =========================================================================== */

.cgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(94px, 1fr));
  gap: 1px clamp(8px, 1.4vw, 18px);
  margin-top: 8px;
}

.cg-cell {
  display: grid;
  grid-template-columns: 1.6ch .9ch auto;
  align-items: baseline;
  gap: 0 4px;
  padding: 4px 6px 4px 0;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--line-hair);
  font-family: var(--f-mono);
  font-size: 13px;
  text-align: left;
  color: var(--fg-2);
  cursor: pointer;
  transition: color .12s var(--ease), border-color .12s var(--ease);
}
.cg-cell:hover { color: var(--fg); border-bottom-color: var(--line-soft); }
.cg-cell:focus-visible { outline: 1px solid var(--green-2); outline-offset: 1px; }

.cg-letter { color: var(--fg); }
.cg-eq { color: var(--fg-3); }
.cg-value { color: var(--fg-2); }

/* A letter the sentence uses. A state on the cell, not a column — the sheet
   answers one question and this is a mark on the answer, not a second one. */
.cg-cell.is-used { border-bottom-color: var(--green-dim); }
.cg-cell.is-used .cg-letter,
.cg-cell.is-used .cg-value { color: var(--green); }

.cg-cell.is-selected { border-bottom-color: var(--green); }
.cg-cell.is-selected .cg-letter { color: var(--accent-hot); }

/* ------------------------------------------------------------ narrow view */

@media (max-width: 900px) {
  .circle-layout { grid-template-columns: 1fr; }
  .circle-stage { position: static; }
  .circle-instruments { grid-template-columns: 1fr; }
}

@media (max-width: 620px) {
  /* Narrower cells rather than fewer of them: three columns of `A = ♭2` still
     fit a phone, and the whole cipher still fits one screen. */
  .cgrid { grid-template-columns: repeat(auto-fill, minmax(80px, 1fr)); gap: 1px 10px; }
  .cg-cell { font-size: 12.5px; padding: 5px 4px 5px 0; }
}

@media (max-width: 700px) {
  /* On a phone the controls between the input and the map are the thing
     standing in the way of it, so they take one row instead of three. */
  .circle-input { gap: 0 12px; }
  .circle-input .field { margin-bottom: 8px; }
  .circle-controls { gap: 6px 14px; padding-bottom: 4px; }
  .circle-layers { gap: 2px 12px; }
  .circle-layers .check { font-size: 11px; }
  .circle-controls .act { padding: 6px 10px; }
  .circle-legend { font-size: 9px; gap: 3px 12px; }
}

@media (max-width: 560px) {
  /* The hub already prints the key and the cipher, and the bar at the top of
     the page prints both again. On a phone that line is pure duplication
     standing between the reader and the map. */
  .circle-controls .sys { display: none; }
  .circle-key-label { font-size: 18px; }
  .circle-degrees-label { font-size: 14px; }
  .circle-chords-label { font-size: 13px; }
  .circle-letters-label { font-size: 11px; }
  .circle-node-letter { font-size: 11px; }
  .circle-facts { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  .circle-cell .circle-face,
  .circle-node-dot,
  .circle-chord,
  .cg-cell { transition: none; }
}
