/**
 * root Design System - documentation styles: sidebar
 *
 * Linked by `scripts/_docs-shell.mjs` on every page. The nav column: the brand row and its
 * header controls, and the draft mark on an unfinished entry's link. The tree itself -
 * `root-tree-view`'s remapped tokens and the leaf links - is `_nav-tree.css`; the search
 * row above it is `_search.css`. Same constraints as the rest of the shell: zero CSS
 * classes - element, `[data-part]` and attribute selectors only - zero inline styles, and
 * every value a root foundation token.
 */

aside[data-part="sidebar"] {
  /* A sticky top offset cannot read a sibling's height, so the height of each
     stuck row is written here, next to the padding it is made of: the brand row
     stops at the top, the search row stops under the brand, and a group heading
     stops under both. Both are measured against the real rows by
     `e2e/dogfooding.spec.js`, which is why this value has moved twice: 7.6rem to 7.7 when
     the shell's type scale moved onto the foundations' steps, and 7.7 to 9.1 when the
     brand row became the mark alone at 5rem instead of a 2rem mark beside the word. */
  --docs-sidebar-brand-h: 9.1rem;
  /* Measured, not chosen: the search row is a label line, the composition's gap, a
     36px small field and the row's own block-end padding, and it came out at 82.58px
     in Chromium once the field became a `root-input` (it was 60px as a bare input with
     a clipped label). A group heading sticking at the wrong sum lets links scroll
     under it, so `e2e/dogfooding.spec.js` compares this value against the row's real
     height and fails if either drifts. */
  --docs-sidebar-search-h: 8.26rem;

  display: flex;
  flex-direction: column;
  width: var(--docs-sidebar-w);
  /* The grid row is `minmax(0, 1fr)`, so the column is exactly as tall as the space the
     footer leaves. `min-height: 0` is what lets it be shorter than its own content and
     scroll instead of pushing the footer off screen. */
  min-height: 0;
  /* No block-start padding and no row gap: both would scroll past as transparent
     strips above and between the stuck rows. The rows carry that space as their
     own padding instead, which keeps their backgrounds contiguous. */
  padding: 0 var(--root-s--xl) var(--root-s--xl);
  overflow-y: auto;
  background: var(--docs-surface);
  border-right: var(--docs-rule-width) solid var(--docs-rule);
}

[data-part="brand"] {
  position: sticky;
  top: 0;
  z-index: calc(var(--root-z--sticky) + 2);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--root-s--sm);
  padding-block: var(--root-s--xl) var(--root-s--md);
  background: var(--docs-surface);
}

/* The mark alone, at a size worth looking at. The word used to be set beside it in bold
   lowercase type - the brand's lockup redrawn in a typeface that is not the brand's - and
   the name is on every page in the title and the footer anyway. What is left in the link
   is the mark and an `sr-only` "root", which is the link's accessible name.

   The version line that used to sit under it is in the footer now, which is where a reader
   looks for it and where it is on every page without costing the sidebar a row. */
[data-part="brand-name"] {
  /* The token, not the property: the foundations re-declare
     `text-decoration: var(--root-t--text-decoration)` on every descendant of `body`, so
     the `<span>` inside underlines *itself* with the value it inherits from the anchor -
     and `text-decoration: none` on the anchor cannot reach it. Setting the token here is
     what the system offers, and the span inherits "none". */
  text-decoration: none;

  display: flex;
  gap: var(--root-s--2xs);
  align-items: center;
  color: var(--docs-text);

  /* The mark keeps its viewBox and drops its intrinsic size, so the height is set here and
     the width follows it. 5rem rather than the 2rem it was beside the word: alone in the
     row it is the only thing identifying the site, and at 2rem it read as an icon in front
     of missing text. */
  svg {
    display: block;
    width: auto;
    height: 5rem;
  }

  span {
    margin: 0;
    font-size: var(--root-t--font-size--2xl);
    font-weight: 700;
    letter-spacing: 0.02rem;
  }
}

[data-part="brand-controls"] {
  display: flex;
  flex-shrink: 0;
  gap: var(--root-s--4xs);
  align-items: center;
}

/* ── Sidebar header controls ───────────────────────────────────────────── */
/* Both controls are Buttons in every respect now: the width switch literally
   (`is="root-button"`), the color-scheme switcher through Button's `[data-button]` opt-in
   (one element cannot carry two `is`). Both wear `tertiary` / `default` / `large` /
   `square` in the markup, so the geometry, the palette, the state ramps and the focus
   behavior are all Button's own rules - nothing is remapped here any more. Tertiary
   because these two frame nothing: they sit in the brand row beside the mark, where a
   pair of outlined squares read as two more things to look at than the one thing that
   row is for.

   The faces are `root-icon`s inside the buttons, which is the point of having an Icon
   component: the two `::before` rules that used to live here reached into
   `iconography/fonts/root-icons/style.css` for four codepoints, so the shell knew where in
   a font each picture lived. `src/scripts/index.js` swaps the width switch's glyph with the
   mode; the switcher swaps its own. */
