/* The shared design system: components and the token plumbing.
 *
 * No colour is defined here. Colours come from a **theme bundle**
 * (assets/stylesheets/themes.css, generated from themes/*.yaml), and a book's
 * subject tint arrives as --tb-book-* values that the bundle composes in. This
 * file owns everything that is not a theme: the mapping onto Material's
 * variables, the figure and booklet components, and the house typography.
 *
 * See SHAPE.md, "Theme bundles".
 */

:root {
  /* Scheme-independent, and not part of any bundle unless a bundle overrides it. */
  --tb-measure: 70ch;
  --tb-radius: 8px;
  --tb-font-body: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --tb-font-display: "Iowan Old Style", Charter, Georgia, "Times New Roman", serif;
  --tb-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* A book tints its diagrams by setting its accent, unless it sets its own. */
[data-md-color-scheme] {
  --tb-fig-accent: var(--tb-accent);
}

/* Map the tokens onto Material's variable names. Deliberately
 * scheme-independent: anything that differs between light and dark is a token,
 * set by a bundle.
 *
 * Only the variables a component here still reads are declared. The names began
 * as Material's, but the shared stylesheet and the booklet widget read them, and
 * themes.css keys its tokens off `[data-md-color-scheme]`, so the attribute and
 * the names it needs stay. Six Material-only variables were deleted with the
 * renderer — `--md-primary-fg-color--light`, `--md-accent-fg-color`,
 * `--md-typeset-a-color`, `--md-code-bg-color`, `--md-primary-bg-color` and
 * `--md-primary-bg-color--light` — because nothing read them any more.
 *
 * Two of those were fixes, not decoration: the dark-mode link and the header's
 * ink on the accent. Material's palette.css beat the bare
 * `[data-md-color-scheme]` selector at (0,2,0), so both had to be restated at
 * that specificity. Material is gone and nothing consumed them, so the
 * restatement went too. The fixes themselves survive where they are now made:
 * shell.css paints links from `--tb-link` (`a { color: var(--tb-link) }`) and the
 * masthead title from `--tb-ink`, both straight from the bundle with no
 * third-party rule to beat. The Settings dialog's focus ring still names
 * `--md-accent-fg-color` with `--tb-accent` as its fallback — the same value, so
 * it is unchanged. */
[data-md-color-scheme] {
  --md-default-bg-color: var(--tb-paper);
  --md-default-fg-color: var(--tb-ink);
  --md-default-fg-color--light: var(--tb-ink-soft);
  --md-default-fg-color--lighter: var(--tb-ink-lighter);
  --md-default-fg-color--lightest: var(--tb-rule);
  --md-primary-fg-color: var(--tb-accent);
}

/* Typography: the faces themselves are bundle tokens; sizes are shared, so a
 * bundle changes the voice without changing the reading measure. */
.md-typeset {
  font-family: var(--tb-font-body);
  font-size: 1.0625rem; /* ~17px */
  line-height: 1.65;
}

.md-typeset h1,
.md-typeset h2,
.md-typeset h3,
.md-typeset h4 {
  font-family: var(--tb-font-display);
  letter-spacing: -0.01em;
}

/* Measure: 45-90 characters (Butterick); 50-75 optimal (Baymard). */
.md-typeset > p,
.md-typeset > ul,
.md-typeset > ol,
.md-typeset > blockquote {
  max-width: var(--tb-measure);
}

/* Maths is browser-rendered MathML; keep it aligned with the body text. */
.md-typeset math {
  font-size: 1.05em;
}

/* Interactive figures read as instrument panels, not decoration. */
.md-typeset maths-figure {
  display: block;
  max-width: 46rem;
  margin: 1.4rem 0;
  padding: 1rem 1.1rem;
  border: 1px solid var(--md-default-fg-color--lightest);
  border-radius: 6px;
  background: color-mix(in srgb, var(--md-default-bg-color) 92%, var(--md-default-fg-color) 8%);
}

.md-typeset maths-figure figcaption,
.md-typeset maths-figure .caption {
  font-size: 0.9rem;
  color: var(--md-default-fg-color--light);
}

/* Progressive-disclosure hints. */
.md-typeset details {
  max-width: var(--tb-measure);
  margin: 0.6rem 0;
  border: 1px solid var(--md-default-fg-color--lightest);
  border-radius: 6px;
  padding: 0.35rem 0.8rem;
}

.md-typeset details > summary {
  cursor: pointer;
  font-weight: 600;
}

.math-error {
  color: var(--tb-fig-warn);
  font-family: var(--tb-font-mono);
}

/* Figure colours come from the scheme variables above, so every figure adapts to
   dark mode and to a future palette change without editing the figure module. */
.fig-accent {
  fill: var(--tb-fig-accent);
  stroke: var(--tb-fig-accent);
}
.fig-warn {
  fill: var(--tb-fig-warn);
  stroke: var(--tb-fig-warn);
}
.fig-good {
  fill: var(--tb-fig-good);
  stroke: var(--tb-fig-good);
}
.fig-ink {
  fill: currentColor;
  stroke: currentColor;
}
.fig-grid {
  fill: none;
  stroke: var(--tb-fig-grid);
}
.fig-line {
  fill: none;
  stroke: var(--tb-fig-accent);
  stroke-width: 2;
}
.text-accent {
  color: var(--tb-fig-accent);
}
.text-warn {
  color: var(--tb-fig-warn);
}
.text-good {
  color: var(--tb-fig-good);
}

/* ------------------------------------------------------------------ */
/* Formulae & tables booklet                                           */
/* ------------------------------------------------------------------ */

.bk-fab {
  position: fixed;
  right: 1.1rem;
  bottom: 1.1rem;
  z-index: 30;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.6rem 0.9rem;
  border: 1px solid var(--md-primary-fg-color--dark);
  border-radius: 999px;
  background: var(--md-primary-fg-color);
  /* The label is knocked out of the accent fill, so it uses the bundle's
   * dedicated on-accent ink, not the paper: a bundle's paper can sit too close
   * to its own accent to read (omarchy light 4.34:1, gruvbox light 4.40:1). */
  color: var(--tb-accent-ink);
  font: 600 0.9rem/1 system-ui, sans-serif;
  cursor: pointer;
  box-shadow: 0 4px 14px color-mix(in srgb, var(--md-default-fg-color) 22%, transparent);
}
.bk-fab:hover { filter: brightness(1.06); }
.bk-fab [aria-hidden] { font-size: 1.1rem; }
.bk-fab__label { font-size: 0.82rem; }

.bk-panel {
  position: fixed;
  right: 1.1rem;
  bottom: 4.6rem;
  z-index: 31;
  display: flex;
  flex-direction: column;
  width: min(430px, calc(100vw - 2rem));
  height: min(72vh, 660px);
  min-width: 320px;
  min-height: 280px;
  border: 1px solid var(--md-default-fg-color--lightest);
  border-radius: 12px;
  background: var(--md-default-bg-color);
  color: var(--md-default-fg-color);
  box-shadow: 0 12px 40px color-mix(in srgb, var(--md-default-fg-color) 28%, transparent);
  overflow: hidden;
}
.bk-panel[hidden] { display: none; }

.bk-bar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.6rem;
  border-bottom: 1px solid var(--md-default-fg-color--lightest);
  background: var(--md-primary-fg-color);
  color: var(--tb-accent-ink);
  cursor: grab;
  touch-action: none;
}
.bk-bar:active { cursor: grabbing; }
.bk-grip {
  width: 14px;
  height: 14px;
  flex: none;
  background-image: radial-gradient(currentColor 1.2px, transparent 1.2px);
  background-size: 5px 5px;
  opacity: 0.6;
}
.bk-title { margin: 0; font-size: 0.95rem; font-weight: 700; flex: 1; }
.bk-bar__tools { display: flex; align-items: center; gap: 0.4rem; }
.bk-field { font-size: 0.72rem; display: flex; align-items: center; gap: 0.25rem; }
.bk-field select {
  font-size: 0.75rem;
  padding: 0.1rem 0.2rem;
  border-radius: 4px;
  border: 1px solid color-mix(in srgb, currentColor 40%, transparent);
  background: color-mix(in srgb, currentColor 12%, transparent);
  color: inherit;
}
.bk-icon {
  border: 0;
  background: transparent;
  color: inherit;
  font-size: 1rem;
  cursor: pointer;
  padding: 0.15rem 0.35rem;
  border-radius: 4px;
}
.bk-icon:hover { background: color-mix(in srgb, currentColor 18%, transparent); }

