/* dterm: nanofil's Prolog drawn as terms (dterm.pl). After the luv wiki's
   dexp boxes: a compound's arguments sit in a box whose side borders are
   its parentheses, and boxes flow and wrap with the page. */

:root {
  /* The type of terms; nanofil/workbench/ compares the choices. */
  --paren-ink: 34%;
  --paren: color-mix(in srgb, var(--ink) var(--paren-ink), transparent);
  --paren-stroke: 0.1em;     /* at the middle of the bow */
  --paren-curve: 0.3em;      /* how far its ends bow in */
  --paren-inside: 0.19em;    /* from a parenthesis to what it holds */
  --paren-outside: 0.07em;   /* from a functor to its parenthesis */
  --paren-grow: 0.06em;      /* above and below, per box nested inside */
  --bracket-ink: 60%;
  --bracket: color-mix(in srgb, #2f6f8f var(--bracket-ink), transparent);
  --bracket-arm: 0.2em;
  --bar-space: 0.1em;
  --sep-ink: 52%;            /* commas */
  --sep: color-mix(in srgb, var(--ink) var(--sep-ink), transparent);
  --hang: 1.5em;             /* continuation lines, without dterm.js */
  --indent: 1.5em;           /* dterm.js: a hung term's lines, past its start */
  --ribbon: 34em;            /* dterm.js: the most a term sets on one line */
  --var: #5a3f9a;
  --atom: #24566e;
  --num: #8a6510;
  --str: #3d7a3d;
  --call: var(--accent);
  --note: #5c666d;
}

main.dterm-page {
  display: grid;
  grid-template-columns: 14rem minmax(0, 1fr);
  gap: clamp(1.5rem, 3vw, 3rem);
}

/* The sidebar: files, and the sections and predicates of this one. */

.dterm-nav { font-size: 0.8rem; }
.dterm-nav > ul > li { margin: 0.12rem 0; }
.dterm-nav li.current > a { color: var(--accent); font-weight: 700; opacity: 1; }
.dterm-nav li.current > ul {
  margin: 0.3rem 0 0.8rem;
  padding-left: 0.6rem;
  border-left: 2px solid var(--rule);
}
.dterm-nav li.current li { margin: 0.1rem 0; }
.dterm-nav .nav-section { margin-top: 0.6rem !important; font-weight: 700; }
.dterm-nav .nav-pred a { opacity: 0.7; overflow-wrap: anywhere; }

/* The article. */

article.dterm { min-width: 0; max-width: 72rem; }
article.dterm h2 {
  margin: 2.8rem 0 1rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--rule);
  scroll-margin-top: 2.6rem;
}

.dterm .prose { max-width: 44rem; }
.dterm .prose p { margin: 0 0 0.55rem; text-align: left; hyphens: manual; }
.dterm .prose p:last-child, .dterm .prose ul:last-child { margin-bottom: 0; }
.dterm .prose ul { margin: 0.2rem 0 0.6rem; }
.dterm .prose pre {
  margin: 0.4rem 0 0.7rem;
  padding: 0.5rem 0.8rem;
  font-size: 0.8rem;
  border-radius: 4px;
}
.dterm .prose code { font-size: 0.82em; }

/* A module header's Markdown (dterm.pl's blocks/2): headings, tables,
   terms drawn as in the code, and box diagrams. Inline code that reads
   as a term is set as one, in the type of the code. */
