/* The documentation navigation set: the site tree, the page contents, and the
 * pager between documents.
 *
 * All three are <nav> landmarks, which is why each one's name is a linter
 * error rather than a suggestion: a page with three unnamed navs gives a
 * screen-reader user three identical entries in the landmark list.
 */

@layer ulex.components {

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

  :where(nav[data-ulex-nav-tree]) ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }
  /* Nesting is an indent on the child list, so depth costs one rule rather
     than one rule per level. */
  nav[data-ulex-nav-tree] ul ul {
    margin-inline-start: var(--ulex-space-3);
    border-inline-start: 1px solid var(--ulex-edge-subtle);
    padding-inline-start: var(--ulex-space-2);
  }

  nav[data-ulex-nav-tree] :is(a, summary) {
    display: flex;
    align-items: center;
    min-block-size: var(--ulex-target-min);
    padding-inline: var(--ulex-space-2);
    font-size: var(--ulex-text-8);
    color: var(--ulex-text-dim);
    text-decoration: none;
    border-radius: var(--ulex-radius-sm);
  }
  nav[data-ulex-nav-tree] summary { cursor: pointer; font-weight: var(--ulex-weight-medium); }
  /* A tree's branches are <details>, which the accordion also claims. In a
     tree they are structure, not panels, so the accordion's box comes off. */
  nav[data-ulex-nav-tree] details {
    border: 0;
    border-radius: 0;
    background: none;
  }
  nav[data-ulex-nav-tree] details > summary { border: 0; padding-block: 0; }
  nav[data-ulex-nav-tree] :is(a, summary):hover {
    background: var(--ulex-surface-hi);
    color: var(--ulex-text);
  }
  nav[data-ulex-nav-tree] a[aria-current="page"] {
    color: var(--ulex-accent);
    background: var(--ulex-surface-hi);
    font-weight: var(--ulex-weight-medium);
  }

  /* ---------- contents, with scroll-spy ---------- */

  :where(nav[data-ulex-toc]) {
    position: sticky;
    inset-block-start: calc(var(--ulex-nav-h) + var(--ulex-space-4));
    max-block-size: calc(100dvh - var(--ulex-nav-h) - var(--ulex-space-8));
    overflow-y: auto;
    font-size: var(--ulex-text-8);
  }
  nav[data-ulex-toc] ul { margin: 0; padding: 0; list-style: none; }
  nav[data-ulex-toc] ul ul { margin-inline-start: var(--ulex-space-3); }

  nav[data-ulex-toc] a {
    display: block;
    padding: 0.25rem var(--ulex-space-2);
    color: var(--ulex-text-subtle);
    text-decoration: none;
    /* The trail down the side of the contents, which the current entry
       brightens. A border rather than a background, so the indent still
       reads as hierarchy. */
    border-inline-start: 2px solid var(--ulex-edge-subtle);
  }
  nav[data-ulex-toc] a:hover { color: var(--ulex-text); }
  nav[data-ulex-toc] a[aria-current="true"] {
    color: var(--ulex-accent);
    border-inline-start-color: var(--ulex-accent);
  }

  /* ---------- the pager ---------- */

  :where(nav[data-ulex-pager]) {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ulex-space-3);
    margin-block-start: var(--ulex-space-8);
    padding-block-start: var(--ulex-space-4);
    border-block-start: 1px solid var(--ulex-edge-subtle);
  }
  nav[data-ulex-pager] a {
    flex: 1 1 12rem;
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    min-block-size: var(--ulex-target-min);
    padding: var(--ulex-space-2) var(--ulex-space-3);
    color: var(--ulex-text);
    text-decoration: none;
    border: 1px solid var(--ulex-edge-subtle);
    border-radius: var(--ulex-radius-md);
  }
  nav[data-ulex-pager] a:hover { border-color: var(--ulex-edge-control); }
  /* "Next" sits at the end and reads from the right, which is the one place
     in the library where alignment carries meaning rather than taste. */
  nav[data-ulex-pager] a[rel="next"] { text-align: end; }
  nav[data-ulex-pager] a > span {
    font-size: var(--ulex-text-8);
    color: var(--ulex-text-subtle);
  }
}
/* Admonition -- a titled callout that is part of the document.
 *
 * The difference from alert is not visual, it is temporal. An alert announces
 * something that just happened and is a live region; an admonition was always
 * on the page, and announcing it would interrupt the reader with prose they
 * were going to reach anyway. So this carries no role and no aria-live, and
 * the linter does not offer it the live-region rule at all.
 *
 * On a <details> it collapses, and the open state is the platform's.
 */