.bk-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  padding: 0.5rem 0.6rem 0.3rem;
}
.bk-search {
  flex: 1 1 10rem;
  padding: 0.35rem 0.5rem;
  border: 1px solid var(--md-default-fg-color--lightest);
  border-radius: 6px;
  background: var(--md-default-bg-color);
  color: inherit;
  font-size: 0.85rem;
}
.bk-chips { display: flex; gap: 0.3rem; }
.bk-chip {
  font-size: 0.72rem;
  padding: 0.2rem 0.5rem;
  border-radius: 999px;
  border: 1px solid var(--md-default-fg-color--lightest);
  background: transparent;
  color: var(--md-default-fg-color--light);
  cursor: pointer;
}
.bk-chip[aria-pressed="true"] {
  background: var(--md-primary-fg-color);
  border-color: var(--md-primary-fg-color);
  color: var(--tb-accent-ink);
}

.bk-tabs {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0 0.6rem;
  border-bottom: 1px solid var(--md-default-fg-color--lightest);
}
.bk-tab {
  border: 0;
  background: transparent;
  color: var(--md-default-fg-color--light);
  font: 600 0.82rem/2.2 system-ui, sans-serif;
  border-bottom: 2px solid transparent;
  cursor: pointer;
}
.bk-tab[aria-selected="true"] {
  color: var(--md-default-fg-color);
  border-bottom-color: var(--md-primary-fg-color);
}
.bk-count { margin-left: auto; font-size: 0.72rem; color: var(--md-default-fg-color--light); }

