/*
 * Inhoudsopgave (table of contents) sidebar — responsive behavior.
 * Loaded by the koopgids-sidebar mu-plugin, only on pages whose content
 * contains the `kijk-toc-panel` class (see ../../koopgids-sidebar.php).
 *
 * Markup requirements:
 *  - `kijk-toc-panel` on the GenerateBlocks container that directly wraps
 *    the "Inhoudsopgave" heading + list (the "Sidebar-innerContainer" block
 *    in the editor's layer tree — currently rendered as .gb-element-7e2f80f5
 *    on the front end). This is the box that actually sticks.
 *  - `kijk-toc-col` on its parent, the "Main-Sidebar-Container" column. GB's
 *    two-column row defaults to `align-items: flex-start`, so that column is
 *    normally only as tall as the (short) panel inside it — leaving the
 *    sticky panel zero room to travel, so it sticks for an instant then
 *    freezes near the top for the rest of the scroll. `kijk-toc-col` forces
 *    that column to stretch to match the content column's height instead.
 *
 * Desktop (> 900px): plain CSS `position: sticky` on the panel itself, so it
 * follows scroll natively with no JS and no jank.
 *
 * Mobile/tablet (<= 900px): the same panel becomes a fixed off-canvas drawer,
 * opened via a vertical tab button fixed to the left edge (injected by
 * toc-sidebar.js). Adjust --kijk-toc-header-offset to match your sticky
 * header's height. The 900px breakpoint is hardcoded (media queries can't
 * read custom properties) — if you change it here, change MOBILE_QUERY in
 * toc-sidebar.js to match.
 */

:root {
	--kijk-toc-header-offset: 140px;
}

/* Anchor-link scroll offset: the site header is GB Pro's "always sticky"
   mode, implemented as position:fixed (with a placeholder div to preserve
   flow height). A native in-page jump like <a href="#afbeelding"> scrolls
   the target's top edge to the very top of the viewport by default — which
   is exactly where that fixed header sits, so it covers the heading (and
   often a paragraph or two below it). scroll-padding-top reserves that same
   clearance for every in-page anchor jump on the page, TOC or otherwise.
   Reuses --kijk-toc-header-offset so there's one value to keep in sync with
   the header's height, not two. */
html {
	scroll-padding-top: var(--kijk-toc-header-offset);
}

@media (prefers-reduced-motion: no-preference) {
	html {
		scroll-behavior: smooth;
	}
}

/* ---------- Desktop: sticky, follows content ---------- */
@media only screen and (min-width: 901px) {
	/* Give the sticky panel room to travel: stretch its column to match the
	   content column's height instead of shrinking to the panel's own
	   (short) height. Works whether the row is flex or grid — align-self
	   behaves the same in both. */
	.kijk-toc-col {
		align-self: stretch !important;
		/* GenerateBlocks sets only min-width:300px on this column with no
		   ceiling, and the row has no flex-wrap — a long enough TOC list
		   can grow it past where it and the content column both still fit
		   the viewport, pushing the whole row (and page) wider than the
		   viewport. Cap it so it wraps its own list items instead. */
		max-width: 340px !important;
	}

	/* !important: GenerateBlocks emits its own per-block stylesheet
	   targeting this same .gb-element-* class (typically with its own
	   `position` declaration), so a plain same-specificity rule here can
	   lose the cascade depending on enqueue order. Same pattern already
	   used elsewhere on this site (see the dibond-calc input styles). */
	.kijk-toc-panel {
		position: sticky !important;
		top: var(--kijk-toc-header-offset) !important;
	}
}

/* Close button is mobile-drawer-only — hidden on desktop where the panel is
   just a static sticky sidebar, not an overlay that needs closing. */
.kijk-toc-close {
	display: none;
}

