tfrere's picture
tfrere HF Staff
feat(frontend): editor refresh (embed studio, comment popover, shiki, top bar, hooks, styles)
76fc93a
/* ============================================================================ */
/* 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 !important;
}
/* ============================================================================ */
/* 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;
}
}