@layer ulex.components {

  :where([data-ulex-admonition]) {
    --_ink: var(--ulex-text-dim);

    display: block;
    margin-block: var(--ulex-space-4);
    padding: var(--ulex-space-3) var(--ulex-space-4);

    background: color-mix(in srgb, var(--_ink) var(--ulex-fill-soft-mix), var(--ulex-surface));
    color: var(--ulex-text);
    border: 1px solid var(--ulex-edge-subtle);
    /* The tone as a stripe. It is never the only channel -- the title says
       which kind it is in words, and the linter requires the title. */
    border-inline-start: 3px solid var(--_ink);
    border-radius: var(--ulex-radius-md);
  }

  [data-ulex-admonition-title] {
    display: flex;
    align-items: center;
    gap: var(--ulex-space-2);
    margin: 0 0 var(--ulex-space-2);
    font-size: var(--ulex-text-7);
    font-weight: var(--ulex-weight-semibold);
    color: var(--_ink);
  }

  /* As a <summary> the title is also the control, so it takes the target
     floor and a pointer. */
  summary[data-ulex-admonition-title] {
    min-block-size: var(--ulex-target-min);
    cursor: pointer;
    margin-block-end: 0;
  }
  details[data-ulex-admonition][open] > [data-ulex-admonition-title] {
    margin-block-end: var(--ulex-space-2);
  }

  [data-ulex-admonition] > :last-child { margin-block-end: 0; }
}
/* Code block -- a <pre><code> with a copy button and optional line numbers.
 *
 * Line numbers are a CSS counter on the wrapper, never markup. A number that
 * lives in the DOM is a number that lands in the clipboard, which is the most
 * common defect in a documentation code block and the reason this is worth a
 * component rather than a page-level style.
 *
 * The <pre> is focusable, because a block that scrolls must be scrollable by
 * keyboard (2.1.1). That is also why the copy button is not the only way to
 * get at long lines.
 */

@layer ulex.components {

  :where([data-ulex-code]) {
    position: relative;
    margin-block: var(--ulex-space-4);
    background: var(--ulex-surface);
    border: 1px solid var(--ulex-edge-subtle);
    border-radius: var(--ulex-radius-md);
    overflow: hidden;
  }

  [data-ulex-code] > pre {
    margin: 0;
    padding: var(--ulex-space-3) var(--ulex-space-4);
    /* 1.4.10 -- the block scrolls, the page never does. */
    overflow-x: auto;
    font-family: var(--ulex-font-mono);
    font-size: var(--ulex-text-8);
    line-height: 1.5;
  }
  [data-ulex-code] > pre:focus-visible {
    outline: var(--ulex-ring-width) solid var(--ulex-ring);
    outline-offset: calc(var(--ulex-ring-offset) * -1);
  }

  [data-ulex-code-copy] {
    position: absolute;
    inset-block-start: var(--ulex-space-2);
    inset-inline-end: var(--ulex-space-2);
    min-inline-size: var(--ulex-target-min);
    min-block-size: var(--ulex-target-min);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding-inline: var(--ulex-space-2);

    font: inherit;
    font-size: var(--ulex-text-8);
    color: var(--ulex-text-subtle);
    background: var(--ulex-surface-hi);
    border: 1px solid var(--ulex-edge-subtle);
    border-radius: var(--ulex-radius-sm);
    cursor: pointer;
  }
  [data-ulex-code-copy]:hover { color: var(--ulex-text); }

  /* ---------- highlighting ----------
     Set by src/js/45-highlight.js. Every colour is a tone token that
     contrast.mjs verifies at 4.5:1 (7:1 at AAA) on every surface, so there is
     no palette of its own to verify and none that can drift. Comments are the
     quietest thing in a block, so they take the subtle text level and an
     italic as a second, non-colour channel. */
  [data-ulex-token="keyword"]  { color: var(--ulex-tone-accent); font-weight: var(--ulex-weight-medium); }
  [data-ulex-token="string"]   { color: var(--ulex-tone-success); }
  [data-ulex-token="number"]   { color: var(--ulex-tone-warning); }
  [data-ulex-token="function"] { color: var(--ulex-tone-info); }
  [data-ulex-token="tag"]      { color: var(--ulex-tone-accent); }
  [data-ulex-token="attr"]     { color: var(--ulex-tone-info); }
  [data-ulex-token="comment"]  { color: var(--ulex-text-subtle); font-style: italic; }

  /* ---------- line numbers ---------- */

  [data-ulex-code="numbered"] > pre > code {
    counter-reset: ulex-line;
    display: block;
  }
  [data-ulex-code="numbered"] > pre > code > span {
    counter-increment: ulex-line;
    display: block;
  }
  [data-ulex-code="numbered"] > pre > code > span::before {
    content: counter(ulex-line);
    display: inline-block;
    inline-size: 2.5ch;
    margin-inline-end: var(--ulex-space-3);
    text-align: end;
    color: var(--ulex-text-subtle);
    /* Not text as far as selection or the clipboard is concerned. */
    user-select: none;
  }

}