/* ---------- Mobile / small screens: collapsible off-canvas panel ---------- */
@media only screen and (max-width: 900px) {

	/* Pulling .kijk-toc-panel out to position:fixed only removes IT from
	   flow — its parent column (.kijk-toc-col, "Main-Sidebar-Container")
	   still sits in the row at its original desktop width, as an invisible
	   "ghost" column next to the content column. That pushes the row wider
	   than the viewport, causing horizontal scroll (the extra width is
	   exactly the sidebar's normal desktop width). Zero it out on mobile;
	   overflow:visible keeps it from clipping the fixed child, though fixed
	   positioning already escapes ancestor overflow/width in most cases. */
	.kijk-toc-col {
		width: 0 !important;
		min-width: 0 !important;
		max-width: 0 !important;
		flex: 0 0 0 !important;
		padding: 0 !important;
		margin: 0 !important;
		border: 0 !important;
		overflow: visible !important;
	}

	/* If the row is CSS Grid rather than flex, zeroing the *item* above
	   doesn't shrink its *track* — grid track sizing comes from
	   grid-template-columns on the parent, not the item. Reach the parent
	   without hardcoding GenerateBlocks' auto-generated class name (which
	   can change if that block gets re-edited) via :has(). Unsupported in
	   pre-2022 browsers, but the overflow-x:hidden below is the real
	   safety net for those. */
	*:has(> .kijk-toc-col) {
		display: block !important;
	}

	/* Belt-and-suspenders: whatever the row's exact grid/flex internals turn
	   out to be, this guarantees no scrollable horizontal gap regardless.
	   Mobile-only deliberately: html/body overflow-x != visible forces the
	   browser to also compute overflow-y as auto (per the CSS Overflow
	   spec, since overflow-x/-y can't sensibly differ that way), which
	   breaks position:sticky on any descendant — sticky needs an unbroken
	   chain of overflow:visible ancestors up to the real viewport. Desktop
	   uses position:sticky above; mobile uses position:fixed, which isn't
	   subject to that rule, so it's safe here. */
	html,
	body {
		overflow-x: hidden !important;
	}

	/* !important on the layout-critical properties: .kijk-toc-panel shares
	   its DOM element with GenerateBlocks' own .gb-element-7e2f80f5, which
	   gets its own per-block stylesheet (also possibly with mobile-specific
	   width/position rules, e.g. for stacking columns to 100% width). A
	   plain same-specificity rule can lose that tie depending on stylesheet
	   load order — and caching/optimization plugins (Combine CSS, Remove
	   Unused CSS) can change that order for real (cached, logged-out)
	   visitors even when it looks fine while testing logged in, since most
	   such plugins skip their optimization pipeline for logged-in users.
	   Same pattern already used for the desktop sticky rule below. */
	.kijk-toc-panel {
		position: fixed !important;
		top: 0 !important;
		left: 0 !important;
		width: min(90vw, 380px) !important;
		height: 100dvh !important;
		/* The site header forces itself to z-index:9998/9999 (!important,
		   site-wide, see .gb-site-header / .kijk-topbar) and is always
		   fixed/sticky. Sitting below that let the header render on top of
		   our drawer's first ~100px — hiding the heading and first list
		   item, and swallowing clicks on "Achterwand inmeten" since the
		   header (not our link) received them. Go above both. */
		z-index: 10010 !important;
		overflow-y: auto;
		box-sizing: border-box;
		/* Reuses --kijk-toc-header-offset (same value as the desktop sticky
		   offset and scroll-padding-top) so the list starts fully clear of
		   the header instead of partially underneath it. */
		padding: var(--kijk-toc-header-offset) 24px 32px;
		background-color: var(--beige, #fff);
		box-shadow: 4px 0 16px rgba(0, 0, 0, 0.2);
		transform: translateX(-100%);
		transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1);
	}

	body.kijk-toc-open .kijk-toc-panel {
		transform: translateX(0) !important;
	}

	body.kijk-toc-open {
		overflow: hidden;
	}

	.kijk-toc-close {
		display: flex;
		align-items: center;
		justify-content: center;
		position: absolute;
		top: 16px;
		right: 16px;
		background: none;
		border: none;
		-webkit-appearance: none;
		appearance: none;
		font-size: 28px;
		line-height: 1;
		color: var(--dark-brown);
		cursor: pointer;
		padding: 4px 8px;
	}
}

