/* /demos/langdag-lab — the conversation trees, the routing panel and the scrub.
 *
 * THE DEPTH INDENT IS A CLASS, NOT AN INLINE STYLE. A custom property written
 * into a style attribute would be the obvious way to carry a computed depth,
 * and it puts a template value into a CSS context — which this site's
 * Content-Security-Policy has no reason to allow and html/template is entitled
 * to blank out. The depths are small and known (the deepest captured tree is
 * four turns), so they are enumerated here and the template picks one.
 *
 * EVERY RULE THAT MATTERS IS A NON-SCRIPT RULE. The page is complete before the
 * script runs: nodes are in the document, indented, in walk order. The script
 * adds connectors and a scrub, and everything it needs is scoped under
 * [data-langdag-ready] so a script that failed to load leaves a readable page
 * rather than a half-built one. */

.ldl__lede {
  max-width: 68ch;
}

.ldl__captured,
.ldl__determinism,
.ldl__reading {
  margin: 1.75rem 0;
  max-width: 78ch;
}

/* --- scenario ------------------------------------------------------------ */

.ldl__scenario {
  margin: 2.5rem 0;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border, #d8dee4);
}

.ldl__scenario:first-child {
  border-top: 0;
}

.ldl__summary {
  max-width: 78ch;
}

.ldl__facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.2rem 1rem;
  margin: 1rem 0 1.25rem;
  font-size: 0.94rem;
}

.ldl__facts dt {
  font-weight: 600;
  opacity: 0.8;
}

.ldl__facts dd {
  margin: 0;
}

/* --- routing policy ------------------------------------------------------ */

.ldl__policy {
  margin: 1.25rem 0 1.5rem;
  padding: 1rem 1.1rem;
  border: 1px solid var(--border, #d8dee4);
  border-radius: 8px;
  max-width: 78ch;
}

.ldl__policy h3 {
  font-size: 1.02rem;
  margin: 0 0 0.4rem;
}

.ldl__policy h3 + p {
  margin-top: 0;
}

.ldl__routes,
.ldl__attempts {
  list-style: none;
  padding-left: 0;
  margin: 0.5rem 0 1rem;
}

.ldl__routes li,
.ldl__attempt {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.55rem;
  padding: 0.32rem 0;
}

.ldl__route-name {
  font-weight: 600;
}

.ldl__route-weight {
  opacity: 0.75;
}

.ldl__attempt-verdict {
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
  border: 1px solid currentColor;
  opacity: 0.85;
}

.ldl__attempt--declined .ldl__attempt-verdict {
  color: #b3261e;
}

.ldl__attempt-error {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.84rem;
  opacity: 0.8;
}

/* --- the tree ------------------------------------------------------------ */

.ldl__tree {
  position: relative;
  margin: 1rem 0;
}

.ldl__nodes {
  list-style: none;
  padding-left: 0;
  margin: 0;
}

.ldl__node {
  position: relative;
  margin: 0.5rem 0;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--border, #d8dee4);
  border-left-width: 3px;
  border-radius: 8px;
  max-width: 62ch;
}

/* The depth ladder. Four steps is every captured tree; a fifth would need a
 * rule here, which is deliberate — a depth with no rule renders flush left and
 * is visible rather than silently wrong. */
.ldl__node--d0 { margin-left: 0; }
.ldl__node--d1 { margin-left: 1.5rem; }
.ldl__node--d2 { margin-left: 3rem; }
.ldl__node--d3 { margin-left: 4.5rem; }
.ldl__node--d4 { margin-left: 6rem; }

.ldl__node--user {
  border-left-color: #6b7785;
}

.ldl__node--assistant {
  border-left-color: #2f6f4f;
}

.ldl__node--diverges {
  border-left-color: #8a5a00;
}

.ldl__node-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.5rem;
  font-size: 0.8rem;
  margin-bottom: 0.35rem;
}

.ldl__node-id {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-weight: 700;
}

.ldl__node-kind {
  text-transform: uppercase;
  letter-spacing: 0.05em;
  opacity: 0.7;
}