.dterm .prose .prose-h {
  margin: 1.5rem 0 0.45rem;
  font-size: 1.02rem;
  letter-spacing: 0;
}
.dterm .prose h4.prose-h { margin-top: 1.1rem; font-size: 0.92rem; color: var(--muted); }
.dterm .prose code.term { font: inherit; font-size: 0.96em; background: none; padding: 0; }
.dterm .prose code.term .c, .dterm .prose code.term .args, .dterm .prose code.term .arg { white-space: nowrap; }
table.prose-table {
  display: table;
  width: auto;
  max-width: 100%;
  margin: 0.4rem 0 0.9rem;
  border-collapse: collapse;
  font-size: 0.9rem;
  line-height: 1.4;
}
table.prose-table th {
  padding: 0 1.1rem 0.25rem 0;
  border-bottom: 1px solid var(--rule);
  color: var(--muted);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-align: left;
  text-transform: uppercase;
}
table.prose-table td {
  padding: 0.28rem 1.1rem 0.28rem 0;
  border-bottom: 1px solid color-mix(in srgb, var(--rule) 55%, transparent);
  vertical-align: baseline;
}
table.prose-table td:first-child { white-space: nowrap; }
table.prose-table tr:last-child td { border-bottom: 0; }
.dterm .prose .prose-terms { margin: 0.4rem 0 0.8rem 1rem; }
.dterm .prose .prose-terms .clause { margin: 0.15rem 0; }
.dterm .prose pre.fence.diagram {
  background: none;
  padding: 0.3rem 0;
  line-height: 1.1;
  font-size: 0.78rem;
}
.dterm a.ref code { color: var(--accent); }

.dterm .lede { font-size: 1.02rem; margin-bottom: 2rem; }
.dterm .prose-block {
  margin: 1.4rem 0;
  padding-left: 0.8rem;
  border-left: 2px solid var(--rule);
  color: var(--note);
  font-size: 0.95rem;
}

/* Module header and imports. */

