/* ── Info page layout ───────────────────────────────────────────────── */
.info-subnav {
  /* .topbar (dashboard.css) is already position:sticky;top:0 with height var(--header-h) —
     stick just below it, not on top of it. */
  position: sticky; top: var(--header-h); z-index: 5;
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap;
  padding: var(--space-3) 0; margin-bottom: var(--space-8);
  background: var(--color-bg);
  border-bottom: 1px solid var(--color-divider);
}
.info-subnav__links { display: flex; gap: var(--space-4); flex-wrap: wrap; }
.info-subnav__link {
  font-size: var(--text-xs); font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--color-text-muted);
}
.info-subnav__link:hover, .info-subnav__link.is-active { color: var(--color-primary); }

.lang-toggle {
  display: flex; flex-shrink: 0; border: 1px solid var(--color-border);
  border-radius: var(--radius-full); overflow: hidden;
}
.lang-toggle__opt {
  font: inherit; padding: 2px var(--space-3); font-size: var(--text-xs); font-weight: 600;
  background: transparent; color: var(--color-text-muted); cursor: pointer;
}
.lang-toggle__opt:hover:not(.is-active) { background: var(--color-surface-offset); }
.lang-toggle__opt.is-active { background: var(--color-primary); color: var(--color-text-inverse); }

/* Clears both sticky bars (topbar ~56px + info-subnav ~46px) so scrollIntoView()
   and hash-anchor jumps don't land a section heading underneath them. */
.info-section { margin-bottom: var(--space-16); scroll-margin-top: 120px; }
.info-section h2 { font-size: var(--text-xl); margin-bottom: var(--space-2); }
.info-section > p.eyebrow { margin-bottom: var(--space-1); }
.info-section__lead { max-width: 68ch; color: var(--color-text-muted); margin-bottom: var(--space-6); }

/* Team credit byline — deliberately understated (a footer-style line, not an alert box) */
.info-credit {
  margin-top: var(--space-8); padding-top: var(--space-4);
  border-top: 1px solid var(--color-divider);
  font-size: var(--text-xs); color: var(--color-text-faint); max-width: 68ch;
}
.info-credit a { color: var(--color-text-muted); }
.info-credit a:hover { color: var(--color-primary); }

/* ── Tree diagrams (shared by §Challenge and §Rules) ────────────────── */
/* No fixed width: each <svg> carries width/height attributes matching its own
   viewBox (see info-diagrams.js), so node circles render at the same native
   pixel size everywhere. max-width only prevents overflow on narrow screens,
   scaling the whole diagram down (not up) while keeping its aspect ratio. */
.mtree { display: block; max-width: 100%; height: auto; margin: 0 auto; }
/* Bigger on desktop, native size on mobile (confirmed good as-is). zoom (not
   transform) affects layout, so surrounding flex/wrap reflows correctly. True fluid
   scaling isn't possible here (zoom's percentage isn't length-relative, so mixing it
   with vw in calc()/clamp() is invalid) — progressive breakpoint tiers instead, so
   very wide/4K monitors get bigger diagrams too, not just a flat desktop bump. */
@media (min-width: 900px)  { .mtree { zoom: 1.3; } }
@media (min-width: 1600px) { .mtree { zoom: 1.55; } }
@media (min-width: 2200px) { .mtree { zoom: 1.8; } }
.mtree-node circle { fill: var(--color-surface-2); stroke: var(--color-border); stroke-width: 1.5; }
.mtree-node text { font-family: var(--font-mono); font-size: 10px; fill: var(--color-text); text-anchor: middle; dominant-baseline: middle; }
.mtree-node--hl circle   { fill: var(--color-primary-subtle); stroke: var(--color-primary); }
.mtree-node--cut circle  { fill: var(--color-warning-bg); stroke: var(--color-warning); stroke-dasharray: 3 2; }
.mtree-node--keep circle { fill: var(--color-success-bg); stroke: var(--color-success); }
.mtree-dot { fill: var(--color-text-faint); }
.mtree-edge { stroke: var(--color-border); stroke-width: 1.5; }
.mtree-edge--cut { stroke: var(--color-warning); stroke-dasharray: 4 3; }

.tree-pair { display: flex; gap: var(--space-4); justify-content: center; flex-wrap: wrap; margin: var(--space-4) 0; }
/* Each forest gets its own bordered sub-box, distinct from the surrounding
   Before/After .rule-phase background — makes clear which diagram belongs to
   which forest whether they sit side by side or stack on narrow screens. */
.tree-pair__item {
  flex: 1 1 auto; text-align: center;
  padding: var(--space-3);
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  border-radius: var(--radius-md);
}
.tree-pair figcaption {
  font-size: var(--text-xs); color: var(--color-text-muted); margin-bottom: var(--space-1);
  text-transform: uppercase; letter-spacing: 0.05em;
}