.bk-content { flex: 1; overflow: auto; padding: 0.5rem 0.7rem 0.8rem; }
.bk-section h3 {
  margin: 0.8rem 0 0.4rem;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--md-default-fg-color--light);
}
.bk-item {
  padding: 0.45rem 0.55rem;
  margin-bottom: 0.35rem;
  border: 1px solid var(--md-default-fg-color--lightest);
  border-left: 3px solid var(--md-primary-fg-color);
  border-radius: 6px;
}
.bk-item[data-group="question"] { border-left-color: var(--tb-fig-warn); }
.bk-item[data-group="know"] { border-left-color: var(--tb-fig-good); }
.bk-item__formula { overflow-x: auto; }
.bk-item__meta { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.25rem; }
.bk-item__name { font-size: 0.8rem; font-weight: 600; }
.bk-item__note { margin: 0.25rem 0 0; font-size: 0.74rem; color: var(--md-default-fg-color--light); }
.bk-badge {
  margin-left: auto;
  font-size: 0.66rem;
  padding: 0.05rem 0.4rem;
  border-radius: 999px;
  white-space: nowrap;
}
.bk-badge--accent { background: color-mix(in srgb, var(--md-primary-fg-color) 18%, transparent); }
.bk-badge--muted { background: color-mix(in srgb, var(--tb-fig-warn) 20%, transparent); }
.bk-badge--warn { background: color-mix(in srgb, var(--tb-fig-good) 20%, transparent); }
.bk-empty { color: var(--md-default-fg-color--light); font-size: 0.85rem; }
.bk-table { width: 100%; border-collapse: collapse; font-size: 0.8rem; }
.bk-table th, .bk-table td { border: 1px solid var(--md-default-fg-color--lightest); padding: 0.25rem 0.4rem; text-align: left; }
.bk-table thead th { background: color-mix(in srgb, var(--md-default-fg-color) 6%, transparent); }

.bk-foot {
  padding: 0.35rem 0.7rem;
  border-top: 1px solid var(--md-default-fg-color--lightest);
  font-size: 0.68rem;
  color: var(--md-default-fg-color--light);
}
.bk-resize {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 18px;
  height: 18px;
  cursor: nwse-resize;
  background: linear-gradient(135deg, transparent 50%, var(--md-default-fg-color--lighter) 50%);
  touch-action: none;
}

