Symptom: On a fresh (no prior consent) visit to docs.vyos.io — e.g. incognito — the Cookiebot consent banner renders completely unstyled: the "Cookiebot by Usercentrics" logo blows up across the page and #CybotCookiebotDialog falls back to position:static, expanding to ~6700px and breaking the layout. Dismissing the banner sets the consent cookie, so it never re-renders and the page looks fine afterwards. It is a race, so it is intermittent.
Root cause (verified in-browser via chrome-devtools): Cookiebot delivers its dialog CSS as a *constructed stylesheet* via document.adoptedStyleSheets (the <style> element path is an old-browser fallback only — so the CSS is invisible to document.styleSheets / <style> / <link>). That property holds the whole sheet list, and ReadTheDocs' readthedocs-addons.js reassigns it with a destructive replace. cc.js is network-gated (~500ms); when RTD's replace lands after Cookiebot's adoption it drops Cookiebot's sheet, leaving the dialog with no CSS. Evidence: in the broken state the only surviving adopted sheet is RTD's @layer defaults{ ... --readthedocs-search-... }; manually replacing document.adoptedStyleSheets in a good state reproduces the exact broken render (dialog position:static, ~6745px, Cookiebot sheet dropped).
Fix:
- docs/_templates/layout.html: a small adoptedStyleSheets shim, installed before any page script, that preserves Cookiebot's sheet so another library cannot drop it.
- docs/_static/css/custom.css: a leak-safe safety net that keeps the dialog contained even if its adopted sheet is ever absent — it uses only properties Cookiebot itself sets, so it has no effect on the normal, styled banner.
Validated end-to-end: 3/3 cold loads render styled with the shim; deterministic re-append holds; zero CSS leak into the styled banner.
Affects all versions sharing the theme (rolling / circinus / sagitta).