.module-decl, .uses {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.3rem 0.6rem;
  margin: 0.3rem 0;
  font-size: 0.92rem;
}
.module-decl { margin-bottom: 0.6rem; }
.module-decl > .f { font-size: 1.05rem; }
.exports { display: flex; flex-wrap: wrap; gap: 0.15rem 0.5rem; flex-basis: 100%; padding-left: 1rem; }
.exports .label { color: var(--muted); font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.05em; }
a.export { color: var(--ink); font-size: 0.85rem; }
a.export:hover { color: var(--accent); }
.dterm .kw {
  color: var(--muted);
  font-size: 0.78em;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.uses .lib { color: var(--atom); }
.uses .lib + .lib::before { content: ""; }

/* A predicate: its documentation, then its clauses. */

section.pred {
  margin: 1.6rem 0;
  scroll-margin-top: 2.6rem;
}
section.pred:target > .doc { box-shadow: -0.9rem 0 0 -0.65rem var(--accent); }

.doc { margin-bottom: 0.6rem; }
.doc .sig {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5em;
  font-size: 1.02rem;
}
.doc .sig .f.def { font-weight: 750; }
.doc .prose { margin-top: 0.3rem; font-size: 0.95rem; }
.arg:has(> .mode) { white-space: nowrap; }
.mode {
  color: var(--muted);
  font-weight: 700;
  font-size: 0.8em;
  margin-right: 0.08em;
}
.det {
  color: var(--muted);
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 0.05rem 0.4rem;
  border: 1px solid var(--rule);
  border-radius: 1rem;
}

/* Clauses: head over goals. A head or a goal is a line of text; when it
   is too long for its line it breaks after a comma or a wide operator, and
   its continuation lines hang under the first. */

.clause {
  position: relative;
  margin: 0.55rem 0;
  font-size: 0.95rem;
  line-height: 1.5;
}
.clause > .head, .goal, .o, .c, .args, .l, .arg, .paren, .braces, .not, .qualified {
  min-width: 0;
}
.clause > .head, div.goal, .clause.item, details.clause > summary {
  padding-left: var(--hang);
  text-indent: calc(-1 * var(--hang));
}
:is(.clause > .head, .clause.item, details.clause > summary) *, div.goal :not(.goal) { text-indent: 0; }
div.goal:has(> div) { padding-left: 0; text-indent: 0; }
.neck { color: var(--muted); font-weight: 600; }
.clause.dcg > .head .neck { color: var(--atom); }
.clause > .goals {
  margin-left: 1.5em;
}
.goals {
  display: grid;
  grid-template-columns: minmax(0, max-content);
  row-gap: 0.12em;
}

/* Line numbers in the margin, quiet until hovered. */

a.ln {
  position: absolute;
  right: 100%;
  margin-right: 0.6rem;
  color: var(--muted);
  font: 500 0.68rem/2.1 var(--mono-font);
  opacity: 0;
  transition: opacity 0.12s;
}
.clause:hover > .head > a.ln, tr:hover a.ln { opacity: 0.8; }
table.facts a.ln { position: static; margin: 0; }

/* Terms, set as text. A compound is its functor and an inline box whose
   side borders are its parentheses: the line breaks it as it breaks a
   parenthesis in prose, the opening one on the first line and the closing
   one after the last argument, and each border is as tall as the type.
   Commas are text, with a space after them; wide operators have a space
   on each side, and a line breaks only after them. */

.c, .o, .qualified, .not, .args, .arg, .l, .paren, .braces { display: inline; }
.f { color: var(--atom); }
.f.call { color: var(--call); }
a.f.call:hover { text-decoration: underline; }
.f.def { color: var(--ink); font-weight: 700; }
.f.pat { font-weight: 600; }
.a { color: var(--atom); }
.n { color: var(--num); font-variant-numeric: tabular-nums; }
.s { color: var(--str); white-space: pre-wrap; }
.v { color: var(--var); }
.v sub { font-size: 0.7em; line-height: 0; }
.v.anon { color: var(--muted); }
.v.lit { background: color-mix(in srgb, var(--var) 14%, transparent); border-radius: 3px; }
.module { color: var(--muted); }
.cut { color: var(--accent); font-weight: 800; }

.op { color: color-mix(in srgb, var(--ink) 62%, transparent); }
.op.neg { color: var(--accent); font-weight: 700; margin-right: 0.1em; }
.o.pre > .op { margin-right: 0.04em; }

/* Parentheses: a hairline that bows like the glyph, thickest at its
   middle. A box with boxes inside stands a little taller, as outer
   delimiters are set bigger in mathematics. */

.args, .paren, .l, .braces {
  padding: 0 var(--paren-inside);
  border: 0 solid var(--paren);
  border-width: 0 var(--paren-stroke);
  border-radius: var(--paren-curve) / 50%;
}
.c > .args { margin-left: var(--paren-outside); }
:is(.args, .l, .paren):has(:is(.args, .l, .paren)) {
  padding-block: var(--paren-grow);
}
:is(.args, .l, .paren):has(:is(.args, .l, .paren) :is(.args, .l, .paren)) {
  padding-block: calc(2 * var(--paren-grow));
}
:is(.args, .l, .paren):has(:is(.args, .l, .paren) :is(.args, .l, .paren) :is(.args, .l, .paren)) {
  padding-block: calc(3 * var(--paren-grow));
}

/* Brackets are square, with arms, so a list never reads as a call. */
.l {
  border-color: var(--bracket);
  border-radius: 0;
  background:
    linear-gradient(var(--bracket) 0 0) left top / var(--bracket-arm) var(--paren-stroke) no-repeat border-box,
    linear-gradient(var(--bracket) 0 0) left bottom / var(--bracket-arm) var(--paren-stroke) no-repeat border-box,
    linear-gradient(var(--bracket) 0 0) right top / var(--bracket-arm) var(--paren-stroke) no-repeat border-box,
    linear-gradient(var(--bracket) 0 0) right bottom / var(--bracket-arm) var(--paren-stroke) no-repeat border-box;
}
.l.empty { padding: 0; border-width: 0; background: none; color: var(--bracket); }
.braces { border-style: dotted; border-width: 0 2px; }
.sep { color: var(--sep); }
.tailbar { color: var(--bracket); margin: 0 var(--bar-space); }
.pushback { opacity: 0.8; }
.terminals .l { background-color: color-mix(in srgb, var(--bracket) 8%, transparent); }

/* A box with a block inside (a conjunction passed to findall/3, say)
   lays out as boxes do, wrapping its arguments as items. */
.args:has(> .arg > .block), .not:has(> .block) {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 0.3em;
}
.args:has(> .arg > .block) { border-radius: 0.55em; }
.arg:has(> .block) { display: inline-flex; align-items: baseline; }

/* dterm.js prints a head or goal (class zt) at the width it has: its
   lines start flush, break at <br class="zbr">, and continue past an
   empty .zin as wide as the line's indent. */
:is(.clause > .head, div.goal, .clause.item, details.clause > summary).zt { padding-left: 0; text-indent: 0; }
.zin { display: inline-block; }
/* While dterm.js sees whether a conditional fits as a table. */
.cases.ztry { width: max-content; }
.cases.ztry .goal { white-space: nowrap; }

/* An assembly line's term stays on its line; the table scrolls instead. */
table.asm td.term { white-space: nowrap; }

/* Blocks inside bodies: conjunctions in parentheses, DCG {} goals,
   conditionals and disjunctions. */

.block {
  display: grid;
  padding: 0.05em 0.5em;
  border-radius: 0.7em;
}
.braces.block { padding: 0.05em 0.5em; }

.cases, .alts {
  display: grid;
  padding: 0.1em 0.55em;
  border: 0 solid var(--paren);
  border-width: 0 1.5px;
  border-radius: 0.7em;
}
.cases {
  grid-template-columns: minmax(0, max-content) max-content minmax(0, max-content);
  column-gap: 0.6em;
}
.case { display: contents; }
.case > div { padding: 0.15em 0; }
.case + .case > div:not(.arrow) { border-top: 1px solid var(--rule); }
.case > .arrow { color: var(--accent); font-weight: 700; }
.case > .cond { min-width: 0; }
.case.plain > .cond { text-align: right; }
.alts { grid-template-columns: minmax(0, max-content); }

/* A chain with conditionals or conjunctions in its branches (dterm.pl's
   alt_nests/1, alt_conj/1), and one too wide for its place (dterm.js, or
   a narrow screen without it), is a flow: each condition, then its
   consequence under it. */
.cases.stack { grid-template-columns: max-content minmax(0, max-content); column-gap: 0.8em; }
.cases.stack > .case {
  display: grid;
  grid-column: 1 / -1;
  grid-template-columns: subgrid;
  align-items: baseline;
}
.cases.stack > .case + .case { border-top: 1px solid var(--rule); }
.cases.stack > .case > :is(.cond, .then) { display: contents; }
.cases.stack > .case > .arrow { display: none; }
.cases.stack > .case > * > .goals { grid-column: 2; padding: 0.1em 0; }
/* The labels share a column, so every branch starts at the same place. */
.cases.stack > .case:not(.plain) > .cond::before { content: "if"; }
.cases.stack > .case + .case:not(.plain) > .cond::before { content: "else if"; }
.cases.stack > .case:not(.plain) > .then::before { content: "then"; }
.cases.stack > .case > :is(.cond, .then)::before, .cases.stack > .case.plain > .cond .kw {
  grid-column: 1;
  color: var(--muted); font-size: 0.72rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.06em; white-space: nowrap;
}
.cases.stack > .case.plain > .cond:has(.kw:empty) { display: none; }
/* The labels are the structure: no bars, and all set alike, flush left
   on the first line of their branch. */
.cases.stack > .case.plain > .cond { text-align: left; }
.cases.stack .kw { justify-self: start; }
@media (max-width: 700px) {
  /* A run of a term with nowhere to break (a functor, its parenthesis
     and a first argument, or a long atom) breaks where it must rather
     than push the page sideways. */
  .clause > .head, .goal, .examples td, .sig, .a, .s { overflow-wrap: anywhere; }
  .dterm .prose pre { max-width: 100%; overflow-x: auto; }
  /* An example whose goal is a block puts its answer on the next row. */
  .examples td.goal:has(.block) { flex-basis: 100%; }
  /* Without dterm.js, a conditional is a column of its parts. */
  html:not(.zp) .cases:not(.stack), html:not(.zp) .cases:not(.stack) > .case { display: block; }
  html:not(.zp) .cases:not(.stack) > .case > .arrow { display: none; }
}
.alts > .or {
  margin: 0.1em 0;
  border-top: 1px dashed var(--rule);
  color: var(--muted);
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  line-height: 1.4;
}

/* Comments among the goals. */

.aside { margin-left: 0.6em; }
.note, .aside {
  color: var(--note);
  font-style: italic;
  font-size: 0.88em;
}
.note { padding-left: 0.6em; border-left: 2px solid var(--rule); max-width: 40rem; }
.aside::before { content: "— "; opacity: 0.6; }
.notes.trailing { margin-left: 1.5em; }
.prose.between, .between .prose {
  color: var(--note);
  font-size: 0.9rem;
  font-style: italic;
  margin: 0.6rem 0 0.4rem;
}

/* A predicate of facts is a table. */

table.facts {
  display: table;
  margin: 0.4rem 0 0.8rem;
  font-size: 0.92rem;
  line-height: 1.45;
}
/* On a phone a table of facts scrolls inside itself. */
@media (max-width: 700px) {
  table.facts { display: block; max-width: 100%; overflow-x: auto; }
}
table.facts caption {
  caption-side: top;
  text-align: left;
  padding-bottom: 0.2rem;
}
table.facts td {
  padding: 0.18rem 1.1rem 0.18rem 0;
  vertical-align: baseline;
}
table.facts td.ln { padding-right: 0.6rem; }
table.facts tr.note td { color: var(--note); font-style: italic; font-size: 0.88em; border-bottom: 0; padding-top: 0.6rem; }

.facts.set {
  display: flex;
  align-items: baseline;
  gap: 0.4em;
  margin: 0.4rem 0 0.8rem;
  font-size: 0.95rem;
}
.facts.set > .args { display: inline-flex; flex-wrap: wrap; column-gap: 0.9em; row-gap: 0.1em; }

/* The index. */

.modules {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
  gap: 0.9rem;
}
.module-card .meta { color: var(--muted) !important; font-size: 0.78rem !important; }
.module-card .summary { color: var(--ink) !important; opacity: 0.8; }

/* Variable occurrences, highlighted together on hover (dterm.js). */

.v.lit { outline: 1px solid color-mix(in srgb, var(--var) 40%, transparent); }

@media (max-width: 900px) {
  main.dterm-page { display: block; }
  .clause > .goals { margin-left: 0.9em; }
  a.ln { display: none; }
}

/* A predicate and its cross references: calls and callers beside it on
   wide screens, under its documentation otherwise. */

section.pred { display: grid; grid-template-columns: minmax(0, 1fr); }
.pred-main { min-width: 0; }
aside.xref {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 1.4rem;
  margin: 0.2rem 0 0.4rem;
  font-size: 0.78rem;
  line-height: 1.35;
}
.xref-group { min-width: 0; }
.xref-title, .examples-title {
  color: var(--muted);
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.xref-title .count, .examples-title .count { font-weight: 500; letter-spacing: 0; text-transform: none; }
aside.xref ul { list-style: none; margin: 0.1rem 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0 0.7em; }
aside.xref li { margin: 0; }
aside.xref a { color: var(--ink); opacity: 0.8; }
aside.xref a:hover { color: var(--accent); opacity: 1; text-decoration: none; }
aside.xref .file { color: var(--muted); font-size: 0.9em; }

@media (min-width: 1500px) {
  section.pred:has(> aside.xref) { grid-template-columns: minmax(0, 1fr) 13rem; column-gap: 2rem; }
  aside.xref {
    display: block;
    padding-left: 0.9rem;
    border-left: 1px solid var(--rule);
    margin: 0.3rem 0;
    align-self: start;
  }
  aside.xref ul { display: block; }
  aside.xref li { margin: 0.08rem 0; overflow-wrap: anywhere; }
  .xref-group + .xref-group { margin-top: 0.7rem; }
}

/* doc/3: signature, the arguments as a table, prose, citations, and the
   examples with what they gave when the page was built. */

.dterm-doc { margin-bottom: 0.8rem; }
.dterm-doc > .sig + .sig { margin-top: -0.1rem; opacity: 0.85; }
table.modes {
  display: table;
  margin: 0.4rem 0 0.5rem;
  font-size: 0.9rem;
  line-height: 1.35;
}
table.modes td { padding: 0.12rem 0.9rem 0.12rem 0; border-bottom: 0; vertical-align: baseline; }
table.modes td.dir { color: var(--muted); font-size: 0.78em; font-weight: 600; white-space: nowrap; }
table.modes td.desc { color: color-mix(in srgb, var(--ink) 85%, transparent); }
.dterm-doc .prose { margin-top: 0.35rem; }

.cites { display: flex; flex-wrap: wrap; gap: 0.3rem; margin: 0.45rem 0 0.2rem; }
a.cite, span.cite {
  font-size: 0.74rem;
  font-weight: 600;
  padding: 0.05rem 0.45rem;
  border: 1px solid color-mix(in srgb, var(--accent) 35%, var(--rule));
  border-radius: 1rem;
  color: var(--accent);
}
a.cite .std { color: var(--muted); font-weight: 700; letter-spacing: 0.04em; }
a.cite:hover { background: color-mix(in srgb, var(--accent) 8%, transparent); text-decoration: none; }

.examples {
  margin: 0.55rem 0 0.3rem;
  padding: 0.4rem 0.7rem 0.45rem;
  background: color-mix(in srgb, var(--paper) 96%, var(--str));
  border-radius: 6px;
}
.examples table { display: table; margin: 0.15rem 0 0; font-size: 0.9rem; line-height: 1.45; }
.examples td { padding: 0.08rem 0.6rem 0.08rem 0; border-bottom: 0; vertical-align: baseline; }
.examples td.mark { font-weight: 800; padding-right: 0.5rem; }
.ex.pass td.mark { color: var(--str); }
.ex.fail td.mark { color: var(--accent); }
.ex.fail td.goal { text-decoration: underline wavy var(--accent); }
.examples td.then { color: var(--muted); }
.kw.fails { color: var(--accent); }

/* Several clauses: each numbered, as cases of one definition. */

section.pred.multi .pred-main { counter-reset: clause; }
section.pred.multi .clause { counter-increment: clause; }
section.pred.multi .clause > .head::before {
  content: counter(clause);
  display: inline-block;
  min-width: 1.25em;
  margin-right: 0.5em;
  padding: 0 0.2em;
  color: var(--muted);
  font-size: 0.68rem;
  font-weight: 700;
  line-height: 1.5;
  text-align: center;
  border: 1px solid var(--rule);
  border-radius: 0.3rem;
  vertical-align: 0.15em;
  text-indent: 0;
}
section.pred.multi .clause > .goals { margin-left: 2.6em; }
section.pred.multi .prose.between {
  font-style: normal;
  color: var(--note);
  margin: 0.9rem 0 0.1rem;
}

@media (max-width: 900px) {
  .examples tr { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 0.45em; padding: 0.15rem 0; }
  .examples td { padding: 0; }
  .examples td:empty { display: none; }
}

/* On a phone a header's table scrolls sideways rather than squeezing its
   terms, and its type is a step smaller. */
@media (max-width: 700px) {
  table.prose-table { display: block; overflow-x: auto; font-size: 0.82rem; }
  table.prose-table td { padding-right: 0.8rem; }
}
@media (max-width: 700px) {
  table.prose-table td:first-child { white-space: normal; min-width: 8rem; }
  .dterm .prose table.prose-table code.term .arg { white-space: normal; }
}
