/* ==========================================================================
   ch/toc — frontend styles
   --------------------------------------------------------------------------
   Neutral skin driven by custom properties; themes override on the block
   (or a parent):
     --ch-toc-rail       hairline colour (default rgba(0,0,0,.12))
     --ch-toc-marker     marker colour (default currentColor)
     --ch-toc-marker-idle  marker colour above the first heading (nothing
                         active; default rgba(0,0,0,.25))
     --ch-toc-marker-size  6px
     --ch-toc-link-opacity / --ch-toc-active-weight
   Sticky placement is the theme's call (position: sticky on the block).
   ========================================================================== */

.ch-toc {
	--ch-toc-rail: rgba(0, 0, 0, 0.12);
	--ch-toc-marker: currentColor;
	--ch-toc-marker-idle: rgba(0, 0, 0, 0.25);
	--ch-toc-marker-size: 6px;
	--ch-toc-link-opacity: 0.7;
	--ch-toc-active-weight: 500;
	--ch-toc-transition: 320ms cubic-bezier(0.2, 0.8, 0.2, 1);
	display: block;
}

.ch-toc__label {
	margin: 0 0 0.75rem;
	font-size: 0.75rem;
	font-weight: 500;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	opacity: 0.6;
}

.ch-toc__rail {
	position: relative;
	padding-left: 1px;
	border-left: 1px solid var(--ch-toc-rail);
}

