/* ============================================================================
   LEARN SIDEBAR COMPONENT

   Sectioned topic-list nav for /learn/ pages. Used by LearnLayout.

   Behaviour:
   - Desktop (>=769px): all sections render expanded; section headings are
     non-interactive labels and the toggle chevron is hidden.
   - Mobile (<=768px): each section is collapsed by default. The active
     page's section is open on initial render (server-set data-open="true").
     Tapping any heading toggles its own state via the inline component
     script.

   Required HTML structure (see LearnSidebar.astro):
     <aside class="learn-sidebar">
       <h2 class="learn-sidebar__title">Learn Topics</h2>
       <nav class="learn-sidebar__sections">
         <section class="learn-sidebar__section" data-open="true|false">
           <h3 class="learn-sidebar__section-heading">
             <button class="learn-sidebar__toggle" aria-expanded=...
                     aria-controls="learn-sidebar-section-N">
               <span class="learn-sidebar__chevron"></span>
               <span class="learn-sidebar__section-name">...</span>
             </button>
           </h3>
           <ul class="learn-sidebar__list" id="learn-sidebar-section-N">
             <li class="learn-sidebar__item [learn-sidebar__item--active]">
               <a href=...>Topic name</a>
             </li>
           </ul>
         </section>
       </nav>
     </aside>
   ============================================================================ */

.learn-layout {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  gap: 2.5rem;
  align-items: start;
  margin-top: 0;
}

.learn-sidebar {
  position: sticky;
  top: 6rem;
  /* Cap height so the sidebar fits inside the visible viewport at every
     page-scroll position. Two competing constraints set the minimum amount
     to subtract:

       1. At the top of the page, the sidebar's natural in-flow position is
          ~298px from the top (header offset + page-title banner +
          page-toolbar + grid padding). Sizing only for the stuck state
          (`top: 6rem`) would leave the sidebar's bottom below the viewport,
          making the bottom menu entries unreachable once internal scroll
          bottoms out.

       2. At the bottom of the page, the sidebar's containing block (the
          grid row) ends ~272px above the document bottom (the page footer +
          its margins). `position: sticky` keeps `sidebar.bottom` inside its
          containing block, so when `viewport - sticky_offset -
          sidebar.height < footer + margins`, the browser pushes the
          sidebar's top up above `top: 6rem`. Subtracting 368px keeps the
          sidebar.bottom no lower than the row's bottom, eliminating the
          push-up.

     368 = 96 (sticky offset) + ~272 (footer + margins below the layout). */
  max-height: calc(100vh - 368px);
  overflow-y: auto;
  /* Without this, when the sidebar's internal scroll hits its top or bottom
     boundary the wheel/touch event chains up to the page scroll, which is
     what produces the "menu stops, page scrolls, menu resumes" stutter.
     `contain` keeps the scroll fully inside this element. */
  overscroll-behavior: contain;
  padding: 1.5rem;
  background: rgba(30, 58, 138, 0.15);
  border: 1px solid rgba(96, 165, 250, 0.2);
  border-radius: var(--radius-md, 8px);
  font-size: 0.9rem;
}

.learn-sidebar__title {
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-secondary);
  margin: 0 0 0.75rem 0;
}

.learn-sidebar__sections {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.learn-sidebar__section {
  /* Removes the user-agent default spacing so sections sit flush. */
  margin: 0;
}

.learn-sidebar__section-heading {
  margin: 0;
  font-size: inherit;
  font-weight: inherit;
}

.learn-sidebar__toggle {
  /* Reset button defaults so the heading reads as a heading on desktop. */
  display: flex;
  align-items: center;
  gap: 0.4rem;
  width: 100%;
  padding: 0.4rem 0.5rem;
  margin: 0;
  background: transparent;
  border: 0;
  font: inherit;
  color: var(--text-primary);
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

.learn-sidebar__chevron {
  display: inline-block;
  width: 0.75rem;
  height: 0.75rem;
  flex-shrink: 0;
  /* Triangle pointing right. Rotated 90deg when section is open. */
  background: currentColor;
  clip-path: polygon(20% 0, 80% 50%, 20% 100%);
  transition: transform 0.15s ease;
}

.learn-sidebar__section[data-open='true'] > .learn-sidebar__section-heading .learn-sidebar__chevron {
  transform: rotate(90deg);
}

.learn-sidebar__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.learn-sidebar__item a {
  display: block;
  padding: 0.4rem 0.5rem 0.4rem 1.4rem;
  border-left: 3px solid transparent;
  color: var(--text-secondary);
  text-decoration: none;
}

.learn-sidebar__item a:hover {
  background: rgba(96, 165, 250, 0.08);
  color: var(--text-primary);
}

.learn-sidebar__item--active a {
  border-left-color: var(--sky-blue);
  color: var(--text-primary);
  font-weight: 600;
}

/* Desktop: every section is expanded, the chevron + button are presented as
   a static heading. The toggle remains in the DOM (and remains a button so
   inline JS can still wire it) but is visually inert. */
@media (min-width: 769px) {
  .learn-sidebar__chevron {
    display: none;
  }
  .learn-sidebar__toggle {
    cursor: default;
    /* Stop accidental hover/focus styles from suggesting interactivity. */
    pointer-events: none;
  }
  .learn-sidebar__list {
    display: block;
  }
}

/* Mobile: collapsed by default; the active section is rendered with
   data-open="true" so it appears expanded on first paint without a flash. */
@media (max-width: 768px) {
  .learn-layout {
    grid-template-columns: 1fr;
  }
  .learn-sidebar {
    position: static;
    max-height: none;
    overflow-y: visible;
  }
  .learn-sidebar__section[data-open='false'] > .learn-sidebar__list {
    display: none;
  }
  .learn-sidebar__toggle:hover {
    background: rgba(96, 165, 250, 0.08);
  }
}