/* ── §Challenge ──────────────────────────────────────────────────────── */
.info-block { margin: var(--space-8) 0; }
.info-block h3 { font-size: var(--text-lg); margin-bottom: var(--space-3); }
.track-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-4); }
.track-card {
  background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-lg);
  padding: var(--space-5); text-align: center; box-shadow: var(--shadow-sm);
}
.track-card h4 { font-size: var(--text-lg); margin: var(--space-2) 0 var(--space-1); }
@media (max-width: 720px) { .track-grid { grid-template-columns: 1fr; } }

/* ── §Website — pipeline diagram ────────────────────────────────────── */
.pipeline { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; justify-content: center; }
.pipeline-step {
  display: flex; flex-direction: column; align-items: center; gap: var(--space-1);
  padding: var(--space-3); min-width: 110px; text-align: center; font-size: var(--text-xs);
  background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-md);
}
.pipeline-step--dest { border-color: var(--color-primary); background: var(--color-primary-subtle); }
.pipeline-step__icon { font-size: 1.3rem; }
.pipeline-arrow { color: var(--color-text-faint); font-size: 1.2rem; }
@media (max-width: 640px) {
  .pipeline { flex-direction: column; }
  .pipeline-arrow { transform: rotate(90deg); }
}

/* ── §Solver — algorithm outline diagram ────────────────────────────── */
.algo-flow { display: flex; flex-direction: column; align-items: center; gap: var(--space-1); max-width: 440px; margin: var(--space-6) auto 0; }
.algo-step {
  width: 100%; text-align: center; padding: var(--space-3) var(--space-4);
  background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-md);
}
.algo-step p { font-weight: 600; }
.algo-step .muted { display: block; font-size: var(--text-xs); margin-top: var(--space-1); }
.algo-step--loop { border-color: var(--color-primary); border-width: 2px; }
.algo-step--end  { border-color: var(--color-success); background: var(--color-success-bg); }
.algo-arrow { color: var(--color-text-faint); }

/* Small chip chain inside the Branch & Reduce step — strictly sequential (a
   competition rule: single CPU core, no multithreading), never rendered as parallel
   branches. */
.cluster-chain { display: flex; align-items: center; justify-content: center; gap: var(--space-2); flex-wrap: wrap; margin-top: var(--space-2); }
.cluster-box {
  padding: var(--space-1) var(--space-3); font-size: var(--text-xs); font-weight: 600;
  background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-sm);
}
.cluster-box--more { color: var(--color-text-faint); border-style: dashed; }
.cluster-arrow { color: var(--color-text-faint); font-size: 0.9rem; }

/* ── §Rules ──────────────────────────────────────────────────────────── */
.badge--reduction { background: var(--color-success-bg); color: var(--color-success); }
.badge--forcedcut { background: var(--color-warning-bg); color: var(--color-warning); }
.badge--branching { background: var(--color-error-bg);   color: var(--color-error); }

.rule-grid { display: flex; flex-direction: column; gap: var(--space-5); }
.rule-card {
  background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-lg);
  padding: var(--space-5); box-shadow: var(--shadow-sm);
}
.rule-card__head { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-2); }
.rule-card__head h4 { font-size: var(--text-base); overflow-wrap: anywhere; }
.rule-card__diagrams { display: flex; align-items: stretch; gap: var(--space-4); flex-wrap: wrap; margin-top: var(--space-3); }

/* Before/After grouping box — keeps each phase visually distinct even when the
   two phases stack into a single mobile column (previously ambiguous: the tree
   diagrams ran together with no boundary between "before" and "after"). */
.rule-phase {
  flex: 1; min-width: 220px; padding: var(--space-3);
  border: 1px solid var(--color-divider); border-radius: var(--radius-md);
  background: var(--color-surface-offset);
}
.rule-arrow { align-self: center; color: var(--color-text-faint); font-size: 1.4rem; }

/* Row of outcome buttons, side by side; wraps to multiple rows only when the
   available width can't fit them (not stacked to one-per-row by default). */
.branch-outcomes { display: flex; flex-direction: row; flex-wrap: wrap; gap: var(--space-2); }
.branch-outcome {
  flex: 1 1 auto;
  font: inherit; font-size: var(--text-xs); text-align: center; padding: var(--space-2);
  border: 1px solid var(--color-border); border-radius: var(--radius-md); color: var(--color-text-muted);
  background: var(--color-surface); cursor: pointer;
}
.branch-outcome:hover { background: var(--color-surface-dynamic); color: var(--color-text); }
.branch-outcome.is-active, .branch-outcome--keep.is-active {
  border-color: var(--color-primary); background: var(--color-primary-subtle); color: var(--color-primary);
}
.ppb-outcome-diagram { margin-top: var(--space-3); }

@media (max-width: 640px) {
  .rule-card__diagrams { flex-direction: column; }
  .rule-arrow { transform: rotate(90deg); }
}