[data-part="brand"] [data-part="width-switch"],
[data-part="brand"] button[is="root-color-scheme-switcher"] {
  /* `square` forces the aspect ratio, not the padding: at Button's own inline padding
     (`--root-s--xs` each side, ~10px) a 16px glyph still fit inside the 44px box and the
     ratio alone made it square. Grown below, the glyph plus that padding plus the 2px
     border stops fitting - a flex item's content width wins over the ratio once it does
     not, which is the 56px-wide button an early pass at this left behind. Zeroed here,
     the box has the full 40px between its borders to give the glyph, and the square
     holds at any of the sizes this was tried at. */
  --root-button--padding-inline: 0;

  flex-shrink: 0;
}

/* No pressed paint on the width switch. `aria-pressed` is still on the button - it is
   the right ARIA role for a two-state toggle, and it is what tells a screen reader
   which state the control is in - but nothing here paints from it: the glyph swapping
   between the two widths is the affordance, and a tertiary control that fills in when
   it is on reads as a selected item in a set rather than as a toggle. It was painted
   for a while off Button's `--root-button--selected--*-base` tokens; the fill was the
   part that was wrong, not the tokens.

   The switcher beside it stays unmarked for the same reason it always was: it is a
   single control, not one of a set. */

/* The glyph, enlarged and weighted - the button's own box is untouched by either. `em`
   on the icon resolves against what it inherits, which is the button's font-size and not
   the icon's own default `1em` of it: the icon component sets that default, this
   overrides it, and only one value ever wins for one property, so the size is exactly a
   multiple of the button's own and not compounded with it. `2em` measured heavier than
   the two glyphs alone in a 44px square could carry - close to touching the border on
   two sides - so this is one and a half, 24px against the button's 16. The block-size
   and the aspect-ratio that make the button a 44px square are separate properties on a
   different element (Button's own `_core.css`) and take no part in this.

   `font-weight: bold` where the font itself has no bold face: `root-icons` ships one
   weight (the foundation rule declares it `normal`, in a lower-priority layer this simply
   outranks), so a browser synthesizes it - the same emboldening a body font gets when
   asked for a weight it does not have. That is the point at two glyphs alone in a 44px
   square: legible as marks in their own right, not just as small print beside a label. */
[data-part="brand"] [data-part="width-switch"] i[is="root-icon"],
[data-part="brand"] button[is="root-color-scheme-switcher"] i[is="root-icon"] {
  font-size: 1.5em;
  font-weight: bold;
}

[data-part="sidebar"] a[data-draft] {
  /* Faded, and read as faded. This was `--docs-muted`, which is the ink prose is set in -
     an indigo step under a light scheme and a near-white one under a dark scheme - so a
     work-in-progress entry was *colored* differently from a finished one rather than
     quieter than it, and in the dark column it was #ded8d8 beside #ffffff, which is a
     difference you have to be told about to see.
     A grey step in each scheme instead: clearly behind the finished entries in both, and
     still a link somebody has to be able to read. `neutral-600` under light and not the
     500 tried first, which measured 4.29:1 against the white ground - under the 4.5:1 floor
     `tests/a11y` holds every label to. Measured: 7.0:1 light, 6.5:1 dark. */
  color: light-dark(var(--root-c--neutral-600--light), var(--root-c--neutral-400--dark));

  /* The pill is a `root-badge` now (ADR-030), so the paint - the ramp steps, the weight,
     the full radius, the label's contrast over the ramp - is the component's. Three things
     are left, and none of them is paint. */
  span[is="root-badge"] {
    /* The token, not the property, for the reason `[data-part="brand-name"]` sets the same
       one: the foundations re-declare `text-decoration: var(--root-t--text-decoration)` on
       every descendant of `body`, so the badge underlines *itself* with the value it
       inherits from the link, and `text-decoration: none` on the link cannot reach it. An
       atomic inline box stops the propagation of an ancestor's underline and this is not
       that - it is the badge's own declaration, measured as `underline` on all thirty-seven
       of them. */
    text-decoration: none;

    /* The same height a branch's count takes, off the same token: the two marks are the only
       things in this column that are not words, and they sit in one line down the trailing
       edge of it. `root-badge`'s own `small` is 25px - a step drawn for a badge beside a
       heading - which in a 1.45rem row was the thing deciding how tall the row was. */
    --root-badge--block-size: var(--docs-nav-badge-h);

    /* The far end of the row, which is where a branch's count is. In flow the mark sat
       against the name it followed, so thirty-six links of different lengths put thirty-six
       badges at thirty-six different offsets - a ragged second column down the middle of the
       sidebar. `auto` takes the free space instead, and `a[data-nav]` is a flex line so that
       there is free space to take. */
    margin-inline-start: auto;
  }
}

/* ── Responsive ─────────────────────────────────────────────────────────── */
@media (max-width: 60rem) {
  aside[data-part="sidebar"] {
    width: auto;
    min-height: auto;
    overflow-y: visible;
    gap: var(--root-s--md);
    padding: var(--root-s--xl);
  }

  /* The sidebar is in the page flow here, with no scrollport of its own: nothing
     can stick to it, so the brand row goes back to taking its space from the sidebar's
     padding rather than carrying it itself. */
  [data-part="brand"] {
    position: static;
    padding-block: 0;
  }
}
