/*
 * .SYNOPSIS
 * base.css - token contract + structural layout
 *
 * .DESCRIPTION
 * Everything in this web part is styled through CSS custom properties that are
 * declared here and given values by the theme files in ./themes. A theme only
 * has to supply colours and a few shape/typography choices; nothing in the
 * structural rules hard-codes a colour. That is what makes "GitHub / Obsidian /
 * VS Code" a data change rather than a fork of the stylesheet.
 *
 * Token groups
 *   --strata-bg / -elevated / -hover ....... surfaces
 *   --strata-text / -muted / -faint ........ foreground text
 *   --strata-border / -strong .............. rules and dividers
 *   --strata-link / -hover ................. anchors
 *   --strata-color-<hue> ................... accent palette, stored as an "R, G, B"
 *                                         triple so rules can do
 *                                         rgba(var(--strata-color-blue), .12)
 *   --strata-font-* / --strata-*-size ......... typography
 *   --strata-code-* ........................ code surfaces and gutter
 *   --strata-syn-* ......................... syntax highlighting tokens
 *   --strata-callout-* ..................... callout shape (colour comes from the
 *                                         per-type --strata-callout-rgb)
 *
 * .USAGE
 *   Loaded in this order by MarkstrataWebPart.ts, because later rules
 *   override earlier ones:
 *
 *     base, typography, code, syntax, callouts, tables-lists, extras,
 *     chrome, the three themes, modifiers, print
 *
 * .NOTES
 * Since:     0.0.6
 * Ships in:  the web part bundle
 * Requires:  nothing else in this project
 * Loaded:    first, so every later rule can read its tokens
 */

.strata-root {
  /* Shape defaults - themes may override. */
  --strata-radius-sm: 3px;

  /* Lines a fence calls out. Built from the theme's own accent palette rather
     than stated as colours, so each theme marks them in its own blue and both
     modes stay legible without either being named here. */
  --strata-code-called-bg: rgba(var(--strata-color-blue), 0.12);
  --strata-code-called-bar: rgb(var(--strata-color-blue));
  --strata-radius-md: 6px;
  --strata-radius-lg: 8px;

  /* Rhythm. Themes set the *-base values; the density and font-size options in
     modifiers.css scale them, so neither side has to win a specificity fight. */
  --strata-block-gap-base: 16px;
  --strata-density-scale: 1;
  --strata-font-scale: 1;
  --strata-line-height-base: 1.6;
  --strata-block-gap: calc(var(--strata-block-gap-base) * var(--strata-density-scale));
  --strata-line-height: calc(var(--strata-line-height-base) * var(--strata-density-scale));
  --strata-content-max-width: 860px;
  /* Heading anchors hang to the left of the text, so the content column
     reserves a gutter to hang them in. It is computed from the body size
     rather than written in em, because an em inside an h1 resolves against
     the heading and the gutter would no longer match the anchor. */
  --strata-anchor-gutter: calc(var(--strata-font-size) * var(--strata-font-scale) * 1.35);
  /* Breathing room at the top and bottom of the web part. SharePoint gives its
     own web parts a generous amount, and without it the first heading sits
     almost on the edge of the panel. Follows the spacing setting, so compact
     gets less of it than relaxed. */
  --strata-root-padding-block: calc(26px * var(--strata-density-scale));

  /* And at the sides, for the same reason. Without it the toolbar's last
     button and a left contents sidebar sit hard against the edge of the
     panel, which reads as clipped rather than as a margin. The content column
     centres inside whatever is left, so this narrows the column rather than
     pushing it off-centre. */
  --strata-root-padding-inline: calc(22px * var(--strata-density-scale));

  /* Code defaults that themes rarely need to change. */
  --strata-code-font-size: 0.875em;
  --strata-code-line-height: 1.55;
  --strata-code-padding: 14px 16px;
  --strata-code-radius: var(--strata-radius-md);
  --strata-code-border: transparent;
  --strata-code-header-bg: transparent;

  /* Callout shape defaults; each theme restyles these. */
  --strata-callout-radius: var(--strata-radius-md);
  --strata-callout-bg-alpha: 0.1;
  --strata-callout-title-bg-alpha: 0.1;
  --strata-callout-border-width: 0px;
  --strata-callout-accent-width: 0px;
  --strata-callout-title-weight: 600;
  --strata-callout-rgb: var(--strata-color-gray);

  box-sizing: border-box;
  position: relative;
  /* Layout decisions below are made on the width of the web part, not the
     width of the window: a web part in a one-third column on a wide screen has
     to behave like a narrow layout, which a media query cannot see. */
  container-type: inline-size;
  container-name: mdf;
  background-color: var(--strata-bg);
  color: var(--strata-text);
  font-family: var(--strata-font-body);
  font-size: calc(var(--strata-font-size) * var(--strata-font-scale));
  line-height: var(--strata-line-height);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-wrap: break-word;
  padding-block: var(--strata-root-padding-block);
  padding-inline: var(--strata-root-padding-inline);
}

.strata-root *,
.strata-root *::before,
.strata-root *::after {
  box-sizing: inherit;
}

/* ------------------------------------------------------------------ layout */

.strata-layout {
  display: flex;
  align-items: flex-start;
  /* The content column stops at its width setting, so on a wider web part
     there is space left over. Centre what there is: a SharePoint page centres
     its own content, and a column stranded against the left edge of a
     full-width web part does not read as part of the page. */
  justify-content: center;
  gap: 32px;
}

/* The contents sidebar is a column of the flex row, never an overlay: it
   cannot cover the text or the page's editing controls the way a floated or
   fixed-position sidebar does.

   Right placement reorders rather than reversing the row: row-reverse packs
   both columns against the right edge when the content is narrower than the
   web part, which leaves an odd gap on the left. */
