Spaces:
Sleeping
Sleeping
| /* ============================================================================ */ | |
| /* Table of Contents */ | |
| /* Extracted from TableOfContents.astro scoped styles. */ | |
| /* Shared between editor and publisher. */ | |
| /* ============================================================================ */ | |
| /* Loading state */ | |
| .table-of-contents.toc-loading, | |
| .toc-mobile-sidebar.toc-loading { | |
| opacity: 0; | |
| transition: opacity 0.3s ease-in-out; | |
| } | |
| .table-of-contents.toc-loaded, | |
| .toc-mobile-sidebar.toc-loaded { | |
| opacity: 1; | |
| } | |
| /* Desktop TOC */ | |
| .table-of-contents { | |
| position: sticky; | |
| top: 32px; | |
| margin-top: 12px; | |
| } | |
| .table-of-contents nav { | |
| border-left: 1px solid var(--border-color); | |
| padding-left: 16px; | |
| font-size: 13px; | |
| } | |
| .table-of-contents .title { | |
| font-weight: 600; | |
| font-size: 14px; | |
| margin-bottom: 8px; | |
| } | |
| .table-of-contents nav ul { | |
| margin: 0 0 6px; | |
| padding-left: 1em; | |
| } | |
| .table-of-contents nav li { | |
| list-style: none; | |
| margin: 0.25em 0; | |
| } | |
| .table-of-contents nav a, | |
| .table-of-contents nav a:link, | |
| .table-of-contents nav a:visited { | |
| color: var(--text-color); | |
| text-decoration: none; | |
| border-bottom: none; | |
| background: none; | |
| cursor: pointer; | |
| } | |
| .table-of-contents nav > ul > li > a { | |
| font-weight: 700; | |
| } | |
| .table-of-contents nav a:hover { | |
| text-decoration: underline solid var(--muted-color); | |
| } | |
| .table-of-contents nav a.active { | |
| color: var(--primary-color); | |
| text-decoration: underline; | |
| text-decoration-color: color-mix(in srgb, var(--primary-color) 50%, transparent); | |
| text-underline-offset: 2px; | |
| } | |
| /* Collapsible sub-sections. | |
| We wrap every nested <ul> in a <div class="toc-children"> and animate via | |
| the grid-template-rows 0fr/1fr trick (CSS can't animate height:auto). | |
| This matches the editor-side React implementation. */ | |
| .toc-children { | |
| display: grid; | |
| grid-template-rows: 1fr; | |
| opacity: 1; | |
| overflow: hidden; | |
| transition: grid-template-rows 200ms ease, opacity 200ms ease; | |
| } | |
| .toc-children > * { | |
| overflow: hidden; | |
| min-height: 0; | |
| } | |
| .toc-collapsible li.collapsed > .toc-children { | |
| grid-template-rows: 0fr; | |
| opacity: 0; | |
| } | |
| /* Applied on the nav root during init to suppress transitions for the first | |
| paint, then removed on the next animation frame. Avoids a close-animation | |
| flash when auto-collapse is enabled. */ | |
| .toc-collapsible.toc-no-transition .toc-children, | |
| .toc-collapsible.toc-no-transition .toc-children > * { | |
| transition: none ; | |
| } | |
| /* ============================================================================ */ | |
| /* Mobile TOC - toggle button */ | |
| /* Hidden on desktop, shown at @media (max-width: 1100px) below. */ | |
| /* ============================================================================ */ | |
| .toc-mobile-toggle { | |
| display: none; | |
| position: fixed; | |
| top: var(--spacing-4); | |
| left: var(--spacing-4); | |
| z-index: var(--z-overlay); | |
| width: 40px; | |
| height: 40px; | |
| border-radius: 50%; | |
| border: 1px solid var(--border-color); | |
| background: var(--page-bg); | |
| box-shadow: 0 2px 12px rgba(0,0,0,.08); | |
| align-items: center; | |
| justify-content: center; | |
| padding: 0; | |
| cursor: pointer; | |
| color: var(--text-color); | |
| transition: transform 150ms ease, box-shadow 150ms ease; | |
| } | |
| .toc-mobile-toggle:active { | |
| transform: scale(0.92); | |
| } | |
| /* ============================================================================ */ | |
| /* Mobile TOC - backdrop */ | |
| /* ============================================================================ */ | |
| .toc-mobile-backdrop { | |
| display: none; | |
| position: fixed; | |
| inset: 0; | |
| z-index: calc(var(--z-overlay) + 1); | |
| background: rgba(0,0,0,.4); | |
| opacity: 0; | |
| pointer-events: none; | |
| transition: opacity 250ms ease; | |
| } | |
| .toc-mobile-backdrop.open { | |
| opacity: 1; | |
| pointer-events: auto; | |
| } | |
| /* ============================================================================ */ | |
| /* Mobile TOC - sidebar panel */ | |
| /* ============================================================================ */ | |
| .toc-mobile-sidebar { | |
| display: none; | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| bottom: 0; | |
| z-index: calc(var(--z-overlay) + 2); | |
| width: min(320px, 85vw); | |
| background: var(--page-bg); | |
| border-right: 1px solid var(--border-color); | |
| transform: translateX(-100%); | |
| transition: transform 300ms cubic-bezier(.4,0,.2,1); | |
| flex-direction: column; | |
| } | |
| .toc-mobile-sidebar.open { | |
| transform: translateX(0); | |
| } | |
| .toc-mobile-sidebar__header { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| padding: 16px; | |
| border-bottom: 1px solid var(--border-color); | |
| flex-shrink: 0; | |
| } | |
| .toc-mobile-sidebar__title { | |
| font-weight: 700; | |
| font-size: 15px; | |
| color: var(--text-color); | |
| } | |
| .toc-mobile-sidebar__actions { | |
| display: flex; | |
| align-items: center; | |
| gap: 4px; | |
| } | |
| .toc-mobile-sidebar__close, | |
| .toc-mobile-sidebar__theme { | |
| background: none; | |
| border: none; | |
| color: var(--muted-color); | |
| cursor: pointer; | |
| padding: 4px; | |
| border-radius: 6px; | |
| width: 32px; | |
| height: 32px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| transition: color 150ms ease, background 150ms ease; | |
| } | |
| .toc-mobile-sidebar__close:hover, | |
| .toc-mobile-sidebar__theme:hover { | |
| color: var(--text-color); | |
| background: var(--surface-bg); | |
| } | |
| /* Theme icon visibility in sidebar */ | |
| .toc-mobile-sidebar__theme .icon.dark { | |
| display: none; | |
| } | |
| [data-theme="dark"] .toc-mobile-sidebar__theme .icon.light { | |
| display: none; | |
| } | |
| [data-theme="dark"] .toc-mobile-sidebar__theme .icon.dark { | |
| display: inline; | |
| } | |
| .toc-mobile-sidebar__body { | |
| flex: 1; | |
| overflow-y: auto; | |
| -webkit-overflow-scrolling: touch; | |
| padding: 16px; | |
| } | |
| /* TOC styles inside mobile sidebar */ | |
| .toc-mobile-sidebar nav ul { | |
| margin: 0 0 6px; | |
| padding-left: 1em; | |
| } | |
| .toc-mobile-sidebar nav li { | |
| list-style: none; | |
| margin: 0.35em 0; | |
| } | |
| .toc-mobile-sidebar nav a, | |
| .toc-mobile-sidebar nav a:link, | |
| .toc-mobile-sidebar nav a:visited { | |
| color: var(--text-color); | |
| text-decoration: none; | |
| border-bottom: none; | |
| font-size: 14px; | |
| line-height: 1.5; | |
| } | |
| .toc-mobile-sidebar nav > ul > li > a { | |
| font-weight: 700; | |
| } | |
| .toc-mobile-sidebar nav a:hover { | |
| text-decoration: underline solid var(--muted-color); | |
| } | |
| .toc-mobile-sidebar nav a.active { | |
| color: var(--primary-color); | |
| text-decoration: underline; | |
| text-decoration-color: color-mix(in srgb, var(--primary-color) 50%, transparent); | |
| text-underline-offset: 2px; | |
| } | |
| /* ============================================================================ */ | |
| /* Responsive: show mobile TOC elements on small viewports */ | |
| /* Must be AFTER default display:none rules to win in the cascade */ | |
| /* ============================================================================ */ | |
| @media (max-width: 1100px) { | |
| .toc-mobile-toggle { | |
| display: flex; | |
| } | |
| .toc-mobile-backdrop { | |
| display: block; | |
| } | |
| .toc-mobile-sidebar { | |
| display: flex; | |
| } | |
| } | |