/* Gamma Migration page. Dark shell to match the option chain and Risk Reversal. */
:root {
    --gm-bg: #0e1116;
    --gm-panel: #161b22;
    --gm-panel2: #1c232c;
    --gm-line: #2a323d;
    --gm-tx: #e6edf3;
    --gm-dim: #8b949e;
    --gm-dim2: #6e7681;
    --gm-pos: #3fb950;
    --gm-neg: #f85149;
    --gm-peak: #d29922;
    --gm-accent: #58a6ff;
    --gm-hot: #60d6ff;
}

body {
    margin: 0;
    background: var(--gm-bg);
    color: var(--gm-tx);
    font: 13px/1.55 ui-sans-serif, -apple-system, "Segoe UI", Roboto, sans-serif;
}

.gm-page { max-width: 1180px; margin: 0 auto; padding: 22px 18px 60px; }
.gm-head h1 { font-size: 20px; margin: 0 0 2px; font-weight: 650; }
.gm-sub { color: var(--gm-dim); font-size: 12px; margin-bottom: 16px; }
.gm-asof { color: var(--gm-dim2); }

.gm-error {
    background: rgba(248, 81, 73, 0.12);
    border: 1px solid var(--gm-neg);
    border-radius: 8px; padding: 10px 14px; margin-bottom: 14px; color: var(--gm-neg);
}

.gm-empty { color: var(--gm-dim2); font-size: 12px; }
.gm-empty.gm-big { padding: 40px 0; font-size: 14px; text-align: center; }

/* --- regime banner ------------------------------------------------------------------------- */
.gm-regime {
    background: var(--gm-panel); border: 1px solid var(--gm-line); border-left-width: 4px;
    border-radius: 8px; padding: 12px 16px; margin-bottom: 14px;
}
.gm-regime-name { font-size: 18px; font-weight: 700; letter-spacing: .2px; }
.gm-regime-reason { color: var(--gm-dim); font-size: 12px; margin-top: 2px; }
.gm-regime.tone-up { border-left-color: var(--gm-pos); }
.gm-regime.tone-up .gm-regime-name { color: var(--gm-pos); }
.gm-regime.tone-down { border-left-color: var(--gm-neg); }
.gm-regime.tone-down .gm-regime-name { color: var(--gm-neg); }
.gm-regime.tone-parked { border-left-color: var(--gm-peak); }
.gm-regime.tone-parked .gm-regime-name { color: var(--gm-peak); }
.gm-regime.tone-unstable { border-left-color: var(--gm-dim); }
.gm-regime.tone-unknown { border-left-color: var(--gm-dim2); }
.gm-regime.tone-unknown .gm-regime-name { color: var(--gm-dim); }

/* --- stat row ------------------------------------------------------------------------------ */
.gm-stats {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(155px, 1fr));
    gap: 10px; margin-bottom: 14px;
}
.gm-stat { background: var(--gm-panel); border: 1px solid var(--gm-line); border-radius: 8px; padding: 9px 12px; }
.gm-stat-label { font-size: 10px; letter-spacing: .5px; text-transform: uppercase; color: var(--gm-dim2); }
.gm-stat-value { font-size: 19px; font-weight: 650; font-variant-numeric: tabular-nums; margin-top: 1px; }
.gm-stat-note { font-size: 10px; color: var(--gm-dim2); margin-top: 1px; }
/* Dwell tone: a level with three hours behind it and one that moved a minute ago must not read
   the same. That distinction is the reason this service exists. */
.gm-stat.tone-strong .gm-stat-value { color: var(--gm-peak); }
.gm-stat.tone-medium .gm-stat-value { color: var(--gm-tx); }
.gm-stat.tone-weak .gm-stat-value { color: var(--gm-accent); }
.gm-stat.tone-fresh .gm-stat-value { color: var(--gm-neg); }

/* --- cards --------------------------------------------------------------------------------- */
.gm-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(330px, 1fr)); gap: 12px; }
.gm-card { background: var(--gm-panel); border: 1px solid var(--gm-line); border-radius: 8px; padding: 12px 14px; }
.gm-card h2 {
    font-size: 11px; letter-spacing: .7px; text-transform: uppercase; color: var(--gm-dim);
    margin: 0 0 10px; font-weight: 650;
}
.gm-foot { font-size: 10px; color: var(--gm-dim2); margin: 10px 0 0; }
.gm-warn {
    font-size: 10px; color: var(--gm-peak); margin: 8px 0 0;
    border-left: 2px solid var(--gm-peak); padding-left: 8px;
}

