/* ═══ §11 · TAB: DISCOVER ═════════════════════════════════════════════════════════════
   The brain's own surface: the header + instrument strip, the theater (the movie), and the
   carousels (Episodes · Patterns · Cluster · Bandit Arms · Moon Scoreboard · Signal Scorecard ·
   Self-Monitor), which all share ONE host class because they render the same card. */

#view-discovery { padding-bottom: var(--sp-md); }

/* ── §11.1 the header + the instrument strip ── */
.discover-hdr {
  margin: 8px 0 14px;
  padding: 18px 16px 14px;
  border-radius: 14px;
  position: relative;
  overflow: hidden;
}
.discover-hdr::before {
  content: '';
  position: absolute;
  inset: -2px;
  background: conic-gradient(from 0deg at 50% 50%, transparent,
              var(--accent-red) 15%, transparent 30%, var(--accent-gold) 50%, transparent 65%);
  filter: blur(22px);
  opacity: 0.14;
  z-index: -1;
  animation: discover-sweep 18s linear infinite;
}
@keyframes discover-sweep {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
.discover-hdr-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 14px;
}
.discover-hdr-eyebrow {
  font-size: 0.55rem;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.discover-hdr-h1 {
  font-size: 1.22rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--accent-gold);
  text-shadow: 0 0 14px rgba(212, 175, 55, 0.35);
}

/* the stat strip. It is ALSO the tile grid every modal's belief readout uses, so it is not
   Discover-private in practice — but Discover is where it is declared and every other consumer
   reaches it through the same class. */
/* ★★ THE COLUMN COUNT IS THE CONTAINER'S, NOT THE VIEWPORT'S, AND THAT IS THE WHOLE FIX.
   This was `repeat(4, 1fr)` with a viewport media query dropping to 2 — and this same class also
   dresses the MODALS' belief tiles (see the note above), where the container is a ~400px sheet that
   does not track the viewport at all. MEASURED off the 390px Brain-modal shot at a 1440px window:
   the query answered "wide", kept four columns in a 400px sheet, gave each tile ~90px, and
   `CONTRIBUTORS` at 0.55rem with 0.14em tracking broke mid-word — `CONTRIBUTO / RS` — while the
   fourth tile ran off the modal's right edge.
   `auto-fit` + `minmax` sizes by the box the grid is ACTUALLY IN, so it lays four across on the
   Discover page and folds to two inside a sheet, with no breakpoint to keep in agreement with a
   width nobody controls. The floor is the widest label this grid carries: `CONTRIBUTORS` measures
   ~86px at this size, so 92px clears it with the padding. */
.discover-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(92px, 1fr));
  gap: 8px;
  /* ⚠ AND IT MAY NOT EXCEED ITS PARENT. A grid is a block, so it takes its containing block's
     width — but inside a scroller that width is measured BEFORE the vertical scrollbar exists, and
     the last column then sits under it. READ off the Brain-modal shot: the third tile clipped at
     the right edge with the scrollbar over it. `min-width: 0` lets the track floor give way rather
     than forcing an overflow the parent cannot show. */
  min-width: 0;
  max-width: 100%;
}
/* ★★ THE DISCOVER STRIP'S ROWS CARRY MEANING, SO ITS COLUMN COUNT IS SEMANTIC — and that is why
   this ONE instance pins three while the class above keeps fitting. They are not two opinions
   about one number; they are two different facts. The modals' belief tiles are an unordered set
   in a sheet whose width nobody controls, so `auto-fit` is exactly right for them. The Discover
   strip is four NAMED TRIPLES (see system.html) — `The beat`, `The mind`, `The gaze`, `The book` —
   and a grid that re-flows to 4 or 5 across tears a triple in half and re-splits it at the next
   breakpoint. MEASURED: at ten tiles the fitting grid laid 3+3+3 and left BPM alone on a fourth
   row, which is the shot that started this.
   `minmax(0, 1fr)` and not `1fr`: a grid track's automatic minimum is its content's min-content
   size, so `CANDIDATES` at 0.14em tracking would push the row wider than the page rather than
   wrapping inside its own tile — the same overflow the `min-width: 0` above exists to stop, one
   level down. */
