/*
 * Expression notebook — Lisp-like rendering
 * ============================================================
 * Expressions use their summary as the clickable operator.
 * Brackets indicate expression boundaries and are selected
 * by the expression's data-eval-strategy.
 *
 * Layout modes:
 *   1. Collapsed expression:       ( op … )
 *   2. Expanded, children closed:  ( op arg1 arg2 )
 *   3. Expanded, child open:       ( op
 *                                    child1
 *                                    child2
 *                                  )
 */


/* ============================================================
 * 1. Disclosure controls
 * Remove the browser's default triangle marker. The expression
 * brackets provide the visual structure instead.
 * ============================================================ */

 .nb-root .expr > summary {
  list-style: none;
}

.nb-root .expr > summary::-webkit-details-marker {
  display: none;
}


/* ============================================================
 * 2. Expression notation and shared defaults
 * Each expression owns its opening and closing brackets.
 * Override these variables for different evaluation strategies.
 * ============================================================ */

/** default strategy is parallel */
.nb-root .expr {
  --bracket-open: "⦅ ";
  --bracket-close: " ⦆";

  cursor: pointer;
}

/* Evaluation strategy notation */

/* Sequential — simple, linear */
.nb-root .expr[data-eval-strategy="sequential"],
.nb-root .expr:not(:has(> .expr ~ .expr)) {
  --bracket-open: "( ";
  --bracket-close: " )";
}

/* Parallel — rounded, doubled */
.nb-root .expr[data-eval-strategy="parallel"] {
  --bracket-open: "⦅ ";
  --bracket-close: " ⦆";
}

/* Settled — strong, enclosed */
.nb-root .expr[data-eval-strategy="settled"] {
  --bracket-open: "⟦ ";
  --bracket-close: " ⟧";
}

/* Consistent punctuation treatment */
.nb-root .expr:not([open]) > summary .op::before,
.nb-root .expr:not([open]) > summary::after,
.nb-root .expr[open] > summary .op::before,
.nb-root .expr[open]::after {
  color: var(--punctuation);
  font-weight: 400;
}

/* ============================================================
 * 3. Operator spacing
 * Add breathing room between the operator and its arguments.
 * ============================================================ */

.nb-root .expr > summary {
  margin-right: 0.35em;
}


/* ============================================================
 * 4. Collapsed expressions
 * Keep the expression inline. Its summary displays the opening
 * bracket, operator, ellipsis, and closing bracket.
 * ============================================================ */

.nb-root .expr:not([open]) {
  display: inline;
}

.nb-root .expr:not([open]) > summary {
  display: inline;
}

.nb-root .expr:not([open]) > summary .op::before {
  content: var(--bracket-open);
  color: var(--punctuation);
  display: inline;
}

.nb-root .expr:not([open]) > summary::after {
  content: " …" var(--bracket-close);
  color: var(--punctuation);
  display: inline;
}


/* ============================================================
 * 5. Expanded expressions with no expanded child
 * Keep the expression and its direct children in inline flow.
 * The opening bracket belongs to the summary; the closing
 * bracket belongs to the expression itself.
 * ============================================================ */

.nb-root .expr[open]:not(:has(> details[open])) {
  display: inline;
}

.nb-root .expr[open]:not(:has(> details[open])) > * {
  display: inline;
}

.nb-root .expr[open] > summary .op::before {
  content: var(--bracket-open);
  color: var(--punctuation);
  display: inline;
}

.nb-root .expr[open]::after {
  content: var(--bracket-close);
  color: var(--punctuation);
}


/* ============================================================
 * 6. Expanded expressions with an expanded child
 * Stack all direct children except the operator summary, and
 * indent them to show the nested evaluation structure.
 * The expression's closing bracket remains attached to the
 * parent, outside the indented children.
 * ============================================================ */

.nb-root .expr[open]:has(> details[open]) > :not(summary) {
  display: block;
  margin-left: 1.5em;
}

/* Inline expressions — always transparent */
.nb-root .expr:not(:has(> details[open])) {
  background: transparent;
}

/* Expanded expressions with nested expanded content */
.nb-root .expr[open]:has(> details[open]) {
  background: var(--type-bg);
  border-radius: 0.6em;
  padding: 0.25em 0.5em;
  box-shadow: 0 2px 5px rgb(91 70 54 / 10%);
}

/* Collapsed non-expr content — superscript card */
.nb-root details:not([open]):not(.expr) {
  font-size: 0.55em;
  padding: 0.02em 0.25em;
  margin-left: 0.2em;
  line-height: 1.2;
  border-radius: 0.25em;
  box-shadow: 0 1px 2px rgb(0 0 0 / 15%);
  vertical-align: super;
  width: fit-content;
}

/* Keep the result summary compact */
.nb-root .expr > details:not([open]) > summary {
  display: inline;
  list-style: none;
}

.nb-root .expr > details > summary::-webkit-details-marker {
  display: none;
}

.nb-root .expr > details > summary {
  list-style: none;
}

/*
 * ExprWiz — Evaluation states
 *
 * Runtime states: pending, success, failure, aborted.
 * The idle state is represented by the absence of a status marker.
 */

/* 1. State colors */

:root {
  --expr-state-pending: oklch(53% 0.13 255);
  --expr-state-success: oklch(48% 0.13 150);
  --expr-state-failure: oklch(51% 0.17 28);
  --expr-state-aborted: oklch(53% 0.09 72);
}

/* 2. Shared status marker */
details.expr > summary::before {
  display: inline-block;
  margin-inline-end: 0.4rem;

  font-family: var(--expr-font, sans-serif);
  font-size: 0.7em;
  font-weight: 700;
  line-height: 1;

  vertical-align: sub;
} 

/* 3. Pending */

details.expr[data-expr-state="pending"] > summary::before {
  content: "⌛";
  color: var(--expr-state-pending);

  animation: expr-hourglass-turn 2.4s ease-in-out infinite;
}

/* 4. Failure */

details.expr[data-expr-state="failure"] > summary::before {
  content: "✗";
  color: var(--expr-state-failure)!important;
}

/* 5. Aborted */

details.expr[data-expr-state="aborted"] > summary::before {
  content: "✋";
  color: var(--expr-state-aborted);
}

/* 6. Pending glyph animation */

@keyframes expr-hourglass-turn {
  0%, 35% {
    transform: rotate(0deg);
  }

  50%, 100% {
    transform: rotate(180deg);
  }
}

/* 7. Respect reduced-motion preferences */

@media (prefers-reduced-motion: reduce) {
  details.expr[data-expr-state="pending"]::before {
    animation: none;
  }
}