/* ---- Help tooltips ("?" button + bubble) ------------------------------------------------
   One pattern site-wide: the tip() Jinja global (app/tooltips.py) draws the markup, the words
   come from app/help_text.py, static/js/tooltips.js shows and places the bubble. Paste this
   block at the end of the site's main stylesheet (or load it after it) and point the --tip-*
   tokens at the theme's own tokens. Colours are tokens only, so the dark theme follows.

   Alignment (the "?" must sit on its text's line, never float):
   * INLINE (default): the mark is the last thing inside the element it explains -- a heading,
     a <th>, a <legend>, a figure label, a <figcaption>. .tip is display: inline (never
     inline-flex: an atomic inline box after text is a line-break opportunity, so the "?" would
     wrap alone), white-space: nowrap, vertical-align: middle, and .tip::before is a WORD JOINER
     that glues it to the last word. The circle is sized in em of the text it follows, so it fits
     a small table header and a large heading alike.
   * ANCHOR (form labels, buttons and links, any flex or grid row): wrap the label (or button) and
     the mark in <span class="tip-anchor">; the row aligns on the first baseline, so the circle
     sits on the label's first line however the label wraps. A label that may wrap with the mark
     after its LAST word takes .tip-anchor--wrap (display: block, the mark inline after the text).
   * Never a "?" on a row of its own, never a direct child of a space-between flex row, never
     inside a label, summary, link or button.
   ------------------------------------------------------------------------------------------ */
:root {
  --tip-ink: var(--ink);
  --tip-muted: var(--slate);
  --tip-face: var(--paper);
  --tip-bubble: var(--paper);
  --tip-rule: var(--slate);
  --tip-accent: var(--brand-600);
  --tip-shadow: 0 6px 18px rgb(0 0 0 / 0.18);
}
/* Dark shadow, always: the explicit theme switch (data-theme="dark"). Every project keeps this rule. */
:root[data-theme="dark"] { --tip-shadow: 0 6px 18px rgb(0 0 0 / 0.5); }

.tip {
  position: relative;
  display: inline;                 /* an atomic box after text is a break opportunity (the "?" wrapped alone); an inline one with the word joiner is not */
  vertical-align: middle;
  white-space: nowrap;
  margin-inline-start: 0.25em;
  line-height: 1;
  font-weight: 400;
  font-style: normal;
  text-transform: none;
  letter-spacing: normal;
}
.tip::before { content: "\2060"; }   /* WORD JOINER: no line break between the last word and the "?" */
/* A mark that still wraps alone (the alignment check finds one): keep the last word with it:
   Last <span class="tip-keep">seen + the tip() call</span> */
.tip-keep { white-space: nowrap; }
.tip-anchor {                       /* ANCHOR: the label (or button), then the mark, in one row */
  display: inline-flex;
  align-items: baseline;
  max-inline-size: 100%;
}
.tip-anchor--block { display: flex; }   /* a block heading row: <div class="tip-anchor tip-anchor--block"> */
.tip-anchor--wrap { display: block; }   /* a label that may wrap: the mark follows its last word, inline */
.tip-anchor > :first-child { min-inline-size: 0; }
.tip-anchor > .tip { align-self: baseline; flex: none; }

.tip-btn {
  position: relative;               /* so ::after (the hit area) centres on the button */
  top: -0.08em;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  vertical-align: middle;
  height: 1.6em;                    /* of its own font-size below: 18.4px beside 16px text, 15.4px beside 12px text */
  aspect-ratio: 1 / 1;
  padding: 0;
  border: 1px solid var(--tip-rule);
  border-radius: 50%;
  background: var(--tip-face);
  color: var(--tip-muted);
  font: 700 max(0.6rem, 0.72em)/1 var(--body);
  cursor: help;
  flex: none;
}
/* A larger touch target than the drawn circle (about 32px), without moving the layout. */
.tip-btn::after {
  content: "";
  position: absolute;
  inset: -0.45rem;
}
.tip-btn:hover,
.tip.is-open .tip-btn {
  color: var(--tip-ink);
  border-color: var(--tip-accent);
}
.tip-btn:focus-visible {
  outline: 2px solid var(--tip-accent);
  outline-offset: 2px;
}

.tip-body {
  position: absolute;
  z-index: 1000;
  left: 50%;
  bottom: calc(100% + 0.5rem);
  transform: translateX(-50%);
  inline-size: max-content;
  max-inline-size: min(20rem, calc(100vw - 1rem));
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--tip-rule);
  border-radius: 6px;
  background: var(--tip-bubble);
  color: var(--tip-ink);
  box-shadow: var(--tip-shadow);
  font-family: var(--body);   /* never the heading's or a table's font */
  font-size: 0.8125rem;
  font-weight: 400;
  font-style: normal;
  line-height: 1.45;
  text-align: start;
  white-space: normal;
  text-transform: none;
  letter-spacing: normal;
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.12s ease;
}
.tip-line { display: block; }
.tip-line + .tip-line, .tip-line + .tip-list, .tip-list + .tip-line { margin-block-start: 0.35rem; }
.tip-list { margin: 0.35rem 0 0; padding-inline-start: 1.1rem; list-style: disc; }
.tip-list li + li { margin-block-start: 0.15rem; }
.tip-body--below { bottom: auto; top: calc(100% + 0.5rem); }
/* Placed by the script: fixed to the viewport so an overflow: hidden tile cannot clip it. */
.tip-body--fixed { position: fixed; bottom: auto; transform: none; }
.tip.is-open .tip-body {
  visibility: visible;
  opacity: 1;
  pointer-events: auto;
}
/* A closed bubble takes no space (hidden bubbles once widened a whole page). The script adds .is-open before it measures. */
:root.tips-ready .tip:not(.is-open) .tip-body { display: none; }
/* No script: hover and keyboard focus still show the bubble in place. */
:root:not(.tips-ready) .tip:hover .tip-body,
:root:not(.tips-ready) .tip:focus-within .tip-body {
  visibility: visible;
  opacity: 1;
}
@media (prefers-reduced-motion: reduce) { .tip-body { transition: none; } }
@media (forced-colors: active) { .tip-btn, .tip-body { border-color: CanvasText; } }
@media print { .tip { display: none; } }