.ldl__node-provider,
.ldl__node-branches {
  padding: 0.05rem 0.45rem;
  border-radius: 999px;
  border: 1px solid var(--border, #d8dee4);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

.ldl__node-branches {
  font-family: inherit;
  border-color: #8a5a00;
}

.ldl__block-text {
  margin: 0.25rem 0;
  line-height: 1.5;
}

.ldl__block {
  margin: 0.4rem 0;
}

.ldl__block-label {
  margin: 0 0 0.25rem;
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  opacity: 0.75;
}

.ldl__tool-id {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  opacity: 0.7;
  text-transform: none;
  letter-spacing: 0;
}

.ldl__block-pre {
  margin: 0;
  padding: 0.5rem 0.65rem;
  border-radius: 6px;
  overflow-x: auto;
  font-size: 0.86rem;
  background: rgba(127, 127, 127, 0.09);
}

.ldl__node-meta {
  margin: 0.45rem 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  font-size: 0.8rem;
  opacity: 0.75;
}

/* --- enhancement, only once the script has said so ----------------------- */

[data-langdag-ready] .ldl__scrub {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin: 0.75rem 0 1rem;
  flex-wrap: wrap;
}

.ldl__scrub {
  display: none;
}

.ldl__scrub label {
  font-size: 0.88rem;
  font-weight: 600;
}

.ldl__scrub-readout {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.86rem;
  min-width: 12ch;
}

[data-langdag-ready] .ldl__node[hidden] {
  display: none;
}

/* The connector layer sits behind the nodes and is drawn by the script. It has
 * no size of its own until then, so nothing shifts if the script never runs. */
.ldl__wires {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: visible;
}

.ldl__wire {
  stroke: var(--border, #d8dee4);
  stroke-width: 1.5;
  fill: none;
}

.ldl__wire--diverges {
  stroke: #8a5a00;
}

@media (max-width: 640px) {
  /* The indent ladder collapses on a narrow screen: four steps of 1.5rem eats
   * a third of a phone's width and the depth is already in the node's own
   * data. The border color and the id still carry the structure. */
  .ldl__node--d1,
  .ldl__node--d2,
  .ldl__node--d3,
  .ldl__node--d4 {
    margin-left: 0.75rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ldl__node {
    transition: none;
  }
}

/* --- the live branch ----------------------------------------------------- */

.ldl__live {
  margin: 2.5rem 0;
  padding: 1.25rem 1.35rem;
  border: 1px solid var(--border, #d8dee4);
  border-left: 3px solid #2f6f4f;
  border-radius: 8px;
  max-width: 78ch;
}

.ldl__live h2 {
  margin-top: 0;
}

.ldl__live-form {
  display: grid;
  gap: 0.4rem;
  margin-top: 1rem;
  max-width: 56ch;
}

.ldl__live-form label {
  font-weight: 600;
  font-size: 0.9rem;
}

.ldl__live-form select,
.ldl__live-form textarea {
  width: 100%;
  padding: 0.45rem 0.55rem;
  border: 1px solid var(--border, #d8dee4);
  border-radius: 6px;
  font: inherit;
  background: transparent;
  color: inherit;
}

.ldl__live-form textarea {
  resize: vertical;
  min-height: 4.5rem;
}

.ldl__live-form button {
  justify-self: start;
  margin-top: 0.35rem;
}

.ldl__live-status {
  margin-top: 0.85rem;
  font-size: 0.92rem;
  padding: 0.5rem 0.7rem;
  border-radius: 6px;
  background: rgba(127, 127, 127, 0.09);
}

/* A LIVE NODE IS MARKED, and the marking is not decoration. Every other node in
 * every tree came out of a committed capture that anyone can re-run and
 * byte-compare; this one came from a model call a moment ago and is gone on
 * reload. A live node styled identically to the captured ones beside it would
 * be quietly claiming the same provenance. */
.ldl__node--live {
  border-style: dashed;
  border-left-style: solid;
  border-left-color: #2f6f4f;
}

.ldl__node-live {
  padding: 0.05rem 0.45rem;
  border-radius: 999px;
  border: 1px solid #2f6f4f;
  color: #2f6f4f;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