.ch-toc__list {
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.ch-toc__item {
	margin: 0;
}

.ch-toc__link {
	display: block;
	padding: 4px 16px;
	color: inherit;
	line-height: 1.4;
	text-decoration: none;
	opacity: var(--ch-toc-link-opacity);
	transition: opacity 200ms ease;
}

.ch-toc__item--h3 .ch-toc__link {
	padding-left: 28px;
	font-size: 0.9375em;
}

.ch-toc__link:hover,
.ch-toc__link:focus-visible,
.ch-toc__link.is-active {
	opacity: 1;
}

.ch-toc__link.is-active {
	font-weight: var(--ch-toc-active-weight);
}

/* Marker riding the rail: centred over the 1px rule, positioned by
   view.js (translateY), faded in after the first measurement. */
.ch-toc__marker {
	position: absolute;
	top: 0;
	left: calc(-1 * (var(--ch-toc-marker-size) - 1px) / 2 - 1px);
	width: var(--ch-toc-marker-size);
	height: var(--ch-toc-marker-size);
	border-radius: 50%;
	background: var(--ch-toc-marker);
	opacity: 0;
	pointer-events: none;
	transition: transform var(--ch-toc-transition), opacity 200ms ease;
}

.ch-toc.is-ready .ch-toc__marker {
	opacity: 1;
}

/* Above the first heading: nothing is active — the marker waits, dimmed,
   at the first row. */
.ch-toc.is-idle .ch-toc__marker {
	background: var(--ch-toc-marker-idle);
}

/* Collapsible (accordion) below the breakpoint — view.js swaps the
   static label for the toggle button and hides the rail. */
.ch-toc__toggle {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.5rem;
	width: 100%;
	margin: 0;
	padding: 0.75rem 0;
	border: 0;
	border-top: 1px solid var(--ch-toc-rail);
	border-bottom: 1px solid var(--ch-toc-rail);
	background: none;
	color: inherit;
	font: inherit;
	font-size: 0.75rem;
	font-weight: 500;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	text-align: left;
	cursor: pointer;
}

.ch-toc__toggle[hidden] {
	display: none;
}

.ch-toc__chevron {
	flex: 0 0 auto;
	transition: transform 200ms ease;
}

.ch-toc__toggle[aria-expanded="true"] .ch-toc__chevron {
	transform: rotate(180deg);
}

.ch-toc.is-collapsible .ch-toc__rail {
	margin-top: 0.75rem;
}

.ch-toc.is-collapsible .ch-toc__rail[hidden] {
	display: none;
}

@media (prefers-reduced-motion: reduce) {
	.ch-toc__link,
	.ch-toc__marker,
	.ch-toc__chevron {
		transition: none;
	}
}

/* ==========================================================================
   Floating placement — for chapter stories. The block is a sticky layer
   spanning the viewport while its container is in view (height 100dvh,
   negative margin keeps it out of the flow); the list is placed inside
   it by side (left/right) + anchor (top/center/bottom). Themes tune
   --ch-toc-float-inset (edge distance) and --ch-toc-float-z.
   ========================================================================== */

/* Doubled class: core's flow layout zeroes margin-block-end on children
   with a same-specificity rule later in the cascade. */
.ch-toc.ch-toc--floating {
	--ch-toc-float-inset: 1.5rem;
	position: sticky;
	top: 0;
	z-index: var(--ch-toc-float-z, 10);
	display: flex;
	flex-direction: column;
	height: 100dvh;
	margin-block-end: -100dvh;
	padding: var(--ch-toc-float-inset);
	box-sizing: border-box;
	pointer-events: none;
}

.ch-toc--floating > * {
	pointer-events: auto;
}

.ch-toc--floating.ch-toc--side-right {
	align-items: flex-end;
}

.ch-toc--floating.ch-toc--side-left {
	align-items: flex-start;
}

.ch-toc--floating.ch-toc--at-top {
	justify-content: flex-start;
}

.ch-toc--floating.ch-toc--at-center {
	justify-content: center;
}

.ch-toc--floating.ch-toc--at-bottom {
	justify-content: flex-end;
}

.ch-toc--floating .ch-toc__rail {
	max-width: 16rem;
}

/* Tone mirrored from the active chapter (data-ch-tone): light text over
   dark chapters. Themes may override per tone. */
.ch-toc--floating[data-tone="dark"] {
	color: #fff;
	--ch-toc-rail: rgba(255, 255, 255, 0.35);
	--ch-toc-marker-idle: rgba(255, 255, 255, 0.4);
}

/* ==========================================================================
   Block style «Dots» — markers only; the label appears next to the active
   (or hovered) dot. The rail line and the sliding marker are dropped: the
   dots ARE the markers. Right-side placement shows labels to the left.
   ========================================================================== */

.ch-toc.is-style-dots {
	--ch-toc-dot: currentColor;
	--ch-toc-dot-size: 10px;
}

.ch-toc.is-style-dots .ch-toc__label,
.ch-toc.is-style-dots .ch-toc__marker {
	display: none;
}

.ch-toc.is-style-dots .ch-toc__rail {
	padding: 0;
	border: 0;
}

.ch-toc.is-style-dots .ch-toc__list {
	gap: 0.75rem;
}

.ch-toc.is-style-dots .ch-toc__link {
	position: relative;
	width: var(--ch-toc-dot-size);
	height: var(--ch-toc-dot-size);
	padding: 0;
	border-radius: 50%;
	background: var(--ch-toc-dot); /* currentColor — never set color: transparent on the link */
	font-size: 0;
	line-height: 0;
	opacity: 0.35;
	transition: opacity 200ms ease, transform 200ms ease;
}

.ch-toc.is-style-dots .ch-toc__link:hover,
.ch-toc.is-style-dots .ch-toc__link:focus-visible,
.ch-toc.is-style-dots .ch-toc__link.is-active {
	opacity: 1;
	transform: scale(1.3);
}

.ch-toc.is-style-dots .ch-toc__link::after {
	content: attr(data-label);
	position: absolute;
	top: 50%;
	right: calc(100% + 0.75rem);
	transform: translateY(-50%);
	color: var(--ch-toc-dot-label, inherit);
	font-size: 0.875rem;
	line-height: 1.2;
	white-space: nowrap;
	opacity: 0;
	pointer-events: none;
	transition: opacity 200ms ease;
}

.ch-toc.is-style-dots .ch-toc__link:hover::after,
.ch-toc.is-style-dots .ch-toc__link:focus-visible::after,
.ch-toc.is-style-dots .ch-toc__link.is-active::after {
	opacity: 1;
}

.ch-toc.is-style-dots.ch-toc--side-left .ch-toc__link::after {
	right: auto;
	left: calc(100% + 0.75rem);
}

.ch-toc.is-style-dots .ch-toc__link.is-active::after {
	color: var(--ch-toc-dot-label-active, inherit);
	font-weight: var(--ch-toc-active-weight);
}

.ch-toc--floating.is-style-dots .ch-toc__rail {
	max-width: none;
}

/* Short labels (data-ch-label, e.g. years) sit next to every dot; the
   full title still appears on the active/hovered one. Right side: short
   label left of the dot, title further left. */
.ch-toc.is-style-dots.has-short .ch-toc__link::before {
	content: attr(data-short);
	position: absolute;
	top: 50%;
	/* The label box reaches the dot (padding bridges the gap) and is a
	   little taller than the dot: year + gap + dot are ONE hit area for
	   hover and click. */
	right: 100%;
	padding: 0.25rem 0.75rem 0.25rem 0;
	transform: translateY(-50%);
	font-size: 0.75rem;
	line-height: 1;
	letter-spacing: 0.04em;
	white-space: nowrap;
	opacity: 0.7;
	pointer-events: auto;
}

.ch-toc.is-style-dots.has-short .ch-toc__link.is-active::before {
	opacity: 1;
	font-weight: var(--ch-toc-active-weight);
}

.ch-toc.is-style-dots.has-short .ch-toc__link::after {
	right: calc(100% + 3.75rem);
}

.ch-toc.is-style-dots.has-short.ch-toc--side-left .ch-toc__link::before {
	right: auto;
	left: 100%;
	padding: 0.25rem 0 0.25rem 0.75rem;
}

/* «Chapter names: only on hover» (dotLabels: hover) — the active dot
   shows no title until hovered/focused; the short label still marks it. */
.ch-toc.is-style-dots.ch-toc--labels-hover .ch-toc__link.is-active:not(:hover):not(:focus-visible)::after {
	opacity: 0;
}

.ch-toc.is-style-dots.has-short.ch-toc--side-left .ch-toc__link::after {
	right: auto;
	left: calc(100% + 3.75rem);
}

/* Phones: a floating list is always dots (labels would cover the
   chapter), with a tighter inset. */
@media (max-width: 781px) {
	.ch-toc--floating {
		--ch-toc-float-inset: 0.75rem;
	}

	.ch-toc--floating:not(.is-style-dots) .ch-toc__label,
	.ch-toc--floating:not(.is-style-dots) .ch-toc__marker {
		display: none;
	}

	.ch-toc--floating:not(.is-style-dots) .ch-toc__rail {
		padding: 0;
		border: 0;
	}

	.ch-toc--floating:not(.is-style-dots) .ch-toc__link {
		width: 10px;
		height: 10px;
		padding: 0;
		border-radius: 50%;
		background: currentColor;
		font-size: 0;
		line-height: 0;
		opacity: 0.35;
	}

	.ch-toc--floating:not(.is-style-dots) .ch-toc__link.is-active {
		opacity: 1;
	}

	/* Dots style on phones: dots only — the title label and the idle
	   short labels would cover the chapter; the ACTIVE short label (a
	   year) stays as a small badge next to its dot. */
	.ch-toc--floating.is-style-dots .ch-toc__link::after,
	.ch-toc--floating.is-style-dots.has-short .ch-toc__link:not(.is-active)::before {
		display: none;
	}
}

@media (prefers-reduced-motion: reduce) {
	.ch-toc.is-style-dots .ch-toc__link,
	.ch-toc.is-style-dots .ch-toc__link::after {
		transition: none;
	}
}