.strata-layout[data-strata-toc='right'] > .strata-toc-sidebar {
  order: 2;
}

.strata-content {
  flex: 1 1 auto;
  min-width: 0;
  max-width: var(--strata-content-max-width);
  /* Room for the heading anchors. Without it they sit outside the web part
     and the page canvas clips them - which only showed up with the contents
     anywhere but on the left, where the sidebar happened to provide the gap. */
  padding-left: var(--strata-anchor-gutter);
}

/* Blocks own their bottom margin only, so spacing never doubles up. */
.strata-content > * {
  margin-top: 0;
  margin-bottom: var(--strata-block-gap);
}

.strata-content > *:last-child {
  margin-bottom: 0;
}

/* ------------------------------------------------------- table of contents */

.strata-toc-sidebar {
  /* Set from the contents width setting. The fallback is what the sidebar was
     before the setting existed, so an older web part keeps its layout. */
  flex: 0 0 var(--strata-toc-width, 240px);
  align-self: flex-start;
  position: sticky;
  top: 16px;
  max-height: calc(100vh - 140px);
  overflow-y: auto;
  padding: 10px 14px;
  border: 1px solid var(--strata-border);
  border-radius: var(--strata-radius-md);
  background-color: var(--strata-bg-elevated);
  font-size: 0.875em;
}

/*
 * Auto sizes the sidebar to its longest entry, so there is no gap beside short
 * headings and no wrapping of long ones. Capped, because one deep heading
 * should not be allowed to take the page, and floored so a document with three
 * short headings still reads as a column rather than a label.
 */
.strata-root[data-strata-toc-width='auto'] .strata-toc-sidebar {
  flex: 0 1 auto;
  width: max-content;
  min-width: 11em;
  max-width: 38%;
}

/* While the page is being edited, sticky positioning fights the page canvas,
   so the contents simply scroll away with everything else. */
.strata-root[data-strata-editing='true'] .strata-toc-sidebar {
  position: static;
  max-height: none;
}

.strata-toc-heading {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  padding: 2px 0;
  font-size: 0.8em;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--strata-text-muted);
  cursor: pointer;
  list-style: none;
}

.strata-toc-heading::-webkit-details-marker {
  display: none;
}

.strata-toc-heading::before {
  content: '';
  width: 0;
  height: 0;
  border-left: 4px solid currentColor;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transform: rotate(90deg);
  transition: transform 0.15s ease-in-out;
}

.strata-toc-sidebar:not([open]) .strata-toc-heading::before {
  transform: none;
}

.strata-toc {
  margin-top: 8px;
}

.strata-toc ul {
  margin: 0;
  padding-left: 14px;
  list-style: none;
}

.strata-toc > ul {
  padding-left: 0;
}

.strata-toc li {
  margin: 2px 0;
}

.strata-toc a {
  display: block;
  padding: 3px 6px;
  border-left: 2px solid transparent;
  border-radius: var(--strata-radius-sm);
  color: var(--strata-text-muted);
  text-decoration: none;
  line-height: 1.35;
}

.strata-toc a:hover {
  background-color: var(--strata-bg-hover);
  color: var(--strata-link);
}

/* Marks the heading currently in view. */
.strata-toc a[aria-current='true'] {
  border-left-color: var(--strata-link);
  color: var(--strata-link);
  font-weight: 600;
}

/* The `[[toc]]` marker's own container, and the inline panel. The child
   combinator matters: the inline panel holds a .strata-toc of its own, which must
   not pick up a second border. */
.strata-content > .strata-toc,
.strata-toc-inline {
  padding: 12px 16px;
  border: 1px solid var(--strata-border);
  border-radius: var(--strata-radius-md);
  background-color: var(--strata-bg-elevated);
}

.strata-toc-inline {
  margin-bottom: var(--strata-block-gap);
}

/* Narrow web part: stack, and let the contents collapse out of the way. */
@container mdf (max-width: 720px) {
  .strata-layout {
    flex-direction: column;
    gap: 16px;
    /* align-items is flex-start in the row layout so a short contents sidebar
       does not stretch to the height of the text. Stacked, that same value
       aligns horizontally, which shrink-wraps the content column to its widest
       line and pushes it out of the web part - so stretch it back. */
    align-items: stretch;
    /* Centring is a horizontal idea; on this axis it would only push the
       content down the page. */
    justify-content: flex-start;
  }

  /* Stacked, the contents belong above the text whichever side they were on. */
  .strata-layout[data-strata-toc='right'] > .strata-toc-sidebar {
    order: 0;
  }

  .strata-toc-sidebar {
    position: static;
    flex: 1 1 auto;
    width: 100%;
    max-height: none;
  }
}

/* Fallback for browsers without container queries. */
@supports not (container-type: inline-size) {
  @media (max-width: 900px) {
    .strata-layout {
      flex-direction: column;
      gap: 16px;
    }

    .strata-layout[data-strata-toc='right'] > .strata-toc-sidebar {
      order: 0;
    }

    .strata-toc-sidebar {
      position: static;
      flex: 1 1 auto;
      width: 100%;
      max-height: none;
    }
  }
}

/* ------------------------------------------------------------------ states */

.strata-empty,
.strata-error {
  padding: 16px;
  border-radius: var(--strata-radius-md);
  border: 1px solid var(--strata-border);
  color: var(--strata-text-muted);
  font-size: 0.95em;
}

.strata-error {
  border-color: rgb(var(--strata-color-red));
  background-color: rgba(var(--strata-color-red), 0.1);
  color: var(--strata-text);
}

.strata-root :focus-visible {
  outline: 2px solid var(--strata-link);
  outline-offset: 2px;
}