#discover-stats { grid-template-columns: repeat(3, minmax(0, 1fr)); }
/* the row label — full width, so the three tiles beneath it read as one answer rather than three
   readings that happen to be adjacent. The rule ABOVE each group is what makes the grouping
   visible at a glance; the first one carries no rule because there is nothing above it to divide. */
#discover-stats .discover-stats-group {
  grid-column: 1 / -1;
  font-size: 0.5rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-dim);
  padding: 6px 2px 0;
  margin-top: 2px;
  border-top: 1px solid var(--glass-border);
  overflow-wrap: anywhere;
}
#discover-stats .discover-stats-group:first-child {
  padding-top: 0;
  margin-top: 0;
  border-top: 0;
}
.discover-stat {
  text-align: center;
  padding: 10px 4px;
  background: rgba(16, 16, 24, 0.45);
  border: 1px solid var(--glass-border);
  border-radius: 10px;
  min-width: 0;
  transition: all 0.2s;
}
.discover-stat:hover { border-color: var(--glass-border-active); transform: translateY(-1px); }
/* ONE INK FOR ALL TWELVE. bpm · beats · wake · minds · claims/min · engram · candidates ·
   signals · open · resolved · win · moon are ONE instrument read at one glance, so they take one
   colour — the live-value gold. Wake and BPM are arguably state rather than measurement, but they
   are rendered as tiles in this same grid: colouring two of twelve differently would state a
   distinction the reader cannot see, and this class also dresses the modals' belief tiles. The
   grouping the reader DOES need is said by the row labels, not by a second ink. */
.discover-stat-val {
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--accent-gold);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 10px rgba(212, 175, 55, 0.35);
  overflow-wrap: anywhere;
}
.discover-stat-lbl {
  font-size: 0.55rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-top: 2px;
  overflow-wrap: anywhere;
}

/* ── §11.2 a section ── */
.discover-section { margin: 14px 0; }
.discover-section-hdr {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 0 4px 10px;
  gap: 8px;
  flex-wrap: wrap;
}
.discover-section-title {
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--accent-gold);
  display: flex;
  align-items: center;
  gap: 10px;
}
.discover-section-sub {
  font-size: 0.6rem;
  color: var(--text-dim);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

/* ── §11.3 THE THEATER — the movie. app._discoverBuildTheater builds ONE dark-field <canvas> in a
   .theater-stage, with the HUD and the fullscreen control absolutely placed over it. Every
   pulse it draws is a REAL Claim; when nothing is in flight the shot RESTS and the HUD states
   the backend's own reason. All motion is drawn by the engine — CSS only frames the stage. ── */
.discover-theater { padding: 6px 6px 8px; border-radius: 14px; }
.theater-stage { position: relative; display: block; }
/* THE CANVAS TAKES THE STAGE'S WIDTH. Without this it keeps the replaced element's INTRINSIC
   300px — measured 300×186 inside a 324px stage at 390px AND inside a 552px stage at 1440px,
   i.e. the movie was the same small box on every screen. */
.discover-theater canvas {
  display: block;
  width: 100%;
  border-radius: 10px;
  background: #05050a;
}

/* FULLSCREEN — two paths, one look:
     .is-fs         the native Fullscreen API element (desktop + Android Chrome)
     .is-fs-inpage  iOS Safari has no element fullscreen, so the stage goes full-viewport
                    in-page, honouring the safe-area insets
   In both the canvas fills the box and the app chrome hides so nothing sits in the shot. */
.theater-stage.is-fs {
  background: #050508;
  box-sizing: border-box;
  width: 100%;
  height: 100%;
}
.theater-stage.is-fs-inpage {
  position: fixed;
  inset: 0;
  /* the same rung the fullscreen chart uses — this app hard-codes its stacking order */
  z-index: 12000;
  padding: env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px)
           env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
}
/* the canvas fills the stage's CONTENT box, IN FLOW, never absolutely positioned: an
   absolutely-positioned REPLACED element resolves width:auto from its INTRINSIC size, which
   makes canvas.width feed back into its own CSS size and run away (measured 2214px at 390px). */
