/* bare.style - site/docs.css
   The reading experience of the documentation pages, and nothing else.

   This is site furniture, not framework. It styles the scaffolding a documentation page is built
   out of - the gap between one section and the next, the block that holds a live example and its
   markup - and it declares no component a consumer could import. Anything here that turned out to
   be reusable belongs in src/ instead, and would move there rather than being linked from a page.

   It still plays by the framework's rules, because the site is the framework's own proof: one
   layer, the layer order declared up front so load position cannot change the outcome, every
   value read from a token, and no colour pairing invented here that src/core/tokens.css has not
   already measured.

   The type scale is deliberately not touched. Heading sizes, leading and tracking are core's and
   the contract puts them out of reach of a page; what a page owns is the space around them, which
   is where the rhythm on these pages had actually gone missing. */

@layer bare.reset, bare.tokens, bare.base, bare.layout, bare.component, bare.utility;

@layer bare.component {
  /* ---- Anchor targets clear the sticky stack -----------------------------------------------
     Clicking a contents link used to land the heading underneath the sticky bar, which is the one
     piece of the page a reader cannot scroll out of the way. The offset is composed from
     --bs-navbar-height, the same hook the section strip pins itself to, rather than from a second
     measurement of the same bar that could drift away from it. site.js measures the bar and
     writes the hook; the fallback below is a one-row bar, which is what a page whose script never
     ran gets.

     Below 64em the strip is pinned directly under the bar and is part of the same stack, so its
     own row is in the sum. Measured at 65px at every width it is shown at, in both engines, which
     is the 4.0625rem below. Above 64em the strip is display:none and the bar is the whole stack.

     Scoped to main so the sum is not applied to ids in the bar itself, where it means nothing.
     Every id rather than a list of headings: a target added to a page later is then already
     covered, and the property is inert on an element nothing ever scrolls to. */
  :root {
    --bs-docs-sticky: calc(var(--bs-navbar-height, 4.35rem) + 4.0625rem);
  }

  @media (min-width: 64em) {
    :root {
      --bs-docs-sticky: var(--bs-navbar-height, 4.35rem);
    }
  }

  main[id],
  main [id] {
    /* One more step of space under the bar, so the heading reads as the top of something rather
       than as a line that happens to have stopped just short of being covered. */
    scroll-margin-block-start: calc(var(--bs-docs-sticky) + var(--bs-space-4));
  }

  /* ---- Section rhythm ----------------------------------------------------------------------
     Three sizes of gap, not one. A section boundary is the largest break on the page, an example
     is the heaviest single block inside a section, and a paragraph follows its heading closely.
     Uniform padding is what made the previous page read as one undifferentiated column: the table
     that ended one section sat exactly as close to the next heading as a paragraph sits to the one
     above it, so nothing announced that a subject had changed.

     Only the block-start side is set, which is the convention src/core/type.css already follows on
     this page: every bottom margin stays zero, so two adjacent margins always collapse to the
     later element's value rather than to an unpredictable maximum of two competing ones. */
  .bs-sidebar__main > section {
    margin-block-start: var(--bs-space-8);
  }

  @media (min-width: 48em) {
    .bs-sidebar__main > section {
      margin-block-start: var(--bs-space-9);
    }
  }

  /* A section that follows a labelled divider has already been announced by it, so it does not
     also pay for the full boundary gap. Without this the two stack into a hole. */
  .bs-sidebar__main > .bs-divider + section {
    margin-block-start: var(--bs-space-5);
  }

  /* The heading belongs to the prose under it far more than to the section above it, and the gap
     on each side is what says so. */
  .bs-sidebar__main > section > :is(h2, h3) {
    margin-block-end: var(--bs-space-4);
  }

  .bs-sidebar__main > section > h3 {
    margin-block-start: var(--bs-space-7);
  }

  /* ---- The example block -------------------------------------------------------------------
     A card holding a live component, the controls that drive it, and the markup that produced it.
     Matched as a direct child of a top-level section, which on every page here is exactly the
     example blocks and never one of the small cards a demo is built out of. */
  .bs-sidebar__main > section > .bs-card {
    margin-block: var(--bs-space-7);
  }

  /* The commentary that follows an example is about it, so it sits nearer to it than the next
     example does. */
  .bs-sidebar__main > section > .bs-card + p {
    margin-block-start: var(--bs-space-4);
  }

  /* ---- Show code ---------------------------------------------------------------------------
     Every example used to print its full markup inline and unconditionally, so the page a reader
     scrolled through was mostly other people's angle brackets with the live component appearing as
     a band between two of them. On /docs/motion.html that made the animation card 871px tall at
     320px in a 740px viewport: the control that replays the entrance and the thing it replays
     could not both be on screen.

     The markup is still read out of the live example, still exact, still one keystroke away. It is
     just no longer the default, and the component is.

     <details> because the platform already owns this: the open state is exposed to assistive
     technology without an aria-expanded to keep in sync, the summary is focusable and operable
     from the keyboard for free, and Chrome opens a closed one to show a find-in-page hit. No
     script was needed and none was written. Copy is unaffected either way, because site.js reads
     the markup out of the live example above and never out of the panel.

     The native marker is kept. It is drawn by the UA in currentColor, it already rotates on open,
     and it survives forced-colors because it is not an author fill. Replacing it with an SVG of
     our own would cost bytes on every example to arrive at the same affordance. */
  .bs-docs-code {
    border-block-start: var(--bs-border-1) solid var(--bs-docs-code-border, var(--bs-border-color));
  }

  .bs-docs-code__summary {
    /* display is deliberately left at the UA's list-item: flex or block removes the disclosure
       marker in Blink, and the marker is the whole affordance. */
    padding-block: var(--bs-space-3);
    padding-inline: var(--bs-space-4);
    /* 42px against the 24px SC 2.5.8 floor, measured, and the row is the full width of the card
       so the target is the row a reader aims at rather than the width of two words. */
    font-size: var(--bs-text-small);
    line-height: var(--bs-leading-normal);
    font-weight: var(--bs-weight-medium);
    color: var(--bs-docs-code-fg, var(--bs-text-secondary));
    /* Dark --ter over --s-card 7.36:1. Light --ter over --s-card 8.11:1. Both are the pairings
       src/nav/sidebar-nav.css already measures for the same two tokens. */
    cursor: pointer;
  }

  .bs-docs-code__summary:hover {
    background-color: var(--bs-docs-code-bg-hover, var(--s-hover));
    color: var(--bs-docs-code-fg-hover, var(--bs-text));
  }

  /* The label says what the control does next, so it changes when the state does. Two spans
     rather than a CSS content string, because a string in a stylesheet is not text a translator
     or a screen reader's language handling can reach. */
  .bs-docs-code__less {
    display: none;
  }

  .bs-docs-code[open] .bs-docs-code__more {
    display: none;
  }

  .bs-docs-code[open] .bs-docs-code__less {
    display: inline;
  }

  /* PRINT. A control that opens something means nothing on paper, so it goes. What is left is the
     platform's own behaviour, which is the right one here: a panel the reader opened prints, a
     panel they left closed does not. The sheet in their hand then matches the page they were
     looking at, which is a better answer than reinstating every panel they had chosen to put
     away. */
  @media print {
    .bs-docs-code__summary {
      display: none;
    }
  }
}

/* The theme toggle's word is dropped on a phone for the same reason the colour lab's is: the bar
   wraps to two rows once the brand, badge and two control labels compete for the width. The button
   carries aria-label="Light theme", so hiding the text costs nothing to a screen reader. Mobile
   first: absent by default, returned when there is room. */
.bs-theme-label-text {
  display: none;
}

@media (min-width: 48em) {
  .bs-theme-label-text {
    display: inline;
  }
}
