diff --git a/public/css/wmw-public.css b/public/css/wmw-public.css new file mode 100644 index 0000000..c81a074 --- /dev/null +++ b/public/css/wmw-public.css @@ -0,0 +1,437 @@ +/* ─── WP Multi Wiki — Public CSS ───────────────────────────────────────── + * Nutzt die CSS-Variablen des "Minecraft Modern Theme" von M_Viper. + * Dark- UND Light-Mode automatisch korrekt. + * ─────────────────────────────────────────────────────────────────────── */ + +.wmw-page { + --wmw-accent: var(--primary-accent, #00d4ff); + --wmw-accent-bg: rgba(0, 212, 255, 0.10); + --wmw-radius: 8px; + --wmw-shadow: 0 4px 20px rgba(0, 0, 0, .35); + padding-top: 24px; + font-family: 'Raleway', sans-serif; + color: var(--text-color); +} +.wmw-page * { box-sizing: border-box; } + +/* ─── Layout ─────────────────────────────────────────────────────────── */ +.wmw-layout { + display: grid; gap: 24px; + max-width: 1200px; margin: 0 auto; + padding: 24px 20px 48px; +} +.wmw-layout--left { grid-template-columns: 260px 1fr; } +.wmw-layout--right { grid-template-columns: 1fr 260px; } +.wmw-layout--none { grid-template-columns: 1fr; max-width: 860px; } +.wmw-layout--right .wmw-sidebar { order: 2; } +.wmw-layout--right .wmw-main { order: 1; } +@media (max-width: 768px) { + .wmw-layout--left, .wmw-layout--right { grid-template-columns: 1fr; } + .wmw-layout--right .wmw-sidebar, + .wmw-layout--right .wmw-main { order: unset; } +} + +/* ─── Breadcrumb ─────────────────────────────────────────────────────── */ +.wmw-breadcrumb { padding: 14px 20px; max-width: 1200px; margin: 0 auto; } +.wmw-breadcrumb__list { + list-style: none; margin: 0; padding: 0; + display: flex; flex-wrap: wrap; align-items: center; + gap: 2px; font-size: 13px; +} +.wmw-breadcrumb__link { color: var(--wmw-accent); text-decoration: none; font-weight: 600; } +.wmw-breadcrumb__link:hover { color: var(--text-color); } +.wmw-breadcrumb__sep { padding: 0 4px; color: var(--text-muted); } +.wmw-breadcrumb__item.is-current { color: var(--text-muted); } + +/* ─── Wiki Index ─────────────────────────────────────────────────────── */ +.wmw-wiki-index { max-width: 1100px; margin: 0 auto; padding: 24px 20px 60px; } + +.wmw-wiki-index__header { + display: flex; align-items: center; gap: 20px; + padding: 28px 32px; margin-bottom: 24px; + background-color: var(--card-bg); + border: 1px solid var(--border-color); + border-top: 3px solid var(--wmw-accent); + border-radius: var(--wmw-radius); +} +.wmw-wiki-index__icon { font-size: 52px; line-height: 1; flex-shrink: 0; } +.wmw-wiki-index__title { margin: 0 0 8px; font-size: 28px; font-weight: 700; color: var(--text-color); } +.wmw-wiki-index__desc { margin: 6px 0 0; color: var(--text-muted); font-size: 15px; } + +.wmw-wiki-index__intro { + margin-bottom: 24px; padding: 20px 24px; + background-color: var(--card-bg); + border: 1px solid var(--border-color); + border-radius: var(--wmw-radius); + color: var(--text-color); +} + +/* ─── Version Badge ──────────────────────────────────────────────────── */ +/* Badge im Header nach rechts */ +.wmw-wiki-index__header .wmw-version-badge { margin-left: auto; flex-shrink: 0; font-size: 12px; padding: 4px 14px; } +.wmw-version-badge { + display: inline-block; font-size: 11px; font-weight: 700; + background-color: var(--wmw-accent-bg); color: var(--wmw-accent); + border: 1px solid rgba(0, 212, 255, 0.3); + padding: 2px 10px; border-radius: 20px; +} + +/* ─── Wiki Sections ──────────────────────────────────────────────────── */ +.wmw-wiki-section { + margin-bottom: 24px; + background-color: var(--card-bg); + border: 1px solid var(--border-color); + border-radius: var(--wmw-radius); + padding: 20px 24px; +} +.wmw-wiki-section__title { + font-size: 15px; font-weight: 700; margin: 0 0 16px; + padding-bottom: 10px; + border-bottom: 2px solid var(--wmw-accent); + color: var(--wmw-accent); +} + +/* ─── Article Card Grid ──────────────────────────────────────────────── */ +.wmw-article-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); + gap: 10px; +} +.wmw-article-card { + display: flex; flex-direction: column; justify-content: space-between; + background-color: var(--surface-color); + border: 1px solid var(--border-color); + border-radius: var(--wmw-radius); + padding: 14px 16px; + text-decoration: none; color: var(--text-color); + transition: border-color .2s, box-shadow .2s, transform .2s; + position: relative; overflow: hidden; +} +.wmw-article-card::before { + content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; + background: var(--wmw-accent); opacity: 0; transition: opacity .2s; +} +.wmw-article-card:hover { + border-color: var(--wmw-accent); + box-shadow: 0 0 15px rgba(0, 212, 255, 0.2); + transform: translateY(-2px); + color: var(--text-color); text-decoration: none; +} +.wmw-article-card:hover::before { opacity: 1; } +.wmw-article-card__title { font-size: 14px; font-weight: 600; margin: 0 0 6px; line-height: 1.4; } +.wmw-article-card__excerpt { font-size: 12px; color: var(--text-muted); margin: 0; line-height: 1.5; } +.wmw-article-card__tags { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 10px; } +.wmw-article-card__arrow { position: absolute; right: 12px; bottom: 12px; font-size: 14px; color: var(--wmw-accent); opacity: 0; transition: opacity .2s, transform .2s; } +.wmw-article-card:hover .wmw-article-card__arrow { opacity: 1; transform: translateX(3px); } + +/* ─── Tags ───────────────────────────────────────────────────────────── */ +.wmw-tag { + display: inline-block; font-size: 11px; padding: 2px 8px; border-radius: 20px; + background-color: var(--wmw-accent-bg); + border: 1px solid rgba(0, 212, 255, 0.25); + color: var(--text-muted); + text-decoration: none; transition: background .15s, color .15s; +} +.wmw-tag:hover, .wmw-tag--cat { + background-color: rgba(0, 212, 255, 0.15); + border-color: var(--wmw-accent); color: var(--wmw-accent); +} + +/* ─── Article Page ───────────────────────────────────────────────────── */ +.wmw-article { + background-color: var(--card-bg); + border: 1px solid var(--border-color); + border-radius: var(--wmw-radius); + padding: 32px 36px; + box-shadow: var(--wmw-shadow); + color: var(--text-color); +} +.wmw-article__header { + margin-bottom: 28px; padding-bottom: 20px; + border-bottom: 1px solid var(--border-color); +} +.wmw-article__wiki-link { + display: inline-flex; align-items: center; gap: 6px; font-size: 13px; + color: var(--wmw-accent); text-decoration: none; margin-bottom: 10px; font-weight: 600; +} +.wmw-article__wiki-link:hover { color: var(--text-color); } +.wmw-article__title { margin: 0 0 12px; font-size: 26px; font-weight: 800; color: var(--text-color); } +.wmw-article__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; } +.wmw-article__updated { font-size: 12px; color: var(--text-muted); margin-left: auto; } + +/* ─── Article Body Content ───────────────────────────────────────────── */ +.wmw-article__body { line-height: 1.8; font-size: 15px; color: var(--text-color); } +.wmw-article__body p { color: var(--text-color); margin: 0 0 16px; } +.wmw-article__body a { color: var(--wmw-accent); font-weight: 600; } +.wmw-article__body a:hover { color: var(--text-color); } + +.wmw-article__body h2, +.wmw-article__body h3, +.wmw-article__body h4 { scroll-margin-top: 80px; font-weight: 700; color: var(--text-color); } +.wmw-article__body h2 { font-size: 20px; margin-top: 36px; padding-bottom: 6px; border-bottom: 2px solid var(--wmw-accent); color: var(--wmw-accent); } +.wmw-article__body h3 { font-size: 17px; margin-top: 28px; } + +.wmw-article__body code { + background-color: var(--surface-color); color: var(--wmw-accent); + padding: 2px 6px; border-radius: 4px; font-size: 13px; + border: 1px solid var(--border-color); +} +.wmw-article__body pre { + background-color: var(--bg-color); color: var(--text-color); + border-radius: var(--wmw-radius); padding: 20px; + overflow-x: auto; font-size: 13px; line-height: 1.7; + border: 1px solid var(--border-color); +} +.wmw-article__body pre code { background: none; border: none; color: inherit; padding: 0; } +.wmw-article__body blockquote { + border-left: 4px solid var(--wmw-accent); + padding: 12px 20px; margin: 20px 0; + background-color: var(--wmw-accent-bg); + border-radius: 0 var(--wmw-radius) var(--wmw-radius) 0; + color: var(--text-color); +} +.wmw-article__body table { width: 100%; border-collapse: collapse; margin: 20px 0; } +.wmw-article__body th, +.wmw-article__body td { padding: 10px 14px; border: 1px solid var(--border-color); font-size: 14px; color: var(--text-color); } +.wmw-article__body th { background-color: var(--surface-color); font-weight: 700; color: var(--wmw-accent); } +.wmw-article__footer { margin-top: 40px; } + +/* ───────────────────────────────────────────────────────────────────── + * BILD-AUSRICHTUNG – funktioniert mit Classic Editor UND Gutenberg + * + * Problem: WordPress setzt auf Bilder "aligncenter" als Klasse ODER + * wraps sie in
ODER in

+ * Wenn img { display:block } gesetzt ist, funktioniert text-align nicht mehr. + * Lösung: img bleibt inline (default), nur bei explizitem aligncenter → block + margin:auto + * ───────────────────────────────────────────────────────────────────── */ + +/* Basis: Bilder responsive, aber NICHT display:block (damit text-align klappt) */ +.wmw-article__body img, +.wmw-wiki-index__intro img, +.wmw-wiki-section img { + max-width: 100%; + height: auto; + border-radius: var(--wmw-radius); + /* Kein display:block hier! */ +} + +/* 1. Direktes aligncenter auf dem img-Tag (Classic Editor) */ +.wmw-article__body img.aligncenter, +.wmw-wiki-index__intro img.aligncenter, +.wmw-wiki-section img.aligncenter { + display: block; + margin-left: auto !important; + margin-right: auto !important; +} + +/* 2. Paragraph mit text-align:center (Classic Editor "Ausrichten") */ +.wmw-article__body p[style*="text-align:center"], +.wmw-article__body p[style*="text-align: center"], +.wmw-wiki-index__intro p[style*="text-align:center"], +.wmw-wiki-index__intro p[style*="text-align: center"], +.wmw-wiki-section p[style*="text-align:center"], +.wmw-wiki-section p[style*="text-align: center"] { + text-align: center; +} + +/* 3. figure.aligncenter (Gutenberg wp-block-image) */ +.wmw-article__body figure.aligncenter, +.wmw-article__body .wp-block-image.aligncenter, +.wmw-wiki-index__intro figure.aligncenter, +.wmw-wiki-index__intro .wp-block-image.aligncenter, +.wmw-wiki-section figure.aligncenter, +.wmw-wiki-section .wp-block-image.aligncenter { + display: flex; + flex-direction: column; + align-items: center; + margin-left: auto; + margin-right: auto; + text-align: center; +} +.wmw-article__body figure.aligncenter img, +.wmw-article__body .wp-block-image.aligncenter img, +.wmw-wiki-index__intro figure.aligncenter img, +.wmw-wiki-index__intro .wp-block-image.aligncenter img, +.wmw-wiki-section figure.aligncenter img, +.wmw-wiki-section .wp-block-image.aligncenter img { + display: block; + margin-left: auto; + margin-right: auto; +} + +/* 4. figure.alignleft / alignright */ +.wmw-article__body figure.alignleft, +.wmw-article__body .wp-block-image.alignleft, +.wmw-wiki-index__intro figure.alignleft, +.wmw-wiki-index__intro .wp-block-image.alignleft { float: left; margin: 0 20px 16px 0; } + +.wmw-article__body figure.alignright, +.wmw-article__body .wp-block-image.alignright, +.wmw-wiki-index__intro figure.alignright, +.wmw-wiki-index__intro .wp-block-image.alignright { float: right; margin: 0 0 16px 20px; } + +/* Clearfix */ +.wmw-article__body::after, +.wmw-wiki-index__intro::after { content: ''; display: table; clear: both; } + +/* figcaption */ +.wmw-article__body figcaption, +.wmw-wiki-index__intro figcaption { + text-align: center; font-size: 12px; + color: var(--text-muted); margin-top: 6px; +} + +/* ─── Article Nav (Prev/Next) ────────────────────────────────────────── */ +.wmw-article-nav { + display: grid; grid-template-columns: 1fr 1fr; + gap: 16px; margin-top: 32px; padding-top: 24px; + border-top: 1px solid var(--border-color); +} +.wmw-article-nav__next { text-align: right; } +.wmw-article-nav a { + text-decoration: none; display: flex; flex-direction: column; gap: 3px; + color: var(--text-color); padding: 14px 16px; + background-color: var(--surface-color); + border-radius: var(--wmw-radius); border: 1px solid var(--border-color); + transition: border-color .2s, background-color .2s; +} +.wmw-article-nav a:hover { + border-color: var(--wmw-accent); background-color: var(--wmw-accent-bg); + color: var(--text-color); text-decoration: none; +} +.wmw-article-nav__label { font-size: 11px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .5px; } +.wmw-article-nav__title { font-size: 14px; font-weight: 600; } + +/* ─── Related Articles ───────────────────────────────────────────────── */ +.wmw-related { margin-top: 36px; } +.wmw-related__title { font-size: 16px; font-weight: 700; margin: 0 0 16px; } +.wmw-related-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 10px; } +.wmw-related-item { + display: flex; flex-direction: column; gap: 4px; + text-decoration: none; padding: 14px 16px; + background-color: var(--surface-color); + border: 1px solid var(--border-color); + border-radius: var(--wmw-radius); color: var(--text-color); + transition: border-color .2s, box-shadow .2s; +} +.wmw-related-item:hover { border-color: var(--wmw-accent); box-shadow: 0 0 12px rgba(0,212,255,.15); color: var(--text-color); text-decoration: none; } +.wmw-related-item__title { font-size: 13px; font-weight: 600; } +.wmw-related-item__exc { font-size: 12px; color: var(--text-muted); } + +/* ─── TOC ────────────────────────────────────────────────────────────── */ +.wmw-toc { + background-color: var(--surface-color); + border: 1px solid var(--border-color); + border-left: 4px solid var(--wmw-accent); + border-radius: var(--wmw-radius); padding: 16px 20px; margin: 0 0 28px; max-width: 520px; +} +.wmw-toc__title { display: flex; align-items: center; justify-content: space-between; font-weight: 700; font-size: 14px; margin-bottom: 10px; cursor: pointer; color: var(--text-color); } +.wmw-toc__toggle { background: none; border: none; cursor: pointer; font-size: 12px; color: var(--text-muted); padding: 0; } +.wmw-toc__list { margin: 0; padding-left: 18px; list-style: decimal; } +.wmw-toc__sub { margin: 4px 0 4px 16px; padding-left: 18px; list-style: lower-alpha; } +.wmw-toc li { margin: 5px 0; } +.wmw-toc a { color: var(--wmw-accent); text-decoration: none; font-size: 13px; font-weight: 600; } +.wmw-toc a:hover { color: var(--text-color); text-decoration: underline; } +.wmw-toc.is-collapsed .wmw-toc__list { display: none; } + +/* ─── Sidebar ────────────────────────────────────────────────────────── */ +.wmw-sidebar { + position: sticky; top: 80px; + max-height: none; overflow-y: visible; + scrollbar-width: thin; scrollbar-color: var(--wmw-accent) var(--surface-color); +} +.wmw-sidebar::-webkit-scrollbar { width: 4px; } +.wmw-sidebar::-webkit-scrollbar-thumb { background: var(--wmw-accent); border-radius: 4px; } + +.wmw-sidebar-nav { + background-color: var(--card-bg); border: 1px solid var(--border-color); + border-radius: var(--wmw-radius); overflow: hidden; +} +.wmw-sidebar-nav__wiki { padding: 14px 16px; border-bottom: 2px solid var(--wmw-accent); background-color: var(--wmw-accent-bg); } +.wmw-sidebar-nav__wiki-link { display: flex; align-items: center; gap: 8px; text-decoration: none; color: var(--text-color); font-weight: 700; font-size: 14px; } +.wmw-sidebar-nav__wiki-link:hover { color: var(--wmw-accent); text-decoration: none; } +.wmw-sidebar-nav__wiki-icon { font-size: 20px; } +.wmw-sidebar-nav__group { padding: 10px 0; border-bottom: 1px solid var(--border-color); } +.wmw-sidebar-nav__group:last-child { border-bottom: none; } +.wmw-sidebar-nav__group-label { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .7px; color: var(--wmw-accent); padding: 0 16px 6px; } +.wmw-sidebar-nav__list { list-style: none; margin: 0; padding: 0; } +.wmw-sidebar-nav__link { + display: block; padding: 6px 16px; font-size: 13px; + color: var(--text-muted); text-decoration: none; + transition: background-color .15s, color .15s, padding-left .15s; + border-left: 2px solid transparent; +} +.wmw-sidebar-nav__link:hover { background-color: var(--wmw-accent-bg); color: var(--wmw-accent); border-left-color: var(--wmw-accent); padding-left: 20px; text-decoration: none; } +.wmw-sidebar-nav__item.is-active .wmw-sidebar-nav__link { font-weight: 700; color: var(--wmw-accent); background-color: var(--wmw-accent-bg); border-left-color: var(--wmw-accent); padding-left: 20px; } + +.wmw-sidebar-header { margin-bottom: 12px; padding-bottom: 12px; border-bottom: 1px solid var(--border-color); } +.wmw-sidebar-wiki-link { display: flex; align-items: center; gap: 6px; color: var(--wmw-accent); text-decoration: none; font-weight: 600; font-size: 14px; } +.wmw-sidebar-wiki-link:hover { color: var(--text-color); } +.wmw-sidebar-search { margin-bottom: 12px; } + +/* ─── Search Box ─────────────────────────────────────────────────────── */ +.wmw-search { position: relative; margin-bottom: 16px; } +.wmw-search__wrap { position: relative; } +.wmw-search__input { + width: 100%; padding: 10px 40px 10px 14px; font-size: 14px; + border: 1px solid var(--border-color); border-radius: var(--wmw-radius); + background-color: var(--surface-color); color: var(--text-color); + padding-top: 24px; + font-family: 'Raleway', sans-serif; + transition: border-color .2s, box-shadow .2s; outline: none; +} +.wmw-search__input::placeholder { color: var(--text-muted); } +.wmw-search__input:focus { border-color: var(--wmw-accent); box-shadow: 0 0 0 2px rgba(0,212,255,.2); } +.wmw-search__icon { position: absolute; right: 12px; top: 50%; transform: translateY(-50%); pointer-events: none; color: var(--text-muted); } +.wmw-search__results { + position: absolute; top: calc(100% + 6px); left: 0; right: 0; + background-color: var(--card-bg); + border: 1px solid var(--border-color); border-top: 2px solid var(--wmw-accent); + border-radius: var(--wmw-radius); z-index: 9999; + box-shadow: 0 10px 30px rgba(0,0,0,.5); + max-height: 400px; overflow-y: auto; +} +.wmw-search__results-inner { padding: 8px; } +.wmw-search-result { display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px; border-radius: 6px; text-decoration: none; color: var(--text-color); border-bottom: 1px solid var(--border-color); transition: background-color .15s; } +.wmw-search-result:last-child { border-bottom: none; } +.wmw-search-result:hover { background-color: var(--wmw-accent-bg); color: var(--text-color); text-decoration: none; } +.wmw-search-result__icon { font-size: 20px; flex-shrink: 0; } +.wmw-search-result__body { min-width: 0; } +.wmw-search-result__title { font-size: 13px; font-weight: 600; margin-bottom: 2px; } +.wmw-search-result__wiki { font-size: 11px; color: var(--wmw-accent); margin-bottom: 2px; font-weight: 700; } +.wmw-search-result__exc { font-size: 12px; color: var(--text-muted); } +.wmw-search-no-results { padding: 16px; text-align: center; color: var(--text-muted); font-size: 13px; } +.wmw-highlight { background-color: rgba(0,212,255,.2); color: var(--text-color); border-radius: 2px; padding: 0 2px; } + +/* ─── Wiki List Shortcode ────────────────────────────────────────────── */ +.wmw-wiki-list { display: grid; grid-template-columns: repeat(var(--wmw-cols, 3), 1fr); gap: 16px; margin: 20px 0; } +@media (max-width: 900px) { .wmw-wiki-list { grid-template-columns: repeat(2,1fr); } } +@media (max-width: 560px) { .wmw-wiki-list { grid-template-columns: 1fr; } } + +.wmw-wiki-card-public { + display: flex; align-items: center; gap: 14px; + background-color: var(--card-bg); border: 1px solid var(--border-color); + border-radius: var(--wmw-radius); padding: 18px 16px; + text-decoration: none; color: var(--text-color); + transition: border-color .2s, box-shadow .2s, transform .2s; + border-left: 4px solid var(--wiki-color, var(--wmw-accent)); +} +.wmw-wiki-card-public:hover { border-color: var(--wiki-color, var(--wmw-accent)); box-shadow: 0 0 20px rgba(0,212,255,.2); transform: translateY(-2px); color: var(--text-color); text-decoration: none; } +.wmw-wiki-card-public__icon { font-size: 32px; flex-shrink: 0; } +.wmw-wiki-card-public__body { flex: 1; min-width: 0; } +.wmw-wiki-card-public__title { font-size: 15px; font-weight: 700; margin: 0 0 4px; } +.wmw-wiki-card-public__desc { font-size: 12px; color: var(--text-muted); margin: 0 0 8px; } +.wmw-wiki-card-public__footer { display: flex; gap: 10px; align-items: center; font-size: 11px; color: var(--text-muted); } +.wmw-wiki-card-public__arrow { margin-left: auto; font-size: 16px; color: var(--wmw-accent); opacity: 0; transition: opacity .2s; } +.wmw-wiki-card-public:hover .wmw-wiki-card-public__arrow { opacity: 1; } + +/* ─── Empty State ────────────────────────────────────────────────────── */ +.wmw-empty-state--inline { text-align: center; padding: 40px 20px; color: var(--text-muted); background-color: var(--surface-color); border-radius: var(--wmw-radius); border: 1px dashed var(--border-color); } + +/* ─── Responsive ─────────────────────────────────────────────────────── */ +@media (max-width: 768px) { + .wmw-article { padding: 20px 18px; } + .wmw-article__title { font-size: 22px; } + .wmw-wiki-index__header { flex-direction: column; } + .wmw-article-nav { grid-template-columns: 1fr; } +} \ No newline at end of file diff --git a/public/js/wmw-public.js b/public/js/wmw-public.js new file mode 100644 index 0000000..45b1dbc --- /dev/null +++ b/public/js/wmw-public.js @@ -0,0 +1,126 @@ +/* jshint esversion: 6 */ +jQuery(function ($) { + 'use strict'; + + // ── TOC Toggle ──────────────────────────────────────────────────────── + $(document).on('click', '.wmw-toc__title, .wmw-toc__toggle', function () { + var $toc = $(this).closest('.wmw-toc'); + var $btn = $toc.find('.wmw-toc__toggle'); + $toc.toggleClass('is-collapsed'); + $btn.text($toc.hasClass('is-collapsed') ? '▶' : '▼'); + }); + + // ── TOC Active Heading Highlight ────────────────────────────────────── + if ($('.wmw-toc').length && $('[id]').length) { + var headingIds = []; + $('.wmw-toc a').each(function () { + var href = $(this).attr('href'); + if (href && href.startsWith('#')) { + headingIds.push(href.substring(1)); + } + }); + + var $tocLinks = $('.wmw-toc a'); + + function highlightToc() { + var scrollTop = $(window).scrollTop() + 120; + var active = null; + headingIds.forEach(function (id) { + var $el = $('#' + id); + if ($el.length && $el.offset().top <= scrollTop) { + active = id; + } + }); + $tocLinks.removeClass('is-active'); + if (active) { + $tocLinks.filter('[href="#' + active + '"]').addClass('is-active'); + } + } + + $(window).on('scroll.wmwToc', highlightToc); + highlightToc(); + } + + // ── AJAX Search ─────────────────────────────────────────────────────── + var searchTimer = null; + + $(document).on('input', '.wmw-search__input', function () { + var $input = $(this); + var $wrap = $input.closest('.wmw-search'); + var $results = $wrap.find('.wmw-search__results'); + var $inner = $wrap.find('.wmw-search__results-inner'); + var query = $input.val().trim(); + var wikiId = $wrap.data('wiki-id') || 0; + + clearTimeout(searchTimer); + + if (query.length < 2) { + $results.attr('hidden', ''); + return; + } + + searchTimer = setTimeout(function () { + $inner.html('

🔍 Suche…
'); + $results.removeAttr('hidden'); + + $.post(wmwPublic.ajaxUrl, { + action: 'wmw_search', + query: query, + wiki_id: wikiId, + nonce: wmwPublic.nonce, + }, function (res) { + if (!res.success) { $inner.html('
Fehler bei der Suche.
'); return; } + + var results = res.data.results; + if (!results || results.length === 0) { + $inner.html('
Keine Ergebnisse für „' + escHtml(query) + '"
'); + return; + } + + var html = ''; + results.forEach(function (r) { + html += ''; + html += '' + r.icon + ''; + html += '
'; + if (r.wiki) html += '
' + escHtml(r.wiki) + '
'; + html += '
' + r.title + '
'; + if (r.excerpt) html += '
' + r.excerpt + '
'; + html += '
'; + }); + + $inner.html(html); + }); + }, 280); + }); + + // Close search on outside click + $(document).on('click', function (e) { + if (!$(e.target).closest('.wmw-search').length) { + $('.wmw-search__results').attr('hidden', ''); + } + }); + + // Prevent closing when clicking inside results + $(document).on('click', '.wmw-search__results', function (e) { + e.stopPropagation(); + }); + + // ── Smooth Scroll for TOC links ─────────────────────────────────────── + $(document).on('click', '.wmw-toc a', function (e) { + var href = $(this).attr('href'); + if (href && href.startsWith('#')) { + var $target = $(href); + if ($target.length) { + e.preventDefault(); + $('html, body').animate({ scrollTop: $target.offset().top - 80 }, 400); + } + } + }); + + // ── Helper ──────────────────────────────────────────────────────────── + function escHtml(str) { + return str.replace(/[&<>"']/g, function (c) { + return { '&':'&','<':'<','>':'>','"':'"',"'":''' }[c]; + }); + } +});