/* Mobile: bottom sheet instead of a floating window. */
@media (max-width: 719px) {
  .bk-panel {
    left: 0;
    right: 0;
    bottom: 0;
    width: auto;
    height: min(82vh, 700px);
    border-radius: 16px 16px 0 0;
  }
  .bk-resize { display: none; }
  .bk-bar { cursor: default; border-radius: 16px 16px 0 0; }
}

/* Document Picture-in-Picture window. */
.bk-popout-body { margin: 0; background: var(--md-default-bg-color); }
.bk-popout-body .bk-panel {
  position: static;
  width: 100%;
  height: 100vh;
  border-radius: 0;
  box-shadow: none;
}

/* ------------------------------------------------------------------ */
/* Print                                                               */
/* ------------------------------------------------------------------ */

/* Printing drops the browser chrome and the pointer. This block turns the page
 * into a sheet: no navigation furniture, one readable measure, and worked
 * examples that stay whole. It declares no colour, so a theme bundle and the
 * book tint still decide everything on paper exactly as they do on screen. */
@media print {
  /* Navigation, search, tabs and footer are for a viewport, not a sheet. The
   * booklet button and panel are fixed overlays, so without this they print
   * over the text on every page.
   *
   * These are the BESPOKE shell's class names (templates/page.html), not
   * Material's. The MkDocs shell was deleted and its `.md-header`/`.md-sidebar`/
   * `.md-search` rules quietly stopped matching anything, so printing a page
   * included the masthead, the sidebar and the search box. `.md-typeset` and
   * `.md-content` stay because the content column still carries both: the
   * reader-facing typography is shared with the landing page. */
  .masthead,
  .sidebar,
  .search,
  .skip,
  .bk-fab,
  .bk-panel {
    display: none !important;
  }

  /* The content column now has the whole width. Give it one measure and centre
   * it, so line length on paper matches the screen rather than the sheet. */
  .layout {
    display: block;
    margin: 0;
    padding: 0;
  }
  .md-typeset {
    max-width: var(--tb-measure);
    margin: 0 auto;
  }

  /* A table wider than the page must read, not sit inside a scroll box that
   * cannot scroll on paper. */
  .md-typeset__scrollwrap,
  .table-scroll { overflow: visible; }

  /* Worked examples should not split across a page break. `break-inside` is a
   * hint: an item taller than a page is still broken by the paginator, so a
   * long answer block cannot overflow the sheet. The `page-break-*` aliases
   * cover engines that predate the fragmentation properties. */
  .md-typeset table,
  .md-typeset__scrollwrap,
  .md-typeset details,
  .md-typeset maths-figure,
  .md-typeset figure {
    break-inside: avoid;
    page-break-inside: avoid;
  }
  .md-typeset h1,
  .md-typeset h2,
  .md-typeset h3,
  .md-typeset h4,
  .md-typeset details > summary {
    break-after: avoid;
    page-break-after: avoid;
  }
  .md-typeset thead {
    display: table-header-group; /* repeat a table's header if it must break */
  }
  .md-typeset p {
    orphans: 2;
    widows: 2;
  }

  /* Practice answers live in <details>. A browser does not lay out the content
   * of a closed detail, and a printed page cannot be clicked, so `details`
   * prints exactly as the reader left it. We deliberately do not force closed
   * details open: these pages are low-stakes retrieval, and printing every
   * answer beside its question would remove the retrieval. A reader who wants
   * an answer opens that detail before printing; the `break-inside: avoid`
   * above then keeps it whole. Open and closed alike keep the summary marker,
   * so a reader can see there is something to unfold. */

  /* Hover does not exist on paper, so links are underlined rather than left to
   * a colour a grayscale or mono printer may drop. */
  .md-typeset a {
    text-decoration: underline;
  }
}

/* A comfortable sheet margin; the printer's own headers and page numbers stay. */
@page {
  margin: 18mm 16mm;
}