/* --- mass balance -------------------------------------------------------------------------- */
.gm-bal-head { display: flex; justify-content: space-between; font-size: 10px; color: var(--gm-dim2); }
.gm-skew { font-variant-numeric: tabular-nums; color: var(--gm-tx); font-weight: 650; }
.gm-balbar {
    display: flex; height: 24px; border-radius: 4px; overflow: hidden; margin-top: 8px;
    background: var(--gm-line); font-size: 10px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.gm-bal-below, .gm-bal-above { display: flex; align-items: center; color: #fff; min-width: 0; overflow: hidden; }
.gm-bal-below { background: var(--gm-neg); justify-content: flex-start; padding-left: 7px; }
.gm-bal-above { background: var(--gm-pos); justify-content: flex-end; padding-right: 7px; }
.gm-bal-ends, .gm-signed {
    display: flex; justify-content: space-between; font-size: 10px; color: var(--gm-dim2); margin-top: 4px;
}
.gm-signed { color: var(--gm-dim); }

/* --- rotation ------------------------------------------------------------------------------ */
.gm-rates { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.gm-rate { background: var(--gm-panel2); border: 1px solid var(--gm-line); border-radius: 6px; padding: 8px; }
.gm-rate-win { font-size: 10px; color: var(--gm-dim2); text-transform: uppercase; letter-spacing: .5px; }
.gm-rate-val { font-size: 14px; font-weight: 650; font-variant-numeric: tabular-nums; margin-top: 1px; }
.gm-rate-note { font-size: 9px; color: var(--gm-dim2); margin-top: 2px; }
.gm-rate.fires { border-color: var(--gm-accent); }
.gm-rate.fires .gm-rate-val { color: var(--gm-accent); }
/* NOT MEASURED must not look like a calm market. It is struck through so a missing anchor cannot
   be misread as a flat reading — the two are different answers. */
.gm-rate.unmeasured .gm-rate-val { color: var(--gm-dim2); font-style: italic; font-size: 12px; }
.gm-rate.unmeasured { border-style: dashed; }

/* --- per-strike ---------------------------------------------------------------------------- */
.gm-hot { border-radius: 6px; padding: 9px 11px; background: var(--gm-panel2); border: 1px solid var(--gm-line); }
.gm-hot.trusted { border-color: var(--gm-hot); }
.gm-hot-head { display: flex; align-items: baseline; gap: 8px; }
.gm-hot-chip {
    font-size: 9px; font-weight: 700; letter-spacing: .4px; padding: 1px 5px; border-radius: 3px;
    background: var(--gm-dim2); color: #fff;
}
.gm-hot.trusted .gm-hot-chip { background: var(--gm-hot); color: #06202b; animation: gmHotPulse 1.8s ease-in-out infinite; }
.gm-hot-strike { font-size: 20px; font-weight: 700; font-variant-numeric: tabular-nums; }
.gm-hot-gain { font-size: 12px; color: var(--gm-tx); margin-top: 2px; font-variant-numeric: tabular-nums; }
.gm-hot-why { font-size: 10px; color: var(--gm-dim2); margin-top: 3px; }

@keyframes gmHotPulse { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
    .gm-hot.trusted .gm-hot-chip { animation: none; opacity: 1; }
}

.gm-flip { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--gm-line); }
.gm-flip-label { font-size: 10px; letter-spacing: .5px; text-transform: uppercase; color: var(--gm-dim2); }
.gm-flip-strike { font-size: 17px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--gm-peak); }
.gm-flip-vals { font-size: 12px; font-variant-numeric: tabular-nums; color: var(--gm-dim); }
.gm-flip-why { font-size: 10px; color: var(--gm-dim2); margin-top: 2px; }

/* --- coverage ------------------------------------------------------------------------------ */
.gm-cov-row {
    display: flex; justify-content: space-between; font-size: 11px; padding: 3px 0;
    border-bottom: 1px solid var(--gm-line);
}
.gm-cov-row:last-of-type { border-bottom: none; }
.gm-cov-row span { color: var(--gm-dim); }
.gm-cov-row b { font-variant-numeric: tabular-nums; }
.gm-cov-row b.bad { color: var(--gm-peak); }

.gm-page-foot {
    margin-top: 20px; padding-top: 14px; border-top: 1px solid var(--gm-line);
    font-size: 11px; color: var(--gm-dim2);
}

/* A reading that has stopped arriving stays on screen — "what was it doing" is still useful — but
   the page must not let it read as the market now. Bannered, and the whole page dimmed so the two
   states cannot be confused at a glance. */
.gm-stale {
    background: rgba(210, 153, 34, 0.12);
    border: 1px solid var(--gm-peak);
    border-radius: 8px; padding: 10px 14px; margin-bottom: 14px; color: var(--gm-peak);
    font-size: 12px;
}
/* STALE is framed, not faded (2026-08-13, USER: "remove this blur layer"). opacity .55 on the
   whole grid made the gamma numbers hard to read, which is a poor trade for a state the banner
   already announces. The rail carries it at full contrast. */
.gm-page.is-stale .gm-regime,
.gm-page.is-stale .gm-stats,
.gm-page.is-stale .gm-grid {
  box-shadow: inset 4px 0 0 var(--gm-peak);
  outline: 1px dashed var(--gm-peak);
  outline-offset: 3px;
}
/* The frame is not enough on its own: a pulsing HOT chip reads as live activity, so the animation
   is stopped outright on a stale reading — stopped, not dimmed. */
.gm-page.is-stale .gm-hot.trusted .gm-hot-chip { animation: none; }
/* The producer's own stamp, surfaced when it is materially older than the page's own arrival
   clock would suggest — the one case arrival time cannot catch. */
.gm-oldrec { color: var(--gm-peak); }

/* ---- the per-strike ladder -------------------------------------------------------------- */
.gm-ladder-head {
    display: flex; justify-content: space-between; gap: 12px;
    font-size: 11px; color: var(--gm-dim2);
    padding-bottom: 6px; margin-bottom: 6px; border-bottom: 1px solid var(--gm-line);
}
.gm-ladder-head .ok { color: var(--gm-pos); }
.gm-ladder-head .weak { color: var(--gm-dim2); }

.gm-ladder { max-height: 460px; overflow-y: auto; }
/* Untrusted: the change column is the only thing that becomes unreliable when spot moves — the
   gamma values themselves are still exactly right, so only the deltas are marked. Marked with a
   colour + a dashed underline; at opacity 0.35 the number was simply gone. */
.gm-ladder.untrusted .gm-rung-d {
  color: var(--gm-dim2);
  font-style: italic;
  text-decoration: underline dashed;
  text-underline-offset: 2px;
}

.gm-rung, .gm-ladder-hdr {
    display: grid; grid-template-columns: 52px 1fr 62px 62px 48px 62px;
    align-items: center; height: 18px;
    font-variant-numeric: tabular-nums; font-size: 11px;
}
/* Column captions. Six columns now carry four different units; unlabelled they invite the
   per-share gamma to be read as another dollar figure. */
.gm-ladder-hdr {
    height: 15px; color: var(--gm-dim2); font-size: 9px;
    letter-spacing: .4px; text-transform: uppercase; border-bottom: 1px solid var(--gm-line);
    margin-bottom: 2px;
}
.gm-ladder-hdr .gm-rung-k, .gm-ladder-hdr .gm-rung-ps { color: var(--gm-dim2); }
.gm-rung-k { text-align: right; padding-right: 8px; color: var(--gm-dim); }
.gm-rung-bar { position: relative; height: 11px; }
.gm-rung-mid { position: absolute; left: 50%; top: -3px; bottom: -3px; width: 1px; background: var(--gm-line); }
.gm-rung-fill { position: absolute; top: 1px; height: 9px; border-radius: 2px; }
.gm-rung-fill.pos { left: 50%; background: var(--gm-pos); opacity: .85; }
.gm-rung-fill.neg { right: 50%; background: var(--gm-neg); opacity: .85; }
.gm-rung-g { text-align: right; padding-right: 8px; color: var(--gm-dim2); font-size: 10px; }
.gm-rung-d { text-align: right; padding-right: 6px; font-size: 10px; font-weight: 700; }
.gm-rung-d .up { color: var(--gm-pos); }
.gm-rung-d .dn { color: var(--gm-neg); }
.gm-rung-nil { color: var(--gm-line); font-weight: 400; }
.gm-rung-ps { text-align: right; padding-right: 6px; font-size: 10px; color: var(--gm-dim2); }
.gm-rung-ps.dead { color: var(--gm-neg); }
.gm-rung-bk { text-align: right; padding-right: 4px; font-size: 10px; color: var(--gm-dim2); }
.gm-rung-bk .bid { color: var(--gm-pos); }
.gm-rung-bk .ask { color: var(--gm-neg); }
.gm-rung-bk .sep { color: var(--gm-line); padding: 0 1px; }
/* A dead rung keeps its bar — the exposure IS there — and loses only the claim that it can act.
   The line-through IS the signal; the fades on top of it only cost legibility (.65 on the strike,
   .32 on the bar, which made the magnitude unjudgeable). */
.gm-rung.dead .gm-rung-k { text-decoration: line-through; color: var(--gm-dim2); }
.gm-rung.dead .gm-rung-fill { opacity: .7; }
.gm-rung-flip {
    background: var(--gm-accent); color: #fff; border-radius: 3px;
    padding: 0 4px; font-size: 9px; letter-spacing: .3px;
}
.gm-rung-tag { position: absolute; right: 2px; top: -2px; font-size: 9px; font-weight: 700; letter-spacing: .3px; }
.gm-rung-tag.spot { color: var(--gm-accent); }
.gm-rung-tag.peak { color: var(--gm-peak); }
.gm-rung.spot { background: color-mix(in srgb, var(--gm-accent) 12%, transparent); }
.gm-rung.peak .gm-rung-k { color: var(--gm-peak); font-weight: 700; }

@keyframes gmRungPulse {
    0%, 100% { background: color-mix(in srgb, var(--gm-pos) 10%, transparent); }
    50%      { background: color-mix(in srgb, var(--gm-pos) 34%, transparent); }
}
.gm-rung.hot { animation: gmRungPulse 1.8s ease-in-out infinite; }
.gm-rung.hot .gm-rung-k { color: var(--gm-pos); font-weight: 700; }
/* Untrusted hot: marked, never animated — a pulse on a distance artefact announces price movement
   as though it were positioning. */
.gm-rung.hot-weak { background: color-mix(in srgb, var(--gm-pos) 8%, transparent); }

@media (prefers-reduced-motion: reduce) {
    .gm-rung.hot { animation: none; background: color-mix(in srgb, var(--gm-pos) 26%, transparent); }
}

/* A stale board must not go on signalling live activity. The rung stays MARKED — the reading is
   still the last known one — but the motion stops, same rule as the hot chip above. */
.gm-page.is-stale .gm-rung.hot {
    animation: none;
    background: color-mix(in srgb, var(--gm-pos) 18%, transparent);
}

/* ---- Wall or monument ------------------------------------------------------------------- */
.gm-live-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 4px 0 8px; }
.gm-live-side {
    background: var(--gm-panel2); border: 1px solid var(--gm-line);
    border-radius: 6px; padding: 8px 10px;
}
.gm-live-side.win { border-color: color-mix(in srgb, var(--gm-pos) 55%, var(--gm-line)); }
.gm-live-cap {
    font-size: 9px; letter-spacing: .5px; text-transform: uppercase; color: var(--gm-dim2);
}
.gm-live-k { font-size: 22px; font-weight: 700; font-variant-numeric: tabular-nums; }
.gm-live-side.win .gm-live-k { color: var(--gm-pos); }
.gm-live-note { font-size: 10px; color: var(--gm-dim2); }
.gm-live-verdict { font-size: 11px; border-radius: 5px; padding: 7px 9px; }
.gm-live-verdict.ok { background: color-mix(in srgb, var(--gm-pos) 10%, transparent); color: var(--gm-dim); }
.gm-live-verdict.bad {
    background: color-mix(in srgb, var(--gm-neg) 13%, transparent);
    color: var(--gm-tx); border: 1px solid color-mix(in srgb, var(--gm-neg) 40%, transparent);
}
.gm-live.is-dead .gm-live-side:first-child .gm-live-k { color: var(--gm-dim2); text-decoration: line-through; }

/* ---- Clock drift (charm) ---------------------------------------------------------------- */
.gm-charm-main { margin: 4px 0 8px; }
.gm-charm-row {
    display: flex; justify-content: space-between; align-items: baseline;
    font-size: 11px; color: var(--gm-dim); padding: 4px 0;
}
.gm-charm-row b { font-size: 14px; font-variant-numeric: tabular-nums; color: var(--gm-tx); }
.gm-charm-row.implied { border-top: 1px dashed var(--gm-line); }
.gm-charm-row .up { color: var(--gm-pos); }
.gm-charm-row .dn { color: var(--gm-neg); }
.gm-charm-sides {
    display: flex; justify-content: space-between;
    font-size: 10px; color: var(--gm-dim2); font-variant-numeric: tabular-nums;
}
.gm-charm-flip { font-size: 11px; color: var(--gm-peak); margin-top: 4px; }

/* ---- Quoted book balance ---------------------------------------------------------------- */
.gm-book-k {
    font-size: 30px; font-weight: 700; color: var(--gm-accent);
    font-variant-numeric: tabular-nums; line-height: 1.1; margin-top: 2px;
}
.gm-book-note { font-size: 11px; color: var(--gm-dim); margin-bottom: 6px; }
.gm-book-ev {
    display: flex; gap: 12px; flex-wrap: wrap;
    font-size: 10px; color: var(--gm-dim2); margin-bottom: 6px;
}

/* ---- The board (board-wide gamma) ------------------------------------------------------- */
.gm-board.pos { border-left: 3px solid var(--gm-pos); }
.gm-board.neg { border-left: 3px solid var(--gm-neg); }
.gm-board-sign {
    font-size: 15px; font-weight: 700; letter-spacing: .3px; margin-bottom: 2px;
}
.gm-board-sign.pos { color: var(--gm-pos); }
.gm-board-sign.neg { color: var(--gm-neg); }
.gm-board-sign.unknown { color: var(--gm-dim2); font-style: italic; }
.gm-board-total { font-size: 13px; color: var(--gm-tx); font-variant-numeric: tabular-nums; }
.gm-board-flip { font-size: 11px; color: var(--gm-dim); margin-top: 3px; font-variant-numeric: tabular-nums; }
.gm-board-flip-k { font-size: 15px; font-weight: 700; color: var(--gm-peak); }
.gm-board-note { font-size: 11px; color: var(--gm-dim2); }
.gm-board-says { font-size: 11px; color: var(--gm-dim); margin: 8px 0 0; }
.gm-board-tail {
    font-size: 10px; color: var(--gm-peak); margin: 8px 0 0;
    border-left: 2px solid var(--gm-peak); padding-left: 8px;
}

/* ---- wall history --------------------------------------------------------------------------
   Rows are strikes, columns are the producer's buckets, and each row carries its own curve on
   ONE shared vertical scale. Colour is the SIGN; opacity is set inline from the magnitude. */
.gm-wallhist .gm-wh-heads {
  display: flex;
  justify-content: space-between;
  font-size: 11px;
  color: var(--gm-muted, #7a7f87);
  margin: 2px 0 4px;
}
.gm-wallhist .gm-wh-heads span:last-child { margin-right: 56px; }
.gm-wh-scroll { overflow-x: auto; }
.gm-wh-svg { width: 100%; height: auto; display: block; }

.gm-wh-cell { fill: var(--gm-flat, #8a8f98); }
.gm-wh-cell.gm-wh-pos { fill: #1d9e75; }
.gm-wh-cell.gm-wh-neg { fill: #d85a30; }
/* Spot moved far enough that repricing explains the change: shown, and OUTLINED rather than
   dropped to 0.3 opacity, which had made the cell effectively invisible. Same treatment logic as
   .gm-wh-partial right below — the chart marks its caveats, it does not hide them. */
.gm-wh-cell.gm-wh-dim {
  opacity: 0.8;
  stroke: var(--gm-line, #9aa0a6);
  stroke-width: 1;
  stroke-dasharray: 2 2;
}
/* Clipped outranks dim and is always SOLID: the two classes co-occur on the same cell, so the
   dim rule's dash must be reset here or a clipped cell would read as a dim one. */
.gm-wh-cell.gm-wh-clipped { stroke: #ba7517; stroke-width: 1.6; stroke-dasharray: none; }
/* The bucket still filling. Outlined rather than faded, so it is not confused with dimming. */
.gm-wh-partial {
  fill: none;
  stroke: var(--gm-line, #9aa0a6);
  stroke-dasharray: 3 2;
}
.gm-wh-plot { fill: var(--gm-panel, #ffffff); opacity: 0.5; }
.gm-wh-zero { stroke: var(--gm-line, #9aa0a6); stroke-dasharray: 2 3; }
.gm-wh-spot { fill: none; stroke: var(--gm-fg, #16181d); stroke-width: 1.5; opacity: 0.8; }

.gm-wh-curve { fill: none; stroke: #888780; stroke-width: 1.3; }
.gm-wh-curve.is-up { stroke: #1d9e75; stroke-width: 2.2; }
.gm-wh-curve.is-down { stroke: #d85a30; stroke-width: 2.2; }
.gm-wh-dot { fill: #888780; }
.gm-wh-dot.is-up { fill: #1d9e75; }
.gm-wh-dot.is-down { fill: #d85a30; }
.gm-wh-dot.gm-wh-clipped { stroke: #ba7517; stroke-width: 1.6; }
.gm-wh-val {
  font-size: 10.5px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  fill: #888780;
}
.gm-wh-val.is-up { fill: #1d9e75; }
.gm-wh-val.is-down { fill: #d85a30; }
.gm-wh-k {
  font-size: 12px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  fill: var(--gm-fg, #16181d);
}
.gm-wh-axis { font-size: 9px; fill: var(--gm-muted, #7a7f87); }
.gm-wh-spotdot { fill: var(--gm-fg, #16181d); opacity: 0.8; }

/* ---- where the ladder turns sign ------------------------------------------------------------ */
.gm-sb-list { list-style: none; margin: 8px 0 0; padding: 0; }
.gm-sb-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: baseline;
  padding: 6px 0;
  border-top: 0.5px solid var(--gm-line, #2a323d);
}
.gm-sb-bracket {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 14px;
  min-width: 110px;
}
.gm-sb-row.is-up .gm-sb-bracket { color: #1d9e75; }
.gm-sb-row.is-down .gm-sb-bracket { color: #d85a30; }
.gm-sb-dir { font-size: 12px; color: var(--gm-muted, #7a7f87); }
.gm-sb-gex {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11.5px;
  color: var(--gm-muted, #7a7f87);
}
.gm-sb-side { font-size: 11px; color: var(--gm-muted, #7a7f87); margin-left: auto; }
/* A transition this build does not know is neither direction, and is not coloured as one. */
.gm-sb-row.is-unknown .gm-sb-bracket { color: var(--gm-muted, #7a7f87); }

/* ---- floor test: the one-word card -------------------------------------------------------- */
.gm-ft-line { display: flex; gap: 12px; align-items: baseline; flex-wrap: wrap; }
.gm-ft-level { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 16px; }
.gm-ft-state { font-size: 15px; font-weight: 600; padding: 3px 10px; border-radius: 6px; }
.gm-ft-state.is-def { background: rgba(29,158,117,.15); color: #1d9e75; }
.gm-ft-state.is-nosig { background: rgba(186,117,23,.15); color: #ba7517; }
.gm-ft-state.is-idle { background: rgba(138,143,152,.15); color: var(--gm-muted, #7a7f87); }
.gm-ft-why, .gm-ft-tests { font-size: 12.5px; line-height: 1.55; margin: 8px 0 0; }
/* The arm button lives in the card title; sound is per-tab and off until clicked. */
.gm-floortest h2 { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.gm-ft-sound {
  font: 600 11px/1 inherit; letter-spacing: .02em; cursor: pointer;
  padding: 4px 9px; border-radius: 6px;
  background: transparent; color: var(--gm-muted, #7a7f87);
  border: 1px solid var(--gm-line, #2a3542);
}
.gm-ft-sound.on { background: rgba(29,158,117,.15); border-color: #1d9e75; color: #1d9e75; }

/* ---- time as leader: which strike has actually held the board ----------------------------- */
.gm-lb-rows { display: flex; flex-direction: column; gap: 5px; margin-top: 4px; }
.gm-lb-row { display: grid; grid-template-columns: 84px 1fr 54px 38px; align-items: center; gap: 8px; }
.gm-lb-strike { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; }
.gm-lb-strike em { font-style: normal; font-size: 9px; margin-left: 5px; letter-spacing: .06em; }
.gm-lb-strike em.pos { color: #1d9e75; }
.gm-lb-strike em.neg { color: #c2564d; }
/* Two segments, never one: minutes measured on a complete board are not the same evidence as
   minutes measured while it was thin, and a single bar would blend them silently. */
.gm-lb-bar { display: flex; height: 10px; border-radius: 3px; overflow: hidden; background: rgba(138,143,152,.12); }
.gm-lb-bar i.clean { background: #3f7ecf; }
.gm-lb-bar i.dirty { background: repeating-linear-gradient(45deg, #7a7f87, #7a7f87 3px, transparent 3px, transparent 6px); }
.gm-lb-time { font-variant-numeric: tabular-nums; font-size: 12.5px; text-align: right; }
.gm-lb-pct { font-size: 11px; color: var(--gm-muted, #7a7f87); text-align: right; }
.gm-lb-audit { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 9px; font-size: 11px; color: var(--gm-muted, #7a7f87); }
.gm-lb-audit .warn { color: #ba7517; }
.gm-lb-el { margin-left: auto; }
.gm-lb-warn { font-size: 11.5px; color: #ba7517; margin: 7px 0 0; }

/* ---- the strip on its own page -------------------------------------------------------------
   The board grid is auto-fit with 330px tracks, which is right for a dozen cards and wrong for
   one wide strip: the strip's ~39 time columns were being squeezed into a single track and the
   right-hand end of the session fell off (USER: "not visible completely, it gets hidden").
   Solo it takes the whole page width, and the strip's SVG (width:100%, viewBox) scales into it.
   The PAGE cap has to lift too: .gm-page is 1180px, and a 39-column strip forces ~1326px through
   its own minWidth, so without this the dedicated page still scrolled sideways (Codex). */
.gm-grid.gm-grid-solo { grid-template-columns: 1fr; }
.gm-grid-solo .gm-card { max-width: none; }
.gm-page-solo { max-width: none; }
.gm-card h2 .gm-wh-link {
  float: right; font-size: 11px; font-weight: 600; letter-spacing: .02em;
  color: var(--gm-muted, #7a7f87); text-decoration: none;
  border: 1px solid var(--gm-line, #2a3542); border-radius: 6px; padding: 3px 8px;
}
.gm-card h2 .gm-wh-link:hover { color: #3f7ecf; border-color: #3f7ecf; }
/* Armed but held shut by the browser's autoplay policy: ON, and honest that nothing can be heard
   until the page has had a gesture. */
.gm-ft-sound.on.blocked { background: rgba(186,117,23,.15); border-color: #ba7517; color: #ba7517; }
.gm-ft-blocked { font-size: 11.5px; color: #ba7517; margin: 6px 0 0; line-height: 1.5; }

/* WHEN each strike led — a second line under its bar, because these are several ranges and a
   fixed column would truncate the answer. */
.gm-lb-when { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 6px; margin: 1px 0 3px 84px; }
.gm-lb-spell {
  font-size: 10.5px; font-variant-numeric: tabular-nums; color: var(--gm-muted, #7a7f87);
  border: 1px solid var(--gm-line, #2a3542); border-radius: 3px; padding: 0 5px; line-height: 16px;
}
.gm-lb-spell.is-open { color: #1d9e75; border-color: #1d9e75; }

/* ---------------------------------------------------------------- peak rotation (GMS-R11)
   Where the mass has been GOING, consolidated over 1m/5m/15m/30m/4h/session. State is carried
   by a coloured rail and by text, never by opacity or blur: a faded row reads as a rendering
   glitch rather than a reading, and this card's whole job is to be readable at a glance. */
.gm-rot-rows { display: flex; flex-direction: column; gap: 4px; margin-top: 4px; }
.gm-rot-row {
  display: grid;
  /* FIVE columns: the follow badge is its own, LAST, so it cannot shift the four that were
     here before. Inserting it as an extra child without a column of its own pushed every field
     one place right and wrapped the detail onto an implicit second row (Codex). */
  grid-template-columns: 52px 1fr 68px auto auto;
  align-items: baseline;
  gap: 8px;
  padding: 3px 0 3px 7px;
  border-left: 2px solid transparent;
}
.gm-rot-row.up { border-left-color: #1d9e75; }
.gm-rot-row.down { border-left-color: #c2564d; }
.gm-rot-row.is-flat { border-left-color: var(--gm-line); }
.gm-rot-win {
  font-size: 11px; letter-spacing: .04em; text-transform: uppercase; color: var(--gm-dim2);
}
.gm-rot-move { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
.gm-rot-move b { font-weight: 600; }
.gm-rot-row.is-flat .gm-rot-move { color: var(--gm-dim2); font-style: italic; }
.gm-rot-net {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px; font-variant-numeric: tabular-nums; text-align: right;
}
.gm-rot-row.up .gm-rot-net { color: #1d9e75; }
.gm-rot-row.down .gm-rot-net { color: #c2564d; }
.gm-rot-detail { font-size: 11px; color: var(--gm-dim2); display: flex; gap: 7px; align-items: baseline; }
/* FLICKER is the reading this card exists to separate from a walk, so it is a badge, not a note. */
.gm-rot-flicker {
  font-style: normal; font-size: 9px; letter-spacing: .06em; text-transform: uppercase;
  border: 1px solid currentColor; border-radius: 3px; padding: 0 3px; color: #b3852f;
}
.gm-rot-spot { font-variant-numeric: tabular-nums; }
.gm-rot-partial {
  font-size: 9px; letter-spacing: .06em; text-transform: uppercase; color: #b3852f;
  border: 1px dashed currentColor; border-radius: 3px; padding: 0 3px; align-self: center;
}
.gm-rot-foot {
  margin-top: 7px; padding-top: 6px; border-top: 1px solid var(--gm-line);
  font-size: 11px; color: var(--gm-dim2); display: flex; gap: 8px; align-items: baseline;
}
.gm-rot-foot em {
  font-style: normal; font-size: 9px; letter-spacing: .06em; text-transform: uppercase;
  color: #b3852f; border: 1px dashed currentColor; border-radius: 3px; padding: 0 3px;
}
.gm-rot-log { margin-top: 6px; }
.gm-rot-log summary { font-size: 11px; color: var(--gm-dim2); cursor: pointer; }
.gm-rot-log ol { list-style: none; margin: 6px 0 0; padding: 0; max-height: 190px; overflow-y: auto; }
.gm-rot-log li {
  display: grid; grid-template-columns: 58px 1fr auto; gap: 8px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px;
  padding: 2px 0 2px 6px; border-left: 2px solid transparent;
}
.gm-rot-log li.up { border-left-color: #1d9e75; }
.gm-rot-log li.down { border-left-color: #c2564d; }
.gm-rot-log li em { font-style: normal; font-variant-numeric: tabular-nums; }
.gm-rot-log li.up em { color: #1d9e75; }
.gm-rot-log li.down em { color: #c2564d; }
.gm-rot-at { color: var(--gm-dim2); }

/* Did the book follow the move? A reading per window, beside the arithmetic it is drawn from.
   The colours say "notable" and "ordinary", never "bullish"/"bearish" — the reading is about the
   BOOK, not about direction, and painting it like a direction call would misread it for the user. */
.gm-rot-caveat {
  margin: -2px 0 10px;
  font-size: 11px;
  line-height: 1.45;
  color: var(--muted, #8b93a7);
}
.gm-rot-follow {
  flex: 0 0 auto;
  margin-right: 8px;
  padding: 1px 6px;
  border-radius: 3px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  white-space: nowrap;
  border: 1px solid transparent;
  cursor: help;
}
/* The two that mean "price moved and the book did not come along". */
.gm-rot-follow.round_trip_unsupported,
.gm-rot-follow.unsupported {
  color: #f2b8b5;
  border-color: rgba(242, 184, 181, 0.45);
  background: rgba(242, 184, 181, 0.10);
}
/* Travelled, but wandered to get there. */
.gm-rot-follow.churned {
  color: #e8c98a;
  border-color: rgba(232, 201, 138, 0.40);
  background: rgba(232, 201, 138, 0.10);
}
/* The book came along. */
.gm-rot-follow.followed {
  color: #9fd6a5;
  border-color: rgba(159, 214, 165, 0.40);
  background: rgba(159, 214, 165, 0.10);
}
/* No reading available — deliberately quiet, so an absence never looks like a verdict. */
.gm-rot-follow.not_alignable {
  color: var(--muted, #8b93a7);
  border-color: rgba(139, 147, 167, 0.35);
}

/* PEAK MOVE — did the biggest gamma level actually change hands?
   The palette says "notable" and "ordinary", never "bullish"/"bearish": a takeover is a statement
   about the BOOK, and painting it like a direction call is how a reader turns it into one. */
.gm-pm-now {
  display: flex; align-items: center; gap: 8px; margin: 2px 0 6px;
}
.gm-pm-badge {
  padding: 1px 7px; border-radius: 3px; font-size: 10px; font-weight: 700;
  letter-spacing: 0.04em; white-space: nowrap; border: 1px solid transparent; cursor: help;
}
/* The takeover confirmed. */
.gm-pm-badge.migrated {
  color: #9fd6a5; border-color: rgba(159, 214, 165, 0.40); background: rgba(159, 214, 165, 0.10);
}
/* Two levels, neither giving way — the mass split rather than moved. */
.gm-pm-badge.two_peak {
  color: #e8c98a; border-color: rgba(232, 201, 138, 0.40); background: rgba(232, 201, 138, 0.10);
}
/* Someone is ahead but has not taken over. */
.gm-pm-badge.transient {
  color: #f2b8b5; border-color: rgba(242, 184, 181, 0.45); background: rgba(242, 184, 181, 0.10);
}
/* Resting states, deliberately quiet: neither is an event. */
.gm-pm-badge.held, .gm-pm-badge.warming {
  color: var(--gm-dim); border-color: rgba(139, 147, 167, 0.35);
}
.gm-pm-lvl { font-variant-numeric: tabular-nums; font-weight: 600; }
.gm-pm-arrow { color: var(--gm-dim2); }
.gm-pm-why { color: var(--gm-dim); font-size: 11.5px; line-height: 1.45; margin: 0 0 8px; }
.gm-pm-ev {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px;
  font-size: 11px; color: var(--gm-dim); font-variant-numeric: tabular-nums;
  padding-bottom: 8px; border-bottom: 1px solid var(--gm-line); margin-bottom: 8px;
}
.gm-pm-ev b { color: var(--gm-tx); font-weight: 600; }
/* The three GATES, as the producer decided them — never re-derived here. */
.gm-pm-gate { font-weight: 600; white-space: nowrap; }
.gm-pm-gate.ok { color: var(--gm-pos); }
.gm-pm-gate.no { color: var(--gm-neg); }
.gm-pm-gate.na { color: var(--gm-dim2); }