.theater-stage.is-fs canvas {
  position: static;
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 0;
}
body.theater-fs .status-bar,
body.theater-fs .holo-nav { display: none; }
body.theater-fs .view-container { overflow: hidden; }
/* the .glass card's backdrop-filter would make the theater card a CONTAINING BLOCK for the
   fixed in-page stage, which would then size to the card, not the viewport (measured 340×144
   on a 390×844 phone). */
body.theater-fs .discover-theater {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* the control — always reachable, never in the shot: it fades out mid-flight and returns on
   any tap or mouse move (the stage sets .ctl-awake). 32 DRAWN, 44 ANSWERED via §2's hit box. */
.theater-fs-btn {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 3;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  line-height: 1;
  color: var(--accent-gold);
  background: rgba(10, 10, 15, 0.55);
  border: 1px solid rgba(230, 57, 70, 0.28);
  border-radius: 9px;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.5s ease, background 0.2s ease;
  -webkit-tap-highlight-color: transparent;
}
.theater-stage.ctl-awake .theater-fs-btn { opacity: 0.85; }
.theater-fs-btn:hover { background: rgba(20, 20, 28, 0.85); color: #fff; }
.theater-stage.is-fs-inpage .theater-fs-btn {
  top: calc(env(safe-area-inset-top, 0px) + 12px);
  right: calc(env(safe-area-inset-right, 0px) + 12px);
  width: 40px;
  height: 40px;
  font-size: 0.95rem;
}

/* the HUD — names the followed THOUGHT's target, which step of how many the camera is riding,
   and that step's own note; at rest it states why nothing is in flight. */
.theater-hud {
  position: absolute;
  left: 10px;
  bottom: 10px;
  z-index: 2;
  max-width: min(78%, 380px);
  padding: 6px 10px;
  border-radius: 10px;
  background: rgba(8, 8, 12, 0.62);
  border: 1px solid var(--glass-border);
  font-family: var(--font-mono);
  font-size: 0.55rem;
  line-height: 1.5;
  color: var(--ink-panel);
  letter-spacing: 0.04em;
  pointer-events: none;
}
.theater-stage.is-fs-inpage .theater-hud {
  left: calc(env(safe-area-inset-left, 0px) + 14px);
  bottom: calc(env(safe-area-inset-bottom, 0px) + 16px);
  font-size: 0.62rem;
}
.theater-hud-line {
  display: flex;
  align-items: center;
  gap: 6px;
}
.theater-hud-line b { color: var(--outcome-moon); font-weight: 700; letter-spacing: 0.1em; }
/* THE DOT ROW IS A STATUS LAMP, AND CYAN IS THE DECK'S STATUS COLOUR — so it keeps it while the
   rest of this surface goes red/gold/silver. It reports WHICH step of the flight the camera is
   riding: unlit is the same lamp dimmed, lit is where the camera is now, and a dark step is red
   because it carried no evidence. Three states in a 4px pip only read at a glance if the unlit
   and lit forms are one hue, and cyan is the one hue on this deck that means state. */
.theater-hud-dots { display: inline-flex; gap: 3px; margin-left: 2px; }
.theater-hud-dots i {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: rgba(108, 248, 255, 0.22);
}
.theater-hud-dots i.on {
  background: var(--accent-cyan-bright);
  box-shadow: 0 0 6px var(--accent-cyan-bright);
}
/* a DARK step is a stage that carried no evidence — it is SHOWN (hollow), never omitted, so the
   flight cannot read as if the hop happened */
.theater-hud-dots i.dark { background: transparent; border: 1px solid rgba(255, 90, 122, 0.55); }
.theater-hud-dots i.dark.on { background: rgba(255, 90, 122, 0.35); box-shadow: none; }
.theater-hud-rep { color: var(--outcome-moon); font-weight: 700; letter-spacing: 0.06em; }
.theater-hud-n { margin-left: auto; color: var(--text-dim); }
/* THE HUD MUST NOT EAT THE SHOT. A terminus sentence is long by design and unclamped it ran
   five lines over a 250px-tall stage — the caption covering the movie it captions. The hop is
   one line, the note at most two; the full text is on the status line under the stage. */
.theater-hud-hop {
  color: var(--ink-panel);
  overflow-wrap: anywhere;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.theater-hud-hop.is-dark { color: #ff8aa0; }
.theater-hud-hop em { color: var(--outcome-fade); font-style: normal; }
.theater-hud-note {
  color: var(--text-dim);
  font-size: 0.92em;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* THE WIRE READING IS ONE LINE, HARD. It sits in the resting HUD's third row — the row that used to
   be a two-line note — and the numbers on it (calls · regions · keys · moved) grow as the organism
   runs, so a clamp of two would let it take a second line on a busy minute and push the box off a
   250px stage. Same law as `.theater-hud-hop` above, applied to the row that carries live counters:
   the full figures ride on /api/brain/anatomy, and this line is the glance. */
.theater-hud-wire {
  color: var(--text-dim);
  font-size: 0.92em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.theater-hud-wire b { color: var(--ink-panel); font-weight: 700; }
.discover-theater-chips { display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 4px 2px; }
.theater-chip {
  font-family: var(--font-mono);
  font-size: 0.58rem;
  padding: 3px 9px;
  border-radius: 999px;
  background: rgba(16, 16, 24, 0.6);
  border: 1px solid var(--glass-border);
  color: var(--ink-panel);
  letter-spacing: 0.04em;
}
.theater-chip b { color: var(--accent-gold); font-weight: 700; }
.discover-theater-status {
  font-family: var(--font-mono);
  font-size: 0.58rem;
  color: var(--text-dim);
  letter-spacing: 0.05em;
  padding: 6px 4px 0;
  line-height: 1.5;
}

/* ── §11.4 THE CAROUSELS — Episodes · Patterns · Cluster · Bandit Arms · Moon Scoreboard ·
   Signal Scorecard · Self-Monitor all render the same card into the same host class, so one
   declaration serves every one of them. ── */
.discover-carousel {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  padding-bottom: 4px;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
}
.discover-carousel::-webkit-scrollbar { display: none; }
.episode-card {
  flex: 0 0 var(--card-peek);
  scroll-snap-align: start;
  background: linear-gradient(135deg, var(--glass-bg), var(--glass-bg-heavy));
  border: 1px solid var(--glass-border);
  border-radius: 12px;
  padding: 12px 14px;
  position: relative;
  overflow: hidden;
  min-width: 0;
}
/* the card head — one row: the title block left, the verdict right */
.episode-card-hdr {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 8px;
  margin-bottom: 8px;
}
.episode-tkr {
  font-size: 1.05rem;
  font-weight: 800;
  color: var(--ink-panel);
  letter-spacing: 0.02em;
  overflow-wrap: anywhere;
}
.episode-sub {
  font-size: 0.55rem;
  color: var(--text-secondary);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  overflow-wrap: anywhere;
}
.episode-peak {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--outcome-win);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.episode-row {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  font-size: 0.65rem;
  color: var(--text-dim);
  margin: 2px 0;
}
.episode-row b {
  color: var(--ink-panel);
  font-variant-numeric: tabular-nums;
  text-align: right;
  overflow-wrap: anywhere;
}

/* the 420px breakpoint that used to fold `.discover-stats` to two columns is DELETED, not kept
   beside the auto-fit rule above (R3): two rules deciding one column count is exactly how the
   modal case came to be wrong while the page case looked right. `auto-fit` already folds at every
   width the query covered, and at the ones it could never see. */