/* Vertical toggle tab, mobile-only, injected by JS */
.kijk-toc-toggle {
	display: none;
}

@media only screen and (max-width: 900px) {
	/* writing-mode:vertical-rl kept fighting WebKit (partial support on the
	   button, then a flex/vertical-writing-mode bug once appearance:none
	   was added) — dropping it entirely. This outer button now only
	   handles fixed positioning; it is never itself rotated, so its
	   border-radius/border can be authored normally (no mirroring needed).
	   The actual vertical-looking text is a plain horizontal label (see
	   .kijk-toc-toggle-label below) rotated -90deg around its own already-
	   centered position — decoupling "position the tab" from "rotate the
	   text" avoids the pivot-point math a single rotated box would need,
	   and doesn't depend on writing-mode support at all. */
	.kijk-toc-toggle {
		display: block;
		width: 44px;
		height: 170px;
		overflow: visible;
		position: fixed;
		/* top/bottom:0 + margin:auto centers it vertically without relying
		   on top:50% + translateY(-50%) percentage math, which is more
		   exposed to iOS Safari's known quirks around position:fixed and
		   its dynamic toolbar (address bar show/hide). */
		top: 0;
		bottom: 0;
		left: 0;
		margin: auto 0;
		z-index: 9400;
		background-color: var(--dark-brown);
		color: var(--dark-blue);
		border: 2px solid var(--dark-blue);
		border-left: none;
		border-radius: 0 8px 8px 0;
		padding: 0;
		font-family: var(--gp-font--poppins);
		font-weight: 700;
		font-size: 14px;
		letter-spacing: 0.03em;
		cursor: pointer;
		-webkit-appearance: none;
		appearance: none;
		box-shadow: 2px 0 8px rgba(0, 0, 0, 0.15);
		transition: opacity 0.2s ease;
	}

	.kijk-toc-toggle-label {
		position: absolute;
		top: 50%;
		left: 50%;
		/* Center first, then rotate around that already-centered point — the
		   rotation doesn't need to compensate for anything since it can't
		   move a point that's already at its own center. -90deg makes the
		   text read bottom-to-top, matching the original vertical-rl +
		   rotate(180deg) reading direction. */
		transform: translate(-50%, -50%) rotate(-90deg);
		white-space: nowrap;
		pointer-events: none;
	}

	.kijk-toc-toggle:hover,
	.kijk-toc-toggle:focus-visible {
		background-color: var(--light-blue);
	}

	/* Hide the tab (same fade as above, via the shared transition) while:
	   the panel is open, so it doesn't overlap the close button; or the
	   visitor is scrolling/touching elsewhere, so it doesn't sit on top of
	   the text underneath it. kijk-toc-scrolling is toggled by JS on
	   scroll/touchstart/touchmove, cleared on touchend/touchcancel and
	   after a pause in scrolling — see toc-sidebar.js. */
	body.kijk-toc-open .kijk-toc-toggle,
	body.kijk-toc-scrolling .kijk-toc-toggle {
		opacity: 0;
		pointer-events: none;
	}
}

/* Backdrop behind the open panel, mobile-only, injected by JS */
.kijk-toc-backdrop {
	display: none;
}

@media only screen and (max-width: 900px) {
	.kijk-toc-backdrop {
		display: block;
		position: fixed;
		inset: 0;
		/* Above the header's own 9998/9999 (see .kijk-toc-panel comment) so
		   the header dims along with the rest of the page; below the panel
		   itself (10010). */
		z-index: 10000;
		background: rgba(0, 0, 0, 0.45);
		opacity: 0;
		pointer-events: none;
		transition: opacity 0.3s ease;
	}

	body.kijk-toc-open .kijk-toc-backdrop {
		opacity: 1;
		pointer-events: auto;
	}
}
