New upstream version 4.4.1+ds1
authorSimon McVittie <smcv@debian.org>
Fri, 5 Nov 2021 09:59:55 +0000 (09:59 +0000)
committerSimon McVittie <smcv@debian.org>
Fri, 5 Nov 2021 09:59:55 +0000 (09:59 +0000)
46 files changed:
1  2 
gtk/theme/Default/Default-dark.css
gtk/theme/Default/Default-hc-dark.css
gtk/theme/Default/Default-hc.css
gtk/theme/Default/Default-light.css
subprojects/gi-docgen/.gitlab-ci.yml
subprojects/gi-docgen/README.md
subprojects/gi-docgen/docs/RELEASING.md
subprojects/gi-docgen/docs/attributes.rst
subprojects/gi-docgen/docs/gi-docgen.1
subprojects/gi-docgen/docs/linking.rst
subprojects/gi-docgen/docs/project-configuration.rst
subprojects/gi-docgen/docs/tools/check.rst
subprojects/gi-docgen/docs/tools/gen-index.rst
subprojects/gi-docgen/docs/tools/generate.rst
subprojects/gi-docgen/docs/tools/index.rst
subprojects/gi-docgen/gidocgen/config.py
subprojects/gi-docgen/gidocgen/core.py
subprojects/gi-docgen/gidocgen/gdcheck.py
subprojects/gi-docgen/gidocgen/gdgendeps.py
subprojects/gi-docgen/gidocgen/gdgenerate.py
subprojects/gi-docgen/gidocgen/gdgenindices.py
subprojects/gi-docgen/gidocgen/gidocmain.py
subprojects/gi-docgen/gidocgen/gir/ast.py
subprojects/gi-docgen/gidocgen/gir/parser.py
subprojects/gi-docgen/gidocgen/log.py
subprojects/gi-docgen/gidocgen/mdext.py
subprojects/gi-docgen/gidocgen/templates/basic/base.html
subprojects/gi-docgen/gidocgen/templates/basic/basic.toml
subprojects/gi-docgen/gidocgen/templates/basic/class.html
subprojects/gi-docgen/gidocgen/templates/basic/class_method.html
subprojects/gi-docgen/gidocgen/templates/basic/enum.html
subprojects/gi-docgen/gidocgen/templates/basic/function.html
subprojects/gi-docgen/gidocgen/templates/basic/interface.html
subprojects/gi-docgen/gidocgen/templates/basic/main.js
subprojects/gi-docgen/gidocgen/templates/basic/method.html
subprojects/gi-docgen/gidocgen/templates/basic/property.html
subprojects/gi-docgen/gidocgen/templates/basic/search.js
subprojects/gi-docgen/gidocgen/templates/basic/signal.html
subprojects/gi-docgen/gidocgen/templates/basic/solarized-dark.css
subprojects/gi-docgen/gidocgen/templates/basic/solarized-light.css
subprojects/gi-docgen/gidocgen/templates/basic/struct.html
subprojects/gi-docgen/gidocgen/templates/basic/style.css
subprojects/gi-docgen/gidocgen/templates/basic/type_func.html
subprojects/gi-docgen/gidocgen/templates/basic/vfunc.html
subprojects/gi-docgen/gidocgen/utils.py
subprojects/gi-docgen/meson.build

index 25986683931cc081b7502950a0810685b6c5c05b,0000000000000000000000000000000000000000..5ee5ec845b05d9f457a412ae479d0a1cf34c59c8
mode 100644,000000..100644
--- /dev/null
@@@ -1,1858 -1,0 +1,1848 @@@
- button.sidebar-button, notebook > header > tabs > arrow, windowcontrols button, notebook > header > tabs > arrow.flat, button.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; transition: none; }
 +/*************************** Check and Radio buttons * */
 +/*************** Base States * */
 +.background { color: #eeeeec; background-color: #353535; }
 +
 +.background:backdrop { text-shadow: none; -gtk-icon-shadow: none; }
 +
 +dnd { color: #eeeeec; }
 +
 +.normal-icons { -gtk-icon-size: 16px; }
 +
 +.large-icons { -gtk-icon-size: 32px; }
 +
 +image:disabled { -gtk-icon-filter: opacity(0.5); }
 +
 +.view, iconview, textview > text { color: white; background-color: #2d2d2d; }
 +
 +.view:disabled, iconview:disabled, textview > text:disabled { color: #919190; background-color: #323232; }
 +
 +.view:selected:focus, iconview:selected:focus, .view:selected, iconview:selected, textview > text:selected:focus, textview > text:selected { border-radius: 3px; }
 +
 +textview:drop(active) { caret-color: #26a269; }
 +
 +textview > border { background-color: #313131; }
 +
 +iconview { transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +iconview { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +iconview:focus:focus-visible { outline-color: rgba(21, 83, 158, 0.7); outline-width: 2px; outline-offset: -2px; }
 +
 +iconview:drop(active) { box-shadow: none; }
 +
 +iconview > dndtarget:drop(active) { border-style: solid; border-width: 1px; border-color: #030c17; }
 +
 +rubberband, .content-view > rubberband, columnview.view > rubberband, treeview.view > rubberband, gridview > rubberband, flowbox > rubberband { border: 1px solid #0f3b71; background-color: rgba(15, 59, 113, 0.2); }
 +
 +flowbox > flowboxchild { padding: 3px; transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +flowbox > flowboxchild { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +flowbox > flowboxchild:focus:focus-visible { outline-color: rgba(21, 83, 158, 0.7); outline-width: 2px; outline-offset: -2px; }
 +
 +flowbox > flowboxchild:selected { outline-color: rgba(255, 255, 255, 0.3); }
 +
 +gridview > child { padding: 3px; transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +gridview > child { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +gridview > child:focus:focus-visible { outline-color: rgba(21, 83, 158, 0.7); outline-width: 2px; outline-offset: -2px; }
 +
 +gridview > child:selected { outline-color: rgba(255, 255, 255, 0.3); }
 +
 +gridview > child box { border-spacing: 8px; margin: 12px; }
 +
 +coverflow cover { color: white; background-color: #2d2d2d; border: 1px solid black; }
 +
 +label { transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +label { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +label:focus:focus-visible { outline-color: rgba(21, 83, 158, 0.7); outline-width: 2px; outline-offset: -2px; }
 +
 +label > selection { background-color: #15539e; color: #ffffff; }
 +
 +label:disabled { color: #919190; }
 +
 +button label:disabled { color: inherit; }
 +
 +label.error { color: #cc0000; }
 +
 +label.error:disabled { color: rgba(204, 0, 0, 0.5); }
 +
 +.dim-label, .titlebar:not(headerbar) .subtitle, headerbar .subtitle, spinbutton.vertical > text > text > placeholder, spinbutton:not(.vertical) > text > placeholder, entry > text > placeholder, label.separator { opacity: 0.55; text-shadow: none; }
 +
 +window.assistant .sidebar { padding: 5px; border-top: 1px solid #1b1b1b; }
 +
 +window.assistant.csd .sidebar { border-top-style: none; }
 +
 +window.assistant .sidebar > label { padding: 6px 12px; }
 +
 +window.assistant .sidebar > label.highlight { background-color: #202020; border-radius: 5px; }
 +
 +window.aboutdialog image.large-icons { -gtk-icon-size: 128px; }
 +
 +.osd .scale-popup, .app-notification, .osd popover.background > arrow, .osd popover.background > contents, popover.background.touch-selection > arrow, popover.background.touch-selection > contents, popover.background.magnifier > arrow, popover.background.magnifier > contents, .osd { color: #eeeeec; border: none; background-color: rgba(38, 38, 38, 0.7); background-clip: padding-box; -gtk-icon-shadow: 0 1px black; }
 +
 +/********************* Spinner Animation * */
 +@keyframes spin { to { transform: rotate(1turn); } }
 +
 +spinner { background: none; opacity: 0; -gtk-icon-source: -gtk-icontheme("process-working-symbolic"); }
 +
 +spinner:checked { opacity: 1; animation: spin 1s linear infinite; }
 +
 +spinner:checked:disabled { opacity: 0.5; }
 +
 +/********************** General Typography * */
 +.large-title { font-weight: 300; font-size: 24pt; }
 +
 +.title-1 { font-weight: 800; font-size: 20pt; }
 +
 +.title-2 { font-weight: 800; font-size: 15pt; }
 +
 +.title-3 { font-weight: 700; font-size: 15pt; }
 +
 +.title-4 { font-weight: 700; font-size: 13pt; }
 +
 +.heading { font-weight: 700; font-size: 11pt; }
 +
 +.body { font-weight: 400; font-size: 11pt; }
 +
 +.caption-heading { font-weight: 700; font-size: 9pt; }
 +
 +.caption { font-weight: 400; font-size: 9pt; }
 +
 +/**************** Text Entries * */
 +spinbutton.vertical > text, spinbutton:not(.vertical), entry { min-height: 32px; padding-left: 8px; padding-right: 8px; border: 1px solid; border-radius: 5px; border-spacing: 6px; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); color: white; border-color: #1b1b1b; background-color: #2d2d2d; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +spinbutton.vertical > text, spinbutton:not(.vertical), entry { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +spinbutton.vertical > text:focus-within, spinbutton:focus-within:not(.vertical), entry:focus-within { outline-color: rgba(21, 83, 158, 0.7); outline-width: 2px; outline-offset: -2px; }
 +
 +spinbutton.vertical > text > image.left, spinbutton:not(.vertical) > image.left, entry > image.left { margin-right: 6px; }
 +
 +spinbutton.vertical > text > image.right, spinbutton:not(.vertical) > image.right, entry > image.right { margin-left: 6px; }
 +
 +spinbutton.vertical > text > text > block-cursor, spinbutton:not(.vertical) > text > block-cursor, entry > text > block-cursor { color: #2d2d2d; background-color: white; }
 +
 +spinbutton.vertical > text.flat, spinbutton.flat:not(.vertical), entry.flat:focus-within, entry.flat:backdrop, entry.flat:disabled, entry.flat { min-height: 0; padding: 2px; background-color: transparent; border-color: transparent; border-radius: 0; }
 +
 +spinbutton.vertical > text:focus-within > placeholder, spinbutton:focus-within:not(.vertical) > placeholder, entry:focus-within > placeholder { opacity: 0; /* We hide placeholders on focus */ }
 +
 +spinbutton.vertical > text:disabled, spinbutton:disabled:not(.vertical), entry:disabled { color: #919190; border-color: #1b1b1b; background-color: #323232; }
 +
 +spinbutton.vertical > text.error, spinbutton.error:not(.vertical), entry.error { color: #cc0000; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +spinbutton.vertical > text.error, spinbutton.error:not(.vertical), entry.error { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +spinbutton.vertical > text.error:focus-within, spinbutton.error:focus-within:not(.vertical), entry.error:focus-within { outline-color: rgba(204, 0, 0, 0.5); outline-width: 2px; outline-offset: -2px; }
 +
 +spinbutton.vertical > text.error > selection, spinbutton.error:not(.vertical) > selection, entry.error > selection { background-color: #cc0000; }
 +
 +spinbutton.vertical > text.warning, spinbutton.warning:not(.vertical), entry.warning { color: #f57900; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +spinbutton.vertical > text.warning, spinbutton.warning:not(.vertical), entry.warning { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +spinbutton.vertical > text.warning:focus-within, spinbutton.warning:focus-within:not(.vertical), entry.warning:focus-within { outline-color: rgba(245, 121, 0, 0.5); outline-width: 2px; outline-offset: -2px; }
 +
 +spinbutton.vertical > text.warning > selection, spinbutton.warning:not(.vertical) > selection, entry.warning > selection { background-color: #f57900; }
 +
 +spinbutton.vertical > text > image, spinbutton:not(.vertical) > image, entry > image { color: #c7c7c6; }
 +
 +spinbutton.vertical > text > image:hover, spinbutton:not(.vertical) > image:hover, entry > image:hover { color: #eeeeec; }
 +
 +spinbutton.vertical > text > image:active, spinbutton:not(.vertical) > image:active, entry > image:active { color: #15539e; }
 +
 +spinbutton.vertical > text.password image.caps-lock-indicator, spinbutton.password:not(.vertical) image.caps-lock-indicator, entry.password image.caps-lock-indicator { color: #7e7e7d; }
 +
 +spinbutton.vertical > text:drop(active), spinbutton:drop(active):not(.vertical), entry:drop(active):focus-within, entry:drop(active) { border-color: #26a269; box-shadow: inset 0 0 0 1px #26a269; }
 +
 +.osd spinbutton.vertical > text, .osd spinbutton:not(.vertical), .osd entry { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: rgba(0, 0, 0, 0.5); background-clip: padding-box; box-shadow: none; -gtk-icon-shadow: 0 1px black; }
 +
 +.osd spinbutton.vertical > text:focus-within, .osd spinbutton:focus-within:not(.vertical), .osd entry:focus-within { color: white; border-color: #15539e; background-color: rgba(0, 0, 0, 0.5); background-clip: padding-box; }
 +
 +.osd spinbutton.vertical > text:disabled, .osd spinbutton:disabled:not(.vertical), .osd entry:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: rgba(58, 58, 57, 0.5); background-clip: padding-box; }
 +
 +spinbutton.vertical > text > progress, spinbutton:not(.vertical) > progress, entry > progress { margin-bottom: 2px; }
 +
 +spinbutton.vertical > text progress > trough > progress, spinbutton:not(.vertical) progress > trough > progress, entry progress > trough > progress { background-color: transparent; background-image: none; border-radius: 0; border-width: 0 0 2px; border-color: #15539e; border-style: solid; box-shadow: none; }
 +
 +spinbutton.vertical.linked:not(.vertical) > text:drop(active) + text, spinbutton.vertical.linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + text, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + spinbutton:not(.vertical), .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + spinbutton:not(.vertical), spinbutton.vertical.linked:not(.vertical) > text:drop(active) + button, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + button, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + menubutton > button, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + menubutton > button, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + dropdown > button, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + dropdown > button, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + colorbutton > button, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + colorbutton > button, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + fontbutton > button, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + fontbutton > button, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + filechooserbutton > button, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + filechooserbutton > button, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + combobox > box > button.combo, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + combobox > box > button.combo, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + entry, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + entry, .linked:not(.vertical) > entry:drop(active) + button, .linked:not(.vertical) > entry:drop(active) + menubutton > button, .linked:not(.vertical) > entry:drop(active) + dropdown > button, .linked:not(.vertical) > entry:drop(active) + colorbutton > button, .linked:not(.vertical) > entry:drop(active) + fontbutton > button, .linked:not(.vertical) > entry:drop(active) + filechooserbutton > button, .linked:not(.vertical) > entry:drop(active) + combobox > box > button.combo, spinbutton.vertical.linked:not(.vertical) > entry:drop(active) + text, .linked:not(.vertical) > entry:drop(active) + spinbutton:not(.vertical), .linked:not(.vertical) > entry:drop(active) + entry { border-left-color: #26a269; }
 +
 +spinbutton.vertical.linked > text:not(:disabled) + entry:not(:disabled), .linked.vertical > spinbutton:not(:disabled):not(.vertical) + entry:not(:disabled), spinbutton.vertical.linked > text:not(:disabled) + text:not(:disabled), spinbutton.vertical.linked > spinbutton:not(:disabled):not(.vertical) + text:not(:disabled), spinbutton.vertical.linked > text:not(:disabled) + spinbutton:not(:disabled):not(.vertical), .linked.vertical > spinbutton:not(:disabled):not(.vertical) + spinbutton:not(:disabled):not(.vertical), .linked.vertical > entry:not(:disabled) + entry:not(:disabled), spinbutton.vertical.linked > entry:not(:disabled) + text:not(:disabled), .linked.vertical > entry:not(:disabled) + spinbutton:not(:disabled):not(.vertical) { border-top-color: #282828; }
 +
 +spinbutton.vertical.linked > text:disabled + text:disabled, spinbutton.vertical.linked > spinbutton:disabled:not(.vertical) + text:disabled, spinbutton.vertical.linked > text:disabled + spinbutton:disabled:not(.vertical), .linked.vertical > spinbutton:disabled:not(.vertical) + spinbutton:disabled:not(.vertical), spinbutton.vertical.linked > text:disabled + entry:disabled, .linked.vertical > spinbutton:disabled:not(.vertical) + entry:disabled, spinbutton.vertical.linked > entry:disabled + text:disabled, .linked.vertical > entry:disabled + spinbutton:disabled:not(.vertical), .linked.vertical > entry:disabled + entry:disabled { border-top-color: #282828; }
 +
 +spinbutton.vertical.linked > text + text:drop(active):not(:only-child), spinbutton.vertical.linked > spinbutton:not(.vertical) + text:drop(active):not(:only-child), spinbutton.vertical.linked > text + spinbutton:drop(active):not(:only-child):not(.vertical), .linked.vertical > spinbutton:not(.vertical) + spinbutton:drop(active):not(:only-child):not(.vertical), spinbutton.vertical.linked > text + entry:drop(active):not(:only-child), .linked.vertical > spinbutton:not(.vertical) + entry:drop(active):not(:only-child), spinbutton.vertical.linked > entry + text:drop(active):not(:only-child), .linked.vertical > entry + spinbutton:drop(active):not(:only-child):not(.vertical), .linked.vertical > entry + entry:drop(active):not(:only-child) { border-top-color: #26a269; }
 +
 +spinbutton.vertical.linked > text:drop(active):not(:only-child) + text, spinbutton.vertical.linked > spinbutton:drop(active):not(:only-child):not(.vertical) + text, spinbutton.vertical.linked > text:drop(active):not(:only-child) + spinbutton:not(.vertical), .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + spinbutton:not(.vertical), spinbutton.vertical.linked > text:drop(active):not(:only-child) + entry, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + entry, spinbutton.vertical.linked > text:drop(active):not(:only-child) + button, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + button, spinbutton.vertical.linked > text:drop(active):not(:only-child) + menubutton > button, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + menubutton > button, spinbutton.vertical.linked > text:drop(active):not(:only-child) + dropdown > button, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + dropdown > button, spinbutton.vertical.linked > text:drop(active):not(:only-child) + colorbutton > button, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + colorbutton > button, spinbutton.vertical.linked > text:drop(active):not(:only-child) + fontbutton > button, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + fontbutton > button, spinbutton.vertical.linked > text:drop(active):not(:only-child) + filechooserbutton > button, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + filechooserbutton > button, spinbutton.vertical.linked > text:drop(active):not(:only-child) + combobox > box > button.combo, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + combobox > box > button.combo, spinbutton.vertical.linked > entry:drop(active):not(:only-child) + text, .linked.vertical > entry:drop(active):not(:only-child) + spinbutton:not(.vertical), .linked.vertical > entry:drop(active):not(:only-child) + entry, .linked.vertical > entry:drop(active):not(:only-child) + button, .linked.vertical > entry:drop(active):not(:only-child) + menubutton > button, .linked.vertical > entry:drop(active):not(:only-child) + dropdown > button, .linked.vertical > entry:drop(active):not(:only-child) + colorbutton > button, .linked.vertical > entry:drop(active):not(:only-child) + fontbutton > button, .linked.vertical > entry:drop(active):not(:only-child) + filechooserbutton > button, .linked.vertical > entry:drop(active):not(:only-child) + combobox > box > button.combo { border-top-color: #26a269; }
 +
 +spinbutton.vertical > text.error, spinbutton.error:not(.vertical), entry.error { color: #cc0000; }
 +
 +treeview entry:focus-within:dir(rtl), treeview entry:focus-within:dir(ltr) { background-color: #2d2d2d; transition-property: color, background; }
 +
 +treeview entry.flat, treeview entry { border-radius: 0; background-image: none; background-color: #2d2d2d; }
 +
 +treeview entry.flat:focus-within, treeview entry:focus-within { border-color: #15539e; }
 +
 +/******************* Editable Labels * */
 +editablelabel > stack > text { color: white; border-color: #1b1b1b; background-color: #2d2d2d; }
 +
 +/*********** Buttons * */
 +@keyframes needs_attention { from { background-image: radial-gradient(farthest-side, #1f76e1 0%, rgba(31, 118, 225, 0) 0%); }
 +  to { background-image: radial-gradient(farthest-side, #1f76e1 95%, rgba(31, 118, 225, 0)); } }
 +
 +notebook > header > tabs > arrow, windowcontrols button, button { min-height: 24px; min-width: 16px; padding: 4px 9px; border: 1px solid; border-radius: 5px; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); color: #eeeeec; outline-color: rgba(21, 83, 158, 0.7); border-color: #1b1b1b; background-image: linear-gradient(to top, #373737 2px, #3a3a3a); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +notebook > header > tabs > arrow, windowcontrols button, button { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +notebook > header > tabs > arrow:focus:focus-visible, button:focus:focus-visible { outline-color: rgba(21, 83, 158, 0.7); outline-width: 2px; outline-offset: -2px; }
 +
 +notebook > header > tabs > arrow:hover, button:hover { color: #eeeeec; border-color: #1b1b1b; background-image: linear-gradient(to top, #303030 20%, #323232 90%); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); -gtk-icon-filter: brightness(1.2); }
 +
 +notebook > header > tabs > arrow.keyboard-activating, notebook > header > tabs > arrow:active, notebook > header > tabs > arrow:checked, button.keyboard-activating, button:active, button:checked { color: #eeeeec; border-color: #1b1b1b; background-image: image(#232323); box-shadow: none; transition-duration: 50ms; }
 +
 +notebook > header > tabs > arrow:checked:hover, button:checked:hover { color: #eeeeec; border-color: #1b1b1b; background-image: image(#1b1b1b); box-shadow: none; }
 +
 +notebook > header > tabs > arrow:checked:active, button:checked:active { color: #eeeeec; border-color: #1b1b1b; background-image: image(#161616); box-shadow: none; }
 +
 +notebook > header > tabs > arrow:backdrop, button.flat:backdrop, button:backdrop { color: #919190; border-color: #202020; background-image: image(#353535); box-shadow: none; transition: 200ms ease-out; }
 +
 +notebook > header > tabs > arrow:backdrop:not(:disabled), button.flat:backdrop:not(:disabled), button:backdrop:not(:disabled) { -gtk-icon-filter: none; }
 +
 +notebook > header > tabs > arrow:backdrop:active, notebook > header > tabs > arrow:backdrop:checked, button.flat:backdrop:active, button.flat:backdrop:checked, button:backdrop:active, button:backdrop:checked { color: #919190; border-color: #202020; background-image: image(#2e2e2e); box-shadow: none; }
 +
 +notebook > header > tabs > arrow:backdrop:disabled, button.flat:backdrop:disabled, button:backdrop:disabled { color: #5b5b5b; border-color: #202020; background-image: image(#323232); box-shadow: none; }
 +
 +notebook > header > tabs > arrow:backdrop:disabled:active, notebook > header > tabs > arrow:backdrop:disabled:checked, button.flat:backdrop:disabled:active, button.flat:backdrop:disabled:checked, button:backdrop:disabled:active, button:backdrop:disabled:checked { color: #5b5b5b; border-color: #202020; background-image: image(#2e2e2e); box-shadow: none; }
 +
 +notebook > header > tabs > arrow:disabled, button:disabled { color: #919190; border-color: #202020; background-image: image(#323232); -gtk-icon-filter: opacity(0.5); }
 +
 +notebook > header > tabs > arrow:disabled:active, notebook > header > tabs > arrow:disabled:checked, button:disabled:active, button:disabled:checked { color: #919190; border-color: #202020; background-image: image(#292929); box-shadow: none; }
 +
- button.sidebar-button:hover, notebook > header > tabs > arrow:hover, windowcontrols button:hover, button.flat:hover { border-color: transparent; background-image: none; box-shadow: none; background-color: #373737; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-duration: 500ms; }
++button.sidebar-button, notebook > header > tabs > arrow, windowcontrols button, .toolbar button, notebook > header > tabs > arrow.flat, button.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; transition: none; }
 +
- button.keyboard-activating.sidebar-button, notebook > header > tabs > arrow.keyboard-activating, windowcontrols button.keyboard-activating, button.sidebar-button:active, notebook > header > tabs > arrow:active, windowcontrols button:active, button.sidebar-button:checked, notebook > header > tabs > arrow:checked, windowcontrols button:checked, button.flat.keyboard-activating, button.flat:active, button.flat:checked { border-color: transparent; background-image: none; box-shadow: none; background-color: #2d2d2d; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
++button.sidebar-button:hover, notebook > header > tabs > arrow:hover, windowcontrols button:hover, .toolbar button:hover, button.flat:hover { border-color: transparent; background-image: none; box-shadow: none; background-color: #373737; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-duration: 500ms; }
 +
- button.sidebar-button:backdrop, notebook > header > tabs > arrow:backdrop, windowcontrols button:backdrop, button.sidebar-button:disabled, notebook > header > tabs > arrow:disabled, windowcontrols button:disabled, button.flat:backdrop, button.flat:disabled, button.flat:backdrop:disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; }
++button.keyboard-activating.sidebar-button, notebook > header > tabs > arrow.keyboard-activating, windowcontrols button.keyboard-activating, .toolbar button.keyboard-activating, button.sidebar-button:active, notebook > header > tabs > arrow:active, windowcontrols button:active, .toolbar button:active, button.sidebar-button:checked, notebook > header > tabs > arrow:checked, windowcontrols button:checked, .toolbar button:checked, button.flat.keyboard-activating, button.flat:active, button.flat:checked { border-color: transparent; background-image: none; box-shadow: none; background-color: #2d2d2d; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
 +
- .scale-popup button:hover, button.link, button.link:hover, button.link:active, button.link:checked, popover.menu box.circular-buttons button.circular.image-button.model, list > row button.image-button:not(.flat), .toolbar button, modelbutton.flat { background-color: transparent; background-image: none; border-color: transparent; box-shadow: inset 0 1px rgba(255, 255, 255, 0), 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
++button.sidebar-button:backdrop, notebook > header > tabs > arrow:backdrop, windowcontrols button:backdrop, .toolbar button:backdrop, button.sidebar-button:disabled, notebook > header > tabs > arrow:disabled, windowcontrols button:disabled, .toolbar button:disabled, button.flat:backdrop, button.flat:disabled, button.flat:backdrop:disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; }
 +
 +notebook > header > tabs > arrow.image-button, button.image-button { min-width: 24px; padding-left: 5px; padding-right: 5px; }
 +
 +notebook > header > tabs > arrow.text-button, button.text-button { padding-left: 16px; padding-right: 16px; }
 +
 +notebook > header > tabs > arrow.text-button.image-button, button.text-button.image-button { padding-left: 8px; padding-right: 8px; }
 +
 +notebook > header > tabs > arrow.text-button.image-button label, button.text-button.image-button label { padding-left: 8px; padding-right: 8px; }
 +
 +dropdown:drop(active) button.combo, combobox:drop(active) button.combo, notebook > header > tabs > arrow:drop(active), button:drop(active) { color: #26a269; border-color: #26a269; box-shadow: inset 0 0 0 1px #26a269; }
 +
 +row:selected button.sidebar-button:not(:active):not(:checked):not(:hover):not(disabled), row:selected button.flat:not(:active):not(:checked):not(:hover):not(disabled) { color: #ffffff; border-color: transparent; }
 +
 +row:selected button.sidebar-button:not(:active):not(:checked):not(:hover):not(disabled):backdrop, row:selected button.flat:not(:active):not(:checked):not(:hover):not(disabled):backdrop { color: #919190; }
 +
 +button.osd { min-width: 26px; min-height: 32px; color: #eeeeec; border-radius: 5px; color: #eeeeec; outline-color: rgba(21, 83, 158, 0.7); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; border: none; box-shadow: none; }
 +
 +button.osd.image-button { min-width: 30px; }
 +
 +button.osd.image-button:only-child { margin: 4px; border-radius: 50%; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); }
 +
 +button.osd:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(12, 12, 12, 0.7)); background-clip: padding-box; border: none; box-shadow: none; }
 +
 +button.osd:active, button.osd:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; border: none; box-shadow: none; }
 +
 +.app-notification button, popover.background.touch-selection button, popover.background.magnifier button, .osd button { color: #eeeeec; outline-color: rgba(21, 83, 158, 0.7); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; }
 +
 +.app-notification button:hover, popover.background.touch-selection button:hover, popover.background.magnifier button:hover, .osd button:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(12, 12, 12, 0.7)); background-clip: padding-box; }
 +
 +.app-notification button:active, popover.background.touch-selection button:active, popover.background.magnifier button:active, .app-notification button:checked, popover.background.touch-selection button:checked, popover.background.magnifier button:checked, .osd button:active:backdrop, .osd button:active, .osd button:checked:backdrop, .osd button:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; }
 +
 +.app-notification button:disabled, popover.background.touch-selection button:disabled, popover.background.magnifier button:disabled, .osd button:disabled:backdrop, .osd button:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; }
 +
 +.app-notification button.flat, popover.background.touch-selection button.flat, popover.background.magnifier button.flat, .osd button.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; box-shadow: none; -gtk-icon-shadow: 0 1px black; }
 +
 +.app-notification button.flat:hover, popover.background.touch-selection button.flat:hover, popover.background.magnifier button.flat:hover, .osd button.flat:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(12, 12, 12, 0.7)); background-clip: padding-box; }
 +
 +.app-notification button.flat:disabled, popover.background.touch-selection button.flat:disabled, popover.background.magnifier button.flat:disabled, .osd button.flat:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; background-image: none; border-color: transparent; box-shadow: none; }
 +
 +.app-notification button.flat:active, popover.background.touch-selection button.flat:active, popover.background.magnifier button.flat:active, .app-notification button.flat:checked, popover.background.touch-selection button.flat:checked, popover.background.magnifier button.flat:checked, .osd button.flat:active, .osd button.flat:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; }
 +
 +button.suggested-action { color: white; outline-color: rgba(255, 255, 255, 0.3); border-color: #092444; background-image: linear-gradient(to top, #155099 2px, #15539e); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +button.suggested-action { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +button.suggested-action:focus:focus-visible { outline-color: rgba(255, 255, 255, 0.3); outline-width: 2px; outline-offset: -2px; }
 +
 +button.suggested-action.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: #15539e; }
 +
 +button.suggested-action:hover { color: white; border-color: #0c2f5a; background-image: linear-gradient(to top, #13498c 20%, #134c90 90%); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +button.suggested-action:active, button.suggested-action:checked { color: white; border-color: #0c2f5a; background-image: image(#103e75); box-shadow: none; }
 +
 +button.suggested-action.flat:disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: rgba(21, 83, 158, 0.8); }
 +
 +button.suggested-action:disabled { color: #919190; border-color: #202020; background-image: image(#323232); }
 +
 +button.suggested-action:disabled:active, button.suggested-action:disabled:checked { color: #a1b2c7; border-color: #0c2f5a; background-image: image(#143f73); box-shadow: none; }
 +
 +.osd button.suggested-action { color: #eeeeec; outline-color: rgba(255, 255, 255, 0.3); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(21, 83, 158, 0.5)); background-clip: padding-box; }
 +
 +.osd button.suggested-action:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(21, 83, 158, 0.7)); background-clip: padding-box; }
 +
 +.osd button.suggested-action:active:backdrop, .osd button.suggested-action:active, .osd button.suggested-action:checked:backdrop, .osd button.suggested-action:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(#15539e); background-clip: padding-box; box-shadow: none; }
 +
 +.osd button.suggested-action:disabled:backdrop, .osd button.suggested-action:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; }
 +
 +button.destructive-action { color: white; outline-color: rgba(255, 255, 255, 0.3); border-color: #570b0e; background-image: linear-gradient(to top, #ae151c 2px, #b2161d); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +button.destructive-action { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +button.destructive-action:focus:focus-visible { outline-color: rgba(255, 255, 255, 0.3); outline-width: 2px; outline-offset: -2px; }
 +
 +button.destructive-action.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: #b2161d; }
 +
 +button.destructive-action:hover { color: white; border-color: #6e0d12; background-image: linear-gradient(to top, #a0131a 20%, #a5141a 90%); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +button.destructive-action:active, button.destructive-action:checked { color: white; border-color: #6e0d12; background-image: image(#8a1116); box-shadow: none; }
 +
 +button.destructive-action.flat:disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: rgba(178, 22, 29, 0.8); }
 +
 +button.destructive-action:disabled { color: #919190; border-color: #202020; background-image: image(#323232); }
 +
 +button.destructive-action:disabled:active, button.destructive-action:disabled:checked { color: #cea1a3; border-color: #6e0d12; background-image: image(#84151a); box-shadow: none; }
 +
 +.osd button.destructive-action { color: #eeeeec; outline-color: rgba(255, 255, 255, 0.3); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(178, 22, 29, 0.5)); background-clip: padding-box; }
 +
 +.osd button.destructive-action:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(178, 22, 29, 0.7)); background-clip: padding-box; }
 +
 +.osd button.destructive-action:active:backdrop, .osd button.destructive-action:active, .osd button.destructive-action:checked:backdrop, .osd button.destructive-action:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(#b2161d); background-clip: padding-box; box-shadow: none; }
 +
 +.osd button.destructive-action:disabled:backdrop, .osd button.destructive-action:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; }
 +
 +stackswitcher > button > label { padding: 0 6px; margin: 0 -6px; }
 +
 +stackswitcher > button > image { padding: 3px 6px; margin: -3px -6px; }
 +
 +button.font separator { background-color: transparent; }
 +
 +button.font > box { border-spacing: 6px; }
 +
 +button.font > box > box > label { font-weight: bold; }
 +
 +menubutton.circular button, button.circular { min-width: 32px; min-height: 32px; padding: 0; border-radius: 9999px; }
 +
 +menubutton.circular button label, button.circular label { padding: 0; }
 +
 +stacksidebar row.needs-attention > label, stackswitcher > button.needs-attention > label, stackswitcher > button.needs-attention > image { animation: needs_attention 150ms ease-in; background-image: radial-gradient(farthest-side, #1f76e1 96%, rgba(31, 118, 225, 0)); background-size: 6px 6px, 6px 6px; background-repeat: no-repeat; background-position: right 3px, right 2px; }
 +
 +stacksidebar row.needs-attention > label:backdrop, stackswitcher > button.needs-attention > label:backdrop, stackswitcher > button.needs-attention > image:backdrop { background-size: 6px 6px, 0 0; }
 +
 +stacksidebar row.needs-attention > label:dir(rtl), stackswitcher > button.needs-attention > label:dir(rtl), stackswitcher > button.needs-attention > image:dir(rtl) { background-position: left 3px, left 2px; }
 +
 +.linked:not(.vertical) > filechooserbutton > combobox:dir(rtl):not(:last-child) > box > button.combo, .linked:not(.vertical) > appchooserbutton > combobox:dir(rtl):not(:last-child) > box > button.combo, .linked:not(.vertical) > combobox:dir(rtl):not(:last-child) > box > button.combo, .linked:not(.vertical) > filechooserbutton > combobox:dir(ltr):not(:first-child) > box > button.combo, .linked:not(.vertical) > appchooserbutton > combobox:dir(ltr):not(:first-child) > box > button.combo, .linked:not(.vertical) > combobox:dir(ltr):not(:first-child) > box > button.combo, dropdown.linked button:nth-child(2):dir(ltr), combobox.linked button:nth-child(2):dir(ltr), .linked:not(.vertical) > menubutton:dir(rtl):not(:last-child) > button, .linked:not(.vertical) > dropdown:dir(rtl):not(:last-child) > button, .linked:not(.vertical) > colorbutton:dir(rtl):not(:last-child) > button, .linked:not(.vertical) > fontbutton:dir(rtl):not(:last-child) > button, .linked:not(.vertical) > filechooserbutton:dir(rtl):not(:last-child) > button, .linked:not(.vertical) > menubutton:dir(ltr):not(:first-child) > button, .linked:not(.vertical) > dropdown:dir(ltr):not(:first-child) > button, .linked:not(.vertical) > colorbutton:dir(ltr):not(:first-child) > button, .linked:not(.vertical) > fontbutton:dir(ltr):not(:first-child) > button, .linked:not(.vertical) > filechooserbutton:dir(ltr):not(:first-child) > button, spinbutton.vertical.linked:not(.vertical) > text:dir(rtl):not(:last-child), .linked:not(.vertical) > spinbutton:dir(rtl):not(:last-child):not(.vertical), .linked:not(.vertical) > entry:dir(rtl):not(:last-child), .linked:not(.vertical) > button:dir(rtl):not(:last-child), spinbutton.vertical.linked:not(.vertical) > text:dir(ltr):not(:first-child), .linked:not(.vertical) > spinbutton:dir(ltr):not(:first-child):not(.vertical), .linked:not(.vertical) > entry:dir(ltr):not(:first-child), .linked:not(.vertical) > button:dir(ltr):not(:first-child) { border-top-left-radius: 0; border-bottom-left-radius: 0; }
 +
 +.linked:not(.vertical) > filechooserbutton > combobox:dir(rtl):not(:first-child) > box > button.combo, .linked:not(.vertical) > appchooserbutton > combobox:dir(rtl):not(:first-child) > box > button.combo, .linked:not(.vertical) > combobox:dir(rtl):not(:first-child) > box > button.combo, .linked:not(.vertical) > filechooserbutton > combobox:dir(ltr):not(:last-child) > box > button.combo, .linked:not(.vertical) > appchooserbutton > combobox:dir(ltr):not(:last-child) > box > button.combo, .linked:not(.vertical) > combobox:dir(ltr):not(:last-child) > box > button.combo, dropdown.linked button:nth-child(2):dir(rtl), combobox.linked button:nth-child(2):dir(rtl), .linked:not(.vertical) > menubutton:dir(rtl):not(:first-child) > button, .linked:not(.vertical) > dropdown:dir(rtl):not(:first-child) > button, .linked:not(.vertical) > colorbutton:dir(rtl):not(:first-child) > button, .linked:not(.vertical) > fontbutton:dir(rtl):not(:first-child) > button, .linked:not(.vertical) > filechooserbutton:dir(rtl):not(:first-child) > button, .linked:not(.vertical) > menubutton:dir(ltr):not(:last-child) > button, .linked:not(.vertical) > dropdown:dir(ltr):not(:last-child) > button, .linked:not(.vertical) > colorbutton:dir(ltr):not(:last-child) > button, .linked:not(.vertical) > fontbutton:dir(ltr):not(:last-child) > button, .linked:not(.vertical) > filechooserbutton:dir(ltr):not(:last-child) > button, spinbutton.vertical.linked:not(.vertical) > text:dir(rtl):not(:first-child), .linked:not(.vertical) > spinbutton:dir(rtl):not(:first-child):not(.vertical), .linked:not(.vertical) > entry:dir(rtl):not(:first-child), .linked:not(.vertical) > button:dir(rtl):not(:first-child), spinbutton.vertical.linked:not(.vertical) > text:dir(ltr):not(:last-child), .linked:not(.vertical) > spinbutton:dir(ltr):not(:last-child):not(.vertical), .linked:not(.vertical) > entry:dir(ltr):not(:last-child), .linked:not(.vertical) > button:dir(ltr):not(:last-child) { border-right-style: none; border-top-right-radius: 0; border-bottom-right-radius: 0; }
 +
 +.linked.vertical > filechooserbutton > combobox:not(:first-child) > box > button.combo, .linked.vertical > appchooserbutton > combobox:not(:first-child) > box > button.combo, .linked.vertical > combobox:not(:first-child) > box > button.combo, .linked.vertical > menubutton:not(:first-child) > button, .linked.vertical > dropdown:not(:first-child) > button, .linked.vertical > colorbutton:not(:first-child) > button, .linked.vertical > fontbutton:not(:first-child) > button, .linked.vertical > filechooserbutton:not(:first-child) > button, spinbutton.vertical.linked > text:not(:first-child), .linked.vertical > spinbutton:not(:first-child):not(.vertical), .linked.vertical > entry:not(:first-child), .linked.vertical > button:not(:first-child) { border-top-left-radius: 0; border-top-right-radius: 0; }
 +
 +.linked.vertical > filechooserbutton > combobox:not(:last-child) > box > button.combo, .linked.vertical > appchooserbutton > combobox:not(:last-child) > box > button.combo, .linked.vertical > combobox:not(:last-child) > box > button.combo, .linked.vertical > menubutton:not(:last-child) > button, .linked.vertical > dropdown:not(:last-child) > button, .linked.vertical > colorbutton:not(:last-child) > button, .linked.vertical > fontbutton:not(:last-child) > button, .linked.vertical > filechooserbutton:not(:last-child) > button, spinbutton.vertical.linked > text:not(:last-child), .linked.vertical > spinbutton:not(:last-child):not(.vertical), .linked.vertical > entry:not(:last-child), .linked.vertical > button:not(:last-child) { border-bottom-style: none; border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
 +
- .toolbar button:hover { color: #eeeeec; border-color: #1b1b1b; background-image: linear-gradient(to top, #303030 20%, #323232 90%); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
- .toolbar button:active { color: #eeeeec; border-color: #1b1b1b; background-image: image(#232323); box-shadow: none; }
- .toolbar button:disabled { color: #919190; border-color: #202020; background-image: image(#323232); }
- .toolbar button:backdrop { color: #919190; border-color: #202020; background-image: image(#353535); box-shadow: none; }
- .toolbar button:backdrop:disabled { color: #5b5b5b; border-color: #202020; background-image: image(#323232); box-shadow: none; }
++.scale-popup button:hover, button.link, button.link:hover, button.link:active, button.link:checked, popover.menu box.circular-buttons button.circular.image-button.model, list > row button.image-button:not(.flat), modelbutton.flat { background-color: transparent; background-image: none; border-color: transparent; box-shadow: inset 0 1px rgba(255, 255, 255, 0), 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
 +
 +/* menu buttons */
 +modelbutton.flat { min-height: 26px; padding-left: 5px; padding-right: 5px; border-radius: 5px; }
 +
 +modelbutton.flat:hover { background-color: #202020; }
 +
 +modelbutton.flat:disabled { color: #919190; }
 +
 +modelbutton.flat arrow { background: none; min-width: 16px; min-height: 16px; opacity: 0.3; }
 +
 +modelbutton.flat arrow:hover { background: none; }
 +
 +modelbutton.flat arrow.left { -gtk-icon-source: -gtk-icontheme("go-previous-symbolic"); }
 +
 +modelbutton.flat arrow.right { -gtk-icon-source: -gtk-icontheme("go-next-symbolic"); }
 +
 +/* oldstyle toolbar buttons */
 +.toolbar button { margin: 1px; }
 +
 +button.color { padding: 4px; }
 +
 +button.color > colorswatch:only-child, button.color > colorswatch:only-child > overlay { border-radius: 0; }
 +
 +/* list buttons */
 +/* tone down as per new designs, see issue #1473 */
 +popover.menu box.circular-buttons button.circular.image-button.model, list > row button.image-button:not(.flat) { border: 1px solid rgba(27, 27, 27, 0.5); }
 +
 +popover.menu box.circular-buttons button.circular.image-button.model:hover, list > row button.image-button:not(.flat):hover { color: #eeeeec; border-color: #1b1b1b; background-image: linear-gradient(to top, #303030 20%, #323232 90%); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +popover.menu box.circular-buttons button.circular.image-button.model:active, popover.menu box.circular-buttons button.circular.image-button.model:checked, list > row button.image-button:not(.flat):active, list > row button.image-button:not(.flat):checked { color: #eeeeec; border-color: #1b1b1b; background-image: image(#232323); box-shadow: none; }
 +
 +popover.menu box.circular-buttons button.suggested-action.circular.image-button.model, list > row button.image-button.suggested-action:not(.flat) { color: white; outline-color: rgba(255, 255, 255, 0.3); border-color: #092444; background-image: linear-gradient(to top, #155099 2px, #15539e); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +popover.menu box.circular-buttons button.suggested-action.circular.image-button.model, list > row button.image-button.suggested-action:not(.flat) { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +popover.menu box.circular-buttons button.suggested-action.circular.image-button.model:focus:focus-visible, list > row button.image-button.suggested-action:not(.flat):focus:focus-visible { outline-color: rgba(255, 255, 255, 0.3); outline-width: 2px; outline-offset: -2px; }
 +
 +popover.menu box.circular-buttons button.destructive-action.circular.image-button.model, list > row button.image-button.destructive-action:not(.flat) { color: white; outline-color: rgba(255, 255, 255, 0.3); border-color: #570b0e; background-image: linear-gradient(to top, #ae151c 2px, #b2161d); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +popover.menu box.circular-buttons button.destructive-action.circular.image-button.model, list > row button.image-button.destructive-action:not(.flat) { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +popover.menu box.circular-buttons button.destructive-action.circular.image-button.model:focus:focus-visible, list > row button.image-button.destructive-action:not(.flat):focus:focus-visible { outline-color: rgba(255, 255, 255, 0.3); outline-width: 2px; outline-offset: -2px; }
 +
 +/********* Links * */
 +button.link, link { color: #3584e4; text-decoration: underline; }
 +
 +button.link:visited, link:visited { color: #1b6acb; }
 +
 +*:selected button.link:visited, *:selected link:visited { color: #a4c4ea; }
 +
 +button.link:hover, link:hover { color: #629fea; }
 +
 +*:selected button.link:hover, *:selected link:hover { color: #eff5fd; }
 +
 +button.link:active, link:active { color: #3584e4; }
 +
 +*:selected button.link:active, *:selected link:active { color: #d7e6fa; }
 +
 +button.link:disabled, link:disabled { color: rgba(141, 141, 141, 0.8); }
 +
 +button.link:selected, *:selected button.link, link:selected, *:selected link { color: #d7e6fa; }
 +
 +link { transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +link { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +link:focus:focus-visible { outline-color: rgba(21, 83, 158, 0.7); outline-width: 2px; outline-offset: -2px; }
 +
 +button.link, button.link:hover, button.link:active, button.link:checked { text-shadow: none; }
 +
 +button.link > label { text-decoration: underline; }
 +
 +/***************** GtkSpinButton * */
 +spinbutton { font-feature-settings: "tnum"; }
 +
 +spinbutton:not(.vertical) { padding: 0; border-spacing: 0; /* :not here just to bump specificity above that of the list button styling */ }
 +
 +.osd spinbutton:not(.vertical) > text, spinbutton:not(.vertical) > text { min-width: 28px; margin: 0; background: none; background-color: transparent; border: none; border-radius: 0; box-shadow: none; padding: 6px; }
 +
 +.osd spinbutton:not(.vertical) > text:backdrop:disabled, spinbutton:not(.vertical) > text:backdrop:disabled { background-color: transparent; }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat), spinbutton:not(.vertical) > button.image-button.down:not(.flat) { min-height: 16px; margin: 0; padding-bottom: 0; padding-top: 0; color: #dbdbd9; background-image: none; border-style: none none none solid; border-color: rgba(27, 27, 27, 0.3); border-radius: 0; box-shadow: none; }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat):dir(rtl), spinbutton:not(.vertical) > button.image-button.down:not(.flat):dir(rtl) { border-style: none solid none none; }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat):hover, spinbutton:not(.vertical) > button.image-button.down:not(.flat):hover { color: #eeeeec; background-color: #282828; }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat):disabled, spinbutton:not(.vertical) > button.image-button.down:not(.flat):disabled { color: rgba(145, 145, 144, 0.3); background-color: transparent; }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat):active, spinbutton:not(.vertical) > button.image-button.down:not(.flat):active { background-color: rgba(0, 0, 0, 0.1); box-shadow: inset 0 2px 3px -1px rgba(0, 0, 0, 0.2); }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat):dir(ltr):last-child, spinbutton:not(.vertical) > button.image-button.down:not(.flat):dir(ltr):last-child { border-radius: 0 5px 5px 0; }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat):dir(rtl):first-child, spinbutton:not(.vertical) > button.image-button.down:not(.flat):dir(rtl):first-child { border-radius: 5px 0 0 5px; }
 +
 +.osd spinbutton:not(.vertical) > button.image-button.up:not(.flat), .osd spinbutton:not(.vertical) > button.image-button.down:not(.flat) { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: #eeeeec; border-style: none none none solid; border-color: rgba(0, 0, 0, 0.4); border-radius: 0; box-shadow: none; -gtk-icon-shadow: 0 1px black; }
 +
 +.osd spinbutton:not(.vertical) > button.image-button.up:not(.flat):dir(rtl), .osd spinbutton:not(.vertical) > button.image-button.down:not(.flat):dir(rtl) { border-style: none solid none none; }
 +
 +.osd spinbutton:not(.vertical) > button.image-button.up:not(.flat):hover, .osd spinbutton:not(.vertical) > button.image-button.down:not(.flat):hover { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: #eeeeec; border-color: rgba(0, 0, 0, 0.5); background-color: rgba(12, 12, 12, 0.7); -gtk-icon-shadow: 0 1px black; box-shadow: none; }
 +
 +.osd spinbutton:not(.vertical) > button.image-button.up:not(.flat):disabled, .osd spinbutton:not(.vertical) > button.image-button.down:not(.flat):disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: #8a8a89; border-color: rgba(0, 0, 0, 0.5); -gtk-icon-shadow: none; box-shadow: none; }
 +
 +.osd spinbutton:not(.vertical) > button.image-button.up:not(.flat):dir(ltr):last-child, .osd spinbutton:not(.vertical) > button.image-button.down:not(.flat):dir(ltr):last-child { border-radius: 0 5px 5px 0; }
 +
 +.osd spinbutton:not(.vertical) > button.image-button.up:not(.flat):dir(rtl):first-child, .osd spinbutton:not(.vertical) > button.image-button.down:not(.flat):dir(rtl):first-child { border-radius: 5px 0 0 5px; }
 +
 +spinbutton.vertical:disabled { color: #919190; }
 +
 +spinbutton.vertical:drop(active) { border-color: transparent; box-shadow: none; }
 +
 +spinbutton.vertical > text { min-height: 32px; min-width: 32px; padding: 0; border-radius: 0; }
 +
 +spinbutton.vertical > text > block-cursor { color: #2d2d2d; background-color: white; }
 +
 +spinbutton.vertical > button { min-height: 32px; min-width: 32px; padding: 0; }
 +
 +spinbutton.vertical > button.up { border-bottom-style: none; border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
 +
 +spinbutton.vertical > button.down { border-top-style: none; border-top-left-radius: 0; border-top-right-radius: 0; }
 +
 +.osd spinbutton.vertical > button:first-child { color: #eeeeec; outline-color: rgba(21, 83, 158, 0.7); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; }
 +
 +.osd spinbutton.vertical > button:first-child:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(12, 12, 12, 0.7)); background-clip: padding-box; }
 +
 +.osd spinbutton.vertical > button:first-child:active { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; }
 +
 +.osd spinbutton.vertical > button:first-child:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; }
 +
 +treeview spinbutton:not(.vertical) { min-height: 0; border-style: none; border-radius: 0; }
 +
 +treeview spinbutton:not(.vertical) > text { min-height: 0; padding: 1px 2px; }
 +
 +/************** ComboBoxes * */
 +dropdown > popover.menu.background > contents { padding: 0; }
 +
 +dropdown > button > box { border-spacing: 6px; }
 +
 +dropdown > button > box > stack > row.activatable:hover { background: none; box-shadow: none; }
 +
 +dropdown arrow, combobox arrow { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); min-height: 16px; min-width: 16px; }
 +
 +dropdown > popover.menu > contents modelbutton, combobox > popover.menu > contents modelbutton { padding-left: 9px; padding-right: 9px; }
 +
 +dropdown:drop(active), combobox:drop(active) { box-shadow: none; }
 +
 +dropdown popover, combobox popover { margin-top: 6px; padding: 0; }
 +
 +dropdown popover listview, combobox popover listview { margin: 8px 0; }
 +
 +dropdown popover listview > row.activatable, combobox popover listview > row.activatable { padding: 8px; }
 +
 +dropdown popover listview > row.activatable:selected, dropdown popover listview > row.activatable:selected:hover, combobox popover listview > row.activatable:selected, combobox popover listview > row.activatable:selected:hover { outline-color: rgba(255, 255, 255, 0.3); color: white; background-color: #202020; box-shadow: none; }
 +
 +dropdown popover .dropdown-searchbar, combobox popover .dropdown-searchbar { padding: 6px; border-bottom: 1px solid #1b1b1b; }
 +
 +/************ Toolbars * */
 +searchbar > revealer > box, .toolbar, toolbar { padding: 4px; border-spacing: 4px; background-color: #353535; }
 +
 +.osd .toolbar, .osd toolbar { background-color: transparent; }
 +
 +.toolbar.osd, toolbar.osd { padding: 13px; border: none; border-radius: 5px; background-color: rgba(38, 38, 38, 0.7); }
 +
 +.toolbar.osd.left, .toolbar.osd.right, .toolbar.osd.top, .toolbar.osd.bottom, toolbar.osd.left, toolbar.osd.right, toolbar.osd.top, toolbar.osd.bottom { border-radius: 0; }
 +
 +.toolbar.horizontal > separator, toolbar.horizontal > separator { margin: 4px 0; }
 +
 +.toolbar.vertical > separator, toolbar.vertical > separator { margin: 0 4px; }
 +
 +searchbar > revealer > box { padding: 6px; border-spacing: 6px; border-width: 0 0 1px; }
 +
 +searchbar > revealer > box { border-style: solid; border-color: #1b1b1b; background-color: #2d2d2d; }
 +
 +searchbar > revealer > box:backdrop { border-color: #202020; background-color: #2e2e2e; box-shadow: none; transition: 200ms ease-out; }
 +
 +/************** GtkInfoBar * */
 +infobar > revealer > box { padding: 8px; border-spacing: 12px; }
 +
 +infobar.action:hover > revealer > box { background-color: #3e3b37; }
 +
 +infobar.info > revealer > box, infobar.question > revealer > box, infobar.warning > revealer > box, infobar.error > revealer > box { border-bottom: 1px solid #282828; background-color: #44403b; }
 +
 +infobar .close, searchbar .close { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; min-width: 16px; min-height: 16px; padding: 4px; border-radius: 50%; }
 +
 +infobar .close:hover, searchbar .close:hover { color: #eeeeec; border-color: #1b1b1b; background-image: linear-gradient(to top, #303030 20%, #323232 90%); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +/***************** Title buttons * */
 +windowcontrols { border-spacing: 6px; }
 +
 +windowcontrols.start:not(.empty):dir(ltr), windowcontrols.end:not(.empty):dir(rtl) { margin-right: 7px; }
 +
 +windowcontrols.start:not(.empty):dir(rtl), windowcontrols.end:not(.empty):dir(ltr) { margin-left: 7px; }
 +
 +windowcontrols button { border-radius: 9999px; padding: 6px; margin: 0 2px; min-width: 0; min-height: 0; }
 +
 +windowcontrols button:hover { border-color: transparent; background-image: none; box-shadow: none; background-color: #1b1b1b; }
 +
 +windowcontrols button:active, windowcontrols button:checked { border-color: transparent; background-image: none; box-shadow: none; background-color: #070707; }
 +
 +/*************** Header bars * */
 +.titlebar:not(headerbar), headerbar { padding: 0 6px; min-height: 46px; border-width: 0 0 1px; border-style: solid; border-color: #070707; border-radius: 0; background: #1b1b1b linear-gradient(to top, #262626, #2b2b2b); /* Darken switchbuttons for headerbars. issue #1588 */ }
 +
 +.titlebar:backdrop:not(headerbar), headerbar:backdrop { border-color: #202020; background-color: #353535; background-image: none; transition: 200ms ease-out; }
 +
 +.titlebar:not(headerbar) .title, headerbar .title { padding-left: 12px; padding-right: 12px; font-weight: bold; }
 +
 +.titlebar:not(headerbar) .subtitle, headerbar .subtitle { font-size: smaller; padding-left: 12px; padding-right: 12px; }
 +
 +.titlebar:not(headerbar) stackswitcher > button:checked, .titlebar:not(headerbar) button.toggle:checked, headerbar stackswitcher > button:checked, headerbar button.toggle:checked { background: image(#1e1e1e); border-color: #141414; border-top-color: #070707; }
 +
 +.titlebar:not(headerbar) stackswitcher > button:checked:backdrop, .titlebar:not(headerbar) button.toggle:checked:backdrop, headerbar stackswitcher > button:checked:backdrop, headerbar button.toggle:checked:backdrop { color: #919190; border-color: #202020; background-image: image(#2e2e2e); box-shadow: none; }
 +
 +.tiled .titlebar:not(headerbar), .tiled-top .titlebar:not(headerbar), .tiled-left .titlebar:not(headerbar), .tiled-right .titlebar:not(headerbar), .tiled-bottom .titlebar:not(headerbar), .maximized .titlebar:not(headerbar), .fullscreen .titlebar:not(headerbar), .tiled headerbar, .tiled-top headerbar, .tiled-left headerbar, .tiled-right headerbar, .tiled-bottom headerbar, .maximized headerbar, .fullscreen headerbar { border-radius: 0; }
 +
 +.default-decoration.titlebar:not(headerbar), headerbar.default-decoration { min-height: 28px; padding: 4px; }
 +
 +.default-decoration.titlebar:not(headerbar) windowcontrols button, .default-decoration.titlebar:not(headerbar) windowcontrols menubutton, headerbar.default-decoration windowcontrols button, headerbar.default-decoration windowcontrols menubutton { min-height: 26px; min-width: 26px; margin: 0; padding: 0; }
 +
 +.default-decoration.titlebar:not(headerbar) windowcontrols menubutton button, headerbar.default-decoration windowcontrols menubutton button { min-height: 20px; min-width: 20px; margin: 0; padding: 4px; }
 +
 +.solid-csd .titlebar:dir(rtl):not(headerbar), .solid-csd .titlebar:dir(ltr):not(headerbar), .solid-csd headerbar:backdrop:dir(rtl), .solid-csd headerbar:backdrop:dir(ltr), .solid-csd headerbar:dir(rtl), .solid-csd headerbar:dir(ltr) { margin-left: -1px; margin-right: -1px; margin-top: -1px; border-radius: 0; box-shadow: none; }
 +
 +headerbar > windowhandle > box, headerbar > windowhandle > box > box.start, headerbar > windowhandle > box > box.end { border-spacing: 6px; }
 +
 +headerbar entry, headerbar spinbutton, headerbar separator:not(.sidebar), headerbar button, headerbar menubutton { margin-top: 6px; margin-bottom: 6px; }
 +
 +headerbar menubutton > button { margin-top: 0px; margin-bottom: 0px; }
 +
 +headerbar switch { margin-top: 10px; margin-bottom: 10px; }
 +
 +window.csd > .titlebar:not(headerbar) { padding: 0; background-color: transparent; background-image: none; border-style: none; border-color: transparent; }
 +
 +.titlebar:not(headerbar) separator { background-color: #1b1b1b; }
 +
 +window.devel headerbar.titlebar { background: #353535 cross-fade(10% -gtk-icontheme("system-run-symbolic"), image(transparent)) 90% 0/256px 256px no-repeat, linear-gradient(to right, transparent 65%, rgba(21, 83, 158, 0.1)), linear-gradient(to top, #232323 3px, #282828); }
 +
 +window.devel headerbar.titlebar:backdrop { background: #353535 cross-fade(10% -gtk-icontheme("system-run-symbolic"), image(transparent)) 90% 0/256px 256px no-repeat, image(#353535); /* background-color would flash */ }
 +
 +/************ Pathbars * */
 +pathbar > button.text-button, pathbar > button.image-button, pathbar > button { padding-left: 4px; padding-right: 4px; }
 +
 +pathbar > button.text-button.image-button label { padding-left: 0; padding-right: 0; }
 +
 +pathbar > button.text-button.image-button label:last-child, pathbar > button label:last-child { padding-right: 8px; }
 +
 +pathbar > button.text-button.image-button label:first-child, pathbar > button label:first-child { padding-left: 8px; }
 +
 +pathbar > button image { padding-left: 4px; padding-right: 4px; }
 +
 +pathbar > button.slider-button { padding-left: 0; padding-right: 0; }
 +
 +/************** Tree Views * */
 +columnview.view, treeview.view { border-left-color: #545453; border-top-color: #545453; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +columnview.view, treeview.view { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +columnview.view:focus:focus-visible, treeview.view:focus:focus-visible { outline-color: rgba(21, 83, 158, 0.7); outline-width: 2px; outline-offset: -2px; }
 +
 +columnview.view:selected:focus, columnview.view:selected, treeview.view:selected:focus, treeview.view:selected { border-radius: 0; outline-color: rgba(255, 255, 255, 0.3); }
 +
 +columnview.view:disabled, treeview.view:disabled { color: #919190; }
 +
 +columnview.view:disabled:selected, treeview.view:disabled:selected { color: #7398c5; }
 +
 +columnview.view:disabled:selected:backdrop, treeview.view:disabled:selected:backdrop { color: #4f7aaf; }
 +
 +columnview.view.separator, treeview.view.separator { min-height: 2px; color: #545453; }
 +
 +columnview.view:backdrop, treeview.view:backdrop { border-left-color: #414141; border-top: #414141; }
 +
 +columnview.view:drop(active), treeview.view:drop(active) { box-shadow: none; }
 +
 +columnview.view > dndtarget:drop(active), treeview.view > dndtarget:drop(active) { border-style: solid none; border-width: 1px; border-color: #030c17; }
 +
 +columnview.view > dndtarget.after:drop(active), treeview.view > dndtarget.after:drop(active) { border-top-style: none; }
 +
 +columnview.view > dndtarget.before:drop(active), treeview.view > dndtarget.before:drop(active) { border-bottom-style: none; }
 +
 +columnview.view.expander, treeview.view.expander { min-width: 16px; min-height: 16px; -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); color: silver; }
 +
 +columnview.view.expander:dir(rtl), treeview.view.expander:dir(rtl) { -gtk-icon-source: -gtk-icontheme("pan-end-symbolic-rtl"); }
 +
 +columnview.view.expander:hover, treeview.view.expander:hover { color: white; }
 +
 +columnview.view.expander:selected, treeview.view.expander:selected { color: #b9cbe2; }
 +
 +columnview.view.expander:selected:hover, treeview.view.expander:selected:hover { color: #ffffff; }
 +
 +columnview.view.expander:checked, treeview.view.expander:checked { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
 +
 +columnview.view.progressbar, treeview.view.progressbar { background-color: #15539e; background-image: image(#15539e); box-shadow: none; }
 +
 +columnview.view.progressbar:selected:focus, columnview.view.progressbar:selected, treeview.view.progressbar:selected:focus, treeview.view.progressbar:selected { box-shadow: inset 0 1px rgba(255, 255, 255, 0.05); background-image: image(#2d2d2d); }
 +
 +columnview.view.progressbar:selected:focus:backdrop, columnview.view.progressbar:selected:backdrop, treeview.view.progressbar:selected:focus:backdrop, treeview.view.progressbar:selected:backdrop { background-color: #303030; }
 +
 +columnview.view.trough, treeview.view.trough { background-color: rgba(238, 238, 236, 0.1); }
 +
 +columnview.view.trough:selected:focus, columnview.view.trough:selected, treeview.view.trough:selected:focus, treeview.view.trough:selected { background-color: #0f3b71; }
 +
 +columnview.view > header > button, treeview.view > header > button { color: #8e8e8d; background-color: #2d2d2d; font-weight: bold; text-shadow: none; box-shadow: none; }
 +
 +columnview.view > header > button:hover, treeview.view > header > button:hover { color: #bebebd; box-shadow: none; transition: none; }
 +
 +columnview.view > header > button:active, treeview.view > header > button:active { color: #eeeeec; transition: none; }
 +
 +columnview.view > header > button sort-indicator, treeview.view > header > button sort-indicator { min-height: 16px; min-width: 16px; }
 +
 +columnview.view > header > button sort-indicator.ascending, treeview.view > header > button sort-indicator.ascending { -gtk-icon-source: -gtk-icontheme("pan-up-symbolic"); }
 +
 +columnview.view > header > button sort-indicator.descending, treeview.view > header > button sort-indicator.descending { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
 +
 +columnview.view button.dnd:active, columnview.view button.dnd:selected, columnview.view button.dnd:hover, columnview.view button.dnd, columnview.view header.button.dnd:active, columnview.view header.button.dnd:selected, columnview.view header.button.dnd:hover, columnview.view header.button.dnd, treeview.view button.dnd:active, treeview.view button.dnd:selected, treeview.view button.dnd:hover, treeview.view button.dnd, treeview.view header.button.dnd:active, treeview.view header.button.dnd:selected, treeview.view header.button.dnd:hover, treeview.view header.button.dnd { padding: 0 6px; color: #2d2d2d; background-image: none; background-color: #15539e; border-style: none; border-radius: 0; box-shadow: inset 0 0 0 1px #2d2d2d; text-shadow: none; transition: none; }
 +
 +columnview.view acceleditor > label, treeview.view acceleditor > label { background-color: #15539e; }
 +
 +columnview.view > header > button, treeview.view > header > button, columnview.view > header > button:hover, treeview.view > header > button:hover, columnview.view > header > button:active, treeview.view > header > button:active { padding: 0 6px; background-image: none; border-style: none none solid solid; border-color: #545453; border-radius: 0; text-shadow: none; }
 +
 +columnview.view > header > button:disabled, treeview.view > header > button:disabled { border-color: #353535; background-image: none; }
 +
 +columnview.view > header > button:last-child, treeview.view > header > button:last-child { border-right-style: none; }
 +
 +/*************** Popovers   * */
 +popover.background { background-color: transparent; font: initial; }
 +
 +popover.background > arrow, popover.background > contents { background-color: #2d2d2d; background-clip: padding-box; border: 1px solid rgba(0, 0, 0, 0.75); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); }
 +
 +popover.background:backdrop { background-color: transparent; }
 +
 +popover.background > contents { padding: 8px; border-radius: 9px; }
 +
 +popover.background > contents > list, popover.background > contents > .view, popover.background > contents > iconview, popover.background > contents > toolbar { border-style: none; background-color: transparent; }
 +
 +popover.background > contents separator { background-color: #232323; margin: 3px; }
 +
 +popover.background > contents list separator { margin: 0; }
 +
 +.osd popover.background, popover.background.touch-selection, popover.background.magnifier { background-color: transparent; }
 +
 +.osd popover.background > arrow, .osd popover.background > contents, popover.background.touch-selection > arrow, popover.background.touch-selection > contents, popover.background.magnifier > arrow, popover.background.magnifier > contents { border: 1px solid rgba(255, 255, 255, 0.1); box-shadow: none; }
 +
 +magnifier { background-color: #2d2d2d; }
 +
 +/********************** Popover Base Menus * */
 +popover.menu { padding: 0; }
 +
 +popover.menu box.inline-buttons { padding: 0 12px; }
 +
 +popover.menu box.inline-buttons button.image-button.model { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; min-height: 30px; min-width: 30px; padding: 0; border: none; outline: none; transition: none; }
 +
 +popover.menu box.inline-buttons button.image-button.model:selected { background: image(#202020); }
 +
 +popover.menu box.circular-buttons { padding: 12px 12px 6px; }
 +
 +popover.menu box.circular-buttons button.circular.image-button.model { padding: 11px; }
 +
 +popover.menu box.circular-buttons button.circular.image-button.model:focus { background-color: #202020; border-color: #202020; }
 +
 +popover.menu > arrow, popover.menu.background > contents { background-color: #2d2d2d; padding: 5px; }
 +
 +popover.menu.background separator { margin: 6px 0; }
 +
 +popover.menu accelerator { color: alpha(currentColor,0.55); }
 +
 +popover.menu accelerator:dir(ltr) { margin-left: 12px; }
 +
 +popover.menu accelerator:dir(rtl) { margin-right: 12px; }
 +
 +popover.menu check, popover.menu radio { transform: scale(0.8); border-width: 1.2px; border-color: transparent; box-shadow: none; background-image: image(transparent); color: white; }
 +
 +popover.menu check:hover, popover.menu radio:hover { transform: scale(0.8); border-width: 1.2px; color: white; box-shadow: none; background-image: image(transparent); }
 +
 +popover.menu check:active, popover.menu radio:active { transform: scale(0.8); border-width: 1.2px; color: white; box-shadow: none; background-image: image(transparent); }
 +
 +popover.menu radio { border-color: #1b1b1b; }
 +
 +popover.menu radio:active { border-color: rgba(27, 27, 27, 0.5); }
 +
 +popover.menu arrow.left, popover.menu radio.left, popover.menu check.left { margin-left: -2px; margin-right: 6px; }
 +
 +popover.menu arrow.right, popover.menu radio.right, popover.menu check.right { margin-left: 6px; margin-right: -2px; }
 +
 +popover.menu modelbutton { min-height: 30px; min-width: 40px; padding: 0 12px; border-radius: 5px; }
 +
 +popover.menu modelbutton:selected { color: white; background-color: #202020; }
 +
 +popover.menu modelbutton:selected:active { background-color: #111111; }
 +
 +popover.menu label.title { font-weight: bold; padding: 4px 32px; }
 +
 +menubar { padding: 0px; box-shadow: inset 0 -1px rgba(0, 0, 0, 0.1); }
 +
 +menubar > item { min-height: 16px; padding: 4px 8px; }
 +
 +menubar > item:selected { box-shadow: inset 0 -3px #15539e; color: #3584e4; }
 +
 +menubar > item:disabled { color: #919190; box-shadow: none; }
 +
 +menubar > item popover.menu.background > contents { padding: 5px; }
 +
 +menubar > item popover.menu popover.menu { padding: 0 0 4px 0; }
 +
 +menubar > item popover.menu.background popover.menu.background > contents { margin: 0; border-radius: 9px; }
 +
 +/************* Notebooks * */
 +notebook { transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +notebook > header > tabs > tab:checked { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +notebook:focus:focus-visible > header > tabs > tab:checked { outline-color: rgba(21, 83, 158, 0.7); outline-width: 2px; outline-offset: -2px; }
 +
 +notebook > header { padding: 1px; border-color: #1b1b1b; border-width: 1px; background-color: #282828; }
 +
 +notebook > header > tabs { margin: -1px; }
 +
 +notebook > header.top { border-bottom-style: solid; }
 +
 +notebook > header.top > tabs { margin-bottom: -2px; }
 +
 +notebook > header.top > tabs > tab:hover { box-shadow: inset 0 -4px #1b1b1b; }
 +
 +notebook > header.top > tabs > tab:checked { box-shadow: inset 0 -4px #15539e; }
 +
 +notebook > header.bottom { border-top-style: solid; }
 +
 +notebook > header.bottom > tabs { margin-top: -2px; }
 +
 +notebook > header.bottom > tabs > tab:hover { box-shadow: inset 0 4px #1b1b1b; }
 +
 +notebook > header.bottom > tabs > tab:checked { box-shadow: inset 0 4px #15539e; }
 +
 +notebook > header.left { border-right-style: solid; }
 +
 +notebook > header.left > tabs { margin-right: -2px; }
 +
 +notebook > header.left > tabs > tab:hover { box-shadow: inset -4px 0 #1b1b1b; }
 +
 +notebook > header.left > tabs > tab:checked { box-shadow: inset -4px 0 #15539e; }
 +
 +notebook > header.right { border-left-style: solid; }
 +
 +notebook > header.right > tabs { margin-left: -2px; }
 +
 +notebook > header.right > tabs > tab:hover { box-shadow: inset 4px 0 #1b1b1b; }
 +
 +notebook > header.right > tabs > tab:checked { box-shadow: inset 4px 0 #15539e; }
 +
 +notebook > header.top > tabs > arrow { border-top-style: none; }
 +
 +notebook > header.bottom > tabs > arrow { border-bottom-style: none; }
 +
 +notebook > header.top > tabs > arrow, notebook > header.bottom > tabs > arrow { margin-left: -5px; margin-right: -5px; padding-left: 4px; padding-right: 4px; }
 +
 +notebook > header.top > tabs > arrow.down, notebook > header.bottom > tabs > arrow.down { -gtk-icon-source: -gtk-icontheme("pan-start-symbolic"); }
 +
 +notebook > header.top > tabs > arrow.up, notebook > header.bottom > tabs > arrow.up { -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); }
 +
 +notebook > header.left > tabs > arrow { border-left-style: none; }
 +
 +notebook > header.right > tabs > arrow { border-right-style: none; }
 +
 +notebook > header.left > tabs > arrow, notebook > header.right > tabs > arrow { margin-top: -5px; margin-bottom: -5px; padding-top: 4px; padding-bottom: 4px; }
 +
 +notebook > header.left > tabs > arrow.down, notebook > header.right > tabs > arrow.down { -gtk-icon-source: -gtk-icontheme("pan-up-symbolic"); }
 +
 +notebook > header.left > tabs > arrow.up, notebook > header.right > tabs > arrow.up { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
 +
 +notebook > header > tabs > arrow { min-height: 16px; min-width: 16px; border-radius: 0; }
 +
 +notebook > header > tabs > arrow:hover:not(:active):not(:backdrop) { background-clip: padding-box; background-image: none; background-color: rgba(255, 255, 255, 0.3); border-color: transparent; box-shadow: none; }
 +
 +notebook > header > tabs > arrow:disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; }
 +
 +notebook > header > tabs > tab { transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); min-height: 30px; min-width: 30px; padding: 3px 12px; color: #eeeeec; font-weight: normal; border-width: 1px; border-color: transparent; }
 +
 +notebook > header > tabs > tab:hover { color: #eeeeec; background-color: #1e1e1e; }
 +
 +notebook > header > tabs > tab.reorderable-page:hover { border-color: rgba(27, 27, 27, 0.3); background-color: rgba(53, 53, 53, 0.2); }
 +
 +notebook > header > tabs > tab:not(:checked) { outline-color: transparent; }
 +
 +notebook > header > tabs > tab:checked { color: #eeeeec; }
 +
 +notebook > header > tabs > tab.reorderable-page:checked { border-color: rgba(27, 27, 27, 0.5); background-color: rgba(53, 53, 53, 0.5); }
 +
 +notebook > header > tabs > tab.reorderable-page:checked:hover { background-color: rgba(53, 53, 53, 0.7); }
 +
 +notebook > header > tabs > tab button.flat { color: alpha(currentColor,0.3); padding: 0; margin-top: 4px; margin-bottom: 4px; min-width: 20px; min-height: 20px; }
 +
 +notebook > header > tabs > tab button.flat:hover { color: currentColor; }
 +
 +notebook > header > tabs > tab button.flat:last-child { margin-left: 4px; margin-right: -4px; }
 +
 +notebook > header > tabs > tab button.flat:first-child { margin-left: -4px; margin-right: 4px; }
 +
 +notebook > header.top > tabs, notebook > header.bottom > tabs { padding-left: 4px; padding-right: 4px; }
 +
 +notebook > header.top > tabs:not(:only-child), notebook > header.bottom > tabs:not(:only-child) { margin-left: 3px; margin-right: 3px; }
 +
 +notebook > header.top > tabs:not(:only-child):first-child, notebook > header.bottom > tabs:not(:only-child):first-child { margin-left: -1px; }
 +
 +notebook > header.top > tabs:not(:only-child):last-child, notebook > header.bottom > tabs:not(:only-child):last-child { margin-right: -1px; }
 +
 +notebook > header.top > tabs > tab, notebook > header.bottom > tabs > tab { margin-left: 4px; margin-right: 4px; }
 +
 +notebook > header.top > tabs > tab.reorderable-page, notebook > header.bottom > tabs > tab.reorderable-page { border-style: none solid; }
 +
 +notebook > header.left > tabs, notebook > header.right > tabs { padding-top: 4px; padding-bottom: 4px; }
 +
 +notebook > header.left > tabs:not(:only-child), notebook > header.right > tabs:not(:only-child) { margin-top: 3px; margin-bottom: 3px; }
 +
 +notebook > header.left > tabs:not(:only-child):first-child, notebook > header.right > tabs:not(:only-child):first-child { margin-top: -1px; }
 +
 +notebook > header.left > tabs:not(:only-child):last-child, notebook > header.right > tabs:not(:only-child):last-child { margin-bottom: -1px; }
 +
 +notebook > header.left > tabs > tab, notebook > header.right > tabs > tab { margin-top: 4px; margin-bottom: 4px; }
 +
 +notebook > header.left > tabs > tab.reorderable-page, notebook > header.right > tabs > tab.reorderable-page { border-style: solid none; }
 +
 +notebook > header.top > tabs > tab { padding-bottom: 4px; }
 +
 +notebook > header.bottom > tabs > tab { padding-top: 4px; }
 +
 +notebook > stack:not(:only-child) { background-color: #2d2d2d; }
 +
 +/************** Scrollbars * */
 +scrollbar { background-color: #313131; transition: all 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
 +
 +scrollbar.top { border-bottom: 1px solid #1b1b1b; }
 +
 +scrollbar.bottom { border-top: 1px solid #1b1b1b; }
 +
 +scrollbar.left { border-right: 1px solid #1b1b1b; }
 +
 +scrollbar.right { border-left: 1px solid #1b1b1b; }
 +
 +scrollbar > range > trough > slider { min-width: 8px; min-height: 8px; margin: -1px; border: 4px solid transparent; border-radius: 10px; background-clip: padding-box; background-color: #a4a4a3; transition: all 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
 +
 +scrollbar > range > trough > slider:hover { background-color: #c9c9c7; }
 +
 +scrollbar > range > trough > slider:hover:active { background-color: #1b6acb; }
 +
 +scrollbar > range > trough > slider:disabled { background-color: transparent; }
 +
 +scrollbar > range.fine-tune > trough > slider { transition: none; min-width: 6px; min-height: 6px; }
 +
 +scrollbar > range.fine-tune.horizontal > trough > slider { border-width: 5px 4px; }
 +
 +scrollbar > range.fine-tune.vertical > trough > slider { border-width: 4px 5px; }
 +
 +scrollbar.overlay-indicator:not(.dragging):not(.hovering) { border-color: transparent; opacity: 0.4; background-color: transparent; }
 +
 +scrollbar.overlay-indicator:not(.dragging):not(.hovering) > range > trough > slider { margin: 0; min-width: 3px; min-height: 3px; background-color: #eeeeec; border: 1px solid black; }
 +
 +scrollbar.overlay-indicator.horizontal:not(.dragging):not(.hovering) > range > trough > slider { margin: 0 2px; min-width: 40px; }
 +
 +scrollbar.overlay-indicator.vertical:not(.dragging):not(.hovering) > range > trough > slider { margin: 2px 0; min-height: 40px; }
 +
 +scrollbar.overlay-indicator.dragging, scrollbar.overlay-indicator.hovering { opacity: 0.8; }
 +
 +scrollbar.horizontal > range > trough > slider { min-width: 40px; }
 +
 +scrollbar.vertical > range > trough > slider { min-height: 40px; }
 +
 +treeview ~ scrollbar.vertical { border-top: 1px solid #1b1b1b; margin-top: -1px; }
 +
 +/********** Switch * */
 +switch { font-weight: bold; font-size: smaller; border: 1px solid #1b1b1b; border-radius: 14px; color: #eeeeec; background-color: #282828; transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; /* only show i / o for the accessible theme */ }
 +
 +switch { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +switch:focus:focus-visible { outline-color: rgba(21, 83, 158, 0.7); outline-width: 2px; outline-offset: 0; }
 +
 +headerbar switch { background-color: #141414; }
 +
 +switch:checked { color: #ffffff; border-color: #030c17; background-color: #15539e; }
 +
 +switch:disabled { color: #919190; border-color: #1b1b1b; background-color: #323232; text-shadow: none; }
 +
 +switch > slider { color: #eeeeec; outline-color: rgba(21, 83, 158, 0.7); border-color: #1b1b1b; background-image: linear-gradient(to top, #373737 2px, #3a3a3a); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); margin: -1px; min-width: 24px; min-height: 24px; border: 1px solid; border-color: #1b1b1b; border-radius: 50%; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
 +
 +switch > image { color: transparent; }
 +
 +switch:hover > slider { color: #eeeeec; border-color: #1b1b1b; background-image: linear-gradient(to top, #303030 20%, #323232 90%); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +switch:checked > slider { border: 1px solid #030c17; }
 +
 +switch:disabled > slider { color: #919190; border-color: #202020; background-image: image(#323232); }
 +
 +row:selected switch { outline-color: rgba(255, 255, 255, 0.3); }
 +
 +/************************* Check and Radio items * */
 +.view.content-view.check:not(list), iconview.content-view.check:not(list), .content-view .tile check:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: #15539e; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:hover:not(list), iconview.content-view.check:hover:not(list), .content-view .tile check:hover:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: #15539e; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:active:not(list), iconview.content-view.check:active:not(list), .content-view .tile check:active:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: #15539e; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:backdrop:not(list), iconview.content-view.check:backdrop:not(list), .content-view .tile check:backdrop:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: #5a5a5a; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:checked:not(list), iconview.content-view.check:checked:not(list), .content-view .tile check:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: #eeeeec; background-color: #15539e; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:checked:hover:not(list), iconview.content-view.check:checked:hover:not(list), .content-view .tile check:checked:hover:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: #eeeeec; background-color: #15539e; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:checked:active:not(list), iconview.content-view.check:checked:active:not(list), .content-view .tile check:checked:active:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: #eeeeec; background-color: #15539e; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:backdrop:checked:not(list), iconview.content-view.check:backdrop:checked:not(list), .content-view .tile check:backdrop:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: rgba(238, 238, 236, 0.8); background-color: #5a5a5a; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
 +
 +checkbutton { border-spacing: 4px; border-radius: 5px; transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +checkbutton { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +checkbutton:focus:focus-visible { outline-color: rgba(21, 83, 158, 0.7); outline-width: 2px; outline-offset: -2px; }
 +
 +checkbutton.text-button { padding: 4px; }
 +
 +check, radio { min-height: 14px; min-width: 14px; border: 1px solid; -gtk-icon-source: none; }
 +
 +check, radio { background-clip: padding-box; background-image: linear-gradient(to bottom, #424242 20%, #353535 90%); border-color: #070707; box-shadow: 0 1px rgba(0, 0, 0, 0.05); color: #ffffff; }
 +
 +check:hover, radio:hover { background-image: linear-gradient(to bottom, #4c4c4c 10%, #3f3f3f 90%); }
 +
 +check:active, radio:active { box-shadow: inset 0 1px black; background-image: image(#282828); }
 +
 +check:disabled, radio:disabled { box-shadow: none; color: rgba(255, 255, 255, 0.7); }
 +
 +check:checked, radio:checked { background-clip: border-box; background-image: linear-gradient(to bottom, #185fb4 20%, #15539e 90%); border-color: #092444; box-shadow: 0 1px rgba(0, 0, 0, 0.05); color: #ffffff; }
 +
 +check:checked:hover, radio:checked:hover { background-image: linear-gradient(to bottom, #1b68c6 10%, #185cb0 90%); }
 +
 +check:checked:active, radio:checked:active { box-shadow: inset 0 1px black; background-image: image(#124787); }
 +
 +check:checked:disabled, radio:checked:disabled { box-shadow: none; color: rgba(255, 255, 255, 0.7); }
 +
 +check:indeterminate, radio:indeterminate { background-clip: border-box; background-image: linear-gradient(to bottom, #185fb4 20%, #15539e 90%); border-color: #092444; box-shadow: 0 1px rgba(0, 0, 0, 0.05); color: #ffffff; }
 +
 +check:indeterminate:hover, radio:indeterminate:hover { background-image: linear-gradient(to bottom, #1b68c6 10%, #185cb0 90%); }
 +
 +check:indeterminate:active, radio:indeterminate:active { box-shadow: inset 0 1px black; background-image: image(#124787); }
 +
 +check:indeterminate:disabled, radio:indeterminate:disabled { box-shadow: none; color: rgba(255, 255, 255, 0.7); }
 +
 +.osd check, .osd radio { color: #eeeeec; outline-color: rgba(21, 83, 158, 0.7); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; }
 +
 +.osd check:hover, .osd radio:hover { color: #eeeeec; outline-color: rgba(21, 83, 158, 0.7); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; }
 +
 +.osd check:active, .osd radio:active { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; }
 +
 +.osd check:disabled, .osd radio:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; }
 +
 +check { border-radius: 3px; -gtk-icon-size: 14px; }
 +
 +check:checked { -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets/check-symbolic.symbolic.png")), -gtk-recolor(url("assets/check@2-symbolic.symbolic.png"))); }
 +
 +check:indeterminate { -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets/dash-symbolic.symbolic.png")), -gtk-recolor(url("assets/dash@2-symbolic.symbolic.png"))); }
 +
 +treeview.view radio:selected:focus, treeview.view radio:selected, radio { border-radius: 100%; -gtk-icon-size: 14px; }
 +
 +treeview.view radio:checked:selected, radio:checked { -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets/bullet-symbolic.symbolic.png")), -gtk-recolor(url("assets/bullet@2-symbolic.symbolic.png"))); }
 +
 +treeview.view radio:indeterminate:selected, radio:indeterminate { -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets/dash-symbolic.symbolic.png")), -gtk-recolor(url("assets/dash@2-symbolic.symbolic.png"))); }
 +
 +treeview.view check:selected:focus, treeview.view check:selected, treeview.view radio:selected:focus, treeview.view radio:selected { color: #ffffff; }
 +
 +/************ GtkScale * */
 +progressbar > trough, scale > trough > fill, scale > trough { border: 1px solid #282828; border-radius: 3px; background-color: #282828; }
 +
 +headerbar progressbar > trough, headerbar scale > trough > fill, headerbar scale > trough { background-color: #141414; }
 +
 +progressbar > trough:disabled, scale > trough > fill:disabled, scale > trough:disabled { background-color: #323232; border-color: #202020; }
 +
 +row:selected progressbar > trough, row:selected scale > trough > fill, row:selected scale > trough { outline-color: rgba(255, 255, 255, 0.3); border-color: #030c17; }
 +
 +.osd progressbar > trough, .osd scale > trough > fill, .osd scale > trough { border-color: rgba(0, 0, 0, 0.7); background-color: rgba(0, 0, 0, 0.5); }
 +
 +.osd progressbar > trough:disabled, .osd scale > trough > fill:disabled, .osd scale > trough:disabled { background-color: rgba(58, 58, 57, 0.5); }
 +
 +progressbar > trough > progress, scale > trough > highlight { border: 1px solid #15539e; border-radius: 3px; background-color: #15539e; }
 +
 +progressbar > trough > progress:disabled, scale > trough > highlight:disabled { background-color: transparent; border-color: transparent; }
 +
 +row:selected progressbar > trough > progress, row:selected scale > trough > highlight { border-color: #030c17; }
 +
 +.osd progressbar > trough > progress, .osd scale > trough > highlight { border-color: rgba(0, 0, 0, 0.7); }
 +
 +.osd progressbar > trough > progress:disabled, .osd scale > trough > highlight:disabled { border-color: transparent; }
 +
 +scale { min-height: 10px; min-width: 10px; padding: 12px; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +scale > trough { outline: 0 solid transparent; outline-offset: 16px; }
 +
 +scale:focus:focus-visible > trough { outline-color: rgba(21, 83, 158, 0.7); outline-width: 2px; outline-offset: 10px; }
 +
 +scale > trough { transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
 +
 +scale > trough > fill, scale > trough > highlight { margin: -1px; }
 +
 +scale > trough > slider { min-height: 18px; min-width: 18px; margin: -9px; }
 +
 +scale.fine-tune.horizontal { padding-top: 9px; padding-bottom: 9px; min-height: 16px; }
 +
 +scale.fine-tune.vertical { padding-left: 9px; padding-right: 9px; min-width: 16px; }
 +
 +scale.fine-tune > trough > slider { margin: -6px; }
 +
 +scale.fine-tune > trough > fill, scale.fine-tune > trough > highlight, scale.fine-tune > trough { border-radius: 5px; }
 +
 +scale > trough > fill:disabled { border-color: transparent; background-color: transparent; }
 +
 +.osd scale > trough > fill { background-color: rgba(91, 91, 90, 0.775); }
 +
 +.osd scale > trough > fill:disabled { border-color: transparent; background-color: transparent; }
 +
 +scale > trough > slider { color: #eeeeec; outline-color: rgba(21, 83, 158, 0.7); border-color: #1b1b1b; background-image: linear-gradient(to top, #373737 2px, #3a3a3a); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); border-width: 1px; border-style: solid; border-radius: 100%; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: background, border, box-shadow; }
 +
 +scale > trough > slider:hover { color: #eeeeec; border-color: #1b1b1b; background-image: linear-gradient(to top, #303030 20%, #323232 90%); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +scale > trough > slider:active { border-color: #030c17; }
 +
 +scale > trough > slider:disabled { color: #919190; border-color: #202020; background-image: image(#323232); }
 +
 +row:selected scale > trough > slider:disabled, row:selected scale > trough > slider { border-color: #030c17; }
 +
 +.osd scale > trough > slider { color: #eeeeec; outline-color: rgba(21, 83, 158, 0.7); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; border-color: rgba(0, 0, 0, 0.7); background-color: #262626; }
 +
 +.osd scale > trough > slider:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(12, 12, 12, 0.7)); background-clip: padding-box; background-color: #262626; }
 +
 +.osd scale > trough > slider:active { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; background-color: #262626; }
 +
 +.osd scale > trough > slider:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; background-color: #262626; }
 +
 +scale > value { color: alpha(currentColor,0.55); font-feature-settings: "tnum"; }
 +
 +scale.horizontal > marks { color: alpha(currentColor,0.55); }
 +
 +scale.horizontal > marks.top { margin-bottom: 6px; }
 +
 +scale.horizontal > marks.bottom { margin-top: 6px; }
 +
 +scale.horizontal > marks indicator { background-color: currentColor; min-height: 6px; min-width: 1px; }
 +
 +scale.horizontal > value.left { margin-right: 9px; }
 +
 +scale.horizontal > value.right { margin-left: 9px; }
 +
 +scale.horizontal.fine-tune > marks.top { margin-top: 3px; }
 +
 +scale.horizontal.fine-tune > marks.bottom { margin-bottom: 3px; }
 +
 +scale.horizontal.fine-tune > marks indicator { min-height: 3px; }
 +
 +scale.vertical > marks { color: alpha(currentColor,0.55); }
 +
 +scale.vertical > marks.top { margin-right: 6px; }
 +
 +scale.vertical > marks.bottom { margin-left: 6px; }
 +
 +scale.vertical > marks indicator { background-color: currentColor; min-height: 1px; min-width: 6px; }
 +
 +scale.vertical > value.top { margin-bottom: 9px; }
 +
 +scale.vertical > value.bottom { margin-top: 9px; }
 +
 +scale.vertical.fine-tune > marks.top { margin-left: 3px; }
 +
 +scale.vertical.fine-tune > marks.bottom { margin-right: 3px; }
 +
 +scale.vertical.fine-tune > marks indicator { min-height: 3px; }
 +
 +scale.horizontal.marks-before:not(.marks-after) > trough > slider { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-above-dark.png"), url("assets/slider-horz-scale-has-marks-above-dark@2.png")); min-height: 26px; min-width: 22px; margin-top: -14px; background-position: top; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -7px -10px; margin-top: -11px; }
 +
 +scale.horizontal.marks-before:not(.marks-after) > trough > slider:hover { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-above-hover-dark.png"), url("assets/slider-horz-scale-has-marks-above-hover-dark@2.png")); min-height: 26px; min-width: 22px; margin-top: -14px; background-position: top; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -7px -10px; margin-top: -11px; }
 +
 +scale.horizontal.marks-before:not(.marks-after) > trough > slider:active { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-above-active-dark.png"), url("assets/slider-horz-scale-has-marks-above-active-dark@2.png")); min-height: 26px; min-width: 22px; margin-top: -14px; background-position: top; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -7px -10px; margin-top: -11px; }
 +
 +scale.horizontal.marks-before:not(.marks-after) > trough > slider:disabled { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-above-insensitive-dark.png"), url("assets/slider-horz-scale-has-marks-above-insensitive-dark@2.png")); min-height: 26px; min-width: 22px; margin-top: -14px; background-position: top; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -7px -10px; margin-top: -11px; }
 +
 +scale.horizontal.marks-after:not(.marks-before) > trough > slider { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-below-dark.png"), url("assets/slider-horz-scale-has-marks-below-dark@2.png")); min-height: 26px; min-width: 22px; margin-bottom: -14px; background-position: bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -7px -10px; margin-bottom: -11px; }
 +
 +scale.horizontal.marks-after:not(.marks-before) > trough > slider:hover { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-below-hover-dark.png"), url("assets/slider-horz-scale-has-marks-below-hover-dark@2.png")); min-height: 26px; min-width: 22px; margin-bottom: -14px; background-position: bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -7px -10px; margin-bottom: -11px; }
 +
 +scale.horizontal.marks-after:not(.marks-before) > trough > slider:active { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-below-active-dark.png"), url("assets/slider-horz-scale-has-marks-below-active-dark@2.png")); min-height: 26px; min-width: 22px; margin-bottom: -14px; background-position: bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -7px -10px; margin-bottom: -11px; }
 +
 +scale.horizontal.marks-after:not(.marks-before) > trough > slider:disabled { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-below-insensitive-dark.png"), url("assets/slider-horz-scale-has-marks-below-insensitive-dark@2.png")); min-height: 26px; min-width: 22px; margin-bottom: -14px; background-position: bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -7px -10px; margin-bottom: -11px; }
 +
 +scale.vertical.marks-before:not(.marks-after) > trough > slider { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-above-dark.png"), url("assets/slider-vert-scale-has-marks-above-dark@2.png")); min-height: 22px; min-width: 26px; margin-left: -14px; background-position: left bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -10px -7px; margin-left: -11px; }
 +
 +scale.vertical.marks-before:not(.marks-after) > trough > slider:hover { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-above-hover-dark.png"), url("assets/slider-vert-scale-has-marks-above-hover-dark@2.png")); min-height: 22px; min-width: 26px; margin-left: -14px; background-position: left bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -10px -7px; margin-left: -11px; }
 +
 +scale.vertical.marks-before:not(.marks-after) > trough > slider:active { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-above-active-dark.png"), url("assets/slider-vert-scale-has-marks-above-active-dark@2.png")); min-height: 22px; min-width: 26px; margin-left: -14px; background-position: left bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -10px -7px; margin-left: -11px; }
 +
 +scale.vertical.marks-before:not(.marks-after) > trough > slider:disabled { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-above-insensitive-dark.png"), url("assets/slider-vert-scale-has-marks-above-insensitive-dark@2.png")); min-height: 22px; min-width: 26px; margin-left: -14px; background-position: left bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -10px -7px; margin-left: -11px; }
 +
 +scale.vertical.marks-after:not(.marks-before) > trough > slider { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-below-dark.png"), url("assets/slider-vert-scale-has-marks-below-dark@2.png")); min-height: 22px; min-width: 26px; margin-right: -14px; background-position: right bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -10px -7px; margin-right: -11px; }
 +
 +scale.vertical.marks-after:not(.marks-before) > trough > slider:hover { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-below-hover-dark.png"), url("assets/slider-vert-scale-has-marks-below-hover-dark@2.png")); min-height: 22px; min-width: 26px; margin-right: -14px; background-position: right bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -10px -7px; margin-right: -11px; }
 +
 +scale.vertical.marks-after:not(.marks-before) > trough > slider:active { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-below-active-dark.png"), url("assets/slider-vert-scale-has-marks-below-active-dark@2.png")); min-height: 22px; min-width: 26px; margin-right: -14px; background-position: right bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -10px -7px; margin-right: -11px; }
 +
 +scale.vertical.marks-after:not(.marks-before) > trough > slider:disabled { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-below-insensitive-dark.png"), url("assets/slider-vert-scale-has-marks-below-insensitive-dark@2.png")); min-height: 22px; min-width: 26px; margin-right: -14px; background-position: right bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -10px -7px; margin-right: -11px; }
 +
 +scale.color { min-height: 0; min-width: 0; }
 +
 +scale.color > trough { background-image: image(#1b1b1b); background-repeat: no-repeat; }
 +
 +scale.color.horizontal { padding: 0 0 15px 0; }
 +
 +scale.color.horizontal > trough { padding-bottom: 4px; background-position: 0 -3px; border-top-left-radius: 0; border-top-right-radius: 0; }
 +
 +scale.color.horizontal > trough > slider:dir(ltr):hover, scale.color.horizontal > trough > slider:dir(ltr):backdrop, scale.color.horizontal > trough > slider:dir(ltr):disabled, scale.color.horizontal > trough > slider:dir(ltr):backdrop:disabled, scale.color.horizontal > trough > slider:dir(ltr), scale.color.horizontal > trough > slider:dir(rtl):hover, scale.color.horizontal > trough > slider:dir(rtl):backdrop, scale.color.horizontal > trough > slider:dir(rtl):disabled, scale.color.horizontal > trough > slider:dir(rtl):backdrop:disabled, scale.color.horizontal > trough > slider:dir(rtl) { margin-bottom: -15px; margin-top: 6px; }
 +
 +scale.color.vertical:dir(ltr) { padding: 0 0 0 15px; }
 +
 +scale.color.vertical:dir(ltr) > trough { padding-left: 4px; background-position: 3px 0; border-bottom-right-radius: 0; border-top-right-radius: 0; }
 +
 +scale.color.vertical:dir(ltr) > trough > slider:hover, scale.color.vertical:dir(ltr) > trough > slider:backdrop, scale.color.vertical:dir(ltr) > trough > slider:disabled, scale.color.vertical:dir(ltr) > trough > slider:backdrop:disabled, scale.color.vertical:dir(ltr) > trough > slider { margin-left: -15px; margin-right: 6px; }
 +
 +scale.color.vertical:dir(rtl) { padding: 0 15px 0 0; }
 +
 +scale.color.vertical:dir(rtl) > trough { padding-right: 4px; background-position: -3px 0; border-bottom-left-radius: 0; border-top-left-radius: 0; }
 +
 +scale.color.vertical:dir(rtl) > trough > slider:hover, scale.color.vertical:dir(rtl) > trough > slider:backdrop, scale.color.vertical:dir(rtl) > trough > slider:disabled, scale.color.vertical:dir(rtl) > trough > slider:backdrop:disabled, scale.color.vertical:dir(rtl) > trough > slider { margin-right: -15px; margin-left: 6px; }
 +
 +scale.color.fine-tune.horizontal:dir(ltr), scale.color.fine-tune.horizontal:dir(rtl) { padding: 0 0 12px 0; }
 +
 +scale.color.fine-tune.horizontal:dir(ltr) > trough, scale.color.fine-tune.horizontal:dir(rtl) > trough { padding-bottom: 7px; background-position: 0 -6px; }
 +
 +scale.color.fine-tune.horizontal:dir(ltr) > trough > slider, scale.color.fine-tune.horizontal:dir(rtl) > trough > slider { margin-bottom: -15px; margin-top: 6px; }
 +
 +scale.color.fine-tune.vertical:dir(ltr) { padding: 0 0 0 12px; }
 +
 +scale.color.fine-tune.vertical:dir(ltr) > trough { padding-left: 7px; background-position: 6px 0; }
 +
 +scale.color.fine-tune.vertical:dir(ltr) > trough > slider { margin-left: -15px; margin-right: 6px; }
 +
 +scale.color.fine-tune.vertical:dir(rtl) { padding: 0 12px 0 0; }
 +
 +scale.color.fine-tune.vertical:dir(rtl) > trough { padding-right: 7px; background-position: -6px 0; }
 +
 +scale.color.fine-tune.vertical:dir(rtl) > trough > slider { margin-right: -15px; margin-left: 6px; }
 +
 +/***************** Progress bars * */
 +progressbar { font-size: smaller; color: rgba(238, 238, 236, 0.4); font-feature-settings: "tnum"; }
 +
 +progressbar.horizontal > trough { min-width: 150px; }
 +
 +progressbar.horizontal > trough, progressbar.horizontal > trough > progress { min-height: 2px; }
 +
 +progressbar.vertical > trough { min-height: 80px; }
 +
 +progressbar.vertical > trough, progressbar.vertical > trough > progress { min-width: 2px; }
 +
 +progressbar.horizontal > trough > progress { margin: 0 -1px; }
 +
 +progressbar.vertical > trough > progress { margin: -1px 0; }
 +
 +progressbar > trough > progress { /* share most of scales' */ /* override insensitive that is specific to progress */ border-radius: 1.5px; }
 +
 +progressbar > trough > progress:disabled { background-color: #919190; border-color: #919190; }
 +
 +progressbar > trough > progress.left { border-top-left-radius: 5px; border-bottom-left-radius: 5px; }
 +
 +progressbar > trough > progress.right { border-top-right-radius: 5px; border-bottom-right-radius: 5px; }
 +
 +progressbar > trough > progress.top { border-top-right-radius: 5px; border-top-left-radius: 5px; }
 +
 +progressbar > trough > progress.bottom { border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; }
 +
 +progressbar.osd { min-width: 3px; min-height: 3px; background-color: transparent; }
 +
 +progressbar.osd > trough { border-style: none; border-radius: 0; background-color: transparent; box-shadow: none; }
 +
 +progressbar.osd > trough > progress { border-style: none; border-radius: 0; }
 +
 +progressbar > trough.empty > progress { all: unset; }
 +
 +/************* Level Bar * */
 +levelbar.horizontal trough > block { min-height: 9px; border-radius: 5px; }
 +
 +levelbar.horizontal trough > block:dir(rtl) { border-radius: 0 5px 5px 0; }
 +
 +levelbar.horizontal trough > block:dir(ltr) { border-radius: 5px 0 0 5px; }
 +
 +levelbar.horizontal trough > block.empty, levelbar.horizontal trough > block.full { border-radius: 5px; }
 +
 +levelbar.horizontal.discrete trough > block { min-height: 2px; margin: 1px; min-width: 24px; border-radius: 0; }
 +
 +levelbar.horizontal.discrete trough > block:first-child { border-radius: 2px 0 0 2px; }
 +
 +levelbar.horizontal.discrete trough > block:last-child { border-radius: 0 2px 2px 0; }
 +
 +levelbar.vertical trough > block { min-width: 9px; border-radius: 5px; }
 +
 +levelbar.vertical.discrete > trough > block { min-width: 2px; margin: 1px 0; min-height: 32px; }
 +
 +levelbar > trough { padding: 0; }
 +
 +levelbar > trough > block { border: 1px solid; }
 +
 +levelbar > trough > block.low { border-color: #f57900; background-color: #f57900; }
 +
 +levelbar > trough > block.high, levelbar > trough > block:not(.empty) { border-color: #15539e; background-color: #15539e; }
 +
 +levelbar > trough > block.full { border-color: #26ab62; background-color: #26ab62; }
 +
 +levelbar > trough > block.empty { background-color: #282828; border-color: #282828; }
 +
 +/**************** Print dialog * */
 +window.dialog.print drawing { color: #eeeeec; background: none; border: none; padding: 0; }
 +
 +window.dialog.print drawing paper { background: white; color: #2e3436; border: 1px solid #1b1b1b; }
 +
 +window.dialog.print .dialog-action-box { margin: 12px; }
 +
 +/********** Frames * */
 +frame, .frame { border: 1px solid #1b1b1b; }
 +
 +frame { border-radius: 8px; }
 +
 +frame > label { margin: 4px; }
 +
 +actionbar > revealer > box { padding: 6px; border-top: 1px solid #1b1b1b; }
 +
 +actionbar > revealer > box, actionbar > revealer > box > box.start, actionbar > revealer > box > box.end { border-spacing: 6px; }
 +
 +scrolledwindow > overshoot.top { background-image: radial-gradient(farthest-side at top, #020202 85%, rgba(2, 2, 2, 0)), radial-gradient(farthest-side at top, rgba(238, 238, 236, 0.07), rgba(238, 238, 236, 0)); background-size: 100% 3%, 100% 50%; background-repeat: no-repeat; background-position: top; background-color: transparent; border: none; box-shadow: none; }
 +
 +scrolledwindow > overshoot.bottom { background-image: radial-gradient(farthest-side at bottom, #020202 85%, rgba(2, 2, 2, 0)), radial-gradient(farthest-side at bottom, rgba(238, 238, 236, 0.07), rgba(238, 238, 236, 0)); background-size: 100% 3%, 100% 50%; background-repeat: no-repeat; background-position: bottom; background-color: transparent; border: none; box-shadow: none; }
 +
 +scrolledwindow > overshoot.left { background-image: radial-gradient(farthest-side at left, #020202 85%, rgba(2, 2, 2, 0)), radial-gradient(farthest-side at left, rgba(238, 238, 236, 0.07), rgba(238, 238, 236, 0)); background-size: 3% 100%, 50% 100%; background-repeat: no-repeat; background-position: left; background-color: transparent; border: none; box-shadow: none; }
 +
 +scrolledwindow > overshoot.right { background-image: radial-gradient(farthest-side at right, #020202 85%, rgba(2, 2, 2, 0)), radial-gradient(farthest-side at right, rgba(238, 238, 236, 0.07), rgba(238, 238, 236, 0)); background-size: 3% 100%, 50% 100%; background-repeat: no-repeat; background-position: right; background-color: transparent; border: none; box-shadow: none; }
 +
 +scrolledwindow > junction { background: #1b1b1b, linear-gradient(to bottom, transparent 1px, #313131 1px), linear-gradient(to right, transparent 1px, #313131 1px); }
 +
 +scrolledwindow > junction:dir(rtl) { background: #1b1b1b, linear-gradient(to bottom, transparent 1px, #313131 1px), linear-gradient(to left, transparent 1px, #313131 1px); }
 +
 +separator { background: #282828; min-width: 1px; min-height: 1px; }
 +
 +/********* Lists * */
 +listview, list { color: white; background-color: #2d2d2d; border-color: #1b1b1b; }
 +
 +listview:backdrop, list:backdrop { color: #d6d6d6; background-color: #303030; border-color: #202020; }
 +
 +listview > row, list > row { padding: 2px; }
 +
 +listview > row.expander, list > row.expander { padding: 0px; }
 +
 +listview > row.expander .row-header, list > row.expander .row-header { padding: 2px; }
 +
 +listview.horizontal row.separator, listview.separators.horizontal > row:not(.separator), list.horizontal row.separator, list.separators.horizontal > row:not(.separator) { border-left: 1px solid #545453; }
 +
 +listview:not(.horizontal) row.separator, listview.separators:not(.horizontal) > row:not(.separator), list:not(.horizontal) row.separator, list.separators:not(.horizontal) > row:not(.separator) { border-bottom: 1px solid #545453; }
 +
 +row { transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +row { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +row:focus:focus-visible { outline-color: rgba(21, 83, 158, 0.7); outline-width: 2px; outline-offset: -2px; }
 +
 +row.activatable.has-open-popup, row.activatable:hover { background-color: rgba(238, 238, 236, 0.05); }
 +
 +row.activatable:active { box-shadow: inset 0 2px 2px -2px rgba(0, 0, 0, 0.2); }
 +
 +row.activatable:selected:active { box-shadow: inset 0 2px 3px -1px rgba(0, 0, 0, 0.5); }
 +
 +row.activatable.has-open-popup:selected, row.activatable:selected:hover { background-color: #2b62a6; }
 +
 +row:selected { outline-color: rgba(255, 255, 255, 0.3); }
 +
 +columnview > listview > row { padding: 0; }
 +
 +columnview > listview > row > cell { padding: 8px 6px; }
 +
 +columnview > listview > row > cell:not(:first-child) { border-left: 1px solid transparent; }
 +
 +columnview.column-separators > listview > row > cell { border-left-color: #545453; }
 +
 +columnview.data-table > listview > row > cell { padding-top: 2px; padding-bottom: 2px; }
 +
 +treeexpander { border-spacing: 4px; }
 +
 +/******************************************************** Data Tables                                          * treeview like tables with individual focusable cells * https://gitlab.gnome.org/GNOME/gtk/-/issues/2929     * */
 +columnview row:not(:selected) cell editablelabel:not(.editing):focus-within { outline: 2px solid rgba(21, 83, 158, 0.7); }
 +
 +columnview row:not(:selected) cell editablelabel.editing:focus-within { outline: 2px solid #15539e; }
 +
 +columnview row:not(:selected) cell editablelabel.editing text selection { color: #ffffff; background-color: #15539e; }
 +
 +/******************************************************* Rich Lists                                          * Large list usually containing lots of widgets       * https://gitlab.gnome.org/GNOME/gtk/-/issues/3073    * */
 +.rich-list { /* rich lists usually containing other widgets than just labels/text */ }
 +
 +.rich-list > row { padding: 8px 12px; min-height: 32px; /* should be tall even when only containing a label */ }
 +
 +.rich-list > row > box { border-spacing: 12px; }
 +
 +/********************* App Notifications * */
 +.app-notification { padding: 10px; border-spacing: 10px; border-radius: 0 0 5px 5px; background-color: rgba(38, 38, 38, 0.7); background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.2), transparent 2px); background-clip: padding-box; }
 +
 +.app-notification border { border: none; }
 +
 +/************* Expanders * */
 +expander { min-width: 16px; min-height: 16px; -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); }
 +
 +expander:dir(rtl) { -gtk-icon-source: -gtk-icontheme("pan-end-symbolic-rtl"); }
 +
 +expander:disabled { color: #919190; }
 +
 +expander:checked { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
 +
 +expander-widget { transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +expander-widget > box > title { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +expander-widget:focus:focus-visible > box > title { outline-color: rgba(21, 83, 158, 0.7); outline-width: 2px; outline-offset: -2px; }
 +
 +expander-widget > box > title { transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); border-radius: 5px; }
 +
 +expander-widget > box > title:hover > expander { color: white; }
 +
 +.navigation-sidebar:not(decoration):not(window):drop(active):focus, .navigation-sidebar:not(decoration):not(window):drop(active), placessidebar:not(decoration):not(window):drop(active):focus, placessidebar:not(decoration):not(window):drop(active), stackswitcher:not(decoration):not(window):drop(active):focus, stackswitcher:not(decoration):not(window):drop(active), expander-widget:not(decoration):not(window):drop(active):focus, expander-widget:not(decoration):not(window):drop(active) { box-shadow: none; }
 +
 +/************ Calendar * */
 +calendar { color: white; border: 1px solid #1b1b1b; }
 +
 +calendar > header { border-bottom: 1px solid #1b1b1b; }
 +
 +calendar > header > button { border: none; box-shadow: none; background: none; border-radius: 0; }
 +
 +calendar > header > button:backdrop { background: none; }
 +
 +calendar > grid > label.today { box-shadow: inset 0px -2px #1b1b1b; }
 +
 +calendar > grid > label.today:selected { box-shadow: none; }
 +
 +calendar > grid > label:focus { outline-color: rgba(21, 83, 158, 0.7); outline-offset: -2px; outline-width: 2px; outline-style: solid; }
 +
 +calendar > grid > label.day-number { padding: 4px; }
 +
 +calendar > grid > label.day-number:selected { border-radius: 3px; }
 +
 +calendar > grid > label.day-number.other-month { color: alpha(currentColor,0.3); }
 +
 +/*********** Dialogs * */
 +window.dialog.message .titlebar { min-height: 20px; background-image: none; background-color: #353535; border-style: none; border-top-left-radius: 7px; border-top-right-radius: 7px; }
 +
 +window.dialog.message box.dialog-vbox.vertical { border-spacing: 10px; }
 +
 +window.dialog.message label.title { font-weight: 800; font-size: 15pt; }
 +
 +window.dialog.message.csd.background { border-bottom-left-radius: 9px; border-bottom-right-radius: 9px; }
 +
 +window.dialog.message.csd .dialog-action-area button { padding: 10px 14px; border-radius: 0; border-left-style: solid; border-right-style: none; border-bottom-style: none; }
 +
 +window.dialog.message.csd .dialog-action-area button:first-child { border-left-style: none; border-bottom-left-radius: 7px; }
 +
 +window.dialog.message.csd .dialog-action-area button:last-child { border-bottom-right-radius: 7px; }
 +
 +filechooser .dialog-action-box { border-top: 1px solid #1b1b1b; }
 +
 +filechooser #pathbarbox { border-bottom: 1px solid #353535; }
 +
 +filechooserbutton > button > box { border-spacing: 6px; }
 +
 +filechooserbutton:drop(active) { box-shadow: none; border-color: transparent; }
 +
 +/*********** Sidebar * */
 +.sidebar { background-color: #313131; }
 +
 +.sidebar:not(separator):dir(ltr), .sidebar.left:not(separator), .sidebar.left:not(separator):dir(rtl) { border-right: 1px solid #1b1b1b; border-left-style: none; }
 +
 +.sidebar:not(separator):dir(rtl), .sidebar.right:not(separator) { border-left: 1px solid #1b1b1b; border-right-style: none; }
 +
 +.sidebar listview.view, .sidebar list { background-color: transparent; }
 +
 +paned .sidebar.left, paned .sidebar.right, paned .sidebar.left:dir(rtl), paned .sidebar:dir(rtl), paned .sidebar:dir(ltr), paned .sidebar { border-style: none; }
 +
 +stacksidebar list.separators:not(.horizontal) > row:not(.separator) { border-bottom: none; }
 +
 +stacksidebar row { padding: 10px 4px; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +stacksidebar row { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +stacksidebar row:focus:focus-visible { outline-color: rgba(21, 83, 158, 0.7); outline-width: 2px; outline-offset: -2px; }
 +
 +stacksidebar row > label { padding-left: 6px; padding-right: 6px; }
 +
 +stacksidebar row.needs-attention > label { background-size: 6px 6px, 0 0; }
 +
 +stacksidebar row:selected { background-color: #202020; border-radius: 5px; color: #eeeeec; }
 +
 +stacksidebar row:selected:hover:dir(ltr), stacksidebar row:selected:hover:dir(rtl) { background-color: #141414; }
 +
 +stacksidebar row.activatable:active, stacksidebar row.activatable:selected:active { box-shadow: none; }
 +
 +separator.sidebar { background-color: #1b1b1b; }
 +
 +/********************** Navigation Sidebar * */
 +.navigation-sidebar { padding: 5px 0; }
 +
 +.navigation-sidebar > separator { margin: 5px; }
 +
 +.navigation-sidebar > row { min-height: 36px; padding: 0 8px; border-radius: 5px; margin: 0 5px 2px; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +.navigation-sidebar > row { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +.navigation-sidebar > row:focus-visible:focus-within { outline-color: rgba(21, 83, 158, 0.7); outline-width: 2px; outline-offset: -2px; }
 +
 +.navigation-sidebar > row:hover { background-color: #141414; }
 +
 +.navigation-sidebar > row:selected { background-color: #202020; color: inherit; }
 +
 +.navigation-sidebar > row:selected:hover { background-color: #141414; }
 +
 +.navigation-sidebar > row:disabled { color: #919190; }
 +
 +/**************** File chooser * */
 +row image.sidebar-icon { opacity: 0.7; }
 +
 +/* this should be more generic, only using .navigation-sidebar https://gitlab.gnome.org/GNOME/gtk/-/issues/2929 */
 +placessidebar .navigation-sidebar > row { padding: 0; }
 +
 +placessidebar .navigation-sidebar > row > revealer { padding: 0 14px; }
 +
 +placessidebar .navigation-sidebar > row image.sidebar-icon:dir(ltr) { padding-right: 8px; }
 +
 +placessidebar .navigation-sidebar > row image.sidebar-icon:dir(rtl) { padding-left: 8px; }
 +
 +placessidebar .navigation-sidebar > row label.sidebar-label:dir(ltr) { padding-right: 2px; }
 +
 +placessidebar .navigation-sidebar > row label.sidebar-label:dir(rtl) { padding-left: 2px; }
 +
 +button.sidebar-button { min-height: 26px; min-width: 26px; margin-top: 3px; margin-bottom: 3px; padding: 0; border-radius: 100%; }
 +
 +placessidebar .navigation-sidebar > row:selected:active { box-shadow: none; }
 +
 +placessidebar .navigation-sidebar > row.sidebar-placeholder-row { padding: 0 8px; min-height: 2px; background-image: image(#26a269); background-clip: content-box; }
 +
 +placessidebar .navigation-sidebar > row.sidebar-new-bookmark-row { color: #15539e; }
 +
 +placessidebar .navigation-sidebar > row:drop(active):not(:disabled) { color: #26a269; box-shadow: inset 0 1px #26a269, inset 0 -1px #26a269; }
 +
 +placessidebar .navigation-sidebar > row:drop(active):not(:disabled):selected { color: #ffffff; background-color: #26a269; }
 +
 +placesview .server-list-button > image { transition: 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); -gtk-icon-transform: rotate(0turn); }
 +
 +placesview .server-list-button:checked > image { transition: 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); -gtk-icon-transform: rotate(-0.5turn); }
 +
 +placesview > actionbar > revealer > box > box { border-spacing: 6px; }
 +
 +/********* Paned * */
 +paned > separator { min-width: 1px; min-height: 1px; -gtk-icon-source: none; border-style: none; background-color: transparent; background-image: image(#1b1b1b); background-size: 1px 1px; }
 +
 +paned > separator:selected { background-image: image(#15539e); }
 +
 +paned > separator.wide { min-width: 5px; min-height: 5px; background-color: #353535; background-image: image(#1b1b1b), image(#1b1b1b); background-size: 1px 1px, 1px 1px; }
 +
 +paned.horizontal > separator { background-repeat: repeat-y; }
 +
 +paned.horizontal > separator:dir(ltr) { margin: 0 -8px 0 0; padding: 0 8px 0 0; background-position: left; }
 +
 +paned.horizontal > separator:dir(rtl) { margin: 0 0 0 -8px; padding: 0 0 0 8px; background-position: right; }
 +
 +paned.horizontal > separator.wide { margin: 0; padding: 0; background-repeat: repeat-y, repeat-y; background-position: left, right; }
 +
 +paned.vertical > separator { margin: 0 0 -8px 0; padding: 0 0 8px 0; background-repeat: repeat-x; background-position: top; }
 +
 +paned.vertical > separator.wide { margin: 0; padding: 0; background-repeat: repeat-x, repeat-x; background-position: bottom, top; }
 +
 +/************** GtkVideo * */
 +video { background: black; }
 +
 +video image.osd { min-width: 64px; min-height: 64px; border-radius: 32px; }
 +
 +/************ Tooltips * */
 +tooltip { padding: 6px 10px; border-radius: 8px; box-shadow: none; }
 +
 +tooltip.background { background-color: rgba(0, 0, 0, 0.8); background-clip: padding-box; border: 1px solid rgba(255, 255, 255, 0.1); color: white; }
 +
 +tooltip > box { border-spacing: 6px; }
 +
 +/***************** Color Chooser * */
 +colorswatch { transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +colorswatch { outline: 0 solid transparent; outline-offset: 6px; }
 +
 +colorswatch:focus:focus-visible { outline-color: rgba(21, 83, 158, 0.7); outline-width: 4px; outline-offset: -2px; }
 +
 +colorswatch:drop(active), colorswatch { border-style: none; }
 +
 +colorswatch.top { border-top-left-radius: 5.5px; border-top-right-radius: 5.5px; }
 +
 +colorswatch.top > overlay { border-top-left-radius: 5px; border-top-right-radius: 5px; }
 +
 +colorswatch.bottom { border-bottom-left-radius: 5.5px; border-bottom-right-radius: 5.5px; }
 +
 +colorswatch.bottom > overlay { border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; }
 +
 +colorswatch.left, colorswatch:first-child:not(.top) { border-top-left-radius: 5.5px; border-bottom-left-radius: 5.5px; }
 +
 +colorswatch.left > overlay, colorswatch:first-child:not(.top) > overlay { border-top-left-radius: 5px; border-bottom-left-radius: 5px; }
 +
 +colorswatch.right, colorswatch:last-child:not(.bottom) { border-top-right-radius: 5.5px; border-bottom-right-radius: 5.5px; }
 +
 +colorswatch.right > overlay, colorswatch:last-child:not(.bottom) > overlay { border-top-right-radius: 5px; border-bottom-right-radius: 5px; }
 +
 +colorswatch.dark > overlay { color: white; }
 +
 +colorswatch.dark.activatable:hover > overlay { border-color: #1b1b1b; }
 +
 +colorswatch.light > overlay { color: black; }
 +
 +colorswatch.light.activatable:hover > overlay { border-color: #1b1b1b; }
 +
 +colorswatch:drop(active) { box-shadow: none; }
 +
 +colorswatch.light:drop(active) > overlay { border-color: #26a269; box-shadow: inset 0 0 0 2px #1b1b1b, inset 0 0 0 1px #26a269; }
 +
 +colorswatch.dark:drop(active) > overlay { border-color: #26a269; box-shadow: inset 0 0 0 2px #1b1b1b, inset 0 0 0 1px #26a269; }
 +
 +colorswatch > overlay { border: 1px solid #1b1b1b; }
 +
 +colorswatch.activatable:hover > overlay { box-shadow: inset 0 1px rgba(255, 255, 255, 0.4), inset 0 -1px rgba(0, 0, 0, 0.2); }
 +
 +colorswatch#add-color-button { border-radius: 5px 0 0 5px; }
 +
 +colorswatch#add-color-button:only-child { border-radius: 5px; }
 +
 +colorswatch#add-color-button > overlay { color: #eeeeec; outline-color: rgba(21, 83, 158, 0.7); border-color: #1b1b1b; background-image: linear-gradient(to top, #373737 2px, #3a3a3a); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +colorswatch#add-color-button.activatable:hover > overlay { color: #eeeeec; border-color: #1b1b1b; background-image: linear-gradient(to top, #303030 20%, #323232 90%); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +colorswatch:disabled { opacity: 0.5; }
 +
 +colorswatch:disabled > overlay { border-color: rgba(0, 0, 0, 0.6); box-shadow: none; }
 +
 +row:selected colorswatch { box-shadow: 0 0 0 2px #ffffff; }
 +
 +colorswatch#editor-color-sample { border-radius: 4px; }
 +
 +colorswatch#editor-color-sample > overlay { border-radius: 4.5px; }
 +
 +plane { transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +plane { outline: 0 solid transparent; outline-offset: 6px; }
 +
 +plane:focus:focus-visible { outline-color: rgba(21, 83, 158, 0.7); outline-width: 2px; outline-offset: 2px; }
 +
 +colorchooser .popover.osd { border-radius: 5px; }
 +
 +/******** Misc * */
 +.content-view { background-color: #232323; }
 +
 +.content-view:hover { -gtk-icon-filter: brightness(1.2); }
 +
 +.content-view .tile { margin: 2px; background-color: black; border-radius: 0; padding: 0; }
 +
 +.content-view .tile:active, .content-view .tile:selected { background-color: #15539e; }
 +
 +.content-view .tile:disabled { background-color: #323232; }
 +
 +.osd .scale-popup button.flat { border-style: none; border-radius: 5px; }
 +
 +.scale-popup button:hover { background-color: rgba(238, 238, 236, 0.1); border-radius: 5px; }
 +
 +/********************** Window Decorations * */
 +window { border-width: 0px; }
 +
 +window.csd { box-shadow: 0 3px 9px 1px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(0, 0, 0, 0.75); margin: 0px; border-radius: 8px 8px 0 0; }
 +
 +window.csd:backdrop { box-shadow: 0 3px 9px 1px transparent, 0 2px 6px 2px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.75); transition: 200ms ease-out; }
 +
 +window.csd.popup { border-radius: 5px; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.65); }
 +
 +window.csd.dialog.message { border-radius: 8px; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.65); }
 +
 +window.solid-csd { margin: 0; padding: 4px; border: solid 1px #1b1b1b; border-radius: 0; box-shadow: inset 0 0 0 4px #1b1b1b, inset 0 0 0 3px #2d2d2d, inset 0 1px rgba(238, 238, 236, 0.07); }
 +
 +window.solid-csd:backdrop { box-shadow: inset 0 0 0 4px #1b1b1b, inset 0 0 0 3px #353535, inset 0 1px rgba(238, 238, 236, 0.07); }
 +
 +window.maximized, window.fullscreen { border-radius: 0; box-shadow: none; }
 +
 +window.tiled, window.tiled-top, window.tiled-left, window.tiled-right, window.tiled-bottom { border-radius: 0; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.75), 0 0 0 20px transparent; }
 +
 +window:backdrop { box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.75), 0 0 0 20px transparent; }
 +
 +window.popup { box-shadow: none; }
 +
 +window.ssd { box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.75); }
 +
 +tooltip.csd { border-radius: 5px; box-shadow: none; }
 +
 +.view:selected:focus, .view:selected, textview > text:selected:focus, textview > text:selected, textview > text > selection:focus, textview > text > selection, iconview:selected:focus, iconview:selected, flowbox > flowboxchild:selected, gridview > child:selected, entry > text > selection, modelbutton.flat:selected, spinbutton:not(.vertical) > text > selection, spinbutton.vertical > text > text > selection, spinbutton.vertical > text > selection, columnview.view:selected:focus, columnview.view:selected, treeview.view:selected:focus, treeview.view:selected, row:selected, calendar > grid > label.day-number:selected { background-color: #15539e; }
 +
 +label:selected, .view:selected:focus, .view:selected, textview > text:selected:focus, textview > text:selected, textview > text > selection:focus, textview > text > selection, iconview:selected:focus, iconview:selected, flowbox > flowboxchild:selected, gridview > child:selected, entry > text > selection, modelbutton.flat:selected, spinbutton:not(.vertical) > text > selection, spinbutton.vertical > text > text > selection, spinbutton.vertical > text > selection, columnview.view:selected:focus, columnview.view:selected, treeview.view:selected:focus, treeview.view:selected, row:selected, calendar > grid > label.day-number:selected { color: #ffffff; }
 +
 +label:disabled > selection, label:disabled:selected, .view:disabled:selected, textview > text:disabled:selected:focus, textview > text:disabled:selected, textview > text > selection:disabled, iconview:disabled:selected:focus, iconview:disabled:selected, flowbox > flowboxchild:disabled:selected, gridview > child:disabled:selected, entry > text > selection:disabled, modelbutton.flat:disabled:selected, spinbutton:not(.vertical) > text > selection:disabled, spinbutton.vertical > text > text > selection:disabled, spinbutton.vertical > text > selection:disabled, columnview.view:disabled:selected, treeview.view:disabled:selected, row:disabled:selected, calendar > grid > label.day-number:disabled:selected { color: #8aa9ce; }
 +
 +.monospace { font-family: monospace; }
 +
 +/********************** Touch Copy & Paste * */
 +cursor-handle { background-color: transparent; background-image: none; box-shadow: none; border-style: none; min-width: 20px; min-height: 24px; padding-left: 20px; padding-right: 20px; padding-top: 24px; padding-bottom: 24px; }
 +
 +cursor-handle.top:dir(ltr), cursor-handle.bottom:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets/text-select-start-dark.png"), url("assets/text-select-start-dark@2.png")); }
 +
 +cursor-handle.bottom:dir(ltr), cursor-handle.top:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets/text-select-end-dark.png"), url("assets/text-select-end-dark@2.png")); }
 +
 +cursor-handle.insertion-cursor:dir(ltr), cursor-handle.insertion-cursor:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets/slider-horz-scale-has-marks-above-dark.png"), url("assets/slider-horz-scale-has-marks-above-dark@2.png")); }
 +
 +cursor-handle.top:hover:dir(ltr), cursor-handle.bottom:hover:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets/text-select-start-hover-dark.png"), url("assets/text-select-start-hover-dark@2.png")); }
 +
 +cursor-handle.bottom:hover:dir(ltr), cursor-handle.top:hover:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets/text-select-end-hover-dark.png"), url("assets/text-select-end-hover-dark@2.png")); }
 +
 +cursor-handle.insertion-cursor:hover:dir(ltr), cursor-handle.insertion-cursor:hover:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets/slider-horz-scale-has-marks-above-hover-dark.png"), url("assets/slider-horz-scale-has-marks-above-hover-dark@2.png")); }
 +
 +cursor-handle.top:active:dir(ltr), cursor-handle.bottom:active:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets/text-select-start-active-dark.png"), url("assets/text-select-start-active-dark@2.png")); }
 +
 +cursor-handle.bottom:active:dir(ltr), cursor-handle.top:active:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets/text-select-end-active-dark.png"), url("assets/text-select-end-active-dark@2.png")); }
 +
 +cursor-handle.insertion-cursor:active:dir(ltr), cursor-handle.insertion-cursor:active:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets/slider-horz-scale-has-marks-above-active-dark.png"), url("assets/slider-horz-scale-has-marks-above-active-dark@2.png")); }
 +
 +shortcuts-section { margin: 20px; }
 +
 +.shortcuts-search-results { margin: 20px; border-spacing: 24px; }
 +
 +shortcut { border-spacing: 6px; }
 +
 +shortcut > .keycap { min-width: 20px; min-height: 25px; margin-top: 2px; padding-bottom: 3px; padding-left: 6px; padding-right: 6px; color: #eeeeec; background-color: #2d2d2d; border: 1px solid; border-color: #1b1b1b; border-radius: 5px; box-shadow: inset 0 -3px #222222; font-size: smaller; }
 +
 +:not(decoration):not(window):drop(active):focus, :not(decoration):not(window):drop(active) { border-color: #26a269; box-shadow: inset 0 0 0 1px #26a269; caret-color: #26a269; }
 +
 +stackswitcher > button.text-button { min-width: 100px; }
 +
 +stackswitcher.circular { border-spacing: 12px; }
 +
 +stackswitcher.circular > button.circular, stackswitcher.circular > button.text-button.circular { min-width: 32px; min-height: 32px; padding: 0; }
 +
 +/************* App Icons * */
 +/* Outline for low res icons */
 +.lowres-icon { -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.05), 1px 0 rgba(0, 0, 0, 0.1), 0 1px rgba(0, 0, 0, 0.3), -1px 0 rgba(0, 0, 0, 0.1); }
 +
 +/* Drapshadow for large icons */
 +.icon-dropshadow { -gtk-icon-shadow: 0 1px 12px rgba(0, 0, 0, 0.05), 0 -1px rgba(0, 0, 0, 0.05), 1px 0 rgba(0, 0, 0, 0.1), 0 1px rgba(0, 0, 0, 0.3), -1px 0 rgba(0, 0, 0, 0.1); }
 +
 +/********* Emoji * */
 +popover.emoji-picker > contents { padding: 0; }
 +
 +.emoji-searchbar { padding: 6px; border-spacing: 6px; border-bottom: 1px solid #1b1b1b; }
 +
 +.emoji-toolbar { padding: 6px; border-spacing: 6px; border-top: 1px solid #1b1b1b; }
 +
 +button.emoji-section { border-color: transparent; border-width: 3px; border-style: none none solid; border-radius: 0; padding: 3px 0 0; min-width: 32px; min-height: 28px; /* reset props inherited from the button style */ background: none; box-shadow: none; text-shadow: none; }
 +
 +button.emoji-section:hover { border-color: rgba(238, 238, 236, 0.1); }
 +
 +button.emoji-section:checked { border-color: #15539e; }
 +
 +popover.emoji-picker emoji { font-size: x-large; padding: 6px; border-radius: 6px; }
 +
 +popover.emoji-picker emoji:focus, popover.emoji-picker emoji:hover { background: #15539e; }
 +
 +emoji-completion-row > box { border-spacing: 10px; padding: 2px 10px; }
 +
 +emoji-completion-row:focus, emoji-completion-row:hover { background-color: #15539e; color: #ffffff; }
 +
 +emoji-completion-row emoji:focus, emoji-completion-row emoji:hover { background-color: #202020; }
 +
 +popover.entry-completion > contents { padding: 0; }
 +
 +statusbar { padding: 6px 10px 6px 10px; }
 +
 +menubutton > button > box { border-spacing: 6px; }
 +
 +menubutton arrow { min-height: 16px; min-width: 16px; }
 +
 +menubutton arrow.none { -gtk-icon-source: -gtk-icontheme("open-menu-symbolic"); }
 +
 +menubutton arrow.down { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
 +
 +menubutton arrow.up { -gtk-icon-source: -gtk-icontheme("pan-up-symbolic"); }
 +
 +menubutton arrow.left { -gtk-icon-source: -gtk-icontheme("pan-start-symbolic"); }
 +
 +menubutton arrow.right { -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); }
 +
 +/* GTK NAMED COLORS ---------------- use responsibly! */
 +/*
 +widget text/foreground color */
 +@define-color theme_fg_color #eeeeec;
 +/*
 +text color for entries, views and content in general */
 +@define-color theme_text_color white;
 +/*
 +widget base background color */
 +@define-color theme_bg_color #353535;
 +/*
 +text widgets and the like base background color */
 +@define-color theme_base_color #2d2d2d;
 +/*
 +base background color of selections */
 +@define-color theme_selected_bg_color #15539e;
 +/*
 +text/foreground color of selections */
 +@define-color theme_selected_fg_color #ffffff;
 +/*
 +base background color of insensitive widgets */
 +@define-color insensitive_bg_color #323232;
 +/*
 +text foreground color of insensitive widgets */
 +@define-color insensitive_fg_color #919190;
 +/*
 +insensitive text widgets and the like base background color */
 +@define-color insensitive_base_color #2d2d2d;
 +/*
 +widget text/foreground color on backdrop windows */
 +@define-color theme_unfocused_fg_color #919190;
 +/*
 +text color for entries, views and content in general on backdrop windows */
 +@define-color theme_unfocused_text_color white;
 +/*
 +widget base background color on backdrop windows */
 +@define-color theme_unfocused_bg_color #353535;
 +/*
 +text widgets and the like base background color on backdrop windows */
 +@define-color theme_unfocused_base_color #303030;
 +/*
 +base background color of selections on backdrop windows */
 +@define-color theme_unfocused_selected_bg_color #15539e;
 +/*
 +text/foreground color of selections on backdrop windows */
 +@define-color theme_unfocused_selected_fg_color #ffffff;
 +/*
 +insensitive color on backdrop windows*/
 +@define-color unfocused_insensitive_color #5b5b5b;
 +/*
 +widgets main borders color */
 +@define-color borders #1b1b1b;
 +/*
 +widgets main borders color on backdrop windows */
 +@define-color unfocused_borders #202020;
 +/*
 +these are pretty self explicative */
 +@define-color warning_color #f57900;
 +@define-color error_color #cc0000;
 +@define-color success_color #26ab62;
 +/*
 +these colors are exported for the window manager and shouldn't be used in applications,
 +read if you used those and something break with a version upgrade you're on your own... */
 +@define-color wm_title shade(#eeeeec, 1.8);
 +@define-color wm_unfocused_title #919190;
 +@define-color wm_highlight rgba(0, 0, 0, 0);
 +@define-color wm_borders_edge rgba(238, 238, 236, 0.07);
 +@define-color wm_bg_a shade(#353535, 1.2);
 +@define-color wm_bg_b #353535;
 +@define-color wm_shadow alpha(black, 0.35);
 +@define-color wm_border alpha(black, 0.18);
 +@define-color wm_button_hover_color_a shade(#353535, 1.3);
 +@define-color wm_button_hover_color_b #353535;
 +@define-color wm_button_active_color_a shade(#353535, 0.85);
 +@define-color wm_button_active_color_b shade(#353535, 0.89);
 +@define-color wm_button_active_color_c shade(#353535, 0.9);
 +/* content view background such as thumbnails view in Photos or Boxes */
 +@define-color content_view_bg #2d2d2d;
 +/* Very contrasty background for text views (@theme_text_color foreground) */
 +@define-color text_view_bg #1e1e1e;
index d8564f173a0838630c1bcac0434261e2535c998a,0000000000000000000000000000000000000000..23752c4a68589f5acc6a778c3f9ea2c93f6d8b83
mode 100644,000000..100644
--- /dev/null
@@@ -1,1857 -1,0 +1,1847 @@@
- button.sidebar-button, notebook > header > tabs > arrow, windowcontrols button, notebook > header > tabs > arrow.flat, button.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; transition: none; }
 +/* GTK NAMED COLORS ---------------- use responsibly! */
 +/*
 +widget text/foreground color */
 +@define-color theme_fg_color #f3f3f1;
 +/*
 +text color for entries, views and content in general */
 +@define-color theme_text_color white;
 +/*
 +widget base background color */
 +@define-color theme_bg_color #303030;
 +/*
 +text widgets and the like base background color */
 +@define-color theme_base_color #2d2d2d;
 +/*
 +base background color of selections */
 +@define-color theme_selected_bg_color #0f3b71;
 +/*
 +text/foreground color of selections */
 +@define-color theme_selected_fg_color #ffffff;
 +/*
 +base background color of insensitive widgets */
 +@define-color insensitive_bg_color #2f2f2f;
 +/*
 +text foreground color of insensitive widgets */
 +@define-color insensitive_fg_color #919191;
 +/*
 +insensitive text widgets and the like base background color */
 +@define-color insensitive_base_color #2d2d2d;
 +/*
 +widget text/foreground color on backdrop windows */
 +@define-color theme_unfocused_fg_color #919190;
 +/*
 +text color for entries, views and content in general on backdrop windows */
 +@define-color theme_unfocused_text_color white;
 +/*
 +widget base background color on backdrop windows */
 +@define-color theme_unfocused_bg_color #353535;
 +/*
 +text widgets and the like base background color on backdrop windows */
 +@define-color theme_unfocused_base_color #303030;
 +/*
 +base background color of selections on backdrop windows */
 +@define-color theme_unfocused_selected_bg_color #0f3b71;
 +/*
 +text/foreground color of selections on backdrop windows */
 +@define-color theme_unfocused_selected_fg_color #ffffff;
 +/*
 +insensitive color on backdrop windows*/
 +@define-color unfocused_insensitive_color #5b5b5b;
 +/*
 +widgets main borders color */
 +@define-color borders #686868;
 +/*
 +widgets main borders color on backdrop windows */
 +@define-color unfocused_borders #202020;
 +/*
 +these are pretty self explicative */
 +@define-color warning_color #f57900;
 +@define-color error_color #cc0000;
 +@define-color success_color #26ab62;
 +/*
 +these colors are exported for the window manager and shouldn't be used in applications,
 +read if you used those and something break with a version upgrade you're on your own... */
 +@define-color wm_title shade(#f3f3f1, 1.8);
 +@define-color wm_unfocused_title #919190;
 +@define-color wm_highlight rgba(0, 0, 0, 0);
 +@define-color wm_borders_edge rgba(238, 238, 236, 0.07);
 +@define-color wm_bg_a shade(#303030, 1.2);
 +@define-color wm_bg_b #303030;
 +@define-color wm_shadow alpha(black, 0.35);
 +@define-color wm_border alpha(black, 0.18);
 +@define-color wm_button_hover_color_a shade(#303030, 1.3);
 +@define-color wm_button_hover_color_b #303030;
 +@define-color wm_button_active_color_a shade(#303030, 0.85);
 +@define-color wm_button_active_color_b shade(#303030, 0.89);
 +@define-color wm_button_active_color_c shade(#303030, 0.9);
 +/* content view background such as thumbnails view in Photos or Boxes */
 +@define-color content_view_bg #2d2d2d;
 +/* Very contrasty background for text views (@theme_text_color foreground) */
 +@define-color text_view_bg #1e1e1e;
 +/*************************** Check and Radio buttons * */
 +/*************** Base States * */
 +.background { color: #f3f3f1; background-color: #303030; }
 +
 +.background:backdrop { text-shadow: none; -gtk-icon-shadow: none; }
 +
 +dnd { color: #f3f3f1; }
 +
 +.normal-icons { -gtk-icon-size: 16px; }
 +
 +.large-icons { -gtk-icon-size: 32px; }
 +
 +image:disabled { -gtk-icon-filter: opacity(0.5); }
 +
 +.view, iconview, textview > text { color: white; background-color: #2d2d2d; }
 +
 +.view:disabled, iconview:disabled, textview > text:disabled { color: #919191; background-color: #2f2f2f; }
 +
 +.view:selected:focus, iconview:selected:focus, .view:selected, iconview:selected, textview > text:selected:focus, textview > text:selected { border-radius: 3px; }
 +
 +textview:drop(active) { caret-color: #26a269; }
 +
 +textview > border { background-color: #2e2e2e; }
 +
 +iconview { transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +iconview { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +iconview:focus:focus-visible { outline-color: rgba(255, 255, 255, 0.6); outline-width: 2px; outline-offset: -2px; }
 +
 +iconview:drop(active) { box-shadow: none; }
 +
 +iconview > dndtarget:drop(active) { border-style: solid; border-width: 1px; border-color: black; }
 +
 +rubberband, .content-view > rubberband, columnview.view > rubberband, treeview.view > rubberband, gridview > rubberband, flowbox > rubberband { border: 1px solid #092444; background-color: rgba(9, 36, 68, 0.2); }
 +
 +flowbox > flowboxchild { padding: 3px; transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +flowbox > flowboxchild { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +flowbox > flowboxchild:focus:focus-visible { outline-color: rgba(255, 255, 255, 0.6); outline-width: 2px; outline-offset: -2px; }
 +
 +flowbox > flowboxchild:selected { outline-color: rgba(255, 255, 255, 0.6); }
 +
 +gridview > child { padding: 3px; transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +gridview > child { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +gridview > child:focus:focus-visible { outline-color: rgba(255, 255, 255, 0.6); outline-width: 2px; outline-offset: -2px; }
 +
 +gridview > child:selected { outline-color: rgba(255, 255, 255, 0.6); }
 +
 +gridview > child box { border-spacing: 8px; margin: 12px; }
 +
 +coverflow cover { color: white; background-color: #2d2d2d; border: 1px solid black; }
 +
 +label { transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +label { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +label:focus:focus-visible { outline-color: rgba(255, 255, 255, 0.6); outline-width: 2px; outline-offset: -2px; }
 +
 +label > selection { background-color: #0f3b71; color: #ffffff; }
 +
 +label:disabled { color: #919191; }
 +
 +button label:disabled { color: inherit; }
 +
 +label.error { color: #cc0000; }
 +
 +label.error:disabled { color: rgba(204, 0, 0, 0.5); }
 +
 +.dim-label, .titlebar:not(headerbar) .subtitle, headerbar .subtitle, spinbutton.vertical > text > text > placeholder, spinbutton:not(.vertical) > text > placeholder, entry > text > placeholder, label.separator { opacity: 0.9; text-shadow: none; }
 +
 +window.assistant .sidebar { padding: 5px; border-top: 1px solid #686868; }
 +
 +window.assistant.csd .sidebar { border-top-style: none; }
 +
 +window.assistant .sidebar > label { padding: 6px 12px; }
 +
 +window.assistant .sidebar > label.highlight { background-color: #161616; border-radius: 5px; }
 +
 +window.aboutdialog image.large-icons { -gtk-icon-size: 128px; }
 +
 +.osd .scale-popup, .app-notification, .osd popover.background > arrow, .osd popover.background > contents, popover.background.touch-selection > arrow, popover.background.touch-selection > contents, popover.background.magnifier > arrow, popover.background.magnifier > contents, .osd { color: #eeeeec; border: none; background-color: rgba(38, 38, 38, 0.7); background-clip: padding-box; -gtk-icon-shadow: 0 1px black; }
 +
 +/********************* Spinner Animation * */
 +@keyframes spin { to { transform: rotate(1turn); } }
 +
 +spinner { background: none; opacity: 0; -gtk-icon-source: -gtk-icontheme("process-working-symbolic"); }
 +
 +spinner:checked { opacity: 1; animation: spin 1s linear infinite; }
 +
 +spinner:checked:disabled { opacity: 0.5; }
 +
 +/********************** General Typography * */
 +.large-title { font-weight: 300; font-size: 24pt; }
 +
 +.title-1 { font-weight: 800; font-size: 20pt; }
 +
 +.title-2 { font-weight: 800; font-size: 15pt; }
 +
 +.title-3 { font-weight: 700; font-size: 15pt; }
 +
 +.title-4 { font-weight: 700; font-size: 13pt; }
 +
 +.heading { font-weight: 700; font-size: 11pt; }
 +
 +.body { font-weight: 400; font-size: 11pt; }
 +
 +.caption-heading { font-weight: 700; font-size: 9pt; }
 +
 +.caption { font-weight: 400; font-size: 9pt; }
 +
 +/**************** Text Entries * */
 +spinbutton.vertical > text, spinbutton:not(.vertical), entry { min-height: 32px; padding-left: 8px; padding-right: 8px; border: 1px solid; border-radius: 5px; border-spacing: 6px; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); color: white; border-color: #686868; background-color: #2d2d2d; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +spinbutton.vertical > text, spinbutton:not(.vertical), entry { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +spinbutton.vertical > text:focus-within, spinbutton:focus-within:not(.vertical), entry:focus-within { outline-color: rgba(255, 255, 255, 0.6); outline-width: 2px; outline-offset: -2px; }
 +
 +spinbutton.vertical > text > image.left, spinbutton:not(.vertical) > image.left, entry > image.left { margin-right: 6px; }
 +
 +spinbutton.vertical > text > image.right, spinbutton:not(.vertical) > image.right, entry > image.right { margin-left: 6px; }
 +
 +spinbutton.vertical > text > text > block-cursor, spinbutton:not(.vertical) > text > block-cursor, entry > text > block-cursor { color: #2d2d2d; background-color: white; }
 +
 +spinbutton.vertical > text.flat, spinbutton.flat:not(.vertical), entry.flat:focus-within, entry.flat:backdrop, entry.flat:disabled, entry.flat { min-height: 0; padding: 2px; background-color: transparent; border-color: transparent; border-radius: 0; }
 +
 +spinbutton.vertical > text:focus-within > placeholder, spinbutton:focus-within:not(.vertical) > placeholder, entry:focus-within > placeholder { opacity: 0; /* We hide placeholders on focus */ }
 +
 +spinbutton.vertical > text:disabled, spinbutton:disabled:not(.vertical), entry:disabled { color: #919191; border-color: #686868; background-color: #2f2f2f; }
 +
 +spinbutton.vertical > text.error, spinbutton.error:not(.vertical), entry.error { color: #cc0000; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +spinbutton.vertical > text.error, spinbutton.error:not(.vertical), entry.error { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +spinbutton.vertical > text.error:focus-within, spinbutton.error:focus-within:not(.vertical), entry.error:focus-within { outline-color: rgba(204, 0, 0, 0.5); outline-width: 2px; outline-offset: -2px; }
 +
 +spinbutton.vertical > text.error > selection, spinbutton.error:not(.vertical) > selection, entry.error > selection { background-color: #cc0000; }
 +
 +spinbutton.vertical > text.warning, spinbutton.warning:not(.vertical), entry.warning { color: #f57900; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +spinbutton.vertical > text.warning, spinbutton.warning:not(.vertical), entry.warning { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +spinbutton.vertical > text.warning:focus-within, spinbutton.warning:focus-within:not(.vertical), entry.warning:focus-within { outline-color: rgba(245, 121, 0, 0.5); outline-width: 2px; outline-offset: -2px; }
 +
 +spinbutton.vertical > text.warning > selection, spinbutton.warning:not(.vertical) > selection, entry.warning > selection { background-color: #f57900; }
 +
 +spinbutton.vertical > text > image, spinbutton:not(.vertical) > image, entry > image { color: #cbcbca; }
 +
 +spinbutton.vertical > text > image:hover, spinbutton:not(.vertical) > image:hover, entry > image:hover { color: #f3f3f1; }
 +
 +spinbutton.vertical > text > image:active, spinbutton:not(.vertical) > image:active, entry > image:active { color: #0f3b71; }
 +
 +spinbutton.vertical > text.password image.caps-lock-indicator, spinbutton.password:not(.vertical) image.caps-lock-indicator, entry.password image.caps-lock-indicator { color: #7e7e7d; }
 +
 +spinbutton.vertical > text:drop(active), spinbutton:drop(active):not(.vertical), entry:drop(active):focus-within, entry:drop(active) { border-color: #26a269; box-shadow: inset 0 0 0 1px #26a269; }
 +
 +.osd spinbutton.vertical > text, .osd spinbutton:not(.vertical), .osd entry { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: rgba(0, 0, 0, 0.5); background-clip: padding-box; box-shadow: none; -gtk-icon-shadow: 0 1px black; }
 +
 +.osd spinbutton.vertical > text:focus-within, .osd spinbutton:focus-within:not(.vertical), .osd entry:focus-within { color: white; border-color: #0f3b71; background-color: rgba(0, 0, 0, 0.5); background-clip: padding-box; }
 +
 +.osd spinbutton.vertical > text:disabled, .osd spinbutton:disabled:not(.vertical), .osd entry:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: rgba(58, 58, 57, 0.5); background-clip: padding-box; }
 +
 +spinbutton.vertical > text > progress, spinbutton:not(.vertical) > progress, entry > progress { margin-bottom: 2px; }
 +
 +spinbutton.vertical > text progress > trough > progress, spinbutton:not(.vertical) progress > trough > progress, entry progress > trough > progress { background-color: transparent; background-image: none; border-radius: 0; border-width: 0 0 2px; border-color: #0f3b71; border-style: solid; box-shadow: none; }
 +
 +spinbutton.vertical.linked:not(.vertical) > text:drop(active) + text, spinbutton.vertical.linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + text, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + spinbutton:not(.vertical), .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + spinbutton:not(.vertical), spinbutton.vertical.linked:not(.vertical) > text:drop(active) + button, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + button, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + menubutton > button, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + menubutton > button, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + dropdown > button, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + dropdown > button, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + colorbutton > button, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + colorbutton > button, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + fontbutton > button, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + fontbutton > button, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + filechooserbutton > button, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + filechooserbutton > button, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + combobox > box > button.combo, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + combobox > box > button.combo, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + entry, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + entry, .linked:not(.vertical) > entry:drop(active) + button, .linked:not(.vertical) > entry:drop(active) + menubutton > button, .linked:not(.vertical) > entry:drop(active) + dropdown > button, .linked:not(.vertical) > entry:drop(active) + colorbutton > button, .linked:not(.vertical) > entry:drop(active) + fontbutton > button, .linked:not(.vertical) > entry:drop(active) + filechooserbutton > button, .linked:not(.vertical) > entry:drop(active) + combobox > box > button.combo, spinbutton.vertical.linked:not(.vertical) > entry:drop(active) + text, .linked:not(.vertical) > entry:drop(active) + spinbutton:not(.vertical), .linked:not(.vertical) > entry:drop(active) + entry { border-left-color: #26a269; }
 +
 +spinbutton.vertical.linked > text:not(:disabled) + entry:not(:disabled), .linked.vertical > spinbutton:not(:disabled):not(.vertical) + entry:not(:disabled), spinbutton.vertical.linked > text:not(:disabled) + text:not(:disabled), spinbutton.vertical.linked > spinbutton:not(:disabled):not(.vertical) + text:not(:disabled), spinbutton.vertical.linked > text:not(:disabled) + spinbutton:not(:disabled):not(.vertical), .linked.vertical > spinbutton:not(:disabled):not(.vertical) + spinbutton:not(:disabled):not(.vertical), .linked.vertical > entry:not(:disabled) + entry:not(:disabled), spinbutton.vertical.linked > entry:not(:disabled) + text:not(:disabled), .linked.vertical > entry:not(:disabled) + spinbutton:not(:disabled):not(.vertical) { border-top-color: #3f3f3f; }
 +
 +spinbutton.vertical.linked > text:disabled + text:disabled, spinbutton.vertical.linked > spinbutton:disabled:not(.vertical) + text:disabled, spinbutton.vertical.linked > text:disabled + spinbutton:disabled:not(.vertical), .linked.vertical > spinbutton:disabled:not(.vertical) + spinbutton:disabled:not(.vertical), spinbutton.vertical.linked > text:disabled + entry:disabled, .linked.vertical > spinbutton:disabled:not(.vertical) + entry:disabled, spinbutton.vertical.linked > entry:disabled + text:disabled, .linked.vertical > entry:disabled + spinbutton:disabled:not(.vertical), .linked.vertical > entry:disabled + entry:disabled { border-top-color: #3f3f3f; }
 +
 +spinbutton.vertical.linked > text + text:drop(active):not(:only-child), spinbutton.vertical.linked > spinbutton:not(.vertical) + text:drop(active):not(:only-child), spinbutton.vertical.linked > text + spinbutton:drop(active):not(:only-child):not(.vertical), .linked.vertical > spinbutton:not(.vertical) + spinbutton:drop(active):not(:only-child):not(.vertical), spinbutton.vertical.linked > text + entry:drop(active):not(:only-child), .linked.vertical > spinbutton:not(.vertical) + entry:drop(active):not(:only-child), spinbutton.vertical.linked > entry + text:drop(active):not(:only-child), .linked.vertical > entry + spinbutton:drop(active):not(:only-child):not(.vertical), .linked.vertical > entry + entry:drop(active):not(:only-child) { border-top-color: #26a269; }
 +
 +spinbutton.vertical.linked > text:drop(active):not(:only-child) + text, spinbutton.vertical.linked > spinbutton:drop(active):not(:only-child):not(.vertical) + text, spinbutton.vertical.linked > text:drop(active):not(:only-child) + spinbutton:not(.vertical), .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + spinbutton:not(.vertical), spinbutton.vertical.linked > text:drop(active):not(:only-child) + entry, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + entry, spinbutton.vertical.linked > text:drop(active):not(:only-child) + button, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + button, spinbutton.vertical.linked > text:drop(active):not(:only-child) + menubutton > button, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + menubutton > button, spinbutton.vertical.linked > text:drop(active):not(:only-child) + dropdown > button, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + dropdown > button, spinbutton.vertical.linked > text:drop(active):not(:only-child) + colorbutton > button, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + colorbutton > button, spinbutton.vertical.linked > text:drop(active):not(:only-child) + fontbutton > button, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + fontbutton > button, spinbutton.vertical.linked > text:drop(active):not(:only-child) + filechooserbutton > button, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + filechooserbutton > button, spinbutton.vertical.linked > text:drop(active):not(:only-child) + combobox > box > button.combo, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + combobox > box > button.combo, spinbutton.vertical.linked > entry:drop(active):not(:only-child) + text, .linked.vertical > entry:drop(active):not(:only-child) + spinbutton:not(.vertical), .linked.vertical > entry:drop(active):not(:only-child) + entry, .linked.vertical > entry:drop(active):not(:only-child) + button, .linked.vertical > entry:drop(active):not(:only-child) + menubutton > button, .linked.vertical > entry:drop(active):not(:only-child) + dropdown > button, .linked.vertical > entry:drop(active):not(:only-child) + colorbutton > button, .linked.vertical > entry:drop(active):not(:only-child) + fontbutton > button, .linked.vertical > entry:drop(active):not(:only-child) + filechooserbutton > button, .linked.vertical > entry:drop(active):not(:only-child) + combobox > box > button.combo { border-top-color: #26a269; }
 +
 +spinbutton.vertical > text.error, spinbutton.error:not(.vertical), entry.error { color: #cc0000; }
 +
 +treeview entry:focus-within:dir(rtl), treeview entry:focus-within:dir(ltr) { background-color: #2d2d2d; transition-property: color, background; }
 +
 +treeview entry.flat, treeview entry { border-radius: 0; background-image: none; background-color: #2d2d2d; }
 +
 +treeview entry.flat:focus-within, treeview entry:focus-within { border-color: #0f3b71; }
 +
 +/******************* Editable Labels * */
 +editablelabel > stack > text { color: white; border-color: #686868; background-color: #2d2d2d; }
 +
 +/*********** Buttons * */
 +@keyframes needs_attention { from { background-image: radial-gradient(farthest-side, #185fb4 0%, rgba(24, 95, 180, 0) 0%); }
 +  to { background-image: radial-gradient(farthest-side, #185fb4 95%, rgba(24, 95, 180, 0)); } }
 +
 +notebook > header > tabs > arrow, windowcontrols button, button { min-height: 24px; min-width: 16px; padding: 4px 9px; border: 1px solid; border-radius: 5px; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); color: #f3f3f1; outline-color: rgba(255, 255, 255, 0.6); border-color: #686868; background-image: linear-gradient(to top, #323232 2px, #353535); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +notebook > header > tabs > arrow, windowcontrols button, button { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +notebook > header > tabs > arrow:focus:focus-visible, button:focus:focus-visible { outline-color: rgba(255, 255, 255, 0.6); outline-width: 2px; outline-offset: -2px; }
 +
 +notebook > header > tabs > arrow:hover, button:hover { color: #f3f3f1; border-color: #686868; background-image: linear-gradient(to top, #2b2b2b 20%, #2d2d2d 90%); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); -gtk-icon-filter: brightness(1.2); }
 +
 +notebook > header > tabs > arrow.keyboard-activating, notebook > header > tabs > arrow:active, notebook > header > tabs > arrow:checked, button.keyboard-activating, button:active, button:checked { color: #f3f3f1; border-color: #686868; background-image: image(#1e1e1e); box-shadow: none; transition-duration: 50ms; }
 +
 +notebook > header > tabs > arrow:checked:hover, button:checked:hover { color: #f3f3f1; border-color: #686868; background-image: image(#161616); box-shadow: none; }
 +
 +notebook > header > tabs > arrow:checked:active, button:checked:active { color: #f3f3f1; border-color: #686868; background-image: image(#111111); box-shadow: none; }
 +
 +notebook > header > tabs > arrow:backdrop, button.flat:backdrop, button:backdrop { color: #919190; border-color: #202020; background-image: image(#353535); box-shadow: none; transition: 200ms ease-out; }
 +
 +notebook > header > tabs > arrow:backdrop:not(:disabled), button.flat:backdrop:not(:disabled), button:backdrop:not(:disabled) { -gtk-icon-filter: none; }
 +
 +notebook > header > tabs > arrow:backdrop:active, notebook > header > tabs > arrow:backdrop:checked, button.flat:backdrop:active, button.flat:backdrop:checked, button:backdrop:active, button:backdrop:checked { color: #919190; border-color: #202020; background-image: image(#2a2a2a); box-shadow: none; }
 +
 +notebook > header > tabs > arrow:backdrop:disabled, button.flat:backdrop:disabled, button:backdrop:disabled { color: #5b5b5b; border-color: #202020; background-image: image(#2f2f2f); box-shadow: none; }
 +
 +notebook > header > tabs > arrow:backdrop:disabled:active, notebook > header > tabs > arrow:backdrop:disabled:checked, button.flat:backdrop:disabled:active, button.flat:backdrop:disabled:checked, button:backdrop:disabled:active, button:backdrop:disabled:checked { color: #5b5b5b; border-color: #202020; background-image: image(#2a2a2a); box-shadow: none; }
 +
 +notebook > header > tabs > arrow:disabled, button:disabled { color: #919191; border-color: #5d5d5d; background-image: image(#2f2f2f); -gtk-icon-filter: opacity(0.5); }
 +
 +notebook > header > tabs > arrow:disabled:active, notebook > header > tabs > arrow:disabled:checked, button:disabled:active, button:disabled:checked { color: #919191; border-color: #5d5d5d; background-image: image(#252525); box-shadow: none; }
 +
- button.sidebar-button:hover, notebook > header > tabs > arrow:hover, windowcontrols button:hover, button.flat:hover { border-color: transparent; background-image: none; box-shadow: none; background-color: #323232; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-duration: 500ms; }
++button.sidebar-button, notebook > header > tabs > arrow, windowcontrols button, .toolbar button, notebook > header > tabs > arrow.flat, button.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; transition: none; }
 +
- button.keyboard-activating.sidebar-button, notebook > header > tabs > arrow.keyboard-activating, windowcontrols button.keyboard-activating, button.sidebar-button:active, notebook > header > tabs > arrow:active, windowcontrols button:active, button.sidebar-button:checked, notebook > header > tabs > arrow:checked, windowcontrols button:checked, button.flat.keyboard-activating, button.flat:active, button.flat:checked { border-color: transparent; background-image: none; box-shadow: none; background-color: #282828; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
++button.sidebar-button:hover, notebook > header > tabs > arrow:hover, windowcontrols button:hover, .toolbar button:hover, button.flat:hover { border-color: transparent; background-image: none; box-shadow: none; background-color: #323232; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-duration: 500ms; }
 +
- button.sidebar-button:backdrop, notebook > header > tabs > arrow:backdrop, windowcontrols button:backdrop, button.sidebar-button:disabled, notebook > header > tabs > arrow:disabled, windowcontrols button:disabled, button.flat:backdrop, button.flat:disabled, button.flat:backdrop:disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; }
++button.keyboard-activating.sidebar-button, notebook > header > tabs > arrow.keyboard-activating, windowcontrols button.keyboard-activating, .toolbar button.keyboard-activating, button.sidebar-button:active, notebook > header > tabs > arrow:active, windowcontrols button:active, .toolbar button:active, button.sidebar-button:checked, notebook > header > tabs > arrow:checked, windowcontrols button:checked, .toolbar button:checked, button.flat.keyboard-activating, button.flat:active, button.flat:checked { border-color: transparent; background-image: none; box-shadow: none; background-color: #282828; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
 +
- .scale-popup button:hover, button.link, button.link:hover, button.link:active, button.link:checked, popover.menu box.circular-buttons button.circular.image-button.model, list > row button.image-button:not(.flat), .toolbar button, modelbutton.flat { background-color: transparent; background-image: none; border-color: transparent; box-shadow: inset 0 1px rgba(255, 255, 255, 0), 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
++button.sidebar-button:backdrop, notebook > header > tabs > arrow:backdrop, windowcontrols button:backdrop, .toolbar button:backdrop, button.sidebar-button:disabled, notebook > header > tabs > arrow:disabled, windowcontrols button:disabled, .toolbar button:disabled, button.flat:backdrop, button.flat:disabled, button.flat:backdrop:disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; }
 +
 +notebook > header > tabs > arrow.image-button, button.image-button { min-width: 24px; padding-left: 5px; padding-right: 5px; }
 +
 +notebook > header > tabs > arrow.text-button, button.text-button { padding-left: 16px; padding-right: 16px; }
 +
 +notebook > header > tabs > arrow.text-button.image-button, button.text-button.image-button { padding-left: 8px; padding-right: 8px; }
 +
 +notebook > header > tabs > arrow.text-button.image-button label, button.text-button.image-button label { padding-left: 8px; padding-right: 8px; }
 +
 +dropdown:drop(active) button.combo, combobox:drop(active) button.combo, notebook > header > tabs > arrow:drop(active), button:drop(active) { color: #26a269; border-color: #26a269; box-shadow: inset 0 0 0 1px #26a269; }
 +
 +row:selected button.sidebar-button:not(:active):not(:checked):not(:hover):not(disabled), row:selected button.flat:not(:active):not(:checked):not(:hover):not(disabled) { color: #ffffff; border-color: transparent; }
 +
 +row:selected button.sidebar-button:not(:active):not(:checked):not(:hover):not(disabled):backdrop, row:selected button.flat:not(:active):not(:checked):not(:hover):not(disabled):backdrop { color: #919190; }
 +
 +button.osd { min-width: 26px; min-height: 32px; color: #eeeeec; border-radius: 5px; color: #eeeeec; outline-color: rgba(255, 255, 255, 0.6); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; border: none; box-shadow: none; }
 +
 +button.osd.image-button { min-width: 30px; }
 +
 +button.osd.image-button:only-child { margin: 4px; border-radius: 50%; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); }
 +
 +button.osd:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(12, 12, 12, 0.7)); background-clip: padding-box; border: none; box-shadow: none; }
 +
 +button.osd:active, button.osd:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; border: none; box-shadow: none; }
 +
 +.app-notification button, popover.background.touch-selection button, popover.background.magnifier button, .osd button { color: #eeeeec; outline-color: rgba(255, 255, 255, 0.6); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; }
 +
 +.app-notification button:hover, popover.background.touch-selection button:hover, popover.background.magnifier button:hover, .osd button:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(12, 12, 12, 0.7)); background-clip: padding-box; }
 +
 +.app-notification button:active, popover.background.touch-selection button:active, popover.background.magnifier button:active, .app-notification button:checked, popover.background.touch-selection button:checked, popover.background.magnifier button:checked, .osd button:active:backdrop, .osd button:active, .osd button:checked:backdrop, .osd button:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; }
 +
 +.app-notification button:disabled, popover.background.touch-selection button:disabled, popover.background.magnifier button:disabled, .osd button:disabled:backdrop, .osd button:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; }
 +
 +.app-notification button.flat, popover.background.touch-selection button.flat, popover.background.magnifier button.flat, .osd button.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; box-shadow: none; -gtk-icon-shadow: 0 1px black; }
 +
 +.app-notification button.flat:hover, popover.background.touch-selection button.flat:hover, popover.background.magnifier button.flat:hover, .osd button.flat:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(12, 12, 12, 0.7)); background-clip: padding-box; }
 +
 +.app-notification button.flat:disabled, popover.background.touch-selection button.flat:disabled, popover.background.magnifier button.flat:disabled, .osd button.flat:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; background-image: none; border-color: transparent; box-shadow: none; }
 +
 +.app-notification button.flat:active, popover.background.touch-selection button.flat:active, popover.background.magnifier button.flat:active, .app-notification button.flat:checked, popover.background.touch-selection button.flat:checked, popover.background.magnifier button.flat:checked, .osd button.flat:active, .osd button.flat:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; }
 +
 +button.suggested-action { color: white; outline-color: rgba(255, 255, 255, 0.6); border-color: #030c17; background-image: linear-gradient(to top, #0e396c 2px, #0f3b71); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +button.suggested-action { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +button.suggested-action:focus:focus-visible { outline-color: rgba(255, 255, 255, 0.6); outline-width: 2px; outline-offset: -2px; }
 +
 +button.suggested-action.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: #0f3b71; }
 +
 +button.suggested-action:hover { color: white; border-color: #06182d; background-image: linear-gradient(to top, #0d325f 20%, #0d3463 90%); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +button.suggested-action:active, button.suggested-action:checked { color: white; border-color: #06182d; background-image: image(#0a2648); box-shadow: none; }
 +
 +button.suggested-action.flat:disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: rgba(15, 59, 113, 0.8); }
 +
 +button.suggested-action:disabled { color: #919191; border-color: #5d5d5d; background-image: image(#2f2f2f); }
 +
 +button.suggested-action:disabled:active, button.suggested-action:disabled:checked { color: #9faab8; border-color: #06182d; background-image: image(#0f2b4d); box-shadow: none; }
 +
 +.osd button.suggested-action { color: #eeeeec; outline-color: rgba(255, 255, 255, 0.6); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(15, 59, 113, 0.5)); background-clip: padding-box; }
 +
 +.osd button.suggested-action:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(15, 59, 113, 0.7)); background-clip: padding-box; }
 +
 +.osd button.suggested-action:active:backdrop, .osd button.suggested-action:active, .osd button.suggested-action:checked:backdrop, .osd button.suggested-action:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(#0f3b71); background-clip: padding-box; box-shadow: none; }
 +
 +.osd button.suggested-action:disabled:backdrop, .osd button.suggested-action:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; }
 +
 +button.destructive-action { color: white; outline-color: rgba(255, 255, 255, 0.6); border-color: #570b0e; background-image: linear-gradient(to top, #ae151c 2px, #b2161d); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +button.destructive-action { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +button.destructive-action:focus:focus-visible { outline-color: rgba(255, 255, 255, 0.6); outline-width: 2px; outline-offset: -2px; }
 +
 +button.destructive-action.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: #b2161d; }
 +
 +button.destructive-action:hover { color: white; border-color: #6e0d12; background-image: linear-gradient(to top, #a0131a 20%, #a5141a 90%); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +button.destructive-action:active, button.destructive-action:checked { color: white; border-color: #6e0d12; background-image: image(#8a1116); box-shadow: none; }
 +
 +button.destructive-action.flat:disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: rgba(178, 22, 29, 0.8); }
 +
 +button.destructive-action:disabled { color: #919191; border-color: #5d5d5d; background-image: image(#2f2f2f); }
 +
 +button.destructive-action:disabled:active, button.destructive-action:disabled:checked { color: #cea1a3; border-color: #6e0d12; background-image: image(#84151a); box-shadow: none; }
 +
 +.osd button.destructive-action { color: #eeeeec; outline-color: rgba(255, 255, 255, 0.6); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(178, 22, 29, 0.5)); background-clip: padding-box; }
 +
 +.osd button.destructive-action:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(178, 22, 29, 0.7)); background-clip: padding-box; }
 +
 +.osd button.destructive-action:active:backdrop, .osd button.destructive-action:active, .osd button.destructive-action:checked:backdrop, .osd button.destructive-action:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(#b2161d); background-clip: padding-box; box-shadow: none; }
 +
 +.osd button.destructive-action:disabled:backdrop, .osd button.destructive-action:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; }
 +
 +stackswitcher > button > label { padding: 0 6px; margin: 0 -6px; }
 +
 +stackswitcher > button > image { padding: 3px 6px; margin: -3px -6px; }
 +
 +button.font separator { background-color: transparent; }
 +
 +button.font > box { border-spacing: 6px; }
 +
 +button.font > box > box > label { font-weight: bold; }
 +
 +menubutton.circular button, button.circular { min-width: 32px; min-height: 32px; padding: 0; border-radius: 9999px; }
 +
 +menubutton.circular button label, button.circular label { padding: 0; }
 +
 +stacksidebar row.needs-attention > label, stackswitcher > button.needs-attention > label, stackswitcher > button.needs-attention > image { animation: needs_attention 150ms ease-in; background-image: radial-gradient(farthest-side, #185fb4 96%, rgba(24, 95, 180, 0)); background-size: 6px 6px, 6px 6px; background-repeat: no-repeat; background-position: right 3px, right 2px; }
 +
 +stacksidebar row.needs-attention > label:backdrop, stackswitcher > button.needs-attention > label:backdrop, stackswitcher > button.needs-attention > image:backdrop { background-size: 6px 6px, 0 0; }
 +
 +stacksidebar row.needs-attention > label:dir(rtl), stackswitcher > button.needs-attention > label:dir(rtl), stackswitcher > button.needs-attention > image:dir(rtl) { background-position: left 3px, left 2px; }
 +
 +.linked:not(.vertical) > filechooserbutton > combobox:dir(rtl):not(:last-child) > box > button.combo, .linked:not(.vertical) > appchooserbutton > combobox:dir(rtl):not(:last-child) > box > button.combo, .linked:not(.vertical) > combobox:dir(rtl):not(:last-child) > box > button.combo, .linked:not(.vertical) > filechooserbutton > combobox:dir(ltr):not(:first-child) > box > button.combo, .linked:not(.vertical) > appchooserbutton > combobox:dir(ltr):not(:first-child) > box > button.combo, .linked:not(.vertical) > combobox:dir(ltr):not(:first-child) > box > button.combo, dropdown.linked button:nth-child(2):dir(ltr), combobox.linked button:nth-child(2):dir(ltr), .linked:not(.vertical) > menubutton:dir(rtl):not(:last-child) > button, .linked:not(.vertical) > dropdown:dir(rtl):not(:last-child) > button, .linked:not(.vertical) > colorbutton:dir(rtl):not(:last-child) > button, .linked:not(.vertical) > fontbutton:dir(rtl):not(:last-child) > button, .linked:not(.vertical) > filechooserbutton:dir(rtl):not(:last-child) > button, .linked:not(.vertical) > menubutton:dir(ltr):not(:first-child) > button, .linked:not(.vertical) > dropdown:dir(ltr):not(:first-child) > button, .linked:not(.vertical) > colorbutton:dir(ltr):not(:first-child) > button, .linked:not(.vertical) > fontbutton:dir(ltr):not(:first-child) > button, .linked:not(.vertical) > filechooserbutton:dir(ltr):not(:first-child) > button, spinbutton.vertical.linked:not(.vertical) > text:dir(rtl):not(:last-child), .linked:not(.vertical) > spinbutton:dir(rtl):not(:last-child):not(.vertical), .linked:not(.vertical) > entry:dir(rtl):not(:last-child), .linked:not(.vertical) > button:dir(rtl):not(:last-child), spinbutton.vertical.linked:not(.vertical) > text:dir(ltr):not(:first-child), .linked:not(.vertical) > spinbutton:dir(ltr):not(:first-child):not(.vertical), .linked:not(.vertical) > entry:dir(ltr):not(:first-child), .linked:not(.vertical) > button:dir(ltr):not(:first-child) { border-top-left-radius: 0; border-bottom-left-radius: 0; }
 +
 +.linked:not(.vertical) > filechooserbutton > combobox:dir(rtl):not(:first-child) > box > button.combo, .linked:not(.vertical) > appchooserbutton > combobox:dir(rtl):not(:first-child) > box > button.combo, .linked:not(.vertical) > combobox:dir(rtl):not(:first-child) > box > button.combo, .linked:not(.vertical) > filechooserbutton > combobox:dir(ltr):not(:last-child) > box > button.combo, .linked:not(.vertical) > appchooserbutton > combobox:dir(ltr):not(:last-child) > box > button.combo, .linked:not(.vertical) > combobox:dir(ltr):not(:last-child) > box > button.combo, dropdown.linked button:nth-child(2):dir(rtl), combobox.linked button:nth-child(2):dir(rtl), .linked:not(.vertical) > menubutton:dir(rtl):not(:first-child) > button, .linked:not(.vertical) > dropdown:dir(rtl):not(:first-child) > button, .linked:not(.vertical) > colorbutton:dir(rtl):not(:first-child) > button, .linked:not(.vertical) > fontbutton:dir(rtl):not(:first-child) > button, .linked:not(.vertical) > filechooserbutton:dir(rtl):not(:first-child) > button, .linked:not(.vertical) > menubutton:dir(ltr):not(:last-child) > button, .linked:not(.vertical) > dropdown:dir(ltr):not(:last-child) > button, .linked:not(.vertical) > colorbutton:dir(ltr):not(:last-child) > button, .linked:not(.vertical) > fontbutton:dir(ltr):not(:last-child) > button, .linked:not(.vertical) > filechooserbutton:dir(ltr):not(:last-child) > button, spinbutton.vertical.linked:not(.vertical) > text:dir(rtl):not(:first-child), .linked:not(.vertical) > spinbutton:dir(rtl):not(:first-child):not(.vertical), .linked:not(.vertical) > entry:dir(rtl):not(:first-child), .linked:not(.vertical) > button:dir(rtl):not(:first-child), spinbutton.vertical.linked:not(.vertical) > text:dir(ltr):not(:last-child), .linked:not(.vertical) > spinbutton:dir(ltr):not(:last-child):not(.vertical), .linked:not(.vertical) > entry:dir(ltr):not(:last-child), .linked:not(.vertical) > button:dir(ltr):not(:last-child) { border-right-style: none; border-top-right-radius: 0; border-bottom-right-radius: 0; }
 +
 +.linked.vertical > filechooserbutton > combobox:not(:first-child) > box > button.combo, .linked.vertical > appchooserbutton > combobox:not(:first-child) > box > button.combo, .linked.vertical > combobox:not(:first-child) > box > button.combo, .linked.vertical > menubutton:not(:first-child) > button, .linked.vertical > dropdown:not(:first-child) > button, .linked.vertical > colorbutton:not(:first-child) > button, .linked.vertical > fontbutton:not(:first-child) > button, .linked.vertical > filechooserbutton:not(:first-child) > button, spinbutton.vertical.linked > text:not(:first-child), .linked.vertical > spinbutton:not(:first-child):not(.vertical), .linked.vertical > entry:not(:first-child), .linked.vertical > button:not(:first-child) { border-top-left-radius: 0; border-top-right-radius: 0; }
 +
 +.linked.vertical > filechooserbutton > combobox:not(:last-child) > box > button.combo, .linked.vertical > appchooserbutton > combobox:not(:last-child) > box > button.combo, .linked.vertical > combobox:not(:last-child) > box > button.combo, .linked.vertical > menubutton:not(:last-child) > button, .linked.vertical > dropdown:not(:last-child) > button, .linked.vertical > colorbutton:not(:last-child) > button, .linked.vertical > fontbutton:not(:last-child) > button, .linked.vertical > filechooserbutton:not(:last-child) > button, spinbutton.vertical.linked > text:not(:last-child), .linked.vertical > spinbutton:not(:last-child):not(.vertical), .linked.vertical > entry:not(:last-child), .linked.vertical > button:not(:last-child) { border-bottom-style: none; border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
 +
- .toolbar button:hover { color: #f3f3f1; border-color: #686868; background-image: linear-gradient(to top, #2b2b2b 20%, #2d2d2d 90%); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
- .toolbar button:active { color: #f3f3f1; border-color: #686868; background-image: image(#1e1e1e); box-shadow: none; }
- .toolbar button:disabled { color: #919191; border-color: #5d5d5d; background-image: image(#2f2f2f); }
- .toolbar button:backdrop { color: #919190; border-color: #202020; background-image: image(#353535); box-shadow: none; }
- .toolbar button:backdrop:disabled { color: #5b5b5b; border-color: #202020; background-image: image(#2f2f2f); box-shadow: none; }
++.scale-popup button:hover, button.link, button.link:hover, button.link:active, button.link:checked, popover.menu box.circular-buttons button.circular.image-button.model, list > row button.image-button:not(.flat), modelbutton.flat { background-color: transparent; background-image: none; border-color: transparent; box-shadow: inset 0 1px rgba(255, 255, 255, 0), 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
 +
 +/* menu buttons */
 +modelbutton.flat { min-height: 26px; padding-left: 5px; padding-right: 5px; border-radius: 5px; }
 +
 +modelbutton.flat:hover { background-color: #161616; }
 +
 +modelbutton.flat:disabled { color: #919191; }
 +
 +modelbutton.flat arrow { background: none; min-width: 16px; min-height: 16px; opacity: 0.3; }
 +
 +modelbutton.flat arrow:hover { background: none; }
 +
 +modelbutton.flat arrow.left { -gtk-icon-source: -gtk-icontheme("go-previous-symbolic"); }
 +
 +modelbutton.flat arrow.right { -gtk-icon-source: -gtk-icontheme("go-next-symbolic"); }
 +
 +/* oldstyle toolbar buttons */
 +.toolbar button { margin: 1px; }
 +
 +button.color { padding: 4px; }
 +
 +button.color > colorswatch:only-child, button.color > colorswatch:only-child > overlay { border-radius: 0; }
 +
 +/* list buttons */
 +/* tone down as per new designs, see issue #1473 */
 +popover.menu box.circular-buttons button.circular.image-button.model, list > row button.image-button:not(.flat) { border: 1px solid rgba(104, 104, 104, 0.5); }
 +
 +popover.menu box.circular-buttons button.circular.image-button.model:hover, list > row button.image-button:not(.flat):hover { color: #f3f3f1; border-color: #686868; background-image: linear-gradient(to top, #2b2b2b 20%, #2d2d2d 90%); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +popover.menu box.circular-buttons button.circular.image-button.model:active, popover.menu box.circular-buttons button.circular.image-button.model:checked, list > row button.image-button:not(.flat):active, list > row button.image-button:not(.flat):checked { color: #f3f3f1; border-color: #686868; background-image: image(#1e1e1e); box-shadow: none; }
 +
 +popover.menu box.circular-buttons button.suggested-action.circular.image-button.model, list > row button.image-button.suggested-action:not(.flat) { color: white; outline-color: rgba(255, 255, 255, 0.6); border-color: #030c17; background-image: linear-gradient(to top, #0e396c 2px, #0f3b71); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +popover.menu box.circular-buttons button.suggested-action.circular.image-button.model, list > row button.image-button.suggested-action:not(.flat) { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +popover.menu box.circular-buttons button.suggested-action.circular.image-button.model:focus:focus-visible, list > row button.image-button.suggested-action:not(.flat):focus:focus-visible { outline-color: rgba(255, 255, 255, 0.6); outline-width: 2px; outline-offset: -2px; }
 +
 +popover.menu box.circular-buttons button.destructive-action.circular.image-button.model, list > row button.image-button.destructive-action:not(.flat) { color: white; outline-color: rgba(255, 255, 255, 0.6); border-color: #570b0e; background-image: linear-gradient(to top, #ae151c 2px, #b2161d); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +popover.menu box.circular-buttons button.destructive-action.circular.image-button.model, list > row button.image-button.destructive-action:not(.flat) { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +popover.menu box.circular-buttons button.destructive-action.circular.image-button.model:focus:focus-visible, list > row button.image-button.destructive-action:not(.flat):focus:focus-visible { outline-color: rgba(255, 255, 255, 0.6); outline-width: 2px; outline-offset: -2px; }
 +
 +/********* Links * */
 +button.link, link { color: #3584e4; text-decoration: underline; }
 +
 +button.link:visited, link:visited { color: #1b6acb; }
 +
 +*:selected button.link:visited, *:selected link:visited { color: #a4c4ea; }
 +
 +button.link:hover, link:hover { color: #629fea; }
 +
 +*:selected button.link:hover, *:selected link:hover { color: #eff5fd; }
 +
 +button.link:active, link:active { color: #3584e4; }
 +
 +*:selected button.link:active, *:selected link:active { color: #d7e6fa; }
 +
 +button.link:disabled, link:disabled { color: rgba(141, 141, 141, 0.8); }
 +
 +button.link:selected, *:selected button.link, link:selected, *:selected link { color: #d7e6fa; }
 +
 +link { transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +link { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +link:focus:focus-visible { outline-color: rgba(255, 255, 255, 0.6); outline-width: 2px; outline-offset: -2px; }
 +
 +button.link, button.link:hover, button.link:active, button.link:checked { text-shadow: none; }
 +
 +button.link > label { text-decoration: underline; }
 +
 +/***************** GtkSpinButton * */
 +spinbutton { font-feature-settings: "tnum"; }
 +
 +spinbutton:not(.vertical) { padding: 0; border-spacing: 0; /* :not here just to bump specificity above that of the list button styling */ }
 +
 +.osd spinbutton:not(.vertical) > text, spinbutton:not(.vertical) > text { min-width: 28px; margin: 0; background: none; background-color: transparent; border: none; border-radius: 0; box-shadow: none; padding: 6px; }
 +
 +.osd spinbutton:not(.vertical) > text:backdrop:disabled, spinbutton:not(.vertical) > text:backdrop:disabled { background-color: transparent; }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat), spinbutton:not(.vertical) > button.image-button.down:not(.flat) { min-height: 16px; margin: 0; padding-bottom: 0; padding-top: 0; color: #dfdfde; background-image: none; border-style: none none none solid; border-color: rgba(104, 104, 104, 0.3); border-radius: 0; box-shadow: none; }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat):dir(rtl), spinbutton:not(.vertical) > button.image-button.down:not(.flat):dir(rtl) { border-style: none solid none none; }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat):hover, spinbutton:not(.vertical) > button.image-button.down:not(.flat):hover { color: #f3f3f1; background-color: #232323; }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat):disabled, spinbutton:not(.vertical) > button.image-button.down:not(.flat):disabled { color: rgba(145, 145, 145, 0.3); background-color: transparent; }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat):active, spinbutton:not(.vertical) > button.image-button.down:not(.flat):active { background-color: rgba(0, 0, 0, 0.1); box-shadow: inset 0 2px 3px -1px rgba(0, 0, 0, 0.2); }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat):dir(ltr):last-child, spinbutton:not(.vertical) > button.image-button.down:not(.flat):dir(ltr):last-child { border-radius: 0 5px 5px 0; }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat):dir(rtl):first-child, spinbutton:not(.vertical) > button.image-button.down:not(.flat):dir(rtl):first-child { border-radius: 5px 0 0 5px; }
 +
 +.osd spinbutton:not(.vertical) > button.image-button.up:not(.flat), .osd spinbutton:not(.vertical) > button.image-button.down:not(.flat) { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: #eeeeec; border-style: none none none solid; border-color: rgba(0, 0, 0, 0.4); border-radius: 0; box-shadow: none; -gtk-icon-shadow: 0 1px black; }
 +
 +.osd spinbutton:not(.vertical) > button.image-button.up:not(.flat):dir(rtl), .osd spinbutton:not(.vertical) > button.image-button.down:not(.flat):dir(rtl) { border-style: none solid none none; }
 +
 +.osd spinbutton:not(.vertical) > button.image-button.up:not(.flat):hover, .osd spinbutton:not(.vertical) > button.image-button.down:not(.flat):hover { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: #eeeeec; border-color: rgba(0, 0, 0, 0.5); background-color: rgba(12, 12, 12, 0.7); -gtk-icon-shadow: 0 1px black; box-shadow: none; }
 +
 +.osd spinbutton:not(.vertical) > button.image-button.up:not(.flat):disabled, .osd spinbutton:not(.vertical) > button.image-button.down:not(.flat):disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: #8a8a89; border-color: rgba(0, 0, 0, 0.5); -gtk-icon-shadow: none; box-shadow: none; }
 +
 +.osd spinbutton:not(.vertical) > button.image-button.up:not(.flat):dir(ltr):last-child, .osd spinbutton:not(.vertical) > button.image-button.down:not(.flat):dir(ltr):last-child { border-radius: 0 5px 5px 0; }
 +
 +.osd spinbutton:not(.vertical) > button.image-button.up:not(.flat):dir(rtl):first-child, .osd spinbutton:not(.vertical) > button.image-button.down:not(.flat):dir(rtl):first-child { border-radius: 5px 0 0 5px; }
 +
 +spinbutton.vertical:disabled { color: #919191; }
 +
 +spinbutton.vertical:drop(active) { border-color: transparent; box-shadow: none; }
 +
 +spinbutton.vertical > text { min-height: 32px; min-width: 32px; padding: 0; border-radius: 0; }
 +
 +spinbutton.vertical > text > block-cursor { color: #2d2d2d; background-color: white; }
 +
 +spinbutton.vertical > button { min-height: 32px; min-width: 32px; padding: 0; }
 +
 +spinbutton.vertical > button.up { border-bottom-style: none; border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
 +
 +spinbutton.vertical > button.down { border-top-style: none; border-top-left-radius: 0; border-top-right-radius: 0; }
 +
 +.osd spinbutton.vertical > button:first-child { color: #eeeeec; outline-color: rgba(255, 255, 255, 0.6); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; }
 +
 +.osd spinbutton.vertical > button:first-child:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(12, 12, 12, 0.7)); background-clip: padding-box; }
 +
 +.osd spinbutton.vertical > button:first-child:active { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; }
 +
 +.osd spinbutton.vertical > button:first-child:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; }
 +
 +treeview spinbutton:not(.vertical) { min-height: 0; border-style: none; border-radius: 0; }
 +
 +treeview spinbutton:not(.vertical) > text { min-height: 0; padding: 1px 2px; }
 +
 +/************** ComboBoxes * */
 +dropdown > popover.menu.background > contents { padding: 0; }
 +
 +dropdown > button > box { border-spacing: 6px; }
 +
 +dropdown > button > box > stack > row.activatable:hover { background: none; box-shadow: none; }
 +
 +dropdown arrow, combobox arrow { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); min-height: 16px; min-width: 16px; }
 +
 +dropdown > popover.menu > contents modelbutton, combobox > popover.menu > contents modelbutton { padding-left: 9px; padding-right: 9px; }
 +
 +dropdown:drop(active), combobox:drop(active) { box-shadow: none; }
 +
 +dropdown popover, combobox popover { margin-top: 6px; padding: 0; }
 +
 +dropdown popover listview, combobox popover listview { margin: 8px 0; }
 +
 +dropdown popover listview > row.activatable, combobox popover listview > row.activatable { padding: 8px; }
 +
 +dropdown popover listview > row.activatable:selected, dropdown popover listview > row.activatable:selected:hover, combobox popover listview > row.activatable:selected, combobox popover listview > row.activatable:selected:hover { outline-color: rgba(255, 255, 255, 0.6); color: white; background-color: #161616; box-shadow: none; }
 +
 +dropdown popover .dropdown-searchbar, combobox popover .dropdown-searchbar { padding: 6px; border-bottom: 1px solid #686868; }
 +
 +/************ Toolbars * */
 +searchbar > revealer > box, .toolbar, toolbar { padding: 4px; border-spacing: 4px; background-color: #303030; }
 +
 +.osd .toolbar, .osd toolbar { background-color: transparent; }
 +
 +.toolbar.osd, toolbar.osd { padding: 13px; border: none; border-radius: 5px; background-color: rgba(38, 38, 38, 0.7); }
 +
 +.toolbar.osd.left, .toolbar.osd.right, .toolbar.osd.top, .toolbar.osd.bottom, toolbar.osd.left, toolbar.osd.right, toolbar.osd.top, toolbar.osd.bottom { border-radius: 0; }
 +
 +.toolbar.horizontal > separator, toolbar.horizontal > separator { margin: 4px 0; }
 +
 +.toolbar.vertical > separator, toolbar.vertical > separator { margin: 0 4px; }
 +
 +searchbar > revealer > box { padding: 6px; border-spacing: 6px; border-width: 0 0 1px; }
 +
 +searchbar > revealer > box { border-style: solid; border-color: #686868; background-color: #414141; }
 +
 +searchbar > revealer > box:backdrop { border-color: #202020; background-color: #2e2e2e; box-shadow: none; transition: 200ms ease-out; }
 +
 +/************** GtkInfoBar * */
 +infobar > revealer > box { padding: 8px; border-spacing: 12px; }
 +
 +infobar.action:hover > revealer > box { background-color: #59544e; }
 +
 +infobar.info > revealer > box, infobar.question > revealer > box, infobar.warning > revealer > box, infobar.error > revealer > box { border-bottom: 1px solid #757575; background-color: #5f5a53; }
 +
 +infobar .close, searchbar .close { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; min-width: 16px; min-height: 16px; padding: 4px; border-radius: 50%; }
 +
 +infobar .close:hover, searchbar .close:hover { color: #f3f3f1; border-color: #686868; background-image: linear-gradient(to top, #2b2b2b 20%, #2d2d2d 90%); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +/***************** Title buttons * */
 +windowcontrols { border-spacing: 6px; }
 +
 +windowcontrols.start:not(.empty):dir(ltr), windowcontrols.end:not(.empty):dir(rtl) { margin-right: 7px; }
 +
 +windowcontrols.start:not(.empty):dir(rtl), windowcontrols.end:not(.empty):dir(ltr) { margin-left: 7px; }
 +
 +windowcontrols button { border-radius: 9999px; padding: 6px; margin: 0 2px; min-width: 0; min-height: 0; }
 +
 +windowcontrols button:hover { border-color: transparent; background-image: none; box-shadow: none; background-color: #1b1b1b; }
 +
 +windowcontrols button:active, windowcontrols button:checked { border-color: transparent; background-image: none; box-shadow: none; background-color: #070707; }
 +
 +/*************** Header bars * */
 +.titlebar:not(headerbar), headerbar { padding: 0 6px; min-height: 46px; border-width: 0 0 1px; border-style: solid; border-color: #4e4e4e; border-radius: 0; background: #161616 linear-gradient(to top, #202020, #262626); /* Darken switchbuttons for headerbars. issue #1588 */ }
 +
 +.titlebar:backdrop:not(headerbar), headerbar:backdrop { border-color: #202020; background-color: #303030; background-image: none; transition: 200ms ease-out; }
 +
 +.titlebar:not(headerbar) .title, headerbar .title { padding-left: 12px; padding-right: 12px; font-weight: bold; }
 +
 +.titlebar:not(headerbar) .subtitle, headerbar .subtitle { font-size: smaller; padding-left: 12px; padding-right: 12px; }
 +
 +.titlebar:not(headerbar) stackswitcher > button:checked, .titlebar:not(headerbar) button.toggle:checked, headerbar stackswitcher > button:checked, headerbar button.toggle:checked { background: image(#191919); border-color: #606060; border-top-color: #535353; }
 +
 +.titlebar:not(headerbar) stackswitcher > button:checked:backdrop, .titlebar:not(headerbar) button.toggle:checked:backdrop, headerbar stackswitcher > button:checked:backdrop, headerbar button.toggle:checked:backdrop { color: #919190; border-color: #202020; background-image: image(#2a2a2a); box-shadow: none; }
 +
 +.tiled .titlebar:not(headerbar), .tiled-top .titlebar:not(headerbar), .tiled-left .titlebar:not(headerbar), .tiled-right .titlebar:not(headerbar), .tiled-bottom .titlebar:not(headerbar), .maximized .titlebar:not(headerbar), .fullscreen .titlebar:not(headerbar), .tiled headerbar, .tiled-top headerbar, .tiled-left headerbar, .tiled-right headerbar, .tiled-bottom headerbar, .maximized headerbar, .fullscreen headerbar { border-radius: 0; }
 +
 +.default-decoration.titlebar:not(headerbar), headerbar.default-decoration { min-height: 28px; padding: 4px; }
 +
 +.default-decoration.titlebar:not(headerbar) windowcontrols button, .default-decoration.titlebar:not(headerbar) windowcontrols menubutton, headerbar.default-decoration windowcontrols button, headerbar.default-decoration windowcontrols menubutton { min-height: 26px; min-width: 26px; margin: 0; padding: 0; }
 +
 +.default-decoration.titlebar:not(headerbar) windowcontrols menubutton button, headerbar.default-decoration windowcontrols menubutton button { min-height: 20px; min-width: 20px; margin: 0; padding: 4px; }
 +
 +.solid-csd .titlebar:dir(rtl):not(headerbar), .solid-csd .titlebar:dir(ltr):not(headerbar), .solid-csd headerbar:backdrop:dir(rtl), .solid-csd headerbar:backdrop:dir(ltr), .solid-csd headerbar:dir(rtl), .solid-csd headerbar:dir(ltr) { margin-left: -1px; margin-right: -1px; margin-top: -1px; border-radius: 0; box-shadow: none; }
 +
 +headerbar > windowhandle > box, headerbar > windowhandle > box > box.start, headerbar > windowhandle > box > box.end { border-spacing: 6px; }
 +
 +headerbar entry, headerbar spinbutton, headerbar separator:not(.sidebar), headerbar button, headerbar menubutton { margin-top: 6px; margin-bottom: 6px; }
 +
 +headerbar menubutton > button { margin-top: 0px; margin-bottom: 0px; }
 +
 +headerbar switch { margin-top: 10px; margin-bottom: 10px; }
 +
 +window.csd > .titlebar:not(headerbar) { padding: 0; background-color: transparent; background-image: none; border-style: none; border-color: transparent; }
 +
 +.titlebar:not(headerbar) separator { background-color: #686868; }
 +
 +window.devel headerbar.titlebar { background: #303030 cross-fade(10% -gtk-icontheme("system-run-symbolic"), image(transparent)) 90% 0/256px 256px no-repeat, linear-gradient(to right, transparent 65%, rgba(15, 59, 113, 0.1)), linear-gradient(to top, #1e1e1e 3px, #232323); }
 +
 +window.devel headerbar.titlebar:backdrop { background: #303030 cross-fade(10% -gtk-icontheme("system-run-symbolic"), image(transparent)) 90% 0/256px 256px no-repeat, image(#303030); /* background-color would flash */ }
 +
 +/************ Pathbars * */
 +pathbar > button.text-button, pathbar > button.image-button, pathbar > button { padding-left: 4px; padding-right: 4px; }
 +
 +pathbar > button.text-button.image-button label { padding-left: 0; padding-right: 0; }
 +
 +pathbar > button.text-button.image-button label:last-child, pathbar > button label:last-child { padding-right: 8px; }
 +
 +pathbar > button.text-button.image-button label:first-child, pathbar > button label:first-child { padding-left: 8px; }
 +
 +pathbar > button image { padding-left: 4px; padding-right: 4px; }
 +
 +pathbar > button.slider-button { padding-left: 0; padding-right: 0; }
 +
 +/************** Tree Views * */
 +columnview.view, treeview.view { border-left-color: #555554; border-top-color: #555554; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +columnview.view, treeview.view { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +columnview.view:focus:focus-visible, treeview.view:focus:focus-visible { outline-color: rgba(255, 255, 255, 0.6); outline-width: 2px; outline-offset: -2px; }
 +
 +columnview.view:selected:focus, columnview.view:selected, treeview.view:selected:focus, treeview.view:selected { border-radius: 0; outline-color: rgba(255, 255, 255, 0.6); }
 +
 +columnview.view:disabled, treeview.view:disabled { color: #919191; }
 +
 +columnview.view:disabled:selected, treeview.view:disabled:selected { color: #6f8aaa; }
 +
 +columnview.view:disabled:selected:backdrop, treeview.view:disabled:selected:backdrop { color: #4b6a8f; }
 +
 +columnview.view.separator, treeview.view.separator { min-height: 2px; color: #555554; }
 +
 +columnview.view:backdrop, treeview.view:backdrop { border-left-color: #414141; border-top: #414141; }
 +
 +columnview.view:drop(active), treeview.view:drop(active) { box-shadow: none; }
 +
 +columnview.view > dndtarget:drop(active), treeview.view > dndtarget:drop(active) { border-style: solid none; border-width: 1px; border-color: black; }
 +
 +columnview.view > dndtarget.after:drop(active), treeview.view > dndtarget.after:drop(active) { border-top-style: none; }
 +
 +columnview.view > dndtarget.before:drop(active), treeview.view > dndtarget.before:drop(active) { border-bottom-style: none; }
 +
 +columnview.view.expander, treeview.view.expander { min-width: 16px; min-height: 16px; -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); color: silver; }
 +
 +columnview.view.expander:dir(rtl), treeview.view.expander:dir(rtl) { -gtk-icon-source: -gtk-icontheme("pan-end-symbolic-rtl"); }
 +
 +columnview.view.expander:hover, treeview.view.expander:hover { color: white; }
 +
 +columnview.view.expander:selected, treeview.view.expander:selected { color: #b7c4d4; }
 +
 +columnview.view.expander:selected:hover, treeview.view.expander:selected:hover { color: #ffffff; }
 +
 +columnview.view.expander:checked, treeview.view.expander:checked { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
 +
 +columnview.view.progressbar, treeview.view.progressbar { background-color: #0f3b71; background-image: image(#0f3b71); box-shadow: none; }
 +
 +columnview.view.progressbar:selected:focus, columnview.view.progressbar:selected, treeview.view.progressbar:selected:focus, treeview.view.progressbar:selected { box-shadow: inset 0 1px rgba(255, 255, 255, 0.05); background-image: image(#2d2d2d); }
 +
 +columnview.view.progressbar:selected:focus:backdrop, columnview.view.progressbar:selected:backdrop, treeview.view.progressbar:selected:focus:backdrop, treeview.view.progressbar:selected:backdrop { background-color: #303030; }
 +
 +columnview.view.trough, treeview.view.trough { background-color: rgba(243, 243, 241, 0.1); }
 +
 +columnview.view.trough:selected:focus, columnview.view.trough:selected, treeview.view.trough:selected:focus, treeview.view.trough:selected { background-color: #092444; }
 +
 +columnview.view > header > button, treeview.view > header > button { color: #90908f; background-color: #2d2d2d; font-weight: bold; text-shadow: none; box-shadow: none; }
 +
 +columnview.view > header > button:hover, treeview.view > header > button:hover { color: #c1c1c0; box-shadow: none; transition: none; }
 +
 +columnview.view > header > button:active, treeview.view > header > button:active { color: #f3f3f1; transition: none; }
 +
 +columnview.view > header > button sort-indicator, treeview.view > header > button sort-indicator { min-height: 16px; min-width: 16px; }
 +
 +columnview.view > header > button sort-indicator.ascending, treeview.view > header > button sort-indicator.ascending { -gtk-icon-source: -gtk-icontheme("pan-up-symbolic"); }
 +
 +columnview.view > header > button sort-indicator.descending, treeview.view > header > button sort-indicator.descending { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
 +
 +columnview.view button.dnd:active, columnview.view button.dnd:selected, columnview.view button.dnd:hover, columnview.view button.dnd, columnview.view header.button.dnd:active, columnview.view header.button.dnd:selected, columnview.view header.button.dnd:hover, columnview.view header.button.dnd, treeview.view button.dnd:active, treeview.view button.dnd:selected, treeview.view button.dnd:hover, treeview.view button.dnd, treeview.view header.button.dnd:active, treeview.view header.button.dnd:selected, treeview.view header.button.dnd:hover, treeview.view header.button.dnd { padding: 0 6px; color: #2d2d2d; background-image: none; background-color: #0f3b71; border-style: none; border-radius: 0; box-shadow: inset 0 0 0 1px #2d2d2d; text-shadow: none; transition: none; }
 +
 +columnview.view acceleditor > label, treeview.view acceleditor > label { background-color: #0f3b71; }
 +
 +columnview.view > header > button, treeview.view > header > button, columnview.view > header > button:hover, treeview.view > header > button:hover, columnview.view > header > button:active, treeview.view > header > button:active { padding: 0 6px; background-image: none; border-style: none none solid solid; border-color: #555554; border-radius: 0; text-shadow: none; }
 +
 +columnview.view > header > button:disabled, treeview.view > header > button:disabled { border-color: #303030; background-image: none; }
 +
 +columnview.view > header > button:last-child, treeview.view > header > button:last-child { border-right-style: none; }
 +
 +/*************** Popovers   * */
 +popover.background { background-color: transparent; font: initial; }
 +
 +popover.background > arrow, popover.background > contents { background-color: #2d2d2d; background-clip: padding-box; border: 1px solid rgba(0, 0, 0, 0.75); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); }
 +
 +popover.background:backdrop { background-color: transparent; }
 +
 +popover.background > contents { padding: 8px; border-radius: 9px; }
 +
 +popover.background > contents > list, popover.background > contents > .view, popover.background > contents > iconview, popover.background > contents > toolbar { border-style: none; background-color: transparent; }
 +
 +popover.background > contents separator { background-color: #575757; margin: 3px; }
 +
 +popover.background > contents list separator { margin: 0; }
 +
 +.osd popover.background, popover.background.touch-selection, popover.background.magnifier { background-color: transparent; }
 +
 +.osd popover.background > arrow, .osd popover.background > contents, popover.background.touch-selection > arrow, popover.background.touch-selection > contents, popover.background.magnifier > arrow, popover.background.magnifier > contents { border: 1px solid rgba(255, 255, 255, 0.1); box-shadow: none; }
 +
 +magnifier { background-color: #2d2d2d; }
 +
 +/********************** Popover Base Menus * */
 +popover.menu { padding: 0; }
 +
 +popover.menu box.inline-buttons { padding: 0 12px; }
 +
 +popover.menu box.inline-buttons button.image-button.model { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; min-height: 30px; min-width: 30px; padding: 0; border: none; outline: none; transition: none; }
 +
 +popover.menu box.inline-buttons button.image-button.model:selected { background: image(#161616); }
 +
 +popover.menu box.circular-buttons { padding: 12px 12px 6px; }
 +
 +popover.menu box.circular-buttons button.circular.image-button.model { padding: 11px; }
 +
 +popover.menu box.circular-buttons button.circular.image-button.model:focus { background-color: #161616; border-color: #161616; }
 +
 +popover.menu > arrow, popover.menu.background > contents { background-color: #2d2d2d; padding: 5px; }
 +
 +popover.menu.background separator { margin: 6px 0; }
 +
 +popover.menu accelerator { color: alpha(currentColor,0.55); }
 +
 +popover.menu accelerator:dir(ltr) { margin-left: 12px; }
 +
 +popover.menu accelerator:dir(rtl) { margin-right: 12px; }
 +
 +popover.menu check, popover.menu radio { transform: scale(0.8); border-width: 1.2px; border-color: transparent; box-shadow: none; background-image: image(transparent); color: white; }
 +
 +popover.menu check:hover, popover.menu radio:hover { transform: scale(0.8); border-width: 1.2px; color: white; box-shadow: none; background-image: image(transparent); }
 +
 +popover.menu check:active, popover.menu radio:active { transform: scale(0.8); border-width: 1.2px; color: white; box-shadow: none; background-image: image(transparent); }
 +
 +popover.menu radio { border-color: #686868; }
 +
 +popover.menu radio:active { border-color: rgba(104, 104, 104, 0.5); }
 +
 +popover.menu arrow.left, popover.menu radio.left, popover.menu check.left { margin-left: -2px; margin-right: 6px; }
 +
 +popover.menu arrow.right, popover.menu radio.right, popover.menu check.right { margin-left: 6px; margin-right: -2px; }
 +
 +popover.menu modelbutton { min-height: 30px; min-width: 40px; padding: 0 12px; border-radius: 5px; }
 +
 +popover.menu modelbutton:selected { color: white; background-color: #161616; }
 +
 +popover.menu modelbutton:selected:active { background-color: #0c0c0c; }
 +
 +popover.menu label.title { font-weight: bold; padding: 4px 32px; }
 +
 +menubar { padding: 0px; box-shadow: inset 0 -1px rgba(0, 0, 0, 0.1); }
 +
 +menubar > item { min-height: 16px; padding: 4px 8px; }
 +
 +menubar > item:selected { box-shadow: inset 0 -3px #0f3b71; color: #3584e4; }
 +
 +menubar > item:disabled { color: #919191; box-shadow: none; }
 +
 +menubar > item popover.menu.background > contents { padding: 5px; }
 +
 +menubar > item popover.menu popover.menu { padding: 0 0 4px 0; }
 +
 +menubar > item popover.menu.background popover.menu.background > contents { margin: 0; border-radius: 9px; }
 +
 +/************* Notebooks * */
 +notebook { transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +notebook > header > tabs > tab:checked { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +notebook:focus:focus-visible > header > tabs > tab:checked { outline-color: rgba(255, 255, 255, 0.6); outline-width: 2px; outline-offset: -2px; }
 +
 +notebook > header { padding: 1px; border-color: #686868; border-width: 1px; background-color: #282828; }
 +
 +notebook > header > tabs { margin: -1px; }
 +
 +notebook > header.top { border-bottom-style: solid; }
 +
 +notebook > header.top > tabs { margin-bottom: -2px; }
 +
 +notebook > header.top > tabs > tab:hover { box-shadow: inset 0 -4px #686868; }
 +
 +notebook > header.top > tabs > tab:checked { box-shadow: inset 0 -4px #0f3b71; }
 +
 +notebook > header.bottom { border-top-style: solid; }
 +
 +notebook > header.bottom > tabs { margin-top: -2px; }
 +
 +notebook > header.bottom > tabs > tab:hover { box-shadow: inset 0 4px #686868; }
 +
 +notebook > header.bottom > tabs > tab:checked { box-shadow: inset 0 4px #0f3b71; }
 +
 +notebook > header.left { border-right-style: solid; }
 +
 +notebook > header.left > tabs { margin-right: -2px; }
 +
 +notebook > header.left > tabs > tab:hover { box-shadow: inset -4px 0 #686868; }
 +
 +notebook > header.left > tabs > tab:checked { box-shadow: inset -4px 0 #0f3b71; }
 +
 +notebook > header.right { border-left-style: solid; }
 +
 +notebook > header.right > tabs { margin-left: -2px; }
 +
 +notebook > header.right > tabs > tab:hover { box-shadow: inset 4px 0 #686868; }
 +
 +notebook > header.right > tabs > tab:checked { box-shadow: inset 4px 0 #0f3b71; }
 +
 +notebook > header.top > tabs > arrow { border-top-style: none; }
 +
 +notebook > header.bottom > tabs > arrow { border-bottom-style: none; }
 +
 +notebook > header.top > tabs > arrow, notebook > header.bottom > tabs > arrow { margin-left: -5px; margin-right: -5px; padding-left: 4px; padding-right: 4px; }
 +
 +notebook > header.top > tabs > arrow.down, notebook > header.bottom > tabs > arrow.down { -gtk-icon-source: -gtk-icontheme("pan-start-symbolic"); }
 +
 +notebook > header.top > tabs > arrow.up, notebook > header.bottom > tabs > arrow.up { -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); }
 +
 +notebook > header.left > tabs > arrow { border-left-style: none; }
 +
 +notebook > header.right > tabs > arrow { border-right-style: none; }
 +
 +notebook > header.left > tabs > arrow, notebook > header.right > tabs > arrow { margin-top: -5px; margin-bottom: -5px; padding-top: 4px; padding-bottom: 4px; }
 +
 +notebook > header.left > tabs > arrow.down, notebook > header.right > tabs > arrow.down { -gtk-icon-source: -gtk-icontheme("pan-up-symbolic"); }
 +
 +notebook > header.left > tabs > arrow.up, notebook > header.right > tabs > arrow.up { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
 +
 +notebook > header > tabs > arrow { min-height: 16px; min-width: 16px; border-radius: 0; }
 +
 +notebook > header > tabs > arrow:hover:not(:active):not(:backdrop) { background-clip: padding-box; background-image: none; background-color: rgba(255, 255, 255, 0.3); border-color: transparent; box-shadow: none; }
 +
 +notebook > header > tabs > arrow:disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; }
 +
 +notebook > header > tabs > tab { transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); min-height: 30px; min-width: 30px; padding: 3px 12px; color: #f3f3f1; font-weight: normal; border-width: 1px; border-color: transparent; }
 +
 +notebook > header > tabs > tab:hover { color: #f3f3f1; background-color: #1e1e1e; }
 +
 +notebook > header > tabs > tab.reorderable-page:hover { border-color: rgba(104, 104, 104, 0.3); background-color: rgba(48, 48, 48, 0.2); }
 +
 +notebook > header > tabs > tab:not(:checked) { outline-color: transparent; }
 +
 +notebook > header > tabs > tab:checked { color: #f3f3f1; }
 +
 +notebook > header > tabs > tab.reorderable-page:checked { border-color: rgba(104, 104, 104, 0.5); background-color: rgba(48, 48, 48, 0.5); }
 +
 +notebook > header > tabs > tab.reorderable-page:checked:hover { background-color: rgba(48, 48, 48, 0.7); }
 +
 +notebook > header > tabs > tab button.flat { color: alpha(currentColor,0.3); padding: 0; margin-top: 4px; margin-bottom: 4px; min-width: 20px; min-height: 20px; }
 +
 +notebook > header > tabs > tab button.flat:hover { color: currentColor; }
 +
 +notebook > header > tabs > tab button.flat:last-child { margin-left: 4px; margin-right: -4px; }
 +
 +notebook > header > tabs > tab button.flat:first-child { margin-left: -4px; margin-right: 4px; }
 +
 +notebook > header.top > tabs, notebook > header.bottom > tabs { padding-left: 4px; padding-right: 4px; }
 +
 +notebook > header.top > tabs:not(:only-child), notebook > header.bottom > tabs:not(:only-child) { margin-left: 3px; margin-right: 3px; }
 +
 +notebook > header.top > tabs:not(:only-child):first-child, notebook > header.bottom > tabs:not(:only-child):first-child { margin-left: -1px; }
 +
 +notebook > header.top > tabs:not(:only-child):last-child, notebook > header.bottom > tabs:not(:only-child):last-child { margin-right: -1px; }
 +
 +notebook > header.top > tabs > tab, notebook > header.bottom > tabs > tab { margin-left: 4px; margin-right: 4px; }
 +
 +notebook > header.top > tabs > tab.reorderable-page, notebook > header.bottom > tabs > tab.reorderable-page { border-style: none solid; }
 +
 +notebook > header.left > tabs, notebook > header.right > tabs { padding-top: 4px; padding-bottom: 4px; }
 +
 +notebook > header.left > tabs:not(:only-child), notebook > header.right > tabs:not(:only-child) { margin-top: 3px; margin-bottom: 3px; }
 +
 +notebook > header.left > tabs:not(:only-child):first-child, notebook > header.right > tabs:not(:only-child):first-child { margin-top: -1px; }
 +
 +notebook > header.left > tabs:not(:only-child):last-child, notebook > header.right > tabs:not(:only-child):last-child { margin-bottom: -1px; }
 +
 +notebook > header.left > tabs > tab, notebook > header.right > tabs > tab { margin-top: 4px; margin-bottom: 4px; }
 +
 +notebook > header.left > tabs > tab.reorderable-page, notebook > header.right > tabs > tab.reorderable-page { border-style: solid none; }
 +
 +notebook > header.top > tabs > tab { padding-bottom: 4px; }
 +
 +notebook > header.bottom > tabs > tab { padding-top: 4px; }
 +
 +notebook > stack:not(:only-child) { background-color: #2d2d2d; }
 +
 +/************** Scrollbars * */
 +scrollbar { background-color: #313131; transition: all 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
 +
 +scrollbar.top { border-bottom: 1px solid #686868; }
 +
 +scrollbar.bottom { border-top: 1px solid #686868; }
 +
 +scrollbar.left { border-right: 1px solid #686868; }
 +
 +scrollbar.right { border-left: 1px solid #686868; }
 +
 +scrollbar > range > trough > slider { min-width: 8px; min-height: 8px; margin: -1px; border: 4px solid transparent; border-radius: 10px; background-clip: padding-box; background-color: #a4a4a3; transition: all 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
 +
 +scrollbar > range > trough > slider:hover { background-color: #c9c9c7; }
 +
 +scrollbar > range > trough > slider:hover:active { background-color: #1b6acb; }
 +
 +scrollbar > range > trough > slider:disabled { background-color: transparent; }
 +
 +scrollbar > range.fine-tune > trough > slider { transition: none; min-width: 6px; min-height: 6px; }
 +
 +scrollbar > range.fine-tune.horizontal > trough > slider { border-width: 5px 4px; }
 +
 +scrollbar > range.fine-tune.vertical > trough > slider { border-width: 4px 5px; }
 +
 +scrollbar.overlay-indicator:not(.dragging):not(.hovering) { border-color: transparent; opacity: 0.4; background-color: transparent; }
 +
 +scrollbar.overlay-indicator:not(.dragging):not(.hovering) > range > trough > slider { margin: 0; min-width: 3px; min-height: 3px; background-color: #f3f3f1; border: 1px solid black; }
 +
 +scrollbar.overlay-indicator.horizontal:not(.dragging):not(.hovering) > range > trough > slider { margin: 0 2px; min-width: 40px; }
 +
 +scrollbar.overlay-indicator.vertical:not(.dragging):not(.hovering) > range > trough > slider { margin: 2px 0; min-height: 40px; }
 +
 +scrollbar.overlay-indicator.dragging, scrollbar.overlay-indicator.hovering { opacity: 0.8; }
 +
 +scrollbar.horizontal > range > trough > slider { min-width: 40px; }
 +
 +scrollbar.vertical > range > trough > slider { min-height: 40px; }
 +
 +treeview ~ scrollbar.vertical { border-top: 1px solid #686868; margin-top: -1px; }
 +
 +/********** Switch * */
 +switch { font-weight: bold; font-size: smaller; border: 1px solid #686868; border-radius: 14px; color: #f3f3f1; background-color: #282828; transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; /* only show i / o for the accessible theme */ }
 +
 +switch { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +switch:focus:focus-visible { outline-color: rgba(255, 255, 255, 0.6); outline-width: 2px; outline-offset: 0; }
 +
 +headerbar switch { background-color: #141414; }
 +
 +switch:checked { color: #ffffff; border-color: #1f76e1; background-color: #15539e; }
 +
 +switch:disabled { color: #919191; border-color: #686868; background-color: #2f2f2f; text-shadow: none; }
 +
 +switch > slider { color: #f3f3f1; outline-color: rgba(255, 255, 255, 0.6); border-color: #686868; background-image: linear-gradient(to top, #323232 2px, #353535); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); margin: -1px; min-width: 24px; min-height: 24px; border: 1px solid; border-color: #686868; border-radius: 50%; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
 +
 +switch > image { color: transparent; }
 +
 +switch:hover > slider { color: #f3f3f1; border-color: #686868; background-image: linear-gradient(to top, #2b2b2b 20%, #2d2d2d 90%); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +switch:checked > slider { border: 1px solid #1f76e1; }
 +
 +switch:disabled > slider { color: #919191; border-color: #5d5d5d; background-image: image(#2f2f2f); }
 +
 +row:selected switch { outline-color: rgba(255, 255, 255, 0.6); }
 +
 +/************************* Check and Radio items * */
 +.view.content-view.check:not(list), iconview.content-view.check:not(list), .content-view .tile check:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: #15539e; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:hover:not(list), iconview.content-view.check:hover:not(list), .content-view .tile check:hover:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: #15539e; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:active:not(list), iconview.content-view.check:active:not(list), .content-view .tile check:active:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: #15539e; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:backdrop:not(list), iconview.content-view.check:backdrop:not(list), .content-view .tile check:backdrop:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: #5a5a5a; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:checked:not(list), iconview.content-view.check:checked:not(list), .content-view .tile check:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: #eeeeec; background-color: #15539e; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:checked:hover:not(list), iconview.content-view.check:checked:hover:not(list), .content-view .tile check:checked:hover:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: #eeeeec; background-color: #15539e; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:checked:active:not(list), iconview.content-view.check:checked:active:not(list), .content-view .tile check:checked:active:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: #eeeeec; background-color: #15539e; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:backdrop:checked:not(list), iconview.content-view.check:backdrop:checked:not(list), .content-view .tile check:backdrop:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: rgba(238, 238, 236, 0.8); background-color: #5a5a5a; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
 +
 +checkbutton { border-spacing: 4px; border-radius: 5px; transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +checkbutton { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +checkbutton:focus:focus-visible { outline-color: rgba(255, 255, 255, 0.6); outline-width: 2px; outline-offset: -2px; }
 +
 +checkbutton.text-button { padding: 4px; }
 +
 +check, radio { min-height: 14px; min-width: 14px; border: 1px solid; -gtk-icon-source: none; }
 +
 +check, radio { background-clip: padding-box; background-image: linear-gradient(to bottom, #3c3c3c 20%, #303030 90%); border-color: #4e4e4e; box-shadow: 0 1px rgba(0, 0, 0, 0.05); color: #ffffff; }
 +
 +check:hover, radio:hover { background-image: linear-gradient(to bottom, #474747 10%, #3a3a3a 90%); }
 +
 +check:active, radio:active { box-shadow: inset 0 1px black; background-image: image(#232323); }
 +
 +check:disabled, radio:disabled { box-shadow: none; color: rgba(255, 255, 255, 0.7); }
 +
 +check:checked, radio:checked { background-clip: border-box; background-image: linear-gradient(to bottom, #185fb4 20%, #15539e 90%); border-color: #092444; box-shadow: 0 1px rgba(0, 0, 0, 0.05); color: #ffffff; }
 +
 +check:checked:hover, radio:checked:hover { background-image: linear-gradient(to bottom, #1b68c6 10%, #185cb0 90%); }
 +
 +check:checked:active, radio:checked:active { box-shadow: inset 0 1px black; background-image: image(#124787); }
 +
 +check:checked:disabled, radio:checked:disabled { box-shadow: none; color: rgba(255, 255, 255, 0.7); }
 +
 +check:indeterminate, radio:indeterminate { background-clip: border-box; background-image: linear-gradient(to bottom, #185fb4 20%, #15539e 90%); border-color: #092444; box-shadow: 0 1px rgba(0, 0, 0, 0.05); color: #ffffff; }
 +
 +check:indeterminate:hover, radio:indeterminate:hover { background-image: linear-gradient(to bottom, #1b68c6 10%, #185cb0 90%); }
 +
 +check:indeterminate:active, radio:indeterminate:active { box-shadow: inset 0 1px black; background-image: image(#124787); }
 +
 +check:indeterminate:disabled, radio:indeterminate:disabled { box-shadow: none; color: rgba(255, 255, 255, 0.7); }
 +
 +.osd check, .osd radio { color: #eeeeec; outline-color: rgba(255, 255, 255, 0.6); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; }
 +
 +.osd check:hover, .osd radio:hover { color: #eeeeec; outline-color: rgba(255, 255, 255, 0.6); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; }
 +
 +.osd check:active, .osd radio:active { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; }
 +
 +.osd check:disabled, .osd radio:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; }
 +
 +check { border-radius: 3px; -gtk-icon-size: 14px; }
 +
 +check:checked { -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets-hc/check-symbolic.symbolic.png")), -gtk-recolor(url("assets-hc/check@2-symbolic.symbolic.png"))); }
 +
 +check:indeterminate { -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets-hc/dash-symbolic.symbolic.png")), -gtk-recolor(url("assets-hc/dash@2-symbolic.symbolic.png"))); }
 +
 +treeview.view radio:selected:focus, treeview.view radio:selected, radio { border-radius: 100%; -gtk-icon-size: 14px; }
 +
 +treeview.view radio:checked:selected, radio:checked { -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets-hc/bullet-symbolic.symbolic.png")), -gtk-recolor(url("assets-hc/bullet@2-symbolic.symbolic.png"))); }
 +
 +treeview.view radio:indeterminate:selected, radio:indeterminate { -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets-hc/dash-symbolic.symbolic.png")), -gtk-recolor(url("assets-hc/dash@2-symbolic.symbolic.png"))); }
 +
 +treeview.view check:selected:focus, treeview.view check:selected, treeview.view radio:selected:focus, treeview.view radio:selected { color: #ffffff; }
 +
 +/************ GtkScale * */
 +progressbar > trough, scale > trough > fill, scale > trough { border: 1px solid #282828; border-radius: 3px; background-color: #282828; }
 +
 +headerbar progressbar > trough, headerbar scale > trough > fill, headerbar scale > trough { background-color: #141414; }
 +
 +progressbar > trough:disabled, scale > trough > fill:disabled, scale > trough:disabled { background-color: #2f2f2f; border-color: #5d5d5d; }
 +
 +row:selected progressbar > trough, row:selected scale > trough > fill, row:selected scale > trough { outline-color: rgba(255, 255, 255, 0.6); border-color: black; }
 +
 +.osd progressbar > trough, .osd scale > trough > fill, .osd scale > trough { border-color: rgba(0, 0, 0, 0.7); background-color: rgba(0, 0, 0, 0.5); }
 +
 +.osd progressbar > trough:disabled, .osd scale > trough > fill:disabled, .osd scale > trough:disabled { background-color: rgba(58, 58, 57, 0.5); }
 +
 +progressbar > trough > progress, scale > trough > highlight { border: 1px solid #0f3b71; border-radius: 3px; background-color: #0f3b71; }
 +
 +progressbar > trough > progress:disabled, scale > trough > highlight:disabled { background-color: transparent; border-color: transparent; }
 +
 +row:selected progressbar > trough > progress, row:selected scale > trough > highlight { border-color: black; }
 +
 +.osd progressbar > trough > progress, .osd scale > trough > highlight { border-color: rgba(0, 0, 0, 0.7); }
 +
 +.osd progressbar > trough > progress:disabled, .osd scale > trough > highlight:disabled { border-color: transparent; }
 +
 +scale { min-height: 10px; min-width: 10px; padding: 12px; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +scale > trough { outline: 0 solid transparent; outline-offset: 16px; }
 +
 +scale:focus:focus-visible > trough { outline-color: rgba(255, 255, 255, 0.6); outline-width: 2px; outline-offset: 10px; }
 +
 +scale > trough { transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
 +
 +scale > trough > fill, scale > trough > highlight { margin: -1px; }
 +
 +scale > trough > slider { min-height: 18px; min-width: 18px; margin: -9px; }
 +
 +scale.fine-tune.horizontal { padding-top: 9px; padding-bottom: 9px; min-height: 16px; }
 +
 +scale.fine-tune.vertical { padding-left: 9px; padding-right: 9px; min-width: 16px; }
 +
 +scale.fine-tune > trough > slider { margin: -6px; }
 +
 +scale.fine-tune > trough > fill, scale.fine-tune > trough > highlight, scale.fine-tune > trough { border-radius: 5px; }
 +
 +scale > trough > fill:disabled { border-color: transparent; background-color: transparent; }
 +
 +.osd scale > trough > fill { background-color: rgba(91, 91, 90, 0.775); }
 +
 +.osd scale > trough > fill:disabled { border-color: transparent; background-color: transparent; }
 +
 +scale > trough > slider { color: #f3f3f1; outline-color: rgba(255, 255, 255, 0.6); border-color: #686868; background-image: linear-gradient(to top, #323232 2px, #353535); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); border-width: 1px; border-style: solid; border-radius: 100%; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: background, border, box-shadow; }
 +
 +scale > trough > slider:hover { color: #f3f3f1; border-color: #686868; background-image: linear-gradient(to top, #2b2b2b 20%, #2d2d2d 90%); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +scale > trough > slider:active { border-color: black; }
 +
 +scale > trough > slider:disabled { color: #919191; border-color: #5d5d5d; background-image: image(#2f2f2f); }
 +
 +row:selected scale > trough > slider:disabled, row:selected scale > trough > slider { border-color: black; }
 +
 +.osd scale > trough > slider { color: #eeeeec; outline-color: rgba(255, 255, 255, 0.6); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; border-color: rgba(0, 0, 0, 0.7); background-color: #262626; }
 +
 +.osd scale > trough > slider:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(12, 12, 12, 0.7)); background-clip: padding-box; background-color: #262626; }
 +
 +.osd scale > trough > slider:active { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; background-color: #262626; }
 +
 +.osd scale > trough > slider:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; background-color: #262626; }
 +
 +scale > value { color: alpha(currentColor,0.55); font-feature-settings: "tnum"; }
 +
 +scale.horizontal > marks { color: alpha(currentColor,0.55); }
 +
 +scale.horizontal > marks.top { margin-bottom: 6px; }
 +
 +scale.horizontal > marks.bottom { margin-top: 6px; }
 +
 +scale.horizontal > marks indicator { background-color: currentColor; min-height: 6px; min-width: 1px; }
 +
 +scale.horizontal > value.left { margin-right: 9px; }
 +
 +scale.horizontal > value.right { margin-left: 9px; }
 +
 +scale.horizontal.fine-tune > marks.top { margin-top: 3px; }
 +
 +scale.horizontal.fine-tune > marks.bottom { margin-bottom: 3px; }
 +
 +scale.horizontal.fine-tune > marks indicator { min-height: 3px; }
 +
 +scale.vertical > marks { color: alpha(currentColor,0.55); }
 +
 +scale.vertical > marks.top { margin-right: 6px; }
 +
 +scale.vertical > marks.bottom { margin-left: 6px; }
 +
 +scale.vertical > marks indicator { background-color: currentColor; min-height: 1px; min-width: 6px; }
 +
 +scale.vertical > value.top { margin-bottom: 9px; }
 +
 +scale.vertical > value.bottom { margin-top: 9px; }
 +
 +scale.vertical.fine-tune > marks.top { margin-left: 3px; }
 +
 +scale.vertical.fine-tune > marks.bottom { margin-right: 3px; }
 +
 +scale.vertical.fine-tune > marks indicator { min-height: 3px; }
 +
 +scale.horizontal.marks-before:not(.marks-after) > trough > slider { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-horz-scale-has-marks-above-dark.png"), url("assets-hc/slider-horz-scale-has-marks-above-dark@2.png")); min-height: 26px; min-width: 22px; margin-top: -14px; background-position: top; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -7px -10px; margin-top: -11px; }
 +
 +scale.horizontal.marks-before:not(.marks-after) > trough > slider:hover { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-horz-scale-has-marks-above-hover-dark.png"), url("assets-hc/slider-horz-scale-has-marks-above-hover-dark@2.png")); min-height: 26px; min-width: 22px; margin-top: -14px; background-position: top; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -7px -10px; margin-top: -11px; }
 +
 +scale.horizontal.marks-before:not(.marks-after) > trough > slider:active { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-horz-scale-has-marks-above-active-dark.png"), url("assets-hc/slider-horz-scale-has-marks-above-active-dark@2.png")); min-height: 26px; min-width: 22px; margin-top: -14px; background-position: top; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -7px -10px; margin-top: -11px; }
 +
 +scale.horizontal.marks-before:not(.marks-after) > trough > slider:disabled { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-horz-scale-has-marks-above-insensitive-dark.png"), url("assets-hc/slider-horz-scale-has-marks-above-insensitive-dark@2.png")); min-height: 26px; min-width: 22px; margin-top: -14px; background-position: top; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -7px -10px; margin-top: -11px; }
 +
 +scale.horizontal.marks-after:not(.marks-before) > trough > slider { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-horz-scale-has-marks-below-dark.png"), url("assets-hc/slider-horz-scale-has-marks-below-dark@2.png")); min-height: 26px; min-width: 22px; margin-bottom: -14px; background-position: bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -7px -10px; margin-bottom: -11px; }
 +
 +scale.horizontal.marks-after:not(.marks-before) > trough > slider:hover { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-horz-scale-has-marks-below-hover-dark.png"), url("assets-hc/slider-horz-scale-has-marks-below-hover-dark@2.png")); min-height: 26px; min-width: 22px; margin-bottom: -14px; background-position: bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -7px -10px; margin-bottom: -11px; }
 +
 +scale.horizontal.marks-after:not(.marks-before) > trough > slider:active { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-horz-scale-has-marks-below-active-dark.png"), url("assets-hc/slider-horz-scale-has-marks-below-active-dark@2.png")); min-height: 26px; min-width: 22px; margin-bottom: -14px; background-position: bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -7px -10px; margin-bottom: -11px; }
 +
 +scale.horizontal.marks-after:not(.marks-before) > trough > slider:disabled { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-horz-scale-has-marks-below-insensitive-dark.png"), url("assets-hc/slider-horz-scale-has-marks-below-insensitive-dark@2.png")); min-height: 26px; min-width: 22px; margin-bottom: -14px; background-position: bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -7px -10px; margin-bottom: -11px; }
 +
 +scale.vertical.marks-before:not(.marks-after) > trough > slider { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-vert-scale-has-marks-above-dark.png"), url("assets-hc/slider-vert-scale-has-marks-above-dark@2.png")); min-height: 22px; min-width: 26px; margin-left: -14px; background-position: left bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -10px -7px; margin-left: -11px; }
 +
 +scale.vertical.marks-before:not(.marks-after) > trough > slider:hover { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-vert-scale-has-marks-above-hover-dark.png"), url("assets-hc/slider-vert-scale-has-marks-above-hover-dark@2.png")); min-height: 22px; min-width: 26px; margin-left: -14px; background-position: left bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -10px -7px; margin-left: -11px; }
 +
 +scale.vertical.marks-before:not(.marks-after) > trough > slider:active { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-vert-scale-has-marks-above-active-dark.png"), url("assets-hc/slider-vert-scale-has-marks-above-active-dark@2.png")); min-height: 22px; min-width: 26px; margin-left: -14px; background-position: left bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -10px -7px; margin-left: -11px; }
 +
 +scale.vertical.marks-before:not(.marks-after) > trough > slider:disabled { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-vert-scale-has-marks-above-insensitive-dark.png"), url("assets-hc/slider-vert-scale-has-marks-above-insensitive-dark@2.png")); min-height: 22px; min-width: 26px; margin-left: -14px; background-position: left bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -10px -7px; margin-left: -11px; }
 +
 +scale.vertical.marks-after:not(.marks-before) > trough > slider { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-vert-scale-has-marks-below-dark.png"), url("assets-hc/slider-vert-scale-has-marks-below-dark@2.png")); min-height: 22px; min-width: 26px; margin-right: -14px; background-position: right bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -10px -7px; margin-right: -11px; }
 +
 +scale.vertical.marks-after:not(.marks-before) > trough > slider:hover { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-vert-scale-has-marks-below-hover-dark.png"), url("assets-hc/slider-vert-scale-has-marks-below-hover-dark@2.png")); min-height: 22px; min-width: 26px; margin-right: -14px; background-position: right bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -10px -7px; margin-right: -11px; }
 +
 +scale.vertical.marks-after:not(.marks-before) > trough > slider:active { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-vert-scale-has-marks-below-active-dark.png"), url("assets-hc/slider-vert-scale-has-marks-below-active-dark@2.png")); min-height: 22px; min-width: 26px; margin-right: -14px; background-position: right bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -10px -7px; margin-right: -11px; }
 +
 +scale.vertical.marks-after:not(.marks-before) > trough > slider:disabled { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-vert-scale-has-marks-below-insensitive-dark.png"), url("assets-hc/slider-vert-scale-has-marks-below-insensitive-dark@2.png")); min-height: 22px; min-width: 26px; margin-right: -14px; background-position: right bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -10px -7px; margin-right: -11px; }
 +
 +scale.color { min-height: 0; min-width: 0; }
 +
 +scale.color > trough { background-image: image(#686868); background-repeat: no-repeat; }
 +
 +scale.color.horizontal { padding: 0 0 15px 0; }
 +
 +scale.color.horizontal > trough { padding-bottom: 4px; background-position: 0 -3px; border-top-left-radius: 0; border-top-right-radius: 0; }
 +
 +scale.color.horizontal > trough > slider:dir(ltr):hover, scale.color.horizontal > trough > slider:dir(ltr):backdrop, scale.color.horizontal > trough > slider:dir(ltr):disabled, scale.color.horizontal > trough > slider:dir(ltr):backdrop:disabled, scale.color.horizontal > trough > slider:dir(ltr), scale.color.horizontal > trough > slider:dir(rtl):hover, scale.color.horizontal > trough > slider:dir(rtl):backdrop, scale.color.horizontal > trough > slider:dir(rtl):disabled, scale.color.horizontal > trough > slider:dir(rtl):backdrop:disabled, scale.color.horizontal > trough > slider:dir(rtl) { margin-bottom: -15px; margin-top: 6px; }
 +
 +scale.color.vertical:dir(ltr) { padding: 0 0 0 15px; }
 +
 +scale.color.vertical:dir(ltr) > trough { padding-left: 4px; background-position: 3px 0; border-bottom-right-radius: 0; border-top-right-radius: 0; }
 +
 +scale.color.vertical:dir(ltr) > trough > slider:hover, scale.color.vertical:dir(ltr) > trough > slider:backdrop, scale.color.vertical:dir(ltr) > trough > slider:disabled, scale.color.vertical:dir(ltr) > trough > slider:backdrop:disabled, scale.color.vertical:dir(ltr) > trough > slider { margin-left: -15px; margin-right: 6px; }
 +
 +scale.color.vertical:dir(rtl) { padding: 0 15px 0 0; }
 +
 +scale.color.vertical:dir(rtl) > trough { padding-right: 4px; background-position: -3px 0; border-bottom-left-radius: 0; border-top-left-radius: 0; }
 +
 +scale.color.vertical:dir(rtl) > trough > slider:hover, scale.color.vertical:dir(rtl) > trough > slider:backdrop, scale.color.vertical:dir(rtl) > trough > slider:disabled, scale.color.vertical:dir(rtl) > trough > slider:backdrop:disabled, scale.color.vertical:dir(rtl) > trough > slider { margin-right: -15px; margin-left: 6px; }
 +
 +scale.color.fine-tune.horizontal:dir(ltr), scale.color.fine-tune.horizontal:dir(rtl) { padding: 0 0 12px 0; }
 +
 +scale.color.fine-tune.horizontal:dir(ltr) > trough, scale.color.fine-tune.horizontal:dir(rtl) > trough { padding-bottom: 7px; background-position: 0 -6px; }
 +
 +scale.color.fine-tune.horizontal:dir(ltr) > trough > slider, scale.color.fine-tune.horizontal:dir(rtl) > trough > slider { margin-bottom: -15px; margin-top: 6px; }
 +
 +scale.color.fine-tune.vertical:dir(ltr) { padding: 0 0 0 12px; }
 +
 +scale.color.fine-tune.vertical:dir(ltr) > trough { padding-left: 7px; background-position: 6px 0; }
 +
 +scale.color.fine-tune.vertical:dir(ltr) > trough > slider { margin-left: -15px; margin-right: 6px; }
 +
 +scale.color.fine-tune.vertical:dir(rtl) { padding: 0 12px 0 0; }
 +
 +scale.color.fine-tune.vertical:dir(rtl) > trough { padding-right: 7px; background-position: -6px 0; }
 +
 +scale.color.fine-tune.vertical:dir(rtl) > trough > slider { margin-right: -15px; margin-left: 6px; }
 +
 +/***************** Progress bars * */
 +progressbar { font-size: smaller; color: rgba(243, 243, 241, 0.4); font-feature-settings: "tnum"; }
 +
 +progressbar.horizontal > trough { min-width: 150px; }
 +
 +progressbar.horizontal > trough, progressbar.horizontal > trough > progress { min-height: 2px; }
 +
 +progressbar.vertical > trough { min-height: 80px; }
 +
 +progressbar.vertical > trough, progressbar.vertical > trough > progress { min-width: 2px; }
 +
 +progressbar.horizontal > trough > progress { margin: 0 -1px; }
 +
 +progressbar.vertical > trough > progress { margin: -1px 0; }
 +
 +progressbar > trough > progress { /* share most of scales' */ /* override insensitive that is specific to progress */ border-radius: 1.5px; }
 +
 +progressbar > trough > progress:disabled { background-color: #919191; border-color: #919191; }
 +
 +progressbar > trough > progress.left { border-top-left-radius: 5px; border-bottom-left-radius: 5px; }
 +
 +progressbar > trough > progress.right { border-top-right-radius: 5px; border-bottom-right-radius: 5px; }
 +
 +progressbar > trough > progress.top { border-top-right-radius: 5px; border-top-left-radius: 5px; }
 +
 +progressbar > trough > progress.bottom { border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; }
 +
 +progressbar.osd { min-width: 3px; min-height: 3px; background-color: transparent; }
 +
 +progressbar.osd > trough { border-style: none; border-radius: 0; background-color: transparent; box-shadow: none; }
 +
 +progressbar.osd > trough > progress { border-style: none; border-radius: 0; }
 +
 +progressbar > trough.empty > progress { all: unset; }
 +
 +/************* Level Bar * */
 +levelbar.horizontal trough > block { min-height: 9px; border-radius: 5px; }
 +
 +levelbar.horizontal trough > block:dir(rtl) { border-radius: 0 5px 5px 0; }
 +
 +levelbar.horizontal trough > block:dir(ltr) { border-radius: 5px 0 0 5px; }
 +
 +levelbar.horizontal trough > block.empty, levelbar.horizontal trough > block.full { border-radius: 5px; }
 +
 +levelbar.horizontal.discrete trough > block { min-height: 2px; margin: 1px; min-width: 24px; border-radius: 0; }
 +
 +levelbar.horizontal.discrete trough > block:first-child { border-radius: 2px 0 0 2px; }
 +
 +levelbar.horizontal.discrete trough > block:last-child { border-radius: 0 2px 2px 0; }
 +
 +levelbar.vertical trough > block { min-width: 9px; border-radius: 5px; }
 +
 +levelbar.vertical.discrete > trough > block { min-width: 2px; margin: 1px 0; min-height: 32px; }
 +
 +levelbar > trough { padding: 0; }
 +
 +levelbar > trough > block { border: 1px solid; }
 +
 +levelbar > trough > block.low { border-color: #f57900; background-color: #f57900; }
 +
 +levelbar > trough > block.high, levelbar > trough > block:not(.empty) { border-color: #0f3b71; background-color: #0f3b71; }
 +
 +levelbar > trough > block.full { border-color: #26ab62; background-color: #26ab62; }
 +
 +levelbar > trough > block.empty { background-color: #232323; border-color: #232323; }
 +
 +/**************** Print dialog * */
 +window.dialog.print drawing { color: #f3f3f1; background: none; border: none; padding: 0; }
 +
 +window.dialog.print drawing paper { background: white; color: #2e3436; border: 1px solid #686868; }
 +
 +window.dialog.print .dialog-action-box { margin: 12px; }
 +
 +/********** Frames * */
 +frame, .frame { border: 1px solid #686868; }
 +
 +frame { border-radius: 8px; }
 +
 +frame > label { margin: 4px; }
 +
 +actionbar > revealer > box { padding: 6px; border-top: 1px solid #686868; }
 +
 +actionbar > revealer > box, actionbar > revealer > box > box.start, actionbar > revealer > box > box.end { border-spacing: 6px; }
 +
 +scrolledwindow > overshoot.top { background-image: radial-gradient(farthest-side at top, #4e4e4e 85%, rgba(78, 78, 78, 0)), radial-gradient(farthest-side at top, rgba(243, 243, 241, 0.07), rgba(243, 243, 241, 0)); background-size: 100% 3%, 100% 50%; background-repeat: no-repeat; background-position: top; background-color: transparent; border: none; box-shadow: none; }
 +
 +scrolledwindow > overshoot.bottom { background-image: radial-gradient(farthest-side at bottom, #4e4e4e 85%, rgba(78, 78, 78, 0)), radial-gradient(farthest-side at bottom, rgba(243, 243, 241, 0.07), rgba(243, 243, 241, 0)); background-size: 100% 3%, 100% 50%; background-repeat: no-repeat; background-position: bottom; background-color: transparent; border: none; box-shadow: none; }
 +
 +scrolledwindow > overshoot.left { background-image: radial-gradient(farthest-side at left, #4e4e4e 85%, rgba(78, 78, 78, 0)), radial-gradient(farthest-side at left, rgba(243, 243, 241, 0.07), rgba(243, 243, 241, 0)); background-size: 3% 100%, 50% 100%; background-repeat: no-repeat; background-position: left; background-color: transparent; border: none; box-shadow: none; }
 +
 +scrolledwindow > overshoot.right { background-image: radial-gradient(farthest-side at right, #4e4e4e 85%, rgba(78, 78, 78, 0)), radial-gradient(farthest-side at right, rgba(243, 243, 241, 0.07), rgba(243, 243, 241, 0)); background-size: 3% 100%, 50% 100%; background-repeat: no-repeat; background-position: right; background-color: transparent; border: none; box-shadow: none; }
 +
 +scrolledwindow > junction { background: #686868, linear-gradient(to bottom, transparent 1px, #313131 1px), linear-gradient(to right, transparent 1px, #313131 1px); }
 +
 +scrolledwindow > junction:dir(rtl) { background: #686868, linear-gradient(to bottom, transparent 1px, #313131 1px), linear-gradient(to left, transparent 1px, #313131 1px); }
 +
 +separator { background: #757575; min-width: 1px; min-height: 1px; }
 +
 +/********* Lists * */
 +listview, list { color: white; background-color: #2d2d2d; border-color: #686868; }
 +
 +listview:backdrop, list:backdrop { color: #d6d6d6; background-color: #303030; border-color: #202020; }
 +
 +listview > row, list > row { padding: 2px; }
 +
 +listview > row.expander, list > row.expander { padding: 0px; }
 +
 +listview > row.expander .row-header, list > row.expander .row-header { padding: 2px; }
 +
 +listview.horizontal row.separator, listview.separators.horizontal > row:not(.separator), list.horizontal row.separator, list.separators.horizontal > row:not(.separator) { border-left: 1px solid #555554; }
 +
 +listview:not(.horizontal) row.separator, listview.separators:not(.horizontal) > row:not(.separator), list:not(.horizontal) row.separator, list.separators:not(.horizontal) > row:not(.separator) { border-bottom: 1px solid #555554; }
 +
 +row { transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +row { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +row:focus:focus-visible { outline-color: rgba(255, 255, 255, 0.6); outline-width: 2px; outline-offset: -2px; }
 +
 +row.activatable.has-open-popup, row.activatable:hover { background-color: rgba(243, 243, 241, 0.05); }
 +
 +row.activatable:active { box-shadow: inset 0 2px 2px -2px rgba(0, 0, 0, 0.2); }
 +
 +row.activatable:selected:active { box-shadow: inset 0 2px 3px -1px rgba(0, 0, 0, 0.5); }
 +
 +row.activatable.has-open-popup:selected, row.activatable:selected:hover { background-color: #264e7e; }
 +
 +row:selected { outline-color: rgba(255, 255, 255, 0.6); }
 +
 +columnview > listview > row { padding: 0; }
 +
 +columnview > listview > row > cell { padding: 8px 6px; }
 +
 +columnview > listview > row > cell:not(:first-child) { border-left: 1px solid transparent; }
 +
 +columnview.column-separators > listview > row > cell { border-left-color: #555554; }
 +
 +columnview.data-table > listview > row > cell { padding-top: 2px; padding-bottom: 2px; }
 +
 +treeexpander { border-spacing: 4px; }
 +
 +/******************************************************** Data Tables                                          * treeview like tables with individual focusable cells * https://gitlab.gnome.org/GNOME/gtk/-/issues/2929     * */
 +columnview row:not(:selected) cell editablelabel:not(.editing):focus-within { outline: 2px solid rgba(255, 255, 255, 0.6); }
 +
 +columnview row:not(:selected) cell editablelabel.editing:focus-within { outline: 2px solid #0f3b71; }
 +
 +columnview row:not(:selected) cell editablelabel.editing text selection { color: #ffffff; background-color: #0f3b71; }
 +
 +/******************************************************* Rich Lists                                          * Large list usually containing lots of widgets       * https://gitlab.gnome.org/GNOME/gtk/-/issues/3073    * */
 +.rich-list { /* rich lists usually containing other widgets than just labels/text */ }
 +
 +.rich-list > row { padding: 8px 12px; min-height: 32px; /* should be tall even when only containing a label */ }
 +
 +.rich-list > row > box { border-spacing: 12px; }
 +
 +/********************* App Notifications * */
 +.app-notification { padding: 10px; border-spacing: 10px; border-radius: 0 0 5px 5px; background-color: rgba(38, 38, 38, 0.7); background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.2), transparent 2px); background-clip: padding-box; }
 +
 +.app-notification border { border: none; }
 +
 +/************* Expanders * */
 +expander { min-width: 16px; min-height: 16px; -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); }
 +
 +expander:dir(rtl) { -gtk-icon-source: -gtk-icontheme("pan-end-symbolic-rtl"); }
 +
 +expander:disabled { color: #919191; }
 +
 +expander:checked { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
 +
 +expander-widget { transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +expander-widget > box > title { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +expander-widget:focus:focus-visible > box > title { outline-color: rgba(255, 255, 255, 0.6); outline-width: 2px; outline-offset: -2px; }
 +
 +expander-widget > box > title { transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); border-radius: 5px; }
 +
 +expander-widget > box > title:hover > expander { color: white; }
 +
 +.navigation-sidebar:not(decoration):not(window):drop(active):focus, .navigation-sidebar:not(decoration):not(window):drop(active), placessidebar:not(decoration):not(window):drop(active):focus, placessidebar:not(decoration):not(window):drop(active), stackswitcher:not(decoration):not(window):drop(active):focus, stackswitcher:not(decoration):not(window):drop(active), expander-widget:not(decoration):not(window):drop(active):focus, expander-widget:not(decoration):not(window):drop(active) { box-shadow: none; }
 +
 +/************ Calendar * */
 +calendar { color: white; border: 1px solid #686868; }
 +
 +calendar > header { border-bottom: 1px solid #686868; }
 +
 +calendar > header > button { border: none; box-shadow: none; background: none; border-radius: 0; }
 +
 +calendar > header > button:backdrop { background: none; }
 +
 +calendar > grid > label.today { box-shadow: inset 0px -2px #686868; }
 +
 +calendar > grid > label.today:selected { box-shadow: none; }
 +
 +calendar > grid > label:focus { outline-color: rgba(255, 255, 255, 0.6); outline-offset: -2px; outline-width: 2px; outline-style: solid; }
 +
 +calendar > grid > label.day-number { padding: 4px; }
 +
 +calendar > grid > label.day-number:selected { border-radius: 3px; }
 +
 +calendar > grid > label.day-number.other-month { color: alpha(currentColor,0.3); }
 +
 +/*********** Dialogs * */
 +window.dialog.message .titlebar { min-height: 20px; background-image: none; background-color: #303030; border-style: none; border-top-left-radius: 7px; border-top-right-radius: 7px; }
 +
 +window.dialog.message box.dialog-vbox.vertical { border-spacing: 10px; }
 +
 +window.dialog.message label.title { font-weight: 800; font-size: 15pt; }
 +
 +window.dialog.message.csd.background { border-bottom-left-radius: 9px; border-bottom-right-radius: 9px; }
 +
 +window.dialog.message.csd .dialog-action-area button { padding: 10px 14px; border-radius: 0; border-left-style: solid; border-right-style: none; border-bottom-style: none; }
 +
 +window.dialog.message.csd .dialog-action-area button:first-child { border-left-style: none; border-bottom-left-radius: 7px; }
 +
 +window.dialog.message.csd .dialog-action-area button:last-child { border-bottom-right-radius: 7px; }
 +
 +filechooser .dialog-action-box { border-top: 1px solid #686868; }
 +
 +filechooser #pathbarbox { border-bottom: 1px solid #303030; }
 +
 +filechooserbutton > button > box { border-spacing: 6px; }
 +
 +filechooserbutton:drop(active) { box-shadow: none; border-color: transparent; }
 +
 +/*********** Sidebar * */
 +.sidebar { background-color: #2e2e2e; }
 +
 +.sidebar:not(separator):dir(ltr), .sidebar.left:not(separator), .sidebar.left:not(separator):dir(rtl) { border-right: 1px solid #686868; border-left-style: none; }
 +
 +.sidebar:not(separator):dir(rtl), .sidebar.right:not(separator) { border-left: 1px solid #686868; border-right-style: none; }
 +
 +.sidebar listview.view, .sidebar list { background-color: transparent; }
 +
 +paned .sidebar.left, paned .sidebar.right, paned .sidebar.left:dir(rtl), paned .sidebar:dir(rtl), paned .sidebar:dir(ltr), paned .sidebar { border-style: none; }
 +
 +stacksidebar list.separators:not(.horizontal) > row:not(.separator) { border-bottom: none; }
 +
 +stacksidebar row { padding: 10px 4px; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +stacksidebar row { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +stacksidebar row:focus:focus-visible { outline-color: rgba(255, 255, 255, 0.6); outline-width: 2px; outline-offset: -2px; }
 +
 +stacksidebar row > label { padding-left: 6px; padding-right: 6px; }
 +
 +stacksidebar row.needs-attention > label { background-size: 6px 6px, 0 0; }
 +
 +stacksidebar row:selected { background-color: #161616; border-radius: 5px; color: #f3f3f1; }
 +
 +stacksidebar row:selected:hover:dir(ltr), stacksidebar row:selected:hover:dir(rtl) { background-color: #090909; }
 +
 +stacksidebar row.activatable:active, stacksidebar row.activatable:selected:active { box-shadow: none; }
 +
 +separator.sidebar { background-color: #686868; }
 +
 +/********************** Navigation Sidebar * */
 +.navigation-sidebar { padding: 5px 0; }
 +
 +.navigation-sidebar > separator { margin: 5px; }
 +
 +.navigation-sidebar > row { min-height: 36px; padding: 0 8px; border-radius: 5px; margin: 0 5px 2px; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +.navigation-sidebar > row { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +.navigation-sidebar > row:focus-visible:focus-within { outline-color: rgba(255, 255, 255, 0.6); outline-width: 2px; outline-offset: -2px; }
 +
 +.navigation-sidebar > row:hover { background-color: #090909; }
 +
 +.navigation-sidebar > row:selected { background-color: #161616; color: inherit; }
 +
 +.navigation-sidebar > row:selected:hover { background-color: #090909; }
 +
 +.navigation-sidebar > row:disabled { color: #919191; }
 +
 +/**************** File chooser * */
 +row image.sidebar-icon { opacity: 0.7; }
 +
 +/* this should be more generic, only using .navigation-sidebar https://gitlab.gnome.org/GNOME/gtk/-/issues/2929 */
 +placessidebar .navigation-sidebar > row { padding: 0; }
 +
 +placessidebar .navigation-sidebar > row > revealer { padding: 0 14px; }
 +
 +placessidebar .navigation-sidebar > row image.sidebar-icon:dir(ltr) { padding-right: 8px; }
 +
 +placessidebar .navigation-sidebar > row image.sidebar-icon:dir(rtl) { padding-left: 8px; }
 +
 +placessidebar .navigation-sidebar > row label.sidebar-label:dir(ltr) { padding-right: 2px; }
 +
 +placessidebar .navigation-sidebar > row label.sidebar-label:dir(rtl) { padding-left: 2px; }
 +
 +button.sidebar-button { min-height: 26px; min-width: 26px; margin-top: 3px; margin-bottom: 3px; padding: 0; border-radius: 100%; }
 +
 +placessidebar .navigation-sidebar > row:selected:active { box-shadow: none; }
 +
 +placessidebar .navigation-sidebar > row.sidebar-placeholder-row { padding: 0 8px; min-height: 2px; background-image: image(#26a269); background-clip: content-box; }
 +
 +placessidebar .navigation-sidebar > row.sidebar-new-bookmark-row { color: #0f3b71; }
 +
 +placessidebar .navigation-sidebar > row:drop(active):not(:disabled) { color: #26a269; box-shadow: inset 0 1px #26a269, inset 0 -1px #26a269; }
 +
 +placessidebar .navigation-sidebar > row:drop(active):not(:disabled):selected { color: #ffffff; background-color: #26a269; }
 +
 +placesview .server-list-button > image { transition: 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); -gtk-icon-transform: rotate(0turn); }
 +
 +placesview .server-list-button:checked > image { transition: 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); -gtk-icon-transform: rotate(-0.5turn); }
 +
 +placesview > actionbar > revealer > box > box { border-spacing: 6px; }
 +
 +/********* Paned * */
 +paned > separator { min-width: 1px; min-height: 1px; -gtk-icon-source: none; border-style: none; background-color: transparent; background-image: image(#686868); background-size: 1px 1px; }
 +
 +paned > separator:selected { background-image: image(#0f3b71); }
 +
 +paned > separator.wide { min-width: 5px; min-height: 5px; background-color: #303030; background-image: image(#686868), image(#686868); background-size: 1px 1px, 1px 1px; }
 +
 +paned.horizontal > separator { background-repeat: repeat-y; }
 +
 +paned.horizontal > separator:dir(ltr) { margin: 0 -8px 0 0; padding: 0 8px 0 0; background-position: left; }
 +
 +paned.horizontal > separator:dir(rtl) { margin: 0 0 0 -8px; padding: 0 0 0 8px; background-position: right; }
 +
 +paned.horizontal > separator.wide { margin: 0; padding: 0; background-repeat: repeat-y, repeat-y; background-position: left, right; }
 +
 +paned.vertical > separator { margin: 0 0 -8px 0; padding: 0 0 8px 0; background-repeat: repeat-x; background-position: top; }
 +
 +paned.vertical > separator.wide { margin: 0; padding: 0; background-repeat: repeat-x, repeat-x; background-position: bottom, top; }
 +
 +/************** GtkVideo * */
 +video { background: black; }
 +
 +video image.osd { min-width: 64px; min-height: 64px; border-radius: 32px; }
 +
 +/************ Tooltips * */
 +tooltip { padding: 6px 10px; border-radius: 8px; box-shadow: none; }
 +
 +tooltip.background { background-color: rgba(0, 0, 0, 0.8); background-clip: padding-box; border: 1px solid rgba(255, 255, 255, 0.1); color: white; }
 +
 +tooltip > box { border-spacing: 6px; }
 +
 +/***************** Color Chooser * */
 +colorswatch { transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +colorswatch { outline: 0 solid transparent; outline-offset: 6px; }
 +
 +colorswatch:focus:focus-visible { outline-color: rgba(255, 255, 255, 0.6); outline-width: 4px; outline-offset: -2px; }
 +
 +colorswatch:drop(active), colorswatch { border-style: none; }
 +
 +colorswatch.top { border-top-left-radius: 5.5px; border-top-right-radius: 5.5px; }
 +
 +colorswatch.top > overlay { border-top-left-radius: 5px; border-top-right-radius: 5px; }
 +
 +colorswatch.bottom { border-bottom-left-radius: 5.5px; border-bottom-right-radius: 5.5px; }
 +
 +colorswatch.bottom > overlay { border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; }
 +
 +colorswatch.left, colorswatch:first-child:not(.top) { border-top-left-radius: 5.5px; border-bottom-left-radius: 5.5px; }
 +
 +colorswatch.left > overlay, colorswatch:first-child:not(.top) > overlay { border-top-left-radius: 5px; border-bottom-left-radius: 5px; }
 +
 +colorswatch.right, colorswatch:last-child:not(.bottom) { border-top-right-radius: 5.5px; border-bottom-right-radius: 5.5px; }
 +
 +colorswatch.right > overlay, colorswatch:last-child:not(.bottom) > overlay { border-top-right-radius: 5px; border-bottom-right-radius: 5px; }
 +
 +colorswatch.dark > overlay { color: white; }
 +
 +colorswatch.dark.activatable:hover > overlay { border-color: #686868; }
 +
 +colorswatch.light > overlay { color: black; }
 +
 +colorswatch.light.activatable:hover > overlay { border-color: #686868; }
 +
 +colorswatch:drop(active) { box-shadow: none; }
 +
 +colorswatch.light:drop(active) > overlay { border-color: #26a269; box-shadow: inset 0 0 0 2px #686868, inset 0 0 0 1px #26a269; }
 +
 +colorswatch.dark:drop(active) > overlay { border-color: #26a269; box-shadow: inset 0 0 0 2px #686868, inset 0 0 0 1px #26a269; }
 +
 +colorswatch > overlay { border: 1px solid #686868; }
 +
 +colorswatch.activatable:hover > overlay { box-shadow: inset 0 1px rgba(255, 255, 255, 0.4), inset 0 -1px rgba(0, 0, 0, 0.2); }
 +
 +colorswatch#add-color-button { border-radius: 5px 0 0 5px; }
 +
 +colorswatch#add-color-button:only-child { border-radius: 5px; }
 +
 +colorswatch#add-color-button > overlay { color: #f3f3f1; outline-color: rgba(255, 255, 255, 0.6); border-color: #686868; background-image: linear-gradient(to top, #323232 2px, #353535); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +colorswatch#add-color-button.activatable:hover > overlay { color: #f3f3f1; border-color: #686868; background-image: linear-gradient(to top, #2b2b2b 20%, #2d2d2d 90%); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +colorswatch:disabled { opacity: 0.5; }
 +
 +colorswatch:disabled > overlay { border-color: rgba(0, 0, 0, 0.6); box-shadow: none; }
 +
 +row:selected colorswatch { box-shadow: 0 0 0 2px #ffffff; }
 +
 +colorswatch#editor-color-sample { border-radius: 4px; }
 +
 +colorswatch#editor-color-sample > overlay { border-radius: 4.5px; }
 +
 +plane { transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +plane { outline: 0 solid transparent; outline-offset: 6px; }
 +
 +plane:focus:focus-visible { outline-color: rgba(255, 255, 255, 0.6); outline-width: 2px; outline-offset: 2px; }
 +
 +colorchooser .popover.osd { border-radius: 5px; }
 +
 +/******** Misc * */
 +.content-view { background-color: #1e1e1e; }
 +
 +.content-view:hover { -gtk-icon-filter: brightness(1.2); }
 +
 +.content-view .tile { margin: 2px; background-color: black; border-radius: 0; padding: 0; }
 +
 +.content-view .tile:active, .content-view .tile:selected { background-color: #0f3b71; }
 +
 +.content-view .tile:disabled { background-color: #2f2f2f; }
 +
 +.osd .scale-popup button.flat { border-style: none; border-radius: 5px; }
 +
 +.scale-popup button:hover { background-color: rgba(243, 243, 241, 0.1); border-radius: 5px; }
 +
 +/********************** Window Decorations * */
 +window { border-width: 0px; }
 +
 +window.csd { box-shadow: 0 3px 9px 1px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(0, 0, 0, 0.75); margin: 0px; border-radius: 8px 8px 0 0; }
 +
 +window.csd:backdrop { box-shadow: 0 3px 9px 1px transparent, 0 2px 6px 2px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.75); transition: 200ms ease-out; }
 +
 +window.csd.popup { border-radius: 5px; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.65); }
 +
 +window.csd.dialog.message { border-radius: 8px; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.65); }
 +
 +window.solid-csd { margin: 0; padding: 4px; border: solid 1px #686868; border-radius: 0; box-shadow: inset 0 0 0 4px #686868, inset 0 0 0 3px #2d2d2d, inset 0 1px rgba(238, 238, 236, 0.07); }
 +
 +window.solid-csd:backdrop { box-shadow: inset 0 0 0 4px #686868, inset 0 0 0 3px #353535, inset 0 1px rgba(238, 238, 236, 0.07); }
 +
 +window.maximized, window.fullscreen { border-radius: 0; box-shadow: none; }
 +
 +window.tiled, window.tiled-top, window.tiled-left, window.tiled-right, window.tiled-bottom { border-radius: 0; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.75), 0 0 0 20px transparent; }
 +
 +window:backdrop { box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.75), 0 0 0 20px transparent; }
 +
 +window.popup { box-shadow: none; }
 +
 +window.ssd { box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.75); }
 +
 +tooltip.csd { border-radius: 5px; box-shadow: none; }
 +
 +.view:selected:focus, .view:selected, textview > text:selected:focus, textview > text:selected, textview > text > selection:focus, textview > text > selection, iconview:selected:focus, iconview:selected, flowbox > flowboxchild:selected, gridview > child:selected, entry > text > selection, modelbutton.flat:selected, spinbutton:not(.vertical) > text > selection, spinbutton.vertical > text > text > selection, spinbutton.vertical > text > selection, columnview.view:selected:focus, columnview.view:selected, treeview.view:selected:focus, treeview.view:selected, row:selected, calendar > grid > label.day-number:selected { background-color: #0f3b71; }
 +
 +label:selected, .view:selected:focus, .view:selected, textview > text:selected:focus, textview > text:selected, textview > text > selection:focus, textview > text > selection, iconview:selected:focus, iconview:selected, flowbox > flowboxchild:selected, gridview > child:selected, entry > text > selection, modelbutton.flat:selected, spinbutton:not(.vertical) > text > selection, spinbutton.vertical > text > text > selection, spinbutton.vertical > text > selection, columnview.view:selected:focus, columnview.view:selected, treeview.view:selected:focus, treeview.view:selected, row:selected, calendar > grid > label.day-number:selected { color: #ffffff; }
 +
 +label:disabled > selection, label:disabled:selected, .view:disabled:selected, textview > text:disabled:selected:focus, textview > text:disabled:selected, textview > text > selection:disabled, iconview:disabled:selected:focus, iconview:disabled:selected, flowbox > flowboxchild:disabled:selected, gridview > child:disabled:selected, entry > text > selection:disabled, modelbutton.flat:disabled:selected, spinbutton:not(.vertical) > text > selection:disabled, spinbutton.vertical > text > text > selection:disabled, spinbutton.vertical > text > selection:disabled, columnview.view:disabled:selected, treeview.view:disabled:selected, row:disabled:selected, calendar > grid > label.day-number:disabled:selected { color: #879db8; }
 +
 +.monospace { font-family: monospace; }
 +
 +/********************** Touch Copy & Paste * */
 +cursor-handle { background-color: transparent; background-image: none; box-shadow: none; border-style: none; min-width: 20px; min-height: 24px; padding-left: 20px; padding-right: 20px; padding-top: 24px; padding-bottom: 24px; }
 +
 +cursor-handle.top:dir(ltr), cursor-handle.bottom:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets-hc/text-select-start-dark.png"), url("assets-hc/text-select-start-dark@2.png")); }
 +
 +cursor-handle.bottom:dir(ltr), cursor-handle.top:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets-hc/text-select-end-dark.png"), url("assets-hc/text-select-end-dark@2.png")); }
 +
 +cursor-handle.insertion-cursor:dir(ltr), cursor-handle.insertion-cursor:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets-hc/slider-horz-scale-has-marks-above-dark.png"), url("assets-hc/slider-horz-scale-has-marks-above-dark@2.png")); }
 +
 +cursor-handle.top:hover:dir(ltr), cursor-handle.bottom:hover:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets-hc/text-select-start-hover-dark.png"), url("assets-hc/text-select-start-hover-dark@2.png")); }
 +
 +cursor-handle.bottom:hover:dir(ltr), cursor-handle.top:hover:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets-hc/text-select-end-hover-dark.png"), url("assets-hc/text-select-end-hover-dark@2.png")); }
 +
 +cursor-handle.insertion-cursor:hover:dir(ltr), cursor-handle.insertion-cursor:hover:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets-hc/slider-horz-scale-has-marks-above-hover-dark.png"), url("assets-hc/slider-horz-scale-has-marks-above-hover-dark@2.png")); }
 +
 +cursor-handle.top:active:dir(ltr), cursor-handle.bottom:active:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets-hc/text-select-start-active-dark.png"), url("assets-hc/text-select-start-active-dark@2.png")); }
 +
 +cursor-handle.bottom:active:dir(ltr), cursor-handle.top:active:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets-hc/text-select-end-active-dark.png"), url("assets-hc/text-select-end-active-dark@2.png")); }
 +
 +cursor-handle.insertion-cursor:active:dir(ltr), cursor-handle.insertion-cursor:active:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets-hc/slider-horz-scale-has-marks-above-active-dark.png"), url("assets-hc/slider-horz-scale-has-marks-above-active-dark@2.png")); }
 +
 +shortcuts-section { margin: 20px; }
 +
 +.shortcuts-search-results { margin: 20px; border-spacing: 24px; }
 +
 +shortcut { border-spacing: 6px; }
 +
 +shortcut > .keycap { min-width: 20px; min-height: 25px; margin-top: 2px; padding-bottom: 3px; padding-left: 6px; padding-right: 6px; color: #f3f3f1; background-color: #2d2d2d; border: 1px solid; border-color: #686868; border-radius: 5px; box-shadow: inset 0 -3px #505050; font-size: smaller; }
 +
 +:not(decoration):not(window):drop(active):focus, :not(decoration):not(window):drop(active) { border-color: #26a269; box-shadow: inset 0 0 0 1px #26a269; caret-color: #26a269; }
 +
 +stackswitcher > button.text-button { min-width: 100px; }
 +
 +stackswitcher.circular { border-spacing: 12px; }
 +
 +stackswitcher.circular > button.circular, stackswitcher.circular > button.text-button.circular { min-width: 32px; min-height: 32px; padding: 0; }
 +
 +/************* App Icons * */
 +/* Outline for low res icons */
 +.lowres-icon { -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.05), 1px 0 rgba(0, 0, 0, 0.1), 0 1px rgba(0, 0, 0, 0.3), -1px 0 rgba(0, 0, 0, 0.1); }
 +
 +/* Drapshadow for large icons */
 +.icon-dropshadow { -gtk-icon-shadow: 0 1px 12px rgba(0, 0, 0, 0.05), 0 -1px rgba(0, 0, 0, 0.05), 1px 0 rgba(0, 0, 0, 0.1), 0 1px rgba(0, 0, 0, 0.3), -1px 0 rgba(0, 0, 0, 0.1); }
 +
 +/********* Emoji * */
 +popover.emoji-picker > contents { padding: 0; }
 +
 +.emoji-searchbar { padding: 6px; border-spacing: 6px; border-bottom: 1px solid #686868; }
 +
 +.emoji-toolbar { padding: 6px; border-spacing: 6px; border-top: 1px solid #686868; }
 +
 +button.emoji-section { border-color: transparent; border-width: 3px; border-style: none none solid; border-radius: 0; padding: 3px 0 0; min-width: 32px; min-height: 28px; /* reset props inherited from the button style */ background: none; box-shadow: none; text-shadow: none; }
 +
 +button.emoji-section:hover { border-color: rgba(243, 243, 241, 0.1); }
 +
 +button.emoji-section:checked { border-color: #0f3b71; }
 +
 +popover.emoji-picker emoji { font-size: x-large; padding: 6px; border-radius: 6px; }
 +
 +popover.emoji-picker emoji:focus, popover.emoji-picker emoji:hover { background: #0f3b71; }
 +
 +emoji-completion-row > box { border-spacing: 10px; padding: 2px 10px; }
 +
 +emoji-completion-row:focus, emoji-completion-row:hover { background-color: #0f3b71; color: #ffffff; }
 +
 +emoji-completion-row emoji:focus, emoji-completion-row emoji:hover { background-color: #161616; }
 +
 +popover.entry-completion > contents { padding: 0; }
 +
 +statusbar { padding: 6px 10px 6px 10px; }
 +
 +menubutton > button > box { border-spacing: 6px; }
 +
 +menubutton arrow { min-height: 16px; min-width: 16px; }
 +
 +menubutton arrow.none { -gtk-icon-source: -gtk-icontheme("open-menu-symbolic"); }
 +
 +menubutton arrow.down { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
 +
 +menubutton arrow.up { -gtk-icon-source: -gtk-icontheme("pan-up-symbolic"); }
 +
 +menubutton arrow.left { -gtk-icon-source: -gtk-icontheme("pan-start-symbolic"); }
 +
 +menubutton arrow.right { -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); }
index e9653069200721aade18b0cfc0bb12fbda541666,0000000000000000000000000000000000000000..f6d8cd92ab97b0e49fcaaab2a655938ff98f4e6e
mode 100644,000000..100644
--- /dev/null
@@@ -1,1869 -1,0 +1,1859 @@@
- button.sidebar-button, notebook > header > tabs > arrow, windowcontrols button, notebook > header > tabs > arrow.flat, button.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; transition: none; }
 +/* GTK NAMED COLORS ---------------- use responsibly! */
 +/*
 +widget text/foreground color */
 +@define-color theme_fg_color #272c2e;
 +/*
 +text color for entries, views and content in general */
 +@define-color theme_text_color black;
 +/*
 +widget base background color */
 +@define-color theme_bg_color #fdfdfc;
 +/*
 +text widgets and the like base background color */
 +@define-color theme_base_color #ffffff;
 +/*
 +base background color of selections */
 +@define-color theme_selected_bg_color #1b6acb;
 +/*
 +text/foreground color of selections */
 +@define-color theme_selected_fg_color #ffffff;
 +/*
 +base background color of insensitive widgets */
 +@define-color insensitive_bg_color #fefefd;
 +/*
 +text foreground color of insensitive widgets */
 +@define-color insensitive_fg_color #929495;
 +/*
 +insensitive text widgets and the like base background color */
 +@define-color insensitive_base_color #ffffff;
 +/*
 +widget text/foreground color on backdrop windows */
 +@define-color theme_unfocused_fg_color #929595;
 +/*
 +text color for entries, views and content in general on backdrop windows */
 +@define-color theme_unfocused_text_color black;
 +/*
 +widget base background color on backdrop windows */
 +@define-color theme_unfocused_bg_color #f6f5f4;
 +/*
 +text widgets and the like base background color on backdrop windows */
 +@define-color theme_unfocused_base_color #fcfcfc;
 +/*
 +base background color of selections on backdrop windows */
 +@define-color theme_unfocused_selected_bg_color #1b6acb;
 +/*
 +text/foreground color of selections on backdrop windows */
 +@define-color theme_unfocused_selected_fg_color #ffffff;
 +/*
 +insensitive color on backdrop windows*/
 +@define-color unfocused_insensitive_color #d4cfca;
 +/*
 +widgets main borders color */
 +@define-color borders #877b6e;
 +/*
 +widgets main borders color on backdrop windows */
 +@define-color unfocused_borders #d5d0cc;
 +/*
 +these are pretty self explicative */
 +@define-color warning_color #f57900;
 +@define-color error_color #cc0000;
 +@define-color success_color #33d17a;
 +/*
 +these colors are exported for the window manager and shouldn't be used in applications,
 +read if you used those and something break with a version upgrade you're on your own... */
 +@define-color wm_title shade(#272c2e, 1.8);
 +@define-color wm_unfocused_title #929595;
 +@define-color wm_highlight rgba(255, 255, 255, 0.8);
 +@define-color wm_borders_edge rgba(255, 255, 255, 0.8);
 +@define-color wm_bg_a shade(#fdfdfc, 1.2);
 +@define-color wm_bg_b #fdfdfc;
 +@define-color wm_shadow alpha(black, 0.35);
 +@define-color wm_border alpha(black, 0.18);
 +@define-color wm_button_hover_color_a shade(#fdfdfc, 1.3);
 +@define-color wm_button_hover_color_b #fdfdfc;
 +@define-color wm_button_active_color_a shade(#fdfdfc, 0.85);
 +@define-color wm_button_active_color_b shade(#fdfdfc, 0.89);
 +@define-color wm_button_active_color_c shade(#fdfdfc, 0.9);
 +/* content view background such as thumbnails view in Photos or Boxes */
 +@define-color content_view_bg #ffffff;
 +/* Very contrasty background for text views (@theme_text_color foreground) */
 +@define-color text_view_bg #ffffff;
 +/*************************** Check and Radio buttons * */
 +/*************** Base States * */
 +.background { color: #272c2e; background-color: #fdfdfc; }
 +
 +.background:backdrop { text-shadow: none; -gtk-icon-shadow: none; }
 +
 +dnd { color: #272c2e; }
 +
 +.normal-icons { -gtk-icon-size: 16px; }
 +
 +.large-icons { -gtk-icon-size: 32px; }
 +
 +image:disabled { -gtk-icon-filter: opacity(0.5); }
 +
 +.view, iconview, textview > text { color: black; background-color: #ffffff; }
 +
 +.view:disabled, iconview:disabled, textview > text:disabled { color: #929495; background-color: #fefefd; }
 +
 +.view:selected:focus, iconview:selected:focus, .view:selected, iconview:selected, textview > text:selected:focus, textview > text:selected { border-radius: 3px; }
 +
 +textview:drop(active) { caret-color: #2ec27e; }
 +
 +textview > border { background-color: #fefefe; }
 +
 +iconview { transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +iconview { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +iconview:focus:focus-visible { outline-color: rgba(27, 106, 203, 0.8); outline-width: 2px; outline-offset: -2px; }
 +
 +iconview:drop(active) { box-shadow: none; }
 +
 +iconview > dndtarget:drop(active) { border-style: solid; border-width: 1px; border-color: #124787; }
 +
 +rubberband, .content-view > rubberband, columnview.view > rubberband, treeview.view > rubberband, gridview > rubberband, flowbox > rubberband { border: 1px solid #15539e; background-color: rgba(21, 83, 158, 0.2); }
 +
 +flowbox > flowboxchild { padding: 3px; transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +flowbox > flowboxchild { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +flowbox > flowboxchild:focus:focus-visible { outline-color: rgba(27, 106, 203, 0.8); outline-width: 2px; outline-offset: -2px; }
 +
 +flowbox > flowboxchild:selected { outline-color: white; }
 +
 +gridview > child { padding: 3px; transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +gridview > child { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +gridview > child:focus:focus-visible { outline-color: rgba(27, 106, 203, 0.8); outline-width: 2px; outline-offset: -2px; }
 +
 +gridview > child:selected { outline-color: white; }
 +
 +gridview > child box { border-spacing: 8px; margin: 12px; }
 +
 +coverflow cover { color: black; background-color: #ffffff; border: 1px solid black; }
 +
 +label { transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +label { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +label:focus:focus-visible { outline-color: rgba(27, 106, 203, 0.8); outline-width: 2px; outline-offset: -2px; }
 +
 +label > selection { background-color: #1b6acb; color: #ffffff; }
 +
 +label:disabled { color: #929495; }
 +
 +button label:disabled { color: inherit; }
 +
 +label.error { color: #cc0000; }
 +
 +label.error:disabled { color: rgba(204, 0, 0, 0.5); }
 +
 +.dim-label, .titlebar:not(headerbar) .subtitle, headerbar .subtitle, spinbutton.vertical > text > text > placeholder, spinbutton:not(.vertical) > text > placeholder, entry > text > placeholder, label.separator { opacity: 0.9; text-shadow: none; }
 +
 +window.assistant .sidebar { padding: 5px; border-top: 1px solid #877b6e; }
 +
 +window.assistant.csd .sidebar { border-top-style: none; }
 +
 +window.assistant .sidebar > label { padding: 6px 12px; }
 +
 +window.assistant .sidebar > label.highlight { background-color: #e6e3e0; border-radius: 5px; }
 +
 +window.aboutdialog image.large-icons { -gtk-icon-size: 128px; }
 +
 +.osd .scale-popup, .app-notification, .osd popover.background > arrow, .osd popover.background > contents, popover.background.touch-selection > arrow, popover.background.touch-selection > contents, popover.background.magnifier > arrow, popover.background.magnifier > contents, .osd { color: #eeeeec; border: none; background-color: rgba(53, 53, 53, 0.7); background-clip: padding-box; -gtk-icon-shadow: 0 1px black; }
 +
 +/********************* Spinner Animation * */
 +@keyframes spin { to { transform: rotate(1turn); } }
 +
 +spinner { background: none; opacity: 0; -gtk-icon-source: -gtk-icontheme("process-working-symbolic"); }
 +
 +spinner:checked { opacity: 1; animation: spin 1s linear infinite; }
 +
 +spinner:checked:disabled { opacity: 0.5; }
 +
 +/********************** General Typography * */
 +.large-title { font-weight: 300; font-size: 24pt; }
 +
 +.title-1 { font-weight: 800; font-size: 20pt; }
 +
 +.title-2 { font-weight: 800; font-size: 15pt; }
 +
 +.title-3 { font-weight: 700; font-size: 15pt; }
 +
 +.title-4 { font-weight: 700; font-size: 13pt; }
 +
 +.heading { font-weight: 700; font-size: 11pt; }
 +
 +.body { font-weight: 400; font-size: 11pt; }
 +
 +.caption-heading { font-weight: 700; font-size: 9pt; }
 +
 +.caption { font-weight: 400; font-size: 9pt; }
 +
 +/**************** Text Entries * */
 +spinbutton.vertical > text, spinbutton:not(.vertical), entry { min-height: 32px; padding-left: 8px; padding-right: 8px; border: 1px solid; border-radius: 5px; border-spacing: 6px; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); color: black; border-color: #877b6e; background-color: #ffffff; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +spinbutton.vertical > text, spinbutton:not(.vertical), entry { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +spinbutton.vertical > text:focus-within, spinbutton:focus-within:not(.vertical), entry:focus-within { outline-color: rgba(27, 106, 203, 0.8); outline-width: 2px; outline-offset: -2px; }
 +
 +spinbutton.vertical > text > image.left, spinbutton:not(.vertical) > image.left, entry > image.left { margin-right: 6px; }
 +
 +spinbutton.vertical > text > image.right, spinbutton:not(.vertical) > image.right, entry > image.right { margin-left: 6px; }
 +
 +spinbutton.vertical > text > text > block-cursor, spinbutton:not(.vertical) > text > block-cursor, entry > text > block-cursor { color: #ffffff; background-color: black; }
 +
 +spinbutton.vertical > text.flat, spinbutton.flat:not(.vertical), entry.flat:focus-within, entry.flat:backdrop, entry.flat:disabled, entry.flat { min-height: 0; padding: 2px; background-color: transparent; border-color: transparent; border-radius: 0; }
 +
 +spinbutton.vertical > text:focus-within > placeholder, spinbutton:focus-within:not(.vertical) > placeholder, entry:focus-within > placeholder { opacity: 0; /* We hide placeholders on focus */ }
 +
 +spinbutton.vertical > text:disabled, spinbutton:disabled:not(.vertical), entry:disabled { color: #929495; border-color: #877b6e; background-color: #fefefd; }
 +
 +spinbutton.vertical > text.error, spinbutton.error:not(.vertical), entry.error { color: #cc0000; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +spinbutton.vertical > text.error, spinbutton.error:not(.vertical), entry.error { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +spinbutton.vertical > text.error:focus-within, spinbutton.error:focus-within:not(.vertical), entry.error:focus-within { outline-color: rgba(204, 0, 0, 0.5); outline-width: 2px; outline-offset: -2px; }
 +
 +spinbutton.vertical > text.error > selection, spinbutton.error:not(.vertical) > selection, entry.error > selection { background-color: #cc0000; }
 +
 +spinbutton.vertical > text.warning, spinbutton.warning:not(.vertical), entry.warning { color: #f57900; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +spinbutton.vertical > text.warning, spinbutton.warning:not(.vertical), entry.warning { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +spinbutton.vertical > text.warning:focus-within, spinbutton.warning:focus-within:not(.vertical), entry.warning:focus-within { outline-color: rgba(245, 121, 0, 0.5); outline-width: 2px; outline-offset: -2px; }
 +
 +spinbutton.vertical > text.warning > selection, spinbutton.warning:not(.vertical) > selection, entry.warning > selection { background-color: #f57900; }
 +
 +spinbutton.vertical > text > image, spinbutton:not(.vertical) > image, entry > image { color: #525658; }
 +
 +spinbutton.vertical > text > image:hover, spinbutton:not(.vertical) > image:hover, entry > image:hover { color: #272c2e; }
 +
 +spinbutton.vertical > text > image:active, spinbutton:not(.vertical) > image:active, entry > image:active { color: #1b6acb; }
 +
 +spinbutton.vertical > text.password image.caps-lock-indicator, spinbutton.password:not(.vertical) image.caps-lock-indicator, entry.password image.caps-lock-indicator { color: #a7aaaa; }
 +
 +spinbutton.vertical > text:drop(active), spinbutton:drop(active):not(.vertical), entry:drop(active):focus-within, entry:drop(active) { border-color: #2ec27e; box-shadow: inset 0 0 0 1px #2ec27e; }
 +
 +.osd spinbutton.vertical > text, .osd spinbutton:not(.vertical), .osd entry { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: rgba(0, 0, 0, 0.5); background-clip: padding-box; box-shadow: none; -gtk-icon-shadow: 0 1px black; }
 +
 +.osd spinbutton.vertical > text:focus-within, .osd spinbutton:focus-within:not(.vertical), .osd entry:focus-within { color: white; border-color: #1b6acb; background-color: rgba(0, 0, 0, 0.5); background-clip: padding-box; }
 +
 +.osd spinbutton.vertical > text:disabled, .osd spinbutton:disabled:not(.vertical), .osd entry:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: rgba(71, 71, 71, 0.5); background-clip: padding-box; }
 +
 +spinbutton.vertical > text > progress, spinbutton:not(.vertical) > progress, entry > progress { margin-bottom: 2px; }
 +
 +spinbutton.vertical > text progress > trough > progress, spinbutton:not(.vertical) progress > trough > progress, entry progress > trough > progress { background-color: transparent; background-image: none; border-radius: 0; border-width: 0 0 2px; border-color: #1b6acb; border-style: solid; box-shadow: none; }
 +
 +spinbutton.vertical.linked:not(.vertical) > text:drop(active) + text, spinbutton.vertical.linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + text, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + spinbutton:not(.vertical), .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + spinbutton:not(.vertical), spinbutton.vertical.linked:not(.vertical) > text:drop(active) + button, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + button, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + menubutton > button, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + menubutton > button, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + dropdown > button, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + dropdown > button, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + colorbutton > button, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + colorbutton > button, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + fontbutton > button, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + fontbutton > button, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + filechooserbutton > button, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + filechooserbutton > button, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + combobox > box > button.combo, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + combobox > box > button.combo, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + entry, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + entry, .linked:not(.vertical) > entry:drop(active) + button, .linked:not(.vertical) > entry:drop(active) + menubutton > button, .linked:not(.vertical) > entry:drop(active) + dropdown > button, .linked:not(.vertical) > entry:drop(active) + colorbutton > button, .linked:not(.vertical) > entry:drop(active) + fontbutton > button, .linked:not(.vertical) > entry:drop(active) + filechooserbutton > button, .linked:not(.vertical) > entry:drop(active) + combobox > box > button.combo, spinbutton.vertical.linked:not(.vertical) > entry:drop(active) + text, .linked:not(.vertical) > entry:drop(active) + spinbutton:not(.vertical), .linked:not(.vertical) > entry:drop(active) + entry { border-left-color: #2ec27e; }
 +
 +spinbutton.vertical.linked > text:not(:disabled) + entry:not(:disabled), .linked.vertical > spinbutton:not(:disabled):not(.vertical) + entry:not(:disabled), spinbutton.vertical.linked > text:not(:disabled) + text:not(:disabled), spinbutton.vertical.linked > spinbutton:not(:disabled):not(.vertical) + text:not(:disabled), spinbutton.vertical.linked > text:not(:disabled) + spinbutton:not(:disabled):not(.vertical), .linked.vertical > spinbutton:not(:disabled):not(.vertical) + spinbutton:not(:disabled):not(.vertical), .linked.vertical > entry:not(:disabled) + entry:not(:disabled), spinbutton.vertical.linked > entry:not(:disabled) + text:not(:disabled), .linked.vertical > entry:not(:disabled) + spinbutton:not(:disabled):not(.vertical) { border-top-color: #dbd7d4; }
 +
 +spinbutton.vertical.linked > text:disabled + text:disabled, spinbutton.vertical.linked > spinbutton:disabled:not(.vertical) + text:disabled, spinbutton.vertical.linked > text:disabled + spinbutton:disabled:not(.vertical), .linked.vertical > spinbutton:disabled:not(.vertical) + spinbutton:disabled:not(.vertical), spinbutton.vertical.linked > text:disabled + entry:disabled, .linked.vertical > spinbutton:disabled:not(.vertical) + entry:disabled, spinbutton.vertical.linked > entry:disabled + text:disabled, .linked.vertical > entry:disabled + spinbutton:disabled:not(.vertical), .linked.vertical > entry:disabled + entry:disabled { border-top-color: #dbd7d4; }
 +
 +spinbutton.vertical.linked > text + text:drop(active):not(:only-child), spinbutton.vertical.linked > spinbutton:not(.vertical) + text:drop(active):not(:only-child), spinbutton.vertical.linked > text + spinbutton:drop(active):not(:only-child):not(.vertical), .linked.vertical > spinbutton:not(.vertical) + spinbutton:drop(active):not(:only-child):not(.vertical), spinbutton.vertical.linked > text + entry:drop(active):not(:only-child), .linked.vertical > spinbutton:not(.vertical) + entry:drop(active):not(:only-child), spinbutton.vertical.linked > entry + text:drop(active):not(:only-child), .linked.vertical > entry + spinbutton:drop(active):not(:only-child):not(.vertical), .linked.vertical > entry + entry:drop(active):not(:only-child) { border-top-color: #2ec27e; }
 +
 +spinbutton.vertical.linked > text:drop(active):not(:only-child) + text, spinbutton.vertical.linked > spinbutton:drop(active):not(:only-child):not(.vertical) + text, spinbutton.vertical.linked > text:drop(active):not(:only-child) + spinbutton:not(.vertical), .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + spinbutton:not(.vertical), spinbutton.vertical.linked > text:drop(active):not(:only-child) + entry, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + entry, spinbutton.vertical.linked > text:drop(active):not(:only-child) + button, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + button, spinbutton.vertical.linked > text:drop(active):not(:only-child) + menubutton > button, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + menubutton > button, spinbutton.vertical.linked > text:drop(active):not(:only-child) + dropdown > button, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + dropdown > button, spinbutton.vertical.linked > text:drop(active):not(:only-child) + colorbutton > button, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + colorbutton > button, spinbutton.vertical.linked > text:drop(active):not(:only-child) + fontbutton > button, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + fontbutton > button, spinbutton.vertical.linked > text:drop(active):not(:only-child) + filechooserbutton > button, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + filechooserbutton > button, spinbutton.vertical.linked > text:drop(active):not(:only-child) + combobox > box > button.combo, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + combobox > box > button.combo, spinbutton.vertical.linked > entry:drop(active):not(:only-child) + text, .linked.vertical > entry:drop(active):not(:only-child) + spinbutton:not(.vertical), .linked.vertical > entry:drop(active):not(:only-child) + entry, .linked.vertical > entry:drop(active):not(:only-child) + button, .linked.vertical > entry:drop(active):not(:only-child) + menubutton > button, .linked.vertical > entry:drop(active):not(:only-child) + dropdown > button, .linked.vertical > entry:drop(active):not(:only-child) + colorbutton > button, .linked.vertical > entry:drop(active):not(:only-child) + fontbutton > button, .linked.vertical > entry:drop(active):not(:only-child) + filechooserbutton > button, .linked.vertical > entry:drop(active):not(:only-child) + combobox > box > button.combo { border-top-color: #2ec27e; }
 +
 +spinbutton.vertical > text.error, spinbutton.error:not(.vertical), entry.error { color: #cc0000; }
 +
 +treeview entry:focus-within:dir(rtl), treeview entry:focus-within:dir(ltr) { background-color: #ffffff; transition-property: color, background; }
 +
 +treeview entry.flat, treeview entry { border-radius: 0; background-image: none; background-color: #ffffff; }
 +
 +treeview entry.flat:focus-within, treeview entry:focus-within { border-color: #1b6acb; }
 +
 +/******************* Editable Labels * */
 +editablelabel > stack > text { color: black; border-color: #877b6e; background-color: #ffffff; }
 +
 +/*********** Buttons * */
 +@keyframes needs_attention { from { background-image: radial-gradient(farthest-side, #1b6acb 0%, rgba(27, 106, 203, 0) 0%); }
 +  to { background-image: radial-gradient(farthest-side, #1b6acb 95%, rgba(27, 106, 203, 0)); } }
 +
 +notebook > header > tabs > arrow, windowcontrols button, button { min-height: 24px; min-width: 16px; padding: 4px 9px; border: 1px solid; border-radius: 5px; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); color: #272c2e; outline-color: rgba(27, 106, 203, 0.8); border-color: #877b6e; background-image: linear-gradient(to top, #fafaf9 2px, white); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +notebook > header > tabs > arrow, windowcontrols button, button { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +notebook > header > tabs > arrow:focus:focus-visible, button:focus:focus-visible { outline-color: rgba(27, 106, 203, 0.8); outline-width: 2px; outline-offset: -2px; }
 +
 +notebook > header > tabs > arrow:hover, button:hover { color: #272c2e; border-color: #877b6e; background-image: linear-gradient(to top, #dad6d2, #edebe9 1px); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); -gtk-icon-filter: brightness(1.2); }
 +
 +notebook > header > tabs > arrow.keyboard-activating, notebook > header > tabs > arrow:active, notebook > header > tabs > arrow:checked, button.keyboard-activating, button:active, button:checked { color: #272c2e; border-color: #877b6e; background-image: image(#dfdbd8); box-shadow: none; transition-duration: 50ms; }
 +
 +notebook > header > tabs > arrow:checked:hover, button:checked:hover { color: #272c2e; border-color: #877b6e; background-image: image(#d6d1cd); box-shadow: none; }
 +
 +notebook > header > tabs > arrow:checked:active, button:checked:active { color: #272c2e; border-color: #877b6e; background-image: image(#cdc7c1); box-shadow: none; }
 +
 +notebook > header > tabs > arrow:backdrop, button.flat:backdrop, button:backdrop { color: #929595; border-color: #d5d0cc; background-image: image(#f6f5f4); box-shadow: none; transition: 200ms ease-out; }
 +
 +notebook > header > tabs > arrow:backdrop:not(:disabled), button.flat:backdrop:not(:disabled), button:backdrop:not(:disabled) { -gtk-icon-filter: none; }
 +
 +notebook > header > tabs > arrow:backdrop:active, notebook > header > tabs > arrow:backdrop:checked, button.flat:backdrop:active, button.flat:backdrop:checked, button:backdrop:active, button:backdrop:checked { color: #929595; border-color: #d5d0cc; background-image: image(#ebebeb); box-shadow: none; }
 +
 +notebook > header > tabs > arrow:backdrop:disabled, button.flat:backdrop:disabled, button:backdrop:disabled { color: #d4cfca; border-color: #d5d0cc; background-image: image(#fefefd); box-shadow: none; }
 +
 +notebook > header > tabs > arrow:backdrop:disabled:active, notebook > header > tabs > arrow:backdrop:disabled:checked, button.flat:backdrop:disabled:active, button.flat:backdrop:disabled:checked, button:backdrop:disabled:active, button:backdrop:disabled:checked { color: #d4cfca; border-color: #d5d0cc; background-image: image(#ebebeb); box-shadow: none; }
 +
 +notebook > header > tabs > arrow:disabled, button:disabled { color: #929495; border-color: #9e958b; background-image: image(#fefefd); -gtk-icon-filter: opacity(0.5); }
 +
 +notebook > header > tabs > arrow:disabled:active, notebook > header > tabs > arrow:disabled:checked, button:disabled:active, button:disabled:checked { color: #929495; border-color: #9e958b; background-image: image(#ebebeb); box-shadow: none; }
 +
- button.sidebar-button:hover, notebook > header > tabs > arrow:hover, windowcontrols button:hover, button.flat:hover { border-color: transparent; background-image: none; box-shadow: none; background-color: #dfdbd8; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-duration: 500ms; }
++button.sidebar-button, notebook > header > tabs > arrow, windowcontrols button, .toolbar button, notebook > header > tabs > arrow.flat, button.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; transition: none; }
 +
- button.keyboard-activating.sidebar-button, notebook > header > tabs > arrow.keyboard-activating, windowcontrols button.keyboard-activating, button.sidebar-button:active, notebook > header > tabs > arrow:active, windowcontrols button:active, button.sidebar-button:checked, notebook > header > tabs > arrow:checked, windowcontrols button:checked, button.flat.keyboard-activating, button.flat:active, button.flat:checked { border-color: transparent; background-image: none; box-shadow: none; background-color: #d1ccc7; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
++button.sidebar-button:hover, notebook > header > tabs > arrow:hover, windowcontrols button:hover, .toolbar button:hover, button.flat:hover { border-color: transparent; background-image: none; box-shadow: none; background-color: #dfdbd8; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-duration: 500ms; }
 +
- button.sidebar-button:backdrop, notebook > header > tabs > arrow:backdrop, windowcontrols button:backdrop, button.sidebar-button:disabled, notebook > header > tabs > arrow:disabled, windowcontrols button:disabled, button.flat:backdrop, button.flat:disabled, button.flat:backdrop:disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; }
++button.keyboard-activating.sidebar-button, notebook > header > tabs > arrow.keyboard-activating, windowcontrols button.keyboard-activating, .toolbar button.keyboard-activating, button.sidebar-button:active, notebook > header > tabs > arrow:active, windowcontrols button:active, .toolbar button:active, button.sidebar-button:checked, notebook > header > tabs > arrow:checked, windowcontrols button:checked, .toolbar button:checked, button.flat.keyboard-activating, button.flat:active, button.flat:checked { border-color: transparent; background-image: none; box-shadow: none; background-color: #d1ccc7; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
 +
- .scale-popup button:hover, button.link, button.link:hover, button.link:active, button.link:checked, popover.menu box.circular-buttons button.circular.image-button.model, list > row button.image-button:not(.flat), .toolbar button, modelbutton.flat { background-color: transparent; background-image: none; border-color: transparent; box-shadow: inset 0 1px rgba(255, 255, 255, 0), 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
++button.sidebar-button:backdrop, notebook > header > tabs > arrow:backdrop, windowcontrols button:backdrop, .toolbar button:backdrop, button.sidebar-button:disabled, notebook > header > tabs > arrow:disabled, windowcontrols button:disabled, .toolbar button:disabled, button.flat:backdrop, button.flat:disabled, button.flat:backdrop:disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; }
 +
 +notebook > header > tabs > arrow.image-button, button.image-button { min-width: 24px; padding-left: 5px; padding-right: 5px; }
 +
 +notebook > header > tabs > arrow.text-button, button.text-button { padding-left: 16px; padding-right: 16px; }
 +
 +notebook > header > tabs > arrow.text-button.image-button, button.text-button.image-button { padding-left: 8px; padding-right: 8px; }
 +
 +notebook > header > tabs > arrow.text-button.image-button label, button.text-button.image-button label { padding-left: 8px; padding-right: 8px; }
 +
 +dropdown:drop(active) button.combo, combobox:drop(active) button.combo, notebook > header > tabs > arrow:drop(active), button:drop(active) { color: #2ec27e; border-color: #2ec27e; box-shadow: inset 0 0 0 1px #2ec27e; }
 +
 +row:selected button { border-color: #124787; }
 +
 +row:selected button.sidebar-button:not(:active):not(:checked):not(:hover):not(disabled), row:selected button.flat:not(:active):not(:checked):not(:hover):not(disabled) { color: #ffffff; border-color: transparent; }
 +
 +row:selected button.sidebar-button:not(:active):not(:checked):not(:hover):not(disabled):backdrop, row:selected button.flat:not(:active):not(:checked):not(:hover):not(disabled):backdrop { color: #fcfcfc; }
 +
 +button.osd { min-width: 26px; min-height: 32px; color: #eeeeec; border-radius: 5px; color: #eeeeec; outline-color: rgba(27, 106, 203, 0.8); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; border: none; box-shadow: none; }
 +
 +button.osd.image-button { min-width: 30px; }
 +
 +button.osd.image-button:only-child { margin: 4px; border-radius: 50%; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); }
 +
 +button.osd:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(27, 27, 27, 0.7)); background-clip: padding-box; border: none; box-shadow: none; }
 +
 +button.osd:active, button.osd:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(2, 2, 2, 0.7)); background-clip: padding-box; box-shadow: none; border: none; box-shadow: none; }
 +
 +.app-notification button, popover.background.touch-selection button, popover.background.magnifier button, .osd button { color: #eeeeec; outline-color: rgba(27, 106, 203, 0.8); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; }
 +
 +.app-notification button:hover, popover.background.touch-selection button:hover, popover.background.magnifier button:hover, .osd button:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(27, 27, 27, 0.7)); background-clip: padding-box; }
 +
 +.app-notification button:active, popover.background.touch-selection button:active, popover.background.magnifier button:active, .app-notification button:checked, popover.background.touch-selection button:checked, popover.background.magnifier button:checked, .osd button:active:backdrop, .osd button:active, .osd button:checked:backdrop, .osd button:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(2, 2, 2, 0.7)); background-clip: padding-box; box-shadow: none; }
 +
 +.app-notification button:disabled, popover.background.touch-selection button:disabled, popover.background.magnifier button:disabled, .osd button:disabled:backdrop, .osd button:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; }
 +
 +.app-notification button.flat, popover.background.touch-selection button.flat, popover.background.magnifier button.flat, .osd button.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; box-shadow: none; -gtk-icon-shadow: 0 1px black; }
 +
 +.app-notification button.flat:hover, popover.background.touch-selection button.flat:hover, popover.background.magnifier button.flat:hover, .osd button.flat:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(27, 27, 27, 0.7)); background-clip: padding-box; }
 +
 +.app-notification button.flat:disabled, popover.background.touch-selection button.flat:disabled, popover.background.magnifier button.flat:disabled, .osd button.flat:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; background-image: none; border-color: transparent; box-shadow: none; }
 +
 +.app-notification button.flat:active, popover.background.touch-selection button.flat:active, popover.background.magnifier button.flat:active, .app-notification button.flat:checked, popover.background.touch-selection button.flat:checked, popover.background.magnifier button.flat:checked, .osd button.flat:active, .osd button.flat:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(2, 2, 2, 0.7)); background-clip: padding-box; box-shadow: none; }
 +
 +button.suggested-action { color: white; outline-color: white; border-color: #0f3b71; background-image: linear-gradient(to top, #1a66c2 2px, #1b6acb); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +button.suggested-action { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +button.suggested-action:focus:focus-visible { outline-color: white; outline-width: 2px; outline-offset: -2px; }
 +
 +button.suggested-action.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: #1b6acb; }
 +
 +button.suggested-action:hover { color: white; border-color: #124787; background-image: linear-gradient(to top, #114583, #1658a7 1px); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +button.suggested-action:active, button.suggested-action:checked { color: white; border-color: #124787; background-image: image(#13498c); box-shadow: none; }
 +
 +button.suggested-action.flat:disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: rgba(27, 106, 203, 0.8); }
 +
 +button.suggested-action:disabled { color: #929495; border-color: #9e958b; background-image: image(#fefefd); }
 +
 +button.suggested-action:disabled:active, button.suggested-action:disabled:checked { color: #aac5e4; border-color: #124787; background-image: image(#2b6dbc); box-shadow: none; }
 +
 +.osd button.suggested-action { color: #eeeeec; outline-color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(27, 106, 203, 0.5)); background-clip: padding-box; }
 +
 +.osd button.suggested-action:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(27, 106, 203, 0.7)); background-clip: padding-box; }
 +
 +.osd button.suggested-action:active:backdrop, .osd button.suggested-action:active, .osd button.suggested-action:checked:backdrop, .osd button.suggested-action:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(#1b6acb); background-clip: padding-box; box-shadow: none; }
 +
 +.osd button.suggested-action:disabled:backdrop, .osd button.suggested-action:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; }
 +
 +button.destructive-action { color: white; outline-color: white; border-color: #851015; background-image: linear-gradient(to top, #d71a23 2px, #e01b24); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +button.destructive-action { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +button.destructive-action:focus:focus-visible { outline-color: white; outline-width: 2px; outline-offset: -2px; }
 +
 +button.destructive-action.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: #e01b24; }
 +
 +button.destructive-action:hover { color: white; border-color: #9c1319; background-image: linear-gradient(to top, #971218, #bc171e 1px); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +button.destructive-action:active, button.destructive-action:checked { color: white; border-color: #9c1319; background-image: image(#a0131a); box-shadow: none; }
 +
 +button.destructive-action.flat:disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: rgba(224, 27, 36, 0.8); }
 +
 +button.destructive-action:disabled { color: #929495; border-color: #9e958b; background-image: image(#fefefd); }
 +
 +button.destructive-action:disabled:active, button.destructive-action:disabled:checked { color: #f1a5a8; border-color: #9c1319; background-image: image(#dc1d27); box-shadow: none; }
 +
 +.osd button.destructive-action { color: #eeeeec; outline-color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(224, 27, 36, 0.5)); background-clip: padding-box; }
 +
 +.osd button.destructive-action:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(224, 27, 36, 0.7)); background-clip: padding-box; }
 +
 +.osd button.destructive-action:active:backdrop, .osd button.destructive-action:active, .osd button.destructive-action:checked:backdrop, .osd button.destructive-action:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(#e01b24); background-clip: padding-box; box-shadow: none; }
 +
 +.osd button.destructive-action:disabled:backdrop, .osd button.destructive-action:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; }
 +
 +stackswitcher > button > label { padding: 0 6px; margin: 0 -6px; }
 +
 +stackswitcher > button > image { padding: 3px 6px; margin: -3px -6px; }
 +
 +button.font separator { background-color: transparent; }
 +
 +button.font > box { border-spacing: 6px; }
 +
 +button.font > box > box > label { font-weight: bold; }
 +
 +menubutton.circular button, button.circular { min-width: 32px; min-height: 32px; padding: 0; border-radius: 9999px; }
 +
 +menubutton.circular button label, button.circular label { padding: 0; }
 +
 +stacksidebar row.needs-attention > label, stackswitcher > button.needs-attention > label, stackswitcher > button.needs-attention > image { animation: needs_attention 150ms ease-in; background-image: radial-gradient(farthest-side, #1b6acb 96%, rgba(27, 106, 203, 0)); background-size: 6px 6px, 6px 6px; background-repeat: no-repeat; background-position: right 3px, right 4px; }
 +
 +stacksidebar row.needs-attention > label:backdrop, stackswitcher > button.needs-attention > label:backdrop, stackswitcher > button.needs-attention > image:backdrop { background-size: 6px 6px, 0 0; }
 +
 +stacksidebar row.needs-attention > label:dir(rtl), stackswitcher > button.needs-attention > label:dir(rtl), stackswitcher > button.needs-attention > image:dir(rtl) { background-position: left 3px, left 4px; }
 +
 +.linked:not(.vertical) > filechooserbutton > combobox:dir(rtl):not(:last-child) > box > button.combo, .linked:not(.vertical) > appchooserbutton > combobox:dir(rtl):not(:last-child) > box > button.combo, .linked:not(.vertical) > combobox:dir(rtl):not(:last-child) > box > button.combo, .linked:not(.vertical) > filechooserbutton > combobox:dir(ltr):not(:first-child) > box > button.combo, .linked:not(.vertical) > appchooserbutton > combobox:dir(ltr):not(:first-child) > box > button.combo, .linked:not(.vertical) > combobox:dir(ltr):not(:first-child) > box > button.combo, dropdown.linked button:nth-child(2):dir(ltr), combobox.linked button:nth-child(2):dir(ltr), .linked:not(.vertical) > menubutton:dir(rtl):not(:last-child) > button, .linked:not(.vertical) > dropdown:dir(rtl):not(:last-child) > button, .linked:not(.vertical) > colorbutton:dir(rtl):not(:last-child) > button, .linked:not(.vertical) > fontbutton:dir(rtl):not(:last-child) > button, .linked:not(.vertical) > filechooserbutton:dir(rtl):not(:last-child) > button, .linked:not(.vertical) > menubutton:dir(ltr):not(:first-child) > button, .linked:not(.vertical) > dropdown:dir(ltr):not(:first-child) > button, .linked:not(.vertical) > colorbutton:dir(ltr):not(:first-child) > button, .linked:not(.vertical) > fontbutton:dir(ltr):not(:first-child) > button, .linked:not(.vertical) > filechooserbutton:dir(ltr):not(:first-child) > button, spinbutton.vertical.linked:not(.vertical) > text:dir(rtl):not(:last-child), .linked:not(.vertical) > spinbutton:dir(rtl):not(:last-child):not(.vertical), .linked:not(.vertical) > entry:dir(rtl):not(:last-child), .linked:not(.vertical) > button:dir(rtl):not(:last-child), spinbutton.vertical.linked:not(.vertical) > text:dir(ltr):not(:first-child), .linked:not(.vertical) > spinbutton:dir(ltr):not(:first-child):not(.vertical), .linked:not(.vertical) > entry:dir(ltr):not(:first-child), .linked:not(.vertical) > button:dir(ltr):not(:first-child) { border-top-left-radius: 0; border-bottom-left-radius: 0; }
 +
 +.linked:not(.vertical) > filechooserbutton > combobox:dir(rtl):not(:first-child) > box > button.combo, .linked:not(.vertical) > appchooserbutton > combobox:dir(rtl):not(:first-child) > box > button.combo, .linked:not(.vertical) > combobox:dir(rtl):not(:first-child) > box > button.combo, .linked:not(.vertical) > filechooserbutton > combobox:dir(ltr):not(:last-child) > box > button.combo, .linked:not(.vertical) > appchooserbutton > combobox:dir(ltr):not(:last-child) > box > button.combo, .linked:not(.vertical) > combobox:dir(ltr):not(:last-child) > box > button.combo, dropdown.linked button:nth-child(2):dir(rtl), combobox.linked button:nth-child(2):dir(rtl), .linked:not(.vertical) > menubutton:dir(rtl):not(:first-child) > button, .linked:not(.vertical) > dropdown:dir(rtl):not(:first-child) > button, .linked:not(.vertical) > colorbutton:dir(rtl):not(:first-child) > button, .linked:not(.vertical) > fontbutton:dir(rtl):not(:first-child) > button, .linked:not(.vertical) > filechooserbutton:dir(rtl):not(:first-child) > button, .linked:not(.vertical) > menubutton:dir(ltr):not(:last-child) > button, .linked:not(.vertical) > dropdown:dir(ltr):not(:last-child) > button, .linked:not(.vertical) > colorbutton:dir(ltr):not(:last-child) > button, .linked:not(.vertical) > fontbutton:dir(ltr):not(:last-child) > button, .linked:not(.vertical) > filechooserbutton:dir(ltr):not(:last-child) > button, spinbutton.vertical.linked:not(.vertical) > text:dir(rtl):not(:first-child), .linked:not(.vertical) > spinbutton:dir(rtl):not(:first-child):not(.vertical), .linked:not(.vertical) > entry:dir(rtl):not(:first-child), .linked:not(.vertical) > button:dir(rtl):not(:first-child), spinbutton.vertical.linked:not(.vertical) > text:dir(ltr):not(:last-child), .linked:not(.vertical) > spinbutton:dir(ltr):not(:last-child):not(.vertical), .linked:not(.vertical) > entry:dir(ltr):not(:last-child), .linked:not(.vertical) > button:dir(ltr):not(:last-child) { border-right-style: none; border-top-right-radius: 0; border-bottom-right-radius: 0; }
 +
 +.linked.vertical > filechooserbutton > combobox:not(:first-child) > box > button.combo, .linked.vertical > appchooserbutton > combobox:not(:first-child) > box > button.combo, .linked.vertical > combobox:not(:first-child) > box > button.combo, .linked.vertical > menubutton:not(:first-child) > button, .linked.vertical > dropdown:not(:first-child) > button, .linked.vertical > colorbutton:not(:first-child) > button, .linked.vertical > fontbutton:not(:first-child) > button, .linked.vertical > filechooserbutton:not(:first-child) > button, spinbutton.vertical.linked > text:not(:first-child), .linked.vertical > spinbutton:not(:first-child):not(.vertical), .linked.vertical > entry:not(:first-child), .linked.vertical > button:not(:first-child) { border-top-left-radius: 0; border-top-right-radius: 0; }
 +
 +.linked.vertical > filechooserbutton > combobox:not(:last-child) > box > button.combo, .linked.vertical > appchooserbutton > combobox:not(:last-child) > box > button.combo, .linked.vertical > combobox:not(:last-child) > box > button.combo, .linked.vertical > menubutton:not(:last-child) > button, .linked.vertical > dropdown:not(:last-child) > button, .linked.vertical > colorbutton:not(:last-child) > button, .linked.vertical > fontbutton:not(:last-child) > button, .linked.vertical > filechooserbutton:not(:last-child) > button, spinbutton.vertical.linked > text:not(:last-child), .linked.vertical > spinbutton:not(:last-child):not(.vertical), .linked.vertical > entry:not(:last-child), .linked.vertical > button:not(:last-child) { border-bottom-style: none; border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
 +
- .toolbar button:hover { color: #272c2e; border-color: #877b6e; background-image: linear-gradient(to top, #dad6d2, #edebe9 1px); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
- .toolbar button:active { color: #272c2e; border-color: #877b6e; background-image: image(#dfdbd8); box-shadow: none; }
- .toolbar button:disabled { color: #929495; border-color: #9e958b; background-image: image(#fefefd); }
- .toolbar button:backdrop { color: #929595; border-color: #d5d0cc; background-image: image(#f6f5f4); box-shadow: none; }
- .toolbar button:backdrop:disabled { color: #d4cfca; border-color: #d5d0cc; background-image: image(#fefefd); box-shadow: none; }
++.scale-popup button:hover, button.link, button.link:hover, button.link:active, button.link:checked, popover.menu box.circular-buttons button.circular.image-button.model, list > row button.image-button:not(.flat), modelbutton.flat { background-color: transparent; background-image: none; border-color: transparent; box-shadow: inset 0 1px rgba(255, 255, 255, 0), 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
 +
 +/* menu buttons */
 +modelbutton.flat { min-height: 26px; padding-left: 5px; padding-right: 5px; border-radius: 5px; }
 +
 +modelbutton.flat:hover { background-color: #e6e3e0; }
 +
 +modelbutton.flat:disabled { color: #929495; }
 +
 +modelbutton.flat arrow { background: none; min-width: 16px; min-height: 16px; opacity: 0.3; }
 +
 +modelbutton.flat arrow:hover { background: none; }
 +
 +modelbutton.flat arrow.left { -gtk-icon-source: -gtk-icontheme("go-previous-symbolic"); }
 +
 +modelbutton.flat arrow.right { -gtk-icon-source: -gtk-icontheme("go-next-symbolic"); }
 +
 +/* oldstyle toolbar buttons */
 +.toolbar button { margin: 1px; }
 +
 +button.color { padding: 4px; }
 +
 +button.color > colorswatch:only-child { box-shadow: 0 1px rgba(0, 0, 0, 0.1); }
 +
 +button.color > colorswatch:only-child, button.color > colorswatch:only-child > overlay { border-radius: 0; }
 +
 +.osd button.color > colorswatch:only-child { box-shadow: none; }
 +
 +.osd button.color:disabled colorswatch:only-child, .osd button.color:active colorswatch:only-child, .osd button.color:checked colorswatch:only-child, button.color:disabled colorswatch:only-child, button.color:active colorswatch:only-child, button.color:checked colorswatch:only-child { box-shadow: none; }
 +
 +/* list buttons */
 +/* tone down as per new designs, see issue #1473 */
 +popover.menu box.circular-buttons button.circular.image-button.model, list > row button.image-button:not(.flat) { border: 1px solid rgba(135, 123, 110, 0.5); }
 +
 +popover.menu box.circular-buttons button.circular.image-button.model:hover, list > row button.image-button:not(.flat):hover { color: #272c2e; border-color: #877b6e; background-image: linear-gradient(to top, #dad6d2, #edebe9 1px); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +popover.menu box.circular-buttons button.circular.image-button.model:active, popover.menu box.circular-buttons button.circular.image-button.model:checked, list > row button.image-button:not(.flat):active, list > row button.image-button:not(.flat):checked { color: #272c2e; border-color: #877b6e; background-image: image(#dfdbd8); box-shadow: none; }
 +
 +popover.menu box.circular-buttons button.suggested-action.circular.image-button.model, list > row button.image-button.suggested-action:not(.flat) { color: white; outline-color: white; border-color: #0f3b71; background-image: linear-gradient(to top, #1a66c2 2px, #1b6acb); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +popover.menu box.circular-buttons button.suggested-action.circular.image-button.model, list > row button.image-button.suggested-action:not(.flat) { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +popover.menu box.circular-buttons button.suggested-action.circular.image-button.model:focus:focus-visible, list > row button.image-button.suggested-action:not(.flat):focus:focus-visible { outline-color: white; outline-width: 2px; outline-offset: -2px; }
 +
 +popover.menu box.circular-buttons button.destructive-action.circular.image-button.model, list > row button.image-button.destructive-action:not(.flat) { color: white; outline-color: white; border-color: #851015; background-image: linear-gradient(to top, #d71a23 2px, #e01b24); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +popover.menu box.circular-buttons button.destructive-action.circular.image-button.model, list > row button.image-button.destructive-action:not(.flat) { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +popover.menu box.circular-buttons button.destructive-action.circular.image-button.model:focus:focus-visible, list > row button.image-button.destructive-action:not(.flat):focus:focus-visible { outline-color: white; outline-width: 2px; outline-offset: -2px; }
 +
 +/********* Links * */
 +button.link, link { color: #1b6acb; text-decoration: underline; }
 +
 +button.link:visited, link:visited { color: #15539e; }
 +
 +*:selected button.link:visited, *:selected link:visited { color: #a1bad8; }
 +
 +button.link:hover, link:hover { color: #3584e4; }
 +
 +*:selected button.link:hover, *:selected link:hover { color: #ebf3fc; }
 +
 +button.link:active, link:active { color: #1b6acb; }
 +
 +*:selected button.link:active, *:selected link:active { color: #d1e1f5; }
 +
 +button.link:disabled, link:disabled { color: rgba(115, 115, 115, 0.8); }
 +
 +button.link:selected, *:selected button.link, link:selected, *:selected link { color: #d1e1f5; }
 +
 +link { transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +link { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +link:focus:focus-visible { outline-color: rgba(27, 106, 203, 0.8); outline-width: 2px; outline-offset: -2px; }
 +
 +button.link, button.link:hover, button.link:active, button.link:checked { text-shadow: none; }
 +
 +button.link > label { text-decoration: underline; }
 +
 +/***************** GtkSpinButton * */
 +spinbutton { font-feature-settings: "tnum"; }
 +
 +spinbutton:not(.vertical) { padding: 0; border-spacing: 0; /* :not here just to bump specificity above that of the list button styling */ }
 +
 +.osd spinbutton:not(.vertical) > text, spinbutton:not(.vertical) > text { min-width: 28px; margin: 0; background: none; background-color: transparent; border: none; border-radius: 0; box-shadow: none; padding: 6px; }
 +
 +.osd spinbutton:not(.vertical) > text:backdrop:disabled, spinbutton:not(.vertical) > text:backdrop:disabled { background-color: transparent; }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat), spinbutton:not(.vertical) > button.image-button.down:not(.flat) { min-height: 16px; margin: 0; padding-bottom: 0; padding-top: 0; color: #3d4143; background-image: none; border-style: none none none solid; border-color: rgba(135, 123, 110, 0.3); border-radius: 0; box-shadow: none; }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat):dir(rtl), spinbutton:not(.vertical) > button.image-button.down:not(.flat):dir(rtl) { border-style: none solid none none; }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat):hover, spinbutton:not(.vertical) > button.image-button.down:not(.flat):hover { color: #272c2e; background-color: #f1f0ee; }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat):disabled, spinbutton:not(.vertical) > button.image-button.down:not(.flat):disabled { color: rgba(146, 148, 149, 0.3); background-color: transparent; }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat):active, spinbutton:not(.vertical) > button.image-button.down:not(.flat):active { background-color: rgba(0, 0, 0, 0.1); box-shadow: inset 0 2px 3px -1px rgba(0, 0, 0, 0.2); }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat):dir(ltr):last-child, spinbutton:not(.vertical) > button.image-button.down:not(.flat):dir(ltr):last-child { border-radius: 0 5px 5px 0; }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat):dir(rtl):first-child, spinbutton:not(.vertical) > button.image-button.down:not(.flat):dir(rtl):first-child { border-radius: 5px 0 0 5px; }
 +
 +.osd spinbutton:not(.vertical) > button.image-button.up:not(.flat), .osd spinbutton:not(.vertical) > button.image-button.down:not(.flat) { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: #eeeeec; border-style: none none none solid; border-color: rgba(0, 0, 0, 0.4); border-radius: 0; box-shadow: none; -gtk-icon-shadow: 0 1px black; }
 +
 +.osd spinbutton:not(.vertical) > button.image-button.up:not(.flat):dir(rtl), .osd spinbutton:not(.vertical) > button.image-button.down:not(.flat):dir(rtl) { border-style: none solid none none; }
 +
 +.osd spinbutton:not(.vertical) > button.image-button.up:not(.flat):hover, .osd spinbutton:not(.vertical) > button.image-button.down:not(.flat):hover { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: #eeeeec; border-color: rgba(0, 0, 0, 0.5); background-color: rgba(27, 27, 27, 0.7); -gtk-icon-shadow: 0 1px black; box-shadow: none; }
 +
 +.osd spinbutton:not(.vertical) > button.image-button.up:not(.flat):disabled, .osd spinbutton:not(.vertical) > button.image-button.down:not(.flat):disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: #919190; border-color: rgba(0, 0, 0, 0.5); -gtk-icon-shadow: none; box-shadow: none; }
 +
 +.osd spinbutton:not(.vertical) > button.image-button.up:not(.flat):dir(ltr):last-child, .osd spinbutton:not(.vertical) > button.image-button.down:not(.flat):dir(ltr):last-child { border-radius: 0 5px 5px 0; }
 +
 +.osd spinbutton:not(.vertical) > button.image-button.up:not(.flat):dir(rtl):first-child, .osd spinbutton:not(.vertical) > button.image-button.down:not(.flat):dir(rtl):first-child { border-radius: 5px 0 0 5px; }
 +
 +spinbutton.vertical:disabled { color: #929495; }
 +
 +spinbutton.vertical:drop(active) { border-color: transparent; box-shadow: none; }
 +
 +spinbutton.vertical > text { min-height: 32px; min-width: 32px; padding: 0; border-radius: 0; }
 +
 +spinbutton.vertical > text > block-cursor { color: #ffffff; background-color: black; }
 +
 +spinbutton.vertical > button { min-height: 32px; min-width: 32px; padding: 0; }
 +
 +spinbutton.vertical > button.up { border-bottom-style: none; border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
 +
 +spinbutton.vertical > button.down { border-top-style: none; border-top-left-radius: 0; border-top-right-radius: 0; }
 +
 +.osd spinbutton.vertical > button:first-child { color: #eeeeec; outline-color: rgba(27, 106, 203, 0.8); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; }
 +
 +.osd spinbutton.vertical > button:first-child:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(27, 27, 27, 0.7)); background-clip: padding-box; }
 +
 +.osd spinbutton.vertical > button:first-child:active { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(2, 2, 2, 0.7)); background-clip: padding-box; box-shadow: none; }
 +
 +.osd spinbutton.vertical > button:first-child:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; }
 +
 +treeview spinbutton:not(.vertical) { min-height: 0; border-style: none; border-radius: 0; }
 +
 +treeview spinbutton:not(.vertical) > text { min-height: 0; padding: 1px 2px; }
 +
 +/************** ComboBoxes * */
 +dropdown > popover.menu.background > contents { padding: 0; }
 +
 +dropdown > button > box { border-spacing: 6px; }
 +
 +dropdown > button > box > stack > row.activatable:hover { background: none; box-shadow: none; }
 +
 +dropdown arrow, combobox arrow { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); min-height: 16px; min-width: 16px; }
 +
 +dropdown > popover.menu > contents modelbutton, combobox > popover.menu > contents modelbutton { padding-left: 9px; padding-right: 9px; }
 +
 +dropdown:drop(active), combobox:drop(active) { box-shadow: none; }
 +
 +dropdown popover, combobox popover { margin-top: 6px; padding: 0; }
 +
 +dropdown popover listview, combobox popover listview { margin: 8px 0; }
 +
 +dropdown popover listview > row.activatable, combobox popover listview > row.activatable { padding: 8px; }
 +
 +dropdown popover listview > row.activatable:selected, dropdown popover listview > row.activatable:selected:hover, combobox popover listview > row.activatable:selected, combobox popover listview > row.activatable:selected:hover { outline-color: white; color: black; background-color: #e6e3e0; box-shadow: none; }
 +
 +dropdown popover .dropdown-searchbar, combobox popover .dropdown-searchbar { padding: 6px; border-bottom: 1px solid #877b6e; }
 +
 +/************ Toolbars * */
 +searchbar > revealer > box, .toolbar, toolbar { padding: 4px; border-spacing: 4px; background-color: #fdfdfc; }
 +
 +.osd .toolbar, .osd toolbar { background-color: transparent; }
 +
 +.toolbar.osd, toolbar.osd { padding: 13px; border: none; border-radius: 5px; background-color: rgba(53, 53, 53, 0.7); }
 +
 +.toolbar.osd.left, .toolbar.osd.right, .toolbar.osd.top, .toolbar.osd.bottom, toolbar.osd.left, toolbar.osd.right, toolbar.osd.top, toolbar.osd.bottom { border-radius: 0; }
 +
 +.toolbar.horizontal > separator, toolbar.horizontal > separator { margin: 4px 0; }
 +
 +.toolbar.vertical > separator, toolbar.vertical > separator { margin: 0 4px; }
 +
 +searchbar > revealer > box { padding: 6px; border-spacing: 6px; border-width: 0 0 1px; }
 +
 +searchbar > revealer > box { border-style: solid; border-color: #877b6e; background-color: #d9d6d2; }
 +
 +searchbar > revealer > box:backdrop { border-color: #d5d0cc; background-color: #eae8e6; box-shadow: none; transition: 200ms ease-out; }
 +
 +/************** GtkInfoBar * */
 +infobar > revealer > box { padding: 8px; border-spacing: 12px; }
 +
 +infobar.action:hover > revealer > box { background-color: white; }
 +
 +infobar.info > revealer > box, infobar.question > revealer > box, infobar.warning > revealer > box, infobar.error > revealer > box { border-bottom: 1px solid #93877b; background-color: white; }
 +
 +infobar .close, searchbar .close { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; min-width: 16px; min-height: 16px; padding: 4px; border-radius: 50%; }
 +
 +infobar .close:hover, searchbar .close:hover { color: #272c2e; border-color: #877b6e; background-image: linear-gradient(to top, #dad6d2, #edebe9 1px); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +/***************** Title buttons * */
 +windowcontrols { border-spacing: 6px; }
 +
 +windowcontrols.start:not(.empty):dir(ltr), windowcontrols.end:not(.empty):dir(rtl) { margin-right: 7px; }
 +
 +windowcontrols.start:not(.empty):dir(rtl), windowcontrols.end:not(.empty):dir(ltr) { margin-left: 7px; }
 +
 +windowcontrols button { border-radius: 9999px; padding: 6px; margin: 0 2px; min-width: 0; min-height: 0; }
 +
 +windowcontrols button:hover { border-color: transparent; background-image: none; box-shadow: none; background-color: #d1ccc7; }
 +
 +windowcontrols button:active, windowcontrols button:checked { border-color: transparent; background-image: none; box-shadow: none; background-color: #bab3ab; }
 +
 +/*************** Header bars * */
 +.titlebar:not(headerbar), headerbar { padding: 0 6px; min-height: 46px; border-width: 0 0 1px; border-style: solid; border-color: #6e645a; border-radius: 0; background: #e6e3e0 linear-gradient(to top, #e1dedb, #e8e6e3); /* Darken switchbuttons for headerbars. issue #1588 */ }
 +
 +.titlebar:backdrop:not(headerbar), headerbar:backdrop { border-color: #d5d0cc; background-color: #fdfdfc; background-image: none; transition: 200ms ease-out; }
 +
 +.titlebar:not(headerbar) .title, headerbar .title { padding-left: 12px; padding-right: 12px; font-weight: bold; }
 +
 +.titlebar:not(headerbar) .subtitle, headerbar .subtitle { font-size: smaller; padding-left: 12px; padding-right: 12px; }
 +
 +.titlebar:not(headerbar) stackswitcher > button:checked, .titlebar:not(headerbar) button.toggle:checked, headerbar stackswitcher > button:checked, headerbar button.toggle:checked { background: image(#d6d1cd); border-color: #7e7367; border-top-color: #70665c; }
 +
 +.titlebar:not(headerbar) stackswitcher > button:checked:backdrop, .titlebar:not(headerbar) button.toggle:checked:backdrop, headerbar stackswitcher > button:checked:backdrop, headerbar button.toggle:checked:backdrop { color: #929595; border-color: #d5d0cc; background-image: image(#ebebeb); box-shadow: none; }
 +
 +.tiled .titlebar:not(headerbar), .tiled-top .titlebar:not(headerbar), .tiled-left .titlebar:not(headerbar), .tiled-right .titlebar:not(headerbar), .tiled-bottom .titlebar:not(headerbar), .maximized .titlebar:not(headerbar), .fullscreen .titlebar:not(headerbar), .tiled headerbar, .tiled-top headerbar, .tiled-left headerbar, .tiled-right headerbar, .tiled-bottom headerbar, .maximized headerbar, .fullscreen headerbar { border-radius: 0; }
 +
 +.default-decoration.titlebar:not(headerbar), headerbar.default-decoration { min-height: 28px; padding: 4px; }
 +
 +.default-decoration.titlebar:not(headerbar) windowcontrols button, .default-decoration.titlebar:not(headerbar) windowcontrols menubutton, headerbar.default-decoration windowcontrols button, headerbar.default-decoration windowcontrols menubutton { min-height: 26px; min-width: 26px; margin: 0; padding: 0; }
 +
 +.default-decoration.titlebar:not(headerbar) windowcontrols menubutton button, headerbar.default-decoration windowcontrols menubutton button { min-height: 20px; min-width: 20px; margin: 0; padding: 4px; }
 +
 +.solid-csd .titlebar:dir(rtl):not(headerbar), .solid-csd .titlebar:dir(ltr):not(headerbar), .solid-csd headerbar:backdrop:dir(rtl), .solid-csd headerbar:backdrop:dir(ltr), .solid-csd headerbar:dir(rtl), .solid-csd headerbar:dir(ltr) { margin-left: -1px; margin-right: -1px; margin-top: -1px; border-radius: 0; box-shadow: none; }
 +
 +headerbar > windowhandle > box, headerbar > windowhandle > box > box.start, headerbar > windowhandle > box > box.end { border-spacing: 6px; }
 +
 +headerbar entry, headerbar spinbutton, headerbar separator:not(.sidebar), headerbar button, headerbar menubutton { margin-top: 6px; margin-bottom: 6px; }
 +
 +headerbar menubutton > button { margin-top: 0px; margin-bottom: 0px; }
 +
 +headerbar switch { margin-top: 10px; margin-bottom: 10px; }
 +
 +window.csd > .titlebar:not(headerbar) { padding: 0; background-color: transparent; background-image: none; border-style: none; border-color: transparent; }
 +
 +.titlebar:not(headerbar) separator { background-color: #877b6e; }
 +
 +window.devel headerbar.titlebar { background: #fdfdfc cross-fade(10% -gtk-icontheme("system-run-symbolic"), image(transparent)) 90% 0/256px 256px no-repeat, linear-gradient(to right, transparent 65%, rgba(27, 106, 203, 0.2)), linear-gradient(to top, #dfdcd8, #e6e3e0 3px, #f4f2f1); }
 +
 +window.devel headerbar.titlebar:backdrop { background: #fdfdfc cross-fade(10% -gtk-icontheme("system-run-symbolic"), image(transparent)) 90% 0/256px 256px no-repeat, image(#fdfdfc); /* background-color would flash */ }
 +
 +/************ Pathbars * */
 +pathbar > button.text-button, pathbar > button.image-button, pathbar > button { padding-left: 4px; padding-right: 4px; }
 +
 +pathbar > button.text-button.image-button label { padding-left: 0; padding-right: 0; }
 +
 +pathbar > button.text-button.image-button label:last-child, pathbar > button label:last-child { padding-right: 8px; }
 +
 +pathbar > button.text-button.image-button label:first-child, pathbar > button label:first-child { padding-left: 8px; }
 +
 +pathbar > button image { padding-left: 4px; padding-right: 4px; }
 +
 +pathbar > button.slider-button { padding-left: 0; padding-right: 0; }
 +
 +/************** Tree Views * */
 +columnview.view, treeview.view { border-left-color: #9f958b; border-top-color: #9f958b; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +columnview.view, treeview.view { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +columnview.view:focus:focus-visible, treeview.view:focus:focus-visible { outline-color: rgba(27, 106, 203, 0.8); outline-width: 2px; outline-offset: -2px; }
 +
 +columnview.view:selected:focus, columnview.view:selected, treeview.view:selected:focus, treeview.view:selected { border-radius: 0; outline-color: white; }
 +
 +columnview.view:disabled, treeview.view:disabled { color: #929495; }
 +
 +columnview.view:disabled:selected, treeview.view:disabled:selected { color: #76a6e0; }
 +
 +columnview.view:disabled:selected:backdrop, treeview.view:disabled:selected:backdrop { color: #5f96da; }
 +
 +columnview.view.separator, treeview.view.separator { min-height: 2px; color: #9f958b; }
 +
 +columnview.view:backdrop, treeview.view:backdrop { border-left-color: #ddd9d6; border-top: #ddd9d6; }
 +
 +columnview.view:drop(active), treeview.view:drop(active) { box-shadow: none; }
 +
 +columnview.view > dndtarget:drop(active), treeview.view > dndtarget:drop(active) { border-style: solid none; border-width: 1px; border-color: #124787; }
 +
 +columnview.view > dndtarget.after:drop(active), treeview.view > dndtarget.after:drop(active) { border-top-style: none; }
 +
 +columnview.view > dndtarget.before:drop(active), treeview.view > dndtarget.before:drop(active) { border-bottom-style: none; }
 +
 +columnview.view.expander, treeview.view.expander { min-width: 16px; min-height: 16px; -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); color: #4d4d4d; }
 +
 +columnview.view.expander:dir(rtl), treeview.view.expander:dir(rtl) { -gtk-icon-source: -gtk-icontheme("pan-end-symbolic-rtl"); }
 +
 +columnview.view.expander:hover, treeview.view.expander:hover { color: black; }
 +
 +columnview.view.expander:selected, treeview.view.expander:selected { color: #bbd2ef; }
 +
 +columnview.view.expander:selected:hover, treeview.view.expander:selected:hover { color: #ffffff; }
 +
 +columnview.view.expander:checked, treeview.view.expander:checked { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
 +
 +columnview.view.progressbar, treeview.view.progressbar { color: #ffffff; background-color: #1b6acb; background-image: image(#1b6acb); box-shadow: none; }
 +
 +columnview.view.progressbar:selected:focus, columnview.view.progressbar:selected, treeview.view.progressbar:selected:focus, treeview.view.progressbar:selected { color: #1b6acb; background-image: image(#ffffff); }
 +
 +columnview.view.progressbar:selected:focus:backdrop, columnview.view.progressbar:selected:backdrop, treeview.view.progressbar:selected:focus:backdrop, treeview.view.progressbar:selected:backdrop { color: #1b6acb; background-color: #fcfcfc; }
 +
 +columnview.view.trough, treeview.view.trough { background-color: rgba(39, 44, 46, 0.1); }
 +
 +columnview.view.trough:selected:focus, columnview.view.trough:selected, treeview.view.trough:selected:focus, treeview.view.trough:selected { background-color: rgba(255, 255, 255, 0.3); }
 +
 +columnview.view > header > button, treeview.view > header > button { color: #939696; background-color: #ffffff; font-weight: bold; text-shadow: none; box-shadow: none; }
 +
 +columnview.view > header > button:hover, treeview.view > header > button:hover { color: #5d6162; box-shadow: none; transition: none; }
 +
 +columnview.view > header > button:active, treeview.view > header > button:active { color: #272c2e; transition: none; }
 +
 +columnview.view > header > button sort-indicator, treeview.view > header > button sort-indicator { min-height: 16px; min-width: 16px; }
 +
 +columnview.view > header > button sort-indicator.ascending, treeview.view > header > button sort-indicator.ascending { -gtk-icon-source: -gtk-icontheme("pan-up-symbolic"); }
 +
 +columnview.view > header > button sort-indicator.descending, treeview.view > header > button sort-indicator.descending { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
 +
 +columnview.view button.dnd:active, columnview.view button.dnd:selected, columnview.view button.dnd:hover, columnview.view button.dnd, columnview.view header.button.dnd:active, columnview.view header.button.dnd:selected, columnview.view header.button.dnd:hover, columnview.view header.button.dnd, treeview.view button.dnd:active, treeview.view button.dnd:selected, treeview.view button.dnd:hover, treeview.view button.dnd, treeview.view header.button.dnd:active, treeview.view header.button.dnd:selected, treeview.view header.button.dnd:hover, treeview.view header.button.dnd { padding: 0 6px; color: #ffffff; background-image: none; background-color: #1b6acb; border-style: none; border-radius: 0; box-shadow: inset 0 0 0 1px #ffffff; text-shadow: none; transition: none; }
 +
 +columnview.view acceleditor > label, treeview.view acceleditor > label { background-color: #1b6acb; }
 +
 +columnview.view > header > button, treeview.view > header > button, columnview.view > header > button:hover, treeview.view > header > button:hover, columnview.view > header > button:active, treeview.view > header > button:active { padding: 0 6px; background-image: none; border-style: none none solid solid; border-color: #9f958b; border-radius: 0; text-shadow: none; }
 +
 +columnview.view > header > button:disabled, treeview.view > header > button:disabled { border-color: #fdfdfc; background-image: none; }
 +
 +columnview.view > header > button:last-child, treeview.view > header > button:last-child { border-right-style: none; }
 +
 +/*************** Popovers   * */
 +popover.background { background-color: transparent; font: initial; }
 +
 +popover.background > arrow, popover.background > contents { background-color: #ffffff; background-clip: padding-box; border: 1px solid rgba(0, 0, 0, 0.23); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); }
 +
 +popover.background:backdrop { background-color: transparent; }
 +
 +popover.background > contents { padding: 8px; border-radius: 9px; }
 +
 +popover.background > contents > list, popover.background > contents > .view, popover.background > contents > iconview, popover.background > contents > toolbar { border-style: none; background-color: transparent; }
 +
 +popover.background > contents separator { background-color: #aaa299; margin: 3px; }
 +
 +popover.background > contents list separator { margin: 0; }
 +
 +.osd popover.background, popover.background.touch-selection, popover.background.magnifier { background-color: transparent; }
 +
 +.osd popover.background > arrow, .osd popover.background > contents, popover.background.touch-selection > arrow, popover.background.touch-selection > contents, popover.background.magnifier > arrow, popover.background.magnifier > contents { border: 1px solid rgba(255, 255, 255, 0.1); box-shadow: none; }
 +
 +magnifier { background-color: #ffffff; }
 +
 +/********************** Popover Base Menus * */
 +popover.menu { padding: 0; }
 +
 +popover.menu box.inline-buttons { padding: 0 12px; }
 +
 +popover.menu box.inline-buttons button.image-button.model { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; min-height: 30px; min-width: 30px; padding: 0; border: none; outline: none; transition: none; }
 +
 +popover.menu box.inline-buttons button.image-button.model:selected { background: image(#e6e3e0); }
 +
 +popover.menu box.circular-buttons { padding: 12px 12px 6px; }
 +
 +popover.menu box.circular-buttons button.circular.image-button.model { padding: 11px; }
 +
 +popover.menu box.circular-buttons button.circular.image-button.model:focus { background-color: #e6e3e0; border-color: #e6e3e0; }
 +
 +popover.menu > arrow, popover.menu.background > contents { background-color: #ffffff; padding: 5px; }
 +
 +popover.menu.background separator { margin: 6px 0; }
 +
 +popover.menu accelerator { color: alpha(currentColor,0.55); }
 +
 +popover.menu accelerator:dir(ltr) { margin-left: 12px; }
 +
 +popover.menu accelerator:dir(rtl) { margin-right: 12px; }
 +
 +popover.menu check, popover.menu radio { transform: scale(0.8); border-width: 1.2px; border-color: transparent; box-shadow: none; background-image: image(transparent); color: black; }
 +
 +popover.menu check:hover, popover.menu radio:hover { transform: scale(0.8); border-width: 1.2px; color: black; box-shadow: none; background-image: image(transparent); }
 +
 +popover.menu check:active, popover.menu radio:active { transform: scale(0.8); border-width: 1.2px; color: black; box-shadow: none; background-image: image(transparent); }
 +
 +popover.menu radio { border-color: #877b6e; }
 +
 +popover.menu radio:active { border-color: rgba(135, 123, 110, 0.5); }
 +
 +popover.menu arrow.left, popover.menu radio.left, popover.menu check.left { margin-left: -2px; margin-right: 6px; }
 +
 +popover.menu arrow.right, popover.menu radio.right, popover.menu check.right { margin-left: 6px; margin-right: -2px; }
 +
 +popover.menu modelbutton { min-height: 30px; min-width: 40px; padding: 0 12px; border-radius: 5px; }
 +
 +popover.menu modelbutton:selected { color: black; background-color: #e6e3e0; }
 +
 +popover.menu modelbutton:selected:active { background-color: #ddd9d5; }
 +
 +popover.menu label.title { font-weight: bold; padding: 4px 32px; }
 +
 +menubar { padding: 0px; box-shadow: inset 0 -1px rgba(0, 0, 0, 0.1); }
 +
 +menubar > item { min-height: 16px; padding: 4px 8px; }
 +
 +menubar > item:selected { box-shadow: inset 0 -3px #1b6acb; color: #1b6acb; }
 +
 +menubar > item:disabled { color: #929495; box-shadow: none; }
 +
 +menubar > item popover.menu.background > contents { padding: 5px; }
 +
 +menubar > item popover.menu popover.menu { padding: 0 0 4px 0; }
 +
 +menubar > item popover.menu.background popover.menu.background > contents { margin: 0; border-radius: 9px; }
 +
 +/************* Notebooks * */
 +notebook { transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +notebook > header > tabs > tab:checked { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +notebook:focus:focus-visible > header > tabs > tab:checked { outline-color: rgba(27, 106, 203, 0.8); outline-width: 2px; outline-offset: -2px; }
 +
 +notebook > header { padding: 1px; border-color: #877b6e; border-width: 1px; background-color: #e1dedb; }
 +
 +notebook > header > tabs { margin: -1px; }
 +
 +notebook > header.top { border-bottom-style: solid; }
 +
 +notebook > header.top > tabs { margin-bottom: -2px; }
 +
 +notebook > header.top > tabs > tab:hover { box-shadow: inset 0 -4px #877b6e; }
 +
 +notebook > header.top > tabs > tab:checked { box-shadow: inset 0 -4px #1b6acb; }
 +
 +notebook > header.bottom { border-top-style: solid; }
 +
 +notebook > header.bottom > tabs { margin-top: -2px; }
 +
 +notebook > header.bottom > tabs > tab:hover { box-shadow: inset 0 4px #877b6e; }
 +
 +notebook > header.bottom > tabs > tab:checked { box-shadow: inset 0 4px #1b6acb; }
 +
 +notebook > header.left { border-right-style: solid; }
 +
 +notebook > header.left > tabs { margin-right: -2px; }
 +
 +notebook > header.left > tabs > tab:hover { box-shadow: inset -4px 0 #877b6e; }
 +
 +notebook > header.left > tabs > tab:checked { box-shadow: inset -4px 0 #1b6acb; }
 +
 +notebook > header.right { border-left-style: solid; }
 +
 +notebook > header.right > tabs { margin-left: -2px; }
 +
 +notebook > header.right > tabs > tab:hover { box-shadow: inset 4px 0 #877b6e; }
 +
 +notebook > header.right > tabs > tab:checked { box-shadow: inset 4px 0 #1b6acb; }
 +
 +notebook > header.top > tabs > arrow { border-top-style: none; }
 +
 +notebook > header.bottom > tabs > arrow { border-bottom-style: none; }
 +
 +notebook > header.top > tabs > arrow, notebook > header.bottom > tabs > arrow { margin-left: -5px; margin-right: -5px; padding-left: 4px; padding-right: 4px; }
 +
 +notebook > header.top > tabs > arrow.down, notebook > header.bottom > tabs > arrow.down { -gtk-icon-source: -gtk-icontheme("pan-start-symbolic"); }
 +
 +notebook > header.top > tabs > arrow.up, notebook > header.bottom > tabs > arrow.up { -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); }
 +
 +notebook > header.left > tabs > arrow { border-left-style: none; }
 +
 +notebook > header.right > tabs > arrow { border-right-style: none; }
 +
 +notebook > header.left > tabs > arrow, notebook > header.right > tabs > arrow { margin-top: -5px; margin-bottom: -5px; padding-top: 4px; padding-bottom: 4px; }
 +
 +notebook > header.left > tabs > arrow.down, notebook > header.right > tabs > arrow.down { -gtk-icon-source: -gtk-icontheme("pan-up-symbolic"); }
 +
 +notebook > header.left > tabs > arrow.up, notebook > header.right > tabs > arrow.up { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
 +
 +notebook > header > tabs > arrow { min-height: 16px; min-width: 16px; border-radius: 0; }
 +
 +notebook > header > tabs > arrow:hover:not(:active):not(:backdrop) { background-clip: padding-box; background-image: none; background-color: rgba(255, 255, 255, 0.3); border-color: transparent; box-shadow: none; }
 +
 +notebook > header > tabs > arrow:disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; }
 +
 +notebook > header > tabs > tab { transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); min-height: 30px; min-width: 30px; padding: 3px 12px; color: #272c2e; font-weight: normal; border-width: 1px; border-color: transparent; }
 +
 +notebook > header > tabs > tab:hover { color: #272c2e; background-color: #d8d4d0; }
 +
 +notebook > header > tabs > tab.reorderable-page:hover { border-color: rgba(135, 123, 110, 0.3); background-color: rgba(253, 253, 252, 0.2); }
 +
 +notebook > header > tabs > tab:not(:checked) { outline-color: transparent; }
 +
 +notebook > header > tabs > tab:checked { color: #272c2e; }
 +
 +notebook > header > tabs > tab.reorderable-page:checked { border-color: rgba(135, 123, 110, 0.5); background-color: rgba(253, 253, 252, 0.5); }
 +
 +notebook > header > tabs > tab.reorderable-page:checked:hover { background-color: rgba(253, 253, 252, 0.7); }
 +
 +notebook > header > tabs > tab button.flat { color: alpha(currentColor,0.3); padding: 0; margin-top: 4px; margin-bottom: 4px; min-width: 20px; min-height: 20px; }
 +
 +notebook > header > tabs > tab button.flat:hover { color: currentColor; }
 +
 +notebook > header > tabs > tab button.flat:last-child { margin-left: 4px; margin-right: -4px; }
 +
 +notebook > header > tabs > tab button.flat:first-child { margin-left: -4px; margin-right: 4px; }
 +
 +notebook > header.top > tabs, notebook > header.bottom > tabs { padding-left: 4px; padding-right: 4px; }
 +
 +notebook > header.top > tabs:not(:only-child), notebook > header.bottom > tabs:not(:only-child) { margin-left: 3px; margin-right: 3px; }
 +
 +notebook > header.top > tabs:not(:only-child):first-child, notebook > header.bottom > tabs:not(:only-child):first-child { margin-left: -1px; }
 +
 +notebook > header.top > tabs:not(:only-child):last-child, notebook > header.bottom > tabs:not(:only-child):last-child { margin-right: -1px; }
 +
 +notebook > header.top > tabs > tab, notebook > header.bottom > tabs > tab { margin-left: 4px; margin-right: 4px; }
 +
 +notebook > header.top > tabs > tab.reorderable-page, notebook > header.bottom > tabs > tab.reorderable-page { border-style: none solid; }
 +
 +notebook > header.left > tabs, notebook > header.right > tabs { padding-top: 4px; padding-bottom: 4px; }
 +
 +notebook > header.left > tabs:not(:only-child), notebook > header.right > tabs:not(:only-child) { margin-top: 3px; margin-bottom: 3px; }
 +
 +notebook > header.left > tabs:not(:only-child):first-child, notebook > header.right > tabs:not(:only-child):first-child { margin-top: -1px; }
 +
 +notebook > header.left > tabs:not(:only-child):last-child, notebook > header.right > tabs:not(:only-child):last-child { margin-bottom: -1px; }
 +
 +notebook > header.left > tabs > tab, notebook > header.right > tabs > tab { margin-top: 4px; margin-bottom: 4px; }
 +
 +notebook > header.left > tabs > tab.reorderable-page, notebook > header.right > tabs > tab.reorderable-page { border-style: solid none; }
 +
 +notebook > header.top > tabs > tab { padding-bottom: 4px; }
 +
 +notebook > header.bottom > tabs > tab { padding-top: 4px; }
 +
 +notebook > stack:not(:only-child) { background-color: #ffffff; }
 +
 +/************** Scrollbars * */
 +scrollbar { background-color: #cecece; transition: all 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
 +
 +scrollbar.top { border-bottom: 1px solid #877b6e; }
 +
 +scrollbar.bottom { border-top: 1px solid #877b6e; }
 +
 +scrollbar.left { border-right: 1px solid #877b6e; }
 +
 +scrollbar.right { border-left: 1px solid #877b6e; }
 +
 +scrollbar > range > trough > slider { min-width: 8px; min-height: 8px; margin: -1px; border: 4px solid transparent; border-radius: 10px; background-clip: padding-box; background-color: #7e8182; transition: all 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
 +
 +scrollbar > range > trough > slider:hover { background-color: #565b5c; }
 +
 +scrollbar > range > trough > slider:hover:active { background-color: #1b6acb; }
 +
 +scrollbar > range > trough > slider:disabled { background-color: transparent; }
 +
 +scrollbar > range.fine-tune > trough > slider { transition: none; min-width: 6px; min-height: 6px; }
 +
 +scrollbar > range.fine-tune.horizontal > trough > slider { border-width: 5px 4px; }
 +
 +scrollbar > range.fine-tune.vertical > trough > slider { border-width: 4px 5px; }
 +
 +scrollbar.overlay-indicator:not(.dragging):not(.hovering) { border-color: transparent; opacity: 0.4; background-color: transparent; }
 +
 +scrollbar.overlay-indicator:not(.dragging):not(.hovering) > range > trough > slider { margin: 0; min-width: 3px; min-height: 3px; background-color: #272c2e; border: 1px solid white; }
 +
 +scrollbar.overlay-indicator.horizontal:not(.dragging):not(.hovering) > range > trough > slider { margin: 0 2px; min-width: 40px; }
 +
 +scrollbar.overlay-indicator.vertical:not(.dragging):not(.hovering) > range > trough > slider { margin: 2px 0; min-height: 40px; }
 +
 +scrollbar.overlay-indicator.dragging, scrollbar.overlay-indicator.hovering { opacity: 0.8; }
 +
 +scrollbar.horizontal > range > trough > slider { min-width: 40px; }
 +
 +scrollbar.vertical > range > trough > slider { min-height: 40px; }
 +
 +treeview ~ scrollbar.vertical { border-top: 1px solid #877b6e; margin-top: -1px; }
 +
 +/********** Switch * */
 +switch { font-weight: bold; font-size: smaller; border: 1px solid #877b6e; border-radius: 14px; color: #272c2e; background-color: #e1dedb; transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; /* only show i / o for the accessible theme */ }
 +
 +switch { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +switch:focus:focus-visible { outline-color: rgba(27, 106, 203, 0.8); outline-width: 2px; outline-offset: 0; }
 +
 +headerbar switch { background-color: #cecac5; }
 +
 +switch:checked { color: #ffffff; border-color: #185fb4; background-color: #3584e4; }
 +
 +switch:disabled { color: #929495; border-color: #877b6e; background-color: #fefefd; text-shadow: none; }
 +
 +switch > slider { color: #272c2e; outline-color: rgba(27, 106, 203, 0.8); border-color: #877b6e; background-image: linear-gradient(to top, #fafaf9 2px, white); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); margin: -1px; min-width: 24px; min-height: 24px; border: 1px solid; border-color: #877b6e; border-radius: 50%; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
 +
 +switch > image { color: transparent; }
 +
 +switch:hover > slider { color: #272c2e; border-color: #877b6e; background-image: linear-gradient(to top, #dad6d2, #edebe9 1px); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +switch:checked > slider { border: 1px solid #185fb4; }
 +
 +switch:disabled > slider { color: #929495; border-color: #9e958b; background-image: image(#fefefd); }
 +
 +row:selected switch { outline-color: white; box-shadow: none; border-color: #185fb4; }
 +
 +row:selected switch > slider:checked, row:selected switch > slider { border-color: #185fb4; }
 +
 +/************************* Check and Radio items * */
 +.view.content-view.check:not(list), iconview.content-view.check:not(list), .content-view .tile check:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: #3584e4; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:hover:not(list), iconview.content-view.check:hover:not(list), .content-view .tile check:hover:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: #3584e4; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:active:not(list), iconview.content-view.check:active:not(list), .content-view .tile check:active:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: #3584e4; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:backdrop:not(list), iconview.content-view.check:backdrop:not(list), .content-view .tile check:backdrop:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: #8d8d8d; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:checked:not(list), iconview.content-view.check:checked:not(list), .content-view .tile check:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: #eeeeec; background-color: #3584e4; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:checked:hover:not(list), iconview.content-view.check:checked:hover:not(list), .content-view .tile check:checked:hover:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: #eeeeec; background-color: #3584e4; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:checked:active:not(list), iconview.content-view.check:checked:active:not(list), .content-view .tile check:checked:active:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: #eeeeec; background-color: #3584e4; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:backdrop:checked:not(list), iconview.content-view.check:backdrop:checked:not(list), .content-view .tile check:backdrop:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: rgba(238, 238, 236, 0.8); background-color: #8d8d8d; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
 +
 +checkbutton { border-spacing: 4px; border-radius: 5px; transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +checkbutton { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +checkbutton:focus:focus-visible { outline-color: rgba(27, 106, 203, 0.8); outline-width: 2px; outline-offset: -2px; }
 +
 +checkbutton.text-button { padding: 4px; }
 +
 +check, radio { min-height: 14px; min-width: 14px; border: 1px solid; -gtk-icon-source: none; }
 +
 +check, radio { background-clip: padding-box; background-image: linear-gradient(to bottom, white 20%, white 90%); border-color: #6e645a; box-shadow: 0 1px rgba(0, 0, 0, 0.05); color: #ffffff; }
 +
 +check:hover, radio:hover { background-image: image(#f2f2f2); }
 +
 +check:active, radio:active { box-shadow: inset 0 1px rgba(0, 0, 0, 0.2); background-image: image(#d9d9d9); }
 +
 +check:disabled, radio:disabled { box-shadow: none; color: rgba(255, 255, 255, 0.7); }
 +
 +check:checked, radio:checked { background-clip: border-box; background-image: linear-gradient(to bottom, #4b92e7 20%, #3584e4 90%); border-color: #1b6acb; box-shadow: 0 1px rgba(0, 0, 0, 0.05); color: #ffffff; }
 +
 +check:checked:hover, radio:checked:hover { background-image: linear-gradient(to bottom, #5d9de9 10%, #478fe6 90%); }
 +
 +check:checked:active, radio:checked:active { box-shadow: inset 0 1px rgba(0, 0, 0, 0.2); background-image: image(#1f76e1); }
 +
 +check:checked:disabled, radio:checked:disabled { box-shadow: none; color: rgba(255, 255, 255, 0.7); }
 +
 +check:indeterminate, radio:indeterminate { background-clip: border-box; background-image: linear-gradient(to bottom, #4b92e7 20%, #3584e4 90%); border-color: #1b6acb; box-shadow: 0 1px rgba(0, 0, 0, 0.05); color: #ffffff; }
 +
 +check:indeterminate:hover, radio:indeterminate:hover { background-image: linear-gradient(to bottom, #5d9de9 10%, #478fe6 90%); }
 +
 +check:indeterminate:active, radio:indeterminate:active { box-shadow: inset 0 1px rgba(0, 0, 0, 0.2); background-image: image(#1f76e1); }
 +
 +check:indeterminate:disabled, radio:indeterminate:disabled { box-shadow: none; color: rgba(255, 255, 255, 0.7); }
 +
 +row:selected check, row:selected radio { border-color: #1b6acb; }
 +
 +.osd check, .osd radio { color: #eeeeec; outline-color: rgba(27, 106, 203, 0.8); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; }
 +
 +.osd check:hover, .osd radio:hover { color: #eeeeec; outline-color: rgba(27, 106, 203, 0.8); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; }
 +
 +.osd check:active, .osd radio:active { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(2, 2, 2, 0.7)); background-clip: padding-box; box-shadow: none; }
 +
 +.osd check:disabled, .osd radio:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; }
 +
 +check { border-radius: 3px; -gtk-icon-size: 14px; }
 +
 +check:checked { -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets-hc/check-symbolic.symbolic.png")), -gtk-recolor(url("assets-hc/check@2-symbolic.symbolic.png"))); }
 +
 +check:indeterminate { -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets-hc/dash-symbolic.symbolic.png")), -gtk-recolor(url("assets-hc/dash@2-symbolic.symbolic.png"))); }
 +
 +treeview.view radio:selected:focus, treeview.view radio:selected, radio { border-radius: 100%; -gtk-icon-size: 14px; }
 +
 +treeview.view radio:checked:selected, radio:checked { -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets-hc/bullet-symbolic.symbolic.png")), -gtk-recolor(url("assets-hc/bullet@2-symbolic.symbolic.png"))); }
 +
 +treeview.view radio:indeterminate:selected, radio:indeterminate { -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets-hc/dash-symbolic.symbolic.png")), -gtk-recolor(url("assets-hc/dash@2-symbolic.symbolic.png"))); }
 +
 +treeview.view check:selected:focus, treeview.view check:selected, treeview.view radio:selected:focus, treeview.view radio:selected { color: #ffffff; border-color: #124787; }
 +
 +/************ GtkScale * */
 +progressbar > trough, scale > trough > fill, scale > trough { border: 1px solid #e1dedb; border-radius: 3px; background-color: #e1dedb; }
 +
 +headerbar progressbar > trough, headerbar scale > trough > fill, headerbar scale > trough { background-color: #cecac5; }
 +
 +progressbar > trough:disabled, scale > trough > fill:disabled, scale > trough:disabled { background-color: #fefefd; border-color: #9e958b; }
 +
 +row:selected progressbar > trough, row:selected scale > trough > fill, row:selected scale > trough { outline-color: white; border-color: #124787; }
 +
 +.osd progressbar > trough, .osd scale > trough > fill, .osd scale > trough { border-color: rgba(0, 0, 0, 0.7); background-color: rgba(0, 0, 0, 0.5); }
 +
 +.osd progressbar > trough:disabled, .osd scale > trough > fill:disabled, .osd scale > trough:disabled { background-color: rgba(71, 71, 71, 0.5); }
 +
 +progressbar > trough > progress, scale > trough > highlight { border: 1px solid #1b6acb; border-radius: 3px; background-color: #1b6acb; }
 +
 +progressbar > trough > progress:disabled, scale > trough > highlight:disabled { background-color: transparent; border-color: transparent; }
 +
 +row:selected progressbar > trough > progress, row:selected scale > trough > highlight { border-color: #124787; }
 +
 +.osd progressbar > trough > progress, .osd scale > trough > highlight { border-color: rgba(0, 0, 0, 0.7); }
 +
 +.osd progressbar > trough > progress:disabled, .osd scale > trough > highlight:disabled { border-color: transparent; }
 +
 +scale { min-height: 10px; min-width: 10px; padding: 12px; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +scale > trough { outline: 0 solid transparent; outline-offset: 16px; }
 +
 +scale:focus:focus-visible > trough { outline-color: rgba(27, 106, 203, 0.8); outline-width: 2px; outline-offset: 10px; }
 +
 +scale > trough { transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
 +
 +scale > trough > fill, scale > trough > highlight { margin: -1px; }
 +
 +scale > trough > slider { min-height: 18px; min-width: 18px; margin: -9px; }
 +
 +scale.fine-tune.horizontal { padding-top: 9px; padding-bottom: 9px; min-height: 16px; }
 +
 +scale.fine-tune.vertical { padding-left: 9px; padding-right: 9px; min-width: 16px; }
 +
 +scale.fine-tune > trough > slider { margin: -6px; }
 +
 +scale.fine-tune > trough > fill, scale.fine-tune > trough > highlight, scale.fine-tune > trough { border-radius: 5px; }
 +
 +scale > trough > fill:disabled { border-color: transparent; background-color: transparent; }
 +
 +.osd scale > trough > fill { background-color: rgba(91, 91, 90, 0.775); }
 +
 +.osd scale > trough > fill:disabled { border-color: transparent; background-color: transparent; }
 +
 +scale > trough > slider { color: #272c2e; outline-color: rgba(27, 106, 203, 0.8); border-color: #877b6e; background-image: linear-gradient(to top, #fafaf9 2px, white); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); border-width: 1px; border-style: solid; border-radius: 100%; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: background, border, box-shadow; }
 +
 +scale > trough > slider:hover { color: #272c2e; border-color: #877b6e; background-image: linear-gradient(to top, #dad6d2, #edebe9 1px); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +scale > trough > slider:active { border-color: #124787; }
 +
 +scale > trough > slider:disabled { color: #929495; border-color: #9e958b; background-image: image(#fefefd); }
 +
 +row:selected scale > trough > slider:disabled, row:selected scale > trough > slider { border-color: #124787; }
 +
 +.osd scale > trough > slider { color: #eeeeec; outline-color: rgba(27, 106, 203, 0.8); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; border-color: rgba(0, 0, 0, 0.7); background-color: #353535; }
 +
 +.osd scale > trough > slider:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(27, 27, 27, 0.7)); background-clip: padding-box; background-color: #353535; }
 +
 +.osd scale > trough > slider:active { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(2, 2, 2, 0.7)); background-clip: padding-box; box-shadow: none; background-color: #353535; }
 +
 +.osd scale > trough > slider:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; background-color: #353535; }
 +
 +scale > value { color: alpha(currentColor,0.55); font-feature-settings: "tnum"; }
 +
 +scale.horizontal > marks { color: alpha(currentColor,0.55); }
 +
 +scale.horizontal > marks.top { margin-bottom: 6px; }
 +
 +scale.horizontal > marks.bottom { margin-top: 6px; }
 +
 +scale.horizontal > marks indicator { background-color: currentColor; min-height: 6px; min-width: 1px; }
 +
 +scale.horizontal > value.left { margin-right: 9px; }
 +
 +scale.horizontal > value.right { margin-left: 9px; }
 +
 +scale.horizontal.fine-tune > marks.top { margin-top: 3px; }
 +
 +scale.horizontal.fine-tune > marks.bottom { margin-bottom: 3px; }
 +
 +scale.horizontal.fine-tune > marks indicator { min-height: 3px; }
 +
 +scale.vertical > marks { color: alpha(currentColor,0.55); }
 +
 +scale.vertical > marks.top { margin-right: 6px; }
 +
 +scale.vertical > marks.bottom { margin-left: 6px; }
 +
 +scale.vertical > marks indicator { background-color: currentColor; min-height: 1px; min-width: 6px; }
 +
 +scale.vertical > value.top { margin-bottom: 9px; }
 +
 +scale.vertical > value.bottom { margin-top: 9px; }
 +
 +scale.vertical.fine-tune > marks.top { margin-left: 3px; }
 +
 +scale.vertical.fine-tune > marks.bottom { margin-right: 3px; }
 +
 +scale.vertical.fine-tune > marks indicator { min-height: 3px; }
 +
 +scale.horizontal.marks-before:not(.marks-after) > trough > slider { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-horz-scale-has-marks-above.png"), url("assets-hc/slider-horz-scale-has-marks-above@2.png")); min-height: 26px; min-width: 22px; margin-top: -14px; background-position: top; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -7px -10px; margin-top: -11px; }
 +
 +scale.horizontal.marks-before:not(.marks-after) > trough > slider:hover { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-horz-scale-has-marks-above-hover.png"), url("assets-hc/slider-horz-scale-has-marks-above-hover@2.png")); min-height: 26px; min-width: 22px; margin-top: -14px; background-position: top; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -7px -10px; margin-top: -11px; }
 +
 +scale.horizontal.marks-before:not(.marks-after) > trough > slider:active { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-horz-scale-has-marks-above-active.png"), url("assets-hc/slider-horz-scale-has-marks-above-active@2.png")); min-height: 26px; min-width: 22px; margin-top: -14px; background-position: top; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -7px -10px; margin-top: -11px; }
 +
 +scale.horizontal.marks-before:not(.marks-after) > trough > slider:disabled { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-horz-scale-has-marks-above-insensitive.png"), url("assets-hc/slider-horz-scale-has-marks-above-insensitive@2.png")); min-height: 26px; min-width: 22px; margin-top: -14px; background-position: top; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -7px -10px; margin-top: -11px; }
 +
 +scale.horizontal.marks-after:not(.marks-before) > trough > slider { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-horz-scale-has-marks-below.png"), url("assets-hc/slider-horz-scale-has-marks-below@2.png")); min-height: 26px; min-width: 22px; margin-bottom: -14px; background-position: bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -7px -10px; margin-bottom: -11px; }
 +
 +scale.horizontal.marks-after:not(.marks-before) > trough > slider:hover { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-horz-scale-has-marks-below-hover.png"), url("assets-hc/slider-horz-scale-has-marks-below-hover@2.png")); min-height: 26px; min-width: 22px; margin-bottom: -14px; background-position: bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -7px -10px; margin-bottom: -11px; }
 +
 +scale.horizontal.marks-after:not(.marks-before) > trough > slider:active { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-horz-scale-has-marks-below-active.png"), url("assets-hc/slider-horz-scale-has-marks-below-active@2.png")); min-height: 26px; min-width: 22px; margin-bottom: -14px; background-position: bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -7px -10px; margin-bottom: -11px; }
 +
 +scale.horizontal.marks-after:not(.marks-before) > trough > slider:disabled { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-horz-scale-has-marks-below-insensitive.png"), url("assets-hc/slider-horz-scale-has-marks-below-insensitive@2.png")); min-height: 26px; min-width: 22px; margin-bottom: -14px; background-position: bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -7px -10px; margin-bottom: -11px; }
 +
 +scale.vertical.marks-before:not(.marks-after) > trough > slider { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-vert-scale-has-marks-above.png"), url("assets-hc/slider-vert-scale-has-marks-above@2.png")); min-height: 22px; min-width: 26px; margin-left: -14px; background-position: left bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -10px -7px; margin-left: -11px; }
 +
 +scale.vertical.marks-before:not(.marks-after) > trough > slider:hover { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-vert-scale-has-marks-above-hover.png"), url("assets-hc/slider-vert-scale-has-marks-above-hover@2.png")); min-height: 22px; min-width: 26px; margin-left: -14px; background-position: left bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -10px -7px; margin-left: -11px; }
 +
 +scale.vertical.marks-before:not(.marks-after) > trough > slider:active { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-vert-scale-has-marks-above-active.png"), url("assets-hc/slider-vert-scale-has-marks-above-active@2.png")); min-height: 22px; min-width: 26px; margin-left: -14px; background-position: left bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -10px -7px; margin-left: -11px; }
 +
 +scale.vertical.marks-before:not(.marks-after) > trough > slider:disabled { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-vert-scale-has-marks-above-insensitive.png"), url("assets-hc/slider-vert-scale-has-marks-above-insensitive@2.png")); min-height: 22px; min-width: 26px; margin-left: -14px; background-position: left bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -10px -7px; margin-left: -11px; }
 +
 +scale.vertical.marks-after:not(.marks-before) > trough > slider { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-vert-scale-has-marks-below.png"), url("assets-hc/slider-vert-scale-has-marks-below@2.png")); min-height: 22px; min-width: 26px; margin-right: -14px; background-position: right bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -10px -7px; margin-right: -11px; }
 +
 +scale.vertical.marks-after:not(.marks-before) > trough > slider:hover { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-vert-scale-has-marks-below-hover.png"), url("assets-hc/slider-vert-scale-has-marks-below-hover@2.png")); min-height: 22px; min-width: 26px; margin-right: -14px; background-position: right bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -10px -7px; margin-right: -11px; }
 +
 +scale.vertical.marks-after:not(.marks-before) > trough > slider:active { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-vert-scale-has-marks-below-active.png"), url("assets-hc/slider-vert-scale-has-marks-below-active@2.png")); min-height: 22px; min-width: 26px; margin-right: -14px; background-position: right bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -10px -7px; margin-right: -11px; }
 +
 +scale.vertical.marks-after:not(.marks-before) > trough > slider:disabled { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets-hc/slider-vert-scale-has-marks-below-insensitive.png"), url("assets-hc/slider-vert-scale-has-marks-below-insensitive@2.png")); min-height: 22px; min-width: 26px; margin-right: -14px; background-position: right bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -10px -7px; margin-right: -11px; }
 +
 +scale.color { min-height: 0; min-width: 0; }
 +
 +scale.color > trough { background-image: image(#877b6e); background-repeat: no-repeat; }
 +
 +scale.color.horizontal { padding: 0 0 15px 0; }
 +
 +scale.color.horizontal > trough { padding-bottom: 4px; background-position: 0 -3px; border-top-left-radius: 0; border-top-right-radius: 0; }
 +
 +scale.color.horizontal > trough > slider:dir(ltr):hover, scale.color.horizontal > trough > slider:dir(ltr):backdrop, scale.color.horizontal > trough > slider:dir(ltr):disabled, scale.color.horizontal > trough > slider:dir(ltr):backdrop:disabled, scale.color.horizontal > trough > slider:dir(ltr), scale.color.horizontal > trough > slider:dir(rtl):hover, scale.color.horizontal > trough > slider:dir(rtl):backdrop, scale.color.horizontal > trough > slider:dir(rtl):disabled, scale.color.horizontal > trough > slider:dir(rtl):backdrop:disabled, scale.color.horizontal > trough > slider:dir(rtl) { margin-bottom: -15px; margin-top: 6px; }
 +
 +scale.color.vertical:dir(ltr) { padding: 0 0 0 15px; }
 +
 +scale.color.vertical:dir(ltr) > trough { padding-left: 4px; background-position: 3px 0; border-bottom-right-radius: 0; border-top-right-radius: 0; }
 +
 +scale.color.vertical:dir(ltr) > trough > slider:hover, scale.color.vertical:dir(ltr) > trough > slider:backdrop, scale.color.vertical:dir(ltr) > trough > slider:disabled, scale.color.vertical:dir(ltr) > trough > slider:backdrop:disabled, scale.color.vertical:dir(ltr) > trough > slider { margin-left: -15px; margin-right: 6px; }
 +
 +scale.color.vertical:dir(rtl) { padding: 0 15px 0 0; }
 +
 +scale.color.vertical:dir(rtl) > trough { padding-right: 4px; background-position: -3px 0; border-bottom-left-radius: 0; border-top-left-radius: 0; }
 +
 +scale.color.vertical:dir(rtl) > trough > slider:hover, scale.color.vertical:dir(rtl) > trough > slider:backdrop, scale.color.vertical:dir(rtl) > trough > slider:disabled, scale.color.vertical:dir(rtl) > trough > slider:backdrop:disabled, scale.color.vertical:dir(rtl) > trough > slider { margin-right: -15px; margin-left: 6px; }
 +
 +scale.color.fine-tune.horizontal:dir(ltr), scale.color.fine-tune.horizontal:dir(rtl) { padding: 0 0 12px 0; }
 +
 +scale.color.fine-tune.horizontal:dir(ltr) > trough, scale.color.fine-tune.horizontal:dir(rtl) > trough { padding-bottom: 7px; background-position: 0 -6px; }
 +
 +scale.color.fine-tune.horizontal:dir(ltr) > trough > slider, scale.color.fine-tune.horizontal:dir(rtl) > trough > slider { margin-bottom: -15px; margin-top: 6px; }
 +
 +scale.color.fine-tune.vertical:dir(ltr) { padding: 0 0 0 12px; }
 +
 +scale.color.fine-tune.vertical:dir(ltr) > trough { padding-left: 7px; background-position: 6px 0; }
 +
 +scale.color.fine-tune.vertical:dir(ltr) > trough > slider { margin-left: -15px; margin-right: 6px; }
 +
 +scale.color.fine-tune.vertical:dir(rtl) { padding: 0 12px 0 0; }
 +
 +scale.color.fine-tune.vertical:dir(rtl) > trough { padding-right: 7px; background-position: -6px 0; }
 +
 +scale.color.fine-tune.vertical:dir(rtl) > trough > slider { margin-right: -15px; margin-left: 6px; }
 +
 +/***************** Progress bars * */
 +progressbar { font-size: smaller; color: rgba(39, 44, 46, 0.4); font-feature-settings: "tnum"; }
 +
 +progressbar.horizontal > trough { min-width: 150px; }
 +
 +progressbar.horizontal > trough, progressbar.horizontal > trough > progress { min-height: 2px; }
 +
 +progressbar.vertical > trough { min-height: 80px; }
 +
 +progressbar.vertical > trough, progressbar.vertical > trough > progress { min-width: 2px; }
 +
 +progressbar.horizontal > trough > progress { margin: 0 -1px; }
 +
 +progressbar.vertical > trough > progress { margin: -1px 0; }
 +
 +progressbar > trough > progress { /* share most of scales' */ /* override insensitive that is specific to progress */ border-radius: 1.5px; }
 +
 +progressbar > trough > progress:disabled { background-color: #929495; border-color: #929495; }
 +
 +progressbar > trough > progress.left { border-top-left-radius: 5px; border-bottom-left-radius: 5px; }
 +
 +progressbar > trough > progress.right { border-top-right-radius: 5px; border-bottom-right-radius: 5px; }
 +
 +progressbar > trough > progress.top { border-top-right-radius: 5px; border-top-left-radius: 5px; }
 +
 +progressbar > trough > progress.bottom { border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; }
 +
 +progressbar.osd { min-width: 3px; min-height: 3px; background-color: transparent; }
 +
 +progressbar.osd > trough { border-style: none; border-radius: 0; background-color: transparent; box-shadow: none; }
 +
 +progressbar.osd > trough > progress { border-style: none; border-radius: 0; }
 +
 +progressbar > trough.empty > progress { all: unset; }
 +
 +/************* Level Bar * */
 +levelbar.horizontal trough > block { min-height: 9px; border-radius: 5px; }
 +
 +levelbar.horizontal trough > block:dir(rtl) { border-radius: 0 5px 5px 0; }
 +
 +levelbar.horizontal trough > block:dir(ltr) { border-radius: 5px 0 0 5px; }
 +
 +levelbar.horizontal trough > block.empty, levelbar.horizontal trough > block.full { border-radius: 5px; }
 +
 +levelbar.horizontal.discrete trough > block { min-height: 2px; margin: 1px; min-width: 24px; border-radius: 0; }
 +
 +levelbar.horizontal.discrete trough > block:first-child { border-radius: 2px 0 0 2px; }
 +
 +levelbar.horizontal.discrete trough > block:last-child { border-radius: 0 2px 2px 0; }
 +
 +levelbar.vertical trough > block { min-width: 9px; border-radius: 5px; }
 +
 +levelbar.vertical.discrete > trough > block { min-width: 2px; margin: 1px 0; min-height: 32px; }
 +
 +levelbar > trough { padding: 0; }
 +
 +levelbar > trough > block { border: 1px solid; }
 +
 +levelbar > trough > block.low { border-color: #f57900; background-color: #f57900; }
 +
 +levelbar > trough > block.high, levelbar > trough > block:not(.empty) { border-color: #1b6acb; background-color: #1b6acb; }
 +
 +levelbar > trough > block.full { border-color: #33d17a; background-color: #33d17a; }
 +
 +levelbar > trough > block.empty { background-color: #f1f0ee; border-color: #f1f0ee; }
 +
 +/**************** Print dialog * */
 +window.dialog.print drawing { color: #272c2e; background: none; border: none; padding: 0; }
 +
 +window.dialog.print drawing paper { background: white; color: #2e3436; border: 1px solid #877b6e; }
 +
 +window.dialog.print .dialog-action-box { margin: 12px; }
 +
 +/********** Frames * */
 +frame, .frame { border: 1px solid #877b6e; }
 +
 +frame { border-radius: 8px; }
 +
 +frame > label { margin: 4px; }
 +
 +actionbar > revealer > box { padding: 6px; border-top: 1px solid #877b6e; }
 +
 +actionbar > revealer > box, actionbar > revealer > box > box.start, actionbar > revealer > box > box.end { border-spacing: 6px; }
 +
 +scrolledwindow > overshoot.top { background-image: radial-gradient(farthest-side at top, #6b6157 85%, rgba(107, 97, 87, 0)), radial-gradient(farthest-side at top, rgba(39, 44, 46, 0.07), rgba(39, 44, 46, 0)); background-size: 100% 3%, 100% 50%; background-repeat: no-repeat; background-position: top; background-color: transparent; border: none; box-shadow: none; }
 +
 +scrolledwindow > overshoot.bottom { background-image: radial-gradient(farthest-side at bottom, #6b6157 85%, rgba(107, 97, 87, 0)), radial-gradient(farthest-side at bottom, rgba(39, 44, 46, 0.07), rgba(39, 44, 46, 0)); background-size: 100% 3%, 100% 50%; background-repeat: no-repeat; background-position: bottom; background-color: transparent; border: none; box-shadow: none; }
 +
 +scrolledwindow > overshoot.left { background-image: radial-gradient(farthest-side at left, #6b6157 85%, rgba(107, 97, 87, 0)), radial-gradient(farthest-side at left, rgba(39, 44, 46, 0.07), rgba(39, 44, 46, 0)); background-size: 3% 100%, 50% 100%; background-repeat: no-repeat; background-position: left; background-color: transparent; border: none; box-shadow: none; }
 +
 +scrolledwindow > overshoot.right { background-image: radial-gradient(farthest-side at right, #6b6157 85%, rgba(107, 97, 87, 0)), radial-gradient(farthest-side at right, rgba(39, 44, 46, 0.07), rgba(39, 44, 46, 0)); background-size: 3% 100%, 50% 100%; background-repeat: no-repeat; background-position: right; background-color: transparent; border: none; box-shadow: none; }
 +
 +scrolledwindow > junction { background: #877b6e, linear-gradient(to bottom, transparent 1px, #cecece 1px), linear-gradient(to right, transparent 1px, #cecece 1px); }
 +
 +scrolledwindow > junction:dir(rtl) { background: #877b6e, linear-gradient(to bottom, transparent 1px, #cecece 1px), linear-gradient(to left, transparent 1px, #cecece 1px); }
 +
 +separator { background: #93877b; min-width: 1px; min-height: 1px; }
 +
 +/********* Lists * */
 +listview, list { color: black; background-color: #ffffff; border-color: #877b6e; }
 +
 +listview:backdrop, list:backdrop { color: #323232; background-color: #fcfcfc; border-color: #d5d0cc; }
 +
 +listview > row, list > row { padding: 2px; }
 +
 +listview > row.expander, list > row.expander { padding: 0px; }
 +
 +listview > row.expander .row-header, list > row.expander .row-header { padding: 2px; }
 +
 +listview.horizontal row.separator, listview.separators.horizontal > row:not(.separator), list.horizontal row.separator, list.separators.horizontal > row:not(.separator) { border-left: 1px solid #9f958b; }
 +
 +listview:not(.horizontal) row.separator, listview.separators:not(.horizontal) > row:not(.separator), list:not(.horizontal) row.separator, list.separators:not(.horizontal) > row:not(.separator) { border-bottom: 1px solid #9f958b; }
 +
 +row { transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +row { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +row:focus:focus-visible { outline-color: rgba(27, 106, 203, 0.8); outline-width: 2px; outline-offset: -2px; }
 +
 +row.activatable.has-open-popup, row.activatable:hover { background-color: rgba(39, 44, 46, 0.05); }
 +
 +row.activatable:active { box-shadow: inset 0 2px 2px -2px rgba(0, 0, 0, 0.2); }
 +
 +row.activatable:selected:active { box-shadow: inset 0 2px 3px -1px rgba(0, 0, 0, 0.5); }
 +
 +row.activatable.has-open-popup:selected, row.activatable:selected:hover { background-color: #1c64bb; }
 +
 +row:selected { outline-color: white; }
 +
 +columnview > listview > row { padding: 0; }
 +
 +columnview > listview > row > cell { padding: 8px 6px; }
 +
 +columnview > listview > row > cell:not(:first-child) { border-left: 1px solid transparent; }
 +
 +columnview.column-separators > listview > row > cell { border-left-color: #9f958b; }
 +
 +columnview.data-table > listview > row > cell { padding-top: 2px; padding-bottom: 2px; }
 +
 +treeexpander { border-spacing: 4px; }
 +
 +/******************************************************** Data Tables                                          * treeview like tables with individual focusable cells * https://gitlab.gnome.org/GNOME/gtk/-/issues/2929     * */
 +columnview row:not(:selected) cell editablelabel:not(.editing):focus-within { outline: 2px solid rgba(27, 106, 203, 0.8); }
 +
 +columnview row:not(:selected) cell editablelabel.editing:focus-within { outline: 2px solid #1b6acb; }
 +
 +columnview row:not(:selected) cell editablelabel.editing text selection { color: #ffffff; background-color: #1b6acb; }
 +
 +/******************************************************* Rich Lists                                          * Large list usually containing lots of widgets       * https://gitlab.gnome.org/GNOME/gtk/-/issues/3073    * */
 +.rich-list { /* rich lists usually containing other widgets than just labels/text */ }
 +
 +.rich-list > row { padding: 8px 12px; min-height: 32px; /* should be tall even when only containing a label */ }
 +
 +.rich-list > row > box { border-spacing: 12px; }
 +
 +/********************* App Notifications * */
 +.app-notification { padding: 10px; border-spacing: 10px; border-radius: 0 0 5px 5px; background-color: rgba(53, 53, 53, 0.7); background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.2), transparent 2px); background-clip: padding-box; }
 +
 +.app-notification border { border: none; }
 +
 +/************* Expanders * */
 +expander { min-width: 16px; min-height: 16px; -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); }
 +
 +expander:dir(rtl) { -gtk-icon-source: -gtk-icontheme("pan-end-symbolic-rtl"); }
 +
 +expander:disabled { color: #929495; }
 +
 +expander:checked { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
 +
 +expander-widget { transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +expander-widget > box > title { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +expander-widget:focus:focus-visible > box > title { outline-color: rgba(27, 106, 203, 0.8); outline-width: 2px; outline-offset: -2px; }
 +
 +expander-widget > box > title { transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); border-radius: 5px; }
 +
 +expander-widget > box > title:hover > expander { color: #6d7c80; }
 +
 +.navigation-sidebar:not(decoration):not(window):drop(active):focus, .navigation-sidebar:not(decoration):not(window):drop(active), placessidebar:not(decoration):not(window):drop(active):focus, placessidebar:not(decoration):not(window):drop(active), stackswitcher:not(decoration):not(window):drop(active):focus, stackswitcher:not(decoration):not(window):drop(active), expander-widget:not(decoration):not(window):drop(active):focus, expander-widget:not(decoration):not(window):drop(active) { box-shadow: none; }
 +
 +/************ Calendar * */
 +calendar { color: black; border: 1px solid #877b6e; }
 +
 +calendar > header { border-bottom: 1px solid #877b6e; }
 +
 +calendar > header > button { border: none; box-shadow: none; background: none; border-radius: 0; }
 +
 +calendar > header > button:backdrop { background: none; }
 +
 +calendar > grid > label.today { box-shadow: inset 0px -2px #877b6e; }
 +
 +calendar > grid > label.today:selected { box-shadow: none; }
 +
 +calendar > grid > label:focus { outline-color: rgba(27, 106, 203, 0.8); outline-offset: -2px; outline-width: 2px; outline-style: solid; }
 +
 +calendar > grid > label.day-number { padding: 4px; }
 +
 +calendar > grid > label.day-number:selected { border-radius: 3px; }
 +
 +calendar > grid > label.day-number.other-month { color: alpha(currentColor,0.3); }
 +
 +/*********** Dialogs * */
 +window.dialog.message .titlebar { min-height: 20px; background-image: none; background-color: #fdfdfc; border-style: none; border-top-left-radius: 7px; border-top-right-radius: 7px; }
 +
 +window.dialog.message box.dialog-vbox.vertical { border-spacing: 10px; }
 +
 +window.dialog.message label.title { font-weight: 800; font-size: 15pt; }
 +
 +window.dialog.message.csd.background { border-bottom-left-radius: 9px; border-bottom-right-radius: 9px; }
 +
 +window.dialog.message.csd .dialog-action-area button { padding: 10px 14px; border-radius: 0; border-left-style: solid; border-right-style: none; border-bottom-style: none; }
 +
 +window.dialog.message.csd .dialog-action-area button:first-child { border-left-style: none; border-bottom-left-radius: 7px; }
 +
 +window.dialog.message.csd .dialog-action-area button:last-child { border-bottom-right-radius: 7px; }
 +
 +filechooser .dialog-action-box { border-top: 1px solid #877b6e; }
 +
 +filechooser #pathbarbox { border-bottom: 1px solid #fdfdfc; }
 +
 +filechooserbutton > button > box { border-spacing: 6px; }
 +
 +filechooserbutton:drop(active) { box-shadow: none; border-color: transparent; }
 +
 +/*********** Sidebar * */
 +.sidebar { background-color: #fefefe; }
 +
 +.sidebar:not(separator):dir(ltr), .sidebar.left:not(separator), .sidebar.left:not(separator):dir(rtl) { border-right: 1px solid #877b6e; border-left-style: none; }
 +
 +.sidebar:not(separator):dir(rtl), .sidebar.right:not(separator) { border-left: 1px solid #877b6e; border-right-style: none; }
 +
 +.sidebar listview.view, .sidebar list { background-color: transparent; }
 +
 +paned .sidebar.left, paned .sidebar.right, paned .sidebar.left:dir(rtl), paned .sidebar:dir(rtl), paned .sidebar:dir(ltr), paned .sidebar { border-style: none; }
 +
 +stacksidebar list.separators:not(.horizontal) > row:not(.separator) { border-bottom: none; }
 +
 +stacksidebar row { padding: 10px 4px; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +stacksidebar row { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +stacksidebar row:focus:focus-visible { outline-color: rgba(27, 106, 203, 0.8); outline-width: 2px; outline-offset: -2px; }
 +
 +stacksidebar row > label { padding-left: 6px; padding-right: 6px; }
 +
 +stacksidebar row.needs-attention > label { background-size: 6px 6px, 0 0; }
 +
 +stacksidebar row:selected { background-color: #e6e3e0; border-radius: 5px; color: #272c2e; }
 +
 +stacksidebar row:selected:hover:dir(ltr), stacksidebar row:selected:hover:dir(rtl) { background-color: #dad6d2; }
 +
 +stacksidebar row.activatable:active, stacksidebar row.activatable:selected:active { box-shadow: none; }
 +
 +separator.sidebar { background-color: #877b6e; }
 +
 +/********************** Navigation Sidebar * */
 +.navigation-sidebar { padding: 5px 0; }
 +
 +.navigation-sidebar > separator { margin: 5px; }
 +
 +.navigation-sidebar > row { min-height: 36px; padding: 0 8px; border-radius: 5px; margin: 0 5px 2px; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +.navigation-sidebar > row { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +.navigation-sidebar > row:focus-visible:focus-within { outline-color: rgba(27, 106, 203, 0.8); outline-width: 2px; outline-offset: -2px; }
 +
 +.navigation-sidebar > row:hover { background-color: #dad6d2; }
 +
 +.navigation-sidebar > row:selected { background-color: #e6e3e0; color: inherit; }
 +
 +.navigation-sidebar > row:selected:hover { background-color: #dad6d2; }
 +
 +.navigation-sidebar > row:disabled { color: #929495; }
 +
 +/**************** File chooser * */
 +row image.sidebar-icon { opacity: 0.7; }
 +
 +/* this should be more generic, only using .navigation-sidebar https://gitlab.gnome.org/GNOME/gtk/-/issues/2929 */
 +placessidebar .navigation-sidebar > row { padding: 0; }
 +
 +placessidebar .navigation-sidebar > row > revealer { padding: 0 14px; }
 +
 +placessidebar .navigation-sidebar > row image.sidebar-icon:dir(ltr) { padding-right: 8px; }
 +
 +placessidebar .navigation-sidebar > row image.sidebar-icon:dir(rtl) { padding-left: 8px; }
 +
 +placessidebar .navigation-sidebar > row label.sidebar-label:dir(ltr) { padding-right: 2px; }
 +
 +placessidebar .navigation-sidebar > row label.sidebar-label:dir(rtl) { padding-left: 2px; }
 +
 +button.sidebar-button { min-height: 26px; min-width: 26px; margin-top: 3px; margin-bottom: 3px; padding: 0; border-radius: 100%; }
 +
 +placessidebar .navigation-sidebar > row:selected:active { box-shadow: none; }
 +
 +placessidebar .navigation-sidebar > row.sidebar-placeholder-row { padding: 0 8px; min-height: 2px; background-image: image(#2ec27e); background-clip: content-box; }
 +
 +placessidebar .navigation-sidebar > row.sidebar-new-bookmark-row { color: #1b6acb; }
 +
 +placessidebar .navigation-sidebar > row:drop(active):not(:disabled) { color: #2ec27e; box-shadow: inset 0 1px #2ec27e, inset 0 -1px #2ec27e; }
 +
 +placessidebar .navigation-sidebar > row:drop(active):not(:disabled):selected { color: #ffffff; background-color: #2ec27e; }
 +
 +placesview .server-list-button > image { transition: 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); -gtk-icon-transform: rotate(0turn); }
 +
 +placesview .server-list-button:checked > image { transition: 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); -gtk-icon-transform: rotate(-0.5turn); }
 +
 +placesview > actionbar > revealer > box > box { border-spacing: 6px; }
 +
 +/********* Paned * */
 +paned > separator { min-width: 1px; min-height: 1px; -gtk-icon-source: none; border-style: none; background-color: transparent; background-image: image(#877b6e); background-size: 1px 1px; }
 +
 +paned > separator:selected { background-image: image(#1b6acb); }
 +
 +paned > separator.wide { min-width: 5px; min-height: 5px; background-color: #fdfdfc; background-image: image(#877b6e), image(#877b6e); background-size: 1px 1px, 1px 1px; }
 +
 +paned.horizontal > separator { background-repeat: repeat-y; }
 +
 +paned.horizontal > separator:dir(ltr) { margin: 0 -8px 0 0; padding: 0 8px 0 0; background-position: left; }
 +
 +paned.horizontal > separator:dir(rtl) { margin: 0 0 0 -8px; padding: 0 0 0 8px; background-position: right; }
 +
 +paned.horizontal > separator.wide { margin: 0; padding: 0; background-repeat: repeat-y, repeat-y; background-position: left, right; }
 +
 +paned.vertical > separator { margin: 0 0 -8px 0; padding: 0 0 8px 0; background-repeat: repeat-x; background-position: top; }
 +
 +paned.vertical > separator.wide { margin: 0; padding: 0; background-repeat: repeat-x, repeat-x; background-position: bottom, top; }
 +
 +/************** GtkVideo * */
 +video { background: black; }
 +
 +video image.osd { min-width: 64px; min-height: 64px; border-radius: 32px; }
 +
 +/************ Tooltips * */
 +tooltip { padding: 6px 10px; border-radius: 8px; box-shadow: none; }
 +
 +tooltip.background { background-color: rgba(0, 0, 0, 0.8); background-clip: padding-box; border: 1px solid rgba(255, 255, 255, 0.1); color: white; }
 +
 +tooltip > box { border-spacing: 6px; }
 +
 +/***************** Color Chooser * */
 +colorswatch { transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +colorswatch { outline: 0 solid transparent; outline-offset: 6px; }
 +
 +colorswatch:focus:focus-visible { outline-color: rgba(27, 106, 203, 0.8); outline-width: 4px; outline-offset: -2px; }
 +
 +colorswatch:drop(active), colorswatch { border-style: none; }
 +
 +colorswatch.top { border-top-left-radius: 5.5px; border-top-right-radius: 5.5px; }
 +
 +colorswatch.top > overlay { border-top-left-radius: 5px; border-top-right-radius: 5px; }
 +
 +colorswatch.bottom { border-bottom-left-radius: 5.5px; border-bottom-right-radius: 5.5px; }
 +
 +colorswatch.bottom > overlay { border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; }
 +
 +colorswatch.left, colorswatch:first-child:not(.top) { border-top-left-radius: 5.5px; border-bottom-left-radius: 5.5px; }
 +
 +colorswatch.left > overlay, colorswatch:first-child:not(.top) > overlay { border-top-left-radius: 5px; border-bottom-left-radius: 5px; }
 +
 +colorswatch.right, colorswatch:last-child:not(.bottom) { border-top-right-radius: 5.5px; border-bottom-right-radius: 5.5px; }
 +
 +colorswatch.right > overlay, colorswatch:last-child:not(.bottom) > overlay { border-top-right-radius: 5px; border-bottom-right-radius: 5px; }
 +
 +colorswatch.dark > overlay { color: white; }
 +
 +colorswatch.dark.activatable:hover > overlay { border-color: rgba(0, 0, 0, 0.8); }
 +
 +colorswatch.light > overlay { color: black; }
 +
 +colorswatch.light.activatable:hover > overlay { border-color: rgba(0, 0, 0, 0.5); }
 +
 +colorswatch:drop(active) { box-shadow: none; }
 +
 +colorswatch.light:drop(active) > overlay { border-color: #2ec27e; box-shadow: inset 0 0 0 2px #27a56b, inset 0 0 0 1px #2ec27e; }
 +
 +colorswatch.dark:drop(active) > overlay { border-color: #2ec27e; box-shadow: inset 0 0 0 2px rgba(0, 0, 0, 0.3), inset 0 0 0 1px #2ec27e; }
 +
 +colorswatch > overlay { border: 1px solid rgba(0, 0, 0, 0.3); }
 +
 +colorswatch.activatable:hover > overlay { box-shadow: inset 0 1px rgba(255, 255, 255, 0.4), inset 0 -1px rgba(0, 0, 0, 0.2); }
 +
 +colorswatch#add-color-button { border-radius: 5px 0 0 5px; }
 +
 +colorswatch#add-color-button:only-child { border-radius: 5px; }
 +
 +colorswatch#add-color-button > overlay { color: #272c2e; outline-color: rgba(27, 106, 203, 0.8); border-color: #877b6e; background-image: linear-gradient(to top, #fafaf9 2px, white); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +colorswatch#add-color-button.activatable:hover > overlay { color: #272c2e; border-color: #877b6e; background-image: linear-gradient(to top, #dad6d2, #edebe9 1px); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +colorswatch:disabled { opacity: 0.5; }
 +
 +colorswatch:disabled > overlay { border-color: rgba(0, 0, 0, 0.6); box-shadow: none; }
 +
 +row:selected colorswatch { box-shadow: 0 0 0 2px #ffffff; }
 +
 +colorswatch#editor-color-sample { border-radius: 4px; }
 +
 +colorswatch#editor-color-sample > overlay { border-radius: 4.5px; }
 +
 +plane { transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +plane { outline: 0 solid transparent; outline-offset: 6px; }
 +
 +plane:focus:focus-visible { outline-color: rgba(27, 106, 203, 0.8); outline-width: 2px; outline-offset: 2px; }
 +
 +colorchooser .popover.osd { border-radius: 5px; }
 +
 +/******** Misc * */
 +.content-view { background-color: #edebe9; }
 +
 +.content-view:hover { -gtk-icon-filter: brightness(1.2); }
 +
 +.content-view .tile { margin: 2px; background-color: transparent; border-radius: 0; padding: 0; }
 +
 +.content-view .tile:active, .content-view .tile:selected { background-color: transparent; }
 +
 +.content-view .tile:disabled { background-color: transparent; }
 +
 +.osd .scale-popup button.flat { border-style: none; border-radius: 5px; }
 +
 +.scale-popup button:hover { background-color: rgba(39, 44, 46, 0.1); border-radius: 5px; }
 +
 +/********************** Window Decorations * */
 +window { border-width: 0px; }
 +
 +window.csd { box-shadow: 0 3px 9px 1px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(0, 0, 0, 0.23); margin: 0px; border-radius: 8px 8px 0 0; }
 +
 +window.csd:backdrop { box-shadow: 0 3px 9px 1px transparent, 0 2px 6px 2px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.18); transition: 200ms ease-out; }
 +
 +window.csd.popup { border-radius: 5px; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.13); }
 +
 +window.csd.dialog.message { border-radius: 8px; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.13); }
 +
 +window.solid-csd { margin: 0; padding: 4px; border: solid 1px #877b6e; border-radius: 0; box-shadow: inset 0 0 0 4px #877b6e, inset 0 0 0 3px white, inset 0 1px rgba(255, 255, 255, 0.8); }
 +
 +window.solid-csd:backdrop { box-shadow: inset 0 0 0 4px #877b6e, inset 0 0 0 3px #f6f5f4, inset 0 1px rgba(255, 255, 255, 0.8); }
 +
 +window.maximized, window.fullscreen { border-radius: 0; box-shadow: none; }
 +
 +window.tiled, window.tiled-top, window.tiled-left, window.tiled-right, window.tiled-bottom { border-radius: 0; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.18), 0 0 0 20px transparent; }
 +
 +window:backdrop { box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.18), 0 0 0 20px transparent; }
 +
 +window.popup { box-shadow: none; }
 +
 +window.ssd { box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.23); }
 +
 +tooltip.csd { border-radius: 5px; box-shadow: none; }
 +
 +.view:selected:focus, .view:selected, textview > text:selected:focus, textview > text:selected, textview > text > selection:focus, textview > text > selection, iconview:selected:focus, iconview:selected, flowbox > flowboxchild:selected, gridview > child:selected, entry > text > selection, modelbutton.flat:selected, spinbutton:not(.vertical) > text > selection, spinbutton.vertical > text > text > selection, spinbutton.vertical > text > selection, columnview.view:selected:focus, columnview.view:selected, treeview.view:selected:focus, treeview.view:selected, row:selected, calendar > grid > label.day-number:selected { background-color: #1b6acb; }
 +
 +label:selected, .view:selected:focus, .view:selected, textview > text:selected:focus, textview > text:selected, textview > text > selection:focus, textview > text > selection, iconview:selected:focus, iconview:selected, flowbox > flowboxchild:selected, gridview > child:selected, entry > text > selection, modelbutton.flat:selected, spinbutton:not(.vertical) > text > selection, spinbutton.vertical > text > text > selection, spinbutton.vertical > text > selection, columnview.view:selected:focus, columnview.view:selected, treeview.view:selected:focus, treeview.view:selected, row:selected, calendar > grid > label.day-number:selected { color: #ffffff; }
 +
 +label:disabled > selection, label:disabled:selected, .view:disabled:selected, textview > text:disabled:selected:focus, textview > text:disabled:selected, textview > text > selection:disabled, iconview:disabled:selected:focus, iconview:disabled:selected, flowbox > flowboxchild:disabled:selected, gridview > child:disabled:selected, entry > text > selection:disabled, modelbutton.flat:disabled:selected, spinbutton:not(.vertical) > text > selection:disabled, spinbutton.vertical > text > text > selection:disabled, spinbutton.vertical > text > selection:disabled, columnview.view:disabled:selected, treeview.view:disabled:selected, row:disabled:selected, calendar > grid > label.day-number:disabled:selected { color: #8db5e5; }
 +
 +.monospace { font-family: monospace; }
 +
 +/********************** Touch Copy & Paste * */
 +cursor-handle { background-color: transparent; background-image: none; box-shadow: none; border-style: none; min-width: 20px; min-height: 24px; padding-left: 20px; padding-right: 20px; padding-top: 24px; padding-bottom: 24px; }
 +
 +cursor-handle.top:dir(ltr), cursor-handle.bottom:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets-hc/text-select-start.png"), url("assets-hc/text-select-start@2.png")); }
 +
 +cursor-handle.bottom:dir(ltr), cursor-handle.top:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets-hc/text-select-end.png"), url("assets-hc/text-select-end@2.png")); }
 +
 +cursor-handle.insertion-cursor:dir(ltr), cursor-handle.insertion-cursor:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets-hc/slider-horz-scale-has-marks-above.png"), url("assets-hc/slider-horz-scale-has-marks-above@2.png")); }
 +
 +cursor-handle.top:hover:dir(ltr), cursor-handle.bottom:hover:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets-hc/text-select-start-hover.png"), url("assets-hc/text-select-start-hover@2.png")); }
 +
 +cursor-handle.bottom:hover:dir(ltr), cursor-handle.top:hover:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets-hc/text-select-end-hover.png"), url("assets-hc/text-select-end-hover@2.png")); }
 +
 +cursor-handle.insertion-cursor:hover:dir(ltr), cursor-handle.insertion-cursor:hover:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets-hc/slider-horz-scale-has-marks-above-hover.png"), url("assets-hc/slider-horz-scale-has-marks-above-hover@2.png")); }
 +
 +cursor-handle.top:active:dir(ltr), cursor-handle.bottom:active:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets-hc/text-select-start-active.png"), url("assets-hc/text-select-start-active@2.png")); }
 +
 +cursor-handle.bottom:active:dir(ltr), cursor-handle.top:active:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets-hc/text-select-end-active.png"), url("assets-hc/text-select-end-active@2.png")); }
 +
 +cursor-handle.insertion-cursor:active:dir(ltr), cursor-handle.insertion-cursor:active:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets-hc/slider-horz-scale-has-marks-above-active.png"), url("assets-hc/slider-horz-scale-has-marks-above-active@2.png")); }
 +
 +shortcuts-section { margin: 20px; }
 +
 +.shortcuts-search-results { margin: 20px; border-spacing: 24px; }
 +
 +shortcut { border-spacing: 6px; }
 +
 +shortcut > .keycap { min-width: 20px; min-height: 25px; margin-top: 2px; padding-bottom: 3px; padding-left: 6px; padding-right: 6px; color: #272c2e; background-color: #ffffff; border: 1px solid; border-color: #c2bcb5; border-radius: 5px; box-shadow: inset 0 -3px #fdfdfd; font-size: smaller; }
 +
 +:not(decoration):not(window):drop(active):focus, :not(decoration):not(window):drop(active) { border-color: #2ec27e; box-shadow: inset 0 0 0 1px #2ec27e; caret-color: #2ec27e; }
 +
 +stackswitcher > button.text-button { min-width: 100px; }
 +
 +stackswitcher.circular { border-spacing: 12px; }
 +
 +stackswitcher.circular > button.circular, stackswitcher.circular > button.text-button.circular { min-width: 32px; min-height: 32px; padding: 0; }
 +
 +/************* App Icons * */
 +/* Outline for low res icons */
 +.lowres-icon { -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.05), 1px 0 rgba(0, 0, 0, 0.1), 0 1px rgba(0, 0, 0, 0.3), -1px 0 rgba(0, 0, 0, 0.1); }
 +
 +/* Drapshadow for large icons */
 +.icon-dropshadow { -gtk-icon-shadow: 0 1px 12px rgba(0, 0, 0, 0.05), 0 -1px rgba(0, 0, 0, 0.05), 1px 0 rgba(0, 0, 0, 0.1), 0 1px rgba(0, 0, 0, 0.3), -1px 0 rgba(0, 0, 0, 0.1); }
 +
 +/********* Emoji * */
 +popover.emoji-picker > contents { padding: 0; }
 +
 +.emoji-searchbar { padding: 6px; border-spacing: 6px; border-bottom: 1px solid #877b6e; }
 +
 +.emoji-toolbar { padding: 6px; border-spacing: 6px; border-top: 1px solid #877b6e; }
 +
 +button.emoji-section { border-color: transparent; border-width: 3px; border-style: none none solid; border-radius: 0; padding: 3px 0 0; min-width: 32px; min-height: 28px; /* reset props inherited from the button style */ background: none; box-shadow: none; text-shadow: none; }
 +
 +button.emoji-section:hover { border-color: #877b6e; }
 +
 +button.emoji-section:checked { border-color: #1b6acb; }
 +
 +popover.emoji-picker emoji { font-size: x-large; padding: 6px; border-radius: 6px; }
 +
 +popover.emoji-picker emoji:focus, popover.emoji-picker emoji:hover { background: #1b6acb; }
 +
 +emoji-completion-row > box { border-spacing: 10px; padding: 2px 10px; }
 +
 +emoji-completion-row:focus, emoji-completion-row:hover { background-color: #1b6acb; color: #ffffff; }
 +
 +emoji-completion-row emoji:focus, emoji-completion-row emoji:hover { background-color: #e6e3e0; }
 +
 +popover.entry-completion > contents { padding: 0; }
 +
 +statusbar { padding: 6px 10px 6px 10px; }
 +
 +menubutton > button > box { border-spacing: 6px; }
 +
 +menubutton arrow { min-height: 16px; min-width: 16px; }
 +
 +menubutton arrow.none { -gtk-icon-source: -gtk-icontheme("open-menu-symbolic"); }
 +
 +menubutton arrow.down { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
 +
 +menubutton arrow.up { -gtk-icon-source: -gtk-icontheme("pan-up-symbolic"); }
 +
 +menubutton arrow.left { -gtk-icon-source: -gtk-icontheme("pan-start-symbolic"); }
 +
 +menubutton arrow.right { -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); }
index 43d1f46aef36ad64d8ad69a112fc1f4351c6c209,0000000000000000000000000000000000000000..9b4d610ef82c9ff221010577b5fe7e1ae2f0da9c
mode 100644,000000..100644
--- /dev/null
@@@ -1,1870 -1,0 +1,1860 @@@
- button.sidebar-button, notebook > header > tabs > arrow, windowcontrols button, notebook > header > tabs > arrow.flat, button.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; transition: none; }
 +/*************************** Check and Radio buttons * */
 +/*************** Base States * */
 +.background { color: #2e3436; background-color: #f6f5f4; }
 +
 +.background:backdrop { text-shadow: none; -gtk-icon-shadow: none; }
 +
 +dnd { color: #2e3436; }
 +
 +.normal-icons { -gtk-icon-size: 16px; }
 +
 +.large-icons { -gtk-icon-size: 32px; }
 +
 +image:disabled { -gtk-icon-filter: opacity(0.5); }
 +
 +.view, iconview, textview > text { color: black; background-color: #ffffff; }
 +
 +.view:disabled, iconview:disabled, textview > text:disabled { color: #929595; background-color: #faf9f8; }
 +
 +.view:selected:focus, iconview:selected:focus, .view:selected, iconview:selected, textview > text:selected:focus, textview > text:selected { border-radius: 3px; }
 +
 +textview:drop(active) { caret-color: #2ec27e; }
 +
 +textview > border { background-color: #fbfafa; }
 +
 +iconview { transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +iconview { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +iconview:focus:focus-visible { outline-color: rgba(53, 132, 228, 0.5); outline-width: 2px; outline-offset: -2px; }
 +
 +iconview:drop(active) { box-shadow: none; }
 +
 +iconview > dndtarget:drop(active) { border-style: solid; border-width: 1px; border-color: #185fb4; }
 +
 +rubberband, .content-view > rubberband, columnview.view > rubberband, treeview.view > rubberband, gridview > rubberband, flowbox > rubberband { border: 1px solid #1b6acb; background-color: rgba(27, 106, 203, 0.2); }
 +
 +flowbox > flowboxchild { padding: 3px; transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +flowbox > flowboxchild { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +flowbox > flowboxchild:focus:focus-visible { outline-color: rgba(53, 132, 228, 0.5); outline-width: 2px; outline-offset: -2px; }
 +
 +flowbox > flowboxchild:selected { outline-color: rgba(255, 255, 255, 0.8); }
 +
 +gridview > child { padding: 3px; transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +gridview > child { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +gridview > child:focus:focus-visible { outline-color: rgba(53, 132, 228, 0.5); outline-width: 2px; outline-offset: -2px; }
 +
 +gridview > child:selected { outline-color: rgba(255, 255, 255, 0.8); }
 +
 +gridview > child box { border-spacing: 8px; margin: 12px; }
 +
 +coverflow cover { color: black; background-color: #ffffff; border: 1px solid black; }
 +
 +label { transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +label { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +label:focus:focus-visible { outline-color: rgba(53, 132, 228, 0.5); outline-width: 2px; outline-offset: -2px; }
 +
 +label > selection { background-color: #3584e4; color: #ffffff; }
 +
 +label:disabled { color: #929595; }
 +
 +button label:disabled { color: inherit; }
 +
 +label.error { color: #cc0000; }
 +
 +label.error:disabled { color: rgba(204, 0, 0, 0.5); }
 +
 +.dim-label, .titlebar:not(headerbar) .subtitle, headerbar .subtitle, spinbutton.vertical > text > text > placeholder, spinbutton:not(.vertical) > text > placeholder, entry > text > placeholder, label.separator { opacity: 0.55; text-shadow: none; }
 +
 +window.assistant .sidebar { padding: 5px; border-top: 1px solid #cdc7c2; }
 +
 +window.assistant.csd .sidebar { border-top-style: none; }
 +
 +window.assistant .sidebar > label { padding: 6px 12px; }
 +
 +window.assistant .sidebar > label.highlight { background-color: #e8e6e3; border-radius: 5px; }
 +
 +window.aboutdialog image.large-icons { -gtk-icon-size: 128px; }
 +
 +.osd .scale-popup, .app-notification, .osd popover.background > arrow, .osd popover.background > contents, popover.background.touch-selection > arrow, popover.background.touch-selection > contents, popover.background.magnifier > arrow, popover.background.magnifier > contents, .osd { color: #eeeeec; border: none; background-color: rgba(53, 53, 53, 0.7); background-clip: padding-box; -gtk-icon-shadow: 0 1px black; }
 +
 +/********************* Spinner Animation * */
 +@keyframes spin { to { transform: rotate(1turn); } }
 +
 +spinner { background: none; opacity: 0; -gtk-icon-source: -gtk-icontheme("process-working-symbolic"); }
 +
 +spinner:checked { opacity: 1; animation: spin 1s linear infinite; }
 +
 +spinner:checked:disabled { opacity: 0.5; }
 +
 +/********************** General Typography * */
 +.large-title { font-weight: 300; font-size: 24pt; }
 +
 +.title-1 { font-weight: 800; font-size: 20pt; }
 +
 +.title-2 { font-weight: 800; font-size: 15pt; }
 +
 +.title-3 { font-weight: 700; font-size: 15pt; }
 +
 +.title-4 { font-weight: 700; font-size: 13pt; }
 +
 +.heading { font-weight: 700; font-size: 11pt; }
 +
 +.body { font-weight: 400; font-size: 11pt; }
 +
 +.caption-heading { font-weight: 700; font-size: 9pt; }
 +
 +.caption { font-weight: 400; font-size: 9pt; }
 +
 +/**************** Text Entries * */
 +spinbutton.vertical > text, spinbutton:not(.vertical), entry { min-height: 32px; padding-left: 8px; padding-right: 8px; border: 1px solid; border-radius: 5px; border-spacing: 6px; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); color: black; border-color: #cdc7c2; background-color: #ffffff; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +spinbutton.vertical > text, spinbutton:not(.vertical), entry { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +spinbutton.vertical > text:focus-within, spinbutton:focus-within:not(.vertical), entry:focus-within { outline-color: rgba(53, 132, 228, 0.5); outline-width: 2px; outline-offset: -2px; }
 +
 +spinbutton.vertical > text > image.left, spinbutton:not(.vertical) > image.left, entry > image.left { margin-right: 6px; }
 +
 +spinbutton.vertical > text > image.right, spinbutton:not(.vertical) > image.right, entry > image.right { margin-left: 6px; }
 +
 +spinbutton.vertical > text > text > block-cursor, spinbutton:not(.vertical) > text > block-cursor, entry > text > block-cursor { color: #ffffff; background-color: black; }
 +
 +spinbutton.vertical > text.flat, spinbutton.flat:not(.vertical), entry.flat:focus-within, entry.flat:backdrop, entry.flat:disabled, entry.flat { min-height: 0; padding: 2px; background-color: transparent; border-color: transparent; border-radius: 0; }
 +
 +spinbutton.vertical > text:focus-within > placeholder, spinbutton:focus-within:not(.vertical) > placeholder, entry:focus-within > placeholder { opacity: 0; /* We hide placeholders on focus */ }
 +
 +spinbutton.vertical > text:disabled, spinbutton:disabled:not(.vertical), entry:disabled { color: #929595; border-color: #cdc7c2; background-color: #faf9f8; }
 +
 +spinbutton.vertical > text.error, spinbutton.error:not(.vertical), entry.error { color: #cc0000; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +spinbutton.vertical > text.error, spinbutton.error:not(.vertical), entry.error { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +spinbutton.vertical > text.error:focus-within, spinbutton.error:focus-within:not(.vertical), entry.error:focus-within { outline-color: rgba(204, 0, 0, 0.5); outline-width: 2px; outline-offset: -2px; }
 +
 +spinbutton.vertical > text.error > selection, spinbutton.error:not(.vertical) > selection, entry.error > selection { background-color: #cc0000; }
 +
 +spinbutton.vertical > text.warning, spinbutton.warning:not(.vertical), entry.warning { color: #f57900; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +spinbutton.vertical > text.warning, spinbutton.warning:not(.vertical), entry.warning { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +spinbutton.vertical > text.warning:focus-within, spinbutton.warning:focus-within:not(.vertical), entry.warning:focus-within { outline-color: rgba(245, 121, 0, 0.5); outline-width: 2px; outline-offset: -2px; }
 +
 +spinbutton.vertical > text.warning > selection, spinbutton.warning:not(.vertical) > selection, entry.warning > selection { background-color: #f57900; }
 +
 +spinbutton.vertical > text > image, spinbutton:not(.vertical) > image, entry > image { color: #585d5e; }
 +
 +spinbutton.vertical > text > image:hover, spinbutton:not(.vertical) > image:hover, entry > image:hover { color: #2e3436; }
 +
 +spinbutton.vertical > text > image:active, spinbutton:not(.vertical) > image:active, entry > image:active { color: #3584e4; }
 +
 +spinbutton.vertical > text.password image.caps-lock-indicator, spinbutton.password:not(.vertical) image.caps-lock-indicator, entry.password image.caps-lock-indicator { color: #a7aaaa; }
 +
 +spinbutton.vertical > text:drop(active), spinbutton:drop(active):not(.vertical), entry:drop(active):focus-within, entry:drop(active) { border-color: #2ec27e; box-shadow: inset 0 0 0 1px #2ec27e; }
 +
 +.osd spinbutton.vertical > text, .osd spinbutton:not(.vertical), .osd entry { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: rgba(0, 0, 0, 0.5); background-clip: padding-box; box-shadow: none; -gtk-icon-shadow: 0 1px black; }
 +
 +.osd spinbutton.vertical > text:focus-within, .osd spinbutton:focus-within:not(.vertical), .osd entry:focus-within { color: white; border-color: #3584e4; background-color: rgba(0, 0, 0, 0.5); background-clip: padding-box; }
 +
 +.osd spinbutton.vertical > text:disabled, .osd spinbutton:disabled:not(.vertical), .osd entry:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: rgba(71, 71, 71, 0.5); background-clip: padding-box; }
 +
 +spinbutton.vertical > text > progress, spinbutton:not(.vertical) > progress, entry > progress { margin-bottom: 2px; }
 +
 +spinbutton.vertical > text progress > trough > progress, spinbutton:not(.vertical) progress > trough > progress, entry progress > trough > progress { background-color: transparent; background-image: none; border-radius: 0; border-width: 0 0 2px; border-color: #3584e4; border-style: solid; box-shadow: none; }
 +
 +spinbutton.vertical.linked:not(.vertical) > text:drop(active) + text, spinbutton.vertical.linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + text, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + spinbutton:not(.vertical), .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + spinbutton:not(.vertical), spinbutton.vertical.linked:not(.vertical) > text:drop(active) + button, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + button, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + menubutton > button, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + menubutton > button, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + dropdown > button, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + dropdown > button, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + colorbutton > button, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + colorbutton > button, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + fontbutton > button, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + fontbutton > button, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + filechooserbutton > button, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + filechooserbutton > button, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + combobox > box > button.combo, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + combobox > box > button.combo, spinbutton.vertical.linked:not(.vertical) > text:drop(active) + entry, .linked:not(.vertical) > spinbutton:drop(active):not(.vertical) + entry, .linked:not(.vertical) > entry:drop(active) + button, .linked:not(.vertical) > entry:drop(active) + menubutton > button, .linked:not(.vertical) > entry:drop(active) + dropdown > button, .linked:not(.vertical) > entry:drop(active) + colorbutton > button, .linked:not(.vertical) > entry:drop(active) + fontbutton > button, .linked:not(.vertical) > entry:drop(active) + filechooserbutton > button, .linked:not(.vertical) > entry:drop(active) + combobox > box > button.combo, spinbutton.vertical.linked:not(.vertical) > entry:drop(active) + text, .linked:not(.vertical) > entry:drop(active) + spinbutton:not(.vertical), .linked:not(.vertical) > entry:drop(active) + entry { border-left-color: #2ec27e; }
 +
 +spinbutton.vertical.linked > text:not(:disabled) + entry:not(:disabled), .linked.vertical > spinbutton:not(:disabled):not(.vertical) + entry:not(:disabled), spinbutton.vertical.linked > text:not(:disabled) + text:not(:disabled), spinbutton.vertical.linked > spinbutton:not(:disabled):not(.vertical) + text:not(:disabled), spinbutton.vertical.linked > text:not(:disabled) + spinbutton:not(:disabled):not(.vertical), .linked.vertical > spinbutton:not(:disabled):not(.vertical) + spinbutton:not(:disabled):not(.vertical), .linked.vertical > entry:not(:disabled) + entry:not(:disabled), spinbutton.vertical.linked > entry:not(:disabled) + text:not(:disabled), .linked.vertical > entry:not(:disabled) + spinbutton:not(:disabled):not(.vertical) { border-top-color: #f0eeed; }
 +
 +spinbutton.vertical.linked > text:disabled + text:disabled, spinbutton.vertical.linked > spinbutton:disabled:not(.vertical) + text:disabled, spinbutton.vertical.linked > text:disabled + spinbutton:disabled:not(.vertical), .linked.vertical > spinbutton:disabled:not(.vertical) + spinbutton:disabled:not(.vertical), spinbutton.vertical.linked > text:disabled + entry:disabled, .linked.vertical > spinbutton:disabled:not(.vertical) + entry:disabled, spinbutton.vertical.linked > entry:disabled + text:disabled, .linked.vertical > entry:disabled + spinbutton:disabled:not(.vertical), .linked.vertical > entry:disabled + entry:disabled { border-top-color: #f0eeed; }
 +
 +spinbutton.vertical.linked > text + text:drop(active):not(:only-child), spinbutton.vertical.linked > spinbutton:not(.vertical) + text:drop(active):not(:only-child), spinbutton.vertical.linked > text + spinbutton:drop(active):not(:only-child):not(.vertical), .linked.vertical > spinbutton:not(.vertical) + spinbutton:drop(active):not(:only-child):not(.vertical), spinbutton.vertical.linked > text + entry:drop(active):not(:only-child), .linked.vertical > spinbutton:not(.vertical) + entry:drop(active):not(:only-child), spinbutton.vertical.linked > entry + text:drop(active):not(:only-child), .linked.vertical > entry + spinbutton:drop(active):not(:only-child):not(.vertical), .linked.vertical > entry + entry:drop(active):not(:only-child) { border-top-color: #2ec27e; }
 +
 +spinbutton.vertical.linked > text:drop(active):not(:only-child) + text, spinbutton.vertical.linked > spinbutton:drop(active):not(:only-child):not(.vertical) + text, spinbutton.vertical.linked > text:drop(active):not(:only-child) + spinbutton:not(.vertical), .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + spinbutton:not(.vertical), spinbutton.vertical.linked > text:drop(active):not(:only-child) + entry, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + entry, spinbutton.vertical.linked > text:drop(active):not(:only-child) + button, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + button, spinbutton.vertical.linked > text:drop(active):not(:only-child) + menubutton > button, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + menubutton > button, spinbutton.vertical.linked > text:drop(active):not(:only-child) + dropdown > button, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + dropdown > button, spinbutton.vertical.linked > text:drop(active):not(:only-child) + colorbutton > button, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + colorbutton > button, spinbutton.vertical.linked > text:drop(active):not(:only-child) + fontbutton > button, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + fontbutton > button, spinbutton.vertical.linked > text:drop(active):not(:only-child) + filechooserbutton > button, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + filechooserbutton > button, spinbutton.vertical.linked > text:drop(active):not(:only-child) + combobox > box > button.combo, .linked.vertical > spinbutton:drop(active):not(:only-child):not(.vertical) + combobox > box > button.combo, spinbutton.vertical.linked > entry:drop(active):not(:only-child) + text, .linked.vertical > entry:drop(active):not(:only-child) + spinbutton:not(.vertical), .linked.vertical > entry:drop(active):not(:only-child) + entry, .linked.vertical > entry:drop(active):not(:only-child) + button, .linked.vertical > entry:drop(active):not(:only-child) + menubutton > button, .linked.vertical > entry:drop(active):not(:only-child) + dropdown > button, .linked.vertical > entry:drop(active):not(:only-child) + colorbutton > button, .linked.vertical > entry:drop(active):not(:only-child) + fontbutton > button, .linked.vertical > entry:drop(active):not(:only-child) + filechooserbutton > button, .linked.vertical > entry:drop(active):not(:only-child) + combobox > box > button.combo { border-top-color: #2ec27e; }
 +
 +spinbutton.vertical > text.error, spinbutton.error:not(.vertical), entry.error { color: #cc0000; }
 +
 +treeview entry:focus-within:dir(rtl), treeview entry:focus-within:dir(ltr) { background-color: #ffffff; transition-property: color, background; }
 +
 +treeview entry.flat, treeview entry { border-radius: 0; background-image: none; background-color: #ffffff; }
 +
 +treeview entry.flat:focus-within, treeview entry:focus-within { border-color: #3584e4; }
 +
 +/******************* Editable Labels * */
 +editablelabel > stack > text { color: black; border-color: #cdc7c2; background-color: #ffffff; }
 +
 +/*********** Buttons * */
 +@keyframes needs_attention { from { background-image: radial-gradient(farthest-side, #3584e4 0%, rgba(53, 132, 228, 0) 0%); }
 +  to { background-image: radial-gradient(farthest-side, #3584e4 95%, rgba(53, 132, 228, 0)); } }
 +
 +notebook > header > tabs > arrow, windowcontrols button, button { min-height: 24px; min-width: 16px; padding: 4px 9px; border: 1px solid; border-radius: 5px; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); color: #2e3436; outline-color: rgba(53, 132, 228, 0.5); border-color: #cdc7c2; background-image: linear-gradient(to top, #f6f5f4 2px, #fbfafa); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +notebook > header > tabs > arrow, windowcontrols button, button { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +notebook > header > tabs > arrow:focus:focus-visible, button:focus:focus-visible { outline-color: rgba(53, 132, 228, 0.5); outline-width: 2px; outline-offset: -2px; }
 +
 +notebook > header > tabs > arrow:hover, button:hover { color: #2e3436; border-color: #cdc7c2; background-image: linear-gradient(to top, #d6d1cd, #e8e6e3 1px); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); -gtk-icon-filter: brightness(1.2); }
 +
 +notebook > header > tabs > arrow.keyboard-activating, notebook > header > tabs > arrow:active, notebook > header > tabs > arrow:checked, button.keyboard-activating, button:active, button:checked { color: #2e3436; border-color: #cdc7c2; background-image: image(#dad6d2); box-shadow: none; transition-duration: 50ms; }
 +
 +notebook > header > tabs > arrow:checked:hover, button:checked:hover { color: #2e3436; border-color: #cdc7c2; background-image: image(#d1ccc7); box-shadow: none; }
 +
 +notebook > header > tabs > arrow:checked:active, button:checked:active { color: #2e3436; border-color: #cdc7c2; background-image: image(#c8c2bc); box-shadow: none; }
 +
 +notebook > header > tabs > arrow:backdrop, button.flat:backdrop, button:backdrop { color: #929595; border-color: #d5d0cc; background-image: image(#f6f5f4); box-shadow: none; transition: 200ms ease-out; }
 +
 +notebook > header > tabs > arrow:backdrop:not(:disabled), button.flat:backdrop:not(:disabled), button:backdrop:not(:disabled) { -gtk-icon-filter: none; }
 +
 +notebook > header > tabs > arrow:backdrop:active, notebook > header > tabs > arrow:backdrop:checked, button.flat:backdrop:active, button.flat:backdrop:checked, button:backdrop:active, button:backdrop:checked { color: #929595; border-color: #d5d0cc; background-image: image(#e9e9e3); box-shadow: none; }
 +
 +notebook > header > tabs > arrow:backdrop:disabled, button.flat:backdrop:disabled, button:backdrop:disabled { color: #d4cfca; border-color: #d5d0cc; background-image: image(#faf9f8); box-shadow: none; }
 +
 +notebook > header > tabs > arrow:backdrop:disabled:active, notebook > header > tabs > arrow:backdrop:disabled:checked, button.flat:backdrop:disabled:active, button.flat:backdrop:disabled:checked, button:backdrop:disabled:active, button:backdrop:disabled:checked { color: #d4cfca; border-color: #d5d0cc; background-image: image(#e9e9e3); box-shadow: none; }
 +
 +notebook > header > tabs > arrow:disabled, button:disabled { color: #929595; border-color: #d5d0cc; background-image: image(#faf9f8); -gtk-icon-filter: opacity(0.5); }
 +
 +notebook > header > tabs > arrow:disabled:active, notebook > header > tabs > arrow:disabled:checked, button:disabled:active, button:disabled:checked { color: #929595; border-color: #d5d0cc; background-image: image(#e9e9e3); box-shadow: none; }
 +
- button.sidebar-button:hover, notebook > header > tabs > arrow:hover, windowcontrols button:hover, button.flat:hover { border-color: transparent; background-image: none; box-shadow: none; background-color: #dad6d2; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-duration: 500ms; }
++button.sidebar-button, notebook > header > tabs > arrow, windowcontrols button, .toolbar button, notebook > header > tabs > arrow.flat, button.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; transition: none; }
 +
- button.keyboard-activating.sidebar-button, notebook > header > tabs > arrow.keyboard-activating, windowcontrols button.keyboard-activating, button.sidebar-button:active, notebook > header > tabs > arrow:active, windowcontrols button:active, button.sidebar-button:checked, notebook > header > tabs > arrow:checked, windowcontrols button:checked, button.flat.keyboard-activating, button.flat:active, button.flat:checked { border-color: transparent; background-image: none; box-shadow: none; background-color: #cdc7c2; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
++button.sidebar-button:hover, notebook > header > tabs > arrow:hover, windowcontrols button:hover, .toolbar button:hover, button.flat:hover { border-color: transparent; background-image: none; box-shadow: none; background-color: #dad6d2; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-duration: 500ms; }
 +
- button.sidebar-button:backdrop, notebook > header > tabs > arrow:backdrop, windowcontrols button:backdrop, button.sidebar-button:disabled, notebook > header > tabs > arrow:disabled, windowcontrols button:disabled, button.flat:backdrop, button.flat:disabled, button.flat:backdrop:disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; }
++button.keyboard-activating.sidebar-button, notebook > header > tabs > arrow.keyboard-activating, windowcontrols button.keyboard-activating, .toolbar button.keyboard-activating, button.sidebar-button:active, notebook > header > tabs > arrow:active, windowcontrols button:active, .toolbar button:active, button.sidebar-button:checked, notebook > header > tabs > arrow:checked, windowcontrols button:checked, .toolbar button:checked, button.flat.keyboard-activating, button.flat:active, button.flat:checked { border-color: transparent; background-image: none; box-shadow: none; background-color: #cdc7c2; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
 +
- .scale-popup button:hover, button.link, button.link:hover, button.link:active, button.link:checked, popover.menu box.circular-buttons button.circular.image-button.model, list > row button.image-button:not(.flat), .toolbar button, modelbutton.flat { background-color: transparent; background-image: none; border-color: transparent; box-shadow: inset 0 1px rgba(255, 255, 255, 0), 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
++button.sidebar-button:backdrop, notebook > header > tabs > arrow:backdrop, windowcontrols button:backdrop, .toolbar button:backdrop, button.sidebar-button:disabled, notebook > header > tabs > arrow:disabled, windowcontrols button:disabled, .toolbar button:disabled, button.flat:backdrop, button.flat:disabled, button.flat:backdrop:disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; }
 +
 +notebook > header > tabs > arrow.image-button, button.image-button { min-width: 24px; padding-left: 5px; padding-right: 5px; }
 +
 +notebook > header > tabs > arrow.text-button, button.text-button { padding-left: 16px; padding-right: 16px; }
 +
 +notebook > header > tabs > arrow.text-button.image-button, button.text-button.image-button { padding-left: 8px; padding-right: 8px; }
 +
 +notebook > header > tabs > arrow.text-button.image-button label, button.text-button.image-button label { padding-left: 8px; padding-right: 8px; }
 +
 +dropdown:drop(active) button.combo, combobox:drop(active) button.combo, notebook > header > tabs > arrow:drop(active), button:drop(active) { color: #2ec27e; border-color: #2ec27e; box-shadow: inset 0 0 0 1px #2ec27e; }
 +
 +row:selected button { border-color: #185fb4; }
 +
 +row:selected button.sidebar-button:not(:active):not(:checked):not(:hover):not(disabled), row:selected button.flat:not(:active):not(:checked):not(:hover):not(disabled) { color: #ffffff; border-color: transparent; }
 +
 +row:selected button.sidebar-button:not(:active):not(:checked):not(:hover):not(disabled):backdrop, row:selected button.flat:not(:active):not(:checked):not(:hover):not(disabled):backdrop { color: #fcfcfc; }
 +
 +button.osd { min-width: 26px; min-height: 32px; color: #eeeeec; border-radius: 5px; color: #eeeeec; outline-color: rgba(53, 132, 228, 0.5); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; border: none; box-shadow: none; }
 +
 +button.osd.image-button { min-width: 30px; }
 +
 +button.osd.image-button:only-child { margin: 4px; border-radius: 50%; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); }
 +
 +button.osd:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(27, 27, 27, 0.7)); background-clip: padding-box; border: none; box-shadow: none; }
 +
 +button.osd:active, button.osd:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(2, 2, 2, 0.7)); background-clip: padding-box; box-shadow: none; border: none; box-shadow: none; }
 +
 +.app-notification button, popover.background.touch-selection button, popover.background.magnifier button, .osd button { color: #eeeeec; outline-color: rgba(53, 132, 228, 0.5); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; }
 +
 +.app-notification button:hover, popover.background.touch-selection button:hover, popover.background.magnifier button:hover, .osd button:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(27, 27, 27, 0.7)); background-clip: padding-box; }
 +
 +.app-notification button:active, popover.background.touch-selection button:active, popover.background.magnifier button:active, .app-notification button:checked, popover.background.touch-selection button:checked, popover.background.magnifier button:checked, .osd button:active:backdrop, .osd button:active, .osd button:checked:backdrop, .osd button:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(2, 2, 2, 0.7)); background-clip: padding-box; box-shadow: none; }
 +
 +.app-notification button:disabled, popover.background.touch-selection button:disabled, popover.background.magnifier button:disabled, .osd button:disabled:backdrop, .osd button:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; }
 +
 +.app-notification button.flat, popover.background.touch-selection button.flat, popover.background.magnifier button.flat, .osd button.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; box-shadow: none; -gtk-icon-shadow: 0 1px black; }
 +
 +.app-notification button.flat:hover, popover.background.touch-selection button.flat:hover, popover.background.magnifier button.flat:hover, .osd button.flat:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(27, 27, 27, 0.7)); background-clip: padding-box; }
 +
 +.app-notification button.flat:disabled, popover.background.touch-selection button.flat:disabled, popover.background.magnifier button.flat:disabled, .osd button.flat:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; background-image: none; border-color: transparent; box-shadow: none; }
 +
 +.app-notification button.flat:active, popover.background.touch-selection button.flat:active, popover.background.magnifier button.flat:active, .app-notification button.flat:checked, popover.background.touch-selection button.flat:checked, popover.background.magnifier button.flat:checked, .osd button.flat:active, .osd button.flat:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(2, 2, 2, 0.7)); background-clip: padding-box; box-shadow: none; }
 +
 +button.suggested-action { color: white; outline-color: rgba(255, 255, 255, 0.8); border-color: #15539e; background-image: linear-gradient(to top, #2c7fe3 2px, #3584e4); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +button.suggested-action { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +button.suggested-action:focus:focus-visible { outline-color: rgba(255, 255, 255, 0.8); outline-width: 2px; outline-offset: -2px; }
 +
 +button.suggested-action.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: #3584e4; }
 +
 +button.suggested-action:hover { color: white; border-color: #185fb4; background-image: linear-gradient(to top, #185cb0, #1c6fd4 1px); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +button.suggested-action:active, button.suggested-action:checked { color: white; border-color: #185fb4; background-image: image(#1961b9); box-shadow: none; }
 +
 +button.suggested-action.flat:disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: rgba(53, 132, 228, 0.8); }
 +
 +button.suggested-action:disabled { color: #929595; border-color: #d5d0cc; background-image: image(#faf9f8); }
 +
 +button.suggested-action:disabled:active, button.suggested-action:disabled:checked { color: #acccf4; border-color: #185fb4; background-image: image(#2f80e3); box-shadow: none; }
 +
 +.osd button.suggested-action { color: #eeeeec; outline-color: rgba(255, 255, 255, 0.8); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 132, 228, 0.5)); background-clip: padding-box; }
 +
 +.osd button.suggested-action:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 132, 228, 0.7)); background-clip: padding-box; }
 +
 +.osd button.suggested-action:active:backdrop, .osd button.suggested-action:active, .osd button.suggested-action:checked:backdrop, .osd button.suggested-action:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(#3584e4); background-clip: padding-box; box-shadow: none; }
 +
 +.osd button.suggested-action:disabled:backdrop, .osd button.suggested-action:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; }
 +
 +button.destructive-action { color: white; outline-color: rgba(255, 255, 255, 0.8); border-color: #851015; background-image: linear-gradient(to top, #d71a23 2px, #e01b24); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +button.destructive-action { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +button.destructive-action:focus:focus-visible { outline-color: rgba(255, 255, 255, 0.8); outline-width: 2px; outline-offset: -2px; }
 +
 +button.destructive-action.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: #e01b24; }
 +
 +button.destructive-action:hover { color: white; border-color: #9c1319; background-image: linear-gradient(to top, #971218, #bc171e 1px); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +button.destructive-action:active, button.destructive-action:checked { color: white; border-color: #9c1319; background-image: image(#a0131a); box-shadow: none; }
 +
 +button.destructive-action.flat:disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: rgba(224, 27, 36, 0.8); }
 +
 +button.destructive-action:disabled { color: #929595; border-color: #d5d0cc; background-image: image(#faf9f8); }
 +
 +button.destructive-action:disabled:active, button.destructive-action:disabled:checked { color: #f1a5a8; border-color: #9c1319; background-image: image(#dc1d27); box-shadow: none; }
 +
 +.osd button.destructive-action { color: #eeeeec; outline-color: rgba(255, 255, 255, 0.8); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(224, 27, 36, 0.5)); background-clip: padding-box; }
 +
 +.osd button.destructive-action:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(224, 27, 36, 0.7)); background-clip: padding-box; }
 +
 +.osd button.destructive-action:active:backdrop, .osd button.destructive-action:active, .osd button.destructive-action:checked:backdrop, .osd button.destructive-action:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(#e01b24); background-clip: padding-box; box-shadow: none; }
 +
 +.osd button.destructive-action:disabled:backdrop, .osd button.destructive-action:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; }
 +
 +stackswitcher > button > label { padding: 0 6px; margin: 0 -6px; }
 +
 +stackswitcher > button > image { padding: 3px 6px; margin: -3px -6px; }
 +
 +button.font separator { background-color: transparent; }
 +
 +button.font > box { border-spacing: 6px; }
 +
 +button.font > box > box > label { font-weight: bold; }
 +
 +menubutton.circular button, button.circular { min-width: 32px; min-height: 32px; padding: 0; border-radius: 9999px; }
 +
 +menubutton.circular button label, button.circular label { padding: 0; }
 +
 +stacksidebar row.needs-attention > label, stackswitcher > button.needs-attention > label, stackswitcher > button.needs-attention > image { animation: needs_attention 150ms ease-in; background-image: radial-gradient(farthest-side, #3584e4 96%, rgba(53, 132, 228, 0)); background-size: 6px 6px, 6px 6px; background-repeat: no-repeat; background-position: right 3px, right 4px; }
 +
 +stacksidebar row.needs-attention > label:backdrop, stackswitcher > button.needs-attention > label:backdrop, stackswitcher > button.needs-attention > image:backdrop { background-size: 6px 6px, 0 0; }
 +
 +stacksidebar row.needs-attention > label:dir(rtl), stackswitcher > button.needs-attention > label:dir(rtl), stackswitcher > button.needs-attention > image:dir(rtl) { background-position: left 3px, left 4px; }
 +
 +.linked:not(.vertical) > filechooserbutton > combobox:dir(rtl):not(:last-child) > box > button.combo, .linked:not(.vertical) > appchooserbutton > combobox:dir(rtl):not(:last-child) > box > button.combo, .linked:not(.vertical) > combobox:dir(rtl):not(:last-child) > box > button.combo, .linked:not(.vertical) > filechooserbutton > combobox:dir(ltr):not(:first-child) > box > button.combo, .linked:not(.vertical) > appchooserbutton > combobox:dir(ltr):not(:first-child) > box > button.combo, .linked:not(.vertical) > combobox:dir(ltr):not(:first-child) > box > button.combo, dropdown.linked button:nth-child(2):dir(ltr), combobox.linked button:nth-child(2):dir(ltr), .linked:not(.vertical) > menubutton:dir(rtl):not(:last-child) > button, .linked:not(.vertical) > dropdown:dir(rtl):not(:last-child) > button, .linked:not(.vertical) > colorbutton:dir(rtl):not(:last-child) > button, .linked:not(.vertical) > fontbutton:dir(rtl):not(:last-child) > button, .linked:not(.vertical) > filechooserbutton:dir(rtl):not(:last-child) > button, .linked:not(.vertical) > menubutton:dir(ltr):not(:first-child) > button, .linked:not(.vertical) > dropdown:dir(ltr):not(:first-child) > button, .linked:not(.vertical) > colorbutton:dir(ltr):not(:first-child) > button, .linked:not(.vertical) > fontbutton:dir(ltr):not(:first-child) > button, .linked:not(.vertical) > filechooserbutton:dir(ltr):not(:first-child) > button, spinbutton.vertical.linked:not(.vertical) > text:dir(rtl):not(:last-child), .linked:not(.vertical) > spinbutton:dir(rtl):not(:last-child):not(.vertical), .linked:not(.vertical) > entry:dir(rtl):not(:last-child), .linked:not(.vertical) > button:dir(rtl):not(:last-child), spinbutton.vertical.linked:not(.vertical) > text:dir(ltr):not(:first-child), .linked:not(.vertical) > spinbutton:dir(ltr):not(:first-child):not(.vertical), .linked:not(.vertical) > entry:dir(ltr):not(:first-child), .linked:not(.vertical) > button:dir(ltr):not(:first-child) { border-top-left-radius: 0; border-bottom-left-radius: 0; }
 +
 +.linked:not(.vertical) > filechooserbutton > combobox:dir(rtl):not(:first-child) > box > button.combo, .linked:not(.vertical) > appchooserbutton > combobox:dir(rtl):not(:first-child) > box > button.combo, .linked:not(.vertical) > combobox:dir(rtl):not(:first-child) > box > button.combo, .linked:not(.vertical) > filechooserbutton > combobox:dir(ltr):not(:last-child) > box > button.combo, .linked:not(.vertical) > appchooserbutton > combobox:dir(ltr):not(:last-child) > box > button.combo, .linked:not(.vertical) > combobox:dir(ltr):not(:last-child) > box > button.combo, dropdown.linked button:nth-child(2):dir(rtl), combobox.linked button:nth-child(2):dir(rtl), .linked:not(.vertical) > menubutton:dir(rtl):not(:first-child) > button, .linked:not(.vertical) > dropdown:dir(rtl):not(:first-child) > button, .linked:not(.vertical) > colorbutton:dir(rtl):not(:first-child) > button, .linked:not(.vertical) > fontbutton:dir(rtl):not(:first-child) > button, .linked:not(.vertical) > filechooserbutton:dir(rtl):not(:first-child) > button, .linked:not(.vertical) > menubutton:dir(ltr):not(:last-child) > button, .linked:not(.vertical) > dropdown:dir(ltr):not(:last-child) > button, .linked:not(.vertical) > colorbutton:dir(ltr):not(:last-child) > button, .linked:not(.vertical) > fontbutton:dir(ltr):not(:last-child) > button, .linked:not(.vertical) > filechooserbutton:dir(ltr):not(:last-child) > button, spinbutton.vertical.linked:not(.vertical) > text:dir(rtl):not(:first-child), .linked:not(.vertical) > spinbutton:dir(rtl):not(:first-child):not(.vertical), .linked:not(.vertical) > entry:dir(rtl):not(:first-child), .linked:not(.vertical) > button:dir(rtl):not(:first-child), spinbutton.vertical.linked:not(.vertical) > text:dir(ltr):not(:last-child), .linked:not(.vertical) > spinbutton:dir(ltr):not(:last-child):not(.vertical), .linked:not(.vertical) > entry:dir(ltr):not(:last-child), .linked:not(.vertical) > button:dir(ltr):not(:last-child) { border-right-style: none; border-top-right-radius: 0; border-bottom-right-radius: 0; }
 +
 +.linked.vertical > filechooserbutton > combobox:not(:first-child) > box > button.combo, .linked.vertical > appchooserbutton > combobox:not(:first-child) > box > button.combo, .linked.vertical > combobox:not(:first-child) > box > button.combo, .linked.vertical > menubutton:not(:first-child) > button, .linked.vertical > dropdown:not(:first-child) > button, .linked.vertical > colorbutton:not(:first-child) > button, .linked.vertical > fontbutton:not(:first-child) > button, .linked.vertical > filechooserbutton:not(:first-child) > button, spinbutton.vertical.linked > text:not(:first-child), .linked.vertical > spinbutton:not(:first-child):not(.vertical), .linked.vertical > entry:not(:first-child), .linked.vertical > button:not(:first-child) { border-top-left-radius: 0; border-top-right-radius: 0; }
 +
 +.linked.vertical > filechooserbutton > combobox:not(:last-child) > box > button.combo, .linked.vertical > appchooserbutton > combobox:not(:last-child) > box > button.combo, .linked.vertical > combobox:not(:last-child) > box > button.combo, .linked.vertical > menubutton:not(:last-child) > button, .linked.vertical > dropdown:not(:last-child) > button, .linked.vertical > colorbutton:not(:last-child) > button, .linked.vertical > fontbutton:not(:last-child) > button, .linked.vertical > filechooserbutton:not(:last-child) > button, spinbutton.vertical.linked > text:not(:last-child), .linked.vertical > spinbutton:not(:last-child):not(.vertical), .linked.vertical > entry:not(:last-child), .linked.vertical > button:not(:last-child) { border-bottom-style: none; border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
 +
- .toolbar button:hover { color: #2e3436; border-color: #cdc7c2; background-image: linear-gradient(to top, #d6d1cd, #e8e6e3 1px); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
- .toolbar button:active { color: #2e3436; border-color: #cdc7c2; background-image: image(#dad6d2); box-shadow: none; }
- .toolbar button:disabled { color: #929595; border-color: #d5d0cc; background-image: image(#faf9f8); }
- .toolbar button:backdrop { color: #929595; border-color: #d5d0cc; background-image: image(#f6f5f4); box-shadow: none; }
- .toolbar button:backdrop:disabled { color: #d4cfca; border-color: #d5d0cc; background-image: image(#faf9f8); box-shadow: none; }
++.scale-popup button:hover, button.link, button.link:hover, button.link:active, button.link:checked, popover.menu box.circular-buttons button.circular.image-button.model, list > row button.image-button:not(.flat), modelbutton.flat { background-color: transparent; background-image: none; border-color: transparent; box-shadow: inset 0 1px rgba(255, 255, 255, 0), 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
 +
 +/* menu buttons */
 +modelbutton.flat { min-height: 26px; padding-left: 5px; padding-right: 5px; border-radius: 5px; }
 +
 +modelbutton.flat:hover { background-color: #e8e6e3; }
 +
 +modelbutton.flat:disabled { color: #929595; }
 +
 +modelbutton.flat arrow { background: none; min-width: 16px; min-height: 16px; opacity: 0.3; }
 +
 +modelbutton.flat arrow:hover { background: none; }
 +
 +modelbutton.flat arrow.left { -gtk-icon-source: -gtk-icontheme("go-previous-symbolic"); }
 +
 +modelbutton.flat arrow.right { -gtk-icon-source: -gtk-icontheme("go-next-symbolic"); }
 +
 +/* oldstyle toolbar buttons */
 +.toolbar button { margin: 1px; }
 +
 +button.color { padding: 4px; }
 +
 +button.color > colorswatch:only-child { box-shadow: 0 1px rgba(0, 0, 0, 0.1); }
 +
 +button.color > colorswatch:only-child, button.color > colorswatch:only-child > overlay { border-radius: 0; }
 +
 +.osd button.color > colorswatch:only-child { box-shadow: none; }
 +
 +.osd button.color:disabled colorswatch:only-child, .osd button.color:active colorswatch:only-child, .osd button.color:checked colorswatch:only-child, button.color:disabled colorswatch:only-child, button.color:active colorswatch:only-child, button.color:checked colorswatch:only-child { box-shadow: none; }
 +
 +/* list buttons */
 +/* tone down as per new designs, see issue #1473 */
 +popover.menu box.circular-buttons button.circular.image-button.model, list > row button.image-button:not(.flat) { border: 1px solid rgba(205, 199, 194, 0.5); }
 +
 +popover.menu box.circular-buttons button.circular.image-button.model:hover, list > row button.image-button:not(.flat):hover { color: #2e3436; border-color: #cdc7c2; background-image: linear-gradient(to top, #d6d1cd, #e8e6e3 1px); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +popover.menu box.circular-buttons button.circular.image-button.model:active, popover.menu box.circular-buttons button.circular.image-button.model:checked, list > row button.image-button:not(.flat):active, list > row button.image-button:not(.flat):checked { color: #2e3436; border-color: #cdc7c2; background-image: image(#dad6d2); box-shadow: none; }
 +
 +popover.menu box.circular-buttons button.suggested-action.circular.image-button.model, list > row button.image-button.suggested-action:not(.flat) { color: white; outline-color: rgba(255, 255, 255, 0.8); border-color: #15539e; background-image: linear-gradient(to top, #2c7fe3 2px, #3584e4); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +popover.menu box.circular-buttons button.suggested-action.circular.image-button.model, list > row button.image-button.suggested-action:not(.flat) { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +popover.menu box.circular-buttons button.suggested-action.circular.image-button.model:focus:focus-visible, list > row button.image-button.suggested-action:not(.flat):focus:focus-visible { outline-color: rgba(255, 255, 255, 0.8); outline-width: 2px; outline-offset: -2px; }
 +
 +popover.menu box.circular-buttons button.destructive-action.circular.image-button.model, list > row button.image-button.destructive-action:not(.flat) { color: white; outline-color: rgba(255, 255, 255, 0.8); border-color: #851015; background-image: linear-gradient(to top, #d71a23 2px, #e01b24); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +popover.menu box.circular-buttons button.destructive-action.circular.image-button.model, list > row button.image-button.destructive-action:not(.flat) { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +popover.menu box.circular-buttons button.destructive-action.circular.image-button.model:focus:focus-visible, list > row button.image-button.destructive-action:not(.flat):focus:focus-visible { outline-color: rgba(255, 255, 255, 0.8); outline-width: 2px; outline-offset: -2px; }
 +
 +/********* Links * */
 +button.link, link { color: #1b6acb; text-decoration: underline; }
 +
 +button.link:visited, link:visited { color: #15539e; }
 +
 +*:selected button.link:visited, *:selected link:visited { color: #a1bad8; }
 +
 +button.link:hover, link:hover { color: #3584e4; }
 +
 +*:selected button.link:hover, *:selected link:hover { color: #ebf3fc; }
 +
 +button.link:active, link:active { color: #1b6acb; }
 +
 +*:selected button.link:active, *:selected link:active { color: #d1e1f5; }
 +
 +button.link:disabled, link:disabled { color: rgba(115, 115, 115, 0.8); }
 +
 +button.link:selected, *:selected button.link, link:selected, *:selected link { color: #d1e1f5; }
 +
 +link { transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +link { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +link:focus:focus-visible { outline-color: rgba(53, 132, 228, 0.5); outline-width: 2px; outline-offset: -2px; }
 +
 +button.link, button.link:hover, button.link:active, button.link:checked { text-shadow: none; }
 +
 +button.link > label { text-decoration: underline; }
 +
 +/***************** GtkSpinButton * */
 +spinbutton { font-feature-settings: "tnum"; }
 +
 +spinbutton:not(.vertical) { padding: 0; border-spacing: 0; /* :not here just to bump specificity above that of the list button styling */ }
 +
 +.osd spinbutton:not(.vertical) > text, spinbutton:not(.vertical) > text { min-width: 28px; margin: 0; background: none; background-color: transparent; border: none; border-radius: 0; box-shadow: none; padding: 6px; }
 +
 +.osd spinbutton:not(.vertical) > text:backdrop:disabled, spinbutton:not(.vertical) > text:backdrop:disabled { background-color: transparent; }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat), spinbutton:not(.vertical) > button.image-button.down:not(.flat) { min-height: 16px; margin: 0; padding-bottom: 0; padding-top: 0; color: #43484a; background-image: none; border-style: none none none solid; border-color: rgba(205, 199, 194, 0.3); border-radius: 0; box-shadow: none; }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat):dir(rtl), spinbutton:not(.vertical) > button.image-button.down:not(.flat):dir(rtl) { border-style: none solid none none; }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat):hover, spinbutton:not(.vertical) > button.image-button.down:not(.flat):hover { color: #2e3436; background-color: #ebe8e6; }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat):disabled, spinbutton:not(.vertical) > button.image-button.down:not(.flat):disabled { color: rgba(146, 149, 149, 0.3); background-color: transparent; }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat):active, spinbutton:not(.vertical) > button.image-button.down:not(.flat):active { background-color: rgba(0, 0, 0, 0.1); box-shadow: inset 0 2px 3px -1px rgba(0, 0, 0, 0.2); }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat):dir(ltr):last-child, spinbutton:not(.vertical) > button.image-button.down:not(.flat):dir(ltr):last-child { border-radius: 0 5px 5px 0; }
 +
 +spinbutton:not(.vertical) > button.image-button.up:not(.flat):dir(rtl):first-child, spinbutton:not(.vertical) > button.image-button.down:not(.flat):dir(rtl):first-child { border-radius: 5px 0 0 5px; }
 +
 +.osd spinbutton:not(.vertical) > button.image-button.up:not(.flat), .osd spinbutton:not(.vertical) > button.image-button.down:not(.flat) { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: #eeeeec; border-style: none none none solid; border-color: rgba(0, 0, 0, 0.4); border-radius: 0; box-shadow: none; -gtk-icon-shadow: 0 1px black; }
 +
 +.osd spinbutton:not(.vertical) > button.image-button.up:not(.flat):dir(rtl), .osd spinbutton:not(.vertical) > button.image-button.down:not(.flat):dir(rtl) { border-style: none solid none none; }
 +
 +.osd spinbutton:not(.vertical) > button.image-button.up:not(.flat):hover, .osd spinbutton:not(.vertical) > button.image-button.down:not(.flat):hover { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: #eeeeec; border-color: rgba(0, 0, 0, 0.5); background-color: rgba(27, 27, 27, 0.7); -gtk-icon-shadow: 0 1px black; box-shadow: none; }
 +
 +.osd spinbutton:not(.vertical) > button.image-button.up:not(.flat):disabled, .osd spinbutton:not(.vertical) > button.image-button.down:not(.flat):disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; color: #919190; border-color: rgba(0, 0, 0, 0.5); -gtk-icon-shadow: none; box-shadow: none; }
 +
 +.osd spinbutton:not(.vertical) > button.image-button.up:not(.flat):dir(ltr):last-child, .osd spinbutton:not(.vertical) > button.image-button.down:not(.flat):dir(ltr):last-child { border-radius: 0 5px 5px 0; }
 +
 +.osd spinbutton:not(.vertical) > button.image-button.up:not(.flat):dir(rtl):first-child, .osd spinbutton:not(.vertical) > button.image-button.down:not(.flat):dir(rtl):first-child { border-radius: 5px 0 0 5px; }
 +
 +spinbutton.vertical:disabled { color: #929595; }
 +
 +spinbutton.vertical:drop(active) { border-color: transparent; box-shadow: none; }
 +
 +spinbutton.vertical > text { min-height: 32px; min-width: 32px; padding: 0; border-radius: 0; }
 +
 +spinbutton.vertical > text > block-cursor { color: #ffffff; background-color: black; }
 +
 +spinbutton.vertical > button { min-height: 32px; min-width: 32px; padding: 0; }
 +
 +spinbutton.vertical > button.up { border-bottom-style: none; border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
 +
 +spinbutton.vertical > button.down { border-top-style: none; border-top-left-radius: 0; border-top-right-radius: 0; }
 +
 +.osd spinbutton.vertical > button:first-child { color: #eeeeec; outline-color: rgba(53, 132, 228, 0.5); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; }
 +
 +.osd spinbutton.vertical > button:first-child:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(27, 27, 27, 0.7)); background-clip: padding-box; }
 +
 +.osd spinbutton.vertical > button:first-child:active { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(2, 2, 2, 0.7)); background-clip: padding-box; box-shadow: none; }
 +
 +.osd spinbutton.vertical > button:first-child:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; }
 +
 +treeview spinbutton:not(.vertical) { min-height: 0; border-style: none; border-radius: 0; }
 +
 +treeview spinbutton:not(.vertical) > text { min-height: 0; padding: 1px 2px; }
 +
 +/************** ComboBoxes * */
 +dropdown > popover.menu.background > contents { padding: 0; }
 +
 +dropdown > button > box { border-spacing: 6px; }
 +
 +dropdown > button > box > stack > row.activatable:hover { background: none; box-shadow: none; }
 +
 +dropdown arrow, combobox arrow { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); min-height: 16px; min-width: 16px; }
 +
 +dropdown > popover.menu > contents modelbutton, combobox > popover.menu > contents modelbutton { padding-left: 9px; padding-right: 9px; }
 +
 +dropdown:drop(active), combobox:drop(active) { box-shadow: none; }
 +
 +dropdown popover, combobox popover { margin-top: 6px; padding: 0; }
 +
 +dropdown popover listview, combobox popover listview { margin: 8px 0; }
 +
 +dropdown popover listview > row.activatable, combobox popover listview > row.activatable { padding: 8px; }
 +
 +dropdown popover listview > row.activatable:selected, dropdown popover listview > row.activatable:selected:hover, combobox popover listview > row.activatable:selected, combobox popover listview > row.activatable:selected:hover { outline-color: rgba(255, 255, 255, 0.8); color: black; background-color: #e8e6e3; box-shadow: none; }
 +
 +dropdown popover .dropdown-searchbar, combobox popover .dropdown-searchbar { padding: 6px; border-bottom: 1px solid #cdc7c2; }
 +
 +/************ Toolbars * */
 +searchbar > revealer > box, .toolbar, toolbar { padding: 4px; border-spacing: 4px; background-color: #f6f5f4; }
 +
 +.osd .toolbar, .osd toolbar { background-color: transparent; }
 +
 +.toolbar.osd, toolbar.osd { padding: 13px; border: none; border-radius: 5px; background-color: rgba(53, 53, 53, 0.7); }
 +
 +.toolbar.osd.left, .toolbar.osd.right, .toolbar.osd.top, .toolbar.osd.bottom, toolbar.osd.left, toolbar.osd.right, toolbar.osd.top, toolbar.osd.bottom { border-radius: 0; }
 +
 +.toolbar.horizontal > separator, toolbar.horizontal > separator { margin: 4px 0; }
 +
 +.toolbar.vertical > separator, toolbar.vertical > separator { margin: 0 4px; }
 +
 +searchbar > revealer > box { padding: 6px; border-spacing: 6px; border-width: 0 0 1px; }
 +
 +searchbar > revealer > box { border-style: solid; border-color: #cdc7c2; background-color: #eae7e5; }
 +
 +searchbar > revealer > box:backdrop { border-color: #d5d0cc; background-color: #eae8e6; box-shadow: none; transition: 200ms ease-out; }
 +
 +/************** GtkInfoBar * */
 +infobar > revealer > box { padding: 8px; border-spacing: 12px; }
 +
 +infobar.action:hover > revealer > box { background-color: #f4ebe1; }
 +
 +infobar.info > revealer > box, infobar.question > revealer > box, infobar.warning > revealer > box, infobar.error > revealer > box { border-bottom: 1px solid #d8d4d0; background-color: #f1e6d9; }
 +
 +infobar .close, searchbar .close { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; min-width: 16px; min-height: 16px; padding: 4px; border-radius: 50%; }
 +
 +infobar .close:hover, searchbar .close:hover { color: #2e3436; border-color: #cdc7c2; background-image: linear-gradient(to top, #d6d1cd, #e8e6e3 1px); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +/***************** Title buttons * */
 +windowcontrols { border-spacing: 6px; }
 +
 +windowcontrols.start:not(.empty):dir(ltr), windowcontrols.end:not(.empty):dir(rtl) { margin-right: 7px; }
 +
 +windowcontrols.start:not(.empty):dir(rtl), windowcontrols.end:not(.empty):dir(ltr) { margin-left: 7px; }
 +
 +windowcontrols button { border-radius: 9999px; padding: 6px; margin: 0 2px; min-width: 0; min-height: 0; }
 +
 +windowcontrols button:hover { border-color: transparent; background-image: none; box-shadow: none; background-color: #d1ccc7; }
 +
 +windowcontrols button:active, windowcontrols button:checked { border-color: transparent; background-image: none; box-shadow: none; background-color: #bab3ab; }
 +
 +/*************** Header bars * */
 +.titlebar:not(headerbar), headerbar { padding: 0 6px; min-height: 46px; border-width: 0 0 1px; border-style: solid; border-color: #bfb8b1; border-radius: 0; background: #dfdcd8 linear-gradient(to top, #dad6d2, #e1dedb); /* Darken switchbuttons for headerbars. issue #1588 */ }
 +
 +.titlebar:backdrop:not(headerbar), headerbar:backdrop { border-color: #d5d0cc; background-color: #f6f5f4; background-image: none; transition: 200ms ease-out; }
 +
 +.titlebar:not(headerbar) .title, headerbar .title { padding-left: 12px; padding-right: 12px; font-weight: bold; }
 +
 +.titlebar:not(headerbar) .subtitle, headerbar .subtitle { font-size: smaller; padding-left: 12px; padding-right: 12px; }
 +
 +.titlebar:not(headerbar) stackswitcher > button:checked, .titlebar:not(headerbar) button.toggle:checked, headerbar stackswitcher > button:checked, headerbar button.toggle:checked { background: image(#cfcac4); border-color: #c6bfb9; border-top-color: #bab3ab; }
 +
 +.titlebar:not(headerbar) stackswitcher > button:checked:backdrop, .titlebar:not(headerbar) button.toggle:checked:backdrop, headerbar stackswitcher > button:checked:backdrop, headerbar button.toggle:checked:backdrop { color: #929595; border-color: #d5d0cc; background-image: image(#e9e9e3); box-shadow: none; }
 +
 +.tiled .titlebar:not(headerbar), .tiled-top .titlebar:not(headerbar), .tiled-left .titlebar:not(headerbar), .tiled-right .titlebar:not(headerbar), .tiled-bottom .titlebar:not(headerbar), .maximized .titlebar:not(headerbar), .fullscreen .titlebar:not(headerbar), .tiled headerbar, .tiled-top headerbar, .tiled-left headerbar, .tiled-right headerbar, .tiled-bottom headerbar, .maximized headerbar, .fullscreen headerbar { border-radius: 0; }
 +
 +.default-decoration.titlebar:not(headerbar), headerbar.default-decoration { min-height: 28px; padding: 4px; }
 +
 +.default-decoration.titlebar:not(headerbar) windowcontrols button, .default-decoration.titlebar:not(headerbar) windowcontrols menubutton, headerbar.default-decoration windowcontrols button, headerbar.default-decoration windowcontrols menubutton { min-height: 26px; min-width: 26px; margin: 0; padding: 0; }
 +
 +.default-decoration.titlebar:not(headerbar) windowcontrols menubutton button, headerbar.default-decoration windowcontrols menubutton button { min-height: 20px; min-width: 20px; margin: 0; padding: 4px; }
 +
 +.solid-csd .titlebar:dir(rtl):not(headerbar), .solid-csd .titlebar:dir(ltr):not(headerbar), .solid-csd headerbar:backdrop:dir(rtl), .solid-csd headerbar:backdrop:dir(ltr), .solid-csd headerbar:dir(rtl), .solid-csd headerbar:dir(ltr) { margin-left: -1px; margin-right: -1px; margin-top: -1px; border-radius: 0; box-shadow: none; }
 +
 +headerbar > windowhandle > box, headerbar > windowhandle > box > box.start, headerbar > windowhandle > box > box.end { border-spacing: 6px; }
 +
 +headerbar entry, headerbar spinbutton, headerbar separator:not(.sidebar), headerbar button, headerbar menubutton { margin-top: 6px; margin-bottom: 6px; }
 +
 +headerbar menubutton > button { margin-top: 0px; margin-bottom: 0px; }
 +
 +headerbar switch { margin-top: 10px; margin-bottom: 10px; }
 +
 +window.csd > .titlebar:not(headerbar) { padding: 0; background-color: transparent; background-image: none; border-style: none; border-color: transparent; }
 +
 +.titlebar:not(headerbar) separator { background-color: #cdc7c2; }
 +
 +window.devel headerbar.titlebar { background: #f6f5f4 cross-fade(10% -gtk-icontheme("system-run-symbolic"), image(transparent)) 90% 0/256px 256px no-repeat, linear-gradient(to right, transparent 65%, rgba(53, 132, 228, 0.2)), linear-gradient(to top, #d8d4d0, #dfdcd8 3px, #edebe9); }
 +
 +window.devel headerbar.titlebar:backdrop { background: #f6f5f4 cross-fade(10% -gtk-icontheme("system-run-symbolic"), image(transparent)) 90% 0/256px 256px no-repeat, image(#f6f5f4); /* background-color would flash */ }
 +
 +/************ Pathbars * */
 +pathbar > button.text-button, pathbar > button.image-button, pathbar > button { padding-left: 4px; padding-right: 4px; }
 +
 +pathbar > button.text-button.image-button label { padding-left: 0; padding-right: 0; }
 +
 +pathbar > button.text-button.image-button label:last-child, pathbar > button label:last-child { padding-right: 8px; }
 +
 +pathbar > button.text-button.image-button label:first-child, pathbar > button label:first-child { padding-left: 8px; }
 +
 +pathbar > button image { padding-left: 4px; padding-right: 4px; }
 +
 +pathbar > button.slider-button { padding-left: 0; padding-right: 0; }
 +
 +/************** Tree Views * */
 +columnview.view, treeview.view { border-left-color: #d7d2ce; border-top-color: #d7d2ce; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +columnview.view, treeview.view { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +columnview.view:focus:focus-visible, treeview.view:focus:focus-visible { outline-color: rgba(53, 132, 228, 0.5); outline-width: 2px; outline-offset: -2px; }
 +
 +columnview.view:selected:focus, columnview.view:selected, treeview.view:selected:focus, treeview.view:selected { border-radius: 0; outline-color: rgba(255, 255, 255, 0.8); }
 +
 +columnview.view:disabled, treeview.view:disabled { color: #929595; }
 +
 +columnview.view:disabled:selected, treeview.view:disabled:selected { color: #86b5ef; }
 +
 +columnview.view:disabled:selected:backdrop, treeview.view:disabled:selected:backdrop { color: #71a8eb; }
 +
 +columnview.view.separator, treeview.view.separator { min-height: 2px; color: #d7d2ce; }
 +
 +columnview.view:backdrop, treeview.view:backdrop { border-left-color: #ddd9d6; border-top: #ddd9d6; }
 +
 +columnview.view:drop(active), treeview.view:drop(active) { box-shadow: none; }
 +
 +columnview.view > dndtarget:drop(active), treeview.view > dndtarget:drop(active) { border-style: solid none; border-width: 1px; border-color: #185fb4; }
 +
 +columnview.view > dndtarget.after:drop(active), treeview.view > dndtarget.after:drop(active) { border-top-style: none; }
 +
 +columnview.view > dndtarget.before:drop(active), treeview.view > dndtarget.before:drop(active) { border-bottom-style: none; }
 +
 +columnview.view.expander, treeview.view.expander { min-width: 16px; min-height: 16px; -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); color: #4d4d4d; }
 +
 +columnview.view.expander:dir(rtl), treeview.view.expander:dir(rtl) { -gtk-icon-source: -gtk-icontheme("pan-end-symbolic-rtl"); }
 +
 +columnview.view.expander:hover, treeview.view.expander:hover { color: black; }
 +
 +columnview.view.expander:selected, treeview.view.expander:selected { color: #c2daf7; }
 +
 +columnview.view.expander:selected:hover, treeview.view.expander:selected:hover { color: #ffffff; }
 +
 +columnview.view.expander:checked, treeview.view.expander:checked { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
 +
 +columnview.view.progressbar, treeview.view.progressbar { color: #ffffff; background-color: #3584e4; background-image: image(#3584e4); box-shadow: none; }
 +
 +columnview.view.progressbar:selected:focus, columnview.view.progressbar:selected, treeview.view.progressbar:selected:focus, treeview.view.progressbar:selected { color: #3584e4; background-image: image(#ffffff); }
 +
 +columnview.view.progressbar:selected:focus:backdrop, columnview.view.progressbar:selected:backdrop, treeview.view.progressbar:selected:focus:backdrop, treeview.view.progressbar:selected:backdrop { color: #3584e4; background-color: #fcfcfc; }
 +
 +columnview.view.trough, treeview.view.trough { background-color: rgba(46, 52, 54, 0.1); }
 +
 +columnview.view.trough:selected:focus, columnview.view.trough:selected, treeview.view.trough:selected:focus, treeview.view.trough:selected { background-color: rgba(255, 255, 255, 0.3); }
 +
 +columnview.view > header > button, treeview.view > header > button { color: #979a9b; background-color: #ffffff; font-weight: bold; text-shadow: none; box-shadow: none; }
 +
 +columnview.view > header > button:hover, treeview.view > header > button:hover { color: #636769; box-shadow: none; transition: none; }
 +
 +columnview.view > header > button:active, treeview.view > header > button:active { color: #2e3436; transition: none; }
 +
 +columnview.view > header > button sort-indicator, treeview.view > header > button sort-indicator { min-height: 16px; min-width: 16px; }
 +
 +columnview.view > header > button sort-indicator.ascending, treeview.view > header > button sort-indicator.ascending { -gtk-icon-source: -gtk-icontheme("pan-up-symbolic"); }
 +
 +columnview.view > header > button sort-indicator.descending, treeview.view > header > button sort-indicator.descending { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
 +
 +columnview.view button.dnd:active, columnview.view button.dnd:selected, columnview.view button.dnd:hover, columnview.view button.dnd, columnview.view header.button.dnd:active, columnview.view header.button.dnd:selected, columnview.view header.button.dnd:hover, columnview.view header.button.dnd, treeview.view button.dnd:active, treeview.view button.dnd:selected, treeview.view button.dnd:hover, treeview.view button.dnd, treeview.view header.button.dnd:active, treeview.view header.button.dnd:selected, treeview.view header.button.dnd:hover, treeview.view header.button.dnd { padding: 0 6px; color: #ffffff; background-image: none; background-color: #3584e4; border-style: none; border-radius: 0; box-shadow: inset 0 0 0 1px #ffffff; text-shadow: none; transition: none; }
 +
 +columnview.view acceleditor > label, treeview.view acceleditor > label { background-color: #3584e4; }
 +
 +columnview.view > header > button, treeview.view > header > button, columnview.view > header > button:hover, treeview.view > header > button:hover, columnview.view > header > button:active, treeview.view > header > button:active { padding: 0 6px; background-image: none; border-style: none none solid solid; border-color: #d7d2ce; border-radius: 0; text-shadow: none; }
 +
 +columnview.view > header > button:disabled, treeview.view > header > button:disabled { border-color: #f6f5f4; background-image: none; }
 +
 +columnview.view > header > button:last-child, treeview.view > header > button:last-child { border-right-style: none; }
 +
 +/*************** Popovers   * */
 +popover.background { background-color: transparent; font: initial; }
 +
 +popover.background > arrow, popover.background > contents { background-color: #ffffff; background-clip: padding-box; border: 1px solid rgba(0, 0, 0, 0.23); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); }
 +
 +popover.background:backdrop { background-color: transparent; }
 +
 +popover.background > contents { padding: 8px; border-radius: 9px; }
 +
 +popover.background > contents > list, popover.background > contents > .view, popover.background > contents > iconview, popover.background > contents > toolbar { border-style: none; background-color: transparent; }
 +
 +popover.background > contents separator { background-color: #d9d5d1; margin: 3px; }
 +
 +popover.background > contents list separator { margin: 0; }
 +
 +.osd popover.background, popover.background.touch-selection, popover.background.magnifier { background-color: transparent; }
 +
 +.osd popover.background > arrow, .osd popover.background > contents, popover.background.touch-selection > arrow, popover.background.touch-selection > contents, popover.background.magnifier > arrow, popover.background.magnifier > contents { border: 1px solid rgba(255, 255, 255, 0.1); box-shadow: none; }
 +
 +magnifier { background-color: #ffffff; }
 +
 +/********************** Popover Base Menus * */
 +popover.menu { padding: 0; }
 +
 +popover.menu box.inline-buttons { padding: 0 12px; }
 +
 +popover.menu box.inline-buttons button.image-button.model { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; min-height: 30px; min-width: 30px; padding: 0; border: none; outline: none; transition: none; }
 +
 +popover.menu box.inline-buttons button.image-button.model:selected { background: image(#e8e6e3); }
 +
 +popover.menu box.circular-buttons { padding: 12px 12px 6px; }
 +
 +popover.menu box.circular-buttons button.circular.image-button.model { padding: 11px; }
 +
 +popover.menu box.circular-buttons button.circular.image-button.model:focus { background-color: #e8e6e3; border-color: #e8e6e3; }
 +
 +popover.menu > arrow, popover.menu.background > contents { background-color: #ffffff; padding: 5px; }
 +
 +popover.menu.background separator { margin: 6px 0; }
 +
 +popover.menu accelerator { color: alpha(currentColor,0.55); }
 +
 +popover.menu accelerator:dir(ltr) { margin-left: 12px; }
 +
 +popover.menu accelerator:dir(rtl) { margin-right: 12px; }
 +
 +popover.menu check, popover.menu radio { transform: scale(0.8); border-width: 1.2px; border-color: transparent; box-shadow: none; background-image: image(transparent); color: black; }
 +
 +popover.menu check:hover, popover.menu radio:hover { transform: scale(0.8); border-width: 1.2px; color: black; box-shadow: none; background-image: image(transparent); }
 +
 +popover.menu check:active, popover.menu radio:active { transform: scale(0.8); border-width: 1.2px; color: black; box-shadow: none; background-image: image(transparent); }
 +
 +popover.menu radio { border-color: #cdc7c2; }
 +
 +popover.menu radio:active { border-color: rgba(205, 199, 194, 0.5); }
 +
 +popover.menu arrow.left, popover.menu radio.left, popover.menu check.left { margin-left: -2px; margin-right: 6px; }
 +
 +popover.menu arrow.right, popover.menu radio.right, popover.menu check.right { margin-left: 6px; margin-right: -2px; }
 +
 +popover.menu modelbutton { min-height: 30px; min-width: 40px; padding: 0 12px; border-radius: 5px; }
 +
 +popover.menu modelbutton:selected { color: black; background-color: #e8e6e3; }
 +
 +popover.menu modelbutton:selected:active { background-color: #d6d1cd; }
 +
 +popover.menu label.title { font-weight: bold; padding: 4px 32px; }
 +
 +menubar { padding: 0px; box-shadow: inset 0 -1px rgba(0, 0, 0, 0.1); }
 +
 +menubar > item { min-height: 16px; padding: 4px 8px; }
 +
 +menubar > item:selected { box-shadow: inset 0 -3px #3584e4; color: #1b6acb; }
 +
 +menubar > item:disabled { color: #929595; box-shadow: none; }
 +
 +menubar > item popover.menu.background > contents { padding: 5px; }
 +
 +menubar > item popover.menu popover.menu { padding: 0 0 4px 0; }
 +
 +menubar > item popover.menu.background popover.menu.background > contents { margin: 0; border-radius: 9px; }
 +
 +/************* Notebooks * */
 +notebook { transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +notebook > header > tabs > tab:checked { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +notebook:focus:focus-visible > header > tabs > tab:checked { outline-color: rgba(53, 132, 228, 0.5); outline-width: 2px; outline-offset: -2px; }
 +
 +notebook > header { padding: 1px; border-color: #cdc7c2; border-width: 1px; background-color: #e1dedb; }
 +
 +notebook > header > tabs { margin: -1px; }
 +
 +notebook > header.top { border-bottom-style: solid; }
 +
 +notebook > header.top > tabs { margin-bottom: -2px; }
 +
 +notebook > header.top > tabs > tab:hover { box-shadow: inset 0 -4px #cdc7c2; }
 +
 +notebook > header.top > tabs > tab:checked { box-shadow: inset 0 -4px #3584e4; }
 +
 +notebook > header.bottom { border-top-style: solid; }
 +
 +notebook > header.bottom > tabs { margin-top: -2px; }
 +
 +notebook > header.bottom > tabs > tab:hover { box-shadow: inset 0 4px #cdc7c2; }
 +
 +notebook > header.bottom > tabs > tab:checked { box-shadow: inset 0 4px #3584e4; }
 +
 +notebook > header.left { border-right-style: solid; }
 +
 +notebook > header.left > tabs { margin-right: -2px; }
 +
 +notebook > header.left > tabs > tab:hover { box-shadow: inset -4px 0 #cdc7c2; }
 +
 +notebook > header.left > tabs > tab:checked { box-shadow: inset -4px 0 #3584e4; }
 +
 +notebook > header.right { border-left-style: solid; }
 +
 +notebook > header.right > tabs { margin-left: -2px; }
 +
 +notebook > header.right > tabs > tab:hover { box-shadow: inset 4px 0 #cdc7c2; }
 +
 +notebook > header.right > tabs > tab:checked { box-shadow: inset 4px 0 #3584e4; }
 +
 +notebook > header.top > tabs > arrow { border-top-style: none; }
 +
 +notebook > header.bottom > tabs > arrow { border-bottom-style: none; }
 +
 +notebook > header.top > tabs > arrow, notebook > header.bottom > tabs > arrow { margin-left: -5px; margin-right: -5px; padding-left: 4px; padding-right: 4px; }
 +
 +notebook > header.top > tabs > arrow.down, notebook > header.bottom > tabs > arrow.down { -gtk-icon-source: -gtk-icontheme("pan-start-symbolic"); }
 +
 +notebook > header.top > tabs > arrow.up, notebook > header.bottom > tabs > arrow.up { -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); }
 +
 +notebook > header.left > tabs > arrow { border-left-style: none; }
 +
 +notebook > header.right > tabs > arrow { border-right-style: none; }
 +
 +notebook > header.left > tabs > arrow, notebook > header.right > tabs > arrow { margin-top: -5px; margin-bottom: -5px; padding-top: 4px; padding-bottom: 4px; }
 +
 +notebook > header.left > tabs > arrow.down, notebook > header.right > tabs > arrow.down { -gtk-icon-source: -gtk-icontheme("pan-up-symbolic"); }
 +
 +notebook > header.left > tabs > arrow.up, notebook > header.right > tabs > arrow.up { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
 +
 +notebook > header > tabs > arrow { min-height: 16px; min-width: 16px; border-radius: 0; }
 +
 +notebook > header > tabs > arrow:hover:not(:active):not(:backdrop) { background-clip: padding-box; background-image: none; background-color: rgba(255, 255, 255, 0.3); border-color: transparent; box-shadow: none; }
 +
 +notebook > header > tabs > arrow:disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: none; }
 +
 +notebook > header > tabs > tab { transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); min-height: 30px; min-width: 30px; padding: 3px 12px; color: #2e3436; font-weight: normal; border-width: 1px; border-color: transparent; }
 +
 +notebook > header > tabs > tab:hover { color: #2e3436; background-color: #d8d4d0; }
 +
 +notebook > header > tabs > tab.reorderable-page:hover { border-color: rgba(205, 199, 194, 0.3); background-color: rgba(246, 245, 244, 0.2); }
 +
 +notebook > header > tabs > tab:not(:checked) { outline-color: transparent; }
 +
 +notebook > header > tabs > tab:checked { color: #2e3436; }
 +
 +notebook > header > tabs > tab.reorderable-page:checked { border-color: rgba(205, 199, 194, 0.5); background-color: rgba(246, 245, 244, 0.5); }
 +
 +notebook > header > tabs > tab.reorderable-page:checked:hover { background-color: rgba(246, 245, 244, 0.7); }
 +
 +notebook > header > tabs > tab button.flat { color: alpha(currentColor,0.3); padding: 0; margin-top: 4px; margin-bottom: 4px; min-width: 20px; min-height: 20px; }
 +
 +notebook > header > tabs > tab button.flat:hover { color: currentColor; }
 +
 +notebook > header > tabs > tab button.flat:last-child { margin-left: 4px; margin-right: -4px; }
 +
 +notebook > header > tabs > tab button.flat:first-child { margin-left: -4px; margin-right: 4px; }
 +
 +notebook > header.top > tabs, notebook > header.bottom > tabs { padding-left: 4px; padding-right: 4px; }
 +
 +notebook > header.top > tabs:not(:only-child), notebook > header.bottom > tabs:not(:only-child) { margin-left: 3px; margin-right: 3px; }
 +
 +notebook > header.top > tabs:not(:only-child):first-child, notebook > header.bottom > tabs:not(:only-child):first-child { margin-left: -1px; }
 +
 +notebook > header.top > tabs:not(:only-child):last-child, notebook > header.bottom > tabs:not(:only-child):last-child { margin-right: -1px; }
 +
 +notebook > header.top > tabs > tab, notebook > header.bottom > tabs > tab { margin-left: 4px; margin-right: 4px; }
 +
 +notebook > header.top > tabs > tab.reorderable-page, notebook > header.bottom > tabs > tab.reorderable-page { border-style: none solid; }
 +
 +notebook > header.left > tabs, notebook > header.right > tabs { padding-top: 4px; padding-bottom: 4px; }
 +
 +notebook > header.left > tabs:not(:only-child), notebook > header.right > tabs:not(:only-child) { margin-top: 3px; margin-bottom: 3px; }
 +
 +notebook > header.left > tabs:not(:only-child):first-child, notebook > header.right > tabs:not(:only-child):first-child { margin-top: -1px; }
 +
 +notebook > header.left > tabs:not(:only-child):last-child, notebook > header.right > tabs:not(:only-child):last-child { margin-bottom: -1px; }
 +
 +notebook > header.left > tabs > tab, notebook > header.right > tabs > tab { margin-top: 4px; margin-bottom: 4px; }
 +
 +notebook > header.left > tabs > tab.reorderable-page, notebook > header.right > tabs > tab.reorderable-page { border-style: solid none; }
 +
 +notebook > header.top > tabs > tab { padding-bottom: 4px; }
 +
 +notebook > header.bottom > tabs > tab { padding-top: 4px; }
 +
 +notebook > stack:not(:only-child) { background-color: #ffffff; }
 +
 +/************** Scrollbars * */
 +scrollbar { background-color: #cecece; transition: all 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
 +
 +scrollbar.top { border-bottom: 1px solid #cdc7c2; }
 +
 +scrollbar.bottom { border-top: 1px solid #cdc7c2; }
 +
 +scrollbar.left { border-right: 1px solid #cdc7c2; }
 +
 +scrollbar.right { border-left: 1px solid #cdc7c2; }
 +
 +scrollbar > range > trough > slider { min-width: 8px; min-height: 8px; margin: -1px; border: 4px solid transparent; border-radius: 10px; background-clip: padding-box; background-color: #7e8182; transition: all 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
 +
 +scrollbar > range > trough > slider:hover { background-color: #565b5c; }
 +
 +scrollbar > range > trough > slider:hover:active { background-color: #1b6acb; }
 +
 +scrollbar > range > trough > slider:disabled { background-color: transparent; }
 +
 +scrollbar > range.fine-tune > trough > slider { transition: none; min-width: 6px; min-height: 6px; }
 +
 +scrollbar > range.fine-tune.horizontal > trough > slider { border-width: 5px 4px; }
 +
 +scrollbar > range.fine-tune.vertical > trough > slider { border-width: 4px 5px; }
 +
 +scrollbar.overlay-indicator:not(.dragging):not(.hovering) { border-color: transparent; opacity: 0.4; background-color: transparent; }
 +
 +scrollbar.overlay-indicator:not(.dragging):not(.hovering) > range > trough > slider { margin: 0; min-width: 3px; min-height: 3px; background-color: #2e3436; border: 1px solid white; }
 +
 +scrollbar.overlay-indicator.horizontal:not(.dragging):not(.hovering) > range > trough > slider { margin: 0 2px; min-width: 40px; }
 +
 +scrollbar.overlay-indicator.vertical:not(.dragging):not(.hovering) > range > trough > slider { margin: 2px 0; min-height: 40px; }
 +
 +scrollbar.overlay-indicator.dragging, scrollbar.overlay-indicator.hovering { opacity: 0.8; }
 +
 +scrollbar.horizontal > range > trough > slider { min-width: 40px; }
 +
 +scrollbar.vertical > range > trough > slider { min-height: 40px; }
 +
 +treeview ~ scrollbar.vertical { border-top: 1px solid #cdc7c2; margin-top: -1px; }
 +
 +/********** Switch * */
 +switch { font-weight: bold; font-size: smaller; border: 1px solid #cdc7c2; border-radius: 14px; color: #2e3436; background-color: #e1dedb; transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; /* only show i / o for the accessible theme */ }
 +
 +switch { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +switch:focus:focus-visible { outline-color: rgba(53, 132, 228, 0.5); outline-width: 2px; outline-offset: 0; }
 +
 +headerbar switch { background-color: #cecac5; }
 +
 +switch:checked { color: #ffffff; border-color: #185fb4; background-color: #3584e4; }
 +
 +switch:disabled { color: #929595; border-color: #cdc7c2; background-color: #faf9f8; text-shadow: none; }
 +
 +switch > slider { color: #2e3436; outline-color: rgba(53, 132, 228, 0.5); border-color: #cdc7c2; background-image: linear-gradient(to top, #f6f5f4 2px, #fbfafa); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); margin: -1px; min-width: 24px; min-height: 24px; border: 1px solid; border-color: #cdc7c2; border-radius: 50%; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
 +
 +switch > image { color: transparent; }
 +
 +switch:hover > slider { color: #2e3436; border-color: #cdc7c2; background-image: linear-gradient(to top, #d6d1cd, #e8e6e3 1px); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +switch:checked > slider { border: 1px solid #185fb4; }
 +
 +switch:disabled > slider { color: #929595; border-color: #d5d0cc; background-image: image(#faf9f8); }
 +
 +row:selected switch { outline-color: rgba(255, 255, 255, 0.8); box-shadow: none; border-color: #185fb4; }
 +
 +row:selected switch > slider:checked, row:selected switch > slider { border-color: #185fb4; }
 +
 +/************************* Check and Radio items * */
 +.view.content-view.check:not(list), iconview.content-view.check:not(list), .content-view .tile check:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: #3584e4; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:hover:not(list), iconview.content-view.check:hover:not(list), .content-view .tile check:hover:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: #3584e4; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:active:not(list), iconview.content-view.check:active:not(list), .content-view .tile check:active:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: #3584e4; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:backdrop:not(list), iconview.content-view.check:backdrop:not(list), .content-view .tile check:backdrop:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: transparent; background-color: #8d8d8d; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: none; -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:checked:not(list), iconview.content-view.check:checked:not(list), .content-view .tile check:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: #eeeeec; background-color: #3584e4; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:checked:hover:not(list), iconview.content-view.check:checked:hover:not(list), .content-view .tile check:checked:hover:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: #eeeeec; background-color: #3584e4; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:checked:active:not(list), iconview.content-view.check:checked:active:not(list), .content-view .tile check:checked:active:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: #eeeeec; background-color: #3584e4; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
 +
 +.view.content-view.check:backdrop:checked:not(list), iconview.content-view.check:backdrop:checked:not(list), .content-view .tile check:backdrop:checked:not(list) { margin: 4px; min-width: 32px; min-height: 32px; color: rgba(238, 238, 236, 0.8); background-color: #8d8d8d; border-radius: 5px; background-image: none; transition: 200ms; box-shadow: none; border-width: 0; -gtk-icon-source: -gtk-icontheme('object-select-symbolic'); -gtk-icon-shadow: none; }
 +
 +checkbutton { border-spacing: 4px; border-radius: 5px; transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +checkbutton { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +checkbutton:focus:focus-visible { outline-color: rgba(53, 132, 228, 0.5); outline-width: 2px; outline-offset: -2px; }
 +
 +checkbutton.text-button { padding: 4px; }
 +
 +check, radio { min-height: 14px; min-width: 14px; border: 1px solid; -gtk-icon-source: none; }
 +
 +check, radio { background-clip: padding-box; background-image: linear-gradient(to bottom, white 20%, white 90%); border-color: #bfb8b1; box-shadow: 0 1px rgba(0, 0, 0, 0.05); color: #ffffff; }
 +
 +check:hover, radio:hover { background-image: image(#f2f2f2); }
 +
 +check:active, radio:active { box-shadow: inset 0 1px rgba(0, 0, 0, 0.2); background-image: image(#d9d9d9); }
 +
 +check:disabled, radio:disabled { box-shadow: none; color: rgba(255, 255, 255, 0.7); }
 +
 +check:checked, radio:checked { background-clip: border-box; background-image: linear-gradient(to bottom, #4b92e7 20%, #3584e4 90%); border-color: #1b6acb; box-shadow: 0 1px rgba(0, 0, 0, 0.05); color: #ffffff; }
 +
 +check:checked:hover, radio:checked:hover { background-image: linear-gradient(to bottom, #5d9de9 10%, #478fe6 90%); }
 +
 +check:checked:active, radio:checked:active { box-shadow: inset 0 1px rgba(0, 0, 0, 0.2); background-image: image(#1f76e1); }
 +
 +check:checked:disabled, radio:checked:disabled { box-shadow: none; color: rgba(255, 255, 255, 0.7); }
 +
 +check:indeterminate, radio:indeterminate { background-clip: border-box; background-image: linear-gradient(to bottom, #4b92e7 20%, #3584e4 90%); border-color: #1b6acb; box-shadow: 0 1px rgba(0, 0, 0, 0.05); color: #ffffff; }
 +
 +check:indeterminate:hover, radio:indeterminate:hover { background-image: linear-gradient(to bottom, #5d9de9 10%, #478fe6 90%); }
 +
 +check:indeterminate:active, radio:indeterminate:active { box-shadow: inset 0 1px rgba(0, 0, 0, 0.2); background-image: image(#1f76e1); }
 +
 +check:indeterminate:disabled, radio:indeterminate:disabled { box-shadow: none; color: rgba(255, 255, 255, 0.7); }
 +
 +row:selected check, row:selected radio { border-color: #1b6acb; }
 +
 +.osd check, .osd radio { color: #eeeeec; outline-color: rgba(53, 132, 228, 0.5); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; }
 +
 +.osd check:hover, .osd radio:hover { color: #eeeeec; outline-color: rgba(53, 132, 228, 0.5); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; }
 +
 +.osd check:active, .osd radio:active { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(2, 2, 2, 0.7)); background-clip: padding-box; box-shadow: none; }
 +
 +.osd check:disabled, .osd radio:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; }
 +
 +check { border-radius: 3px; -gtk-icon-size: 14px; }
 +
 +check:checked { -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets/check-symbolic.symbolic.png")), -gtk-recolor(url("assets/check@2-symbolic.symbolic.png"))); }
 +
 +check:indeterminate { -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets/dash-symbolic.symbolic.png")), -gtk-recolor(url("assets/dash@2-symbolic.symbolic.png"))); }
 +
 +treeview.view radio:selected:focus, treeview.view radio:selected, radio { border-radius: 100%; -gtk-icon-size: 14px; }
 +
 +treeview.view radio:checked:selected, radio:checked { -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets/bullet-symbolic.symbolic.png")), -gtk-recolor(url("assets/bullet@2-symbolic.symbolic.png"))); }
 +
 +treeview.view radio:indeterminate:selected, radio:indeterminate { -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets/dash-symbolic.symbolic.png")), -gtk-recolor(url("assets/dash@2-symbolic.symbolic.png"))); }
 +
 +treeview.view check:selected:focus, treeview.view check:selected, treeview.view radio:selected:focus, treeview.view radio:selected { color: #ffffff; border-color: #185fb4; }
 +
 +/************ GtkScale * */
 +progressbar > trough, scale > trough > fill, scale > trough { border: 1px solid #e1dedb; border-radius: 3px; background-color: #e1dedb; }
 +
 +headerbar progressbar > trough, headerbar scale > trough > fill, headerbar scale > trough { background-color: #cecac5; }
 +
 +progressbar > trough:disabled, scale > trough > fill:disabled, scale > trough:disabled { background-color: #faf9f8; border-color: #d5d0cc; }
 +
 +row:selected progressbar > trough, row:selected scale > trough > fill, row:selected scale > trough { outline-color: rgba(255, 255, 255, 0.8); border-color: #185fb4; }
 +
 +.osd progressbar > trough, .osd scale > trough > fill, .osd scale > trough { border-color: rgba(0, 0, 0, 0.7); background-color: rgba(0, 0, 0, 0.5); }
 +
 +.osd progressbar > trough:disabled, .osd scale > trough > fill:disabled, .osd scale > trough:disabled { background-color: rgba(71, 71, 71, 0.5); }
 +
 +progressbar > trough > progress, scale > trough > highlight { border: 1px solid #3584e4; border-radius: 3px; background-color: #3584e4; }
 +
 +progressbar > trough > progress:disabled, scale > trough > highlight:disabled { background-color: transparent; border-color: transparent; }
 +
 +row:selected progressbar > trough > progress, row:selected scale > trough > highlight { border-color: #185fb4; }
 +
 +.osd progressbar > trough > progress, .osd scale > trough > highlight { border-color: rgba(0, 0, 0, 0.7); }
 +
 +.osd progressbar > trough > progress:disabled, .osd scale > trough > highlight:disabled { border-color: transparent; }
 +
 +scale { min-height: 10px; min-width: 10px; padding: 12px; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +scale > trough { outline: 0 solid transparent; outline-offset: 16px; }
 +
 +scale:focus:focus-visible > trough { outline-color: rgba(53, 132, 228, 0.5); outline-width: 2px; outline-offset: 10px; }
 +
 +scale > trough { transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
 +
 +scale > trough > fill, scale > trough > highlight { margin: -1px; }
 +
 +scale > trough > slider { min-height: 18px; min-width: 18px; margin: -9px; }
 +
 +scale.fine-tune.horizontal { padding-top: 9px; padding-bottom: 9px; min-height: 16px; }
 +
 +scale.fine-tune.vertical { padding-left: 9px; padding-right: 9px; min-width: 16px; }
 +
 +scale.fine-tune > trough > slider { margin: -6px; }
 +
 +scale.fine-tune > trough > fill, scale.fine-tune > trough > highlight, scale.fine-tune > trough { border-radius: 5px; }
 +
 +scale > trough > fill:disabled { border-color: transparent; background-color: transparent; }
 +
 +.osd scale > trough > fill { background-color: rgba(91, 91, 90, 0.775); }
 +
 +.osd scale > trough > fill:disabled { border-color: transparent; background-color: transparent; }
 +
 +scale > trough > slider { color: #2e3436; outline-color: rgba(53, 132, 228, 0.5); border-color: #cdc7c2; background-image: linear-gradient(to top, #f6f5f4 2px, #fbfafa); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); border-width: 1px; border-style: solid; border-radius: 100%; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: background, border, box-shadow; }
 +
 +scale > trough > slider:hover { color: #2e3436; border-color: #cdc7c2; background-image: linear-gradient(to top, #d6d1cd, #e8e6e3 1px); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +scale > trough > slider:active { border-color: #185fb4; }
 +
 +scale > trough > slider:disabled { color: #929595; border-color: #d5d0cc; background-image: image(#faf9f8); }
 +
 +row:selected scale > trough > slider:disabled, row:selected scale > trough > slider { border-color: #185fb4; }
 +
 +.osd scale > trough > slider { color: #eeeeec; outline-color: rgba(53, 132, 228, 0.5); border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; border-color: rgba(0, 0, 0, 0.7); background-color: #353535; }
 +
 +.osd scale > trough > slider:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(27, 27, 27, 0.7)); background-clip: padding-box; background-color: #353535; }
 +
 +.osd scale > trough > slider:active { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(2, 2, 2, 0.7)); background-clip: padding-box; box-shadow: none; background-color: #353535; }
 +
 +.osd scale > trough > slider:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; background-color: #353535; }
 +
 +scale > value { color: alpha(currentColor,0.55); font-feature-settings: "tnum"; }
 +
 +scale.horizontal > marks { color: alpha(currentColor,0.55); }
 +
 +scale.horizontal > marks.top { margin-bottom: 6px; }
 +
 +scale.horizontal > marks.bottom { margin-top: 6px; }
 +
 +scale.horizontal > marks indicator { background-color: currentColor; min-height: 6px; min-width: 1px; }
 +
 +scale.horizontal > value.left { margin-right: 9px; }
 +
 +scale.horizontal > value.right { margin-left: 9px; }
 +
 +scale.horizontal.fine-tune > marks.top { margin-top: 3px; }
 +
 +scale.horizontal.fine-tune > marks.bottom { margin-bottom: 3px; }
 +
 +scale.horizontal.fine-tune > marks indicator { min-height: 3px; }
 +
 +scale.vertical > marks { color: alpha(currentColor,0.55); }
 +
 +scale.vertical > marks.top { margin-right: 6px; }
 +
 +scale.vertical > marks.bottom { margin-left: 6px; }
 +
 +scale.vertical > marks indicator { background-color: currentColor; min-height: 1px; min-width: 6px; }
 +
 +scale.vertical > value.top { margin-bottom: 9px; }
 +
 +scale.vertical > value.bottom { margin-top: 9px; }
 +
 +scale.vertical.fine-tune > marks.top { margin-left: 3px; }
 +
 +scale.vertical.fine-tune > marks.bottom { margin-right: 3px; }
 +
 +scale.vertical.fine-tune > marks indicator { min-height: 3px; }
 +
 +scale.horizontal.marks-before:not(.marks-after) > trough > slider { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-above.png"), url("assets/slider-horz-scale-has-marks-above@2.png")); min-height: 26px; min-width: 22px; margin-top: -14px; background-position: top; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -7px -10px; margin-top: -11px; }
 +
 +scale.horizontal.marks-before:not(.marks-after) > trough > slider:hover { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-above-hover.png"), url("assets/slider-horz-scale-has-marks-above-hover@2.png")); min-height: 26px; min-width: 22px; margin-top: -14px; background-position: top; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -7px -10px; margin-top: -11px; }
 +
 +scale.horizontal.marks-before:not(.marks-after) > trough > slider:active { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-above-active.png"), url("assets/slider-horz-scale-has-marks-above-active@2.png")); min-height: 26px; min-width: 22px; margin-top: -14px; background-position: top; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -7px -10px; margin-top: -11px; }
 +
 +scale.horizontal.marks-before:not(.marks-after) > trough > slider:disabled { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-above-insensitive.png"), url("assets/slider-horz-scale-has-marks-above-insensitive@2.png")); min-height: 26px; min-width: 22px; margin-top: -14px; background-position: top; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -7px -10px; margin-top: -11px; }
 +
 +scale.horizontal.marks-after:not(.marks-before) > trough > slider { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-below.png"), url("assets/slider-horz-scale-has-marks-below@2.png")); min-height: 26px; min-width: 22px; margin-bottom: -14px; background-position: bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -7px -10px; margin-bottom: -11px; }
 +
 +scale.horizontal.marks-after:not(.marks-before) > trough > slider:hover { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-below-hover.png"), url("assets/slider-horz-scale-has-marks-below-hover@2.png")); min-height: 26px; min-width: 22px; margin-bottom: -14px; background-position: bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -7px -10px; margin-bottom: -11px; }
 +
 +scale.horizontal.marks-after:not(.marks-before) > trough > slider:active { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-below-active.png"), url("assets/slider-horz-scale-has-marks-below-active@2.png")); min-height: 26px; min-width: 22px; margin-bottom: -14px; background-position: bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -7px -10px; margin-bottom: -11px; }
 +
 +scale.horizontal.marks-after:not(.marks-before) > trough > slider:disabled { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-horz-scale-has-marks-below-insensitive.png"), url("assets/slider-horz-scale-has-marks-below-insensitive@2.png")); min-height: 26px; min-width: 22px; margin-bottom: -14px; background-position: bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.horizontal.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -7px -10px; margin-bottom: -11px; }
 +
 +scale.vertical.marks-before:not(.marks-after) > trough > slider { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-above.png"), url("assets/slider-vert-scale-has-marks-above@2.png")); min-height: 22px; min-width: 26px; margin-left: -14px; background-position: left bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -10px -7px; margin-left: -11px; }
 +
 +scale.vertical.marks-before:not(.marks-after) > trough > slider:hover { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-above-hover.png"), url("assets/slider-vert-scale-has-marks-above-hover@2.png")); min-height: 22px; min-width: 26px; margin-left: -14px; background-position: left bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -10px -7px; margin-left: -11px; }
 +
 +scale.vertical.marks-before:not(.marks-after) > trough > slider:active { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-above-active.png"), url("assets/slider-vert-scale-has-marks-above-active@2.png")); min-height: 22px; min-width: 26px; margin-left: -14px; background-position: left bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -10px -7px; margin-left: -11px; }
 +
 +scale.vertical.marks-before:not(.marks-after) > trough > slider:disabled { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-above-insensitive.png"), url("assets/slider-vert-scale-has-marks-above-insensitive@2.png")); min-height: 22px; min-width: 26px; margin-left: -14px; background-position: left bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-before.fine-tune:not(.marks-after) > trough > slider { margin: -10px -7px; margin-left: -11px; }
 +
 +scale.vertical.marks-after:not(.marks-before) > trough > slider { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-below.png"), url("assets/slider-vert-scale-has-marks-below@2.png")); min-height: 22px; min-width: 26px; margin-right: -14px; background-position: right bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -10px -7px; margin-right: -11px; }
 +
 +scale.vertical.marks-after:not(.marks-before) > trough > slider:hover { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-below-hover.png"), url("assets/slider-vert-scale-has-marks-below-hover@2.png")); min-height: 22px; min-width: 26px; margin-right: -14px; background-position: right bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -10px -7px; margin-right: -11px; }
 +
 +scale.vertical.marks-after:not(.marks-before) > trough > slider:active { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-below-active.png"), url("assets/slider-vert-scale-has-marks-below-active@2.png")); min-height: 22px; min-width: 26px; margin-right: -14px; background-position: right bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -10px -7px; margin-right: -11px; }
 +
 +scale.vertical.marks-after:not(.marks-before) > trough > slider:disabled { margin: -10px; border-style: none; border-radius: 0; background-color: transparent; background-image: -gtk-scaled(url("assets/slider-vert-scale-has-marks-below-insensitive.png"), url("assets/slider-vert-scale-has-marks-below-insensitive@2.png")); min-height: 22px; min-width: 26px; margin-right: -14px; background-position: right bottom; background-repeat: no-repeat; box-shadow: none; }
 +
 +scale.vertical.marks-after.fine-tune:not(.marks-before) > trough > slider { margin: -10px -7px; margin-right: -11px; }
 +
 +scale.color { min-height: 0; min-width: 0; }
 +
 +scale.color > trough { background-image: image(#cdc7c2); background-repeat: no-repeat; }
 +
 +scale.color.horizontal { padding: 0 0 15px 0; }
 +
 +scale.color.horizontal > trough { padding-bottom: 4px; background-position: 0 -3px; border-top-left-radius: 0; border-top-right-radius: 0; }
 +
 +scale.color.horizontal > trough > slider:dir(ltr):hover, scale.color.horizontal > trough > slider:dir(ltr):backdrop, scale.color.horizontal > trough > slider:dir(ltr):disabled, scale.color.horizontal > trough > slider:dir(ltr):backdrop:disabled, scale.color.horizontal > trough > slider:dir(ltr), scale.color.horizontal > trough > slider:dir(rtl):hover, scale.color.horizontal > trough > slider:dir(rtl):backdrop, scale.color.horizontal > trough > slider:dir(rtl):disabled, scale.color.horizontal > trough > slider:dir(rtl):backdrop:disabled, scale.color.horizontal > trough > slider:dir(rtl) { margin-bottom: -15px; margin-top: 6px; }
 +
 +scale.color.vertical:dir(ltr) { padding: 0 0 0 15px; }
 +
 +scale.color.vertical:dir(ltr) > trough { padding-left: 4px; background-position: 3px 0; border-bottom-right-radius: 0; border-top-right-radius: 0; }
 +
 +scale.color.vertical:dir(ltr) > trough > slider:hover, scale.color.vertical:dir(ltr) > trough > slider:backdrop, scale.color.vertical:dir(ltr) > trough > slider:disabled, scale.color.vertical:dir(ltr) > trough > slider:backdrop:disabled, scale.color.vertical:dir(ltr) > trough > slider { margin-left: -15px; margin-right: 6px; }
 +
 +scale.color.vertical:dir(rtl) { padding: 0 15px 0 0; }
 +
 +scale.color.vertical:dir(rtl) > trough { padding-right: 4px; background-position: -3px 0; border-bottom-left-radius: 0; border-top-left-radius: 0; }
 +
 +scale.color.vertical:dir(rtl) > trough > slider:hover, scale.color.vertical:dir(rtl) > trough > slider:backdrop, scale.color.vertical:dir(rtl) > trough > slider:disabled, scale.color.vertical:dir(rtl) > trough > slider:backdrop:disabled, scale.color.vertical:dir(rtl) > trough > slider { margin-right: -15px; margin-left: 6px; }
 +
 +scale.color.fine-tune.horizontal:dir(ltr), scale.color.fine-tune.horizontal:dir(rtl) { padding: 0 0 12px 0; }
 +
 +scale.color.fine-tune.horizontal:dir(ltr) > trough, scale.color.fine-tune.horizontal:dir(rtl) > trough { padding-bottom: 7px; background-position: 0 -6px; }
 +
 +scale.color.fine-tune.horizontal:dir(ltr) > trough > slider, scale.color.fine-tune.horizontal:dir(rtl) > trough > slider { margin-bottom: -15px; margin-top: 6px; }
 +
 +scale.color.fine-tune.vertical:dir(ltr) { padding: 0 0 0 12px; }
 +
 +scale.color.fine-tune.vertical:dir(ltr) > trough { padding-left: 7px; background-position: 6px 0; }
 +
 +scale.color.fine-tune.vertical:dir(ltr) > trough > slider { margin-left: -15px; margin-right: 6px; }
 +
 +scale.color.fine-tune.vertical:dir(rtl) { padding: 0 12px 0 0; }
 +
 +scale.color.fine-tune.vertical:dir(rtl) > trough { padding-right: 7px; background-position: -6px 0; }
 +
 +scale.color.fine-tune.vertical:dir(rtl) > trough > slider { margin-right: -15px; margin-left: 6px; }
 +
 +/***************** Progress bars * */
 +progressbar { font-size: smaller; color: rgba(46, 52, 54, 0.4); font-feature-settings: "tnum"; }
 +
 +progressbar.horizontal > trough { min-width: 150px; }
 +
 +progressbar.horizontal > trough, progressbar.horizontal > trough > progress { min-height: 2px; }
 +
 +progressbar.vertical > trough { min-height: 80px; }
 +
 +progressbar.vertical > trough, progressbar.vertical > trough > progress { min-width: 2px; }
 +
 +progressbar.horizontal > trough > progress { margin: 0 -1px; }
 +
 +progressbar.vertical > trough > progress { margin: -1px 0; }
 +
 +progressbar > trough > progress { /* share most of scales' */ /* override insensitive that is specific to progress */ border-radius: 1.5px; }
 +
 +progressbar > trough > progress:disabled { background-color: #929595; border-color: #929595; }
 +
 +progressbar > trough > progress.left { border-top-left-radius: 5px; border-bottom-left-radius: 5px; }
 +
 +progressbar > trough > progress.right { border-top-right-radius: 5px; border-bottom-right-radius: 5px; }
 +
 +progressbar > trough > progress.top { border-top-right-radius: 5px; border-top-left-radius: 5px; }
 +
 +progressbar > trough > progress.bottom { border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; }
 +
 +progressbar.osd { min-width: 3px; min-height: 3px; background-color: transparent; }
 +
 +progressbar.osd > trough { border-style: none; border-radius: 0; background-color: transparent; box-shadow: none; }
 +
 +progressbar.osd > trough > progress { border-style: none; border-radius: 0; }
 +
 +progressbar > trough.empty > progress { all: unset; }
 +
 +/************* Level Bar * */
 +levelbar.horizontal trough > block { min-height: 9px; border-radius: 5px; }
 +
 +levelbar.horizontal trough > block:dir(rtl) { border-radius: 0 5px 5px 0; }
 +
 +levelbar.horizontal trough > block:dir(ltr) { border-radius: 5px 0 0 5px; }
 +
 +levelbar.horizontal trough > block.empty, levelbar.horizontal trough > block.full { border-radius: 5px; }
 +
 +levelbar.horizontal.discrete trough > block { min-height: 2px; margin: 1px; min-width: 24px; border-radius: 0; }
 +
 +levelbar.horizontal.discrete trough > block:first-child { border-radius: 2px 0 0 2px; }
 +
 +levelbar.horizontal.discrete trough > block:last-child { border-radius: 0 2px 2px 0; }
 +
 +levelbar.vertical trough > block { min-width: 9px; border-radius: 5px; }
 +
 +levelbar.vertical.discrete > trough > block { min-width: 2px; margin: 1px 0; min-height: 32px; }
 +
 +levelbar > trough { padding: 0; }
 +
 +levelbar > trough > block { border: 1px solid; }
 +
 +levelbar > trough > block.low { border-color: #f57900; background-color: #f57900; }
 +
 +levelbar > trough > block.high, levelbar > trough > block:not(.empty) { border-color: #3584e4; background-color: #3584e4; }
 +
 +levelbar > trough > block.full { border-color: #33d17a; background-color: #33d17a; }
 +
 +levelbar > trough > block.empty { background-color: #ebe8e6; border-color: #ebe8e6; }
 +
 +/**************** Print dialog * */
 +window.dialog.print drawing { color: #2e3436; background: none; border: none; padding: 0; }
 +
 +window.dialog.print drawing paper { background: white; color: #2e3436; border: 1px solid #cdc7c2; }
 +
 +window.dialog.print .dialog-action-box { margin: 12px; }
 +
 +/********** Frames * */
 +frame, .frame { border: 1px solid #cdc7c2; }
 +
 +frame { border-radius: 8px; }
 +
 +frame > label { margin: 4px; }
 +
 +actionbar > revealer > box { padding: 6px; border-top: 1px solid #cdc7c2; }
 +
 +actionbar > revealer > box, actionbar > revealer > box > box.start, actionbar > revealer > box > box.end { border-spacing: 6px; }
 +
 +scrolledwindow > overshoot.top { background-image: radial-gradient(farthest-side at top, #b6aea5 85%, rgba(182, 174, 165, 0)), radial-gradient(farthest-side at top, rgba(46, 52, 54, 0.07), rgba(46, 52, 54, 0)); background-size: 100% 3%, 100% 50%; background-repeat: no-repeat; background-position: top; background-color: transparent; border: none; box-shadow: none; }
 +
 +scrolledwindow > overshoot.bottom { background-image: radial-gradient(farthest-side at bottom, #b6aea5 85%, rgba(182, 174, 165, 0)), radial-gradient(farthest-side at bottom, rgba(46, 52, 54, 0.07), rgba(46, 52, 54, 0)); background-size: 100% 3%, 100% 50%; background-repeat: no-repeat; background-position: bottom; background-color: transparent; border: none; box-shadow: none; }
 +
 +scrolledwindow > overshoot.left { background-image: radial-gradient(farthest-side at left, #b6aea5 85%, rgba(182, 174, 165, 0)), radial-gradient(farthest-side at left, rgba(46, 52, 54, 0.07), rgba(46, 52, 54, 0)); background-size: 3% 100%, 50% 100%; background-repeat: no-repeat; background-position: left; background-color: transparent; border: none; box-shadow: none; }
 +
 +scrolledwindow > overshoot.right { background-image: radial-gradient(farthest-side at right, #b6aea5 85%, rgba(182, 174, 165, 0)), radial-gradient(farthest-side at right, rgba(46, 52, 54, 0.07), rgba(46, 52, 54, 0)); background-size: 3% 100%, 50% 100%; background-repeat: no-repeat; background-position: right; background-color: transparent; border: none; box-shadow: none; }
 +
 +scrolledwindow > junction { background: #cdc7c2, linear-gradient(to bottom, transparent 1px, #cecece 1px), linear-gradient(to right, transparent 1px, #cecece 1px); }
 +
 +scrolledwindow > junction:dir(rtl) { background: #cdc7c2, linear-gradient(to bottom, transparent 1px, #cecece 1px), linear-gradient(to left, transparent 1px, #cecece 1px); }
 +
 +separator { background: #d8d4d0; min-width: 1px; min-height: 1px; }
 +
 +/********* Lists * */
 +listview, list { color: black; background-color: #ffffff; border-color: #cdc7c2; }
 +
 +listview:backdrop, list:backdrop { color: #323232; background-color: #fcfcfc; border-color: #d5d0cc; }
 +
 +listview > row, list > row { padding: 2px; }
 +
 +listview > row.expander, list > row.expander { padding: 0px; }
 +
 +listview > row.expander .row-header, list > row.expander .row-header { padding: 2px; }
 +
 +listview.horizontal row.separator, listview.separators.horizontal > row:not(.separator), list.horizontal row.separator, list.separators.horizontal > row:not(.separator) { border-left: 1px solid #d7d2ce; }
 +
 +listview:not(.horizontal) row.separator, listview.separators:not(.horizontal) > row:not(.separator), list:not(.horizontal) row.separator, list.separators:not(.horizontal) > row:not(.separator) { border-bottom: 1px solid #d7d2ce; }
 +
 +row { transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +row { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +row:focus:focus-visible { outline-color: rgba(53, 132, 228, 0.5); outline-width: 2px; outline-offset: -2px; }
 +
 +row.activatable.has-open-popup, row.activatable:hover { background-color: rgba(46, 52, 54, 0.05); }
 +
 +row.activatable:active { box-shadow: inset 0 2px 2px -2px rgba(0, 0, 0, 0.2); }
 +
 +row.activatable:selected:active { box-shadow: inset 0 2px 3px -1px rgba(0, 0, 0, 0.5); }
 +
 +row.activatable.has-open-popup:selected, row.activatable:selected:hover { background-color: #347cd3; }
 +
 +row:selected { outline-color: rgba(255, 255, 255, 0.8); }
 +
 +columnview > listview > row { padding: 0; }
 +
 +columnview > listview > row > cell { padding: 8px 6px; }
 +
 +columnview > listview > row > cell:not(:first-child) { border-left: 1px solid transparent; }
 +
 +columnview.column-separators > listview > row > cell { border-left-color: #d7d2ce; }
 +
 +columnview.data-table > listview > row > cell { padding-top: 2px; padding-bottom: 2px; }
 +
 +treeexpander { border-spacing: 4px; }
 +
 +/******************************************************** Data Tables                                          * treeview like tables with individual focusable cells * https://gitlab.gnome.org/GNOME/gtk/-/issues/2929     * */
 +columnview row:not(:selected) cell editablelabel:not(.editing):focus-within { outline: 2px solid rgba(53, 132, 228, 0.5); }
 +
 +columnview row:not(:selected) cell editablelabel.editing:focus-within { outline: 2px solid #3584e4; }
 +
 +columnview row:not(:selected) cell editablelabel.editing text selection { color: #ffffff; background-color: #3584e4; }
 +
 +/******************************************************* Rich Lists                                          * Large list usually containing lots of widgets       * https://gitlab.gnome.org/GNOME/gtk/-/issues/3073    * */
 +.rich-list { /* rich lists usually containing other widgets than just labels/text */ }
 +
 +.rich-list > row { padding: 8px 12px; min-height: 32px; /* should be tall even when only containing a label */ }
 +
 +.rich-list > row > box { border-spacing: 12px; }
 +
 +/********************* App Notifications * */
 +.app-notification { padding: 10px; border-spacing: 10px; border-radius: 0 0 5px 5px; background-color: rgba(53, 53, 53, 0.7); background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.2), transparent 2px); background-clip: padding-box; }
 +
 +.app-notification border { border: none; }
 +
 +/************* Expanders * */
 +expander { min-width: 16px; min-height: 16px; -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); }
 +
 +expander:dir(rtl) { -gtk-icon-source: -gtk-icontheme("pan-end-symbolic-rtl"); }
 +
 +expander:disabled { color: #929595; }
 +
 +expander:checked { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
 +
 +expander-widget { transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +expander-widget > box > title { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +expander-widget:focus:focus-visible > box > title { outline-color: rgba(53, 132, 228, 0.5); outline-width: 2px; outline-offset: -2px; }
 +
 +expander-widget > box > title { transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); border-radius: 5px; }
 +
 +expander-widget > box > title:hover > expander { color: #748489; }
 +
 +.navigation-sidebar:not(decoration):not(window):drop(active):focus, .navigation-sidebar:not(decoration):not(window):drop(active), placessidebar:not(decoration):not(window):drop(active):focus, placessidebar:not(decoration):not(window):drop(active), stackswitcher:not(decoration):not(window):drop(active):focus, stackswitcher:not(decoration):not(window):drop(active), expander-widget:not(decoration):not(window):drop(active):focus, expander-widget:not(decoration):not(window):drop(active) { box-shadow: none; }
 +
 +/************ Calendar * */
 +calendar { color: black; border: 1px solid #cdc7c2; }
 +
 +calendar > header { border-bottom: 1px solid #cdc7c2; }
 +
 +calendar > header > button { border: none; box-shadow: none; background: none; border-radius: 0; }
 +
 +calendar > header > button:backdrop { background: none; }
 +
 +calendar > grid > label.today { box-shadow: inset 0px -2px #cdc7c2; }
 +
 +calendar > grid > label.today:selected { box-shadow: none; }
 +
 +calendar > grid > label:focus { outline-color: rgba(53, 132, 228, 0.5); outline-offset: -2px; outline-width: 2px; outline-style: solid; }
 +
 +calendar > grid > label.day-number { padding: 4px; }
 +
 +calendar > grid > label.day-number:selected { border-radius: 3px; }
 +
 +calendar > grid > label.day-number.other-month { color: alpha(currentColor,0.3); }
 +
 +/*********** Dialogs * */
 +window.dialog.message .titlebar { min-height: 20px; background-image: none; background-color: #f6f5f4; border-style: none; border-top-left-radius: 7px; border-top-right-radius: 7px; }
 +
 +window.dialog.message box.dialog-vbox.vertical { border-spacing: 10px; }
 +
 +window.dialog.message label.title { font-weight: 800; font-size: 15pt; }
 +
 +window.dialog.message.csd.background { border-bottom-left-radius: 9px; border-bottom-right-radius: 9px; }
 +
 +window.dialog.message.csd .dialog-action-area button { padding: 10px 14px; border-radius: 0; border-left-style: solid; border-right-style: none; border-bottom-style: none; }
 +
 +window.dialog.message.csd .dialog-action-area button:first-child { border-left-style: none; border-bottom-left-radius: 7px; }
 +
 +window.dialog.message.csd .dialog-action-area button:last-child { border-bottom-right-radius: 7px; }
 +
 +filechooser .dialog-action-box { border-top: 1px solid #cdc7c2; }
 +
 +filechooser #pathbarbox { border-bottom: 1px solid #f6f5f4; }
 +
 +filechooserbutton > button > box { border-spacing: 6px; }
 +
 +filechooserbutton:drop(active) { box-shadow: none; border-color: transparent; }
 +
 +/*********** Sidebar * */
 +.sidebar { background-color: #fbfafa; }
 +
 +.sidebar:not(separator):dir(ltr), .sidebar.left:not(separator), .sidebar.left:not(separator):dir(rtl) { border-right: 1px solid #cdc7c2; border-left-style: none; }
 +
 +.sidebar:not(separator):dir(rtl), .sidebar.right:not(separator) { border-left: 1px solid #cdc7c2; border-right-style: none; }
 +
 +.sidebar listview.view, .sidebar list { background-color: transparent; }
 +
 +paned .sidebar.left, paned .sidebar.right, paned .sidebar.left:dir(rtl), paned .sidebar:dir(rtl), paned .sidebar:dir(ltr), paned .sidebar { border-style: none; }
 +
 +stacksidebar list.separators:not(.horizontal) > row:not(.separator) { border-bottom: none; }
 +
 +stacksidebar row { padding: 10px 4px; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +stacksidebar row { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +stacksidebar row:focus:focus-visible { outline-color: rgba(53, 132, 228, 0.5); outline-width: 2px; outline-offset: -2px; }
 +
 +stacksidebar row > label { padding-left: 6px; padding-right: 6px; }
 +
 +stacksidebar row.needs-attention > label { background-size: 6px 6px, 0 0; }
 +
 +stacksidebar row:selected { background-color: #e8e6e3; border-radius: 5px; color: #2e3436; }
 +
 +stacksidebar row:selected:hover:dir(ltr), stacksidebar row:selected:hover:dir(rtl) { background-color: #ddd9d5; }
 +
 +stacksidebar row.activatable:active, stacksidebar row.activatable:selected:active { box-shadow: none; }
 +
 +separator.sidebar { background-color: #cdc7c2; }
 +
 +/********************** Navigation Sidebar * */
 +.navigation-sidebar { padding: 5px 0; }
 +
 +.navigation-sidebar > separator { margin: 5px; }
 +
 +.navigation-sidebar > row { min-height: 36px; padding: 0 8px; border-radius: 5px; margin: 0 5px 2px; transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +.navigation-sidebar > row { outline: 0 solid transparent; outline-offset: 4px; }
 +
 +.navigation-sidebar > row:focus-visible:focus-within { outline-color: rgba(53, 132, 228, 0.5); outline-width: 2px; outline-offset: -2px; }
 +
 +.navigation-sidebar > row:hover { background-color: #ddd9d5; }
 +
 +.navigation-sidebar > row:selected { background-color: #e8e6e3; color: inherit; }
 +
 +.navigation-sidebar > row:selected:hover { background-color: #ddd9d5; }
 +
 +.navigation-sidebar > row:disabled { color: #929595; }
 +
 +/**************** File chooser * */
 +row image.sidebar-icon { opacity: 0.7; }
 +
 +/* this should be more generic, only using .navigation-sidebar https://gitlab.gnome.org/GNOME/gtk/-/issues/2929 */
 +placessidebar .navigation-sidebar > row { padding: 0; }
 +
 +placessidebar .navigation-sidebar > row > revealer { padding: 0 14px; }
 +
 +placessidebar .navigation-sidebar > row image.sidebar-icon:dir(ltr) { padding-right: 8px; }
 +
 +placessidebar .navigation-sidebar > row image.sidebar-icon:dir(rtl) { padding-left: 8px; }
 +
 +placessidebar .navigation-sidebar > row label.sidebar-label:dir(ltr) { padding-right: 2px; }
 +
 +placessidebar .navigation-sidebar > row label.sidebar-label:dir(rtl) { padding-left: 2px; }
 +
 +button.sidebar-button { min-height: 26px; min-width: 26px; margin-top: 3px; margin-bottom: 3px; padding: 0; border-radius: 100%; }
 +
 +placessidebar .navigation-sidebar > row:selected:active { box-shadow: none; }
 +
 +placessidebar .navigation-sidebar > row.sidebar-placeholder-row { padding: 0 8px; min-height: 2px; background-image: image(#2ec27e); background-clip: content-box; }
 +
 +placessidebar .navigation-sidebar > row.sidebar-new-bookmark-row { color: #3584e4; }
 +
 +placessidebar .navigation-sidebar > row:drop(active):not(:disabled) { color: #2ec27e; box-shadow: inset 0 1px #2ec27e, inset 0 -1px #2ec27e; }
 +
 +placessidebar .navigation-sidebar > row:drop(active):not(:disabled):selected { color: #ffffff; background-color: #2ec27e; }
 +
 +placesview .server-list-button > image { transition: 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); -gtk-icon-transform: rotate(0turn); }
 +
 +placesview .server-list-button:checked > image { transition: 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); -gtk-icon-transform: rotate(-0.5turn); }
 +
 +placesview > actionbar > revealer > box > box { border-spacing: 6px; }
 +
 +/********* Paned * */
 +paned > separator { min-width: 1px; min-height: 1px; -gtk-icon-source: none; border-style: none; background-color: transparent; background-image: image(#cdc7c2); background-size: 1px 1px; }
 +
 +paned > separator:selected { background-image: image(#3584e4); }
 +
 +paned > separator.wide { min-width: 5px; min-height: 5px; background-color: #f6f5f4; background-image: image(#cdc7c2), image(#cdc7c2); background-size: 1px 1px, 1px 1px; }
 +
 +paned.horizontal > separator { background-repeat: repeat-y; }
 +
 +paned.horizontal > separator:dir(ltr) { margin: 0 -8px 0 0; padding: 0 8px 0 0; background-position: left; }
 +
 +paned.horizontal > separator:dir(rtl) { margin: 0 0 0 -8px; padding: 0 0 0 8px; background-position: right; }
 +
 +paned.horizontal > separator.wide { margin: 0; padding: 0; background-repeat: repeat-y, repeat-y; background-position: left, right; }
 +
 +paned.vertical > separator { margin: 0 0 -8px 0; padding: 0 0 8px 0; background-repeat: repeat-x; background-position: top; }
 +
 +paned.vertical > separator.wide { margin: 0; padding: 0; background-repeat: repeat-x, repeat-x; background-position: bottom, top; }
 +
 +/************** GtkVideo * */
 +video { background: black; }
 +
 +video image.osd { min-width: 64px; min-height: 64px; border-radius: 32px; }
 +
 +/************ Tooltips * */
 +tooltip { padding: 6px 10px; border-radius: 8px; box-shadow: none; }
 +
 +tooltip.background { background-color: rgba(0, 0, 0, 0.8); background-clip: padding-box; border: 1px solid rgba(255, 255, 255, 0.1); color: white; }
 +
 +tooltip > box { border-spacing: 6px; }
 +
 +/***************** Color Chooser * */
 +colorswatch { transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +colorswatch { outline: 0 solid transparent; outline-offset: 6px; }
 +
 +colorswatch:focus:focus-visible { outline-color: rgba(53, 132, 228, 0.5); outline-width: 4px; outline-offset: -2px; }
 +
 +colorswatch:drop(active), colorswatch { border-style: none; }
 +
 +colorswatch.top { border-top-left-radius: 5.5px; border-top-right-radius: 5.5px; }
 +
 +colorswatch.top > overlay { border-top-left-radius: 5px; border-top-right-radius: 5px; }
 +
 +colorswatch.bottom { border-bottom-left-radius: 5.5px; border-bottom-right-radius: 5.5px; }
 +
 +colorswatch.bottom > overlay { border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; }
 +
 +colorswatch.left, colorswatch:first-child:not(.top) { border-top-left-radius: 5.5px; border-bottom-left-radius: 5.5px; }
 +
 +colorswatch.left > overlay, colorswatch:first-child:not(.top) > overlay { border-top-left-radius: 5px; border-bottom-left-radius: 5px; }
 +
 +colorswatch.right, colorswatch:last-child:not(.bottom) { border-top-right-radius: 5.5px; border-bottom-right-radius: 5.5px; }
 +
 +colorswatch.right > overlay, colorswatch:last-child:not(.bottom) > overlay { border-top-right-radius: 5px; border-bottom-right-radius: 5px; }
 +
 +colorswatch.dark > overlay { color: white; }
 +
 +colorswatch.dark.activatable:hover > overlay { border-color: rgba(0, 0, 0, 0.8); }
 +
 +colorswatch.light > overlay { color: black; }
 +
 +colorswatch.light.activatable:hover > overlay { border-color: rgba(0, 0, 0, 0.5); }
 +
 +colorswatch:drop(active) { box-shadow: none; }
 +
 +colorswatch.light:drop(active) > overlay { border-color: #2ec27e; box-shadow: inset 0 0 0 2px #27a56b, inset 0 0 0 1px #2ec27e; }
 +
 +colorswatch.dark:drop(active) > overlay { border-color: #2ec27e; box-shadow: inset 0 0 0 2px rgba(0, 0, 0, 0.3), inset 0 0 0 1px #2ec27e; }
 +
 +colorswatch > overlay { border: 1px solid rgba(0, 0, 0, 0.3); }
 +
 +colorswatch.activatable:hover > overlay { box-shadow: inset 0 1px rgba(255, 255, 255, 0.4), inset 0 -1px rgba(0, 0, 0, 0.2); }
 +
 +colorswatch#add-color-button { border-radius: 5px 0 0 5px; }
 +
 +colorswatch#add-color-button:only-child { border-radius: 5px; }
 +
 +colorswatch#add-color-button > overlay { color: #2e3436; outline-color: rgba(53, 132, 228, 0.5); border-color: #cdc7c2; background-image: linear-gradient(to top, #f6f5f4 2px, #fbfafa); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +colorswatch#add-color-button.activatable:hover > overlay { color: #2e3436; border-color: #cdc7c2; background-image: linear-gradient(to top, #d6d1cd, #e8e6e3 1px); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); }
 +
 +colorswatch:disabled { opacity: 0.5; }
 +
 +colorswatch:disabled > overlay { border-color: rgba(0, 0, 0, 0.6); box-shadow: none; }
 +
 +row:selected colorswatch { box-shadow: 0 0 0 2px #ffffff; }
 +
 +colorswatch#editor-color-sample { border-radius: 4px; }
 +
 +colorswatch#editor-color-sample > overlay { border-radius: 4.5px; }
 +
 +plane { transition: outline-width 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94), outline-offset 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); transition-property: outline, outline-width, outline-offset, outline-color; transition-duration: 300ms; animation-timing-function: ease-in-out; }
 +
 +plane { outline: 0 solid transparent; outline-offset: 6px; }
 +
 +plane:focus:focus-visible { outline-color: rgba(53, 132, 228, 0.5); outline-width: 2px; outline-offset: 2px; }
 +
 +colorchooser .popover.osd { border-radius: 5px; }
 +
 +/******** Misc * */
 +.content-view { background-color: #e6e3e0; }
 +
 +.content-view:hover { -gtk-icon-filter: brightness(1.2); }
 +
 +.content-view .tile { margin: 2px; background-color: transparent; border-radius: 0; padding: 0; }
 +
 +.content-view .tile:active, .content-view .tile:selected { background-color: transparent; }
 +
 +.content-view .tile:disabled { background-color: transparent; }
 +
 +.osd .scale-popup button.flat { border-style: none; border-radius: 5px; }
 +
 +.scale-popup button:hover { background-color: rgba(46, 52, 54, 0.1); border-radius: 5px; }
 +
 +/********************** Window Decorations * */
 +window { border-width: 0px; }
 +
 +window.csd { box-shadow: 0 3px 9px 1px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(0, 0, 0, 0.23); margin: 0px; border-radius: 8px 8px 0 0; }
 +
 +window.csd:backdrop { box-shadow: 0 3px 9px 1px transparent, 0 2px 6px 2px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.18); transition: 200ms ease-out; }
 +
 +window.csd.popup { border-radius: 5px; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.13); }
 +
 +window.csd.dialog.message { border-radius: 8px; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(0, 0, 0, 0.13); }
 +
 +window.solid-csd { margin: 0; padding: 4px; border: solid 1px #cdc7c2; border-radius: 0; box-shadow: inset 0 0 0 4px #cdc7c2, inset 0 0 0 3px white, inset 0 1px rgba(255, 255, 255, 0.8); }
 +
 +window.solid-csd:backdrop { box-shadow: inset 0 0 0 4px #cdc7c2, inset 0 0 0 3px #f6f5f4, inset 0 1px rgba(255, 255, 255, 0.8); }
 +
 +window.maximized, window.fullscreen { border-radius: 0; box-shadow: none; }
 +
 +window.tiled, window.tiled-top, window.tiled-left, window.tiled-right, window.tiled-bottom { border-radius: 0; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.18), 0 0 0 20px transparent; }
 +
 +window:backdrop { box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.18), 0 0 0 20px transparent; }
 +
 +window.popup { box-shadow: none; }
 +
 +window.ssd { box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.23); }
 +
 +tooltip.csd { border-radius: 5px; box-shadow: none; }
 +
 +.view:selected:focus, .view:selected, textview > text:selected:focus, textview > text:selected, textview > text > selection:focus, textview > text > selection, iconview:selected:focus, iconview:selected, flowbox > flowboxchild:selected, gridview > child:selected, entry > text > selection, modelbutton.flat:selected, spinbutton:not(.vertical) > text > selection, spinbutton.vertical > text > text > selection, spinbutton.vertical > text > selection, columnview.view:selected:focus, columnview.view:selected, treeview.view:selected:focus, treeview.view:selected, row:selected, calendar > grid > label.day-number:selected { background-color: #3584e4; }
 +
 +label:selected, .view:selected:focus, .view:selected, textview > text:selected:focus, textview > text:selected, textview > text > selection:focus, textview > text > selection, iconview:selected:focus, iconview:selected, flowbox > flowboxchild:selected, gridview > child:selected, entry > text > selection, modelbutton.flat:selected, spinbutton:not(.vertical) > text > selection, spinbutton.vertical > text > text > selection, spinbutton.vertical > text > selection, columnview.view:selected:focus, columnview.view:selected, treeview.view:selected:focus, treeview.view:selected, row:selected, calendar > grid > label.day-number:selected { color: #ffffff; }
 +
 +label:disabled > selection, label:disabled:selected, .view:disabled:selected, textview > text:disabled:selected:focus, textview > text:disabled:selected, textview > text > selection:disabled, iconview:disabled:selected:focus, iconview:disabled:selected, flowbox > flowboxchild:disabled:selected, gridview > child:disabled:selected, entry > text > selection:disabled, modelbutton.flat:disabled:selected, spinbutton:not(.vertical) > text > selection:disabled, spinbutton.vertical > text > text > selection:disabled, spinbutton.vertical > text > selection:disabled, columnview.view:disabled:selected, treeview.view:disabled:selected, row:disabled:selected, calendar > grid > label.day-number:disabled:selected { color: #9ac2f2; }
 +
 +.monospace { font-family: monospace; }
 +
 +/********************** Touch Copy & Paste * */
 +cursor-handle { background-color: transparent; background-image: none; box-shadow: none; border-style: none; min-width: 20px; min-height: 24px; padding-left: 20px; padding-right: 20px; padding-top: 24px; padding-bottom: 24px; }
 +
 +cursor-handle.top:dir(ltr), cursor-handle.bottom:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets/text-select-start.png"), url("assets/text-select-start@2.png")); }
 +
 +cursor-handle.bottom:dir(ltr), cursor-handle.top:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets/text-select-end.png"), url("assets/text-select-end@2.png")); }
 +
 +cursor-handle.insertion-cursor:dir(ltr), cursor-handle.insertion-cursor:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets/slider-horz-scale-has-marks-above.png"), url("assets/slider-horz-scale-has-marks-above@2.png")); }
 +
 +cursor-handle.top:hover:dir(ltr), cursor-handle.bottom:hover:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets/text-select-start-hover.png"), url("assets/text-select-start-hover@2.png")); }
 +
 +cursor-handle.bottom:hover:dir(ltr), cursor-handle.top:hover:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets/text-select-end-hover.png"), url("assets/text-select-end-hover@2.png")); }
 +
 +cursor-handle.insertion-cursor:hover:dir(ltr), cursor-handle.insertion-cursor:hover:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets/slider-horz-scale-has-marks-above-hover.png"), url("assets/slider-horz-scale-has-marks-above-hover@2.png")); }
 +
 +cursor-handle.top:active:dir(ltr), cursor-handle.bottom:active:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets/text-select-start-active.png"), url("assets/text-select-start-active@2.png")); }
 +
 +cursor-handle.bottom:active:dir(ltr), cursor-handle.top:active:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets/text-select-end-active.png"), url("assets/text-select-end-active@2.png")); }
 +
 +cursor-handle.insertion-cursor:active:dir(ltr), cursor-handle.insertion-cursor:active:dir(rtl) { -gtk-icon-source: -gtk-scaled(url("assets/slider-horz-scale-has-marks-above-active.png"), url("assets/slider-horz-scale-has-marks-above-active@2.png")); }
 +
 +shortcuts-section { margin: 20px; }
 +
 +.shortcuts-search-results { margin: 20px; border-spacing: 24px; }
 +
 +shortcut { border-spacing: 6px; }
 +
 +shortcut > .keycap { min-width: 20px; min-height: 25px; margin-top: 2px; padding-bottom: 3px; padding-left: 6px; padding-right: 6px; color: #2e3436; background-color: #ffffff; border: 1px solid; border-color: #e1dedb; border-radius: 5px; box-shadow: inset 0 -3px #f8f7f6; font-size: smaller; }
 +
 +:not(decoration):not(window):drop(active):focus, :not(decoration):not(window):drop(active) { border-color: #2ec27e; box-shadow: inset 0 0 0 1px #2ec27e; caret-color: #2ec27e; }
 +
 +stackswitcher > button.text-button { min-width: 100px; }
 +
 +stackswitcher.circular { border-spacing: 12px; }
 +
 +stackswitcher.circular > button.circular, stackswitcher.circular > button.text-button.circular { min-width: 32px; min-height: 32px; padding: 0; }
 +
 +/************* App Icons * */
 +/* Outline for low res icons */
 +.lowres-icon { -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.05), 1px 0 rgba(0, 0, 0, 0.1), 0 1px rgba(0, 0, 0, 0.3), -1px 0 rgba(0, 0, 0, 0.1); }
 +
 +/* Drapshadow for large icons */
 +.icon-dropshadow { -gtk-icon-shadow: 0 1px 12px rgba(0, 0, 0, 0.05), 0 -1px rgba(0, 0, 0, 0.05), 1px 0 rgba(0, 0, 0, 0.1), 0 1px rgba(0, 0, 0, 0.3), -1px 0 rgba(0, 0, 0, 0.1); }
 +
 +/********* Emoji * */
 +popover.emoji-picker > contents { padding: 0; }
 +
 +.emoji-searchbar { padding: 6px; border-spacing: 6px; border-bottom: 1px solid #cdc7c2; }
 +
 +.emoji-toolbar { padding: 6px; border-spacing: 6px; border-top: 1px solid #cdc7c2; }
 +
 +button.emoji-section { border-color: transparent; border-width: 3px; border-style: none none solid; border-radius: 0; padding: 3px 0 0; min-width: 32px; min-height: 28px; /* reset props inherited from the button style */ background: none; box-shadow: none; text-shadow: none; }
 +
 +button.emoji-section:hover { border-color: #cdc7c2; }
 +
 +button.emoji-section:checked { border-color: #3584e4; }
 +
 +popover.emoji-picker emoji { font-size: x-large; padding: 6px; border-radius: 6px; }
 +
 +popover.emoji-picker emoji:focus, popover.emoji-picker emoji:hover { background: #3584e4; }
 +
 +emoji-completion-row > box { border-spacing: 10px; padding: 2px 10px; }
 +
 +emoji-completion-row:focus, emoji-completion-row:hover { background-color: #3584e4; color: #ffffff; }
 +
 +emoji-completion-row emoji:focus, emoji-completion-row emoji:hover { background-color: #e8e6e3; }
 +
 +popover.entry-completion > contents { padding: 0; }
 +
 +statusbar { padding: 6px 10px 6px 10px; }
 +
 +menubutton > button > box { border-spacing: 6px; }
 +
 +menubutton arrow { min-height: 16px; min-width: 16px; }
 +
 +menubutton arrow.none { -gtk-icon-source: -gtk-icontheme("open-menu-symbolic"); }
 +
 +menubutton arrow.down { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
 +
 +menubutton arrow.up { -gtk-icon-source: -gtk-icontheme("pan-up-symbolic"); }
 +
 +menubutton arrow.left { -gtk-icon-source: -gtk-icontheme("pan-start-symbolic"); }
 +
 +menubutton arrow.right { -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); }
 +
 +/* GTK NAMED COLORS ---------------- use responsibly! */
 +/*
 +widget text/foreground color */
 +@define-color theme_fg_color #2e3436;
 +/*
 +text color for entries, views and content in general */
 +@define-color theme_text_color black;
 +/*
 +widget base background color */
 +@define-color theme_bg_color #f6f5f4;
 +/*
 +text widgets and the like base background color */
 +@define-color theme_base_color #ffffff;
 +/*
 +base background color of selections */
 +@define-color theme_selected_bg_color #3584e4;
 +/*
 +text/foreground color of selections */
 +@define-color theme_selected_fg_color #ffffff;
 +/*
 +base background color of insensitive widgets */
 +@define-color insensitive_bg_color #faf9f8;
 +/*
 +text foreground color of insensitive widgets */
 +@define-color insensitive_fg_color #929595;
 +/*
 +insensitive text widgets and the like base background color */
 +@define-color insensitive_base_color #ffffff;
 +/*
 +widget text/foreground color on backdrop windows */
 +@define-color theme_unfocused_fg_color #929595;
 +/*
 +text color for entries, views and content in general on backdrop windows */
 +@define-color theme_unfocused_text_color black;
 +/*
 +widget base background color on backdrop windows */
 +@define-color theme_unfocused_bg_color #f6f5f4;
 +/*
 +text widgets and the like base background color on backdrop windows */
 +@define-color theme_unfocused_base_color #fcfcfc;
 +/*
 +base background color of selections on backdrop windows */
 +@define-color theme_unfocused_selected_bg_color #3584e4;
 +/*
 +text/foreground color of selections on backdrop windows */
 +@define-color theme_unfocused_selected_fg_color #ffffff;
 +/*
 +insensitive color on backdrop windows*/
 +@define-color unfocused_insensitive_color #d4cfca;
 +/*
 +widgets main borders color */
 +@define-color borders #cdc7c2;
 +/*
 +widgets main borders color on backdrop windows */
 +@define-color unfocused_borders #d5d0cc;
 +/*
 +these are pretty self explicative */
 +@define-color warning_color #f57900;
 +@define-color error_color #cc0000;
 +@define-color success_color #33d17a;
 +/*
 +these colors are exported for the window manager and shouldn't be used in applications,
 +read if you used those and something break with a version upgrade you're on your own... */
 +@define-color wm_title shade(#2e3436, 1.8);
 +@define-color wm_unfocused_title #929595;
 +@define-color wm_highlight rgba(255, 255, 255, 0.8);
 +@define-color wm_borders_edge rgba(255, 255, 255, 0.8);
 +@define-color wm_bg_a shade(#f6f5f4, 1.2);
 +@define-color wm_bg_b #f6f5f4;
 +@define-color wm_shadow alpha(black, 0.35);
 +@define-color wm_border alpha(black, 0.18);
 +@define-color wm_button_hover_color_a shade(#f6f5f4, 1.3);
 +@define-color wm_button_hover_color_b #f6f5f4;
 +@define-color wm_button_active_color_a shade(#f6f5f4, 0.85);
 +@define-color wm_button_active_color_b shade(#f6f5f4, 0.89);
 +@define-color wm_button_active_color_c shade(#f6f5f4, 0.9);
 +/* content view background such as thumbnails view in Photos or Boxes */
 +@define-color content_view_bg #ffffff;
 +/* Very contrasty background for text views (@theme_text_color foreground) */
 +@define-color text_view_bg #ffffff;
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ee3c6355fae5e0ccd3309545c6d8c3e464378843
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,66 @@@
++# SPDX-FileCopyrightText: 2021 GNOME Foundation
++#
++# SPDX-License-Identifier: CC0-1.0
++
++stages:
++  - build
++  - check
++  - deploy
++
++#meson-build:
++#  stage: build
++#  needs: []
++#  script:
++#    - dnf install -y meson ninja-build python3-flake8 python3-mypy python3-markdown python3-jinja2 python3-toml python3-typogrify
++#    - meson _build .
++#    - meson test -C _build
++#
++#pip-build:
++#  stage: build
++#  needs: []
++#  script:
++#    - dnf install -y python3-pip
++#    - python3 -m pip install --user -e .
++
++.pip:
++  before_script:
++    - export PATH="$HOME/.local/bin:$PATH"
++    - dnf install -y python3-pip
++
++flake8:
++  stage: check
++  needs: []
++  script:
++    - dnf install -y python3-flake8
++    - flake8 --ignore E501,E402,F405,W503 --show-source gidocgen
++
++mypy:
++  stage: check
++  needs: []
++  script:
++    - dnf install -y python3-mypy
++    - mypy --ignore-missing-imports --disallow-incomplete-defs gidocgen
++  allow_failure: true
++
++reuse:
++  extends: .pip
++  stage: check
++  needs: []
++  script:
++    - pip install --user reuse
++    - reuse lint
++
++pages:
++  extends: .pip
++  stage: deploy
++  needs: []
++  script:
++    - pip install --user sphinx sphinx_rtd_theme
++    - cd docs
++    - python3 -m sphinx  -b html . _build
++    - mv _build ../public
++  artifacts:
++    paths:
++      - public
++  only:
++    - main
index 6d77374d336a5c38395df696a32db0bc4047fb39,0000000000000000000000000000000000000000..c07e06aea6deec866455851b5094e0686d593e68
mode 100644,000000..100644
--- /dev/null
@@@ -1,88 -1,0 +1,88 @@@
- under the terms of the GNU General Publice License, either version 3.0 or,
 +<!--
 +SPDX-FileCopyrightText: 2021 GNOME Foundation
 +
 +SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +-->
 +
 +GI-DocGen: Documentation tool for GObject-based libraries
 +-------------------------------------------------------------------------------
 +
 +GI-DocGen is a document generator for GObject-based libraries. GObject is
 +the base type system of the GNOME project. GI-Docgen reuses the
 +introspection data generated by GObject-based libraries to generate the API
 +reference of these libraries, as well as other ancillary documentation.
 +
 +## Installation
 +
 +### Running GI-DocGen uninstalled
 +
 +You can run GI-DocGen from its repository, by calling:
 +
 +```
 +./gi-docgen.py
 +```
 +
 +GI-DocGen will automatically detect this case.
 +
 +### Installing GI-DocGen via pip
 +
 +To install GI-DocGen, you will need to have the following pieces of software
 +available on your computer:
 +
 + - Python 3.6, or later
 + - pip
 +
 +Run the following command:
 +
 +```
 +pip3 install --user gi-docgen
 +```
 +
 +After running the command above, make sure to have the `~/.local/bin`
 +directory listed in your `$PATH` environment variable.
 +
 +To update GI-DocGen, run the following command:
 +
 +```
 +pip3 install --user --upgrade gi-docgen
 +```
 +
 +## Usage
 +
 +First, read [the GI-DocGen tutorial](https://gnome.pages.gitlab.gnome.org/gi-docgen/tutorial.html).
 +
 +The documentation for GI-DocGen is [available online](https://gnome.pages.gitlab.gnome.org/gi-docgen/).
 +
 +The `examples` directory in the repository contains simple project files for
 +various GNOME libraries.
 +
 +## Disclaimer
 +
 +GI-DocGen is **not** a general purpose documentation tool for C libraries.
 +
 +While GI-DocGen can be used to generate API references for most GObject/C
 +libraries that expose introspection data, its main goal is to generate the
 +reference for GTK and its immediate dependencies. Any and all attempts at
 +making this tool more generic, or to cover more use cases, will be weighted
 +heavily against its primary goal.
 +
 +GI-DocGen is still in development. The recommended use of GI-DocGen is to
 +add it as a sub-project to your [Meson build system](https://mesonbuild.com),
 +and vendor it when releasing dist archives.
 +
 +You should **not** depend on a system-wide installation until GI-DocGen is
 +declared stable.
 +
 +If you need a general purpose documentation tool, I strongly recommend:
 +
 + - [HotDoc](https://hotdoc.github.io/)
 + - [Doxygen](https://www.doxygen.nl/index.html)
 + - [GTK-Doc](https://gitlab.gnome.org/GNOME/gtk-doc/)
 +
 +## Copyright and Licensing terms
 +
 +Copyright 2021  GNOME Foundation
 +
 +GI-DocGen is released under the terms of the Apache License, version 2.0, or
++under the terms of the GNU General Public License, either version 3.0 or,
 +at your option, any later version.
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..7985ea69358b858f957c283259af2c4ee76ef7fc
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,21 @@@
++<!--
++SPDX-FileCopyrightText: 2021 GNOME Foundation
++
++SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
++-->
++
++Release check list
++==================
++
++- [ ] Collect all changes since the previous tag
++- [ ] Tag the release, using `git tag -s YYYY.N`
++- [ ] Write down all the noteworthy changes in the tag message
++- [ ] Update `twine`: `pip install --upgrade --user twine`
++- [ ] Build a Python dist: `python -m build`
++- [ ] Upload the dist to PyPI: `python -m twine upload dist/*`
++- [ ] Build a Meson dist: `meson setup _build . && meson dist -C _build`
++- [ ] Upload the Meson dist to gnome.org
++- [ ] Clean up the repository: `git clean -xdf`
++- [ ] Bump the version in `meson.build` and `gidocgen/core.py` to `YYYY.N+1`
++- [ ] Push the changes to the repository: `git push origin HEAD`
++- [ ] Push the release tag to the repository: `git push origin YYYY.N`
index c467b347caaab85013c46077bf7f31156bdea592,0000000000000000000000000000000000000000..b67625a205625b6901cc8141a21e0d5ed84ee635
mode 100644,000000..100644
--- /dev/null
@@@ -1,39 -1,0 +1,42 @@@
 +.. SPDX-FileCopyrightText: 2021 GNOME Foundation
 +..
 +.. SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +
 +Introspection attributes
 +========================
 +
 +GI-DocGen consumes the following attributes found in the introspection data when
 +generating the API reference for that data.
 +
 +Properties
 +----------
 +
 +The following attributes apply to properties.
 +
 +``org.gtk.Property.get`` = ``s``
 +  Defines the getter method for a given property. The value of the attribute is
 +  the C symbol of the function.
 +
 +``org.gtk.Property.set`` = ``s``
 +  Defines the setter method for a given property. The value of the attribute is
 +  the C symbol of the function.
 +
++``org.gtk.Property.default`` = ``s``
++  Defines the default value for a given property.
++
 +Methods
 +-------
 +
 +The following attributes apply to methods of a classed type or interface.
 +
 +``org.gtk.Method.set_property`` = ``s``
 +  Defines the property set by the function. The property name must be in
 +  the same type as the method
 +
 +``org.gtk.Method.get_property`` = ``s``
 +  Defines the property retrieved by the function. The property name must
 +  be in the same type as the method
 +
 +``org.gtk.Method.signal`` = ``s``
 +  Defines the signal emitted by the function. The signal name must be
 +  in the same type as the method
index 36fc14ed74ee5f7583fbbef8783ba5cf572cc35f,0000000000000000000000000000000000000000..2947c93aa1809e333e2e65cdc1ff72cf343160aa
mode 100644,000000..100644
--- /dev/null
@@@ -1,170 -1,0 +1,191 @@@
 +\" SPDX-FileCopyrightText: 2021 GNOME Foundation
 +\" SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +.TH GI\-DOCGEN "1" "" "gi-docgen 2021.3" "User Commands"
 +.SH NAME
 +gi-docgen - a documentation generator using gobject\-introspection
 +.SH SYNOPSIS
 +.sp
 +\fBgi\-docgen\fP COMMAND [OPTION...] GIR_FILE
 +.SH DESCRIPTION
 +.sp
 +GI\-DocGen is a document generator for GObject\-based libraries. GObject
 +is the base type system of the GNOME project. GI\-DocGen uses the machine
 +readable introspection data provided by GObject\-based libraries in order
 +to generate the API reference of these libraries, as well as other
 +ancillary documentation.
 +.sp
 +The main gi\-docgen executable provides various subcommands to access all
 +its functionality.
 +
 +.SH Common options
 +.sp
 +All commands have the following options:
 +
 +.TP
 +.B \-\-quiet
 +do not print details of the current operation
 +.TP
 +.B \-\-fatal\-warnings
 +make warnings fatal errors
 +.TP
 +.B \-\-help
 +print command line help
 +
 +.SH The generate command
 +.sp
 +The \fBgenerate\fR command provides the main functionality of gi\-docgen.
 +
 +.B gi-docgen generate [
 +.I OPTIONS
 +.B ] [
 +.I GIR_FILE
 +.B ]
 +
 +.sp
 +The generate command will parse the given GIR file, as well as its
 +dependencies, and build an API reference for the namespace it finds
 +in the introspection data. Projects can use a configuration file to
 +control aspects of the output, as well as provide additional content
 +that should be included in the documentation.
 +
 +.SS "options:"
 +.TP
 +.BI \-\-config\fB= FILE
 +use the given project configuration file
 +.TP
 +.BI \-\-content\-dir\fB= PATH
 +specify the directory where the content files listed in the project
 +configuration file can be found
 +.TP
 +.BI \-\-templates\-dir\fB= PATH
 +specify the directory where the templates used to generate the
 +documentation can be found
 +.TP
 +.BI \-\-theme\-name\fB= NAME
 +specify the template name to be used when generating the documentation,
 +overriding the project's configuration
 +.TP
 +.BI \-\-output\-dir\fB= PATH
 +create the documentation under the given directory
 +.TP
 +.B \-\-no\-namespace\-dir
 +generate all documentation files directly under the output directory,
 +instead of creating a directory using the namespace name and version
 +.TP
 +.BI \-\-add\-include\-path\fB= PATH
 +add a directory to the path which the scanner uses to find GIR files. Can
 +be used multiple times to specify multiple directories
 +.TP
 +.BI \-\-section\fB= NAME
 +generate the documentation only for the given section. Can be used
 +multiple times to specify multiple sections. The supported sections are
 +\fIaliases\fR, \fIbitfields\fR, \fIclasses\fR, \fIdomains\fR, \fIenums\fR,
 +\fIinterfaces\fR, \fIstructs\fR and \fIunions\fR. Special values are \fIall\fR,
 +meaning all sections (the default); and \fInone\fR, meaning no section
 +.TP
 +.B \-\-dry\-run
 +parse the \fIGIR_FILE\fR without generating the documentation
 +
 +.SH The gen-index command
 +.sp
 +The \fBgen-index\fR command generates an index of symbols and terms
 +that can be used to search inside the documentation generated by
 +gi\-docgen.
 +
 +.B gi-docgen gen-index [
 +.I OPTIONS
 +.B ] [
 +.I GIR_FILE
 +.B ]
 +
 +.sp
 +The generated index is a JSON formatted file is called \fIindex.json\fR.
 +
 +.SS "options:"
 +.TP
 +.BI \-\-config\fB= FILE
 +use the given project configuration file
 +.TP
 +.BI \-\-content\-dir\fB= PATH
 +specify the directory where the content files listed in the project
 +configuration file can be found
 +.TP
 +.BI \-\-output\-dir\fB= PATH
 +create the index under the given directory
 +.TP
 +.BI \-\-add\-include\-path\fB= PATH
 +add a directory to the path which the scanner uses to find GIR files. Can
 +be used multiple times to specify multiple directories
 +.TP
 +.B \-\-dry\-run
 +parse the \fIGIR_FILE\fR without generating the documentation
 +
++.SH The check command
++.sp
++The \fBcheck\fR command runs a series of checks on the introspection
++file, to verify that public API is properly documented. It can be used
++as part of a test suite.
++
++.B gi-docgen check [
++.I OPTIONS
++.B ] [
++.I GIR_FILE
++.B ]
++
++.SS "options:"
++.TP
++.BI \-\-config\fB= FILE
++use the given project configuration file
++.TP
++.BI \-\-add\-include\-path\fB= PATH
++add a directory to the path which the scanner uses to find GIR files. Can
++be used multiple times to specify multiple directories
++
 +.SH The help command
 +.sp
 +The \fBhelp\fR command prints out the command line help. If you don't
 +specify any command or option when invoking gi\-docgen, the help command
 +will be implied.
 +
 +.B gi-docgen help [
 +.I OPTIONS
 +.B ] [
 +.I COMMAND
 +.B ]
 +
 +.sp
 +If no command is specified, help will print out the list of commands.
 +.sp
 +If a command is specified, help will print out the command line help for
 +that program.
 +
 +.SS "options:"
 +.TP
 +.B \-\-version
 +print out the version of gi\-docgen
 +
 +.SH EXIT STATUS
 +
 +.TP
 +.B 0
 +The command was successful.
 +.TP
 +.B 1
 +Error, or warning, was generated.
 +
 +.SH ENVIRONMENT VARIABLES
 +.sp
 +The gi\-docgen executable uses the \fBXDG_DATA_DIRS\fP and \fBXDG_DATA_HOME\fP
 +environment variables to search for introspection data included in the GIR
 +file.
 +.sp
 +If the \fBGIDOCGEN_DEBUG\fP environment variable is set, gi\-docgen will print
 +out additional messages, which can be helpful when debugging issues.
 +
 +.SH SEE ALSO
 +.sp
 +GI\-DocGen: http://gnome.pages.gitlab.gnome.org/gi-docgen/
 +.sp
 +GObject\-Introspection: https://gi.readthedocs.org/
 +.sp
 +GObject: https://developer.gnome.org/gobject/
index fc2858d2e856012c3ddbd531d2c2712879205507,0000000000000000000000000000000000000000..1dd596194b6f6080f6e3cd384c86b93fa17d0e8b
mode 100644,000000..100644
--- /dev/null
@@@ -1,184 -1,0 +1,209 @@@
-    :widths: 15 35 50
 +.. SPDX-FileCopyrightText: 2021 GNOME Foundation
 +..
 +.. SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +
 +=====================
 +Linking items by name
 +=====================
 +
 +Gi-docgen is capable of linking symbols across the same introspected namespace,
 +by using a qualifier fragment and the symbol name.
 +
 +For instance:
 +
 +.. code-block:: c
 +
 +   /**
 +    * ExampleFoo:
 +    *
 +    * This structure is related to [struct@Bar].
 +    */
 +
 +    /**
 +     * example_foo_set_bar:
 +     *
 +     * Sets [struct@Example.Bar] on an instance of `Foo`.
 +     */
 +
 +    /**
 +     * ExampleFoo:bar:
 +     *
 +     * Sets an instance of [`Bar`](struct.Bar.html) on `Foo`.
 +     */
 +
 +
 +will all link to ``Bar``.
 +
 +Backticks will be stripped, so ``[`class@Foo`]`` will correctly link to ``Foo``.
 +
 +The link can either be a fully qualified name, which includes the namespace; or
 +a name relative to the current namespace; for instance, both of the following links
 +will point to ``ExampleFoo`` when generating the documentation for the "Example"
 +namespace:
 +
 +- ``[class@Foo]``
 +- ``[class@Example.Foo]``
 +
 +The available qualifier fragments are:
 +
 +.. list-table::
- The ``id`` fragment can only be used for symbols within the current namespace.
++   :widths: 10 15 25 50
 +   :header-rows: 1
 +
 +   * - Fragment
++     - Argument
 +     - Description
 +     - Example
 +   * - ``alias``
++     - ``TypeName``
 +     - An alias to another type
 +     - ``[alias@Allocation]``
 +   * - ``callback``
++     - ``TypeName``
 +     - A callback type
 +     - ``[callback@Gtk.ListBoxForeachFunc]``
 +   * - ``class``
++     - ``TypeName``
 +     - An object class
 +     - ``[class@Widget]``, ``[class@Gdk.Surface]``, ``[class@Gsk.RenderNode]``
 +   * - ``const``
++     - ``CONSTANT``
 +     - A constant or pre-processor symbol
 +     - ``[const@Gdk.KEY_q]``
 +   * - ``ctor``
++     - ``TypeName.constructor``
 +     - A constructor function
 +     - ``[ctor@Gtk.Box.new]``, ``[ctor@Button.new_with_label]``
 +   * - ``enum``
++     - ``TypeName``
 +     - A plain enumeration
 +     - ``[enum@Orientation]``
 +   * - ``error``
++     - ``TypeName``
 +     - A ``GError`` domain enumeration
 +     - ``[error@Gtk.BuilderParseError]``
 +   * - ``flags``
++     - ``TypeName``
 +     - A bitfield
 +     - ``[flags@Gdk.ModifierType]``
 +   * - ``func``
++     - ``function``, ``TypeName.function``
 +     - A global or a type function
 +     - ``[func@Gtk.init]``, ``[func@show_uri]``, ``[func@Gtk.Window.list_toplevels]``
 +   * - ``iface``
++     - ``TypeName``
 +     - A ``GTypeInterface``
 +     - ``[iface@Gtk.Buildable]``
 +   * - ``method``
++     - ``TypeName.method``, ``TypeNameClass.method``
 +     - An instance or class method
 +     - ``[method@Gtk.Widget.show]``, ``[method@WidgetClass.add_binding]``
 +   * - ``property``
++     - ``TypeName:property``
 +     - A ``GObject`` property
 +     - ``[property@Gtk.Orientable:orientation]``
 +   * - ``signal``
++     - ``TypeName::signal``
 +     - A ``GObject`` signal
 +     - ``[signal@Gtk.RecentManager::changed]``
 +   * - ``struct``
++     - ``TypeName``
 +     - A plain C structure or union
 +     - ``[struct@Gtk.TextIter]``
 +   * - ``vfunc``
++     - ``TypeName.virtual``
 +     - A virtual function in a class or interface
 +     - ``[vfunc@Gtk.Widget.measure]``
++   * - ``type``
++     - ``TypeName``
++     - A registered type
++     - ``[type@Widget]``, ``[type@Gdk.ModifierType]``, ``[type@Gtk.TextIter]``
++   * - ``id``
++     - ``function``
++     - A C symbol
++     - ``[id@gtk_window_new]``, ``[id@g_signal_connect]``
 +
 +The generic ``type`` fragment, followed by a type, will look up the given type
 +and generate the appropriate link for it. The type can be fully qualified or
 +relative to the current namespace:
 +
 +::
 +
 +    // Equivalent to [class@Gtk.Window]
 +    [type@Gtk.Window]
 +
 +    // Equivalent to [enum@Gtk.Orientation]
 +    [type@Gtk.Orientation]
 +
 +Anything that is a known type—aliases, callbacks, classes, constants,
 +enumerations, interfaces, structures—can be linked using the ``type`` fragment.
 +
 +Additionally, the ``id`` fragment, followed by a C symbol identifier, will try
 +to link to the function; for instance:
 +
 +::
 +
 +    // Equivalent to [func@Gtk.show_uri], will link to gtk_show_uri()
 +    [id@gtk_show_uri]
 +
 +    // Equivalent to [method@Gtk.Widget.show], will link to gtk_widget_show()
 +    [id@gtk_widget_show]
 +
++    // Equivalent to [func@GObject.signal_emit], will link to g_signal_emit()
++    [id@g_signal_emit]
 +
 +It's important to note that the ``method`` and ``func`` fragments can have
 +multiple meanings:
 +
 +- the ``method`` fragment will match both instance and class methods, depending
 +  on the type used; for instance, to match an instance method you should use the
 +  type name, and to match a class method you should use the class name. The class
 +  method should not be confused with the ``vfunc`` fragment, which uses the type
 +  name and links to virtual methods defined in the class or interface structure.
 +  Class methods take the class pointer as their first argument, whereas virtual
 +  methods take the instance pointer as their first argument.
 +
 +::
 +
 +    // will link to gtk_widget_show()
 +    [method@Gtk.Widget.show]
 +
 +    // will link to gtk_widget_class_add_binding()
 +    [method@Gtk.WidgetClass.add_binding]
 +
 +    // will link to GtkWidgetClass.show
 +    [vfunc@Gtk.Widget.show]
 +
 +
 +- similarly, the ``func`` fragment will match global functions and type
 +  functions, depending on whether the link contains a type or not. Additionally,
 +  ``func`` will match function macros, which are part of the global namespace.
 +
 +::
 +
 +    // will link to gtk_show_uri()
 +    [func@Gtk.show_uri]
 +
 +    // will link to gtk_window_list_toplevels()
 +    [func@Gtk.Window.list_toplevels]
 +
 +    // will link to gtk_widget_class_bind_template_child()
 +    [func@Gtk.widget_class_bind_template_child]
 +
 +External Links
 +--------------
 +
 +Gi-docgen can use the same syntax to point to symbols in other namespaces
 +with gi-docgen-generated documentation, as long as you provide it with
 +a mapping from the namespace names to a base url for the docs. This is
 +done by defining a JavaScript map called ``baseURLs`` like this:
 +
 +.. code-block:: js
 +
 +    baseURLs = [
 +      [ 'Pango', 'https://gnome.pages.gitlab.gnome.org/pango/Pango/' ],
 +      [ 'PangoCairo', 'https://gnome.pages.gitlab.gnome.org/pango/PangoCairo/' ],
 +    ]
 +
 +And specifying the path of the JavaScript file into the ``extras`` section
 +of the project configuration, in the ``urlmap_file`` key.
index 979ac05def53b77aeb4d95e52f5c922fb2ded1e0,0000000000000000000000000000000000000000..9da5c84b9c666f87b05b3c42832de085cd69c4f7
mode 100644,000000..100644
--- /dev/null
@@@ -1,212 -1,0 +1,239 @@@
-   file name, relative to the directory specified by the ``--content-dir``
-   command line argument; the second element of the tuple is the
 +.. SPDX-FileCopyrightText: 2021 GNOME Foundation
 +..
 +.. SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +
 +=====================
 +Project configuration
 +=====================
 +
 +Projects using gi-docgen should provide their own configuration file to describe
 +how to generate their API reference.
 +
 +The configuration file format uses `ToML <https://toml.io/en/>`__ to provide key
 +and value pairs that will be used by gi-docgen and, optionally, by the templates
 +themselves.
 +
 +Project configuration takes precendence over gi-docgen's defaults, but can be
 +overridden by command line options, where applicable.
 +
 +Standard sections and keys
 +--------------------------
 +
 +The ``library`` section
 +~~~~~~~~~~~~~~~~~~~~~~~
 +
 +The ``library`` section is used to define the library configuration values
 +that gi-docgen will pass to the templates, as well as configuration switches
 +that control the files generated by gi-docgen.
 +
 +The following keys are used, if found:
 +
 +``version`` = ``s``
 +  The version of the library. This is the actual version of the shared
 +  library, as opposed to the version of the API as represented by the
 +  namespace.
 +
 +``authors`` = ``s``
 +  The name of the authors of the library, as a string.
 +
 +``license`` = ``s``
 +  The license of the documentation, as an `SPDX identifier <https://spdx.org/licenses/>`__.
 +
 +``website_url`` = ``s``
 +  The website for the library.
 +
 +``browse_url`` = ``s``
 +  The website that can be used to browse the source code of the library.
 +
 +``logo_url`` = ``s``
 +  The location of a logo image. This can be a local file, or a URL.
 +
 +``description`` = ``s``
 +  A short description of the library.
 +
 +``dependencies`` = ``dict(s, dict(s, s)``
 +  A dictionary of dependencies; each entry in the dictionary has a key in the
 +  form of ``{namespace}-{version}``, and values in the form of a dictionary
 +  with the following keys: ``name``, ``description``, and ``docs_url``.
 +
 +``devhelp`` = ``b``
 +  Whether gi-docgen should generate a DevHelp file for the namespace.
 +
 +``search_index`` = ``b``
 +  Whether gi-docgen should generate a search index file for the namespace.
 +
 +
 +The ``theme`` section
 +~~~~~~~~~~~~~~~~~~~~~
 +
 +The ``theme`` section is used to define the theme being used by gi-docgen when
 +generating the API reference of a project.
 +
 +The following keys are used, if found:
 +
 +``templates_dir`` = ``s``
 +  The directory that contains the templates to be used by gi-docgen. The
 +  default directory is inside the gi-docgen module directory. This key
 +  can be overridden by the ``--templates-dir`` command line argument.
 +
 +``name`` = ``s``
 +  The name of the template to use. The name is a sub-directory of the
 +  ``template_dir`` directory, and will be used to load the template's
 +  configuration file. This key can be overridden by the ``--theme-name``
 +  command line argument.
 +
 +``show_index_summary`` = ``b``
 +  A boolean value that controls whether to show the summary of each
 +  symbol in the namespace index.
 +
 +``show_class_hierarchy`` = ``b``
 +  A boolean value that controls whether to generate a class graph
 +  with the ancestors of a type, as well as the implemented interfaces.
 +  Requires the ``dot`` utility from `GraphViz <https://graphviz.org/>`__
 +  installed in the ``PATH``.
 +
 +The ``source-location`` section
 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 +
 +The ``source-location`` section is used to define the location of the source
 +code repository of a project to allow gi-docgen to create links from the API
 +reference to the definition of symbols and the source of the documentation
 +stanzas.
 +
 +The following keys are used, if found:
 +
 +``base_url`` = ``s``
 +  The base URL for accessing a file in the source code repository.
 +
 +``file_format`` = ``s``
 +  The format string used to point to a file, and a line in that file;
 +  the string can contain the token ``{filename}``, which will be replaced
 +  with the basename of the file; and the token ``{line}``, which will be
 +  replaced with the line in the file. The default value for this key
 +  is: ``{filename}#L{line}``.
 +
 +The ``extra`` section
 +~~~~~~~~~~~~~~~~~~~~~
 +
 +The ``extra`` section is used to define additional content used when
 +generating the API reference of a project.
 +
 +The following keys are used, if found:
 +
 +``content_files`` = ``list(s)``
 +  A list of tuples. The first element of the tuple is a Markdown
-   A list of files, relative to the directory specified by the
-   ``--content-dir`` command line argument. The files will be copied
++  file name, relative to the directories specified by the ``--content-dir``
++  command line arguments; the second element of the tuple is the
 +  title used for the link to the content file. When generating the
 +  API reference, gi-docgen will transform the Markdown file into
 +  an HTML one, using the same pre-processing filters applied to the
 +  documentation blocks found in the introspection data. The
 +  generated HTML files will be placed in the root directory of
 +  the namespace.
 +
 +``content_images`` = ``list(s)``
- The ``object`` key is always an array of dictionaries; each element in the array
- has a ``name`` key, used to match it; it can also have a ``property`` and a
- ``signal`` keys, each containing an array of dictionaries with a ``name`` key.
++  A list of files, relative to the directories specified by the
++  ``--content-dir`` command line arguments. The files will be copied
 +  in the root directory of the namespace.
 +
 +``urlmap_file`` = ``s``
 +  Path of a JavaScript file that defines the mapping from namespaces
 +  to url prefixes for resolving links to external symbols, as a
 +  JavaScript map with the name `baseURLs`:
 +
 +::
 +
 +    baseURLs = [
 +      [ 'Pango', 'https://gnome.pages.gitlab.gnome.org/pango/Pango/' ],
 +      [ 'PangoCairo', 'https://gnome.pages.gitlab.gnome.org/pango/PangoCairo/' ],
 +    ]
 +
 +
 +Symbol overrides
 +----------------
 +
 +Visibility
 +~~~~~~~~~~
 +
 +It is possible to override the visibility of types, properties, and symbols in
 +the introspection data from within the project configuration file.
 +
 +The following example will hide the type ``Protected``:
 +
 +::
 +
 +    [[object]]
 +    name = "Protected"
 +    hidden = true
 +
 +The type will be skipped when generating the API reference and the search index.
 +This annotation applies to all possible top-level types:
 +
 + - aliases
 + - bitfields
 + - callbacks
 + - classes
 + - domains
 + - enums
 + - functions
 + - function macros
 + - interfaces
 + - records
 + - unions
 +
++The ``object`` key is always an array of dictionaries; each element in the array
++can have a ``name`` key, used to match the object name exactly; or a ``pattern``
++key, which uses a regular expression to match the object name.
++
++Each object can contain the following keys:
++
++ - ``name``: the name of the symbol to match exactly
++ - ``pattern``: a regular expression to match the symbol name
++ - ``hidden``: whether the symbol should be hidden from the documentation
++ - ``check_ignore``: whether the symbol should be skipped when checking the
++   documentation
++
++Each element can also have the following sections:
++
++ - ``property``
++ - ``signal``
++ - ``constructor``
++ - ``method``
++ - ``function``
++
++Each one of these sections can contain array of objects.
++
 +The following example will hide the ``backend`` property on the ``Printer`` type:
 +
 +::
 +
 +    [[object]]
 +    name = "Printer"
 +
 +      [[object.property]]
 +      name = "backend"
 +      hidden = true
 +
 +The following example will hide the ``private-changed`` signal on the
 +``StyleProvider`` type:
 +
 +::
 +
 +    [[object]]
 +    name = "StyleProvider"
 +
 +      [[object.signal]]
 +      name = "private-changed"
 +      hidden = true
 +
- The ``hidden`` key can be used in both an ``object`` element, or in the
- ``property`` and ``signal`` elements.
++The following example will skip the ``quark`` function on the ``ParserError``
++type when checking the documentation:
++
++::
++
++    [[object]]
++    name = "ParserError"
 +
++      [[object.function]]
++      name = "quark"
++      check_ignore = true
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6c6a065d5da8ba62918cb987bbb3f6a00c17b0c9
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,35 @@@
++.. SPDX-FileCopyrightText: 2021 GNOME Foundation
++..
++.. SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
++
++===============
++gi-docgen check
++===============
++
++Check the documentation in the introspection data
++-------------------------------------------------
++
++SYNOPSIS
++========
++
++**gi-docgen check** [OPTIONS...] [GIRFILE]
++
++DESCRIPTION
++===========
++
++The **check** command runs a series of checks on the introspection
++file, to verify that public API is properly documented. It can be used 
++as part of a test suite.
++
++OPTIONS
++=======
++
++``--add-include--path DIR``
++  Adds ``DIR`` to the list of paths used to find introspection data
++  files included in the given ``GIRFILE``. The default search path
++  for GIR files is ``$XDG_DATA_DIRS/gir-1.0`` and ``$XDG_DATA_HOME/gir-1.0``;
++  this option is typically used to include uninstalled GIR files, or
++  non-standard locations.
++
++``-C, --config FILE``
++  Loads a project configuration file.
index 552522188216e23cae71009889147e583c6e4022,0000000000000000000000000000000000000000..5882ac02b7fde365d1c18b887d7bacdae6c5a2a7
mode 100644,000000..100644
--- /dev/null
@@@ -1,110 -1,0 +1,113 @@@
-   The directory for extra content, like additional files and images
-   specified in the project configuration file.
 +.. SPDX-FileCopyrightText: 2021 GNOME Foundation
 +..
 +.. SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +
 +===================
 +gi-docgen gen-index
 +===================
 +
 +Generating the symbols index from introspection data
 +----------------------------------------------------
 +
 +SYNOPSIS
 +========
 +
 +**gi-docgen gen-index** [OPTIONS...] [GIRFILE]
 +
 +DESCRIPTION
 +===========
 +
 +The **gen-index** command generates a symbols index from introspection
 +data. The symbols index can be used to efficiently search symbols and
 +terms.
 +
 +The generated index file is called ``index.json``
 +
 +OPTIONS
 +=======
 +
 +``--add-include--path DIR``
 +  Adds ``DIR`` to the list of paths used to find introspection data
 +  files included in the given ``GIRFILE``. The default search path
 +  for GIR files is ``$XDG_DATA_DIRS/gir-1.0`` and ``$XDG_DATA_HOME/gir-1.0``;
 +  this option is typically used to include uninstalled GIR files, or
 +  non-standard locations.
 +
 +``-C, --config FILE``
 +  Loads a project configuration file.
 +
 +``--dry-run``
 +  Only load the introspection data, without generating the index.
 +
 +``--content-dir DIR``
++  The directories for extra content, like additional files and images
++  specified in the project configuration file. This argument may be
++  called multiple times to specify several lookup directories, the
++  content files will be looked these directories in the same order
++  they are added.
 +
 +``--output-dir DIR``
 +  Generates the index file under ``DIR``.
 +
 +INDEX FILE
 +==========
 +
 +The index file is in `JSON format <https://json.org>`__.
 +
 +The index file contains a single object with the following members:
 +
 +``meta`` = ``object``
 +  An object with metadata about the index.
 +
 +``symbols`` = ``array of objects``
 +  An array of all the addressable symbols.
 +
 +``terms`` = ``object``
 +  A dictionary of all terms.
 +
 +The ``meta`` object contains the following members:
 +
 +``ns`` = ``s``
 +  The namespace name.
 +
 +``version`` = ``s``
 +  The namespace version.
 +
 +``generator`` = ``s``
 +  The ``gi-docgen`` string.
 +
 +``generator-version`` = ``s``
 +  The version of ``gi-docgen``.
 +
 +The ``symbols`` array contains objects with the following members:
 +
 +``type`` = ``s`` (*mandatory*)
 +  The type of symbol: ``alias``, ``bitfield``, ``callback``, ``class``,
 +  ``class_method``, ``ctor``, ``domain``, ``enum``, ``function``,
 +  ``function_macro``, ``interface``, ``method``, ``property``, ``signal``,
 +  ``type_func``, ``union``, ``vfunc``.
 +
 +``name`` = ``s`` (*mandatory*)
 +  The name of the symbol.
 +
 +``ctype`` = ``s``
 +  The base C type for identifiers; only available for types: ``alias``,
 +  ``bitfield``, ``class``, ``domain``, ``enum``, ``interface``,
 +  ``union``.
 +
 +``type_name`` = ``s``
 +  The type name related to a symbol; only available for types:
 +  ``class_method``, ``ctor``, ``method``, ``property``, ``signal``,
 +  ``type_func``, ``vfunc``.
 +
 +``ident`` = ``s``
 +  The C identifier for symbols; only available for types:
 +  ``class_method``, ``constant``, ``ctor``, ``function``, ``function_macro``,
 +  ``method``, ``type_func``.
 +
 +``struct_for`` = ``s``
 +  The C type related to a class structure; only available for the
 +  ``class_method`` type.
 +
 +The ``terms`` dictonary contains all terms as members; each term is associated
 +to an array of indices in the ``symbols`` array.
index b36f22b6ff8f4f5230be4dc9b66c2435841f47db,0000000000000000000000000000000000000000..146d3e35f15c88a61860050ff68d72acb0309092
mode 100644,000000..100644
--- /dev/null
@@@ -1,66 -1,0 +1,69 @@@
-   The directory for extra content, like additional files and images
-   specified in the project configuration file.
 +.. SPDX-FileCopyrightText: 2021 GNOME Foundation
 +..
 +.. SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +
 +==================
 +gi-docgen generate
 +==================
 +
 +Generating the API reference from introspection data
 +----------------------------------------------------
 +
 +SYNOPSIS
 +========
 +
 +**gi-docgen generate** [OPTIONS...] [GIRFILE]
 +
 +DESCRIPTION
 +===========
 +
 +The **generate** command generates the API reference from a GIR file.
 +
 +GIR files are XML files that describe an API in a machine readable way,
 +and are typically provided by a GObject library.
 +
 +OPTIONS
 +=======
 +
 +``--add-include--path DIR``
 +  Adds ``DIR`` to the list of paths used to find introspection data
 +  files included in the given ``GIRFILE``. The default search path
 +  for GIR files is ``$XDG_DATA_DIRS/gir-1.0`` and ``$XDG_DATA_HOME/gir-1.0``;
 +  this option is typically used to include uninstalled GIR files, or
 +  non-standard locations.
 +
 +``-C, --config FILE``
 +  Loads a project configuration file.
 +
 +``--dry-run``
 +  Only load the introspection data, without generating the reference.
 +
 +``--templates-dir DIR``
 +  Look for templates under ``DIR``. The default location for the
 +  templates directory is inside the ``gi-docgen`` installation.
 +
 +``--content-dir DIR``
++  The directories for extra content, like additional files and images
++  specified in the project configuration file. This argument may be
++  called multiple times to specify several lookup directories, content
++  files will be looked up in the content directories in the
++  same order they are added.
 +
 +``--theme-name NAME``
 +  The name of the template to use. Overrides the name specified by
 +  the project configuration file.
 +
 +``--output-dir DIR``
 +  Generates the reference under ``DIR``.
 +
 +``--no-namespace-dir``
 +  When specified, the files are directly generated under the output
 +  directory, instead of using a sub-directory based on the namespace
 +  name and version.
 +
 +``--section NAME``
 +  Only generate the section ``NAME`` of the reference. Valid section
 +  names are: ``aliases``, ``bitfields``, ``callbacks``, ``classes``,
 +  ``constants``, ``domains``, ``enums``, ``functions``, ``function_macros``,
 +  ``interfaces``, ``structs``, and ``unions``. Additionally, ``all``
 +  will generate all sections, and ``none`` will generate no section.
index e52da635fd94dd2ba43cce82ebf45a85d5373c42,0000000000000000000000000000000000000000..5508dc252737f07401046c001088178e2183eec8
mode 100644,000000..100644
--- /dev/null
@@@ -1,70 -1,0 +1,74 @@@
-   
 +.. SPDX-FileCopyrightText: 2021 GNOME Foundation
 +..
 +.. SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +
 +========
 +Commands
 +========
 +  
 +.. toctree::
 +    :hidden:
 +    :titlesonly:
 +    :maxdepth: 1
 +  
 +    generate
 +    gen-index
++    check
 +
 +SYNOPSIS
 +========
 +
 +**gi-docgen** COMMAND [OPTIONS...]
 +
 +The ``gi-docgen`` command line utility has several commands, each with its
 +own functionality and options.
 +
 +COMMANDS
 +========
 +
 +:doc:`generate`
 +  Generates the API reference
 +  
 +:doc:`gen-index`
 +  Generates the symbol indices for search
++
++:doc:`check`
++  Checks the documentation
++
 +OPTIONS
 +=======
 +
 +All commands support the following options:
 +
 +``-q, --quiet``
 +  Do not emit any additional information message.
 +
 +``--fatal-warnings``
 +  Make all warnings fatal, immediately terminating the process.
 +
 +``--help``
 +  Show an help message.
 +
 +ENVIRONMENT VARIABLES
 +=====================
 +
 +All commands support the following environment variables:
 +
 +``GIDOCGEN_DEBUG``
 +  If set, ``gi-docgen`` will emit debugging messages.
 +
 +
 +BUGS
 +====
 +
 +Report bugs at https://gitlab.gnome.org/GNOME/gi-docgen/issues
 +
 +HOMEPAGE and CONTACT
 +====================
 +
 +https://gnome.pages.gitlab.gnome.org/gi-docgen/
 +
 +AUTHOR
 +======
 +
 +Emmanuele Bassi
index eba2cafa33db70ba42f690470b982e4d0392ef32,0000000000000000000000000000000000000000..3da1709be86d475075470cfb48c3e19840050dda
mode 100644,000000..100644
--- /dev/null
@@@ -1,279 -1,0 +1,297 @@@
-     def is_hidden(self, name, category=None, key=None):
 +# SPDX-FileCopyrightText: 2021 GNOME Foundation <https://gnome.org>
 +# SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +
 +import os
++import re
 +import toml
 +
 +from urllib.parse import urljoin
 +
 +from . import log, utils
 +
 +
 +class GIDocConfig:
 +    """Load and represent the configuration for gidocgen"""
 +    def __init__(self, config_file=None):
 +        self._config_file = config_file
 +
 +        self._config = {}
 +        if self._config_file is not None:
 +            try:
 +                log.debug(f"Reading configuration file: {self._config_file}")
 +                self._config = toml.load(self._config_file)
 +            except toml.TomlDecodeError as err:
 +                log.error(f"Invalid configuration file: {self._config_file}: {err}")
 +
 +    @property
 +    def library(self):
 +        return self._config.get('library', {})
 +
 +    @property
 +    def extra(self):
 +        return self._config.get('extra', {})
 +
 +    @property
 +    def theme(self):
 +        return self._config.get('theme', {})
 +
 +    def get_templates_dir(self, default=None):
 +        return self.theme.get('templates_dir', default)
 +
 +    def get_theme_name(self, default=None):
 +        return self.theme.get('name', default)
 +
 +    def get_library_name(self, default=None):
 +        return self.library.get('name', default)
 +
 +    def get_website_url(self, default=None):
 +        return self.library.get('website_url', default)
 +
 +    def get_logo_url(self, default=None):
 +        return self.library.get('logo_url', default)
 +
 +    def get_description(self, default=None):
 +        return self.library.get('description', default)
 +
 +    @property
 +    def urlmap_file(self):
 +        return self.extra.get('urlmap_file')
 +
 +    @property
 +    def version(self):
 +        return self.library.get('version', 'Unknown')
 +
 +    @property
 +    def authors(self):
 +        return self.library.get('authors', 'Unknown authors')
 +
 +    @property
 +    def license(self):
 +        return self.library.get('license', 'All rights reserved')
 +
 +    @property
 +    def website_url(self):
 +        return self.library.get('website_url', '')
 +
 +    @property
 +    def browse_url(self):
 +        return self.library.get('browse_url', '')
 +
 +    @property
 +    def logo_url(self):
 +        return self.library.get('logo_url', '')
 +
 +    @property
 +    def description(self):
 +        return self.library.get('description', '')
 +
 +    @property
 +    def dependencies(self):
 +        library = self._config.get('library', None)
 +        if library is None:
 +            return {}
 +
 +        retval = {}
 +        dependencies = self._config.get('dependencies', {})
 +        for gir_name, dep in dependencies.items():
 +            res = {}
 +            res['name'] = dep.get('name', 'Unknown')
 +            res['description'] = dep.get('description', 'No description provided')
 +            res['docs_url'] = dep.get('docs_url', '#')
 +            retval[gir_name] = res
 +            log.debug(f"Found dependency {gir_name}: {res}")
 +
 +        return retval
 +
 +    @property
 +    def devhelp(self):
 +        return self.library.get('devhelp', False)
 +
 +    @property
 +    def search_index(self):
 +        return self.library.get('search_index', False)
 +
 +    @property
 +    def content_files(self):
 +        return self.extra.get('content_files', [])
 +
 +    @property
 +    def content_images(self):
 +        return self.extra.get('content_images', [])
 +
 +    @property
 +    def source_location_url(self):
 +        source_location = self._config.get('source-location', {})
 +        return source_location.get('base_url', '')
 +
 +    @property
 +    def file_format(self):
 +        source_location = self._config.get('source-location', {})
 +        return source_location.get('file_format', '{filename}#L{line}')
 +
 +    @property
 +    def theme_name(self):
 +        return self.theme.get('name', '')
 +
 +    @property
 +    def show_index_summary(self):
 +        return self.theme.get('show_index_summary', False)
 +
 +    @property
 +    def show_class_hierarchy(self):
 +        if utils.find_program('dot') is None:
 +            return False
 +        return self.theme.get('show_class_hierarchy', False)
 +
 +    def source_link(self, *args):
 +        (filename, line) = args[0]
 +        base_url = self.source_location_url
 +        file_format = self.file_format
 +        endpoint = file_format.replace('{filename}', filename)
 +        endpoint = endpoint.replace('{line}', str(line))
 +        return urljoin(base_url, endpoint)
 +
 +    @property
 +    def objects(self):
 +        return self._config.get('object', {})
 +
-             if obj['name'] == name:
++    def match_object(self, name, match_key, category=None, key=None):
++        def obj_matches(obj, name):
++            n = obj.get('name')
++            p = obj.get('pattern')
++            if n is not None and n == name:
++                return True
++            elif p is not None and re.match(p, name):
++                return True
++            return False
 +        for obj in self.objects:
-                     return obj.get('hidden', False)
++            if obj_matches(obj, name):
 +                if category is None:
-                     obj_category = obj.get(category)
-                     if obj_category is None:
-                         return False
-                     for c in obj_category:
-                         if c['name'] == key:
-                             return c.get('hidden', False)
++                    return obj.get(match_key, False)
 +                else:
++                    assert key is not None
++                obj_category = obj.get(category)
++                if obj_category is None:
++                    return False
++                for c in obj_category:
++                    if obj_matches(c, key):
++                        return c.get(match_key, False)
 +        return False
 +
++    def is_hidden(self, name, category=None, key=None):
++        return self.match_object(name, 'hidden', category, key)
++
++    def is_skipped(self, name, category=None, key=None):
++        if self.is_hidden(name, category, key):
++            return True
++        return self.match_object(name, 'check_ignore', category, key)
++
 +
 +class GITemplateConfig:
 +    """Load and represent the template configuration"""
 +    def __init__(self, templates_dir, template_name):
 +        self._templates_dir = templates_dir
 +        self._template_name = template_name
 +        self._config_file = os.path.join(templates_dir, template_name, f"{template_name}.toml")
 +
 +        self._config = {}
 +        try:
 +            log.debug(f"Reading template configuration file: {self._config_file}")
 +            self._config = toml.load(self._config_file)
 +        except toml.TomlDecodeError as err:
 +            log.error(f"Invalid template configuration file: {self._config_file}: {err}")
 +
 +    @property
 +    def name(self):
 +        metadata = self._config.get('metadata', {})
 +        return metadata.get('name', self._template_name)
 +
 +    @property
 +    def css(self):
 +        css = self._config.get('css', {})
 +        return css.get('style', None)
 +
 +    @property
 +    def extra_files(self):
 +        extra = self._config.get('extra_files', {})
 +        return extra.get('files', [])
 +
 +    @property
 +    def templates(self):
 +        return self._config.get('templates', {})
 +
 +    @property
 +    def class_template(self):
 +        return self.templates.get('class', 'class.html')
 +
 +    @property
 +    def method_template(self):
 +        return self.templates.get('method', 'method.html')
 +
 +    @property
 +    def class_method_template(self):
 +        return self.templates.get('class_method', 'class_method.html')
 +
 +    @property
 +    def vfunc_template(self):
 +        return self.templates.get('vfunc', 'vfunc.html')
 +
 +    @property
 +    def property_template(self):
 +        return self.templates.get('property', 'property.html')
 +
 +    @property
 +    def signal_template(self):
 +        return self.templates.get('signal', 'signal.html')
 +
 +    @property
 +    def type_func_template(self):
 +        return self.templates.get('type_func', 'type_func.html')
 +
 +    @property
 +    def ctor_template(self):
 +        return self.templates.get('ctor', 'type_func.html')
 +
 +    @property
 +    def func_template(self):
 +        return self.templates.get('function', 'function.html')
 +
 +    @property
 +    def constant_template(self):
 +        return self.templates.get('constant', 'constant.html')
 +
 +    @property
 +    def interface_template(self):
 +        return self.templates.get('interface', 'interface.html')
 +
 +    @property
 +    def namespace_template(self):
 +        return self.templates.get('namespace', 'namespace.html')
 +
 +    @property
 +    def content_template(self):
 +        return self.templates.get('content', 'content.html')
 +
 +    @property
 +    def enum_template(self):
 +        return self.templates.get('enum', 'enum.html')
 +
 +    @property
 +    def flags_template(self):
 +        return self.templates.get('flags', 'flags.html')
 +
 +    @property
 +    def error_template(self):
 +        return self.templates.get('error', 'error.html')
 +
 +    @property
 +    def record_template(self):
 +        return self.templates.get('record', 'record.html')
 +
 +    @property
 +    def union_template(self):
 +        return self.templates.get('union', 'union.html')
 +
 +    @property
 +    def alias_template(self):
 +        return self.templates.get('alias', 'alias.html')
index c02346b034986c0bca2373b550427c192ff49c83,0000000000000000000000000000000000000000..b1e3ae6ebe435083332b76e2434aadafac929371
mode 100644,000000..100644
--- /dev/null
@@@ -1,4 -1,0 +1,4 @@@
- version = "2021.6"
 +# SPDX-FileCopyrightText: 2020 GNOME Foundation <https://gnome.org>
 +# SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +
++version = "2021.9"
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..73d29f0f09e59f515e68e0c6a350a53babc964d4
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,371 @@@
++# SPDX-FileCopyrightText: 2021 GNOME Foundation
++# SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
++
++import argparse
++import sys
++
++from . import config, gir, log, utils
++
++
++HELP_MSG = "Checks introspection data for valid documentation"
++
++
++def _check_doc_element(path, symbol, results):
++    name = '.'.join(path + [symbol.name])
++
++    if symbol.source_position is not None:
++        filename = symbol.source_position[0]
++        line = symbol.source_position[1]
++    else:
++        filename = "<unknown>"
++        line = 0
++
++    if symbol.doc is None:
++        results.append(f"Symbol '{name}' at {filename}:{line} is not documented")
++
++
++def _check_arg_docs(path, arguments, results):
++    symbol = '.'.join(path)
++    for arg in arguments:
++        if arg.doc is None:
++            results.append(f"Parameter '{arg.name}' of symbol '{symbol}' is not documented")
++
++
++def _check_retval_docs(path, retval, results):
++    if retval is None:
++        return
++
++    if isinstance(retval.target, gir.VoidType):
++        return
++
++    symbol = '.'.join(path)
++    if retval.doc is None:
++        results.append(f"Return value for symbol '{symbol}' is not documented")
++
++
++def _check_aliases(config, repository, symbols, results):
++    for alias in symbols:
++        if config.is_skipped(alias.name):
++            log.debug(f"Skipping hidden alias {alias.name}")
++            continue
++        _check_doc_element([repository.namespace.name], alias, results)
++
++
++def _check_bitfields(config, repository, symbols, results):
++    for bitfield in symbols:
++        if config.is_skipped(bitfield.name):
++            log.debug(f"Skipping hidden bitfield {bitfield.name}")
++            continue
++
++        _check_doc_element([repository.namespace.name], bitfield, results)
++
++        for member in bitfield.members:
++            _check_doc_element([repository.namespace.name, bitfield.name], member, results)
++
++        for func in bitfield.functions:
++            if config.is_skipped(bitfield.name, 'function', func.name):
++                continue
++            _check_doc_element([repository.namespace.name, bitfield.name], func, results)
++            _check_arg_docs([repository.namespace.name, bitfield.name, func.name], func.parameters, results)
++            _check_retval_docs([repository.namespace.name, bitfield.name, func.name], func.return_value, results)
++
++
++def _check_callbacks(config, repository, symbols, results):
++    for cb in symbols:
++        if config.is_skipped(cb.name):
++            log.debug(f"Skipping hidden callback {cb.name}")
++            continue
++
++        _check_doc_element([repository.namespace.name], cb, results)
++        _check_arg_docs([repository.namespace.name, cb.name], cb.parameters, results)
++        _check_retval_docs([repository.namespace.name, cb.name], cb.return_value, results)
++
++
++def _check_classes(config, repository, symbols, results):
++    for cls in symbols:
++        if config.is_skipped(cls.name):
++            log.debug(f"Skipping hidden class {cls.name}")
++            continue
++
++        _check_doc_element([repository.namespace.name], cls, results)
++
++        for ctor in cls.constructors:
++            if config.is_skipped(cls.name, 'constructor', ctor.name):
++                continue
++            _check_doc_element([repository.namespace.name, cls.name], ctor, results)
++            _check_arg_docs([repository.namespace.name, cls.name, ctor.name], ctor.parameters, results)
++            _check_retval_docs([repository.namespace.name, cls.name, ctor.name], ctor.return_value, results)
++
++        for method in cls.methods:
++            if config.is_skipped(cls.name, 'method', method.name):
++                continue
++            _check_doc_element([repository.namespace.name, cls.name], method, results)
++            _check_arg_docs([repository.namespace.name, cls.name, method.name], method.parameters, results)
++            _check_retval_docs([repository.namespace.name, cls.name, method.name], method.return_value, results)
++
++        for func in cls.functions:
++            if config.is_skipped(cls.name, 'function', func.name):
++                continue
++            _check_doc_element([repository.namespace.name, cls.name], func, results)
++            _check_arg_docs([repository.namespace.name, cls.name, func.name], func.parameters, results)
++            _check_retval_docs([repository.namespace.name, cls.name, func.name], func.return_value, results)
++
++        for prop in cls.properties.values():
++            if config.is_skipped(cls.name, 'property', prop.name):
++                continue
++            _check_doc_element([repository.namespace.name, cls.name], prop, results)
++
++        for signal in cls.signals.values():
++            if config.is_skipped(cls.name, 'signal', signal.name):
++                continue
++            _check_doc_element([repository.namespace.name, cls.name], signal, results)
++            _check_arg_docs([repository.namespace.name, cls.name, signal.name], signal.parameters, results)
++            _check_retval_docs([repository.namespace.name, cls.name, signal.name], signal.return_value, results)
++
++
++def _check_constants(config, repository, symbols, results):
++    for constant in symbols:
++        if config.is_skipped(constant.name):
++            log.debug(f"Skipping hidden constant {constant.name}")
++            continue
++
++        _check_doc_element([repository.namespace.name], constant, results)
++
++
++def _check_domains(config, repository, symbols, results):
++    for domain in symbols:
++        if config.is_skipped(domain.name):
++            log.debug(f"Skipping hidden error domain {domain.name}")
++            continue
++
++        _check_doc_element([repository.namespace.name], domain, results)
++
++        for member in domain.members:
++            _check_doc_element([repository.namespace.name, domain.name], member, results)
++
++        for func in domain.functions:
++            if config.is_skipped(domain.name, 'function', func.name):
++                continue
++            _check_doc_element([repository.namespace.name, domain.name], func, results)
++            _check_arg_docs([repository.namespace.name, domain.name, func.name], func.parameters, results)
++            _check_retval_docs([repository.namespace.name, domain.name, func.name], func.return_value, results)
++
++
++def _check_enums(config, repository, symbols, results):
++    for enum in symbols:
++        if config.is_skipped(enum.name):
++            log.debug(f"Skipping hidden enumeration {enum.name}")
++            continue
++
++        _check_doc_element([repository.namespace.name], enum, results)
++
++        for member in enum.members:
++            _check_doc_element([repository.namespace.name, enum.name], member, results)
++
++        for func in enum.functions:
++            if config.is_skipped(enum.name, 'function', func.name):
++                continue
++            _check_doc_element([repository.namespace.name, enum.name], func, results)
++            _check_arg_docs([repository.namespace.name, enum.name, func.name], func.parameters, results)
++            _check_retval_docs([repository.namespace.name, enum.name, func.name], func.return_value, results)
++
++
++def _check_functions(config, repository, symbols, results):
++    for func in symbols:
++        if config.is_skipped(func.name):
++            log.debug(f"Skipping hidden function {func.name}")
++            continue
++
++        _check_doc_element([repository.namespace.name], func, results)
++        _check_arg_docs([repository.namespace.name, func.name], func.parameters, results)
++        _check_retval_docs([repository.namespace.name, func.name], func.return_value, results)
++
++
++def _check_function_macros(config, repository, symbols, results):
++    for func in symbols:
++        if config.is_skipped(func.name):
++            log.debug(f"Skipping hidden function macro {func.name}")
++            continue
++
++        _check_doc_element([repository.namespace.name], func, results)
++        _check_arg_docs([repository.namespace.name, func.name], func.parameters, results)
++        _check_retval_docs([repository.namespace.name, func.name], func.return_value, results)
++
++
++def _check_interfaces(config, repository, symbols, results):
++    for iface in symbols:
++        if config.is_skipped(iface.name):
++            log.debug(f"Skipping hidden interface {iface.name}")
++            continue
++
++        _check_doc_element([repository.namespace.name], iface, results)
++
++        for method in iface.methods:
++            if config.is_skipped(iface.name, 'method', method.name):
++                continue
++            _check_doc_element([repository.namespace.name, iface.name], method, results)
++            _check_arg_docs([repository.namespace.name, iface.name, method.name], method.parameters, results)
++            _check_retval_docs([repository.namespace.name, iface.name, method.name], method.return_value, results)
++
++        for func in iface.functions:
++            if config.is_skipped(iface.name, 'function', func.name):
++                continue
++            _check_doc_element([repository.namespace.name, iface.name], func, results)
++            _check_arg_docs([repository.namespace.name, iface.name, func.name], func.parameters, results)
++            _check_retval_docs([repository.namespace.name, iface.name, func.name], func.return_value, results)
++
++        for prop in iface.properties.values():
++            if config.is_skipped(iface.name, 'property', prop.name):
++                continue
++            _check_doc_element([repository.namespace.name, iface.name], prop, results)
++
++        for signal in iface.signals.values():
++            if config.is_skipped(iface.name, 'signal', signal.name):
++                continue
++            _check_doc_element([repository.namespace.name, iface.name], signal, results)
++            _check_arg_docs([repository.namespace.name, iface.name, signal.name], signal.parameters, results)
++            _check_retval_docs([repository.namespace.name, iface.name, signal.name], signal.return_value, results)
++
++
++def _check_records(config, repository, symbols, results):
++    for struct in symbols:
++        if config.is_skipped(struct.name):
++            log.debug(f"Skipping hidden record {struct.name}")
++            continue
++
++        _check_doc_element([repository.namespace.name], struct, results)
++
++        for ctor in struct.constructors:
++            if config.is_skipped(struct.name, 'constructor', ctor.name):
++                continue
++            _check_doc_element([repository.namespace.name, struct.name], ctor, results)
++            _check_arg_docs([repository.namespace.name, struct.name, ctor.name], ctor.parameters, results)
++            _check_retval_docs([repository.namespace.name, struct.name, ctor.name], ctor.return_value, results)
++
++        for method in struct.methods:
++            if config.is_skipped(struct.name, 'method', method.name):
++                continue
++            _check_doc_element([repository.namespace.name, struct.name], method, results)
++            _check_arg_docs([repository.namespace.name, struct.name, method.name], method.parameters, results)
++            _check_retval_docs([repository.namespace.name, struct.name, method.name], method.return_value, results)
++
++        for func in struct.functions:
++            if config.is_skipped(struct.name, 'function', func.name):
++                continue
++            _check_doc_element([repository.namespace.name, struct.name], func, results)
++            _check_arg_docs([repository.namespace.name, struct.name, func.name], func.parameters, results)
++            _check_retval_docs([repository.namespace.name, struct.name, func.name], func.return_value, results)
++
++
++def _check_unions(config, repository, symbols, results):
++    for union in symbols:
++        if config.is_skipped(union.name):
++            log.debug(f"Skipping hidden union {union.name}")
++            continue
++
++        _check_doc_element([repository.namespace.name], union, results)
++
++        for ctor in union.constructors:
++            if config.is_skipped(union.name, 'constructor', ctor.name):
++                continue
++            _check_doc_element([repository.namespace.name, union.name], ctor, results)
++            _check_arg_docs([repository.namespace.name, union.name, ctor.name], ctor.parameters, results)
++            _check_retval_docs([repository.namespace.name, union.name, ctor.name], ctor.return_value, results)
++
++        for method in union.methods:
++            if config.is_skipped(union.name, 'method', method.name):
++                continue
++            _check_doc_element([repository.namespace.name, union.name], method, results)
++            _check_arg_docs([repository.namespace.name, union.name, method.name], method.parameters, results)
++            _check_retval_docs([repository.namespace.name, union.name, method.name], method.return_value, results)
++
++        for func in union.functions:
++            if config.is_skipped(union.name, 'function', func.name):
++                continue
++            _check_doc_element([repository.namespace.name, union.name], func, results)
++            _check_arg_docs([repository.namespace.name, union.name, func.name], func.parameters, results)
++            _check_retval_docs([repository.namespace.name, union.name, func.name], func.return_value, results)
++
++
++def check(repository, config):
++    namespace = repository.namespace
++
++    symbols = {
++        "aliases": sorted(namespace.get_aliases(), key=lambda alias: alias.name.lower()),
++        "bitfields": sorted(namespace.get_bitfields(), key=lambda bitfield: bitfield.name.lower()),
++        "callbacks": sorted(namespace.get_callbacks(), key=lambda callback: callback.name.lower()),
++        "classes": sorted(namespace.get_classes(), key=lambda cls: cls.name.lower()),
++        "constants": sorted(namespace.get_constants(), key=lambda const: const.name.lower()),
++        "domains": sorted(namespace.get_error_domains(), key=lambda domain: domain.name.lower()),
++        "enums": sorted(namespace.get_enumerations(), key=lambda enum: enum.name.lower()),
++        "functions": sorted(namespace.get_functions(), key=lambda func: func.name.lower()),
++        "function_macros": sorted(namespace.get_effective_function_macros(), key=lambda func: func.name.lower()),
++        "interfaces": sorted(namespace.get_interfaces(), key=lambda interface: interface.name.lower()),
++        "structs": sorted(namespace.get_effective_records(), key=lambda record: record.name.lower()),
++        "unions": sorted(namespace.get_unions(), key=lambda union: union.name.lower()),
++    }
++
++    all_indices = {
++        "aliases": _check_aliases,
++        "bitfields": _check_bitfields,
++        "callbacks": _check_callbacks,
++        "classes": _check_classes,
++        "constants": _check_constants,
++        "domains": _check_domains,
++        "enums": _check_enums,
++        "functions": _check_functions,
++        "function_macros": _check_function_macros,
++        "interfaces": _check_interfaces,
++        "structs": _check_records,
++        "unions": _check_unions,
++    }
++
++    results = []
++
++    # Each section is isolated, so we run it into a thread pool
++    for section in all_indices:
++        checker = all_indices.get(section, None)
++        if checker is None:
++            log.error(f"No checker for section {section}")
++            continue
++
++        s = symbols.get(section, None)
++        if s is None:
++            log.debug(f"No symbols for section {section}")
++            continue
++
++        log.debug(f"Checking symbols for section {section}")
++        checker(config, repository, s, results)
++
++    for res in results:
++        log.warning(res)
++
++    if len(results) == 0:
++        return 0
++    else:
++        return 1
++
++
++def add_args(parser):
++    parser.add_argument("-C", "--config", metavar="FILE", help="the configuration file")
++    parser.add_argument("--add-include-path", action="append", dest="include_paths", default=[],
++                        help="include paths for other GIR files")
++    parser.add_argument("infile", metavar="GIRFILE", type=argparse.FileType('r', encoding='UTF-8'),
++                        default=sys.stdin, help="the GIR file to parse")
++
++
++def run(options):
++    log.info(f"Loading config file: {options.config}")
++
++    conf = config.GIDocConfig(options.config)
++
++    paths = []
++    paths.extend(options.include_paths)
++    paths.extend(utils.default_search_paths())
++    log.info(f"Search paths: {paths}")
++
++    parser = gir.GirParser(search_paths=paths)
++    parser.parse(options.infile)
++
++    log.checkpoint()
++    return check(parser.get_repository(), conf)
index 89cac7f7b098e80879fb64017fd097ea1d0b26ff,0000000000000000000000000000000000000000..c6186a17a4e21b24b308f3b2b715f821b322094c
mode 100644,000000..100644
--- /dev/null
@@@ -1,88 -1,0 +1,91 @@@
- def _gen_content_files(config, content_dir):
 +# SPDX-FileCopyrightText: 2021 GNOME Foundation
 +# SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +
 +import argparse
 +import os
 +import sys
 +
 +from . import config, gir, log, utils
 +
 +
 +HELP_MSG = "Generates the build dependencies"
 +
 +
-         content_files.append(os.path.join(content_dir, file_name))
++def _gen_content_files(config, content_dirs):
 +    content_files = []
 +    for file_name in config.content_files:
- def _gen_content_images(config, content_dir):
++        content_files.append(utils.find_extra_content_file(content_dirs, file_name))
 +    return content_files
 +
 +
-         content_images.append(os.path.join(content_dir, image_file))
++def _gen_content_images(config, content_dirs):
 +    content_images = []
 +    for image_file in config.content_images:
-     content_dir = options.content_dir or os.getcwd()
++        content_images.append(utils.find_extra_content_file(content_dirs, image_file))
 +    return content_images
 +
 +
 +def gen_dependencies(repository, config, options):
 +    outfile = options.outfile
 +
 +    outfile.write(options.config)
 +    outfile.write("\n")
 +
 +    for name in repository.includes:
 +        include = repository.includes[name]
 +        if include.girfile is not None:
 +            outfile.write(include.girfile)
 +            outfile.write("\n")
 +
 +    outfile.write(repository.girfile)
 +    outfile.write("\n")
 +
-     content_files = _gen_content_files(config, content_dir)
++    content_dirs = options.content_dirs
++    if content_dirs == []:
++        content_dirs = [os.getcwd()]
 +
-     content_images = _gen_content_images(config, content_dir)
++    content_files = _gen_content_files(config, content_dirs)
 +    for f in content_files:
 +        outfile.write(f)
 +        outfile.write("\n")
 +
-     parser.add_argument("--content-dir", default=None, help="the base directory with the extra content")
++    content_images = _gen_content_images(config, content_dirs)
 +    for f in content_images:
 +        outfile.write(f)
 +        outfile.write("\n")
 +
 +
 +def add_args(parser):
 +    parser.add_argument("--add-include-path", action="append", dest="include_paths", default=[],
 +                        help="include paths for other GIR files")
 +    parser.add_argument("-C", "--config", metavar="FILE", help="the configuration file")
++    parser.add_argument("--content-dir", action="append", dest="content_dirs", default=[],
++                        help="the base directories with the extra content")
 +    parser.add_argument("--dry-run", action="store_true", help="parses the GIR file without generating files")
 +    parser.add_argument("infile", metavar="GIRFILE", type=argparse.FileType('r', encoding='UTF-8'),
 +                        default=sys.stdin, help="the GIR file to parse")
 +    parser.add_argument("outfile", metavar="DEPFILE", type=argparse.FileType('w', encoding='UTF-8'),
 +                        default=sys.stdout, help="the dependencies file to generate")
 +
 +
 +def run(options):
 +    # If we're sending output to stdout, we disable logging
 +    if options.outfile.name == "<stdout>":
 +        log.set_quiet(True)
 +
 +    log.info(f"Loading config file: {options.config}")
 +    conf = config.GIDocConfig(options.config)
 +
 +    paths = []
 +    paths.extend(options.include_paths)
 +    paths.extend(utils.default_search_paths())
 +    log.info(f"Search paths: {paths}")
 +
 +    log.info("Parsing GIR file")
 +    parser = gir.GirParser(search_paths=paths)
 +    parser.parse(options.infile)
 +
 +    if not options.dry_run:
 +        gen_dependencies(parser.get_repository(), conf, options)
 +
 +    return 0
index 8b78259ad1e73201932b4a27624d08921913de35,0000000000000000000000000000000000000000..325c11ad6a38f75799aba66cd91e5fcdba1461f9
mode 100644,000000..100644
--- /dev/null
@@@ -1,2749 -1,0 +1,3034 @@@
-     'utf8': 'The string is a NUL terminated UTF-8 string.',
-     'filename': 'The string is a file system path, using the OS encoding.',
 +# SPDX-FileCopyrightText: 2021 GNOME Foundation
 +# SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +
 +import argparse
 +import concurrent.futures
 +import jinja2
 +import markdown
 +import os
 +import shutil
 +import sys
 +
 +import xml.etree.ElementTree as etree
 +
 +from markupsafe import Markup
 +
 +from . import config, gir, log, utils
 +from . import gdgenindices
 +
 +
 +HELP_MSG = "Generates the reference"
 +
 +MISSING_DESCRIPTION = "No description available."
 +
 +STRING_TYPES = {
-     'container': 'The caller of the function takes ownership of the data container, but not the data inside it.',
-     'full': 'The caller of the function takes ownership of the data, and is responsible for freeing it.',
++    'utf8': 'The value is a NUL terminated UTF-8 string.',
++    'filename': 'The value is a file system path, using the OS encoding.',
++}
++
++STRING_ELEMENT_TYPES = {
++    'utf8': 'Each element is a NUL terminated UTF-8 string.',
++    'filename': 'Each element is a file system path, using the OS encoding.',
 +}
 +
 +ARG_TRANSFER_MODES = {
 +    'none': 'The data is owned by the caller of the function.',
 +    'container': 'The called function takes ownership of the data container, but not the data inside it.',
 +    'full': 'The called function takes ownership of the data, and is responsible for freeing it.',
 +}
 +
 +METHOD_ARG_TRANSFER_MODES = {
 +    'none': 'The data is owned by the caller of the function.',
 +    'container': 'The instance takes ownership of the data container, but not the data inside it.',
 +    'full': 'The instance takes ownership of the data, and is responsible for freeing it.',
 +}
 +
 +RETVAL_TRANSFER_MODES = {
 +    'none': 'The data is owned by the called function.',
 +    'container': 'The caller of the function takes ownership of the data container, but not the data inside it.',
 +    'full': 'The caller of the function takes ownership of the data, and is responsible for freeing it.',
 +    'floating': 'The returned data has a floating reference.',
 +}
 +
 +METHOD_RETVAL_TRANSFER_MODES = {
 +    'none': 'The data is owned by the instance.',
-     'call': 'Arguments are valid during the call.',
-     'notified': 'Arguments are valid until the notify function is called.',
-     'async': 'Arguments are valid until the call is completed.',
++    'container': 'The caller of the method takes ownership of the data container, but not the data inside it.',
++    'full': 'The caller of the method takes ownership of the data, and is responsible for freeing it.',
 +    'floating': 'The returned data has a floating reference.',
 +}
 +
 +DIRECTION_MODES = {
 +    'in': '-',
 +    'inout': 'The argument will be modified by the function.',
 +    'out': 'The argument will be set by the function.',
 +}
 +
 +SCOPE_MODES = {
 +    'none': '-',
- def gen_type_link(namespace, name):
-     t = namespace.find_real_type(name)
-     if t is not None:
-         if isinstance(t, gir.Alias):
-             return f"<a href=\"alias.{name}.html\"><code>{t.ctype}</code></a>"
-         elif isinstance(t, gir.BitField):
-             return f"<a href=\"flags.{name}.html\"><code>{t.ctype}</code></a>"
-         elif isinstance(t, gir.Class):
-             return f"<a href=\"class.{name}.html\"><code>{t.ctype}</code></a>"
-         elif isinstance(t, gir.ErrorDomain):
-             return f"<a href=\"error.{name}.html\"><code>{t.ctype}</code></a>"
-         elif isinstance(t, gir.Enumeration):
-             return f"<a href=\"enum.{name}.html\"><code>{t.ctype}</code></a>"
-         elif isinstance(t, gir.Interface):
-             return f"<a href=\"iface.{name}.html\"><code>{t.ctype}</code></a>"
-         elif isinstance(t, gir.Record):
-             return f"<a href=\"struct.{name}.html\"><code>{t.ctype}</code></a>"
-         elif isinstance(t, gir.Union):
-             return f"<a href=\"union.{name}.html\"><code>{t.ctype}</code></a>"
-     return f"<code>{namespace.identifier_prefix[0]}{name}</code>"
++    'call': 'The callback arguments are valid during the call.',
++    'notified': 'The callback arguments are valid until the notify function is called.',
++    'async': 'The callback arguments are valid until the asynchronous call is completed.',
 +}
 +
 +SIGNAL_WHEN = {
 +    'first': "The default handler is called before the handlers added via `g_signal_connect()`.",
 +    'last': "The default handler is called after the handlers added via `g_signal_connect()`.",
 +    'cleanup': "The default handler is called after the handlers added via `g_signal_connect_after()`.",
 +}
 +
 +FRAGMENT = {
 +    "aliases": "alias",
 +    "bitfields": "flags",
 +    "callbacks": "callback",
 +    "classes": "class",
 +    "constants": "const",
 +    "domains": "error",
 +    "enums": "enum",
 +    "functions": "func",
 +    "function_macros": "func",
 +    "interfaces": "iface",
 +    "structs": "struct",
 +    "unions": "union",
 +}
 +
 +
 +def type_name_to_cname(fqtn, is_pointer=False):
 +    res = []
 +    try:
 +        ns, name = fqtn.split('.', 1)
 +        res.append(ns)
 +        res.append(name)
 +    except ValueError:
 +        res.append(fqtn.replace('.', ''))
 +    if is_pointer:
 +        res.append('*')
 +    return "".join(res)
 +
 +
 +def gen_index_func(func, namespace, md=None):
 +    """Generates a dictionary with the callable metadata required by an index template"""
 +    name = func.name
 +    if getattr(func, "identifier"):
 +        identifier = func.identifier
 +    else:
 +        identifier = None
 +    if func.doc is not None:
 +        summary = utils.preprocess_docs(func.doc.content, namespace, summary=True, md=md)
 +    else:
 +        summary = MISSING_DESCRIPTION
 +    if func.available_since is not None:
 +        available_since = func.available_since
 +    else:
 +        available_since = None
 +    if func.deprecated_since is not None:
 +        (version, msg) = func.deprecated_since
 +        deprecated_since = version
 +    else:
 +        deprecated_since = None
 +    return {
 +        "name": name,
 +        "identifier": identifier,
 +        "summary": summary,
 +        "available_since": available_since,
 +        "deprecated_since": deprecated_since,
 +    }
 +
 +
 +def gen_index_property(prop, namespace, md=None):
 +    name = prop.name
 +    if prop.doc is not None:
 +        summary = utils.preprocess_docs(prop.doc.content, namespace, summary=True, md=md)
 +    else:
 +        summary = MISSING_DESCRIPTION
 +    if prop.available_since is not None:
 +        available_since = prop.available_since
 +    else:
 +        available_since = None
 +    if prop.deprecated_since is not None:
 +        (version, msg) = prop.deprecated_since
 +        deprecated_since = version
 +    else:
 +        deprecated_since = None
 +    return {
 +        "name": name,
 +        "summary": summary,
 +        "available_since": available_since,
 +        "deprecated_since": deprecated_since,
 +    }
 +
 +
 +def gen_index_signal(signal, namespace, md=None):
 +    name = signal.name
 +    if signal.doc is not None:
 +        summary = utils.preprocess_docs(signal.doc.content, namespace, summary=True, md=md)
 +    else:
 +        summary = MISSING_DESCRIPTION
 +    if signal.available_since is not None:
 +        available_since = signal.available_since
 +    else:
 +        available_since = None
 +    if signal.deprecated_since is not None:
 +        (version, msg) = signal.deprecated_since
 +        deprecated_since = version
 +    else:
 +        deprecated_since = None
 +    return {
 +        "name": name,
 +        "summary": summary,
 +        "available_since": available_since,
 +        "deprecated_since": deprecated_since,
 +    }
 +
 +
-         if self.type_cname is None:
-             self.type_cname = type_name_to_cname(prop.target.name, True)
++def gen_index_ancestor(ancestor_type, namespace, config, md=None):
++    ancestor_name = ancestor_type.name
++    if '.' in ancestor_name:
++        ns, ancestor_name = ancestor_name.split('.')
++    else:
++        ns = ancestor_type.namespace or namespace.name
++    res = namespace.repository.find_class(ancestor_name, ns)
++    if res is not None:
++        ancestor_ns = res[0].name
++        ancestor_ctype = res[1].base_ctype
++        ancestor = res[1]
++    else:
++        ancestor_ns = ancestor_type.namespace or namespace.name
++        ancestor_ctype = ancestor_type.base_ctype
++        ancestor = None
++    n_methods = 0
++    methods = []
++    n_properties = 0
++    properties = []
++    n_signals = 0
++    signals = []
++    # We don't use real Template objects, here, because it can be
++    # extremely expensive, unless we add a cache somewhere
++    if ancestor is not None:
++        # Set a hard-limit on the number of methods; base types can
++        # add *a lot* of them; two dozens feel like a good compromise
++        for m in ancestor.methods:
++            is_hidden = config.is_hidden(ancestor_name, "method", m.name)
++            if not is_hidden:
++                n_methods += 1
++        if n_methods > 0 and n_methods < 24:
++            for m in ancestor.methods:
++                if not config.is_hidden(ancestor_name, "method", m.name):
++                    methods.append(gen_index_func(m, namespace, md))
++        for p in ancestor.properties.values():
++            if not config.is_hidden(ancestor_name, "property", p.name):
++                n_properties += 1
++                properties.append(gen_index_property(p, namespace, md))
++        for s in ancestor.signals.values():
++            if not config.is_hidden(ancestor_name, "signal", s.name):
++                n_signals += 1
++                signals.append(gen_index_signal(s, namespace, md))
++    return {
++        "namespace": ancestor_ns,
++        "name": ancestor_name,
++        "fqtn": f"{ancestor_ns}.{ancestor_name}",
++        "type_cname": ancestor_ctype,
++        "properties": properties,
++        "n_properties": n_properties,
++        "signals": signals,
++        "n_signals": n_signals,
++        "methods": methods,
++        "n_methods": n_methods,
++    }
++
++
++def gen_index_implements(iface_type, namespace, config, md=None):
++    iface_name = iface_type.name
++    if '.' in iface_name:
++        ns, iface_name = iface_name.split('.')
++    else:
++        ns = iface_type.namespace or namespace.name
++    res = namespace.repository.find_interface(iface_name, ns)
++    if res is not None:
++        iface_ns = res[0].name
++        iface_ctype = res[1].base_ctype
++        iface = res[1]
++    else:
++        iface_ns = iface_type.namespace or namespace.name
++        iface_ctype = iface_type.base_ctype
++        iface = None
++    n_methods = 0
++    methods = []
++    n_properties = 0
++    properties = []
++    n_signals = 0
++    signals = []
++    if iface is not None:
++        # Set a hard-limit on the number of methods; base types can
++        # add *a lot* of them; two dozens feel like a good compromise
++        for m in iface.methods:
++            is_hidden = config.is_hidden(iface_name, "method", m.name)
++            if not is_hidden:
++                n_methods += 1
++        if n_methods > 0 and n_methods < 24:
++            for m in iface.methods:
++                if not config.is_hidden(iface_name, "method", m.name):
++                    methods.append(gen_index_func(m, namespace, md))
++        for p in iface.properties.values():
++            if not config.is_hidden(iface_name, "property", p.name):
++                n_properties += 1
++                properties.append(gen_index_property(p, namespace, md))
++        for s in iface.signals.values():
++            if not config.is_hidden(iface.name, "signal", s.name):
++                n_signals += 1
++                signals.append(gen_index_signal(s, namespace, md))
++    return {
++        "namespace": iface_ns,
++        "name": iface_name,
++        "fqtn": f"{iface_ns}.{iface_name}",
++        "type_cname": iface_ctype,
++        "properties": properties,
++        "n_properties": n_properties,
++        "signals": signals,
++        "n_signals": n_signals,
++        "methods": methods,
++        "n_methods": n_methods,
++    }
++
++
++def gen_type_link(repository, namespace, name, ctype=None):
++    res = repository.find_type(name, ns=namespace)
++    if res is None:
++        if ctype is not None:
++            return f"<code>{ctype}</code>"
++        elif name in ['utf8', 'filename']:
++            return "<code>char*</code>"
++        else:
++            return f"<code>{name}</code>"
++
++    ns, t = res
++    if t.is_fundamental:
++        return f"<code>{t.ctype}</code>"
++
++    if isinstance(t, gir.Alias):
++        link = f"alias.{name}.html"
++    elif isinstance(t, gir.BitField):
++        link = f"flags.{name}.html"
++    elif isinstance(t, gir.Callback):
++        link = f"callback.{name}.html"
++    elif isinstance(t, gir.Class):
++        link = f"class.{name}.html"
++    elif isinstance(t, gir.ErrorDomain):
++        link = f"error.{name}.html"
++    elif isinstance(t, gir.Enumeration):
++        link = f"enum.{name}.html"
++    elif isinstance(t, gir.Interface):
++        link = f"iface.{name}.html"
++    elif isinstance(t, gir.Record):
++        link = f"struct.{name}.html"
++    elif isinstance(t, gir.Union):
++        link = f"union.{name}.html"
++    else:
++        return f"<code>{t.ctype}</code>"
++
++    text = f"<code>{t.ctype}</code>"
++    if ns.name == repository.namespace.name:
++        href = f'href="{link}"'
++        css_class = ""
++        data_link = ""
++        data_ns = ""
++    else:
++        href = 'href="javascript:void(0)"'
++        css_class = ' class="external"'
++        data_link = f' data-link="{link}"'
++        data_ns = f' data-namespace="{ns.name}"'
++
++    return f"<a {href}{data_link}{data_ns}{css_class}>{text}</a>"
 +
 +
 +class TemplateConstant:
 +    def __init__(self, namespace, const):
 +        self.value = const.value
 +        self.identifier = const.ctype
 +        self.type_cname = const.target.ctype
 +        self.namespace = namespace.name
 +        self.name = const.name
 +        self.fqtn = f"{namespace.name}.{const.name}"
 +
 +        if const.doc is not None:
 +            self.summary = utils.preprocess_docs(const.doc.content, namespace, summary=True)
 +            self.description = utils.preprocess_docs(const.doc.content, namespace)
 +            filename = const.doc.filename
 +            if filename.startswith('../'):
 +                filename = filename.replace('../', '')
 +            line = const.doc.line
 +            const.docs_location = (filename, line)
 +        else:
 +            self.description = MISSING_DESCRIPTION
 +
 +        self.stability = const.stability
 +        self.attributes = const.attributes
 +        self.available_since = const.available_since
 +        if const.deprecated_since is not None:
 +            (version, msg) = const.deprecated_since
 +            self.deprecated_since = {
 +                "version": version,
 +                "message": utils.preprocess_docs(msg, namespace),
 +            }
 +        else:
 +            self.deprecated_since = None
 +
 +        self.introspectable = const.introspectable
 +        self.hierarchy_svg = None
 +
 +    @property
 +    def c_decl(self):
 +        return utils.code_highlight(f"#define {self.identifier} {self.value}")
 +
 +
 +class TemplateProperty:
 +    def __init__(self, namespace, type_, prop):
 +        self.name = prop.name
 +        self.type_name = prop.target.name
 +        self.type_cname = prop.target.ctype
-         if self.type_name is not None:
++        self.is_fundamental = prop.target.is_fundamental
++        self.is_array = isinstance(prop.target, gir.ArrayType)
++        self.is_list = isinstance(prop.target, gir.ListType)
++        self.is_list_model = prop.target.name in ['Gio.ListModel', 'GListModel']
 +        self.readable = prop.readable
 +        self.writable = prop.writable
 +        self.construct = prop.construct
 +        self.construct_only = prop.construct_only
++        if self.type_cname is None:
++            if prop.target.is_fundamental:
++                self.type_cname = prop.target.name
++            elif self.is_array or self.is_list:
++                value_type = prop.target.value_type
++                if value_type.name in ['utf8', 'filename']:
++                    self.type_cname = 'gchar*'
++                elif value_type.ctype is None:
++                    self.type_cname = type_name_to_cname(value_type.name, True)
++                else:
++                    self.type_cname = value_type.ctype
++            else:
++                self.type_cname = type_name_to_cname(prop.target.name, True)
 +        if prop.doc is not None:
 +            self.summary = utils.preprocess_docs(prop.doc.content, namespace, summary=True)
 +            self.description = utils.preprocess_docs(prop.doc.content, namespace)
 +            filename = prop.doc.filename
 +            if filename.startswith('../'):
 +                filename = filename.replace('../', '')
 +            line = prop.doc.line
 +            self.docs_location = (filename, line)
 +        else:
 +            self.description = MISSING_DESCRIPTION
 +
 +        self.stability = prop.stability
 +        self.available_since = prop.available_since
 +        if prop.deprecated_since is not None:
 +            (version, msg) = prop.deprecated_since
 +            self.deprecated_since = {
 +                "version": version,
 +                "message": utils.preprocess_docs(msg, namespace),
 +            }
 +        else:
 +            self.deprecated_since = None
 +
 +        self.introspectable = prop.introspectable
 +
 +        def transform_set_attribute(namespace, prop, setter_func):
 +            if setter_func is None:
 +                log.warning(f"Missing value in the set attribute for {prop.name}")
 +                return None
 +            t = namespace.find_symbol(setter_func)
 +            if t is None:
 +                log.warning(f"Invalid Property.set attribute for {prop.name}: {setter_func}")
 +                return setter_func
 +            if not (isinstance(t, gir.Class) or isinstance(t, gir.Interface)):
 +                log.warning(f"Invalid setter function {setter_func} for property {namespace.name}.{t.name}:{prop.name}")
 +                return setter_func
 +            func_name = setter_func.replace(namespace.symbol_prefix[0] + '_', '')
 +            func_name = func_name.replace(t.symbol_prefix + '_', '')
 +            href = f"method.{t.name}.{func_name}.html"
 +            return Markup(f"<a href=\"{href}\"><code>{setter_func}</code></a>")
 +
 +        def transform_get_attribute(namespace, prop, getter_func):
 +            if getter_func is None:
 +                log.warning(f"Missing value in the get attribute for {prop.name}")
 +                return None
 +            t = namespace.find_symbol(getter_func)
 +            if t is None:
 +                log.warning(f"Invalid Property.get attribute for {prop.name}: {getter_func}")
 +                return getter_func
 +            if not (isinstance(t, gir.Class) or isinstance(t, gir.Interface)):
 +                log.warning(f"Invalid getter function {getter_func} for property {namespace.name}.{t.name}:{prop.name}")
 +                return getter_func
 +            func_name = getter_func.replace(namespace.symbol_prefix[0] + '_', '')
 +            func_name = func_name.replace(t.symbol_prefix + '_', '')
 +            href = f"method.{t.name}.{func_name}.html"
 +            return Markup(f"<a href=\"{href}\"><code>{getter_func}</code></a>")
 +
++        def transform_default_attribute(namespace, prop, default_value):
++            if default_value is None:
++                log.warning(f"Missing value in the default attribute for {prop.name}")
++                return None
++            return Markup(f"<code>{default_value}</code>")
++
 +        ATTRIBUTE_NAMES = {
 +            "org.gtk.Property.set": {
 +                "label": "Setter method",
 +                "transform": transform_set_attribute,
 +            },
 +            "org.gtk.Property.get": {
 +                "label": "Getter method",
 +                "transform": transform_get_attribute,
 +            },
++            "org.gtk.Property.default": {
++                "label": "Default value",
++                "transform": transform_default_attribute,
++            },
 +        }
 +
 +        self.attributes = {}
 +        for name in (prop.attributes or {}):
 +            value = prop.attributes[name]
 +            if name in ATTRIBUTE_NAMES:
 +                label = ATTRIBUTE_NAMES[name].get("label")
 +                transform = ATTRIBUTE_NAMES[name].get("transform")
 +                if transform is not None:
 +                    self.attributes[label] = transform(namespace, prop, value)
 +            else:
 +                self.attributes[name] = value
-             if name.startswith(namespace.name):
-                 self.link = gen_type_link(namespace, name[len(namespace.name) + 1:])
++
++        def gen_method_link(ns, t, method):
++            for m in t.methods:
++                if m.name == method:
++                    href = f"method.{t.name}.{m.name}.html"
++                    return Markup(f'<a href="{href}"><code>{m.identifier}()</code></a>')
++            return None
++
++        if prop.setter is not None:
++            link = gen_method_link(namespace, type_, prop.setter)
++            if link is not None:
++                self.attributes["Setter method"] = link
++        if prop.getter is not None:
++            link = gen_method_link(namespace, type_, prop.getter)
++            if link is not None:
++                self.attributes["Getter method"] = link
++
++        if self.is_array:
++            name = prop.target.value_type.name
++        elif self.is_list:
++            name = prop.target.value_type.name
++        elif self.type_name is not None:
 +            name = self.type_name
 +        else:
 +            name = None
 +        if name is not None:
-         self.type_cname = argument.target.ctype
-         if self.type_cname is None:
-             self.type_cname = type_name_to_cname(argument.target.name, True)
++            if self.is_fundamental:
++                self.link = f"<code>{self.type_cname}</code>"
++            elif self.is_array or self.is_list:
++                self.link = f"<code>{self.type_cname}</code>"
++            else:
++                if '.' in name:
++                    ns, name = name.split('.')
++                else:
++                    ns = namespace.name
++                self.link = gen_type_link(namespace.repository, ns, name, self.type_cname)
 +
 +    @property
 +    def c_decl(self):
 +        flags = []
 +        if self.readable:
 +            flags += ['read']
 +        if self.writable:
 +            flags += ['write']
 +        if self.construct:
 +            flags += ['construct']
 +        if self.construct_only:
 +            flags += ['construct-only']
 +        flags = ", ".join(flags)
 +        return f"property {self.name}: {self.type_name} [ {flags} ]"
 +
 +
 +class TemplateArgument:
 +    def __init__(self, namespace, call, argument):
 +        self.name = argument.name
 +        self.type_name = argument.target.name
-         if self.type_name in ['utf8', 'filename']:
-             self.string_note = STRING_TYPES[self.type_name]
++        if isinstance(call, gir.FunctionMacro):
++            self.type_cname = '-'
++        else:
++            self.type_cname = argument.target.ctype
++            if self.type_cname is None:
++                self.type_cname = type_name_to_cname(argument.target.name, True)
 +        self.is_array = isinstance(argument.target, gir.ArrayType)
 +        self.is_list = isinstance(argument.target, gir.ListType)
 +        self.is_map = isinstance(argument.target, gir.MapType)
 +        self.is_varargs = isinstance(argument.target, gir.VarArgs)
 +        self.is_macro = isinstance(call, gir.FunctionMacro)
++        self.is_list_model = self.type_name in ['Gio.ListModel', 'GListModel']
++        self.is_fundamental = argument.target.is_fundamental
 +        self.transfer = argument.transfer or 'none'
 +        if isinstance(call, gir.Method):
 +            self.transfer_note = METHOD_ARG_TRANSFER_MODES[argument.transfer or 'none']
 +        else:
 +            self.transfer_note = ARG_TRANSFER_MODES[argument.transfer or 'none']
 +        self.direction = argument.direction or 'in'
 +        self.direction_note = DIRECTION_MODES[argument.direction]
 +        self.optional = argument.optional
 +        self.nullable = argument.nullable
 +        self.scope = SCOPE_MODES[argument.scope or 'none']
 +        self.introspectable = argument.introspectable
-             if name.startswith(namespace.name):
-                 self.link = gen_type_link(namespace, name[len(namespace.name) + 1:])
 +        if argument.closure != -1:
 +            self.closure = call.parameters[argument.closure]
 +        else:
 +            self.closure = None
 +        if self.is_array:
 +            self.value_type = argument.target.value_type.name
 +            self.value_type_cname = argument.target.value_type.ctype
 +            self.fixed_size = argument.target.fixed_size
 +            self.zero_terminated = argument.target.zero_terminated
 +            self.len_arg = argument.target.length != -1 and call.parameters[argument.target.length].name
 +        if self.is_list:
 +            self.value_type = argument.target.value_type.name
 +            self.value_type_cname = argument.target.value_type.ctype
++        if self.is_list_model:
++            self.value_type = argument.attributes.get('element-type', 'GObject')
++        if self.type_name in ['utf8', 'filename']:
++            self.string_note = STRING_TYPES[self.type_name]
++        elif self.is_array or self.is_list:
++            if self.value_type in ['utf8', 'filename']:
++                self.string_note = STRING_ELEMENT_TYPES[self.value_type]
 +        if argument.doc is not None:
 +            self.summary = utils.preprocess_docs(argument.doc.content, namespace, summary=True)
 +            self.description = utils.preprocess_docs(argument.doc.content, namespace)
 +        else:
 +            self.description = MISSING_DESCRIPTION
 +        if self.is_array:
 +            name = self.value_type
 +        elif self.is_list:
 +            name = self.value_type
 +        elif self.type_name is not None:
 +            name = self.type_name
 +        else:
 +            name = None
 +        if name is not None:
-                 if self.is_array:
-                     self.link = f"<code>{self.value_type_cname}</code>"
-                 elif self.is_list:
-                     self.link = f"<code>{self.value_type_cname}</code>"
++            if self.is_fundamental:
++                self.link = f"<code>{self.type_cname}</code>"
++            elif self.is_array:
++                self.link = f"<code>{self.value_type_cname}</code>"
++            elif self.is_list:
++                self.link = f"<code>{self.value_type_cname}</code>"
++            elif self.is_list_model:
++                self.link = f"<code>{self.value_type}</code>"
 +            else:
-             if name.startswith(namespace.name):
-                 self.link = gen_type_link(namespace, name[len(namespace.name) + 1:])
++                if '.' in name:
++                    ns, name = name.split('.')
++                else:
++                    ns = namespace.name
++                self.link = gen_type_link(namespace.repository, ns, name, self.type_cname)
 +
 +    @property
 +    def is_pointer(self):
 +        return '*' in self.type_cname
 +
 +    @property
 +    def c_decl(self):
 +        if self.is_varargs:
 +            return "..."
 +        elif self.is_macro:
 +            return f"{self.name}"
 +        else:
 +            return f"{self.type_cname} {self.name}"
 +
 +
 +class TemplateReturnValue:
 +    def __init__(self, namespace, call, retval):
 +        self.name = retval.name
 +        self.type_name = retval.target.name
 +        self.type_cname = retval.target.ctype
++        self.is_fundamental = retval.target.is_fundamental
 +        if self.type_cname is None:
 +            self.type_cname = type_name_to_cname(retval.target.name, True)
 +        self.is_array = isinstance(retval.target, gir.ArrayType)
 +        self.is_list = isinstance(retval.target, gir.ListType)
++        self.is_list_model = self.type_name in ['Gio.ListModel', 'GListModel']
 +        self.transfer = retval.transfer or 'none'
 +        if isinstance(call, gir.Method):
 +            self.transfer_note = METHOD_RETVAL_TRANSFER_MODES[retval.transfer or 'none']
 +        else:
 +            self.transfer_note = RETVAL_TRANSFER_MODES[retval.transfer or 'none']
 +        self.nullable = retval.nullable
 +        if self.is_array:
 +            self.value_type = retval.target.value_type.name
 +            self.value_type_cname = retval.target.value_type.ctype
 +            self.fixed_size = retval.target.fixed_size
 +            self.zero_terminated = retval.target.zero_terminated
 +            self.len_arg = retval.target.length != -1 and call.parameters[retval.target.length].name
 +        if self.is_list:
 +            self.value_type = retval.target.value_type.name
 +            self.value_type_cname = retval.target.value_type.ctype
++        if self.is_list_model:
++            self.value_type = retval.attributes.get('element-type', 'GObject')
 +        if self.type_name in ['utf8', 'filename']:
 +            self.string_note = STRING_TYPES[self.type_name]
++        elif self.is_array or self.is_list:
++            if self.value_type in ['utf8', 'filename']:
++                self.string_note = STRING_ELEMENT_TYPES[self.value_type]
 +        if retval.doc is not None:
 +            self.summary = utils.preprocess_docs(retval.doc.content, namespace, summary=True)
 +            self.description = utils.preprocess_docs(retval.doc.content, namespace)
 +        else:
 +            self.description = MISSING_DESCRIPTION
 +        self.introspectable = retval.introspectable
 +        if self.is_array:
 +            name = self.value_type
 +        elif self.is_list:
 +            name = self.value_type
++        elif self.is_list_model:
++            name = self.value_type
 +        elif self.type_name is not None:
 +            name = self.type_name
 +        else:
 +            name = None
 +        if name is not None:
-                 if self.is_array:
-                     self.link = f"<code>{self.value_type_cname}</code>"
-                 elif self.is_list:
-                     self.link = f"<code>{self.value_type_cname}</code>"
++            if self.is_fundamental:
++                self.link = f"<code>{self.type_cname}</code>"
++            elif self.is_array:
++                self.link = f"<code>{self.value_type_cname}</code>"
++            elif self.is_list:
++                self.link = f"<code>{self.value_type_cname}</code>"
++            elif self.is_list_model:
++                self.link = f"<code>{self.value_type}</code>"
 +            else:
-         res += [f"  {self.type_cname} self,"]
++                if '.' in name:
++                    ns, name = name.split('.')
++                else:
++                    ns = namespace.name
++                self.link = gen_type_link(namespace.repository, ns, name, self.type_cname)
 +
 +    @property
 +    def is_pointer(self):
 +        return '*' in self.type_cname
 +
 +
 +class TemplateSignal:
 +    def __init__(self, namespace, type_, signal):
 +        self.name = signal.name
 +        self.type_cname = type_.base_ctype
 +        self.identifier = signal.name.replace("-", "_")
 +
 +        if signal.doc is not None:
 +            self.summary = utils.preprocess_docs(signal.doc.content, namespace, summary=True)
 +            self.description = utils.preprocess_docs(signal.doc.content, namespace)
 +            filename = signal.doc.filename
 +            if filename.startswith('../'):
 +                filename = filename.replace('../', '')
 +            line = signal.doc.line
 +            self.docs_location = (filename, line)
 +        else:
 +            self.description = MISSING_DESCRIPTION
 +
 +        self.is_detailed = signal.detailed
 +        self.is_action = signal.action
 +        self.no_recurse = signal.no_recurse
 +        self.no_hooks = signal.no_hooks
 +        if signal.when:
 +            self.when = utils.preprocess_docs(SIGNAL_WHEN[signal.when], namespace)
 +
 +        self.arguments = []
 +        for arg in signal.parameters:
 +            self.arguments.append(TemplateArgument(namespace, signal, arg))
 +
 +        self.return_value = None
 +        if not isinstance(signal.return_value.target, gir.VoidType):
 +            self.return_value = TemplateReturnValue(namespace, signal, signal.return_value)
 +
 +        self.stability = signal.stability
 +        self.attributes = signal.attributes
 +        self.available_since = signal.available_since
 +        if signal.deprecated_since is not None:
 +            (version, msg) = signal.deprecated_since
 +            self.deprecated_since = {
 +                "version": version,
 +                "message": utils.preprocess_docs(msg, namespace),
 +            }
 +        else:
 +            self.deprecated_since = None
 +
 +        self.introspectable = signal.introspectable
 +
 +    @property
 +    def c_decl(self):
 +        res = []
 +        if self.return_value is None:
 +            res += ["void"]
 +        else:
 +            res += [f"{self.return_value.type_cname}"]
 +        res += [f"{self.identifier} ("]
-         self.class_type_cname = cls.type_struct
++        res += [f"  {self.type_cname}* self,"]
 +        for arg in self.arguments:
 +            res += [f"  {arg.c_decl},"]
 +        res += ["  gpointer user_data"]
 +        res += [")"]
 +        return utils.code_highlight("\n".join(res))
 +
 +
 +class TemplateMethod:
 +    def __init__(self, namespace, type_, method):
 +        self.name = method.name
 +        self.identifier = method.identifier
 +
 +        if method.doc is not None:
 +            self.summary = utils.preprocess_docs(method.doc.content, namespace, summary=True)
 +            self.description = utils.preprocess_docs(method.doc.content, namespace)
 +            filename = method.doc.filename
 +            line = method.doc.line
 +            if filename.startswith('../'):
 +                filename = filename.replace('../', '')
 +            self.docs_location = (filename, line)
 +        else:
 +            self.description = MISSING_DESCRIPTION
 +
 +        self.throws = method.throws
 +
 +        self.instance_parameter = TemplateArgument(namespace, method, method.instance_param)
 +
 +        self.arguments = []
 +        for arg in method.parameters:
 +            self.arguments.append(TemplateArgument(namespace, method, arg))
 +
 +        self.return_value = None
 +        if not isinstance(method.return_value.target, gir.VoidType):
 +            self.return_value = TemplateReturnValue(namespace, method, method.return_value)
 +
 +        self.stability = method.stability
 +        self.available_since = method.available_since
 +        if method.deprecated_since is not None:
 +            (version, msg) = method.deprecated_since
 +            self.deprecated_since = {
 +                "version": version,
 +                "message": utils.preprocess_docs(msg, namespace),
 +            }
 +        else:
 +            self.deprecated_since = None
 +
 +        if method.source_position is not None:
 +            filename, line = method.source_position
 +            if filename.startswith('../'):
 +                filename = filename.replace('../', '')
 +            self.source_location = (filename, line)
 +
 +        self.introspectable = method.introspectable
 +
 +        def transform_property_attribute(namespace, type_, method, value):
 +            if value in type_.properties:
 +                text = f"{namespace.name}.{type_.name}:{value}"
 +                href = f"property.{type_.name}.{value}.html"
 +                return Markup(f"<a href=\"{href}\"><code>{text}</code></a>")
 +            log.warning(f"Property {value} linked to method {method.name} not found in {namespace.name}.{type_.name}")
 +            return value
 +
 +        def transform_signal_attribute(namespace, type_, method, value):
 +            if value in type_.signals:
 +                text = f"{namespace.name}.{type_.name}::{value}"
 +                href = f"signal.{type_.name}.{value}.html"
 +                return Markup(f"<a href=\"{href}\"><code>{text}</code></a>")
 +            log.warning(f"Signal {value} linked to method {method.name} not found in {namespace.name}.{type_.name}")
 +            return value
 +
 +        ATTRIBUTE_NAMES = {
 +            "org.gtk.Method.set_property": {
 +                "label": "Sets property",
 +                "transform": transform_property_attribute,
 +            },
 +            "org.gtk.Method.get_property": {
 +                "label": "Gets property",
 +                "transform": transform_property_attribute,
 +            },
 +            "org.gtk.Method.signal": {
 +                "label": "Emits signal",
 +                "transform": transform_signal_attribute,
 +            }
 +        }
 +
 +        self.attributes = {}
 +        for name in (method.attributes or {}):
 +            value = method.attributes[name]
 +            if name in ATTRIBUTE_NAMES:
 +                label = ATTRIBUTE_NAMES[name].get("label")
 +                transform = ATTRIBUTE_NAMES[name].get("transform")
 +                if transform is not None:
 +                    self.attributes[label] = transform(namespace, type_, method, value)
 +            else:
 +                self.attributes[name] = value
 +
++        def gen_property_link(namespace, t, prop_name):
++            if prop_name not in t.properties:
++                return None
++            prop = t.properties[prop_name]
++            text = f"{namespace.name}.{t.name}:{prop.name}"
++            href = f"property.{t.name}.{prop.name}.html"
++            return Markup(f'<a href="{href}"><code>{text}</code></a>')
++
++        if isinstance(method, gir.Method):
++            if method.set_property is not None:
++                link = gen_property_link(namespace, type_, method.set_property)
++                if link is not None:
++                    self.attributes["Sets property"] = link
++            if method.get_property is not None:
++                link = gen_property_link(namespace, type_, method.get_property)
++                if link is not None:
++                    self.attributes["Gets property"] = link
++
 +    @property
 +    def c_decl(self):
 +        res = []
 +        if self.return_value is None:
 +            res += ["void"]
 +        else:
 +            res += [f"{self.return_value.type_cname}"]
 +        if self.identifier is not None:
 +            res += [f"{self.identifier} ("]
 +        else:
 +            res += [f"{self.name} ("]
 +        n_args = len(self.arguments)
 +        if n_args == 0:
 +            res += [f"  {self.instance_parameter.type_cname} {self.instance_parameter.name}"]
 +        else:
 +            res += [f"  {self.instance_parameter.type_cname} {self.instance_parameter.name},"]
 +            for (idx, arg) in enumerate(self.arguments):
 +                if idx == n_args - 1 and not self.throws:
 +                    res += [f"  {arg.c_decl}"]
 +                else:
 +                    res += [f"  {arg.c_decl},"]
 +        if self.throws:
 +            res += ["  GError** error"]
 +        res += [")"]
 +        return utils.code_highlight("\n".join(res))
 +
 +
 +class TemplateClassMethod:
 +    def __init__(self, namespace, cls, method):
 +        self.name = method.name
 +        self.identifier = method.identifier
-         if n_args == 1:
-             res += [f"  {self.class_type_cname}* self"]
++        self.class_type_cname = namespace.identifier_prefix[0] + cls.type_struct
 +
 +        self.throws = method.throws
 +
 +        if method.doc is not None:
 +            self.summary = utils.preprocess_docs(method.doc.content, namespace, summary=True)
 +            self.description = utils.preprocess_docs(method.doc.content, namespace)
 +            filename = method.doc.filename
 +            line = method.doc.line
 +            if filename.startswith('../'):
 +                filename = filename.replace('../', '')
 +            self.docs_location = (filename, line)
 +        else:
 +            self.description = MISSING_DESCRIPTION
 +
++        self.instance_parameter = TemplateArgument(namespace, method, method.instance_param)
++
 +        self.arguments = []
 +        for arg in method.parameters:
 +            self.arguments.append(TemplateArgument(namespace, method, arg))
 +
 +        self.return_value = None
 +        if not isinstance(method.return_value.target, gir.VoidType):
 +            self.return_value = TemplateReturnValue(namespace, method, method.return_value)
 +
 +        self.stability = method.stability
 +        self.attributes = method.attributes
 +        self.available_since = method.available_since
 +        if method.deprecated_since is not None:
 +            (version, msg) = method.deprecated_since
 +            self.deprecated_since = {
 +                "version": version,
 +                "message": utils.preprocess_docs(msg, namespace),
 +            }
 +        else:
 +            self.deprecated_since = None
 +
 +        if method.source_position is not None:
 +            filename, line = method.source_position
 +            if filename.startswith('../'):
 +                filename = filename.replace('../', '')
 +            self.source_location = (filename, line)
 +
 +        self.introspectable = method.introspectable
 +
 +    @property
 +    def c_decl(self):
 +        res = []
 +        if self.return_value is None:
 +            res += ["void"]
 +        else:
 +            res += [f"{self.return_value.type_cname}"]
 +        res += [f"{self.identifier} ("]
 +        n_args = len(self.arguments)
-             res += [f"  {self.class_type_cname}* self,"]
-             for (idx, arg) in enumerate(self.arguments, start=1):
++        if n_args == 0:
++            res += [f"  {self.instance_parameter.type_cname} {self.instance_parameter.name}"]
 +        else:
-             res += [f"{self.identifier} ("]
++            res += [f"  {self.instance_parameter.type_cname} {self.instance_parameter.name},"]
++            for (idx, arg) in enumerate(self.arguments):
 +                if idx == n_args - 1 and not self.throws:
 +                    res += [f"  {arg.c_decl}"]
 +                else:
 +                    res += [f"  {arg.c_decl},"]
 +        if self.throws:
 +            res += ["  GError** error"]
 +        res += [")"]
 +        return utils.code_highlight("\n".join(res))
 +
 +
 +class TemplateFunction:
 +    def __init__(self, namespace, func):
 +        self.identifier = func.identifier
 +        self.name = func.name
 +        self.namespace = namespace.name
 +
 +        self.is_macro = isinstance(func, gir.FunctionMacro)
 +
 +        self.throws = func.throws
 +
 +        if func.doc is not None:
 +            self.summary = utils.preprocess_docs(func.doc.content, namespace, summary=True)
 +            self.description = utils.preprocess_docs(func.doc.content, namespace)
 +            filename = func.doc.filename
 +            line = func.doc.line
 +            if filename.startswith('../'):
 +                filename = filename.replace('../', '')
 +            self.docs_location = (filename, line)
 +        else:
 +            self.description = MISSING_DESCRIPTION
 +
 +        self.arguments = []
 +        for arg in func.parameters:
 +            self.arguments.append(TemplateArgument(namespace, func, arg))
 +
 +        self.return_value = None
 +        if not isinstance(func.return_value.target, gir.VoidType):
 +            self.return_value = TemplateReturnValue(namespace, func, func.return_value)
 +
 +        self.stability = func.stability
 +        self.attributes = func.attributes
 +        self.available_since = func.available_since
 +        if func.deprecated_since is not None:
 +            (version, msg) = func.deprecated_since
 +            self.deprecated_since = {
 +                "version": version,
 +                "message": utils.preprocess_docs(msg, namespace),
 +            }
 +        else:
 +            self.deprecated_since = None
 +
 +        if func.source_position is not None:
 +            filename, line = func.source_position
 +            if filename.startswith('../'):
 +                filename = filename.replace('../', '')
 +            self.source_location = (filename, line)
 +
 +        self.introspectable = func.introspectable
 +
 +    @property
 +    def c_decl(self):
 +        res = []
 +        if self.is_macro:
 +            res += [f"#define {self.identifier} ("]
 +        else:
 +            if self.return_value is None:
 +                res += ["void"]
 +            else:
 +                res += [f"{self.return_value.type_cname}"]
 +            res += [f"{self.identifier} ("]
 +        n_args = len(self.arguments)
 +        if n_args == 0:
 +            res += ["  void"]
 +        else:
 +            for (idx, arg) in enumerate(self.arguments):
 +                if idx == n_args - 1 and not self.throws:
 +                    res += [f"  {arg.c_decl}"]
 +                else:
 +                    res += [f"  {arg.c_decl},"]
 +        if self.throws:
 +            res += ["  GError** error"]
 +        res += [")"]
 +        return utils.code_highlight("\n".join(res))
 +
 +
 +class TemplateCallback:
 +    def __init__(self, namespace, cb, field=False):
 +        self.name = cb.name
++        self.type_cname = cb.ctype
 +        self.identifier = cb.name.replace("-", "_")
 +        self.field = field
 +
 +        if cb.doc is not None:
 +            self.summary = utils.preprocess_docs(cb.doc.content, namespace, summary=True)
 +            self.description = utils.preprocess_docs(cb.doc.content, namespace)
 +            filename = cb.doc.filename
 +            line = cb.doc.line
 +            if filename.startswith('../'):
 +                filename = filename.replace('../', '')
 +            self.docs_location = (filename, line)
 +        else:
 +            self.description = MISSING_DESCRIPTION
 +
 +        self.arguments = []
 +        for arg in cb.parameters:
 +            self.arguments.append(TemplateArgument(namespace, cb, arg))
 +
 +        self.return_value = None
 +        if not isinstance(cb.return_value.target, gir.VoidType):
 +            self.return_value = TemplateReturnValue(namespace, cb, cb.return_value)
 +
 +        self.throws = cb.throws
 +
 +        self.stability = cb.stability
 +        self.attributes = cb.attributes
 +        self.available_since = cb.available_since
 +        if cb.deprecated_since is not None:
 +            (version, msg) = cb.deprecated_since
 +            self.deprecated_since = {
 +                "version": version,
 +                "message": utils.preprocess_docs(msg, namespace),
 +            }
 +        else:
 +            self.deprecated_since = None
 +
 +        self.introspectable = cb.introspectable
 +
 +    @property
 +    def c_decl(self):
 +        res = []
 +        if self.field:
 +            arg_indent = "    "
 +        else:
 +            arg_indent = "  "
 +        if self.return_value is None:
 +            retval = "void"
 +        else:
 +            retval = f"{self.return_value.type_cname}"
 +        if self.field:
 +            res += [f"{retval} (* {self.identifier}) ("]
 +        else:
 +            res += [retval]
-     def __init__(self, namespace, interface):
++            res += [f"(* {self.type_cname}) ("]
 +        n_args = len(self.arguments)
 +        if n_args == 0:
 +            res += ["void"]
 +        else:
 +            for (idx, arg) in enumerate(self.arguments):
 +                if idx == n_args - 1 and not self.throws:
 +                    res += [f"{arg_indent}{arg.type_cname} {arg.name}"]
 +                else:
 +                    res += [f"{arg_indent}{arg.type_cname} {arg.name},"]
 +        if self.throws:
 +            res += [f"{arg_indent}GError** error"]
 +        if self.field:
 +            res += ["  )"]
 +        else:
 +            res += [")"]
 +        if self.field:
 +            return "\n".join(res)
 +        else:
 +            return utils.code_highlight("\n".join(res))
 +
 +
 +class TemplateField:
 +    def __init__(self, namespace, field):
 +        self.name = field.name
 +        if field.target is not None:
 +            if isinstance(field.target, gir.Callback):
 +                self.is_callback = True
 +                self.type_name: field.target.name
 +                self.type_cname = TemplateCallback(namespace, field.target, field=True).c_decl
 +            else:
 +                self.is_callback = False
 +                self.type_name = field.target.name
 +                self.type_cname = field.target.ctype
 +        else:
 +            self.is_callback = False
 +            self.type_name = 'none'
 +            self.type_cname = 'gpointer'
 +        self.private = field.private
 +        if field.doc is not None:
 +            self.description = utils.preprocess_docs(field.doc.content, namespace)
 +        else:
 +            self.description = MISSING_DESCRIPTION
 +        self.introspectable = field.introspectable
 +
 +
 +class TemplateInterface:
-                 self.properties.append(gen_index_property(prop, namespace, md))
++    def __init__(self, namespace, interface, config):
 +        if isinstance(interface, gir.Interface):
 +            if '.' in interface.name:
 +                self.namespace, self.name = interface.name.split('.')
 +                self.fqtn = interface.name
 +            else:
 +                self.namespace = interface.namespace
 +                self.name = interface.name
 +                self.fqtn = f"{self.namespace}.{self.name}"
 +        elif isinstance(interface, gir.Type):
 +            if '.' in interface.name:
 +                self.namespace, self.name = interface.name.split('.')
 +            else:
 +                self.namespace = interface.namespace or namespace.name
 +                self.name = interface.name
 +            self.fqtn = f"{self.namespace}.{self.name}"
 +            self.requires = "GObject.Object"
 +            self.link_prefix = "iface"
 +            self.description = MISSING_DESCRIPTION
 +            return
 +
 +        md = markdown.Markdown(extensions=utils.MD_EXTENSIONS,
 +                               extension_configs=utils.MD_EXTENSIONS_CONF)
 +
 +        requires = interface.prerequisite
 +        if requires is None:
 +            self.requires_namespace = "GObject"
 +            self.requires_name = "Object"
++            self.requires_ctype = "GObject"
 +        elif '.' in requires.name:
 +            self.requires_namespace, self.requires_name = requires.name.split('.')
++            self.requires_ctype = requires.ctype
 +        else:
 +            self.requires_namespace = requires.namespace or namespace.name
 +            self.requires_name = requires.name
++            self.requires_ctype = requires.ctype
 +
 +        self.requires_fqtn = f"{self.requires_namespace}.{self.requires_name}"
++        log.debug(f"Preqrequisite for {self.fqtn}: {self.requires_fqtn}")
 +
 +        self.symbol_prefix = f"{namespace.symbol_prefix[0]}_{interface.symbol_prefix}"
 +        self.type_cname = interface.base_ctype
 +
 +        self.link_prefix = "iface"
 +
 +        if interface.doc is not None:
 +            self.summary = utils.preprocess_docs(interface.doc.content, namespace, summary=True, md=md)
 +            self.description = utils.preprocess_docs(interface.doc.content, namespace, md=md)
 +            filename = interface.doc.filename
 +            line = interface.doc.line
 +            if filename.startswith('../'):
 +                filename = filename.replace('../', '')
 +            self.docs_location = (filename, line)
 +        else:
 +            self.description = MISSING_DESCRIPTION
 +
 +        self.stability = interface.stability
 +        self.attributes = interface.attributes
 +        self.available_since = interface.available_since
 +        if interface.deprecated_since is not None:
 +            (version, msg) = interface.deprecated_since
 +            self.deprecated_since = {
 +                "version": version,
 +                "message": utils.preprocess_docs(msg, namespace),
 +            }
 +        else:
 +            self.deprecated_since = None
 +
 +        self.introspectable = interface.introspectable
 +
 +        self.class_name = interface.type_struct
 +
 +        self.class_struct = namespace.find_record(interface.type_struct)
 +        if self.class_struct is not None:
 +            self.class_fields = []
 +            self.class_methods = []
 +
 +            for field in self.class_struct.fields:
 +                if not field.private:
 +                    self.class_fields.append(TemplateField(namespace, field))
 +
 +            for method in self.class_struct.methods:
 +                self.class_methods.append(gen_index_func(method, namespace, md))
 +
 +        if len(interface.properties) != 0:
 +            self.properties = []
 +            for pname, prop in interface.properties.items():
-                 self.signals.append(gen_index_signal(signal, namespace, md))
++                if not config.is_hidden(interface.name, "property", pname):
++                    self.properties.append(gen_index_property(prop, namespace, md))
 +
 +        if len(interface.signals) != 0:
 +            self.signals = []
 +            for sname, signal in interface.signals.items():
-                 self.methods.append(gen_index_func(method, namespace, md))
++                if not config.is_hidden(interface.name, "signal", sname):
++                    self.signals.append(gen_index_signal(signal, namespace, md))
 +
 +        if len(interface.methods) != 0:
 +            self.methods = []
 +            for method in interface.methods:
-                 self.type_funcs.append(gen_index_func(func, namespace, md))
++                if not config.is_hidden(interface.name, "method", method.name):
++                    self.methods.append(gen_index_func(method, namespace, md))
 +
 +        if len(interface.virtual_methods) != 0:
 +            self.virtual_methods = []
 +            for vfunc in interface.virtual_methods:
 +                self.virtual_methods.append(gen_index_func(vfunc, namespace, md))
 +
 +        if len(interface.functions) != 0:
 +            self.type_funcs = []
 +            for func in interface.functions:
-     def __init__(self, namespace, cls, recurse=True):
++                if not config.is_hidden(interface.name, "function", func.name):
++                    self.type_funcs.append(gen_index_func(func, namespace, md))
++
++        if len(interface.implementations) != 0:
++            self.implementations = []
++            for impl in interface.implementations:
++                self.implementations.append({
++                    'name': impl.name,
++                    'ctype': impl.ctype,
++                })
 +
 +    @property
 +    def c_decl(self):
 +        return f"interface {self.fqtn} : {self.requires_fqtn}"
 +
 +
 +class TemplateClass:
-             self.ancestors = []
++    def __init__(self, namespace, cls, config, recurse=True):
 +        self.symbol_prefix = f"{namespace.symbol_prefix[0]}_{cls.symbol_prefix}"
 +        self.type_cname = cls.base_ctype
 +        self.link_prefix = "class"
 +        self.fundamental = cls.fundamental
 +        self.abstract = cls.abstract
 +
 +        md = markdown.Markdown(extensions=utils.MD_EXTENSIONS,
 +                               extension_configs=utils.MD_EXTENSIONS_CONF)
 +
 +        if '.' in cls.name:
 +            self.namespace = cls.name.split('.')[0]
 +            self.name = cls.name.split('.')[1]
 +            self.fqtn = cls.name
 +        else:
 +            self.namespace = namespace.name
 +            self.name = cls.name
 +            self.fqtn = f"{namespace.name}.{self.name}"
 +
 +        if cls.parent is None or cls.fundamental:
 +            self.parent_fqtn = 'GObject.TypeInstance'
 +            self.parent_cname = 'GTypeInstance*'
 +            self.parent_name = 'TypeInstance'
 +            self.parent_namespace = 'GObject'
 +        elif '.' in cls.parent.name:
 +            self.parent_fqtn = cls.parent.name
 +            self.parent_cname = cls.parent.ctype
 +            self.parent_namespace = self.parent_fqtn.split('.')[0]
 +            self.parent_name = self.parent_fqtn.split('.')[1]
 +        else:
 +            self.parent_cname = cls.parent.ctype
 +            self.parent_name = cls.parent.name
 +            self.parent_namespace = cls.parent.namespace or namespace.name
 +            self.parent_fqtn = f"{self.parent_namespace}.{self.parent_name}"
 +
++        self.ancestors = []
 +        if recurse:
-                 if '.' in ancestor_type.name:
-                     ancestor_ns, ancestor_name = ancestor_type.name.split('.')
-                 else:
-                     ancestor_ns = ancestor_type.namespace or namespace.name
-                     ancestor_name = ancestor_type.name
-                 ancestor = namespace.find_class(ancestor_name)
-                 # We don't use real Template objects, here, because it can be
-                 # extremely expensive, unless we add a cache somewhere
-                 if ancestor is not None:
-                     # Set a hard-limit on the number of methods; base types can
-                     # add *a lot* of them; two dozens feel like a good compromise
-                     if len(ancestor.methods) < 24:
-                         methods = [gen_index_func(m, namespace, md) for m in ancestor.methods]
-                     else:
-                         methods = []
-                     self.ancestors.append({
-                         "namespace": ancestor_ns,
-                         "name": ancestor_name,
-                         "fqtn": f"{ancestor_ns}.{ancestor_name}",
-                         "type_cname": ancestor_type.base_ctype,
-                         "properties": [gen_index_property(p, namespace, md) for p in ancestor.properties.values()],
-                         "n_properties": len(ancestor.properties),
-                         "signals": [gen_index_signal(s, namespace, md) for s in ancestor.signals.values()],
-                         "n_signals": len(ancestor.signals),
-                         "methods": methods,
-                         "n_methods": len(ancestor.methods),
-                     })
-                 else:
-                     self.ancestors.append({
-                         "namespace": ancestor_ns,
-                         "name": ancestor_name,
-                         "fqtn": f"{ancestor_ns}.{ancestor_name}",
-                         "type_cname": ancestor_type.base_ctype,
-                         "properties": [],
-                         "n_properties": 0,
-                         "signals": [],
-                         "n_signals": 0,
-                         "methods": [],
-                         "n_methods": 0,
-                     })
 +            for ancestor_type in cls.ancestors:
-             self.properties = []
++                self.ancestors.append(gen_index_ancestor(ancestor_type, namespace, config, md))
++
++        if cls.descendants:
++            self.descendants = []
++            for descendant in cls.descendants:
++                self.descendants.append({
++                    'name': descendant.name,
++                    'ctype': descendant.ctype,
++                })
 +
 +        self.class_name = cls.type_struct
 +
 +        self.instance_struct = None
 +        if len(cls.fields) != 0:
 +            self.instance_struct = self.class_name
 +
 +        if cls.type_struct is not None:
 +            self.class_struct = namespace.find_record(cls.type_struct)
 +        else:
 +            self.class_struct = None
 +
 +        # "Final", in the absence of an actual flag or annotation,
 +        # is determined through an heuristic; if either the instance
 +        # or the class structures are missing or disguised, then the
 +        # type cannot be derived
 +        if self.instance_struct is None or self.class_struct is None or self.class_struct.disguised:
 +            self.final = True
 +        else:
 +            self.final = False
 +
 +        if cls.doc is not None:
 +            self.summary = utils.preprocess_docs(cls.doc.content, namespace, summary=True, md=md)
 +            self.description = utils.preprocess_docs(cls.doc.content, namespace, md=md)
 +            filename = cls.doc.filename
 +            line = cls.doc.line
 +            if filename.startswith('../'):
 +                filename = filename.replace('../', '')
 +            self.docs_location = (filename, line)
 +        else:
 +            self.description = MISSING_DESCRIPTION
 +
 +        self.stability = cls.stability
 +        self.attributes = cls.attributes
 +        self.available_since = cls.available_since
 +        if cls.deprecated_since is not None:
 +            (version, msg) = cls.deprecated_since
 +            self.deprecated_since = {
 +                "version": version,
 +                "message": utils.preprocess_docs(msg, namespace, md=md),
 +            }
 +        else:
 +            self.deprecated_since = None
 +
 +        self.introspectable = cls.introspectable
 +
 +        self.fields = []
 +        for field in cls.fields:
 +            if not field.private:
 +                self.fields.append(TemplateField(namespace, field))
 +
++        self.properties = []
 +        if len(cls.properties) != 0:
-                 self.properties.append(gen_index_property(prop, namespace, md))
 +            for pname, prop in cls.properties.items():
-             self.signals = []
++                if not config.is_hidden(cls.name, "property", pname):
++                    self.properties.append(gen_index_property(prop, namespace, md))
 +
++        self.signals = []
 +        if len(cls.signals) != 0:
-                 self.signals.append(gen_index_signal(signal, namespace, md))
 +            for sname, signal in cls.signals.items():
-             self.ctors = []
++                if not config.is_hidden(cls.name, "signal", sname):
++                    self.signals.append(gen_index_signal(signal, namespace, md))
 +
++        self.ctors = []
 +        if len(cls.constructors) != 0:
-                 self.ctors.append(gen_index_func(ctor, namespace, md))
 +            for ctor in cls.constructors:
-             self.methods = []
++                if not config.is_hidden(cls.name, "constructor", ctor.name):
++                    self.ctors.append(gen_index_func(ctor, namespace, md))
 +
++        self.methods = []
 +        if len(cls.methods) != 0:
-                 self.methods.append(gen_index_func(method, namespace, md))
 +            for method in cls.methods:
-             self.interfaces = []
++                if not config.is_hidden(cls.name, "method", method.name):
++                    self.methods.append(gen_index_func(method, namespace, md))
 +
 +        if self.class_struct is not None:
 +            self.class_ctype = self.class_struct.ctype
 +            self.class_fields = []
 +            self.class_methods = []
 +
 +            for field in self.class_struct.fields:
 +                if not field.private:
 +                    self.class_fields.append(TemplateField(namespace, field))
 +
 +            for method in self.class_struct.methods:
 +                self.class_methods.append(gen_index_func(method, namespace, md))
 +
++        self.interfaces = []
 +        if len(cls.implements) != 0:
-                 if '.' in iface_type.name:
-                     iface_ns, iface_name = iface_type.name.split('.')
-                 else:
-                     iface_ns = iface_type.namespace or namespace.name
-                     iface_name = iface_type.name
-                 iface = namespace.find_interface(iface_name)
-                 if iface is not None:
-                     # Set a hard-limit on the number of methods; base types can
-                     # add *a lot* of them; two dozens feel like a good compromise
-                     if len(iface.methods) < 24:
-                         methods = [gen_index_func(m, namespace, md) for m in iface.methods]
-                     else:
-                         methods = []
-                     self.interfaces.append({
-                         "namespace": iface_ns,
-                         "name": iface_name,
-                         "fqtn": f"{iface_ns}.{iface_name}",
-                         "type_cname": iface_type.base_ctype,
-                         "properties": [gen_index_property(p, namespace, md) for p in iface.properties.values()],
-                         "n_properties": len(iface.properties),
-                         "signals": [gen_index_signal(s, namespace, md) for s in iface.signals.values()],
-                         "n_signals": len(iface.signals),
-                         "methods": methods,
-                         "n_methods": len(iface.methods),
-                     })
-                 else:
-                     self.interfaces.append({
-                         "namespace": iface_ns,
-                         "name": iface_name,
-                         "fqtn": f"{iface_ns}.{iface_name}",
-                         "type_cname": iface_type.base_ctype,
-                         "properties": [],
-                         "n_properties": 0,
-                         "signals": [],
-                         "n_signals": 0,
-                         "methods": [],
-                         "n_methods": 0,
-                     })
 +            for iface_type in cls.implements:
-             self.virtual_methods = []
++                self.interfaces.append(gen_index_implements(iface_type, namespace, config, md))
 +
++        self.virtual_methods = []
 +        if len(cls.virtual_methods) != 0:
-             self.type_funcs = []
 +            for vfunc in cls.virtual_methods:
 +                self.virtual_methods.append(gen_index_func(vfunc, namespace, md))
 +
++        self.type_funcs = []
 +        if len(cls.functions) != 0:
-                 self.type_funcs.append(gen_index_func(func, namespace, md))
 +            for func in cls.functions:
-         def add_link(attrs, other):
++                if not config.is_hidden(cls.name, "function", func.name):
++                    self.type_funcs.append(gen_index_func(func, namespace, md))
++
++    @property
++    def show_methods(self):
++        if len(self.methods) > 0:
++            return True
++        for ancestor in self.ancestors:
++            if ancestor["n_methods"] > 0:
++                return True
++        for iface in self.interfaces:
++            if iface["n_methods"] > 0:
++                return True
++        return False
++
++    @property
++    def show_properties(self):
++        if len(self.properties) > 0:
++            return True
++        for ancestor in self.ancestors:
++            if ancestor["n_properties"] > 0:
++                return True
++        for iface in self.interfaces:
++            if iface["n_properties"] > 0:
++                return True
++        return False
++
++    @property
++    def show_signals(self):
++        if len(self.signals) > 0:
++            return True
++        for ancestor in self.ancestors:
++            if ancestor["n_signals"] > 0:
++                return True
++        for iface in self.interfaces:
++            if iface["n_signals"] > 0:
++                return True
++        return False
 +
 +    @property
 +    def c_decl(self):
 +        if self.abstract:
 +            res = [f"abstract class {self.fqtn} : {self.parent_fqtn} {{"]
 +        elif self.final:
 +            res = [f"final class {self.fqtn} : {self.parent_fqtn} {{"]
 +        else:
 +            res = [f"class {self.fqtn} : {self.parent_fqtn} {{"]
 +        n_fields = len(self.fields)
 +        if n_fields > 0:
 +            for (idx, field) in enumerate(self.fields):
 +                if idx < n_fields - 1:
 +                    res += [f"  {field.name}: {field.type_cname},"]
 +                else:
 +                    res += [f"  {field.name}: {field.type_cname}"]
 +        else:
 +            res += ["  /* No available fields */"]
 +        res += ["}"]
 +        return "\n".join(res)
 +
 +    @property
 +    def dot(self):
 +
 +        def fmt_attrs(attrs):
 +            return ','.join(f'{k}="{v}"' for k, v in attrs.items())
 +
-                 attrs['href'] = f"class.{other['name']}.html"
++        def add_link(attrs, other, fragment):
 +            if other['namespace'] == self.namespace:
-             add_link(ancestor_attrs, ancestor)
++                attrs['href'] = f"{fragment}.{other['name']}.html"
 +                attrs['class'] = 'link'
 +            else:
 +                attrs['tooltip'] = other['fqtn']
 +
 +        ancestors = []
 +        implements = []
 +        res = ["graph hierarchy {"]
 +        res.append("  bgcolor=\"transparent\";")
 +        node_attrs = {
 +            'shape': 'box',
 +            'style': 'rounded',
 +            'border': 0
 +        }
 +        this_attrs = {
 +            'label': self.type_cname,
 +            'tooltip': self.type_cname
 +        }
 +        this_attrs.update(node_attrs)
 +        res.append(f"  this [{fmt_attrs(this_attrs)}];")
 +        for idx, ancestor in enumerate(self.ancestors):
 +            node_id = f"ancestor_{idx}"
 +            ancestor_attrs = {
 +                'label': ancestor['type_cname']
 +            }
 +            ancestor_attrs.update(node_attrs)
-             add_link(iface_attrs, iface)
++            add_link(ancestor_attrs, ancestor, 'class')
 +            res.append(f"  {node_id} [{fmt_attrs(ancestor_attrs)}];")
 +            ancestors.append(node_id)
 +        ancestors.reverse()
 +        for idx, iface in enumerate(getattr(self, "interfaces", [])):
 +            node_id = f"implements_{idx}"
 +            iface_attrs = {
 +                'label': iface['type_cname'],
 +                'fontname': 'sans-serif',
 +                'shape': 'box',
 +            }
-     def __init__(self, namespace, record):
++            add_link(iface_attrs, iface, 'iface')
 +            res.append(f"  {node_id} [{fmt_attrs(iface_attrs)}];")
 +            implements.append(node_id)
 +        if len(ancestors) > 0:
 +            res.append("  " + " -- ".join(ancestors) + " -- this;")
 +        for node in implements:
 +            res.append(f"  this -- {node} [style=dotted];")
 +        res.append("}")
 +        return "\n".join(res)
 +
 +
 +class TemplateRecord:
-                 self.ctors.append(gen_index_func(ctor, namespace, md))
++    def __init__(self, namespace, record, config):
 +        self.symbol_prefix = f"{namespace.symbol_prefix[0]}_{record.symbol_prefix}"
 +        self.type_cname = record.ctype
 +        self.link_prefix = "struct"
 +
 +        self.name = record.name
 +        self.namespace = record.name or namespace.name
 +        self.fqtn = f"{self.namespace}.{self.name}"
 +
 +        md = markdown.Markdown(extensions=utils.MD_EXTENSIONS,
 +                               extension_configs=utils.MD_EXTENSIONS_CONF)
 +
 +        if record.doc is not None:
 +            self.summary = utils.preprocess_docs(record.doc.content, namespace, summary=True, md=md)
 +            self.description = utils.preprocess_docs(record.doc.content, namespace, md=md)
 +            filename = record.doc.filename
 +            line = record.doc.line
 +            if filename.startswith('../'):
 +                filename = filename.replace('../', '')
 +            self.docs_location = (filename, line)
 +        else:
 +            self.description = MISSING_DESCRIPTION
 +
 +        self.stability = record.stability
 +        self.attributes = record.attributes
 +        self.available_since = record.available_since
 +        if record.deprecated_since is not None:
 +            (version, msg) = record.deprecated_since
 +            self.deprecated_since = {
 +                "version": version,
 +                "message": utils.preprocess_docs(msg, namespace, md=md),
 +            }
 +        else:
 +            self.deprecated_since = None
 +
 +        self.introspectable = record.introspectable
 +
 +        self.fields = []
 +        for field in record.fields:
 +            if not field.private:
 +                self.fields.append(TemplateField(namespace, field))
 +
 +        if len(record.constructors) != 0:
 +            self.ctors = []
 +            for ctor in record.constructors:
-                 self.methods.append(gen_index_func(method, namespace, md))
++                if not config.is_hidden(record.name, "constructor", ctor.name):
++                    self.ctors.append(gen_index_func(ctor, namespace, md))
 +
 +        if len(record.methods) != 0:
 +            self.methods = []
 +            for method in record.methods:
-                 self.type_funcs.append(gen_index_func(func, namespace, md))
++                if not config.is_hidden(record.name, "method", method.name):
++                    self.methods.append(gen_index_func(method, namespace, md))
 +
 +        if len(record.functions) != 0:
 +            self.type_funcs = []
 +            for func in record.functions:
-     def __init__(self, namespace, union):
++                if not config.is_hidden(record.name, "function", func.name):
++                    self.type_funcs.append(gen_index_func(func, namespace, md))
 +
 +    @property
 +    def c_decl(self):
 +        res = [f"struct {self.type_cname} {{"]
 +        n_fields = len(self.fields)
 +        if n_fields > 0:
 +            for field in self.fields:
 +                if field.is_callback:
 +                    res += [f"  {field.type_cname};"]
 +                else:
 +                    res += [f"  {field.type_cname} {field.name};"]
 +        else:
 +            res += ["  /* No available fields */"]
 +        res += ["}"]
 +        return utils.code_highlight("\n".join(res))
 +
 +
 +class TemplateUnion:
-                 self.ctors.append(gen_index_func(ctor, namespace, md))
++    def __init__(self, namespace, union, config):
 +        self.symbol_prefix = f"{namespace.symbol_prefix[0]}_{union.symbol_prefix}"
 +        self.type_cname = union.ctype
 +        self.link_prefix = "union"
 +        self.name = union.name
 +        self.namespace = union.namespace or namespace.name
 +        self.fqtn = f"{self.namespace}.{self.name}"
 +
 +        md = markdown.Markdown(extensions=utils.MD_EXTENSIONS,
 +                               extension_configs=utils.MD_EXTENSIONS_CONF)
 +
 +        if union.doc is not None:
 +            self.summary = utils.preprocess_docs(union.doc.content, namespace, summary=True, md=md)
 +            self.description = utils.preprocess_docs(union.doc.content, namespace, md=md)
 +            filename = union.doc.filename
 +            line = union.doc.line
 +            if filename.startswith('../'):
 +                filename = filename.replace('../', '')
 +            self.docs_location = (filename, line)
 +        else:
 +            self.description = MISSING_DESCRIPTION
 +
 +        self.stability = union.stability
 +        self.attributes = union.attributes
 +        self.available_since = union.available_since
 +        if union.deprecated_since is not None:
 +            (version, msg) = union.deprecated_since
 +            self.deprecated_since = {
 +                "version": version,
 +                "message": utils.preprocess_docs(msg, namespace, md=md),
 +            }
 +        else:
 +            self.deprecated_since = None
 +
 +        self.introspectable = union.introspectable
 +
 +        self.fields = []
 +        for field in union.fields:
 +            if not field.private:
 +                self.fields.append(TemplateField(namespace, field))
 +
 +        if len(union.constructors) != 0:
 +            self.ctors = []
 +            for ctor in union.constructors:
-                 self.methods.append(gen_index_func(method, namespace, md))
++                if not config.is_hidden(union.name, "constructor", ctor.name):
++                    self.ctors.append(gen_index_func(ctor, namespace, md))
 +
 +        if len(union.methods) != 0:
 +            self.methods = []
 +            for method in union.methods:
-                 self.type_funcs.append(gen_index_func(func, namespace, md))
++                if not config.is_hidden(union.name, "method", method.name):
++                    self.methods.append(gen_index_func(method, namespace, md))
 +
 +        if len(union.functions) != 0:
 +            self.type_funcs = []
 +            for func in union.functions:
-     def __init__(self, namespace, enum):
++                if not config.is_hidden(union.name, "function", func.name):
++                    self.type_funcs.append(gen_index_func(func, namespace, md))
 +
 +    @property
 +    def c_decl(self):
 +        res = [f"union {self.type_cname} {{"]
 +        n_fields = len(self.fields)
 +        if n_fields > 0:
 +            for field in self.fields:
 +                if field.is_callback:
 +                    res += [f"  {field.type_cname};"]
 +                else:
 +                    res += [f"  {field.type_cname} {field.name};"]
 +        else:
 +            res += ["  /* No available fields */"]
 +        res += ["}"]
 +        return utils.code_highlight("\n".join(res))
 +
 +
 +class TemplateAlias:
 +    def __init__(self, namespace, alias):
 +        self.type_cname = alias.base_ctype
 +        self.target_ctype = alias.target.ctype
 +        self.link_prefix = "alias"
 +
 +        self.namespace = alias.namespace or namespace.name
 +        self.name = alias.name
 +        self.fqtn = f"{self.namespace}.{self.name}"
 +
 +        md = markdown.Markdown(extensions=utils.MD_EXTENSIONS,
 +                               extension_configs=utils.MD_EXTENSIONS_CONF)
 +
 +        if alias.doc is not None:
 +            self.summary = utils.preprocess_docs(alias.doc.content, namespace, summary=True, md=md)
 +            self.description = utils.preprocess_docs(alias.doc.content, namespace, md=md)
 +            filename = alias.doc.filename
 +            line = alias.doc.line
 +            if filename.startswith('../'):
 +                filename = filename.replace('../', '')
 +            self.docs_location = (filename, line)
 +        else:
 +            self.description = MISSING_DESCRIPTION
 +
 +        self.stability = alias.stability
 +        self.attributes = alias.attributes
 +        self.available_since = alias.available_since
 +        self.deprecated_since = alias.deprecated_since
 +        if alias.deprecated_since is not None:
 +            (version, msg) = alias.deprecated_since
 +            self.deprecated_since = {
 +                "version": version,
 +                "message": utils.preprocess_docs(msg, namespace),
 +            }
 +        else:
 +            self.deprecated_since = None
 +
 +        self.introspectable = alias.introspectable
 +
 +    @property
 +    def c_decl(self):
 +        return f"typedef {self.target_ctype} {self.type_cname}"
 +
 +
 +class TemplateMember:
 +    def __init__(self, namespace, enum, member):
 +        self.name = member.identifier
 +        self.nick = member.nick
 +        self.value = member.value
 +        if member.doc is not None:
 +            self.description = utils.preprocess_docs(member.doc.content, namespace)
 +            filename = member.doc.filename
 +            line = member.doc.line
 +            if filename.startswith('../'):
 +                filename = filename.replace('../', '')
 +            self.docs_location = (filename, line)
 +        else:
 +            self.description = MISSING_DESCRIPTION
 +
 +
 +class TemplateEnum:
-                 self.type_funcs.append(gen_index_func(func, namespace, md))
++    def __init__(self, namespace, enum, config):
 +        self.symbol_prefix = None
 +        self.type_cname = enum.ctype
 +        self.bitfield = False
 +        self.error = False
 +        self.domain = None
 +
 +        self.namespace = namespace.name
 +        self.name = enum.name
 +        self.fqtn = f"{namespace.name}.{enum.name}"
 +
 +        md = markdown.Markdown(extensions=utils.MD_EXTENSIONS,
 +                               extension_configs=utils.MD_EXTENSIONS_CONF)
 +
 +        if enum.doc is not None:
 +            self.summary = utils.preprocess_docs(enum.doc.content, namespace, summary=True, md=md)
 +            self.description = utils.preprocess_docs(enum.doc.content, namespace, md=md)
 +            filename = enum.doc.filename
 +            line = enum.doc.line
 +            if filename.startswith('../'):
 +                filename = filename.replace('../', '')
 +            self.docs_location = (filename, line)
 +        else:
 +            self.description = MISSING_DESCRIPTION
 +
 +        self.stability = enum.stability
 +        self.attributes = enum.attributes
 +        self.available_since = enum.available_since
 +        self.deprecated_since = enum.deprecated_since
 +        if enum.deprecated_since is not None:
 +            (version, msg) = enum.deprecated_since
 +            self.deprecated_since = {
 +                "version": version,
 +                "message": utils.preprocess_docs(msg, namespace, md=md),
 +            }
 +        else:
 +            self.deprecated_since = None
 +
 +        self.introspectable = enum.introspectable
 +
 +        if isinstance(enum, gir.BitField):
 +            self.link_prefix = "flags"
 +            self.bitfield = True
 +        elif isinstance(enum, gir.ErrorDomain):
 +            self.link_prefix = "error"
 +            self.error = True
 +            self.domain = enum.domain
 +        else:
 +            self.link_prefix = "enum"
 +
 +        if len(enum.members) != 0:
 +            self.members = []
 +            for member in enum.members:
 +                self.members.append(TemplateMember(namespace, enum, member))
 +
 +        if len(enum.functions) != 0:
 +            self.type_funcs = []
 +            for func in enum.functions:
-         tmpl = TemplateClass(namespace, cls)
++                if not config.is_hidden(enum.name, "function", func.name):
++                    self.type_funcs.append(gen_index_func(func, namespace, md))
 +
 +    @property
 +    def c_decl(self):
 +        if self.error:
 +            return f"error-domain {self.fqtn}"
 +        elif self.bitfield:
 +            return f"flags {self.fqtn}"
 +        else:
 +            return f"enum {self.fqtn}"
 +
 +
 +class TemplateNamespace:
 +    def __init__(self, namespace):
 +        self.name = namespace.name
 +        self.version = namespace.version
 +        self.symbol_prefix = namespace.symbol_prefix[0]
 +        self.identifier_prefix = namespace.identifier_prefix[0]
 +
 +
 +def _gen_classes(config, theme_config, output_dir, jinja_env, repository, all_classes):
 +    namespace = repository.namespace
 +
 +    class_tmpl = jinja_env.get_template(theme_config.class_template)
 +    method_tmpl = jinja_env.get_template(theme_config.method_template)
 +    property_tmpl = jinja_env.get_template(theme_config.property_template)
 +    signal_tmpl = jinja_env.get_template(theme_config.signal_template)
 +    class_method_tmpl = jinja_env.get_template(theme_config.class_method_template)
 +    ctor_tmpl = jinja_env.get_template(theme_config.ctor_template)
 +    type_func_tmpl = jinja_env.get_template(theme_config.type_func_template)
 +    vfunc_tmpl = jinja_env.get_template(theme_config.vfunc_template)
 +
 +    template_classes = []
 +
 +    for cls in all_classes:
 +        if config.is_hidden(cls.name):
 +            log.debug(f"Skipping hidden class {cls.name}")
 +            continue
 +        class_file = os.path.join(output_dir, f"class.{cls.name}.html")
 +        log.info(f"Creating class file for {namespace.name}.{cls.name}: {class_file}")
 +
-         tmpl = TemplateInterface(namespace, iface)
++        tmpl = TemplateClass(namespace, cls, config)
 +        template_classes.append(tmpl)
 +
 +        if config.show_class_hierarchy:
 +            tmpl.hierarchy_svg = utils.render_dot(tmpl.dot, output_format="svg")
 +
 +        with open(class_file, "w") as out:
 +            content = class_tmpl.render({
 +                'CONFIG': config,
 +                'namespace': namespace,
 +                'class': tmpl,
 +            })
 +
 +            out.write(content)
 +
 +        for ctor in cls.constructors:
++            if config.is_hidden(cls.name, "constructor", ctor.name):
++                log.debug(f"Skipping hidden constructor {cls.name}.{ctor.name}")
++                continue
 +            c = TemplateFunction(namespace, ctor)
 +            ctor_file = os.path.join(output_dir, f"ctor.{cls.name}.{ctor.name}.html")
 +            log.debug(f"Creating ctor file for {namespace.name}.{cls.name}.{ctor.name}: {ctor_file}")
 +
 +            with open(ctor_file, "w") as out:
 +                out.write(ctor_tmpl.render({
 +                    'CONFIG': config,
 +                    'namespace': namespace,
 +                    'class': tmpl,
 +                    'type_func': c,
 +                }))
 +
 +        for method in cls.methods:
++            if config.is_hidden(cls.name, "method", method.name):
++                log.debug(f"Skipping hidden method {cls.name}.{method.name}")
++                continue
 +            m = TemplateMethod(namespace, cls, method)
 +            method_file = os.path.join(output_dir, f"method.{cls.name}.{method.name}.html")
 +            log.debug(f"Creating method file for {namespace.name}.{cls.name}.{method.name}: {method_file}")
 +
 +            with open(method_file, "w") as out:
 +                out.write(method_tmpl.render({
 +                    'CONFIG': config,
 +                    'namespace': namespace,
 +                    'class': tmpl,
 +                    'method': m,
 +                }))
 +
 +        for prop in cls.properties.values():
 +            if config.is_hidden(cls.name, 'property', prop.name):
 +                log.debug(f"Skipping hidden property {cls.name}.{prop.name}")
 +                continue
 +            p = TemplateProperty(namespace, cls, prop)
 +            prop_file = os.path.join(output_dir, f"property.{cls.name}.{prop.name}.html")
 +            log.debug(f"Creating property file for {namespace.name}.{cls.name}.{prop.name}: {prop_file}")
 +
 +            with open(prop_file, "w") as out:
 +                out.write(property_tmpl.render({
 +                    'CONFIG': config,
 +                    'namespace': namespace,
 +                    'class': tmpl,
 +                    'property': p,
 +                }))
 +
 +        for signal in cls.signals.values():
 +            if config.is_hidden(cls.name, 'signal', signal.name):
 +                log.debug(f"Skipping hidden signal {cls.name}.{signal.name}")
 +                continue
 +            s = TemplateSignal(namespace, cls, signal)
 +            signal_file = os.path.join(output_dir, f"signal.{cls.name}.{signal.name}.html")
 +            log.debug(f"Creating signal file for {namespace.name}.{cls.name}.{signal.name}: {signal_file}")
 +
 +            with open(signal_file, "w") as out:
 +                out.write(signal_tmpl.render({
 +                    'CONFIG': config,
 +                    'namespace': namespace,
 +                    'class': tmpl,
 +                    'signal': s,
 +                }))
 +
 +        if cls.type_struct is not None:
 +            class_struct = namespace.find_record(cls.type_struct)
 +            for cls_method in class_struct.methods:
 +                c = TemplateClassMethod(namespace, cls, cls_method)
 +                cls_method_file = os.path.join(output_dir, f"class_method.{cls.name}.{cls_method.name}.html")
 +                log.debug(f"Creating class method file for {namespace.name}.{cls.name}.{cls_method.name}: {cls_method_file}")
 +
 +                with open(cls_method_file, "w") as out:
 +                    out.write(class_method_tmpl.render({
 +                        'CONFIG': config,
 +                        'namespace': namespace,
 +                        'class': tmpl,
 +                        'class_method': c,
 +                    }))
 +
 +        for vfunc in cls.virtual_methods:
 +            f = TemplateMethod(namespace, cls, vfunc)
 +            vfunc_file = os.path.join(output_dir, f"vfunc.{cls.name}.{vfunc.name}.html")
 +            log.debug(f"Creating vfunc file for {namespace.name}.{cls.name}.{vfunc.name}: {vfunc_file}")
 +
 +            with open(vfunc_file, "w") as out:
 +                out.write(vfunc_tmpl.render({
 +                    'CONFIG': config,
 +                    'namespace': namespace,
 +                    'class': tmpl,
 +                    'vfunc': f,
 +                }))
 +
 +        for type_func in cls.functions:
++            if config.is_hidden(cls.name, "function", type_func.name):
++                log.debug(f"Skipping hidden type function {cls.name}.{type_func.name}")
++                continue
 +            f = TemplateFunction(namespace, type_func)
 +            type_func_file = os.path.join(output_dir, f"type_func.{cls.name}.{type_func.name}.html")
 +            log.debug(f"Creating type func file for {namespace.name}.{cls.name}.{type_func.name}: {type_func_file}")
 +
 +            with open(type_func_file, "w") as out:
 +                out.write(type_func_tmpl.render({
 +                    'CONFIG': config,
 +                    'namespace': namespace,
 +                    'class': tmpl,
 +                    'type_func': f,
 +                }))
 +
 +    return template_classes
 +
 +
 +def _gen_interfaces(config, theme_config, output_dir, jinja_env, repository, all_interfaces):
 +    namespace = repository.namespace
 +
 +    iface_tmpl = jinja_env.get_template(theme_config.interface_template)
 +    method_tmpl = jinja_env.get_template(theme_config.method_template)
 +    property_tmpl = jinja_env.get_template(theme_config.property_template)
 +    signal_tmpl = jinja_env.get_template(theme_config.signal_template)
 +    class_method_tmpl = jinja_env.get_template(theme_config.class_method_template)
 +    type_func_tmpl = jinja_env.get_template(theme_config.type_func_template)
 +    vfunc_tmpl = jinja_env.get_template(theme_config.vfunc_template)
 +
 +    template_interfaces = []
 +
 +    for iface in all_interfaces:
 +        if config.is_hidden(iface.name):
 +            log.debug(f"Skipping hidden interface {iface.name}")
 +            continue
 +        iface_file = os.path.join(output_dir, f"iface.{iface.name}.html")
 +        log.info(f"Creating interface file for {namespace.name}.{iface.name}: {iface_file}")
 +
-         tmpl = TemplateEnum(namespace, enum)
++        tmpl = TemplateInterface(namespace, iface, config)
 +        template_interfaces.append(tmpl)
 +
 +        with open(iface_file, "w") as out:
 +            out.write(iface_tmpl.render({
 +                'CONFIG': config,
 +                'namespace': namespace,
 +                'interface': tmpl,
 +            }))
 +
 +        for method in iface.methods:
++            if config.is_hidden(iface.name, "method", method.name):
++                log.debug(f"Skipping hidden method {iface.name}.{method.name}")
++                continue
 +            m = TemplateMethod(namespace, iface, method)
 +            method_file = os.path.join(output_dir, f"method.{iface.name}.{method.name}.html")
 +            log.debug(f"Creating method file for {namespace.name}.{iface.name}.{method.name}: {method_file}")
 +
 +            with open(method_file, "w") as out:
 +                out.write(method_tmpl.render({
 +                    'CONFIG': config,
 +                    'namespace': namespace,
 +                    'class': tmpl,
 +                    'method': m,
 +                }))
 +
 +        for prop in iface.properties.values():
 +            if config.is_hidden(iface.name, 'property', prop.name):
 +                log.debug(f"Skipping hidden property {iface.name}.{prop.name}")
 +                continue
 +            p = TemplateProperty(namespace, iface, prop)
 +            prop_file = os.path.join(output_dir, f"property.{iface.name}.{prop.name}.html")
 +            log.debug(f"Creating property file for {namespace.name}.{iface.name}.{prop.name}: {prop_file}")
 +
 +            with open(prop_file, "w") as out:
 +                out.write(property_tmpl.render({
 +                    'CONFIG': config,
 +                    'namespace': namespace,
 +                    'class': tmpl,
 +                    'property': p,
 +                }))
 +
 +        for signal in iface.signals.values():
 +            if config.is_hidden(iface.name, 'signal', signal.name):
 +                log.debug(f"Skipping hidden property {iface.name}.{signal.name}")
 +                continue
 +            s = TemplateSignal(namespace, iface, signal)
 +            signal_file = os.path.join(output_dir, f"signal.{iface.name}.{signal.name}.html")
 +            log.debug(f"Creating signal file for {namespace.name}.{iface.name}.{signal.name}: {signal_file}")
 +
 +            with open(signal_file, "w") as out:
 +                out.write(signal_tmpl.render({
 +                    'CONFIG': config,
 +                    'namespace': namespace,
 +                    'class': tmpl,
 +                    'signal': s,
 +                }))
 +
 +        for vfunc in iface.virtual_methods:
 +            v = TemplateMethod(namespace, iface, vfunc)
 +            vfunc_file = os.path.join(output_dir, f"vfunc.{iface.name}.{vfunc.name}.html")
 +            log.debug(f"Creating vfunc file for {namespace.name}.{iface.name}.{vfunc.name}: {vfunc_file}")
 +
 +            with open(vfunc_file, "w") as out:
 +                out.write(vfunc_tmpl.render({
 +                    'CONFIG': config,
 +                    'namespace': namespace,
 +                    'class': tmpl,
 +                    'vfunc': v,
 +                }))
 +
 +        if iface.type_struct is not None:
 +            iface_struct = namespace.find_record(iface.type_struct)
 +            for cls_method in iface_struct.methods:
 +                m = TemplateClassMethod(namespace, iface, cls_method)
 +                cls_method_file = os.path.join(output_dir, f"class_method.{iface.name}.{cls_method.name}.html")
 +                log.debug(f"Creating class method file for {namespace.name}.{iface.name}.{cls_method.name}: {cls_method_file}")
 +
 +                with open(cls_method_file, "w") as out:
 +                    out.write(class_method_tmpl.render({
 +                        'CONFIG': config,
 +                        'namespace': namespace,
 +                        'class': tmpl,
 +                        'class_method': m,
 +                    }))
 +
 +        for type_func in iface.functions:
++            if config.is_hidden(iface.name, "function", type_func.name):
++                log.debug(f"Skipping hidden type function {iface.name}.{type_func.name}")
++                continue
 +            f = TemplateFunction(namespace, type_func)
 +            type_func_file = os.path.join(output_dir, f"type_func.{iface.name}.{type_func.name}.html")
 +            log.debug(f"Creating type func file for {namespace.name}.{iface.name}.{type_func.name}: {type_func_file}")
 +
 +            with open(type_func_file, "w") as out:
 +                out.write(type_func_tmpl.render({
 +                    'CONFIG': config,
 +                    'namespace': namespace,
 +                    'class': tmpl,
 +                    'type_func': f,
 +                }))
 +
 +    return template_interfaces
 +
 +
 +def _gen_enums(config, theme_config, output_dir, jinja_env, repository, all_enums):
 +    namespace = repository.namespace
 +
 +    enum_tmpl = jinja_env.get_template(theme_config.enum_template)
 +    type_func_tmpl = jinja_env.get_template(theme_config.type_func_template)
 +
 +    template_enums = []
 +
 +    for enum in all_enums:
 +        if config.is_hidden(enum.name):
 +            log.debug(f"Skipping hidden enum {enum.name}")
 +            continue
 +        enum_file = os.path.join(output_dir, f"enum.{enum.name}.html")
 +        log.info(f"Creating enum file for {namespace.name}.{enum.name}: {enum_file}")
 +
-         tmpl = TemplateEnum(namespace, enum)
++        tmpl = TemplateEnum(namespace, enum, config)
 +        template_enums.append(tmpl)
 +
 +        with open(enum_file, "w") as out:
 +            out.write(enum_tmpl.render({
 +                'CONFIG': config,
 +                'namespace': namespace,
 +                'enum': tmpl,
 +            }))
 +
 +        for type_func in enum.functions:
 +            f = TemplateFunction(namespace, type_func)
 +            type_func_file = os.path.join(output_dir, f"type_func.{enum.name}.{type_func.name}.html")
 +            log.debug(f"Creating type func file for {namespace.name}.{enum.name}.{type_func.name}: {type_func_file}")
 +
 +            with open(type_func_file, "w") as out:
 +                out.write(type_func_tmpl.render({
 +                    'CONFIG': config,
 +                    'namespace': namespace,
 +                    'class': tmpl,
 +                    'type_func': f,
 +                }))
 +
 +    return template_enums
 +
 +
 +def _gen_bitfields(config, theme_config, output_dir, jinja_env, repository, all_enums):
 +    namespace = repository.namespace
 +
 +    enum_tmpl = jinja_env.get_template(theme_config.flags_template)
 +    type_func_tmpl = jinja_env.get_template(theme_config.type_func_template)
 +
 +    template_bitfields = []
 +
 +    for enum in all_enums:
 +        if config.is_hidden(enum.name):
 +            log.debug(f"Skipping hidden bitfield {enum.name}")
 +            continue
 +        enum_file = os.path.join(output_dir, f"flags.{enum.name}.html")
 +        log.info(f"Creating enum file for {namespace.name}.{enum.name}: {enum_file}")
 +
-         tmpl = TemplateEnum(namespace, enum)
++        tmpl = TemplateEnum(namespace, enum, config)
 +        template_bitfields.append(tmpl)
 +
 +        with open(enum_file, "w") as out:
 +            out.write(enum_tmpl.render({
 +                'CONFIG': config,
 +                'namespace': namespace,
 +                'enum': tmpl,
 +            }))
 +
 +        for type_func in enum.functions:
 +            f = TemplateFunction(namespace, type_func)
 +            type_func_file = os.path.join(output_dir, f"type_func.{enum.name}.{type_func.name}.html")
 +            log.debug(f"Creating type func file for {namespace.name}.{enum.name}.{type_func.name}: {type_func_file}")
 +
 +            with open(type_func_file, "w") as out:
 +                out.write(type_func_tmpl.render({
 +                    'CONFIG': config,
 +                    'namespace': namespace,
 +                    'class': tmpl,
 +                    'type_func': f,
 +                }))
 +
 +    return template_bitfields
 +
 +
 +def _gen_domains(config, theme_config, output_dir, jinja_env, repository, all_enums):
 +    namespace = repository.namespace
 +
 +    enum_tmpl = jinja_env.get_template(theme_config.error_template)
 +    type_func_tmpl = jinja_env.get_template(theme_config.type_func_template)
 +
 +    template_domains = []
 +
 +    for enum in all_enums:
 +        if config.is_hidden(enum.name):
 +            log.debug(f"Skipping hidden domain {enum.name}")
 +            continue
 +        enum_file = os.path.join(output_dir, f"error.{enum.name}.html")
 +        log.info(f"Creating enum file for {namespace.name}.{enum.name}: {enum_file}")
 +
-         tmpl = TemplateRecord(namespace, record)
++        tmpl = TemplateEnum(namespace, enum, config)
 +        template_domains.append(tmpl)
 +
 +        with open(enum_file, "w") as out:
 +            out.write(enum_tmpl.render({
 +                'CONFIG': config,
 +                'namespace': namespace,
 +                'enum': tmpl,
 +            }))
 +
 +        for type_func in enum.functions:
 +            f = TemplateFunction(namespace, type_func)
 +            type_func_file = os.path.join(output_dir, f"type_func.{enum.name}.{type_func.name}.html")
 +            log.debug(f"Creating type func file for {namespace.name}.{enum.name}.{type_func.name}: {type_func_file}")
 +
 +            with open(type_func_file, "w") as out:
 +                out.write(type_func_tmpl.render({
 +                    'CONFIG': config,
 +                    'namespace': namespace,
 +                    'class': tmpl,
 +                    'type_func': f,
 +                }))
 +
 +    return template_domains
 +
 +
 +def _gen_constants(config, theme_config, output_dir, jinja_env, repository, all_constants):
 +    namespace = repository.namespace
 +
 +    const_tmpl = jinja_env.get_template(theme_config.constant_template)
 +
 +    template_constants = []
 +
 +    for const in all_constants:
 +        if config.is_hidden(const.name):
 +            log.debug(f"Skipping hidden constant {const.name}")
 +            continue
 +        const_file = os.path.join(output_dir, f"const.{const.name}.html")
 +        log.info(f"Creating constant file for {namespace.name}.{const.name}: {const_file}")
 +
 +        tmpl = TemplateConstant(namespace, const)
 +        template_constants.append(tmpl)
 +
 +        with open(const_file, "w") as out:
 +            out.write(const_tmpl.render({
 +                'CONFIG': config,
 +                'namespace': namespace,
 +                'constant': tmpl,
 +            }))
 +
 +    return template_constants
 +
 +
 +def _gen_aliases(config, theme_config, output_dir, jinja_env, repository, all_aliases):
 +    namespace = repository.namespace
 +
 +    alias_tmpl = jinja_env.get_template(theme_config.alias_template)
 +
 +    template_aliases = []
 +
 +    for alias in all_aliases:
 +        if config.is_hidden(alias.name):
 +            log.debug(f"Skipping hidden alias {alias.name}")
 +            continue
 +        alias_file = os.path.join(output_dir, f"alias.{alias.name}.html")
 +        log.info(f"Creating alias file for {namespace.name}.{alias.name}: {alias_file}")
 +
 +        tmpl = TemplateAlias(namespace, alias)
 +        template_aliases.append(tmpl)
 +
 +        with open(alias_file, "w") as out:
 +            content = alias_tmpl.render({
 +                'CONFIG': config,
 +                'namespace': namespace,
 +                'struct': tmpl,
 +            })
 +
 +            out.write(content)
 +
 +    return template_aliases
 +
 +
 +def _gen_records(config, theme_config, output_dir, jinja_env, repository, all_records):
 +    namespace = repository.namespace
 +
 +    record_tmpl = jinja_env.get_template(theme_config.record_template)
 +    method_tmpl = jinja_env.get_template(theme_config.method_template)
 +    type_func_tmpl = jinja_env.get_template(theme_config.type_func_template)
 +
 +    template_records = []
 +
 +    for record in all_records:
 +        if config.is_hidden(record.name):
 +            log.debug(f"Skipping hidden record {record.name}")
 +            continue
 +        record_file = os.path.join(output_dir, f"struct.{record.name}.html")
 +        log.info(f"Creating record file for {namespace.name}.{record.name}: {record_file}")
 +
-         tmpl = TemplateUnion(namespace, union)
++        tmpl = TemplateRecord(namespace, record, config)
 +        template_records.append(tmpl)
 +
 +        with open(record_file, "w") as out:
 +            content = record_tmpl.render({
 +                'CONFIG': config,
 +                'namespace': namespace,
 +                'struct': tmpl,
 +            })
 +
 +            out.write(content)
 +
 +        for ctor in record.constructors:
++            if config.is_hidden(record.name, "constructor", ctor.name):
++                log.debug(f"Skipping hidden constructor {record.name}.{ctor.name}")
++                continue
 +            c = TemplateFunction(namespace, ctor)
 +            ctor_file = os.path.join(output_dir, f"ctor.{record.name}.{ctor.name}.html")
 +            log.debug(f"Creating ctor file for {namespace.name}.{record.name}.{ctor.name}: {ctor_file}")
 +
 +            with open(ctor_file, "w") as out:
 +                out.write(type_func_tmpl.render({
 +                    'CONFIG': config,
 +                    'namespace': namespace,
 +                    'class': tmpl,
 +                    'type_func': c,
 +                }))
 +
 +        for method in record.methods:
++            if config.is_hidden(record.name, "method", method.name):
++                log.debug(f"Skipping hidden method {record.name}.{method.name}")
++                continue
 +            m = TemplateMethod(namespace, record, method)
 +            method_file = os.path.join(output_dir, f"method.{record.name}.{method.name}.html")
 +            log.debug(f"Creating method file for {namespace.name}.{record.name}.{method.name}: {method_file}")
 +
 +            with open(method_file, "w") as out:
 +                out.write(method_tmpl.render({
 +                    'CONFIG': config,
 +                    'namespace': namespace,
 +                    'class': tmpl,
 +                    'method': m,
 +                }))
 +
 +        for type_func in record.functions:
++            if config.is_hidden(record.name, "method", type_func.name):
++                log.debug(f"Skipping hidden type function {record.name}.{type_func.name}")
++                continue
 +            f = TemplateFunction(namespace, type_func)
 +            type_func_file = os.path.join(output_dir, f"type_func.{record.name}.{type_func.name}.html")
 +            log.debug(f"Creating type func file for {namespace.name}.{record.name}.{type_func.name}: {type_func_file}")
 +
 +            with open(type_func_file, "w") as out:
 +                out.write(type_func_tmpl.render({
 +                    'CONFIG': config,
 +                    'namespace': namespace,
 +                    'class': tmpl,
 +                    'type_func': f,
 +                }))
 +
 +    return template_records
 +
 +
 +def _gen_unions(config, theme_config, output_dir, jinja_env, repository, all_unions):
 +    namespace = repository.namespace
 +
 +    union_tmpl = jinja_env.get_template(theme_config.union_template)
 +    method_tmpl = jinja_env.get_template(theme_config.method_template)
 +    type_func_tmpl = jinja_env.get_template(theme_config.type_func_template)
 +
 +    template_unions = []
 +
 +    for union in all_unions:
 +        if config.is_hidden(union.name):
 +            log.debug(f"Skipping hidden union {union.name}")
 +            continue
 +        union_file = os.path.join(output_dir, f"union.{union.name}.html")
 +        log.info(f"Creating union file for {namespace.name}.{union.name}: {union_file}")
 +
- def gen_content_files(config, theme_config, content_dir, output_dir, jinja_env, namespace):
++        tmpl = TemplateUnion(namespace, union, config)
 +        template_unions.append(tmpl)
 +
 +        with open(union_file, "w") as out:
 +            content = union_tmpl.render({
 +                'CONFIG': config,
 +                'namespace': namespace,
 +                'struct': tmpl,
 +            })
 +
 +            out.write(content)
 +
 +        for ctor in union.constructors:
++            if config.is_hidden(union.name, "constructor", ctor.name):
++                log.debug(f"Skipping hidden constructor {union.name}.{ctor.name}")
++                continue
 +            c = TemplateFunction(namespace, ctor)
 +            ctor_file = os.path.join(output_dir, f"ctor.{union.name}.{ctor.name}.html")
 +            log.debug(f"Creating ctor file for {namespace.name}.{union.name}.{ctor.name}: {ctor_file}")
 +
 +            with open(ctor_file, "w") as out:
 +                out.write(type_func_tmpl.render({
 +                    'CONFIG': config,
 +                    'namespace': namespace,
 +                    'class': tmpl,
 +                    'type_func': c,
 +                }))
 +
 +        for method in union.methods:
++            if config.is_hidden(union.name, "method", method.name):
++                log.debug(f"Skipping hidden method {union.name}.{method.name}")
++                continue
 +            m = TemplateMethod(namespace, union, method)
 +            method_file = os.path.join(output_dir, f"method.{union.name}.{method.name}.html")
 +            log.debug(f"Creating method file for {namespace.name}.{union.name}.{method.name}: {method_file}")
 +
 +            with open(method_file, "w") as out:
 +                out.write(method_tmpl.render({
 +                    'CONFIG': config,
 +                    'namespace': namespace,
 +                    'class': tmpl,
 +                    'method': m,
 +                }))
 +
 +        for type_func in union.functions:
++            if config.is_hidden(union.name, "function", type_func.name):
++                log.debug(f"Skipping hidden type function {union.name}.{type_func.name}")
++                continue
 +            f = TemplateFunction(namespace, type_func)
 +            type_func_file = os.path.join(output_dir, f"type_func.{union.name}.{type_func.name}.html")
 +            log.debug(f"Creating type func file for {namespace.name}.{union.name}.{type_func.name}: {type_func_file}")
 +
 +            with open(type_func_file, "w") as out:
 +                out.write(type_func_tmpl.render({
 +                    'CONFIG': config,
 +                    'namespace': namespace,
 +                    'class': tmpl,
 +                    'type_func': f,
 +                }))
 +
 +    return template_unions
 +
 +
 +def _gen_functions(config, theme_config, output_dir, jinja_env, repository, all_functions):
 +    namespace = repository.namespace
 +
 +    func_tmpl = jinja_env.get_template(theme_config.func_template)
 +
 +    template_functions = []
 +
 +    for func in all_functions:
 +        if config.is_hidden(func.name):
 +            log.debug(f"Skipping hidden function {func.name}")
 +            continue
 +        func_file = os.path.join(output_dir, f"func.{func.name}.html")
 +        log.info(f"Creating function file for {namespace.name}.{func.name}: {func_file}")
 +
 +        tmpl = TemplateFunction(namespace, func)
 +        template_functions.append(tmpl)
 +
 +        with open(func_file, "w") as out:
 +            content = func_tmpl.render({
 +                'CONFIG': config,
 +                'namespace': namespace,
 +                'func': tmpl,
 +            })
 +
 +            out.write(content)
 +
 +    return template_functions
 +
 +
 +def _gen_callbacks(config, theme_config, output_dir, jinja_env, repository, all_callbacks):
 +    namespace = repository.namespace
 +
 +    func_tmpl = jinja_env.get_template(theme_config.func_template)
 +
 +    template_callbacks = []
 +
 +    for func in all_callbacks:
 +        if config.is_hidden(func.name):
 +            log.debug(f"Skipping hidden callback {func.name}")
 +            continue
 +        func_file = os.path.join(output_dir, f"callback.{func.name}.html")
 +        log.info(f"Creating callback file for {namespace.name}.{func.name}: {func_file}")
 +
 +        tmpl = TemplateCallback(namespace, func)
 +        template_callbacks.append(tmpl)
 +
 +        with open(func_file, "w") as out:
 +            content = func_tmpl.render({
 +                'CONFIG': config,
 +                'namespace': namespace,
 +                'func': tmpl,
 +            })
 +
 +            out.write(content)
 +
 +    return template_callbacks
 +
 +
 +def _gen_function_macros(config, theme_config, output_dir, jinja_env, repository, all_functions):
 +    namespace = repository.namespace
 +
 +    func_tmpl = jinja_env.get_template(theme_config.func_template)
 +
 +    template_functions = []
 +
 +    for func in all_functions:
 +        if config.is_hidden(func.name):
 +            log.debug(f"Skipping hidden macro {func.name}")
 +            continue
 +        func_file = os.path.join(output_dir, f"func.{func.name}.html")
 +        log.info(f"Creating function macro file for {namespace.name}.{func.name}: {func_file}")
 +
 +        tmpl = TemplateFunction(namespace, func)
 +        template_functions.append(tmpl)
 +
 +        with open(func_file, "w") as out:
 +            content = func_tmpl.render({
 +                'CONFIG': config,
 +                'namespace': namespace,
 +                'func': tmpl,
 +            })
 +
 +            out.write(content)
 +
 +    return template_functions
 +
 +
-         src_file = os.path.join(content_dir, file_name)
++def gen_content_files(config, theme_config, content_dirs, output_dir, jinja_env, namespace):
 +    content_files = []
 +
 +    content_tmpl = jinja_env.get_template(theme_config.content_template)
 +    md = markdown.Markdown(extensions=utils.MD_EXTENSIONS, extension_configs=utils.MD_EXTENSIONS_CONF)
 +
 +    for file_name in config.content_files:
- def gen_content_images(config, content_dir, output_dir):
++        src_file = utils.find_extra_content_file(content_dirs, file_name)
 +
 +        src_data = ""
 +        with open(src_file, encoding='utf-8') as infile:
 +            source = []
 +            for line in infile:
 +                source.append(line)
 +            src_data = "".join(source)
 +
 +        dst_data = utils.preprocess_docs(src_data, namespace, md=md)
 +        title = "\n".join(md.Meta.get("title", ["Unknown document"]))
 +
 +        content_file = file_name.replace(".md", ".html")
 +        dst_file = os.path.join(output_dir, content_file)
 +
 +        content = {
 +            "abs_input_file": src_file,
 +            "abs_output_file": dst_file,
 +            "source_file": file_name,
 +            "output_file": content_file,
 +            "meta": md.Meta,
 +            "title": title,
 +            "data": dst_data,
 +        }
 +
 +        log.info(f"Generating content file {file_name}: {dst_file}")
 +        with open(dst_file, "w", encoding='utf-8') as outfile:
 +            outfile.write(content_tmpl.render({
 +                "CONFIG": config,
 +                "namespace": namespace,
 +                "content": content,
 +            }))
 +
 +        content_files.append({
 +            "title": title,
 +            "href": content_file,
 +        })
 +
 +        md.reset()
 +
 +    return content_files
 +
 +
-         infile = os.path.join(content_dir, image_file)
++def gen_content_images(config, content_dirs, output_dir):
 +    content_images = []
 +
 +    for image_file in config.content_images:
- def gen_reference(config, options, repository, templates_dir, theme_config, content_dir, output_dir):
++        infile = utils.find_extra_content_file(content_dirs, image_file)
 +        outfile = os.path.join(output_dir, os.path.basename(image_file))
 +        log.debug(f"Adding extra content image: {infile} -> {outfile}")
 +        content_images += [(infile, outfile)]
 +
 +    return content_images
 +
 +
 +def gen_types_hierarchy(config, theme_config, output_dir, jinja_env, repository):
 +    # All GObject sub-types
 +    objects_tree = repository.get_class_hierarchy(root="GObject.Object")
 +
 +    # All GTypeInstance sub-types
 +    typed_tree = repository.get_class_hierarchy()
 +
 +    res = ["<h1>Classes Hierarchy</h1>"]
 +
 +    def dump_tree(node, out):
 +        for k in node:
 +            if '.' in k:
 +                out.append(f'<li class="type"><code>{k}</code>')
 +            else:
 +                out.append(f'<li class="type"><a href="class.{k}.html"><code>{k}</code></a>')
 +            if len(node[k]) != 0:
 +                out.append('<ul class="type">')
 +                dump_tree(node[k], out)
 +                out.append("</ul>")
 +            out.append("</li>")
 +
 +    if len(objects_tree) != 0:
 +        res += ["<div class=\"docblock\">"]
 +        res += ["<ul class=\"type root\">"]
 +        res += [" <li class=\"type\"><code>GObject</code></li><ul class=\"type\">"]
 +        dump_tree(objects_tree, res)
 +        res += [" </ul></li>"]
 +        res += ["</ul>"]
 +        res += ["</div>"]
 +
 +    if len(typed_tree) != 0:
 +        res += ["<div class=\"docblock\">"]
 +        res += ["<ul class=\"type root\">"]
 +        res += [" <li class=\"type\"><code>GTypeInstance</code></li><ul class=\"type\">"]
 +        dump_tree(typed_tree, res)
 +        res += [" </ul></li>"]
 +        res += ["</ul>"]
 +        res += ["</div>"]
 +
 +    content = {
 +        "output_file": "classes_hierarchy.html",
 +        "meta": {
 +            "keywords": "types, hierarchy, classes",
 +        },
 +        "title": "Classes Hierarchy",
 +        "data": Markup("\n".join(res)),
 +    }
 +
 +    content_tmpl = jinja_env.get_template(theme_config.content_template)
 +
 +    namespace = repository.namespace
 +
 +    dst_file = os.path.join(output_dir, content["output_file"])
 +    log.info(f"Generating type hierarchy file: {dst_file}")
 +    with open(dst_file, "w") as outfile:
 +        outfile.write(content_tmpl.render({
 +            "CONFIG": config,
 +            "namespace": namespace,
 +            "content": content,
 +        }))
 +
 +    return {
 +        "title": content["title"],
 +        "href": content["output_file"],
 +    }
 +
 +
 +def gen_devhelp(config, repository, namespace, symbols, content_files):
 +    book = etree.Element('book')
 +    book.set("xmlns", "http://www.devhelp.net/book")
 +    book.set("title", f"{namespace.name}-{namespace.version} Reference Manual")
 +    book.set("link", "index.html")
 +    book.set("author", f"{config.authors}")
 +    book.set("name", f"{namespace.name}")
 +    book.set("version", "2")
 +    book.set("language", "c")
 +
 +    chapters = etree.SubElement(book, 'chapters')
 +
 +    for f in content_files:
 +        sub = etree.SubElement(chapters, 'sub')
 +        sub.set("name", f["title"])
 +        sub.set("link", f["href"])
 +
 +    for section, types in symbols.items():
 +        if len(types) == 0:
 +            continue
 +
 +        sub = etree.SubElement(chapters, "sub")
 +        sub.set("name", section.replace("_", " ").capitalize())
 +        sub.set("link", f"index.html#{section}")
 +
 +        for t in types:
 +            sub_section = etree.SubElement(sub, "sub")
 +            sub_section.set("name", t.name)
 +            sub_section.set("link", f"{FRAGMENT[section]}.{t.name}.html")
 +
 +    functions = etree.SubElement(book, "functions")
 +    for section, types in symbols.items():
 +        if len(types) == 0:
 +            continue
 +
 +        for t in types:
 +            if section in ["functions", "function_macros"]:
 +                keyword = etree.SubElement(functions, "keyword")
 +                if section == "functions":
 +                    keyword.set("type", "function")
 +                else:
 +                    keyword.set("type", "macro")
 +                keyword.set("name", t.identifier)
 +                keyword.set("link", f"func.{t.name}.html")
 +                if t.available_since is not None:
 +                    keyword.set("since", t.available_since)
 +                if t.deprecated_since is not None and t.deprecated_since["version"] is not None:
 +                    keyword.set("deprecated", t.deprecated_since["version"])
 +                continue
 +
 +            if section == "constants":
 +                keyword = etree.SubElement(functions, "keyword")
 +                keyword.set("type", "constant")
 +                keyword.set("name", t.identifier)
 +                keyword.set("link", f"constant.{t.name}.html")
 +                if t.available_since is not None:
 +                    keyword.set("since", t.available_since)
 +                if t.deprecated_since is not None and t.deprecated_since["version"] is not None:
 +                    keyword.set("deprecated", t.deprecated_since["version"])
 +                continue
 +
 +            if section in ["aliases", "bitfields", "classes", "domains", "enums", "interfaces", "structs", "unions"]:
 +                # Skip anonymous types; e.g. GValue's anonymous union
 +                if t.type_cname is None:
 +                    continue
 +                keyword = etree.SubElement(functions, "keyword")
 +                if section == "aliases":
 +                    keyword.set("type", "typedef")
 +                elif section in ["bitfields", "domains", "enums"]:
 +                    keyword.set("type", "enum")
 +                elif section == "unions":
 +                    keyword.set("type", "union")
 +                else:
 +                    keyword.set("type", "struct")
 +                keyword.set("name", t.type_cname)
 +                keyword.set("link", f"{FRAGMENT[section]}.{t.name}.html")
 +                if t.available_since is not None:
 +                    keyword.set("since", t.available_since)
 +                if t.deprecated_since is not None and t.deprecated_since["version"] is not None:
 +                    keyword.set("deprecated", t.deprecated_since["version"])
 +
 +            for m in getattr(t, "members", []):
 +                keyword = etree.SubElement(functions, "keyword")
 +                keyword.set("type", "constant")
 +                keyword.set("name", m.name)
 +                keyword.set("link", f"{FRAGMENT[section]}.{t.name}.html")
 +
 +            for f in getattr(t, "fields", []):
 +                keyword = etree.SubElement(functions, "keyword")
 +                keyword.set("type", "member")
 +                keyword.set("name", f"{t.type_cname}.{f.name}")
 +                keyword.set("link", f"{FRAGMENT[section]}.{t.name}.html")
 +
 +            class_struct = getattr(t, "class_struct", None)
 +            if class_struct is not None:
 +                for f in getattr(class_struct, "fields", []):
 +                    keyword = etree.SubElement(functions, "keyword")
 +                    keyword.set("type", "member")
 +                    keyword.set("name", f"{t.class_name}.{f.name}")
 +                    if section == "class":
 +                        keyword.set("link", f"class.{t.name}.html#class-struct")
 +                    elif section == "interface":
 +                        keyword.set("link", f"iface.{t.name}.html#interface-struct")
 +                    else:
 +                        keyword.set("link", f"{FRAGMENT[section]}.{t.name}.html")
 +
 +            for m in getattr(t, "methods", []):
 +                keyword = etree.SubElement(functions, "keyword")
 +                keyword.set("type", "function")
 +                keyword.set("name", m['identifier'])
 +                keyword.set("link", f"method.{t.name}.{m['name']}.html")
 +                if m["available_since"] is not None:
 +                    keyword.set("since", m["available_since"])
 +                if m["deprecated_since"] is not None:
 +                    keyword.set("deprecated", m["deprecated_since"])
 +
 +            for c in getattr(t, "ctors", []):
 +                keyword = etree.SubElement(functions, "keyword")
 +                keyword.set("type", "function")
 +                keyword.set("name", c['identifier'])
 +                keyword.set("link", f"ctor.{t.name}.{c['name']}.html")
 +                if c["available_since"] is not None:
 +                    keyword.set("since", c["available_since"])
 +                if c["deprecated_since"] is not None:
 +                    keyword.set("deprecated", c["deprecated_since"])
 +
 +            for f in getattr(t, "type_funcs", []):
 +                keyword = etree.SubElement(functions, "keyword")
 +                keyword.set("type", "function")
 +                keyword.set("name", f['identifier'])
 +                keyword.set("link", f"type_func.{t.name}.{f['name']}.html")
 +                if f["available_since"] is not None:
 +                    keyword.set("since", f["available_since"])
 +                if f["deprecated_since"] is not None:
 +                    keyword.set("deprecated", f["deprecated_since"])
 +
 +            for m in getattr(t, "class_methods", []):
 +                keyword = etree.SubElement(functions, "keyword")
 +                keyword.set("type", "function")
 +                keyword.set("name", m['identifier'])
 +                keyword.set("link", f"class_method.{t.name}.{m['name']}.html")
 +                if m["available_since"] is not None:
 +                    keyword.set("since", m["available_since"])
 +                if m["deprecated_since"] is not None:
 +                    keyword.set("deprecated", m["deprecated_since"])
 +
 +            for p in getattr(t, "properties", []):
 +                keyword = etree.SubElement(functions, "keyword")
 +                keyword.set("type", "property")
 +                keyword.set("name", f"The {t.type_cname}:{p['name']} property")
 +                keyword.set("link", f"property.{t.name}.{p['name']}.html")
 +                if p["available_since"] is not None:
 +                    keyword.set("since", p["available_since"])
 +                if p["deprecated_since"] is not None:
 +                    keyword.set("deprecated", p["deprecated_since"])
 +
 +            for s in getattr(t, "signals", []):
 +                keyword = etree.SubElement(functions, "keyword")
 +                keyword.set("type", "signal")
 +                keyword.set("name", f"The {t.type_cname}::{s['name']} signal")
 +                keyword.set("link", f"signal.{t.name}.{s['name']}.html")
 +                if s["available_since"] is not None:
 +                    keyword.set("since", s["available_since"])
 +                if s["deprecated_since"] is not None:
 +                    keyword.set("deprecated", s["deprecated_since"])
 +
 +    return etree.ElementTree(book)
 +
 +
-     content_files = gen_content_files(config, theme_config, content_dir, ns_dir, jinja_env, namespace)
-     content_images = gen_content_images(config, content_dir, ns_dir)
++def gen_reference(config, options, repository, templates_dir, theme_config, content_dirs, output_dir):
 +    theme_dir = os.path.join(templates_dir, theme_config.name.lower())
 +    log.debug(f"Loading jinja templates from {theme_dir}")
 +
 +    fs_loader = jinja2.FileSystemLoader(theme_dir)
 +    jinja_env = jinja2.Environment(loader=fs_loader, autoescape=jinja2.select_autoescape(['html']))
 +
 +    namespace = repository.namespace
 +
 +    symbols = {
 +        "aliases": sorted(namespace.get_aliases(), key=lambda alias: alias.name.lower()),
 +        "bitfields": sorted(namespace.get_bitfields(), key=lambda bitfield: bitfield.name.lower()),
 +        "callbacks": sorted(namespace.get_callbacks(), key=lambda callback: callback.name.lower()),
 +        "classes": sorted(namespace.get_classes(), key=lambda cls: cls.name.lower()),
 +        "constants": sorted(namespace.get_constants(), key=lambda const: const.name.lower()),
 +        "domains": sorted(namespace.get_error_domains(), key=lambda domain: domain.name.lower()),
 +        "enums": sorted(namespace.get_enumerations(), key=lambda enum: enum.name.lower()),
 +        "functions": sorted(namespace.get_functions(), key=lambda func: func.name.lower()),
 +        "function_macros": sorted(namespace.get_effective_function_macros(), key=lambda func: func.name.lower()),
 +        "interfaces": sorted(namespace.get_interfaces(), key=lambda interface: interface.name.lower()),
 +        "structs": sorted(namespace.get_effective_records(), key=lambda record: record.name.lower()),
 +        "unions": sorted(namespace.get_unions(), key=lambda union: union.name.lower()),
 +    }
 +
 +    all_indices = {
 +        "aliases": _gen_aliases,
 +        "bitfields": _gen_bitfields,
 +        "callbacks": _gen_callbacks,
 +        "classes": _gen_classes,
 +        "constants": _gen_constants,
 +        "domains": _gen_domains,
 +        "enums": _gen_enums,
 +        "functions": _gen_functions,
 +        "function_macros": _gen_function_macros,
 +        "interfaces": _gen_interfaces,
 +        "structs": _gen_records,
 +        "unions": _gen_unions,
 +    }
 +
 +    if options.no_namespace_dir:
 +        ns_dir = output_dir
 +    else:
 +        ns_dir = os.path.join(output_dir, f"{namespace.name}-{namespace.version}")
 +
 +    log.debug(f"Creating output path for the namespace: {ns_dir}")
 +    os.makedirs(ns_dir, exist_ok=True)
 +
-         gdgenindices.gen_indices(config, repository, content_dir, ns_dir)
++    content_files = gen_content_files(config, theme_config, content_dirs, ns_dir, jinja_env, namespace)
++    content_images = gen_content_images(config, content_dirs, ns_dir)
 +    content_files.append(gen_types_hierarchy(config, theme_config, ns_dir, jinja_env, repository))
 +
 +    if options.sections == [] or options.sections == ["all"]:
 +        gen_indices = list(all_indices.keys())
 +    elif options.sections == ["none"]:
 +        gen_indices = []
 +    else:
 +        gen_indices = options.sections
 +
 +    log.info(f"Generating references for: {gen_indices}")
 +
 +    template_symbols = {}
 +
 +    # Each section is isolated, so we run it into a thread pool
 +    with concurrent.futures.ThreadPoolExecutor() as executor:
 +        futures_to_section = {}
 +        for section in gen_indices:
 +            s = symbols.get(section, [])
 +            if s is None:
 +                log.debug(f"No symbols for section {section}")
 +                continue
 +
 +            generator = all_indices.get(section, None)
 +            if generator is None:
 +                log.debug(f"No generator for section {section}")
 +                continue
 +
 +            f = executor.submit(generator, config, theme_config, ns_dir, jinja_env, repository, s)
 +            futures_to_section[f] = section
 +
 +        for future in concurrent.futures.as_completed(futures_to_section):
 +            section = futures_to_section[future]
 +            try:
 +                res = future.result()
 +            except Exception as e:
 +                if log.log_fatal_warnings:
 +                    import traceback
 +                    traceback.print_exc()
 +                log.warning(f"Section {section} raised {e}")
 +            else:
 +                template_symbols[section] = res
 +
 +    # The concurrent processing introduces non-determinism. Ensure iteration order is reproducible
 +    # by sorting by key. This has virtually no overhead since the values are not copied.
 +    template_symbols = dict(sorted(template_symbols.items()))
 +
 +    ns_tmpl = jinja_env.get_template(theme_config.namespace_template)
 +    ns_file = os.path.join(ns_dir, "index.html")
 +    log.info(f"Creating namespace index file for {namespace.name}-{namespace.version}: {ns_file}")
 +    with open(ns_file, "w") as out:
 +        out.write(ns_tmpl.render({
 +            "CONFIG": config,
 +            "repository": repository,
 +            "namespace": namespace,
 +            "symbols": template_symbols,
 +            "content_files": content_files,
 +        }))
 +
 +    if config.devhelp:
 +        # Devhelp expects the book file to have the same basename as the directory it is in.
 +        devhelp_file = os.path.join(ns_dir, f"{os.path.basename(ns_dir)}.devhelp2")
 +        log.info(f"Creating DevHelp file for {namespace.name}-{namespace.version}: {devhelp_file}")
 +        res = gen_devhelp(config, repository, namespace, template_symbols, content_files)
 +        res.write(devhelp_file, encoding="UTF-8")
 +
 +    if config.search_index:
-         src = os.path.join(content_dir, config.urlmap_file)
++        gdgenindices.gen_indices(config, repository, content_dirs, ns_dir)
 +
 +    copy_files = []
 +    if theme_config.css is not None:
 +        style_src = os.path.join(theme_dir, theme_config.css)
 +        style_dst = os.path.join(ns_dir, theme_config.css)
 +        copy_files.append((style_src, style_dst))
 +
 +    for extra_file in theme_config.extra_files:
 +        src = os.path.join(theme_dir, extra_file)
 +        dst = os.path.join(ns_dir, extra_file)
 +        copy_files.append((src, dst))
 +
 +    if config.urlmap_file is not None:
-     parser.add_argument("--content-dir", default=None, help="the base directory with the extra content")
++        src = utils.find_extra_content_file(content_dirs, config.urlmap_file)
 +        dst = os.path.join(ns_dir, os.path.basename(config.urlmap_file))
 +        copy_files.append((src, dst))
 +
 +    copy_files.extend(content_images)
 +
 +    def copy_worker(src, dst):
 +        log.info(f"Copying file {src}: {dst}")
 +        dst_dir = os.path.dirname(dst)
 +        os.makedirs(dst_dir, exist_ok=True)
 +        shutil.copy(src, dst)
 +
 +    with concurrent.futures.ThreadPoolExecutor() as executor:
 +        for (src, dst) in copy_files:
 +            executor.submit(copy_worker, src, dst)
 +
 +
 +def add_args(parser):
 +    parser.add_argument("--add-include-path", action="append", dest="include_paths", default=[],
 +                        help="include paths for other GIR files")
 +    parser.add_argument("-C", "--config", metavar="FILE", help="the configuration file")
 +    parser.add_argument("--dry-run", action="store_true", help="parses the GIR file without generating files")
 +    parser.add_argument("--templates-dir", default=None, help="the base directory with the theme templates")
-     parser.add_argument("--no-namespace-dir", action="store_true", help="do not create a namespace directory under the output directory")
++    parser.add_argument("--content-dir", action="append", dest="content_dirs", default=[],
++                        help="the base directories with the extra content")
 +    parser.add_argument("--theme-name", default="basic", help="the theme to use")
 +    parser.add_argument("--output-dir", default=None, help="the output directory for the index files")
-     content_dir = options.content_dir or os.getcwd()
++    parser.add_argument("--no-namespace-dir", action="store_true",
++                        help="do not create a namespace directory under the output directory")
 +    parser.add_argument("--section", action="append", dest="sections", default=[], help="the sections to generate, or 'all'")
 +    parser.add_argument("infile", metavar="GIRFILE", type=argparse.FileType('r', encoding='UTF-8'),
 +                        default=sys.stdin, help="the GIR file to parse")
 +
 +
 +def run(options):
 +    log.info(f"Loading config file: {options.config}")
 +
 +    conf = config.GIDocConfig(options.config)
 +
 +    output_dir = options.output_dir or os.getcwd()
-         gen_reference(conf, options, parser.get_repository(), templates_dir, theme_conf, content_dir, output_dir)
++
++    content_dirs = options.content_dirs
++    if content_dirs == []:
++        content_dirs = [os.getcwd()]
 +
 +    if options.templates_dir is not None:
 +        templates_dir = options.templates_dir
 +    else:
 +        templates_dir = conf.get_templates_dir()
 +        if templates_dir is None:
 +            templates_dir = os.path.join(os.path.dirname(__file__), 'templates')
 +
 +    theme_name = conf.get_theme_name(default=options.theme_name)
 +    theme_conf = config.GITemplateConfig(templates_dir, theme_name)
 +
 +    log.debug(f"Templates directory: {templates_dir}")
 +    log.info(f"Theme name: {theme_conf.name}")
 +    log.info(f"Output directory: {output_dir}")
 +
 +    paths = []
 +    paths.extend(options.include_paths)
 +    paths.extend(utils.default_search_paths())
 +    log.debug(f"Search paths: {paths}")
 +
 +    log.info("Parsing GIR file")
 +    parser = gir.GirParser(search_paths=paths)
 +    parser.parse(options.infile)
 +
 +    if not options.dry_run:
 +        log.checkpoint()
++        gen_reference(conf, options, parser.get_repository(), templates_dir, theme_conf, content_dirs, output_dir)
 +
 +    return 0
index da8846b9e4ef122dabc412e2f7e6be560415946a,0000000000000000000000000000000000000000..e759c2db70c112d809f05655bd87fad930a1301c
mode 100644,000000..100644
--- /dev/null
@@@ -1,794 -1,0 +1,838 @@@
-         add_index_terms(index_terms, [callback.name.lower()], idx)
 +# SPDX-FileCopyrightText: 2020 GNOME Foundation
 +# SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +
 +import argparse
 +import json
 +import os
 +import sys
 +
 +from . import config, core, gir, log, porter, utils
 +
 +
 +HELP_MSG = "Generates the symbol indices for search"
 +
 +MISSING_DESCRIPTION = "No description available."
 +
 +
 +def add_index_terms(index, terms, docid):
 +    for term in terms:
 +        docs = index.setdefault(term, [])
 +        if docid not in docs:
 +            docs.append(docid)
 +
 +
 +def _gen_aliases(config, stemmer, index, repository, symbols):
 +    index_symbols = index["symbols"]
 +    index_terms = index["terms"]
 +
 +    for alias in symbols:
 +        if config.is_hidden(alias.name):
 +            log.debug(f"Skipping hidden type {alias.name}")
 +            continue
 +        idx = len(index_symbols)
 +        if alias.doc is not None:
 +            description = alias.doc.content
 +        else:
 +            description = MISSING_DESCRIPTION
 +        index_symbols.append({
 +            "type": "alias",
 +            "name": alias.name,
 +            "ctype": alias.base_ctype,
 +            "summary": utils.preprocess_docs(description, repository.namespace, summary=True, plain=True),
 +        })
 +        add_index_terms(index_terms, [alias.base_ctype.lower()], idx)
 +        add_index_terms(index_terms, utils.index_identifier(alias.name, stemmer), idx)
 +        add_index_terms(index_terms, utils.index_description(description, stemmer), idx)
 +
 +
 +def _gen_bitfields(config, stemmer, index, repository, symbols):
 +    index_symbols = index["symbols"]
 +    index_terms = index["terms"]
 +
 +    for bitfield in symbols:
 +        if config.is_hidden(bitfield.name):
 +            log.debug(f"Skipping hidden type {bitfield.name}")
 +            continue
 +        idx = len(index_symbols)
 +        if bitfield.doc is not None:
 +            description = bitfield.doc.content
 +        else:
 +            description = MISSING_DESCRIPTION
 +        index_symbols.append({
 +            "type": "bitfield",
 +            "name": bitfield.name,
 +            "ctype": bitfield.base_ctype,
 +            "summary": utils.preprocess_docs(description, repository.namespace, summary=True, plain=True),
 +        })
 +        add_index_terms(index_terms, [bitfield.base_ctype.lower()], idx)
 +        add_index_terms(index_terms, utils.index_identifier(bitfield.name, stemmer), idx)
 +        add_index_terms(index_terms, utils.index_description(description, stemmer), idx)
 +
 +        for member in bitfield.members:
 +            add_index_terms(index_terms, [member.name], idx)
 +            if member.doc is not None:
 +                add_index_terms(index_terms, utils.index_description(member.doc.content, stemmer), idx)
 +
 +        for func in bitfield.functions:
 +            func_idx = len(index_symbols)
 +            if func.doc is not None:
 +                func_desc = func.doc.content
 +            else:
 +                func_desc = MISSING_DESCRIPTION
 +            index_symbols.append({
 +                "type": "type_func",
 +                "name": func.name,
 +                "type_name": bitfield.name,
 +                "ident": func.identifier,
 +                "summary": utils.preprocess_docs(func_desc, repository.namespace, summary=True, plain=True)
 +            })
 +            add_index_terms(index_terms, [func.identifier], func_idx)
 +            add_index_terms(index_terms, utils.index_symbol(func.name, stemmer), func_idx)
 +            add_index_terms(index_terms, utils.index_description(func_desc, stemmer), func_idx)
 +
 +
 +def _gen_callbacks(config, stemmer, index, repository, symbols):
 +    index_symbols = index["symbols"]
 +    index_terms = index["terms"]
 +
 +    for callback in symbols:
 +        if config.is_hidden(callback.name):
 +            log.debug(f"Skipping hidden callback {callback.name}")
 +            continue
 +        idx = len(index_symbols)
 +        if callback.doc is not None:
 +            cb_desc = callback.doc.content
 +        else:
 +            cb_desc = MISSING_DESCRIPTION
 +        index_symbols.append({
 +            "type": "callback",
 +            "name": callback.name,
++            "ctype": callback.base_ctype,
 +            "summary": utils.preprocess_docs(cb_desc, repository.namespace, summary=True, plain=True),
 +        })
- def gen_indices(config, repository, content_dir, output_dir):
++        add_index_terms(index_terms, [callback.base_ctype.lower()], idx)
 +        add_index_terms(index_terms, utils.index_identifier(callback.name, stemmer), idx)
 +        add_index_terms(index_terms, utils.index_description(cb_desc, stemmer), idx)
 +
 +
 +def _gen_classes(config, stemmer, index, repository, symbols):
 +    namespace = repository.namespace
 +
 +    index_symbols = index["symbols"]
 +    index_terms = index["terms"]
 +
 +    for cls in symbols:
 +        if config.is_hidden(cls.name):
 +            log.debug(f"Skipping hidden type {cls.name}")
 +            continue
 +        idx = len(index_symbols)
 +        if cls.doc is not None:
 +            cls_desc = cls.doc.content
 +        else:
 +            cls_desc = MISSING_DESCRIPTION
 +        index_symbols.append({
 +            "type": "class",
 +            "name": cls.name,
 +            "ctype": cls.base_ctype,
 +            "summary": utils.preprocess_docs(cls_desc, repository.namespace, summary=True, plain=True),
 +        })
 +        add_index_terms(index_terms, [cls.base_ctype.lower()], idx)
 +        add_index_terms(index_terms, utils.index_identifier(cls.name, stemmer), idx)
 +        add_index_terms(index_terms, utils.index_description(cls_desc, stemmer), idx)
 +
 +        for ctor in cls.constructors:
 +            ctor_idx = len(index_symbols)
 +            if ctor.doc is not None:
 +                ctor_desc = ctor.doc.content
 +            else:
 +                ctor_desc = MISSING_DESCRIPTION
 +            index_symbols.append({
 +                "type": "ctor",
 +                "name": ctor.name,
 +                "type_name": cls.name,
 +                "ident": ctor.identifier,
 +                "summary": utils.preprocess_docs(ctor_desc, repository.namespace, summary=True, plain=True),
 +            })
 +            add_index_terms(index_terms, [ctor.identifier], ctor_idx)
 +            add_index_terms(index_terms, utils.index_symbol(ctor.name, stemmer), ctor_idx)
 +            add_index_terms(index_terms, utils.index_description(ctor_desc, stemmer), ctor_idx)
 +
 +        for method in cls.methods:
 +            method_idx = len(index_symbols)
 +            if method.doc is not None:
 +                method_desc = method.doc.content
 +            else:
 +                method_desc = MISSING_DESCRIPTION
 +            index_symbols.append({
 +                "type": "method",
 +                "name": method.name,
 +                "type_name": cls.name,
 +                "ident": method.identifier,
 +                "summary": utils.preprocess_docs(method_desc, repository.namespace, summary=True, plain=True),
 +            })
 +            add_index_terms(index_terms, [method.identifier], method_idx)
 +            add_index_terms(index_terms, utils.index_symbol(method.name, stemmer), method_idx)
 +            add_index_terms(index_terms, utils.index_description(method_desc, stemmer), method_idx)
 +
 +        for func in cls.functions:
 +            func_idx = len(index_symbols)
 +            if func.doc is not None:
 +                func_desc = func.doc.content
 +            else:
 +                func_desc = MISSING_DESCRIPTION
 +            index_symbols.append({
 +                "type": "type_func",
 +                "name": func.name,
 +                "type_name": cls.name,
 +                "ident": func.identifier,
 +                "summary": utils.preprocess_docs(func_desc, repository.namespace, summary=True, plain=True),
 +            })
 +            add_index_terms(index_terms, [func.identifier], func_idx)
 +            add_index_terms(index_terms, utils.index_symbol(func.name, stemmer), func_idx)
 +            add_index_terms(index_terms, utils.index_description(func_desc, stemmer), func_idx)
 +
 +        for prop_name, prop in cls.properties.items():
 +            if config.is_hidden(cls.name, 'property', prop_name):
 +                log.debug(f"Skipping hidden property {cls.name}.{prop_name}")
 +                continue
 +            prop_idx = len(index_symbols)
 +            if prop.doc is not None:
 +                prop_desc = prop.doc.content
 +            else:
 +                prop_desc = MISSING_DESCRIPTION
 +            index_symbols.append({
 +                "type": "property",
 +                "name": prop.name,
 +                "type_name": cls.name,
 +                "summary": utils.preprocess_docs(prop_desc, repository.namespace, summary=True, plain=True),
 +            })
 +            add_index_terms(index_terms, utils.index_symbol(prop.name, stemmer), prop_idx)
 +            add_index_terms(index_terms, utils.index_description(prop_desc, stemmer), prop_idx)
 +
 +        for signal_name, signal in cls.signals.items():
 +            if config.is_hidden(cls.name, 'signal', signal_name):
 +                log.debug(f"Skipping hidden signal {cls.name}.{signal_name}")
 +                continue
 +            signal_idx = len(index_symbols)
 +            if signal.doc is not None:
 +                signal_desc = signal.doc.content
 +            else:
 +                signal_desc = MISSING_DESCRIPTION
 +            index_symbols.append({
 +                "type": "signal",
 +                "name": signal.name,
 +                "type_name": cls.name,
 +                "summary": utils.preprocess_docs(signal_desc, repository.namespace, summary=True, plain=True),
 +            })
 +            add_index_terms(index_terms, utils.index_symbol(signal.name, stemmer), signal_idx)
 +            add_index_terms(index_terms, utils.index_description(signal_desc, stemmer), signal_idx)
 +
 +        for vfunc in cls.virtual_methods:
 +            vfunc_idx = len(index_symbols)
 +            if vfunc.doc is not None:
 +                vfunc_desc = vfunc.doc.content
 +            else:
 +                vfunc_desc = MISSING_DESCRIPTION
 +            index_symbols.append({
 +                "type": "vfunc",
 +                "name": vfunc.name,
 +                "type_name": cls.name,
 +                "summary": utils.preprocess_docs(vfunc_desc, repository.namespace, summary=True, plain=True),
 +            })
 +            add_index_terms(index_terms, utils.index_symbol(vfunc.name, stemmer), vfunc_idx)
 +            add_index_terms(index_terms, utils.index_description(vfunc_desc, stemmer), vfunc_idx)
 +
 +        if cls.type_struct is not None:
 +            cls_struct = namespace.find_record(cls.type_struct)
 +            for cls_method in cls_struct.methods:
 +                cls_method_idx = len(index_symbols)
 +                if cls_method.doc is not None:
 +                    cls_method_desc = cls_method.doc.content
 +                else:
 +                    cls_method_desc = MISSING_DESCRIPTION
 +                index_symbols.append({
 +                    "type": "class_method",
 +                    "name": cls_method.name,
 +                    "type_name": cls_struct.name,
 +                    "struct_for": cls_struct.struct_for,
 +                    "ident": cls_method.identifier,
 +                    "summary": utils.preprocess_docs(cls_method_desc, repository.namespace, summary=True, plain=True),
 +                })
 +                add_index_terms(index_terms, [cls_method.identifier], cls_method_idx)
 +                add_index_terms(index_terms, utils.index_symbol(cls_method.name, stemmer), cls_method_idx)
 +                add_index_terms(index_terms, utils.index_description(cls_method_desc, stemmer), cls_method_idx)
 +
 +
 +def _gen_constants(config, stemmer, index, repository, symbols):
 +    index_symbols = index["symbols"]
 +    index_terms = index["terms"]
 +
 +    for const in symbols:
 +        if config.is_hidden(const.name):
 +            log.debug(f"Skipping hidden const {const.name}")
 +            continue
 +        idx = len(index_symbols)
 +        if const.doc is not None:
 +            const_desc = const.doc.content
 +        else:
 +            const_desc = MISSING_DESCRIPTION
 +        index_symbols.append({
 +            "type": "constant",
 +            "name": const.name,
 +            "ident": const.ctype,
 +            "summary": utils.preprocess_docs(const_desc, repository.namespace, summary=True, plain=True),
 +        })
 +        add_index_terms(index_terms, [const.ctype.lower()], idx)
 +        add_index_terms(index_terms, utils.index_symbol(const.name, stemmer), idx)
 +        add_index_terms(index_terms, utils.index_description(const_desc, stemmer), idx)
 +
 +
 +def _gen_domains(config, stemmer, index, repository, symbols):
 +    index_symbols = index["symbols"]
 +    index_terms = index["terms"]
 +
 +    for domain in symbols:
 +        if config.is_hidden(domain.name):
 +            log.debug(f"Skipping hidden type {domain.name}")
 +            continue
 +        idx = len(index_symbols)
 +        if domain.doc is not None:
 +            domain_desc = domain.doc.content
 +        else:
 +            domain_desc = MISSING_DESCRIPTION
 +        index_symbols.append({
 +            "type": "domain",
 +            "name": domain.name,
 +            "ctype": domain.base_ctype,
 +            "summary": utils.preprocess_docs(domain_desc, repository.namespace, summary=True, plain=True),
 +        })
 +        add_index_terms(index_terms, [domain.base_ctype.lower()], idx)
 +        add_index_terms(index_terms, utils.index_identifier(domain.name, stemmer), idx)
 +        add_index_terms(index_terms, utils.index_description(domain_desc, stemmer), idx)
 +
 +        for member in domain.members:
 +            add_index_terms(index_terms, [member.name], idx)
 +            if member.doc is not None:
 +                add_index_terms(index_terms, utils.index_description(member.doc.content, stemmer), idx)
 +
 +        for func in domain.functions:
 +            func_idx = len(index_symbols)
 +            if func.doc is not None:
 +                func_desc = func.doc.content
 +            else:
 +                func_desc = MISSING_DESCRIPTION
 +            index_symbols.append({
 +                "type": "type_func",
 +                "name": func.name,
 +                "type_name": domain.name,
 +                "ident": func.identifier,
 +                "summary": utils.preprocess_docs(func_desc, repository.namespace, summary=True, plain=True),
 +            })
 +            add_index_terms(index_terms, [func.identifier], func_idx)
 +            add_index_terms(index_terms, utils.index_symbol(func.name, stemmer), func_idx)
 +            add_index_terms(index_terms, utils.index_description(func_desc, stemmer), func_idx)
 +
 +
 +def _gen_enums(config, stemmer, index, repository, symbols):
 +    index_symbols = index["symbols"]
 +    index_terms = index["terms"]
 +
 +    for enum in symbols:
 +        if config.is_hidden(enum.name):
 +            log.debug(f"Skipping hidden type {enum.name}")
 +            continue
 +        idx = len(index_symbols)
 +        if enum.doc is not None:
 +            enum_desc = enum.doc.content
 +        else:
 +            enum_desc = MISSING_DESCRIPTION
 +        index_symbols.append({
 +            "type": "enum",
 +            "name": enum.name,
 +            "ctype": enum.base_ctype,
 +            "summary": utils.preprocess_docs(enum_desc, repository.namespace, summary=True, plain=True),
 +        })
 +        add_index_terms(index_terms, [enum.base_ctype.lower()], idx)
 +        add_index_terms(index_terms, utils.index_identifier(enum.name, stemmer), idx)
 +        add_index_terms(index_terms, utils.index_description(enum_desc, stemmer), idx)
 +
 +        for member in enum.members:
 +            add_index_terms(index_terms, [member.name], idx)
 +            if member.doc is not None:
 +                add_index_terms(index_terms, utils.index_description(member.doc.content, stemmer), idx)
 +
 +        for func in enum.functions:
 +            func_idx = len(index_symbols)
 +            if func.doc is not None:
 +                func_desc = func.doc.content
 +            else:
 +                func_desc = MISSING_DESCRIPTION
 +            index_symbols.append({
 +                "type": "type_func",
 +                "name": func.name,
 +                "type_name": enum.name,
 +                "ident": func.identifier,
 +                "summary": utils.preprocess_docs(func_desc, repository.namespace, summary=True, plain=True),
 +            })
 +            add_index_terms(index_terms, [func.identifier], func_idx)
 +            add_index_terms(index_terms, utils.index_symbol(func.name, stemmer), func_idx)
 +            add_index_terms(index_terms, utils.index_description(func_desc, stemmer), func_idx)
 +
 +
 +def _gen_functions(config, stemmer, index, repository, symbols):
 +    index_symbols = index["symbols"]
 +    index_terms = index["terms"]
 +
 +    for func in symbols:
 +        if config.is_hidden(func.name):
 +            log.debug(f"Skipping hidden function {func.name}")
 +            continue
 +        idx = len(index_symbols)
 +        if func.doc is not None:
 +            func_desc = func.doc.content
 +        else:
 +            func_desc = MISSING_DESCRIPTION
 +        index_symbols.append({
 +            "type": "function",
 +            "name": func.name,
 +            "ident": func.identifier,
 +            "summary": utils.preprocess_docs(func_desc, repository.namespace, summary=True, plain=True),
 +        })
 +        add_index_terms(index_terms, [func.identifier], idx)
 +        add_index_terms(index_terms, utils.index_symbol(func.name, stemmer), idx)
 +        add_index_terms(index_terms, utils.index_description(func_desc, stemmer), idx)
 +
 +
 +def _gen_function_macros(config, stemmer, index, repository, symbols):
 +    index_symbols = index["symbols"]
 +    index_terms = index["terms"]
 +
 +    for func in symbols:
 +        if config.is_hidden(func.name):
 +            log.debug(f"Skipping hidden macro {func.name}")
 +            continue
 +        idx = len(index_symbols)
 +        if func.doc is not None:
 +            func_desc = func.doc.content
 +        else:
 +            func_desc = MISSING_DESCRIPTION
 +        index_symbols.append({
 +            "type": "function_macro",
 +            "name": func.name,
 +            "ident": func.identifier,
 +            "summary": utils.preprocess_docs(func_desc, repository.namespace, summary=True, plain=True),
 +        })
 +        add_index_terms(index_terms, [func.identifier], idx)
 +        add_index_terms(index_terms, utils.index_symbol(func.name, stemmer), idx)
 +        add_index_terms(index_terms, utils.index_description(func_desc, stemmer), idx)
 +
 +
 +def _gen_interfaces(config, stemmer, index, repository, symbols):
 +    index_symbols = index["symbols"]
 +    index_terms = index["terms"]
 +
 +    for iface in symbols:
 +        if config.is_hidden(iface.name):
 +            log.debug(f"Skipping hidden type {iface.name}")
 +            continue
 +        idx = len(index_symbols)
 +        if iface.doc is not None:
 +            iface_desc = iface.doc.content
 +        else:
 +            iface_desc = MISSING_DESCRIPTION
 +        index_symbols.append({
 +            "type": "interface",
 +            "name": iface.name,
 +            "ctype": iface.base_ctype,
 +            "summary": utils.preprocess_docs(iface_desc, repository.namespace, summary=True, plain=True),
 +        })
 +        add_index_terms(index_terms, [iface.base_ctype.lower()], idx)
 +        add_index_terms(index_terms, utils.index_identifier(iface.name, stemmer), idx)
 +        add_index_terms(index_terms, utils.index_description(iface_desc, stemmer), idx)
 +
 +        for method in iface.methods:
 +            method_idx = len(index_symbols)
 +            if method.doc is not None:
 +                method_desc = method.doc.content
 +            else:
 +                method_desc = MISSING_DESCRIPTION
 +            index_symbols.append({
 +                "type": "method",
 +                "name": method.name,
 +                "type_name": iface.name,
 +                "ident": method.identifier,
 +                "summary": utils.preprocess_docs(method_desc, repository.namespace, summary=True, plain=True),
 +            })
 +            add_index_terms(index_terms, [method.identifier], method_idx)
 +            add_index_terms(index_terms, utils.index_symbol(method.name, stemmer), method_idx)
 +            add_index_terms(index_terms, utils.index_description(method_desc, stemmer), method_idx)
 +
 +        for func in iface.functions:
 +            func_idx = len(index_symbols)
 +            if func.doc is not None:
 +                func_desc = func.doc.content
 +            else:
 +                func_desc = MISSING_DESCRIPTION
 +            index_symbols.append({
 +                "type": "type_func",
 +                "name": func.name,
 +                "type_name": iface.name,
 +                "ident": func.identifier,
 +                "summary": utils.preprocess_docs(func_desc, repository.namespace, summary=True, plain=True),
 +            })
 +            add_index_terms(index_terms, [func.identifier], func_idx)
 +            add_index_terms(index_terms, utils.index_symbol(func.name, stemmer), func_idx)
 +            add_index_terms(index_terms, utils.index_description(func_desc, stemmer), func_idx)
 +
 +        for prop_name, prop in iface.properties.items():
 +            if config.is_hidden(iface.name, 'property', prop_name):
 +                log.debug(f"Skipping hidden property {iface.name}.{prop_name}")
 +                continue
 +            prop_idx = len(index_symbols)
 +            if prop.doc is not None:
 +                prop_desc = prop.doc.content
 +            else:
 +                prop_desc = MISSING_DESCRIPTION
 +            index_symbols.append({
 +                "type": "property",
 +                "name": prop.name,
 +                "type_name": iface.name,
 +                "summary": utils.preprocess_docs(prop_desc, repository.namespace, summary=True, plain=True),
 +            })
 +            add_index_terms(index_terms, utils.index_symbol(prop.name, stemmer), prop_idx)
 +            add_index_terms(index_terms, utils.index_description(prop_desc, stemmer), prop_idx)
 +
 +        for signal_name, signal in iface.signals.items():
 +            if config.is_hidden(iface.name, 'signal', signal_name):
 +                log.debug(f"Skipping hidden signal {iface.name}.{signal_name}")
 +                continue
 +            signal_idx = len(index_symbols)
 +            if signal.doc is not None:
 +                signal_desc = signal.doc.content
 +            else:
 +                signal_desc = MISSING_DESCRIPTION
 +            index_symbols.append({
 +                "type": "signal",
 +                "name": signal.name,
 +                "type_name": iface.name,
 +                "summary": utils.preprocess_docs(signal_desc, repository.namespace, summary=True, plain=True),
 +            })
 +            add_index_terms(index_terms, utils.index_symbol(signal.name, stemmer), signal_idx)
 +            add_index_terms(index_terms, utils.index_description(signal_desc, stemmer), signal_idx)
 +
 +        for vfunc in iface.virtual_methods:
 +            vfunc_idx = len(index_symbols)
 +            if vfunc.doc is not None:
 +                vfunc_desc = vfunc.doc.content
 +            else:
 +                vfunc_desc = MISSING_DESCRIPTION
 +            index_symbols.append({
 +                "type": "vfunc",
 +                "name": vfunc.name,
 +                "type_name": iface.name,
 +                "summary": utils.preprocess_docs(vfunc_desc, repository.namespace, summary=True, plain=True),
 +            })
 +            add_index_terms(index_terms, utils.index_symbol(vfunc.name, stemmer), vfunc_idx)
 +            add_index_terms(index_terms, utils.index_description(vfunc_desc, stemmer), vfunc_idx)
 +
 +
 +def _gen_records(config, stemmer, index, repository, symbols):
 +    index_symbols = index["symbols"]
 +    index_terms = index["terms"]
 +
 +    for record in symbols:
 +        if config.is_hidden(record.name):
 +            log.debug(f"Skipping hidden type {record.name}")
 +            continue
 +        idx = len(index_symbols)
 +        if record.doc is not None:
 +            desc = record.doc.content
 +        else:
 +            desc = MISSING_DESCRIPTION
 +        index_symbols.append({
 +            "type": "record",
 +            "name": record.name,
 +            "ctype": record.base_ctype,
 +            "summary": utils.preprocess_docs(desc, repository.namespace, summary=True, plain=True),
 +        })
 +        add_index_terms(index_terms, [record.base_ctype.lower()], idx)
 +        add_index_terms(index_terms, utils.index_identifier(record.name, stemmer), idx)
 +        add_index_terms(index_terms, utils.index_description(desc, stemmer), idx)
 +
 +        for ctor in record.constructors:
 +            ctor_idx = len(index_symbols)
 +            if ctor.doc is not None:
 +                ctor_desc = ctor.doc.content
 +            else:
 +                ctor_desc = MISSING_DESCRIPTION
 +            index_symbols.append({
 +                "type": "ctor",
 +                "name": ctor.name,
 +                "type_name": record.name,
 +                "ident": ctor.identifier,
 +                "summary": utils.preprocess_docs(ctor_desc, repository.namespace, summary=True, plain=True),
 +            })
 +            add_index_terms(index_terms, [ctor.identifier], ctor_idx)
 +            add_index_terms(index_terms, utils.index_symbol(ctor.name, stemmer), ctor_idx)
 +            add_index_terms(index_terms, utils.index_description(ctor_desc, stemmer), ctor_idx)
 +
 +        for method in record.methods:
 +            method_idx = len(index_symbols)
 +            if method.doc is not None:
 +                method_desc = method.doc.content
 +            else:
 +                method_desc = MISSING_DESCRIPTION
 +            index_symbols.append({
 +                "type": "method",
 +                "name": method.name,
 +                "type_name": record.name,
 +                "ident": method.identifier,
 +                "summary": utils.preprocess_docs(method_desc, repository.namespace, summary=True, plain=True),
 +            })
 +            add_index_terms(index_terms, [method.identifier], method_idx)
 +            add_index_terms(index_terms, utils.index_symbol(method.name, stemmer), method_idx)
 +            add_index_terms(index_terms, utils.index_description(method_desc, stemmer), method_idx)
 +
 +        for func in record.functions:
 +            func_idx = len(index_symbols)
 +            if func.doc is not None:
 +                func_desc = func.doc.content
 +            else:
 +                func_desc = MISSING_DESCRIPTION
 +            index_symbols.append({
 +                "type": "type_func",
 +                "name": func.name,
 +                "type_name": record.name,
 +                "ident": func.identifier,
 +                "summary": utils.preprocess_docs(func_desc, repository.namespace, summary=True, plain=True),
 +            })
 +            add_index_terms(index_terms, [func.identifier], func_idx)
 +            add_index_terms(index_terms, utils.index_symbol(func.name, stemmer), func_idx)
 +            add_index_terms(index_terms, utils.index_description(func_desc, stemmer), func_idx)
 +
 +
 +def _gen_unions(config, stemmer, index, repository, symbols):
 +    index_symbols = index["symbols"]
 +    index_terms = index["terms"]
 +
 +    for union in symbols:
 +        if config.is_hidden(union.name):
 +            log.debug(f"Skipping hidden type {union.name}")
 +            continue
 +        idx = len(index_symbols)
 +        if union.doc is not None:
 +            desc = union.doc.content
 +        else:
 +            desc = MISSING_DESCRIPTION
 +        index_symbols.append({
 +            "type": "union",
 +            "name": union.name,
 +            "ctype": union.base_ctype,
 +            "summary": utils.preprocess_docs(desc, repository.namespace, summary=True, plain=True),
 +        })
 +        add_index_terms(index_terms, [union.base_ctype.lower()], idx)
 +        add_index_terms(index_terms, utils.index_identifier(union.name, stemmer), idx)
 +        add_index_terms(index_terms, utils.index_description(desc, stemmer), idx)
 +
 +        for ctor in union.constructors:
 +            ctor_idx = len(index_symbols)
 +            if ctor.doc is not None:
 +                ctor_desc = ctor.doc.content
 +            else:
 +                ctor_desc = MISSING_DESCRIPTION
 +            index_symbols.append({
 +                "type": "ctor",
 +                "name": ctor.name,
 +                "type_name": union.name,
 +                "ident": ctor.identifier,
 +                "summary": utils.preprocess_docs(ctor_desc, repository.namespace, summary=True, plain=True),
 +            })
 +            add_index_terms(index_terms, [ctor.identifier], ctor_idx)
 +            add_index_terms(index_terms, utils.index_symbol(ctor.name, stemmer), ctor_idx)
 +            add_index_terms(index_terms, utils.index_description(ctor_desc, stemmer), ctor_idx)
 +
 +        for method in union.methods:
 +            method_idx = len(index_symbols)
 +            if method.doc is not None:
 +                method_desc = method.doc.content
 +            else:
 +                method_desc = MISSING_DESCRIPTION
 +            index_symbols.append({
 +                "type": "method",
 +                "name": method.name,
 +                "type_name": union.name,
 +                "ident": method.identifier,
 +                "summary": utils.preprocess_docs(method_desc, repository.namespace, summary=True, plain=True),
 +            })
 +            add_index_terms(index_terms, [method.identifier], method_idx)
 +            add_index_terms(index_terms, utils.index_symbol(method.name, stemmer), method_idx)
 +            add_index_terms(index_terms, utils.index_description(method_desc, stemmer), method_idx)
 +
 +        for func in union.functions:
 +            func_idx = len(index_symbols)
 +            if func.doc is not None:
 +                func_desc = func.doc.content
 +            else:
 +                func_desc = MISSING_DESCRIPTION
 +            index_symbols.append({
 +                "type": "type_func",
 +                "name": func.name,
 +                "type_name": union.name,
 +                "ident": func.identifier,
 +                "summary": utils.preprocess_docs(func_desc, repository.namespace, summary=True, plain=True),
 +            })
 +            add_index_terms(index_terms, [func.identifier], func_idx)
 +            add_index_terms(index_terms, utils.index_symbol(func.name, stemmer), func_idx)
 +            add_index_terms(index_terms, utils.index_description(func_desc, stemmer), func_idx)
 +
 +
-     parser.add_argument("--content-dir", default=None, help="the base directory with the extra content")
++def _gen_content_files(config, stemmer, index, repository, content_dirs):
++    index_symbols = index["symbols"]
++    index_terms = index["terms"]
++
++    for file_name in config.content_files:
++        src_file = utils.find_extra_content_file(content_dirs, file_name)
++
++        src_data = ""
++        with open(src_file, encoding='utf-8') as infile:
++            source = []
++            header = True
++            title = None
++            for line in infile:
++                if header:
++                    if line.startswith("Title: "):
++                        title = line.replace("Title: ", "").strip()
++                    if line == "\n":
++                        header = False
++
++                if not header:
++                    source.append(line)
++            src_data = "".join(source)
++
++        if title is None:
++            title = f"Untitled document '{file_name}'"
++
++        index_symbols.append({
++            "type": "content",
++            "name": title,
++            "href": file_name.replace(".md", ".html"),
++            "summary": utils.preprocess_docs(src_data, repository.namespace, summary=True, plain=True),
++        })
++
++        content_idx = len(index_symbols)
++        add_index_terms(index_terms, utils.index_description(src_data, stemmer), content_idx)
++
++
++def gen_indices(config, repository, content_dirs, output_dir):
 +    namespace = repository.namespace
 +
 +    symbols = {
 +        "aliases": sorted(namespace.get_aliases(), key=lambda alias: alias.name.lower()),
 +        "bitfields": sorted(namespace.get_bitfields(), key=lambda bitfield: bitfield.name.lower()),
 +        "callbacks": sorted(namespace.get_callbacks(), key=lambda callback: callback.name.lower()),
 +        "classes": sorted(namespace.get_classes(), key=lambda cls: cls.name.lower()),
 +        "constants": sorted(namespace.get_constants(), key=lambda const: const.name.lower()),
 +        "domains": sorted(namespace.get_error_domains(), key=lambda domain: domain.name.lower()),
 +        "enums": sorted(namespace.get_enumerations(), key=lambda enum: enum.name.lower()),
 +        "functions": sorted(namespace.get_functions(), key=lambda func: func.name.lower()),
 +        "function_macros": sorted(namespace.get_effective_function_macros(), key=lambda func: func.name.lower()),
 +        "interfaces": sorted(namespace.get_interfaces(), key=lambda interface: interface.name.lower()),
 +        "structs": sorted(namespace.get_effective_records(), key=lambda record: record.name.lower()),
 +        "unions": sorted(namespace.get_unions(), key=lambda union: union.name.lower()),
 +    }
 +
 +    all_indices = {
 +        "aliases": _gen_aliases,
 +        "bitfields": _gen_bitfields,
 +        "callbacks": _gen_callbacks,
 +        "classes": _gen_classes,
 +        "constants": _gen_constants,
 +        "domains": _gen_domains,
 +        "enums": _gen_enums,
 +        "functions": _gen_functions,
 +        "function_macros": _gen_function_macros,
 +        "interfaces": _gen_interfaces,
 +        "structs": _gen_records,
 +        "unions": _gen_unions,
 +    }
 +
 +    index = {
 +        "meta": {
 +            "ns": namespace.name,
 +            "version": namespace.version,
 +            "generator": "gi-docgen",
 +            "generator-version": core.version,
 +        },
 +        "symbols": [],
 +        "terms": {},
 +    }
 +
 +    stemmer = porter.PorterStemmer()
 +
 +    # Each section is isolated, so we run it into a thread pool
 +    for section in all_indices:
 +        generator = all_indices.get(section, None)
 +        if generator is None:
 +            log.error(f"No generator for section {section}")
 +            continue
 +
 +        s = symbols.get(section, None)
 +        if s is None:
 +            log.debug(f"No symbols for section {section}")
 +            continue
 +
 +        log.debug(f"Generating symbols for section {section}")
 +        generator(config, stemmer, index, repository, s)
 +
++    _gen_content_files(config, stemmer, index, repository, content_dirs)
++
 +    # Ensure iteration order is reproducible by sorting symbols by type/name,
 +    # and terms by key. This has no overhead since values are not copied.
 +    index["symbols"].sort(key=lambda s: (s["type"], s["name"]))
 +    index["terms"] = dict(sorted(index["terms"].items()))
 +
 +    data = json.dumps(index, separators=(',', ':'))
 +    index_file = os.path.join(output_dir, "index.json")
 +    log.info(f"Creating index file for {namespace.name}-{namespace.version}: {index_file}")
 +    with open(index_file, "w") as out:
 +        out.write(data)
 +
 +
 +def add_args(parser):
 +    parser.add_argument("--add-include-path", action="append", dest="include_paths", default=[],
 +                        help="include paths for other GIR files")
 +    parser.add_argument("-C", "--config", metavar="FILE", help="the configuration file")
-     content_dir = options.content_dir or os.getcwd()
++    parser.add_argument("--content-dir", action="append", dest="content_dirs", default=[],
++                        help="the base directories with the extra content")
 +    parser.add_argument("--dry-run", action="store_true", help="parses the GIR file without generating files")
 +    parser.add_argument("--output-dir", default=None, help="the output directory for the index files")
 +    parser.add_argument("infile", metavar="GIRFILE", type=argparse.FileType('r', encoding='UTF-8'),
 +                        default=sys.stdin, help="the GIR file to parse")
 +
 +
 +def run(options):
 +    log.info(f"Loading config file: {options.config}")
 +
 +    conf = config.GIDocConfig(options.config)
 +
 +    output_dir = options.output_dir or os.getcwd()
-         gen_indices(conf, parser.get_repository(), content_dir, output_dir)
 +    log.info(f"Output directory: {output_dir}")
 +
++    content_dirs = options.content_dirs
++    if content_dirs == []:
++        content_dirs = [os.getcwd()]
++
 +    paths = []
 +    paths.extend(options.include_paths)
 +    paths.extend(utils.default_search_paths())
 +    log.debug(f"Search paths: {paths}")
 +
 +    log.info("Parsing GIR file")
 +    parser = gir.GirParser(search_paths=paths)
 +    parser.parse(options.infile)
 +
 +    if not options.dry_run:
 +        log.checkpoint()
++        gen_indices(conf, parser.get_repository(), content_dirs, output_dir)
 +
 +    return 0
index 679efa61f5376e07178450fb872372a3b6cd6a3d,0000000000000000000000000000000000000000..a3c97f2eda0200593cc88c70ad3785f22eeafc85
mode 100644,000000..100644
--- /dev/null
@@@ -1,125 -1,0 +1,129 @@@
- from . import gdindex, gdgenerate, gdgenindices, gdgendeps, gdsearch
 +# SPDX-FileCopyrightText: 2020 GNOME Foundation
 +# SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +
 +import argparse
 +import shutil
 +import sys
 +import traceback
 +
 +from . import core, log
++from . import gdindex, gdgenerate, gdgenindices, gdgendeps, gdsearch, gdcheck
 +
 +
 +class GIDocGenApp:
 +    """
 +    The main GIDocGen application, working as a multiplexer for different
 +    commands.
 +    """
 +    def __init__(self):
 +        self.term_width = shutil.get_terminal_size().columns
 +        self.formatter = lambda prog: argparse.HelpFormatter(prog, max_help_position=int(self.term_width / 2), width=self.term_width)
 +
 +        self.quiet = False
 +        self.commands = {}
 +        self.parser = argparse.ArgumentParser(prog='gi-docgen', formatter_class=self.formatter)
 +
 +        self.subparser = self.parser.add_subparsers(title='Commands',
 +                                                    description='If no command is specified, default to help')
 +
 +        self.add_command('help',
 +                         add_args_func=self.add_help_args,
 +                         run_func=self.run_help_cmd,
 +                         help_msg='Show the help for gi-docgen or a sub-command')
 +        self.add_command('index',
 +                         add_args_func=gdindex.add_args,
 +                         run_func=gdindex.run,
 +                         help_msg=gdindex.HELP_MSG)
 +        self.add_command('generate',
 +                         add_args_func=gdgenerate.add_args,
 +                         run_func=gdgenerate.run,
 +                         help_msg=gdgenerate.HELP_MSG)
 +        self.add_command('gen-index',
 +                         add_args_func=gdgenindices.add_args,
 +                         run_func=gdgenindices.run,
 +                         help_msg=gdgenindices.HELP_MSG)
 +        self.add_command('gen-deps',
 +                         add_args_func=gdgendeps.add_args,
 +                         run_func=gdgendeps.run,
 +                         help_msg=gdgendeps.HELP_MSG)
 +        self.add_command('search',
 +                         add_args_func=gdsearch.add_args,
 +                         run_func=gdsearch.run,
 +                         help_msg=gdsearch.HELP_MSG)
++        self.add_command('check',
++                         add_args_func=gdcheck.add_args,
++                         run_func=gdcheck.run,
++                         help_msg=gdcheck.HELP_MSG)
 +
 +    def run(self, args):
 +        """
 +        Run the main application.
 +        """
 +        known_commands = list(self.commands.keys()) + ['-h', '--help']
 +        if not args or args[0] not in known_commands:
 +            args = ['help'] + args
 +
 +        options = self.parser.parse_args(args)
 +
 +        # Set up the logging system
 +        log.set_quiet(options.quiet)
 +        log.set_fatal_warnings(options.fatal_warnings)
 +        log.set_log_epoch()
 +
 +        try:
 +            res = options.run_func(options)
 +            if 'help' not in args:
 +                report_res = log.report()
 +            else:
 +                report_res = 0
 +            if res == 0:
 +                return report_res
 +            return res
 +
 +        except Exception:
 +            traceback.print_exc()
 +            return 1
 +
 +    def add_command(self, name, add_args_func, run_func, help_msg, aliases=[]):
 +        """
 +        Add a command to the application.
 +
 +        @name (str): the name of the command
 +        @add_args_func (callable): a function to be called to add the arguments
 +        @run_func (callable): a function to be called when running the command
 +        @help_msg (str): short help message for the command
 +        @aliases (array): a list of aliases for the command
 +        """
 +        p = self.subparser.add_parser(name, help=help_msg, aliases=aliases, formatter_class=self.formatter)
 +
 +        # Add shared commands
 +        p.add_argument("-q", "--quiet", action="store_true", help="suppress messages except warnings")
 +        p.add_argument("--fatal-warnings", action="store_true", help="whether warnings are fatal")
 +
 +        if add_args_func:
 +            add_args_func(p)
 +        p.set_defaults(run_func=run_func)
 +        for i in [name] + aliases:
 +            self.commands[i] = p
 +
 +    def add_help_args(self, parser):
 +        parser.add_argument("-v", "--version", action="store_true", help="show the version of gi-docgen")
 +        parser.add_argument('command', nargs='?')
 +
 +    def run_help_cmd(self, options):
 +        if options.version:
 +            print(core.version)
 +        elif options.command:
 +            known_commands = list(self.commands.keys())
 +            if options.command not in known_commands:
 +                log.error(f'Unknown command {options.command}.')
 +                return 1
 +            self.commands[options.command].print_help()
 +        else:
 +            self.parser.print_help()
 +        return 0
 +
 +
 +def main():
 +    """The entry point expected by setuptools"""
 +    return GIDocGenApp().run(sys.argv[1:])
index e3a86adc5b9c4a876ac0a47da2c75456d21cda76,0000000000000000000000000000000000000000..8a7294a10298fffd9cd8040c90705d625c1a672a
mode 100644,000000..100644
--- /dev/null
@@@ -1,1172 -1,0 +1,1272 @@@
-         if self.namespace is not None:
 +# SPDX-FileCopyrightText: 2020 GNOME Foundation
 +# SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +
 +import typing as T
 +
 +from .. import log
 +
 +
 +class Doc:
 +    """A documentation node, pointing to the source code"""
 +    def __init__(self, content: str, filename: str, line: int, version: str = None, stability: str = None):
 +        self.content = content
 +        self.filename = filename
 +        self.line = line
 +        self.version = version
 +        self.stability = stability
 +
 +    def __str__(self):
 +        return self.content
 +
 +
 +class SourcePosition:
 +    """A location inside the source code"""
 +    def __init__(self, filename: str, line: int):
 +        self.filename = filename
 +        self.line = line
 +
 +    def __str__(self):
 +        return f'{self.filename}:{self.line}'
 +
 +
 +class Attribute:
 +    """A user-defined annotation"""
 +    def __init__(self, name: str, value: T.Optional[str]):
 +        self.name = name
 +        self.value = value
 +
 +
 +class CInclude:
 +    """A C include header"""
 +    def __init__(self, name: str):
 +        self.name = name
 +
 +
 +class Include:
 +    """A GIR include"""
 +    def __init__(self, name: str, version: str = None):
 +        self.name = name
 +        self.version = version
 +
 +    def __str__(self):
 +        if self.version is not None:
 +            return f"{self.name}-{self.version}"
 +        return f"{self.name}"
 +
 +    def girfile(self) -> str:
 +        if self.version is not None:
 +            return f"{self.name}-{self.version}.gir"
 +        return f"{self.name}.gir"
 +
 +
 +class Package:
 +    """Pkg-config containing the library"""
 +    def __init__(self, name: str):
 +        self.name = name
 +
 +
 +class Info:
 +    """Base information for most types"""
 +    def __init__(self, introspectable: bool = True, deprecated: T.Optional[str] = None,
 +                 deprecated_version: T.Optional[str] = None, version: str = None,
 +                 stability: str = None):
 +        self.introspectable = introspectable
 +        self.deprecated_msg = deprecated
 +        self.deprecated_version = deprecated_version
 +        self.version = version
 +        self.stability = stability
 +        self.attributes: T.Mapping[str, T.Optional[str]] = {}
 +        self.doc: T.Optional[Doc] = None
 +        self.source_position: T.Optional[SourcePosition] = None
 +
 +    def add_attribute(self, name: str, value: T.Optional[str] = None) -> None:
 +        self.attributes[name] = value
 +
 +
 +class GIRElement:
 +    """Base type for elements inside the GIR"""
 +    def __init__(self, name: T.Optional[str] = None, namespace: T.Optional[str] = None):
 +        self.name = name
 +        self.namespace = namespace
-     def __init__(self, name: str, ctype: T.Optional[str] = None, namespace: T.Optional[str] = None):
++        if self.namespace is None:
 +            if self.name is not None and '.' in self.name:
 +                self.namespace = self.name.split('.')[0]
 +        self.info = Info()
 +
 +    def set_introspectable(self, introspectable: bool) -> None:
 +        """Set whether the symbol is introspectable"""
 +        self.info.introspectable = introspectable
 +
 +    @property
 +    def introspectable(self):
 +        return self.info.introspectable
 +
 +    def set_version(self, version: str) -> None:
 +        """Set the version of the symbol"""
 +        self.info.version = version
 +
 +    def set_stability(self, stability: str) -> None:
 +        """Set the stability of the symbol"""
 +        self.info.stability = stability
 +
 +    @property
 +    def stability(self):
 +        return self.info.stability
 +
 +    def set_doc(self, doc: Doc) -> None:
 +        """Set the documentation for the element"""
 +        self.info.doc = doc
 +
 +    @property
 +    def doc(self):
 +        return self.info.doc
 +
 +    def set_source_position(self, pos: SourcePosition) -> None:
 +        """Set the position in the source code for the element"""
 +        self.info.source_position = pos
 +
 +    @property
 +    def source_position(self) -> T.Optional[T.Tuple[str, int]]:
 +        if self.info.source_position is None:
 +            return None
 +        return self.info.source_position.filename, self.info.source_position.line
 +
 +    def set_deprecated(self, doc: T.Optional[str] = None, since_version: T.Optional[str] = None) -> None:
 +        """Set the deprecation annotations for the element"""
 +        self.info.deprecated_msg = doc
 +        self.info.deprecated_version = since_version
 +
 +    def set_attributes(self, attrs: T.Mapping[str, T.Optional[str]]) -> None:
 +        """Add an annotation to the symbol"""
 +        for name, value in attrs.items():
 +            self.info.add_attribute(name, value)
 +
 +    @property
 +    def attributes(self) -> T.Mapping[str, T.Optional[str]]:
 +        return self.info.attributes
 +
 +    @property
 +    def available_since(self) -> T.Optional[str]:
 +        return self.info.version
 +
 +    @property
 +    def deprecated_since(self) -> T.Optional[T.Tuple[str, str]]:
 +        if not self.info.deprecated_msg:
 +            return None
 +        version = self.info.deprecated_version
 +        message = self.info.deprecated_msg
 +        if message is None:
 +            message = "Please do not use it in newly written code"
 +        return (version, message)
 +
 +
 +class Type(GIRElement):
 +    """Base class for all Type nodes"""
-                 return self.namespace == other.namespace and self.name == self.name
++    def __init__(self, name: str, ctype: T.Optional[str] = None, namespace: T.Optional[str] = None, is_fundamental: bool = False):
 +        super().__init__(name=name, namespace=namespace)
 +        self.ctype = ctype
++        self.is_fundamental = is_fundamental
 +
 +    def __eq__(self, other):
 +        if isinstance(other, Type):
 +            if self.namespace is not None:
-         if '.' in self.name:
++                return self.namespace == other.namespace and self.name == other.name
 +            elif self.ctype is not None:
 +                return self.name == other.name and self.ctype == other.ctype
 +            else:
 +                return self.name == other.name
 +        elif isinstance(other, str):
 +            return self.name == other
 +        else:
 +            return False
 +
 +    def __cmp__(self, other):
 +        if self.ctype is not None:
 +            return self.name == other.name and self.ctype == other.ctype
 +        return self.name == other.name
 +
 +    def __repr__(self):
 +        return f"Type({self.fqtn}, {self.ctype})"
 +
 +    @property
 +    def resolved(self):
 +        return self.ctype is not None
 +
 +    @property
 +    def base_ctype(self):
 +        if self.ctype is None:
 +            return None
 +        return self.ctype.replace('*', '')
 +
 +    @property
 +    def fqtn(self):
-     def __init__(self, name: str, identifier: str, instance_param: Parameter, throws: bool = False):
++        if self.is_fundamental:
++            return self.name
++        elif '.' in self.name:
 +            return self.name
 +        elif self.namespace is not None:
 +            return f"{self.namespace}.{self.name}"
 +        else:
 +            return None
 +
 +
 +class ArrayType(GIRElement):
 +    """Base class for Array nodes"""
 +    def __init__(self, name: str, value_type: Type, ctype: str = None, zero_terminated: bool = False,
 +                 fixed_size: int = -1, length: int = -1):
 +        super().__init__(name)
 +        self.ctype = ctype
 +        self.zero_terminated = zero_terminated
 +        self.fixed_size = fixed_size
 +        self.length = length
 +        self.value_type = value_type
++        self.is_fundamental = False
 +
 +
 +class ListType(GIRElement):
 +    """Type class for List nodes"""
 +    def __init__(self, name: str, value_type: Type, ctype: str = None):
 +        super().__init__(name)
 +        self.ctype = ctype
 +        self.value_type = value_type
++        self.is_fundamental = False
 +
 +
 +class MapType(GIRElement):
 +    """Type class for Map nodes"""
 +    def __init__(self, name: str, key_type: Type, value_type: Type, ctype: str = None):
 +        super().__init__(name)
 +        self.ctype = ctype
 +        self.key_type = key_type
 +        self.value_type = value_type
++        self.is_fundamental = False
 +
 +
 +class GType:
 +    """Base class for GType information"""
 +    def __init__(self, type_name: str, get_type: str, type_struct: T.Optional[str] = None):
 +        self.type_name = type_name
 +        self.get_type = get_type
 +        self.type_struct = type_struct
 +
 +
 +class VoidType(Type):
 +    def __init__(self):
 +        super().__init__(name='none', ctype='void')
 +
 +    def __str__(self):
 +        return "void"
 +
 +
 +class VarArgs(Type):
 +    def __init__(self):
 +        super().__init__(name='none', ctype='')
 +
 +    def __str__(self):
 +        return "..."
 +
 +
 +class Alias(Type):
 +    """Alias to a Type"""
 +    def __init__(self, name: str, namespace: str, ctype: str, target: Type):
 +        super().__init__(name=name, ctype=ctype, namespace=namespace)
 +        self.target = target
 +
 +
 +class Constant(Type):
 +    """A constant"""
 +    def __init__(self, name: str, namespace: str, ctype: str, target: Type, value: str):
 +        super().__init__(name=name, ctype=ctype, namespace=namespace)
 +        self.target = target
 +        self.value = value
 +
 +
 +class Parameter(GIRElement):
 +    """A callable parameter"""
 +    def __init__(self, name: str, direction: str, transfer: str, target: Type = None, caller_allocates: bool = False,
 +                 optional: bool = False, nullable: bool = False, closure: int = -1, destroy: int = -1,
 +                 scope: str = None):
 +        super().__init__(name)
 +        self.direction = direction
 +        self.transfer = transfer
 +        self.caller_allocates = caller_allocates
 +        self.optional = optional
 +        self.nullable = nullable
 +        self.scope = scope
 +        self.closure = closure
 +        self.destroy = destroy
 +        if target is None:
 +            self.target: Type = VoidType()
 +        else:
 +            self.target = target
 +
 +
 +class ReturnValue(GIRElement):
 +    """A callable's return value"""
 +    def __init__(self, transfer: str, target: Type, nullable: bool = False, closure: int = -1, destroy: int = -1, scope: str = None):
 +        super().__init__()
 +        self.transfer = transfer
 +        self.nullable = nullable
 +        self.scope = scope
 +        self.closure = closure
 +        self.destroy = destroy
 +        if target is None:
 +            self.target: Type = VoidType()
 +        else:
 +            self.target = target
 +
 +
 +class Callable(GIRElement):
 +    """A callable symbol: function, method, function-macro, ..."""
 +    def __init__(self, name: str, namespace: T.Optional[str], identifier: T.Optional[str], throws: bool = False):
 +        super().__init__(name=name, namespace=namespace)
 +        self.identifier = identifier
 +        self.parameters: T.List[Parameter] = []
 +        self.return_value: T.Optional[ReturnValue] = None
 +        self.throws: bool = throws
 +        self.moved_to: T.Optional[str] = None
 +        self.shadows: T.Optional[str] = None
 +        self.shadowed_by: T.Optional[str] = None
 +
 +    def add_parameter(self, param: Parameter) -> None:
 +        self.parameters.append(param)
 +
 +    def set_parameters(self, params: T.List[Parameter]) -> None:
 +        self.parameters.extend(params)
 +
 +    def set_return_value(self, res: ReturnValue) -> None:
 +        self.return_value = res
 +
 +    def set_shadows(self, func: str) -> None:
 +        self.shadows = func
 +
 +    def set_shadowed_by(self, func: str) -> None:
 +        self.shadowed_by = func
 +
 +    def set_moved_to(self, func: str) -> None:
 +        self.moved_to = func
 +
 +    def __contains__(self, param):
 +        if isinstance(param, str):
 +            for p in self.parameters:
 +                if p.name == param:
 +                    return True
 +        elif isinstance(param, Parameter):
 +            return param in self.parameters
 +        elif isinstance(param, ReturnValue):
 +            return param == self.return_value
 +        return False
 +
 +
 +class FunctionMacro(Callable):
 +    def __init__(self, name: str, namespace: T.Optional[str], identifier: str):
 +        super().__init__(name, namespace, identifier)
 +
 +
 +class Function(Callable):
 +    def __init__(self, name: str, namespace: T.Optional[str], identifier: str, throws: bool = False):
 +        super().__init__(name, namespace, identifier, throws)
 +
 +
 +class Method(Callable):
-                  construct_only: bool = False):
++    def __init__(self, name: str, identifier: str, instance_param: Parameter, throws: bool = False,
++                 set_property: T.Optional[str] = None, get_property: T.Optional[str] = None):
 +        super().__init__(name, None, identifier, throws)
 +        self.instance_param = instance_param
++        self.set_property = set_property
++        self.get_property = get_property
 +
 +    def __contains__(self, param):
 +        if isinstance(param, Parameter) and param == self.instance_param:
 +            return True
 +        return super().__contains__(self, param)
 +
 +
 +class VirtualMethod(Callable):
 +    def __init__(self, name: str, identifier: str, invoker: str, instance_param: Parameter, throws: bool = False):
 +        super().__init__(name, None, identifier, throws)
 +        self.instance_param = instance_param
 +        self.invoker = invoker
 +
 +    def __contains__(self, param):
 +        if isinstance(param, Parameter) and param == self.instance_param:
 +            return True
 +        return super().__contains__(self, param)
 +
 +
 +class Callback(Callable):
 +    def __init__(self, name: str, namespace: str, ctype: T.Optional[str], throws: bool = False):
 +        super().__init__(name=name, namespace=namespace, identifier=None, throws=throws)
 +        self.ctype = ctype
++        self.is_fundamental = False
 +
 +    @property
 +    def base_ctype(self):
 +        if self.ctype is None:
 +            return None
 +        return self.ctype.replace('*', '')
 +
 +
 +class Member(GIRElement):
 +    """A member in an enumeration, error domain, or bitfield"""
 +    def __init__(self, name: str, value: str, identifier: str, nick: str):
 +        super().__init__(name)
 +        self.value = value
 +        self.identifier = identifier
 +        self.nick = nick
 +
 +
 +class Enumeration(Type):
 +    """An enumeration type"""
 +    def __init__(self, name: str, namespace: str, ctype: str, gtype: T.Optional[GType]):
 +        super().__init__(name=name, ctype=ctype, namespace=namespace)
 +        self.gtype = gtype
 +        self.members: T.List[Member] = []
 +        self.functions: T.List[Function] = []
 +
 +    def add_member(self, member: Member) -> None:
 +        self.members.append(member)
 +
 +    def add_function(self, function: Function) -> None:
 +        self.functions.append(function)
 +
 +    def set_members(self, members: T.List[Member]) -> None:
 +        self.members.extend(members)
 +
 +    def set_functions(self, functions: T.List[Function]) -> None:
 +        self.functions.extend(functions)
 +
 +    def __contains__(self, member):
 +        if isinstance(member, Member):
 +            return member in self.members
 +        return False
 +
 +    def __iter__(self):
 +        for member in self.members:
 +            yield member
 +
 +
 +class BitField(Enumeration):
 +    """An enumeration type of bit masks"""
 +    def __init__(self, name: str, namespace: str, ctype: str, gtype: T.Optional[GType]):
 +        super().__init__(name, namespace, ctype, gtype)
 +
 +
 +class ErrorDomain(Enumeration):
 +    """An error domain for GError"""
 +    def __init__(self, name: str, namespace: str, ctype: str, gtype: T.Optional[GType], domain: str):
 +        super().__init__(name, namespace, ctype, gtype)
 +        self.domain = domain
 +
 +
 +class Property(GIRElement):
 +    def __init__(self, name: str, transfer: str, target: Type, writable: bool = True, readable: bool = True, construct: bool = False,
-         if name is self._interfaces:
++                 construct_only: bool = False, setter: T.Optional[str] = None, getter: T.Optional[str] = None):
 +        super().__init__(name)
 +        self.transfer = transfer
 +        self.writable = writable
 +        self.readable = readable
 +        self.construct = construct
 +        self.construct_only = construct_only
 +        self.target = target
++        self.setter = setter
++        self.getter = getter
 +
 +
 +class Signal(GIRElement):
 +    def __init__(self, name: str, detailed: bool, when: str, action: bool = False, no_hooks: bool = False, no_recurse: bool = False):
 +        super().__init__(name)
 +        self.detailed = detailed
 +        self.when = when
 +        self.action = action
 +        self.no_hooks = no_hooks
 +        self.no_recurse = no_recurse
 +        self.parameters: T.List[Parameter] = []
 +        self.return_value: T.Optional[ReturnValue] = None
 +
 +    def set_parameters(self, params: T.List[Parameter]) -> None:
 +        self.parameters.extend(params)
 +
 +    def set_return_value(self, res: ReturnValue) -> None:
 +        self.return_value = res
 +
 +
 +class Field(GIRElement):
 +    """A field in a struct or union"""
 +    def __init__(self, name: str, target: Type, writable: bool, readable: bool, private: bool = False, bits: int = 0):
 +        super().__init__(name)
 +        self.target = target
 +        self.writable = writable
 +        self.readable = readable
 +        self.private = private
 +        self.bits = bits
 +
 +
 +class Interface(Type):
 +    def __init__(self, name: str, namespace: str, ctype: str, symbol_prefix: str, gtype: GType):
 +        super().__init__(name=name, ctype=ctype, namespace=namespace)
 +        self.symbol_prefix = symbol_prefix
 +        self.gtype = gtype
 +        self.methods: T.List[Method] = []
 +        self.virtual_methods: T.List[VirtualMethod] = []
 +        self.properties: T.Mapping[str, Property] = {}
 +        self.signals: T.Mapping[str, Signal] = {}
 +        self.functions: T.List[Function] = []
 +        self.fields: T.List[Field] = []
 +        self.prerequisite: T.Optional[str] = None
++        self.implementations: T.List[Type] = []
 +
 +    @property
 +    def type_struct(self) -> T.Optional[str]:
 +        if self.gtype is not None:
 +            return self.gtype.type_struct
 +        return self.ctype
 +
 +    @property
 +    def type_func(self) -> str:
 +        return self.gtype.get_type
 +
 +    def set_methods(self, methods: T.List[Method]) -> None:
 +        self.methods.extend(methods)
 +
 +    def set_virtual_methods(self, methods: T.List[VirtualMethod]) -> None:
 +        self.virtual_methods.extend(methods)
 +
 +    def set_properties(self, properties: T.List[Property]) -> None:
 +        for p in properties:
 +            self.properties[p.name] = p
 +
 +    def set_signals(self, signals: T.List[Signal]) -> None:
 +        for s in signals:
 +            self.signals[s.name] = s
 +
 +    def set_functions(self, functions: T.List[Function]) -> None:
 +        self.functions.extend(functions)
 +
 +    def set_fields(self, fields: T.List[Field]) -> None:
 +        self.fields.extend(fields)
 +
 +    def set_prerequisite(self, prerequisite: str) -> None:
 +        self.prerequisite = prerequisite
 +
 +
 +class Class(Type):
 +    def __init__(self, name: str, namespace: str, ctype: str, symbol_prefix: str,
 +                 gtype: GType, parent: T.Optional[Type] = None,
 +                 abstract: bool = False, fundamental: bool = False,
 +                 ref_func: T.Optional[str] = None, unref_func: T.Optional[str] = None):
 +        super().__init__(name=name, ctype=ctype, namespace=namespace)
 +        self.symbol_prefix = symbol_prefix
 +        self.parent = parent
 +        self.abstract = abstract
 +        self.fundamental = fundamental
 +        self.ref_func = ref_func
 +        self.unref_func = unref_func
 +        self.gtype = gtype
 +        self.ancestors: T.List[Type] = []
 +        self.implements: T.List[Type] = []
 +        self.constructors: T.List[Function] = []
 +        self.methods: T.List[Method] = []
 +        self.virtual_methods: T.List[VirtualMethod] = []
 +        self.properties: T.Mapping[str, Property] = {}
 +        self.signals: T.Mapping[str, Signal] = {}
 +        self.functions: T.List[Function] = []
 +        self.fields: T.List[Field] = []
 +        self.callbacks: T.List[Callback] = []
++        self.descendants: T.List[Type] = []
 +
 +    @property
 +    def type_struct(self) -> T.Optional[str]:
 +        if self.gtype is not None:
 +            return self.gtype.type_struct
 +        return None
 +
 +    @property
 +    def type_func(self) -> T.Optional[str]:
 +        if self.gtype is not None:
 +            return self.gtype.get_type
 +        return self.ctype
 +
 +    def set_constructors(self, ctors: T.List[Function]) -> None:
 +        self.constructors.extend(ctors)
 +
 +    def set_methods(self, methods: T.List[Method]) -> None:
 +        self.methods.extend(methods)
 +
 +    def set_virtual_methods(self, methods: T.List[VirtualMethod]) -> None:
 +        self.virtual_methods.extend(methods)
 +
 +    def set_properties(self, properties: T.List[Property]) -> None:
 +        for p in properties:
 +            self.properties[p.name] = p
 +
 +    def set_signals(self, signals: T.List[Signal]) -> None:
 +        for s in signals:
 +            self.signals[s.name] = s
 +
 +    def set_functions(self, functions: T.List[Function]) -> None:
 +        self.functions.extend(functions)
 +
 +    def set_implements(self, ifaces: T.List[Type]) -> None:
 +        self.implements.extend(ifaces)
 +
 +    def set_fields(self, fields: T.List[Field]) -> None:
 +        self.fields.extend(fields)
 +
 +
 +class Boxed(Type):
 +    def __init__(self, name: str, namespace: str, symbol_prefix: str, gtype: GType):
 +        super().__init__(name=name, ctype=None, namespace=namespace)
 +        self.symbol_prefix = symbol_prefix
 +        self.gtype = gtype
 +        self.functions: T.List[Function] = []
 +
 +    def set_functions(self, functions: T.List[Function]) -> None:
 +        self.functions.extend(functions)
 +
 +
 +class Record(Type):
 +    def __init__(self, name: str, namespace: str, ctype: str, symbol_prefix: str,
 +                 gtype: T.Optional[GType] = None, struct_for: T.Optional[str] = None,
 +                 disguised: bool = False):
 +        super().__init__(name=name, ctype=ctype, namespace=namespace)
 +        self.symbol_prefix = symbol_prefix
 +        self.gtype = gtype
 +        self.struct_for = struct_for
 +        self.disguised = disguised
 +        self.constructors: T.List[Function] = []
 +        self.methods: T.List[Method] = []
 +        self.functions: T.List[Function] = []
 +        self.fields: T.List[Field] = []
 +
 +    @property
 +    def type_struct(self) -> T.Optional[str]:
 +        if self.gtype is not None:
 +            return self.gtype.type_struct
 +        return self.ctype
 +
 +    @property
 +    def type_func(self) -> T.Optional[str]:
 +        if self.gtype is not None:
 +            return self.gtype.get_type
 +        return None
 +
 +    def set_constructors(self, ctors: T.List[Function]) -> None:
 +        self.constructors.extend(ctors)
 +
 +    def set_methods(self, methods: T.List[Method]) -> None:
 +        self.methods.extend(methods)
 +
 +    def set_functions(self, functions: T.List[Function]) -> None:
 +        self.functions.extend(functions)
 +
 +    def set_fields(self, fields: T.List[Field]) -> None:
 +        self.fields.extend(fields)
 +
 +
 +class Union(Type):
 +    def __init__(self, name: str, namespace: str, ctype: str, symbol_prefix: str, gtype: T.Optional[GType]):
 +        super().__init__(name=name, ctype=ctype, namespace=namespace)
 +        self.symbol_prefix = symbol_prefix
 +        self.gtype = gtype
 +        self.constructors: T.List[Function] = []
 +        self.methods: T.List[Method] = []
 +        self.functions: T.List[Function] = []
 +        self.fields: T.List[Field] = []
 +
 +    @property
 +    def type_struct(self) -> T.Optional[str]:
 +        if self.gtype is not None:
 +            return self.gtype.type_struct
 +        return self.ctype
 +
 +    @property
 +    def type_func(self) -> T.Optional[str]:
 +        if self.gtype is not None:
 +            return self.gtype.get_type
 +        return None
 +
 +    def set_constructors(self, ctors: T.List[Function]) -> None:
 +        self.constructors.extend(ctors)
 +
 +    def set_methods(self, methods: T.List[Method]) -> None:
 +        self.methods.extend(methods)
 +
 +    def set_functions(self, functions: T.List[Function]) -> None:
 +        self.functions.extend(functions)
 +
 +    def set_fields(self, fields: T.List[Field]) -> None:
 +        self.fields.extend(fields)
 +
 +
 +class Namespace:
 +    def __init__(self, name: str, version: str, identifier_prefix: T.List[str] = [], symbol_prefix: T.List[str] = []):
 +        self.name = name
 +        self.version = version
 +
 +        self._shared_libraries: T.List[str] = []
 +
 +        self._aliases: T.Mapping[str, Alias] = {}
 +        self._bitfields: T.Mapping[str, BitField] = {}
 +        self._boxeds: T.Mapping[str, Boxed] = {}
 +        self._callbacks: T.Mapping[str, Callback] = {}
 +        self._classes: T.Mapping[str, Class] = {}
 +        self._constants: T.Mapping[str, Constant] = {}
 +        self._enumerations: T.Mapping[str, Enumeration] = {}
 +        self._error_domains: T.Mapping[str, ErrorDomain] = {}
 +        self._functions: T.Mapping[str, Function] = {}
 +        self._function_macros: T.Mapping[str, FunctionMacro] = {}
 +        self._interfaces: T.Mapping[str, Interface] = {}
 +        self._records: T.Mapping[str, Record] = {}
 +        self._unions: T.Mapping[str, Union] = {}
 +
 +        self._symbols: T.Mapping[str, Type] = {}
 +        self.repository: T.Optional[Repository] = None
 +
 +        if identifier_prefix:
 +            self.identifier_prefix = identifier_prefix
 +        else:
 +            self.identifier_prefix = [self.name]
 +        if symbol_prefix:
 +            self.symbol_prefix = symbol_prefix
 +        else:
 +            self.symbol_prefix = [self.name.lower()]
 +
 +    def __str__(self):
 +        return f"{self.name}-{self.version}"
 +
 +    def add_shared_libraries(self, libs: T.List[str]) -> None:
 +        self._shared_libraries.extend(libs)
 +
 +    def get_shared_libraries(self) -> T.List[str]:
 +        return self._shared_libraries
 +
 +    def add_alias(self, alias: Alias) -> None:
 +        self._aliases[alias.name] = alias
 +
 +    def add_enumeration(self, enum: Enumeration) -> None:
 +        self._enumerations[enum.name] = enum
 +
 +    def add_error_domain(self, domain: ErrorDomain) -> None:
 +        self._error_domains[domain.name] = domain
 +
 +    def add_class(self, cls: Class) -> None:
 +        self._classes[cls.name] = cls
 +
 +    def add_constant(self, constant: Constant) -> None:
 +        self._constants[constant.name] = constant
 +
 +    def add_interface(self, interface: Interface) -> None:
 +        self._interfaces[interface.name] = interface
 +
 +    def add_boxed(self, boxed: Boxed) -> None:
 +        self._boxeds[boxed.name] = boxed
 +
 +    def add_record(self, record: Record) -> None:
 +        self._records[record.name] = record
 +
 +    def add_union(self, union: Union) -> None:
 +        self._unions[union.name] = union
 +
 +    def add_function(self, function: Function) -> None:
 +        self._functions[function.name] = function
 +
 +    def add_bitfield(self, bitfield: BitField) -> None:
 +        self._bitfields[bitfield.name] = bitfield
 +
 +    def add_function_macro(self, function: FunctionMacro) -> None:
 +        self._function_macros[function.name] = function
 +
 +    def add_callback(self, callback: Callback) -> None:
 +        self._callbacks[callback.name] = callback
 +
 +    def get_classes(self) -> T.List[Class]:
 +        return self._classes.values()
 +
 +    def get_constants(self) -> T.List[Constant]:
 +        return self._constants.values()
 +
 +    def get_enumerations(self) -> T.List[Enumeration]:
 +        return self._enumerations.values()
 +
 +    def get_error_domains(self) -> T.List[ErrorDomain]:
 +        return self._error_domains.values()
 +
 +    def get_aliases(self) -> T.List[Alias]:
 +        return self._aliases.values()
 +
 +    def get_interfaces(self) -> T.List[Interface]:
 +        return self._interfaces.values()
 +
 +    def get_boxeds(self) -> T.List[Boxed]:
 +        return self._boxeds.values()
 +
 +    def get_records(self) -> T.List[Record]:
 +        return self._records.values()
 +
 +    def get_effective_records(self) -> T.List[Record]:
 +        def is_effective(r):
 +            if "Private" in r.name and r.disguised:
 +                return False
 +            if r.struct_for is not None:
 +                return False
 +            return True
 +
 +        return [x for x in self._records.values() if is_effective(x)]
 +
 +    def get_unions(self) -> T.List[Union]:
 +        return self._unions.values()
 +
 +    def get_functions(self) -> T.List[Function]:
 +        return self._functions.values()
 +
 +    def get_bitfields(self) -> T.List[BitField]:
 +        return self._bitfields.values()
 +
 +    def get_function_macros(self) -> T.List[FunctionMacro]:
 +        return self._function_macros.values()
 +
 +    def get_effective_function_macros(self) -> T.List[FunctionMacro]:
 +        def is_effective(f, ns):
 +            # Lower-case identifiers are an automatic pass
 +            if f.name.islower():
 +                return True
 +            # Try to eliminate the GObject type macros from the pool
 +            t = f.name.split('_')
 +            # Skip "is-a" macros
 +            if 'IS' in t:
 +                return False
 +            # Skip "get class/iface" macros
 +            if 'GET' in t:
 +                return False
 +            # Re-assemble into what most likely is a type name
 +            s = "".join([x.capitalize() if len(x) > 2 else x for x in t])
 +            # Skip "cast" macros
 +            if ns.find_class(s) is not None:
 +                return False
 +            if ns.find_interface(s) is not None:
 +                return False
 +            if ns.find_record(s) is not None:
 +                return False
 +            # Anything that survived at this point is likely a valid function
 +            # macro
 +            return True
 +
 +        return [x for x in self._function_macros.values() if is_effective(x, self)]
 +
 +    def get_callbacks(self) -> T.List[Callback]:
 +        return self._callbacks.values()
 +
 +    def find_class(self, cls: str) -> T.Optional[Class]:
 +        return self._classes.get(cls)
 +
 +    def find_record(self, record: str) -> T.Optional[Record]:
 +        return self._records.get(record)
 +
 +    def find_interface(self, iface: str) -> T.Optional[Interface]:
 +        return self._interfaces.get(iface)
 +
 +    def find_union(self, union: str) -> T.Optional[Union]:
 +        return self._unions.get(union)
 +
 +    def find_enumeration(self, enum: str) -> T.Optional[Enumeration]:
 +        return self._enumerations.get(enum)
 +
 +    def find_bitfield(self, bitfield: str) -> T.Optional[BitField]:
 +        return self._bitfields.get(bitfield)
 +
 +    def find_error_domain(self, domain: str) -> T.Optional[ErrorDomain]:
 +        return self._error_domains.get(domain)
 +
 +    def find_alias(self, alias: str) -> T.Optional[Alias]:
 +        return self._aliases.get(alias)
 +
 +    def find_function(self, func: str) -> T.Optional[Function]:
 +        if func in self._functions:
 +            return self._functions.get(func)
 +        if func in self._function_macros:
 +            return self._function_macros.get(func)
 +        return None
 +
 +    def find_real_type(self, name: str) -> T.Optional[Type]:
 +        if name in self._aliases:
 +            return self._aliases[name]
 +        if name in self._bitfields:
 +            return self._bitfields[name]
 +        if name in self._callbacks:
 +            return self._callbacks[name]
 +        if name in self._constants:
 +            return self._constants[name]
 +        if name in self._enumerations:
 +            return self._enumerations[name]
 +        if name in self._error_domains:
 +            return self._error_domains[name]
 +        if name in self._classes:
 +            return self._classes[name]
 +        if name in self._interfaces:
 +            return self._interfaces[name]
 +        if name in self._records:
 +            return self._records[name]
 +        if name in self._unions:
 +            return self._unions[name]
 +        return None
 +
 +    def find_symbol(self, name: str) -> T.Optional[Type]:
 +        return self._symbols.get(name)
 +
 +    def find_prerequisite_type(self, name: str) -> T.Optional[Type]:
 +        if name in self._classes:
 +            return self._classes[name]
-             for repo in includes.values():
-                 if repo.namespace.name != ns:
-                     continue
-                 prereq = repo.namespace.find_prerequisite_type(name)
-                 if prereq is not None:
-                     return Type(name=f"{repo.namespace.name}.{prereq.name}", ctype=prereq.ctype)
-             return None
++        if name in self._interfaces:
 +            return self._interfaces[name]
 +        return None
 +
 +
 +class Repository:
 +    def __init__(self):
 +        self.includes: T.Mapping[str, Repository] = {}
 +        self.packages: T.List[Package] = []
 +        self.c_includes: T.List[CInclude] = []
 +        self.types: T.Mapping[str, T.List[Type]] = {}
 +        self._namespaces: T.List[Namespace] = []
 +        self.girfile: T.Optional[str] = None
 +
 +    def add_namespace(self, ns: Namespace) -> None:
 +        self._namespaces.append(ns)
 +        ns.repository = self
 +
 +    def get_namespace(self, ns: str) -> T.Optional[Namespace]:
 +        for namespace in self._namespaces:
 +            if namespace.name == ns:
 +                return namespace
 +        return None
 +
 +    def find_included_namespace(self, ns: str) -> T.Optional[Namespace]:
 +        for repo_name in self.includes:
 +            repo = self.includes[repo_name]
 +            if repo.namespace.name == ns:
 +                return repo.namespace
 +        return None
 +
++    def _lookup_type(self, name: str) -> T.Optional[Type]:
++        types = self.types.get(name)
++        if types is None:
++            return None
++        for t in types:
++            if t.resolved:
++                return t
++        return types[0]
++
 +    def resolve_empty_ctypes(self, seen_types: T.Mapping[str, T.List[Type]]) -> None:
 +        for fqtn in seen_types:
 +            types = seen_types[fqtn]
 +            resolved_types = [t for t in types if t.resolved]
 +            if len(resolved_types) == 0:
 +                ns, name = fqtn.split('.', 1)
 +                backstop = f"{self.namespace.identifier_prefix[0]}{name}"
 +                resolved_types.append(Type(fqtn, backstop))
 +            self.types[fqtn] = resolved_types
 +            log.debug(f"Type: {fqtn}: {resolved_types}")
 +
 +    def resolve_interface_requires(self) -> None:
 +        def find_prerequisite_type(includes, ns, name):
-                     t = self.find_type(prerequisite.name)
-                     prerequisite.ctype = t.ctype
++            repository = includes.get(ns)
++            if repository is None:
++                return None
++            prereq = repository.namespace.find_prerequisite_type(name)
++            # If the prerequisite type is unqualified, then we qualify it here
++            if '.' not in prereq.name:
++                prereq.name = f"{repository.namespace.name}.{prereq.name}"
++            return prereq
 +
 +        ifaces = self.namespace.get_interfaces()
 +        for iface in ifaces:
 +            if iface.prerequisite is None:
 +                continue
 +            prerequisite = None
 +            if '.' in iface.prerequisite.name:
 +                ns, name = iface.prerequisite.name.split('.', 1)
 +                if ns == self.namespace.name:
 +                    prerequisite = self.namespace.find_prerequisite_type(name)
 +                else:
 +                    prerequisite = find_prerequisite_type(self.includes, ns, name)
 +            else:
 +                prerequisite = self.namespace.find_prerequisite_type(iface.prerequisite.name)
 +            if prerequisite is not None:
 +                if prerequisite.ctype is None:
-     def resolve_class_type(self) -> None:
++                    if '.' not in prerequisite.name:
++                        name = f"{self.namespace.name}.{prerequisite.name}"
++                    else:
++                        name = prerequisite.name
++                    t = self._lookup_type(name)
++                    if t is not None:
++                        prerequisite.ctype = t.ctype
++                    else:
++                        # This is kind of a kludge, but apparently we can get into
++                        # class definitions missing a c:type; if that happens, we
++                        # take the identifier prefix of the namespace and append the
++                        # class name, because that's the inverse of how g-ir-scanner
++                        # determines the class name
++                        prerequisite.ctype = f"{self.namespace.identifier_prefix[0]}{prerequisite.name}"
 +                iface.prerequisite = prerequisite
 +                log.debug(f"Prerequisite type for interface {iface}: {iface.prerequisite}")
 +
-                 t = self.find_type(name)
++    def resolve_class_ctype(self) -> None:
 +        classes = self.namespace.get_classes()
 +        for cls in classes:
 +            if cls.ctype is None:
 +                if '.' not in cls.name:
 +                    name = f"{self.namespace.name}.{cls.name}"
 +                else:
 +                    name = cls.name
-             for repo in includes.values():
-                 if repo.namespace.name != ns:
-                     continue
-                 iface = repo.namespace.find_interface(name)
-                 if iface is not None:
-                     return Type(name=f"{repo.namespace.name}.{iface.name}", ctype=iface.ctype)
-             return None
++                t = self._lookup_type(name)
 +                if t is not None:
 +                    cls.ctype = t.base_ctype
 +                else:
 +                    # This is kind of a kludge, but apparently we can get into
 +                    # class definitions missing a c:type; if that happens, we
 +                    # take the identifier prefix of the namespace and append the
 +                    # class name, because that's the inverse of how g-ir-scanner
 +                    # determines the class name
 +                    cls.ctype = f"{self.namespace.identifier_prefix[0]}{cls.name}"
 +                log.debug(f"Updated C type for {cls}")
 +
 +    def resolve_class_implements(self) -> None:
 +        def find_interface_type(includes, ns, name):
-                         t = self.find_type(iface_type.name)
++            repository = includes.get(ns)
++            if repository is None:
++                return None
++            iface = repository.namespace.find_interface(name)
++            # If the interface type is unqualified, then we qualify it here
++            if '.' not in iface.name:
++                iface.name = f"{repository.namespace.name}.{iface.name}"
++            return iface
 +
 +        classes = self.namespace.get_classes()
 +        for cls in classes:
 +            if cls.implements is None:
 +                continue
 +            implements = cls.implements
 +            cls.implements = []
 +            for iface in implements:
 +                if '.' in iface.name:
 +                    ns, name = iface.name.split('.', 1)
 +                    if ns == self.namespace.name:
 +                        iface_type = self.namespace.find_interface(name)
 +                    else:
 +                        iface_type = find_interface_type(self.includes, ns, name)
 +                else:
 +                    iface_type = self.namespace.find_interface(iface.name)
 +                if iface_type is not None:
 +                    if iface_type.ctype is None:
-                     t = self.find_type(parent.name)
++                        t = self._lookup_type(iface_type.name)
 +                        iface_type.ctype = t.ctype
 +                    cls.implements.append(iface_type)
 +            log.debug(f"Interfaces implemented by {cls}: {cls.implements}")
 +
 +    def resolve_class_ancestors(self) -> None:
 +        def find_parent_class(includes, ns, name):
 +            repository = includes.get(ns)
 +            if repository is None:
 +                return None
 +            parent_class = repository.namespace.find_class(name)
 +            # If the parent type is unqualified, then we qualify it here
 +            if '.' not in parent_class.name:
 +                parent_class.name = f"{repository.namespace.name}.{parent_class.name}"
 +            return parent_class
 +
 +        classes = self.namespace.get_classes()
 +        for cls in classes:
 +            if cls.parent is None:
 +                continue
 +            ancestors = []
 +            parent = cls.parent
 +            while parent is not None:
 +                if '.' in parent.name:
 +                    ns, name = parent.name.split('.')
 +                    if ns == self.namespace.name:
 +                        real_parent = self.namespace.find_class(name)
 +                    else:
 +                        real_parent = find_parent_class(self.includes, ns, name)
 +                else:
 +                    real_parent = self.namespace.find_class(parent.name)
 +                if real_parent is None:
 +                    break
 +                if real_parent.parent is not None and real_parent.parent.name == parent.name:
 +                    log.warning(f"Found a loop in the ancestors for {cls}: {real_parent} matches {parent}")
 +                    break
 +                if real_parent.ctype is None:
 +                    log.debug(f"Looking up C type for {parent.fqtn}")
-     def find_type(self, name: str) -> T.Optional[Type]:
-         types = self.types.get(name)
-         if types is None:
-             return None
-         for t in types:
-             if t.resolved:
-                 return t
-         return types[0]
++                    t = self._lookup_type(parent.name)
 +                    real_parent.ctype = t.ctype
 +                log.debug(f"Adding ancestor {real_parent} for {cls}")
 +                ancestors.append(real_parent)
 +                parent = real_parent.parent
 +            cls.ancestors = ancestors
 +            cls.parent = ancestors[0]
 +            log.debug(f"Ancestors for {cls}: parent: {cls.parent}, ancestors: {cls.ancestors}")
 +
++    def resolve_class_descendants(self) -> None:
++        seen_parents = {}
++        for cls in self.namespace.get_classes():
++            if cls.parent is not None:
++                seen_parents.setdefault(cls.parent.name, []).append(cls)
++        for name, descendants in seen_parents.items():
++            if name in self.namespace._classes:
++                self.namespace._classes[name].descendants = descendants
++
 +    def resolve_moved_to(self) -> None:
 +        functions = list(self.namespace.get_functions())
 +        old_len = len(functions)
 +        for func in functions[:]:
 +            if func.moved_to is None:
 +                continue
 +            moved_type, moved_func_name = func.moved_to.split('.')
 +            real_type = self.namespace.find_real_type(moved_type)
 +            if real_type is None:
 +                continue
 +            self.namespace._functions.pop(func.name)    # XXX: Add accessor
 +        new_len = len(self.namespace._functions)
 +        diff = old_len - new_len
 +        log.debug(f"Removed {old_len} - {new_len} functions: {diff}")
 +
 +    def resolve_symbols(self) -> None:
 +        symbols: T.Mapping[str, Type] = {}
 +        for func in self.namespace.get_functions():
 +            symbols[func.identifier] = func
 +        for func in self.namespace.get_function_macros():
 +            symbols[func.identifier] = func
 +        for cls in self.namespace.get_classes():
 +            for m in cls.constructors:
 +                symbols[m.identifier] = cls
 +            for m in cls.methods:
 +                symbols[m.identifier] = cls
 +            for m in cls.functions:
 +                symbols[m.identifier] = cls
 +        for iface in self.namespace.get_interfaces():
 +            for m in iface.methods:
 +                symbols[m.identifier] = iface
 +            for m in iface.functions:
 +                symbols[m.identifier] = iface
 +        for record in self.namespace.get_records():
 +            for m in record.constructors:
 +                symbols[m.identifier] = record
 +            for m in record.methods:
 +                symbols[m.identifier] = record
 +            for m in record.functions:
 +                symbols[m.identifier] = record
 +        for union in self.namespace.get_unions():
 +            for m in union.constructors:
 +                symbols[m.identifier] = union
 +            for m in union.methods:
 +                symbols[m.identifier] = union
 +            for m in union.functions:
 +                symbols[m.identifier] = union
 +        self.namespace._symbols = symbols
 +
++    def resolve_interface_implementations(self) -> None:
++        seen_impls = {}
++        for iface in self.namespace.get_interfaces():
++            for cls in self.namespace.get_classes():
++                if cls.implements is None:
++                    continue
++                if iface in cls.implements:
++                    seen_impls.setdefault(iface.name, []).append(cls)
++        for iface, seen in seen_impls.items():
++            if iface in self.namespace._interfaces:
++                self.namespace._interfaces[iface].implementations = seen
++
 +    def get_class_hierarchy(self, root=None):
 +        flat_tree = []
 +        seen_types = {}
 +
 +        def window(iterable, size=2):
 +            i = iter(iterable)
 +            win = []
 +            for e in range(0, size):
 +                win.append(next(i))
 +            yield win
 +            for e in i:
 +                win = win[1:] + [e]
 +                yield win
 +
 +        for cls in self.namespace.get_classes():
 +            if cls.parent is None:
 +                flat_tree.append((cls.name, None))
 +                continue
 +
 +            if len(cls.ancestors) < 2:
 +                flat_tree.append((cls.name, cls.ancestors[0].name))
 +            else:
 +                flat_tree.append((cls.name, cls.ancestors[0].name))
 +                for chunk in window(cls.ancestors, size=2):
 +                    if chunk[0].name in seen_types:
 +                        continue
 +                    if len(chunk) == 2:
 +                        flat_tree.append((chunk[0].name, chunk[1].name))
 +                    else:
 +                        flat_tree.append((chunk[0].name, None))
 +                    seen_types[chunk[0].name] = 1
 +
 +        def subtree(cls, rel):
 +            return {
 +                v: subtree(v, rel)
 +                for v in [x[0] for x in rel if x[1] == cls]
 +            }
 +
 +        return subtree(root, flat_tree)
 +
 +    @property
 +    def namespace(self) -> T.Optional[Namespace]:
 +        return self._namespaces[0]
 +
++    def find_type(self, name: str, ns: T.Optional[str] = None) -> T.Optional[T.Tuple[Namespace, Type]]:
++        if ns is None or self.namespace.name == ns:
++            res = self.namespace.find_real_type(name)
++            if res is not None:
++                return (self.namespace, res)
++        for repo in self.includes.values():
++            if ns is not None and ns != repo.namespace.name:
++                continue
++            res = repo.namespace.find_real_type(name)
++            if res is not None:
++                return (repo.namespace, res)
++        return None
++
++    def find_symbol(self, name: str) -> T.Optional[T.Tuple[Namespace, Type]]:
++        log.debug(f"Looking for symbol {name} in current namespace {self.namespace.name}")
++        res = self.namespace.find_symbol(name)
++        if res is not None:
++            return (self.namespace, res)
++        for repo in self.includes.values():
++            log.debug(f"Looking for symbol {name} in namespace {repo.namespace.name}")
++            res = repo.namespace.find_symbol(name)
++            if res is not None:
++                return (repo.namespace, res)
++        return None
++
++    def find_class(self, name: str, ns: T.Optional[str] = None) -> T.Optional[T.Tuple[Namespace, Type]]:
++        if ns is None or self.namespace.name == ns:
++            res = self.namespace.find_class(name)
++            if res is not None:
++                return (self.namespace, res)
++        for repo in self.includes.values():
++            if ns is not None and ns != repo.namespace.name:
++                continue
++            res = repo.namespace.find_class(name)
++            if res is not None:
++                return (repo.namespace, res)
++        return None
++
++    def find_interface(self, name: str, ns: T.Optional[str] = None) -> T.Optional[T.Tuple[Namespace, Type]]:
++        if ns is None or self.namespace.name == ns:
++            res = self.namespace.find_interface(name)
++            if res is not None:
++                return (self.namespace, res)
++        for repo in self.includes.values():
++            if ns is not None and ns != repo.namespace.name:
++                continue
++            res = repo.namespace.find_interface(name)
++            if res is not None:
++                return (repo.namespace, res)
++        return None
index 92b3cbfe85ff35a5a20162a96e87e7fa29a426c1,0000000000000000000000000000000000000000..7637f194a33b83faa66f1845ac8decca11281ccb
mode 100644,000000..100644
--- /dev/null
@@@ -1,1012 -1,0 +1,1057 @@@
- FUNDAMENTAL_TYPES = [
 +# SPDX-FileCopyrightText: 2020 GNOME Foundation
 +# SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +
 +import os
 +import typing as T
 +import xml.etree.ElementTree as ET
 +
 +from .. import log
 +from . import ast
 +
 +GI_NAMESPACES = {
 +    'core': "http://www.gtk.org/introspection/core/1.0",
 +    'c': "http://www.gtk.org/introspection/c/1.0",
 +    'glib': "http://www.gtk.org/introspection/glib/1.0",
 +}
 +
-     'gint', 'guint', 'int', 'unsigned', 'unsigned int',
++FUNDAMENTAL_INTEGRAL_TYPES = [
 +    'gint8', 'guint8', 'int8_t', 'uint8_t',
 +    'gint16', 'guint16', 'int16_t', 'uint16_t',
 +    'gint32', 'guint32', 'int32_t', 'uint32_t',
 +    'gint64', 'guint64', 'int64_t', 'uint64_t',
-     'utf8', 'filename',
++    'gint', 'int',
++    'guint', 'unsigned', 'unsigned int',
 +    'gfloat', 'float',
 +    'gdouble', 'double', 'long double',
 +    'gchar', 'guchar', 'char', 'unsigned char',
 +    'gshort', 'gushort', 'short', 'unsigned short',
 +    'glong', 'gulong', 'long', 'unsigned long',
-     'gpointer', 'gconstpointer',
-     'gchar*', 'char*', 'guchar*',
 +    'gunichar',
-             self._repository.resolve_interface_requires()
-             self._repository.resolve_class_type()
 +    'gsize', 'gssize', 'size_t',
 +    'gboolean', 'bool',
 +    'va_list',
 +]
 +
++FUNDAMENTAL_TYPES = FUNDAMENTAL_INTEGRAL_TYPES + [
++    'gpointer', 'gconstpointer',
++    'gchar*', 'char*', 'guchar*',
++    'utf8', 'filename',
++]
++
 +GLIB_ALIASES = {
 +    'gchar': 'char',
 +    'gdouble': 'double',
 +    'gfloat': 'float',
 +    'gint': 'int',
 +    'glong': 'long',
 +    'gshort': 'short',
 +}
 +
 +FUNDAMENTAL_CTYPES = {
++    'utf8': 'char*',
++    'filename': 'char*',
 +    'GObject.Object': 'GObject*',
 +    'GObject.InitiallyUnowned': 'GInitiallyUnowned*',
 +    'GObject.ParamSpec': 'GObject.ParamSpec*',
 +}
 +
 +
 +def _corens(tag: str) -> str:
 +    return f"{{{GI_NAMESPACES['core']}}}{tag}"
 +
 +
 +def _glibns(tag: str) -> str:
 +    return f"{{{GI_NAMESPACES['glib']}}}{tag}"
 +
 +
 +def _cns(tag: str) -> str:
 +    return f"{{{GI_NAMESPACES['c']}}}{tag}"
 +
 +
 +class GirParser:
 +    def __init__(self, search_paths=[]):
 +        self._search_paths = search_paths
 +        self._repository = None
 +        self._dependencies = {}
 +        self._seen_types = {}
 +        self._current_namespace = []
 +
 +    def append_search_path(self, path: str) -> None:
 +        """Append a path to the list of search paths"""
 +        self._search_paths.append(path)
 +
 +    def prepend_search_paths(self, path: str) -> None:
 +        """Prepend a path to the list of search paths"""
 +        self._search_paths = [path] + self._search_paths
 +
 +    def parse(self, girfile: T.TextIO) -> None:
 +        """Parse @girfile"""
 +        log.debug(f"Loading GIR for {girfile}")
 +        tree = ET.parse(girfile)
 +        repository = self._parse_tree(tree.getroot())
 +        if repository is None:
 +            log.error(f"Could not parse GIR {girfile}")
 +        else:
 +            if isinstance(girfile, str):
 +                repository.girfile = girfile
 +            else:
 +                repository.girfile = girfile.name
 +            self._repository = repository
 +            self._repository.resolve_empty_ctypes(self._seen_types)
-         assert(ns not in self._current_namespace)
++            self._repository.resolve_class_ctype()
 +            self._repository.resolve_class_implements()
 +            self._repository.resolve_class_ancestors()
++            self._repository.resolve_class_descendants()
++            self._repository.resolve_interface_requires()
++            self._repository.resolve_interface_implementations()
 +            self._repository.resolve_moved_to()
 +            self._repository.resolve_symbols()
 +
 +    def get_repository(self, name: T.Optional[str] = None) -> T.Optional[ast.Repository]:
 +        if name is None:
 +            return self._repository
 +        else:
 +            return self._dependencies[name]
 +
 +    def _push_namespace(self, ns: ast.Namespace) -> None:
-                 t = ast.Type(name=fqtn, ctype=ctype)
++        assert ns not in self._current_namespace
 +        self._current_namespace.append(ns)
 +
 +    def _pop_namespace(self) -> None:
 +        self._current_namespace.pop()
 +
 +    def _get_namespace(self) -> T.Optional[ast.Namespace]:
 +        if len(self._current_namespace) == 0:
 +            return None
 +        return self._current_namespace[len(self._current_namespace) - 1]
 +
 +    def _lookup_type(self, name: str, ctype: T.Optional[str] = None) -> ast.Type:
 +        """Look up a type, and if not found, register it"""
++        is_fundamental = False
 +        if name in FUNDAMENTAL_TYPES:
 +            if name in GLIB_ALIASES:
 +                fqtn = GLIB_ALIASES[name]
 +            else:
 +                fqtn = name
++            is_fundamental = True
 +        elif name == 'GType':
 +            # This is messy, because GType is part of GObject, but GLib ends up
 +            # registering it first
 +            fqtn = 'GObject.Type'
++            is_fundamental = True
 +        elif '.' in name:
 +            fqtn = name
 +        else:
 +            ns = self._get_namespace()
 +            if ns is not None:
 +                fqtn = f"{ns.name}.{name}"
 +            else:
 +                log.debug(f"Unqualified type name {name} found")
 +                fqtn = name
 +        if ctype is None and fqtn in FUNDAMENTAL_TYPES:
 +            for t in FUNDAMENTAL_TYPES:
 +                if t == fqtn:
 +                    ctype = t
 +                    break
 +        if ctype is None and fqtn in FUNDAMENTAL_CTYPES:
 +            ctype = FUNDAMENTAL_CTYPES[fqtn]
 +        found_types = self._seen_types.get(fqtn)
 +        if found_types is not None:
 +            if ctype is not None:
 +                for t in found_types:
 +                    if t.resolved and t.ctype == ctype:
 +                        log.debug(f"Found seen type: {t} (with ctype)")
 +                        return t
-         res = ast.Type(name=fqtn, ctype=ctype)
++                t = ast.Type(name=fqtn, ctype=ctype, is_fundamental=is_fundamental)
 +                found_types.append(t)
 +                log.debug(f"Seen new type: {t} (with ctype)")
 +                return t
 +            log.debug(f"Found seen type: {found_types[0]}")
 +            return found_types[0]
 +        # First time we saw this type
-             zero_terminated = int(child.attrib.get('zero-terminated', 0))
-             fixed_size = int(child.attrib.get('fixed-size', -1))
-             length = int(child.attrib.get('length', -1))
++        res = ast.Type(name=fqtn, ctype=ctype, is_fundamental=is_fundamental)
 +        self._seen_types[fqtn] = [res]
 +        log.debug(f"Seen new type: {res}")
 +        return res
 +
 +    def _parse_dependency(self, include: ast.Include) -> None:
 +        if self._dependencies.get(include.name, None) is not None:
 +            log.debug(f"Dependency {include} already parsed")
 +            return
 +        found = False
 +        for base_path in self._search_paths:
 +            girfile = os.path.join(base_path, f"{include}.gir")
 +            if os.path.exists(girfile) and os.path.isfile(girfile):
 +                log.debug(f"Loading GIR for dependency {include} at {girfile}")
 +                tree = ET.parse(girfile)
 +                repository = self._parse_tree(tree.getroot())
 +                if repository is not None:
 +                    repository.girfile = girfile
++                    repository.resolve_moved_to()
++                    repository.resolve_symbols()
 +                    ns = repository.namespace
 +                    self._dependencies[ns.name] = repository
 +                    found = True
 +                    break
 +        if not found:
 +            log.error(f"Could not find GIR dependency in the search paths: {include}")
 +
 +    def _parse_tree(self, root: ET.Element) -> ast.Repository:
 +        assert root.tag == _corens('repository')
 +
 +        includes: T.List[ast.Include] = []
 +        c_includes: T.List[str] = []
 +        packages: T.List[str] = []
 +
 +        for node in root:
 +            if node.tag == _corens('include'):
 +                includes.append(self._parse_include(node))
 +            elif node.tag == _cns('include'):
 +                c_includes.append(self._parse_c_include(node))
 +            elif node.tag == _corens('package'):
 +                packages.append(self._parse_package(node))
 +
 +        ns = root.find(_corens('namespace'))
 +        assert ns is not None
 +
 +        identifier_prefixes = ns.attrib.get(_cns('identifier-prefixes'))
 +        if identifier_prefixes is not None:
 +            identifier_prefixes = identifier_prefixes.split(',')
 +        symbol_prefixes = ns.attrib.get(_cns('symbol-prefixes'))
 +        if symbol_prefixes is not None:
 +            symbol_prefixes = symbol_prefixes.split(',')
 +
 +        namespace = ast.Namespace(ns.attrib['name'], ns.attrib['version'], identifier_prefixes, symbol_prefixes)
 +        shared_libs = ns.attrib.get('shared-library')
 +        if shared_libs:
 +            namespace.add_shared_libraries(shared_libs.split(','))
 +
 +        repository = ast.Repository()
 +        repository.c_includes = c_includes
 +        repository.packages = packages
 +
 +        for include in includes:
 +            log.debug(f"Parsing dependency {include}")
 +            self._parse_dependency(include)
 +
 +        repository.includes = self._dependencies
 +
 +        repository.add_namespace(namespace)
 +
 +        parse_sections: T.Mapping[str, T.Callable[[ET.Element, ast.Repository, ast.Namespace], T.Any]] = {
 +            _corens('alias'): self._parse_alias,
 +            _corens('bitfield'): self._parse_bitfield,
 +            _glibns('boxed'): self._parse_boxed,
 +            _corens('callback'): self._parse_callback,
 +            _corens('class'): self._parse_class,
 +            _corens('constant'): self._parse_constant,
 +            _corens('enumeration'): self._parse_enumeration,
 +            _corens('function-macro'): self._parse_function_macro,
 +            _corens('function'): self._parse_function,
 +            _corens('interface'): self._parse_interface,
 +            _corens('record'): self._parse_record,
 +            _corens('union'): self._parse_union,
 +        }
 +
 +        self._push_namespace(namespace)
 +
 +        for node in ns:
 +            parser_method = parse_sections.get(node.tag, None)
 +            if parser_method is not None:
 +                parser_method(node, repository, namespace)
 +
 +        self._pop_namespace()
 +
 +        return repository
 +
 +    def _parse_include(self, node: ET.Element) -> ast.Include:
 +        return ast.Include(node.attrib['name'], node.attrib['version'])
 +
 +    def _parse_c_include(self, node: ET.Element) -> str:
 +        return node.attrib['name']
 +
 +    def _parse_package(self, node: ET.Element) -> str:
 +        return node.attrib['name']
 +
 +    def _maybe_parse_doc(self, node: ET.Element) -> T.Optional[ast.Doc]:
 +        child = node.find('core:doc', GI_NAMESPACES)
 +        if child is None:
 +            return None
 +
 +        content = child.text or ""
 +
 +        return ast.Doc(content=content, filename=child.attrib['filename'], line=int(child.attrib['line']))
 +
 +    def _maybe_parse_source_position(self, node: ET.Element) -> T.Optional[ast.SourcePosition]:
 +        child = node.find('core:source-position', GI_NAMESPACES)
 +        if child is None:
 +            return None
 +
 +        return ast.SourcePosition(filename=child.attrib['filename'], line=int(child.attrib['line']))
 +
 +    def _maybe_parse_deprecated_doc(self, node: ET.Element) -> T.Optional[str]:
 +        child = node.find('core:doc-deprecated', GI_NAMESPACES)
 +        if child is None:
 +            return None
 +
 +        return "".join(child.itertext())
 +
 +    def _maybe_parse_attributes(self, node: ET.Element) -> T.Optional[T.Mapping[str, str]]:
 +        children = node.findall('core:attribute', GI_NAMESPACES)
 +        if children is None:
 +            return None
 +
 +        attrs = {}
 +        for child in children:
 +            name = child.attrib.get('name')
 +            value = child.attrib.get('value')
 +            if name is not None:
 +                attrs[name] = value
 +        return attrs
 +
 +    def _maybe_parse_docs(self, node: ET.Element, element: ast.GIRElement) -> None:
 +        doc = self._maybe_parse_doc(node)
 +        if doc is not None:
 +            element.set_doc(doc)
 +        source_pos = self._maybe_parse_source_position(node)
 +        if source_pos is not None:
 +            element.set_source_position(source_pos)
 +        attrs = self._maybe_parse_attributes(node)
 +        if attrs is not None:
 +            element.set_attributes(attrs)
 +        stability = node.attrib.get('stability')
 +        if stability is not None:
 +            element.set_stability(stability)
 +        deprecated = node.attrib.get('deprecated')
 +        if deprecated is not None:
 +            deprecated_since = node.attrib.get('deprecated-version')
 +            deprecated_doc = self._maybe_parse_deprecated_doc(node)
 +            if deprecated_doc is not None:
 +                element.set_deprecated(deprecated_doc, deprecated_since)
 +
 +    def _parse_ctype(self, node: ET.Element) -> ast.Type:
 +        ctype: T.Optional[ast.Type] = None
 +
 +        child = node.find('core:array', GI_NAMESPACES)
 +        if child is not None:
 +            name = node.attrib.get('name')
-                     log.debug(f"Unnabled element type {ttype}")
 +            array_type = child.attrib.get(_cns('type'))
++            attr_zero_terminated = child.attrib.get('zero-terminated')
++            attr_fixed_size = child.attrib.get('fixed-size')
++            attr_length = child.attrib.get('length')
 +
 +            target: T.Optional[ast.Type] = None
 +            child_type = child.find('core:type', GI_NAMESPACES)
 +            if child_type is not None:
 +                ttype = child_type.attrib.get(_cns('type'))
 +                tname = child_type.attrib.get('name')
 +                if tname is None and ttype is not None:
-                 elif tname != 'gpointer' and ttype == 'gpointer':
++                    log.debug(f"Unlabled element type {ttype}")
 +                    target = ast.Type(name=ttype.replace('*', ''), ctype=ttype)
 +                if tname == 'none' and ttype == 'void':
 +                    target = ast.VoidType()
-                 else:
++                elif ttype == 'gpointer' and tname in FUNDAMENTAL_INTEGRAL_TYPES:
++                    # API returning a pointer with an overridden fundamental type,
++                    # like in-out/out signal arguments
++                    ctype = self._lookup_type(name=tname, ctype=f"{tname}*")
++                elif ttype == 'gpointer' and tname != 'gpointer':
 +                    # API returning gpointer to avoid casting
 +                    target = self._lookup_type(name=tname)
-             ctype = ast.ArrayType(name=name, zero_terminated=zero_terminated, fixed_size=fixed_size, length=length,
++                elif tname:
 +                    target = self._lookup_type(name=tname, ctype=ttype)
++                else:
++                    target = ast.VoidType()
 +            else:
 +                target = ast.VoidType()
-                 elif tname != 'gpointer' and ttype == 'gpointer':
++            # This sort of complete brain damage is par for the course in g-i, sadly; I really
++            # need to go into it with a sledgehammer and make the output complete, instead of
++            # relying on assumptions made in 2010.
++            zero_terminated = False
++            fixed_size = -1
++            length = -1
++            if attr_zero_terminated is not None:
++                zero_terminated = bool(attr_zero_terminated == '1')
++            else:
++                zero_terminated = bool(attr_fixed_size is None and attr_length is None)
++            if attr_fixed_size is not None:
++                fixed_size = int(attr_fixed_size)
++            if attr_length is not None:
++                length = int(attr_length)
++
++            ctype = ast.ArrayType(name=name, zero_terminated=zero_terminated,
++                                  fixed_size=fixed_size, length=length,
 +                                  ctype=array_type, value_type=target)
 +        else:
 +            child = node.find('core:type', GI_NAMESPACES)
 +            if child is not None:
 +                ttype = child.attrib.get(_cns('type'))
 +                tname = child.attrib.get('name')
 +                if tname is None and ttype is None:
 +                    log.debug(f"Found empty type annotation for node {node.tag}")
 +                    ctype = ast.VoidType()
 +                elif tname is None and ttype is not None:
 +                    log.debug(f"Unnamed type {ttype}")
 +                    ctype = ast.Type(name=ttype.replace('*', ''), ctype=ttype)
 +                elif tname == 'none' and ttype == 'void':
 +                    ctype = None
 +                elif tname in ['GLib.List', 'GLib.SList']:
 +                    child_type = child.find('core:type', GI_NAMESPACES)
 +                    if child_type is not None:
 +                        etname = child_type.attrib.get('name', 'gpointer')
 +                        etype = self._lookup_type(name=etname)
 +                        ctype = ast.ListType(name=tname, ctype=ttype, value_type=etype)
 +                    else:
 +                        ctype = self._lookup_type(name=tname, ctype=ttype)
 +                elif tname in ['GList.HashTable']:
 +                    child_types = child.findall('core:type', GI_NAMESPACES)
 +                    if child_types is not None and len(child_types) == 2:
 +                        ktname = child_types[0].attrib.get('name', 'gpointer')
 +                        vtname = child_types[1].attrib.get('name', 'gpointer')
 +                        ctype = ast.MapType(name=tname, ctype=ttype,
 +                                            key_type=ast.Type(ktname),
 +                                            value_type=ast.Type(vtname))
 +                    else:
 +                        ctype = self._lookup_type(name=tname, ctype=ttype)
-         res = ast.Method(name=name, identifier=identifier, instance_param=instance_param, throws=throws)
++                elif ttype == 'gpointer' and tname in FUNDAMENTAL_INTEGRAL_TYPES:
++                    # API returning a pointer with an overridden fundamental type,
++                    # like in-out/out signal arguments
++                    ctype = self._lookup_type(name=tname, ctype=f"{tname}*")
++                elif ttype == 'gpointer' and tname != 'gpointer':
 +                    # API returning gpointer to avoid casting
 +                    ctype = self._lookup_type(name=tname)
 +                else:
 +                    ctype = self._lookup_type(name=tname, ctype=ttype)
 +            else:
 +                child = node.find('core:varargs', GI_NAMESPACES)
 +                if child is not None:
 +                    ctype = ast.VarArgs()
 +
 +        if ctype is None:
 +            ctype = ast.VoidType()
 +
 +        return ctype
 +
 +    def _parse_alias(self, node: ET.Element, repo: ast.Repository, ns: ast.Namespace) -> None:
 +        child = node.find('core:type', GI_NAMESPACES)
 +        assert child is not None
 +
 +        name = node.attrib.get('name')
 +        ctype = node.attrib.get(_cns('type'))
 +
 +        alias_type = ast.Type(name=child.attrib['name'], ctype=child.attrib.get(_cns('type')))
 +
 +        res = ast.Alias(name=name, namespace=ns.name, ctype=ctype, target=alias_type)
 +        res.set_introspectable(node.attrib.get('introspectable', '1') != '0')
 +        res.set_version(node.attrib.get('version'))
 +        self._maybe_parse_docs(node, res)
 +
 +        ns.add_alias(res)
 +
 +    def _parse_callback_field(self, node: ET.Element) -> ast.Callback:
 +        name = node.attrib.get('name')
 +        ctype = node.attrib.get(_cns('type'))
 +        throws = node.attrib.get('throws', '0') == '1'
 +
 +        child = node.find('core:return-value', GI_NAMESPACES)
 +        return_value = self._parse_return_value(child)
 +
 +        children = node.findall('./core:parameters/core:parameter', GI_NAMESPACES)
 +        params = []
 +        for child in children:
 +            params.append(self._parse_parameter(child))
 +
 +        res = ast.Callback(name=name, namespace=None, ctype=ctype, throws=throws)
 +        res.set_introspectable(node.attrib.get('introspectable', '1') != '0')
 +        res.set_version(node.attrib.get('version'))
 +        res.set_parameters(params)
 +        res.set_return_value(return_value)
 +        self._maybe_parse_docs(node, res)
 +        return res
 +
 +    def _parse_callback(self, node: ET.Element, repo: ast.Repository, ns: ast.Namespace) -> None:
 +        name = node.attrib.get('name')
 +        ctype = node.attrib.get(_cns('type'))
 +        throws = node.attrib.get('throws', '0') == '1'
 +
 +        child = node.find('core:return-value', GI_NAMESPACES)
 +        return_value = self._parse_return_value(child)
 +
 +        children = node.findall('./core:parameters/core:parameter', GI_NAMESPACES)
 +        params = []
 +        for child in children:
 +            params.append(self._parse_parameter(child))
 +
 +        res = ast.Callback(name=name, namespace=ns.name, ctype=ctype, throws=throws)
 +        res.set_introspectable(node.attrib.get('introspectable', '1') != '0')
 +        res.set_version(node.attrib.get('version'))
 +        res.set_parameters(params)
 +        res.set_return_value(return_value)
 +        self._maybe_parse_docs(node, res)
 +        ns.add_callback(res)
 +
 +    def _parse_constant(self, node: ET.Element, repo: ast.Repository, ns: T.Optional[ast.Namespace]) -> None:
 +        child = node.find('core:type', GI_NAMESPACES)
 +        assert child is not None
 +
 +        name = node.attrib.get('name')
 +        ctype = node.attrib.get(_cns('type'))
 +        value = node.attrib.get('value')
 +
 +        const_type = ast.Type(name=child.attrib['name'], ctype=child.attrib.get(_cns('type')))
 +
 +        res = ast.Constant(name=name, namespace=ns.name, ctype=ctype, value=value, target=const_type)
 +        res.set_introspectable(node.attrib.get('introspectable', '1') != '0')
 +        self._maybe_parse_docs(node, res)
 +
 +        ns.add_constant(res)
 +
 +    def _parse_return_value(self, node: ET.Element) -> ast.ReturnValue:
 +        transfer = node.attrib.get('transfer-ownership', 'none')
 +        nullable = node.attrib.get('nullable', '0') == '1'
 +        closure = int(node.attrib.get('closure', -1))
 +        destroy = int(node.attrib.get('destroy', -1))
 +        scope = node.attrib.get('scope')
 +
 +        ctype = self._parse_ctype(node)
 +
 +        res = ast.ReturnValue(transfer=transfer, target=ctype, nullable=nullable, closure=closure,
 +                              destroy=destroy, scope=scope)
 +        res.set_introspectable(node.attrib.get('introspectable', '1') != '0')
 +        self._maybe_parse_docs(node, res)
 +
 +        return res
 +
 +    def _parse_parameter(self, node: ET.Element, is_instance_param: bool = False) -> ast.Parameter:
 +        name = node.attrib.get('name')
 +        direction = node.attrib.get('direction', 'in')
 +        transfer = node.attrib.get('transfer-ownership', 'none')
 +        nullable = node.attrib.get('nullable', '0') == '1'
 +        optional = node.attrib.get('optional', '0') == '1'
 +        caller_allocates = node.attrib.get('caller-allocates', '1') == '1'
 +        closure = int(node.attrib.get('closure', -1))
 +        destroy = int(node.attrib.get('destroy', -1))
 +        scope = node.attrib.get('scope')
 +
 +        ctype = self._parse_ctype(node)
 +
 +        res = ast.Parameter(name=name, direction=direction, transfer=transfer, target=ctype,
 +                            optional=optional, nullable=nullable, caller_allocates=caller_allocates,
 +                            closure=closure, destroy=destroy, scope=scope)
 +        res.set_introspectable(node.attrib.get('introspectable', '1') != '0')
 +        self._maybe_parse_docs(node, res)
 +
 +        return res
 +
 +    def _parse_type_function(self, node: ET.Element, ns: T.Optional[ast.Namespace] = None) -> ast.Function:
 +        name = node.attrib.get('name')
 +        identifier = node.attrib.get(_cns('identifier'))
 +        throws = node.attrib.get('throws', '0') == '1'
 +        shadows = node.attrib.get('shadows')
 +        shadowed_by = node.attrib.get('shadowed-by')
 +        moved_to = node.attrib.get('moved-to')
 +
 +        child = node.find('core:return-value', GI_NAMESPACES)
 +        return_value = self._parse_return_value(child)
 +
 +        children = node.findall('./core:parameters/core:parameter', GI_NAMESPACES)
 +        params = []
 +        for child in children:
 +            params.append(self._parse_parameter(child))
 +
 +        if ns is not None:
 +            namespace = ns.name
 +        else:
 +            namespace = None
 +
 +        res = ast.Function(name=name, namespace=namespace, identifier=identifier, throws=throws)
 +        res.set_introspectable(node.attrib.get('introspectable', '1') != '0')
 +        res.set_version(node.attrib.get('version'))
 +        res.set_return_value(return_value)
 +        res.set_parameters(params)
 +        res.set_shadows(shadows)
 +        res.set_shadowed_by(shadowed_by)
 +        res.set_moved_to(moved_to)
 +        self._maybe_parse_docs(node, res)
 +        return res
 +
 +    def _parse_function(self, node: ET.Element, repo: ast.Repository, ns: ast.Namespace) -> None:
 +        res = self._parse_type_function(node, ns)
 +        ns.add_function(res)
 +
 +    def _parse_function_macro(self, node: ET.Element, repo: ast.Repository, ns: ast.Namespace) -> None:
 +        name = node.attrib.get('name')
 +        identifier = node.attrib.get(_cns('identifier'))
 +
 +        children = node.findall('./core:parameters/core:parameter', GI_NAMESPACES)
 +        params = []
 +        for child in children:
 +            params.append(self._parse_parameter(child))
 +
 +        res = ast.FunctionMacro(name=name, namespace=ns.name, identifier=identifier)
 +        res.set_introspectable(node.attrib.get('introspectable', '1') != '0')
 +        res.set_parameters(params)
 +        res.set_return_value(ast.ReturnValue(transfer='none',
 +                                             target=ast.VoidType(),
 +                                             nullable=False,
 +                                             closure=-1, destroy=-1,
 +                                             scope=None))
 +        res.set_introspectable(node.attrib.get('introspectable', '1') != '0')
 +        res.set_version(node.attrib.get('version'))
 +        self._maybe_parse_docs(node, res)
 +        ns.add_function_macro(res)
 +
 +    def _parse_method(self, node: ET.Element) -> ast.Method:
 +        name = node.attrib.get('name')
 +        identifier = node.attrib.get(_cns('identifier'))
 +        throws = node.attrib.get('throws', '0') == '1'
 +        shadows = node.attrib.get('shadows')
 +        shadowed_by = node.attrib.get('shadowed-by')
++        set_property = node.attrib.get(_glibns('set-property'))
++        get_property = node.attrib.get(_glibns('get-property'))
 +
 +        child = node.find('core:return-value', GI_NAMESPACES)
 +        return_value = self._parse_return_value(child)
 +
 +        child = node.find('./core:parameters/core:instance-parameter', GI_NAMESPACES)
 +        instance_param = self._parse_parameter(child, True)
 +
 +        children = node.findall('./core:parameters/core:parameter', GI_NAMESPACES)
 +        params = []
 +        for child in children:
 +            params.append(self._parse_parameter(child))
 +
-                            construct=construct, construct_only=construct_only)
++        res = ast.Method(name=name, identifier=identifier, instance_param=instance_param, throws=throws,
++                         set_property=set_property, get_property=get_property)
 +        res.set_return_value(return_value)
 +        res.set_parameters(params)
 +        res.set_introspectable(node.attrib.get('introspectable', '1') != '0')
 +        res.set_shadows(shadows)
 +        res.set_shadowed_by(shadowed_by)
 +        res.set_version(node.attrib.get('version'))
 +        self._maybe_parse_docs(node, res)
 +        return res
 +
 +    def _parse_virtual_method(self, node: ET.Element) -> ast.VirtualMethod:
 +        name = node.attrib.get('name')
 +        identifier = node.attrib.get(_cns('identifier'))
 +        invoker = node.attrib.get('invoker')
 +        throws = node.attrib.get('throws', '0') == '1'
 +
 +        child = node.find('core:return-value', GI_NAMESPACES)
 +        return_value = self._parse_return_value(child)
 +
 +        child = node.find('./core:parameters/core:instance-parameter', GI_NAMESPACES)
 +        instance_param = self._parse_parameter(child, True)
 +
 +        children = node.findall('./core:parameters/core:parameter', GI_NAMESPACES)
 +        params = []
 +        for child in children:
 +            params.append(self._parse_parameter(child))
 +
 +        res = ast.VirtualMethod(name=name, identifier=identifier, invoker=invoker, instance_param=instance_param, throws=throws)
 +        res.set_return_value(return_value)
 +        res.set_parameters(params)
 +        res.set_introspectable(node.attrib.get('introspectable', '1') != '0')
 +        res.set_version(node.attrib.get('version'))
 +        self._maybe_parse_docs(node, res)
 +        return res
 +
 +    def _parse_enum_member(self, node: ET.Element) -> ast.Member:
 +        name = node.attrib.get('name')
 +        value = node.attrib.get('value')
 +        identifier = node.attrib.get(_cns("identifier"))
 +        nick = node.attrib.get(_glibns("nick"))
 +
 +        res = ast.Member(name=name, value=value, identifier=identifier, nick=nick)
 +        self._maybe_parse_docs(node, res)
 +        return res
 +
 +    def _parse_enumeration(self, node: ET.Element, repo: ast.Repository, ns: ast.Namespace) -> None:
 +        children = node.findall('core:member', GI_NAMESPACES)
 +        if children is None or len(children) == 0:
 +            return
 +
 +        members = []
 +        for child in children:
 +            members.append(self._parse_enum_member(child))
 +
 +        children = node.findall('core:function', GI_NAMESPACES)
 +        functions = []
 +        for child in children:
 +            functions.append(self._parse_type_function(child))
 +
 +        name: str = node.attrib['name']
 +        ctype: str = node.attrib[_cns('type')]
 +        type_name: T.Optional[str] = node.attrib.get(_glibns('type-name'))
 +        get_type: T.Optional[str] = node.attrib.get(_glibns('get-type'))
 +        error_domain: T.Optional[str] = node.attrib.get(_glibns('error-domain'))
 +
 +        gtype = None
 +        if type_name is not None and get_type is not None:
 +            gtype = ast.GType(type_name, get_type)
 +
 +        if error_domain is not None:
 +            res: ast.ErrorDomain = ast.ErrorDomain(name=name, namespace=ns.name,
 +                                                   ctype=ctype, gtype=gtype,
 +                                                   domain=error_domain)
 +            ns.add_error_domain(res)
 +        else:
 +            res: ast.Enumeration = ast.Enumeration(name=name, namespace=ns.name,
 +                                                   ctype=ctype, gtype=gtype)
 +            ns.add_enumeration(res)
 +
 +        res.set_members(members)
 +        res.set_functions(functions)
 +        res.set_version(node.attrib.get('version'))
 +        self._maybe_parse_docs(node, res)
 +
 +    def _parse_bitfield(self, node: ET.Element, repo: ast.Repository, ns: ast.Namespace) -> None:
 +        children = node.findall('core:member', GI_NAMESPACES)
 +        if children is None or len(children) == 0:
 +            return
 +
 +        members = []
 +        for child in children:
 +            members.append(self._parse_enum_member(child))
 +
 +        children = node.findall('core:function', GI_NAMESPACES)
 +        functions = []
 +        for child in children:
 +            functions.append(self._parse_type_function(child))
 +
 +        name = node.attrib.get('name')
 +        ctype = node.attrib.get(_cns('type'))
 +        type_name = node.attrib.get(_glibns('type-name'))
 +        get_type = node.attrib.get(_glibns('get-type'))
 +
 +        gtype = None
 +        if type_name is not None:
 +            gtype = ast.GType(type_name, get_type)
 +
 +        res = ast.BitField(name=name, namespace=ns.name, ctype=ctype, gtype=gtype)
 +        res.set_members(members)
 +        res.set_functions(functions)
 +        res.set_version(node.attrib.get('version'))
 +        self._maybe_parse_docs(node, res)
 +        ns.add_bitfield(res)
 +
 +    def _parse_property(self, node: ET.Element) -> ast.Property:
 +        name = node.attrib.get('name')
 +        writable = node.attrib.get('writable', '0') == '1'
 +        readable = node.attrib.get('readable', '1') == '1'
 +        construct_only = node.attrib.get('construct-only', '0') == '1'
 +        construct = node.attrib.get('construct', '0') == '1'
 +        transfer = node.attrib.get('transfer-ownership')
++        setter = node.attrib.get('setter')
++        getter = node.attrib.get('getter')
 +
 +        ctype = self._parse_ctype(node)
 +
 +        res = ast.Property(name=name, transfer=transfer, target=ctype,
 +                           writable=writable, readable=readable,
++                           construct=construct, construct_only=construct_only,
++                           setter=setter, getter=getter)
 +        res.set_introspectable(node.attrib.get('introspectable', '1') != '0')
 +        res.set_version(node.attrib.get('version'))
 +        self._maybe_parse_docs(node, res)
 +        return res
 +
 +    def _parse_signal(self, node: ET.Element) -> ast.Signal:
 +        name = node.attrib.get('name')
 +        when = node.attrib.get('when')
 +        detailed = node.attrib.get('detailed') == '1'
 +        action = node.attrib.get('action') == '1'
 +        no_hooks = node.attrib.get('no-hooks') == '1'
 +        no_recurse = node.attrib.get('no-recurse') == '1'
 +
 +        child = node.find('core:return-value', GI_NAMESPACES)
 +        return_value = None
 +        if child is not None:
 +            return_value = self._parse_return_value(child)
 +
 +        children = node.findall('./core:parameters/core:parameter', GI_NAMESPACES)
 +        params = []
 +        for child in children:
 +            params.append(self._parse_parameter(child))
 +
 +        res = ast.Signal(name=name, when=when, detailed=detailed, action=action, no_hooks=no_hooks, no_recurse=no_recurse)
 +        res.set_parameters(params)
 +        res.set_introspectable(node.attrib.get('introspectable', '1') != '0')
 +        res.set_version(node.attrib.get('version'))
 +        self._maybe_parse_docs(node, res)
 +        if return_value is not None:
 +            res.set_return_value(return_value)
 +        return res
 +
 +    def _parse_field(self, node: ET.Element) -> ast.Field:
 +        name = node.attrib.get('name')
 +        writable = node.attrib.get('writable', '0') == '1'
 +        readable = node.attrib.get('readable', '0') == '1'
 +        private = node.attrib.get('private', '0') == '1'
 +        bits = int(node.attrib.get('bits', '0'))
 +
 +        child = node.find('core:callback', GI_NAMESPACES)
 +        if child is not None:
 +            ctype = self._parse_callback_field(child)
 +        else:
 +            ctype = self._parse_ctype(node)
 +
 +        if ctype is None:
 +            ctype = ast.VoidType()
 +
 +        res = ast.Field(name=name, writable=writable, readable=readable, private=private, bits=bits, target=ctype)
 +        res.set_introspectable(node.attrib.get('introspectable', '1') != '0')
 +        res.set_version(node.attrib.get('version'))
 +        self._maybe_parse_docs(node, res)
 +        return res
 +
 +    def _parse_implements(self, node: ET.Element) -> ast.Interface:
 +        return self._lookup_type(name=node.attrib['name'])
 +
 +    def _parse_class(self, node: ET.Element, repo: ast.Repository, ns: ast.Namespace) -> None:
 +        name = node.attrib.get('name')
 +        symbol_prefix = node.attrib.get(_cns('symbol-prefix'))
 +        ctype = node.attrib.get(_cns('type'))
 +        parent = node.attrib.get('parent')
 +        type_name = node.attrib.get(_glibns('type-name'))
 +        get_type = node.attrib.get(_glibns('get-type'))
 +        type_struct = node.attrib.get(_glibns('type-struct'))
 +        abstract = node.attrib.get('abstract', '0') == '1'
 +        fundamental = node.attrib.get(_glibns('fundamental'), '0') == '1'
 +        ref_func = node.attrib.get(_glibns('ref-func'))
 +        unref_func = node.attrib.get(_glibns('unref-func'))
 +
 +        parent_type = None
 +        if parent is not None:
 +            parent_type = self._lookup_type(name=parent)
 +
 +        gtype = None
 +        if type_name is not None:
 +            gtype = ast.GType(type_name=type_name, get_type=get_type, type_struct=type_struct)
 +
 +        fields = []
 +        children = node.findall('core:field', GI_NAMESPACES)
 +        for child in children:
 +            fields.append(self._parse_field(child))
 +
 +        ifaces = []
 +        children = node.findall('core:implements', GI_NAMESPACES)
 +        for child in children:
 +            ifaces.append(self._parse_implements(child))
 +
 +        ctors = []
 +        children = node.findall('core:constructor', GI_NAMESPACES)
 +        for child in children:
 +            ctors.append(self._parse_type_function(child))
 +
 +        methods = []
 +        children = node.findall('core:method', GI_NAMESPACES)
 +        for child in children:
 +            methods.append(self._parse_method(child))
 +
 +        vmethods = []
 +        children = node.findall('core:virtual-method', GI_NAMESPACES)
 +        for child in children:
 +            vmethods.append(self._parse_virtual_method(child))
 +
 +        functions = []
 +        children = node.findall('core:function', GI_NAMESPACES)
 +        for child in children:
 +            functions.append(self._parse_type_function(child))
 +
 +        properties = []
 +        children = node.findall('core:property', GI_NAMESPACES)
 +        for child in children:
 +            properties.append(self._parse_property(child))
 +
 +        signals = []
 +        children = node.findall('glib:signal', GI_NAMESPACES)
 +        for child in children:
 +            signals.append(self._parse_signal(child))
 +
 +        res = ast.Class(name=name, namespace=ns.name, symbol_prefix=symbol_prefix, ctype=ctype,
 +                        parent=parent_type, gtype=gtype,
 +                        abstract=abstract, fundamental=fundamental,
 +                        ref_func=ref_func, unref_func=unref_func)
 +        res.set_introspectable(node.attrib.get('introspectable', '1') != '0')
 +        res.set_version(node.attrib.get('version'))
 +        res.set_fields(fields)
 +        res.set_implements(ifaces)
 +        res.set_constructors(ctors)
 +        res.set_methods(methods)
 +        res.set_virtual_methods(vmethods)
 +        res.set_functions(functions)
 +        res.set_properties(properties)
 +        res.set_signals(signals)
 +        self._maybe_parse_docs(node, res)
 +        ns.add_class(res)
 +
 +    def _parse_interface(self, node: ET.Element, repo: ast.Repository, ns: ast.Namespace) -> None:
 +        name = node.attrib.get('name')
 +        symbol_prefix = node.attrib.get(_cns('symbol-prefix'))
 +        ctype = node.attrib.get(_cns('type'))
 +        type_name = node.attrib.get(_glibns('type-name'))
 +        get_type = node.attrib.get(_glibns('get-type'))
 +        type_struct = node.attrib.get(_glibns('type-struct'))
 +
 +        gtype = None
 +        if type_name is not None:
 +            gtype = ast.GType(type_name=type_name, get_type=get_type, type_struct=type_struct)
 +
 +        prerequisite = None
 +        child = node.find('core:prerequisite', GI_NAMESPACES)
 +        if child is not None:
 +            prerequisite = self._lookup_type(name=child.attrib['name'])
 +
 +        fields = []
 +        children = node.findall('core:field', GI_NAMESPACES)
 +        for child in children:
 +            fields.append(self._parse_field(child))
 +
 +        methods = []
 +        children = node.findall('core:method', GI_NAMESPACES)
 +        for child in children:
 +            methods.append(self._parse_method(child))
 +
 +        vmethods = []
 +        children = node.findall('core:virtual-method', GI_NAMESPACES)
 +        for child in children:
 +            vmethods.append(self._parse_virtual_method(child))
 +
 +        functions = []
 +        children = node.findall('core:function', GI_NAMESPACES)
 +        for child in children:
 +            functions.append(self._parse_type_function(child))
 +
 +        properties = []
 +        children = node.findall('core:property', GI_NAMESPACES)
 +        for child in children:
 +            properties.append(self._parse_property(child))
 +
 +        signals = []
 +        children = node.findall('glib:signal', GI_NAMESPACES)
 +        for child in children:
 +            signals.append(self._parse_signal(child))
 +
 +        res = ast.Interface(name=name, namespace=ns.name, symbol_prefix=symbol_prefix, ctype=ctype, gtype=gtype)
 +        res.set_prerequisite(prerequisite)
 +        res.set_fields(fields)
 +        res.set_virtual_methods(vmethods)
 +        res.set_properties(properties)
 +        res.set_signals(signals)
 +        res.set_methods(methods)
 +        res.set_functions(functions)
 +        res.set_introspectable(node.attrib.get('introspectable', '1') != '0')
 +        res.set_version(node.attrib.get('version'))
 +        self._maybe_parse_docs(node, res)
 +        ns.add_interface(res)
 +
 +    def _parse_boxed(self, node: ET.Element, repo: ast.Repository, ns: ast.Namespace) -> None:
 +        name = node.attrib.get(_glibns('name'))
 +        symbol_prefix = node.attrib.get(_cns('symbol-prefix'))
 +        type_name = node.attrib.get(_glibns('type-name'))
 +        get_type = node.attrib.get(_glibns('get-type'))
 +
 +        gtype = None
 +        if type_name is not None:
 +            gtype = ast.GType(type_name=type_name, get_type=get_type)
 +
 +        functions = []
 +        children = node.findall('core:function', GI_NAMESPACES)
 +        for child in children:
 +            functions.append(self._parse_type_function(child))
 +
 +        res = ast.Boxed(name=name, namespace=ns.name, symbol_prefix=symbol_prefix, gtype=gtype)
 +        res.set_introspectable(node.attrib.get('introspectable', '1') != '0')
 +        res.set_version(node.attrib.get('version'))
 +        res.set_functions(functions)
 +        self._maybe_parse_docs(node, res)
 +        ns.add_boxed(res)
 +
 +    def _parse_record(self, node: ET.Element, repo: ast.Repository, ns: ast.Namespace) -> None:
 +        name: str = node.attrib['name']
 +        symbol_prefix: str = node.attrib.get(_cns('symbol-prefix'), '')
 +        ctype: str = node.attrib[_cns('type')]
 +        type_name: T.Optional[str] = node.attrib.get(_glibns('type-name'))
 +        get_type: T.Optional[str] = node.attrib.get(_glibns('get-type'))
 +        type_struct: T.Optional[str] = node.attrib.get(_glibns('type-struct'))
 +        gtype_struct_for: T.Optional[str] = node.attrib.get(_glibns('is-gtype-struct-for'))
 +        disguised: bool = node.attrib.get('disguised', '0') == '1'
 +
 +        gtype = None
 +        if type_name is not None:
 +            gtype = ast.GType(type_name=type_name, get_type=get_type, type_struct=type_struct)
 +
 +        fields = []
 +        children = node.findall('core:field', GI_NAMESPACES)
 +        for child in children:
 +            fields.append(self._parse_field(child))
 +
 +        ctors = []
 +        children = node.findall('core:constructor', GI_NAMESPACES)
 +        for child in children:
 +            ctors.append(self._parse_type_function(child))
 +
 +        methods = []
 +        children = node.findall('core:method', GI_NAMESPACES)
 +        for child in children:
 +            methods.append(self._parse_method(child))
 +
 +        functions = []
 +        children = node.findall('core:function', GI_NAMESPACES)
 +        for child in children:
 +            functions.append(self._parse_type_function(child))
 +
 +        res = ast.Record(name=name, namespace=ns.name, symbol_prefix=symbol_prefix,
 +                         ctype=ctype, gtype=gtype,
 +                         struct_for=gtype_struct_for, disguised=disguised)
 +        res.set_introspectable(node.attrib.get('introspectable', '1') != '0')
 +        res.set_version(node.attrib.get('version'))
 +        res.set_fields(fields)
 +        res.set_constructors(ctors)
 +        res.set_methods(methods)
 +        res.set_functions(functions)
 +        self._maybe_parse_docs(node, res)
 +        ns.add_record(res)
 +
 +    def _parse_union(self, node: ET.Element, repo: ast.Repository, ns: ast.Namespace) -> None:
 +        name = node.attrib.get('name')
 +        symbol_prefix = node.attrib.get(_cns('symbol-prefix'))
 +        ctype = node.attrib.get(_cns('type'))
 +        type_name = node.attrib.get(_glibns('type-name'))
 +        get_type = node.attrib.get(_glibns('get-type'))
 +        type_struct = node.attrib.get(_glibns('type-struct'))
 +
 +        gtype = None
 +        if type_name is not None:
 +            gtype = ast.GType(type_name=type_name, get_type=get_type, type_struct=type_struct)
 +
 +        fields = []
 +        children = node.findall('core:field', GI_NAMESPACES)
 +        for child in children:
 +            fields.append(self._parse_field(child))
 +
 +        ctors = []
 +        children = node.findall('core:constructor', GI_NAMESPACES)
 +        for child in children:
 +            ctors.append(self._parse_type_function(child))
 +
 +        methods = []
 +        children = node.findall('core:method', GI_NAMESPACES)
 +        for child in children:
 +            methods.append(self._parse_method(child))
 +
 +        functions = []
 +        children = node.findall('core:function', GI_NAMESPACES)
 +        for child in children:
 +            functions.append(self._parse_type_function(child))
 +
 +        res = ast.Union(name=name, namespace=ns.name, symbol_prefix=symbol_prefix, ctype=ctype, gtype=gtype)
 +        res.set_introspectable(node.attrib.get('introspectable', '1') != '0')
 +        res.set_version(node.attrib.get('version'))
 +        res.set_fields(fields)
 +        res.set_constructors(ctors)
 +        res.set_methods(methods)
 +        res.set_functions(functions)
 +        self._maybe_parse_docs(node, res)
 +        ns.add_union(res)
index 9e4e4ccfe4d78f91b79a7d2c531e93bf6bb02c5b,0000000000000000000000000000000000000000..e5a2262b4a09ac7883d09c7b655ccfc9ee19972e
mode 100644,000000..100644
--- /dev/null
@@@ -1,210 -1,0 +1,212 @@@
-     print("\n".join(report))
-     return log_warnings_counter != 0
 +# SPDX-FileCopyrightText: 2020 GNOME Foundation
 +# SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +
 +import os
 +import platform
 +import sys
 +import time
 +
 +
 +def setup_output():
 +    try:
 +        if platform.system().lower() == 'windows':
 +            return os.isatty(sys.stdout.fileno())
 +        return os.isatty(sys.stdout.fileno()) and os.environ.get('TERM') != 'dumb'
 +    except Exception:
 +        return False
 +
 +
 +def setup_debug():
 +    if os.environ.get('GIDOCGEN_DEBUG', '0') == '1':
 +        return True
 +    return False
 +
 +
 +log_colorize_output = setup_output()
 +log_debug = setup_debug()
 +log_quiet = False
 +log_fatal_warnings = False
 +log_warnings_counter = 0
 +log_epoch = 0
 +
 +colors = {
 +    'NONE': "[0m",
 +    'RED': "[1;31m",
 +    'GREEN': "[1;32m",
 +    'YELLOW': "[1;33m",
 +    'BLUE': "[1;34m",
 +    'LIGHT_GREY': "[1;37m",
 +    'DARK_GREY': "[1;90m",
 +}
 +
 +modifiers = {
 +    'NONE': "[0m",
 +    'DEFAULT': "[4;39m",
 +    'BOLD_DEFAULT': "[1;39m",
 +    'DIM_DEFAULT': "[2;39m",
 +}
 +
 +
 +logged_once = set()
 +
 +
 +class AnsiEscape(object):
 +    '''
 +    A string-like object that contains an ANSI escaped string.
 +    '''
 +    char = '\033'
 +
 +    def __init__(self, *args, **kwargs):
 +        self.text = kwargs.get('text', '')
 +        self.color = kwargs.get('color', 'NONE')
 +        self.mods = kwargs.get('mods', 'DEFAULT')
 +
 +    def __str__(self):
 +        if self.mods != 'DEFAULT':
 +            return f'{AnsiEscape.char}{modifiers[self.mods]}{self.text}{AnsiEscape.char}{modifiers["NONE"]}'
 +        return f'{AnsiEscape.char}{colors[self.color]}{self.text}{AnsiEscape.char}{colors["NONE"]}'
 +
 +
 +def color(text, color_id):
 +    return f'\u001b[38;5;{color_id}m{text}\u001b[0m'
 +
 +
 +def red(text):
 +    return AnsiEscape(text=text, color='RED')
 +
 +
 +def green(text):
 +    return AnsiEscape(text=text, color='GREEN')
 +
 +
 +def yellow(text):
 +    return AnsiEscape(text=text, color='YELLOW')
 +
 +
 +def blue(text):
 +    return AnsiEscape(text=text, color='BLUE')
 +
 +
 +def bold(text):
 +    return AnsiEscape(text=text, mods='BOLD_DEFAULT')
 +
 +
 +def dim(text):
 +    return AnsiEscape(text=text, mods='DIM_DEFAULT')
 +
 +
 +class Location(object):
 +    '''
 +    A location object, pointing to a filename and a line.
 +    '''
 +    def __init__(self, **kwargs):
 +        self.filename = kwargs.get('filename', 'input')
 +        self.line = kwargs.get('line', 0)
 +
 +    def __str__(self):
 +        return f'{self.filename}:{self.line}:'
 +
 +
 +def log_once(text, prefix=None, location=None):
 +    '''
 +    Prints a line of text only once.
 +    '''
 +    t = tuple(text, prefix, location)
 +    if t in logged_once:
 +        return
 +    log(text, prefix, location)
 +    logged_once.add(t)
 +
 +
 +def set_quiet(quiet):
 +    global log_quiet
 +    log_quiet = quiet
 +
 +
 +def set_fatal_warnings(fatal_warnings):
 +    global log_fatal_warnings
 +    log_fatal_warnings = fatal_warnings
 +
 +
 +def set_log_epoch(epoch=0):
 +    global log_epoch
 +    if epoch == 0:
 +        log_epoch = time.monotonic()
 +    else:
 +        log_epoch = epoch
 +
 +
 +def log(text, prefix=None, location=None, out=None):
 +    '''
 +    Prints a line of text using the given prefix and location.
 +
 +    @prefix: (optional): a prefix string, or an AnsiEscape object
 +    @location: (optional): a location string, or a Location object
 +    @out: (optional): a File object
 +    '''
 +    res = []
 +    if prefix:
 +        res += [str(prefix), ': ']
 +    if location:
 +        res += [str(location), ' ']
 +    res += [text]
 +    print(''.join(res), file=out)
 +
 +
 +def error(text, location=None):
 +    '''Prints an error message'''
 +    log(text, prefix=red('ERROR'), location=location, out=sys.stderr)
 +    sys.exit(1)
 +
 +
 +def warning(text, location=None):
 +    '''Prints a warning message'''
 +    log(text, prefix=yellow('WARNING'), location=location, out=sys.stderr)
 +
 +    global log_warnings_counter
 +    log_warnings_counter += 1
 +
 +    if log_fatal_warnings:
 +        sys.exit(1)
 +
 +
 +def info(text, location=None):
 +    '''Prints an information message'''
 +    if not log_quiet:
 +        log(text, prefix=green('INFO'), location=location)
 +
 +
 +def debug(text, location=None):
 +    '''Prints a debug message'''
 +    if log_debug:
 +        log(text, prefix=dim('DEBUG'), location=location)
 +
 +
 +def deprecation(text, location=None):
 +    '''Prints a deprecation warning'''
 +    log(text, prefix=blue('DEPRECATED'), location=location, out=sys.stderr)
 +    global log_warnings_counter
 +    log_warnings_counter += 1
 +
 +
 +def checkpoint(prefix=None):
 +    if log_quiet:
 +        return
 +    elapsed = (time.monotonic() - log_epoch)
 +    msg = f"Elapsed time {elapsed:.3f} seconds"
 +    if prefix is None:
 +        prefix = green('INFO')
 +    log(msg, prefix)
 +
 +
 +def report():
++    global log_warnings_counter
 +    if log_quiet:
 +        return
 +    elapsed = (time.monotonic() - log_epoch)
 +    report = [""]
 +    report += [f"Elapsed time: {elapsed:.3f} seconds"]
 +    report += [f"Total warnings: {log_warnings_counter}"]
++    if log_warnings_counter == 0:
++        return 0
++    return 1
index 7ee1761c47c5ee16d2d0700ca3b5202a9d9f163c,0000000000000000000000000000000000000000..5106871b07c96754703463500e1ab8abf0ea32ef
mode 100644,000000..100644
--- /dev/null
@@@ -1,53 -1,0 +1,68 @@@
-             # XXX: The order is important; signals and properties have
-             # higher precedence than types
 +# SPDX-FileCopyrightText: 2021 GNOME Foundation <https://gnome.org>
 +# SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +
 +from markdown.extensions import Extension
 +from markdown.preprocessors import Preprocessor
 +
 +import re
 +
 +
 +SIGNAL_SIGIL_RE = re.compile(r"(^|\W)#([A-Z][A-Za-z0-9]+)::([a-z0-9_-]+)\b")
 +
 +PROP_SIGIL_RE = re.compile(r"(^|\W)#([A-Z][A-Za-z0-9]+):([a-z0-9_-]+)\b")
 +
 +TYPE_SIGIL_RE = re.compile(r"(^|\W)#([A-Z][A-Za-z0-9]+)\b")
 +
 +ARG_SIGIL_RE = re.compile(r"(^|\W)@([A-Za-z0-9_]+)\b")
 +
 +CONST_SIGIL_RE = re.compile(r"(^|\W)%([A-Z0-9_]+)\b")
 +
++FUNCTION_RE = re.compile(r"(^|\s+)([a-z][a-z0-9_]*)\(\)(\s+|$)")
++
 +
 +class GtkDocPreprocessor(Preprocessor):
 +    """Remove all gtk-doc sigils from the Markdown text"""
 +    def run(self, lines):
 +        new_lines = []
++        inside_code_block = False
 +        for line in lines:
++            if line.startswith("```"):
++                if not inside_code_block:
++                    inside_code_block = True
++                else:
++                    inside_code_block = False
++
 +            new_line = line
-             # Signal sigil
-             new_line = re.sub(SIGNAL_SIGIL_RE, r"\g<1>`\g<2>::\g<3>`", new_line)
 +
-             # Property sigil
-             new_line = re.sub(PROP_SIGIL_RE, r"\g<1>`\g<2>:\g<3>`", new_line)
++            # Never transform code blocks
++            if not inside_code_block:
++                # XXX: The order is important; signals and properties have
++                # higher precedence than types
++
++                # Signal sigil
++                new_line = re.sub(SIGNAL_SIGIL_RE, r"\g<1>`\g<2>::\g<3>`", new_line)
++
++                # Property sigil
++                new_line = re.sub(PROP_SIGIL_RE, r"\g<1>`\g<2>:\g<3>`", new_line)
 +
-             # Type sigil
-             new_line = re.sub(TYPE_SIGIL_RE, r"\g<1>`\g<2>`", new_line)
++                # Type sigil
++                new_line = re.sub(TYPE_SIGIL_RE, r"\g<1>`\g<2>`", new_line)
 +
-             # Constant sygil
-             new_line = re.sub(CONST_SIGIL_RE, r"\g<1>`\g<2>`", new_line)
++                # Constant sygil
++                new_line = re.sub(CONST_SIGIL_RE, r"\g<1>`\g<2>`", new_line)
 +
-             # Argument sygil
-             new_line = re.sub(ARG_SIGIL_RE, r"\g<1>`\g<2>`", new_line)
++                # Argument sygil
++                new_line = re.sub(ARG_SIGIL_RE, r"\g<1>`\g<2>`", new_line)
 +
++                # Function
++                new_line = re.sub(FUNCTION_RE, r"\g<1>`\g<2>()`\g<3>", new_line)
 +
 +            new_lines.append(new_line)
 +        return new_lines
 +
 +
 +class GtkDocExtension(Extension):
 +    """Markdown extension for gtk-doc"""
 +    def extendMarkdown(self, md):
 +        """Add extensions"""
 +        md.preprocessors.register(GtkDocPreprocessor(md), 'gtkdoc', 27)
index e353208ca27bbc19d00e453f9f2daa3fb827a63b,0000000000000000000000000000000000000000..963a73e1e2f10efde286bb1539a3c6950b863e4d
mode 100644,000000..100644
--- /dev/null
@@@ -1,93 -1,0 +1,93 @@@
-     {% block navbar %}
 +<!--
 +SPDX-FileCopyrightText: 2021 GNOME Foundation
 +
 +SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +-->
 +
 +<!DOCTYPE html>
 +<html lang="en">
 +<head>
 +  <title>{% block title %}{{ namespace.name }}{% endblock %}</title>
 +  <meta name="viewport" content="width=device-width, initial-scale=1">
 +
 +  <meta charset="utf-8" />
 +
 +  {% if CONFIG.site_url %}
 +  <meta property="og:url" content="{{ CONFIG.site_url }}"/>
 +  {% endif %}
 +  <meta property="og:type" content="website"/>
 +
 +  {% if CONFIG.logo_url %}
 +  <meta property="og:image:width" content="256"/>
 +  <meta property="og:image:height" content="256"/>
 +  <meta property="og:image:secure_url" content="{{ CONFIG.logo_url }}"/>
 +  <meta property="og:image:alt" content="{{ namespace.name }}-{{ namespace.version }}"/>
 +  {% endif %}
 +
 +  {% block meta_other %}{% endblock %}
 +
 +  {% if CONFIG.site_url %}
 +  <meta name="twitter:url" content="{{ CONFIG.site_url }}"/>
 +  {% endif %}
 +  <meta name="twitter:card" content="summary"/>
 +
 +  {% if CONFIG.site_url %}
 +  <link rel="canonical" href="{{ CONFIG.site_url }}"/>
 +  {% endif %}
 +
 +  <link rel="stylesheet" href="style.css" type="text/css" />
 +
 +  {% block style_other %}{% endblock %}
 +
 +  {% if CONFIG.urlmap_file %}
 +  <script src="{{ CONFIG.urlmap_file }}"></script>
 +  {% endif %}
 +  {% if CONFIG.search_index %}
 +  <script src="fzy.js"></script>
 +  <script src="search.js"></script>
 +  {% endif %}
 +  <script src="main.js"></script>
 +  <!--[if IE]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
 +</head>
 +
 +<body>
 +  <div id="body-wrapper" tabindex="-1">
 +
 +    <nav class="sidebar devhelp-hidden">
 +      {% if CONFIG.logo_url %}
 +      <div class="section">
 +        <img src="{{ CONFIG.logo_url }}" class="logo"/>
 +      </div>
 +      {% endif %}
 +      {% if CONFIG.search_index %}
 +      <div class="search section">
 +        <form id="search-form" autocomplete="off">
 +          <input id="search-input" type="text" name="do-not-autocomplete" placeholder="Click, or press 's' to search" autocomplete="off"/>
 +        </form>
 +      </div>
 +      {% endif %}
 +      <div class="section namespace">
 +        <h3><a href="index.html">{{ namespace.name }}</a></h3>
 +        <p>API Version: {{ namespace.version }}</p>
 +        {% if CONFIG.version %}
 +        <p>Library Version: {{ CONFIG.version }}</p>
 +        {% endif %}
 +      </div>
 +      {% block sidebar %}
 +      {% endblock %}
 +    </nav>
-     {% endblock %}
++    
 +    <button id="btn-to-top" class="hidden"><span class="up-arrow"></span></button>
 +
 +    {% block content %}{% endblock %}
 +
++    {% block navbar %}{% endblock %}
++
 +    <section id="search" class="content hidden"></section>
 +
 +    <footer>
 +    {% block footer %}{% endblock %}
 +    </footer>
 +  </div>
 +</body>
 +</html>
index 15b6a7fb69b1c0ae7bdb315ca33670badaaf32f4,0000000000000000000000000000000000000000..3274d0475544f772c951a04f530f8b8060a3cdc6
mode 100644,000000..100644
--- /dev/null
@@@ -1,75 -1,0 +1,76 @@@
-   "pygment.css",
 +# SPDX-FileCopyrightText: 2021 GNOME Foundation
 +#
 +# SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +
 +[metadata]
 +name = "Basic"
 +author_name = "Emmanuele Bassi"
 +author_email = "ebassi@gnome.org"
 +copyright_year = "2021"
 +license = "Apache-2.0 OR GPL-3.0-or-later"
 +
 +[templates]
 +class = "class.html"
 +interface = "interface.html"
 +content = "content.html"
 +property = "property.html"
 +signal = "signal.html"
 +vfunc = "vfunc.html"
 +method = "method.html"
 +type_func = "type_func.html"
 +class_method = "class_method.html"
 +namespace = "namespace.html"
 +error = "enum.html"
 +flags = "enum.html"
 +enum = "enum.html"
 +constant = "constant.html"
 +record = "struct.html"
 +union = "struct.html"
 +alias = "struct.html"
 +function = "function.html"
 +ctor = "ctor.html"
 +
 +[css]
 +style = "style.css"
 +
 +[extra_files]
 +files = [
 +  "fonts.css",
 +  "fzy.js",
 +  "go-up-symbolic.png",
 +  "main.js",
++  "solarized-light.css",
++  "solarized-dark.css",
 +  "search.js",
 +  "RedHatDisplay-Black.woff",
 +  "RedHatDisplay-Black.woff2",
 +  "RedHatDisplay-BlackItalic.woff",
 +  "RedHatDisplay-BlackItalic.woff2",
 +  "RedHatDisplay-Bold.woff",
 +  "RedHatDisplay-Bold.woff2",
 +  "RedHatDisplay-BoldItalic.woff",
 +  "RedHatDisplay-BoldItalic.woff2",
 +  "RedHatDisplay-Italic.woff",
 +  "RedHatDisplay-Italic.woff2",
 +  "RedHatDisplay-Medium.woff",
 +  "RedHatDisplay-Medium.woff2",
 +  "RedHatDisplay-MediumItalic.woff",
 +  "RedHatDisplay-MediumItalic.woff2",
 +  "RedHatDisplay-Regular.woff",
 +  "RedHatDisplay-Regular.woff2",
 +  "RedHatText-Bold.woff",
 +  "RedHatText-Bold.woff2",
 +  "RedHatText-BoldItalic.woff",
 +  "RedHatText-BoldItalic.woff2",
 +  "RedHatText-Italic.woff",
 +  "RedHatText-Italic.woff2",
 +  "RedHatText-Medium.woff",
 +  "RedHatText-Medium.woff2",
 +  "RedHatText-MediumItalic.woff",
 +  "RedHatText-MediumItalic.woff2",
 +  "RedHatText-Regular.woff",
 +  "RedHatText-Regular.woff2",
 +  "SourceCodePro-It.ttf.woff",
 +  "SourceCodePro-Regular.ttf.woff",
 +  "SourceCodePro-Semibold.ttf.woff",
 +]
index 591fa79a76f390df142e8c8a010e5d328354e596,0000000000000000000000000000000000000000..435f6e0fa9a87d909648dbed51abb91176bcaae2
mode 100644,000000..100644
--- /dev/null
@@@ -1,591 -1,0 +1,677 @@@
- {{ sidebar_block(class.type_funcs, class.name, "Functions", "func", "type_func") }}
 +<!--
 +SPDX-FileCopyrightText: 2021 GNOME Foundation
 +
 +SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +-->
 +
 +{% extends "base.html" %}
 +
 +{% block title %}{{ namespace.name }}.{{ class.name }}{% endblock %}
 +
 +{% block meta_other %}
 +  <meta property="og:title" content="{{ namespace.name }}.{{ class.name }}"/>
 +  <meta property="og:description" content="Reference for {{ namespace.name }}.{{ class.name }}"/>
 +  <meta name="twitter:title" content="{{ namespace.name }}.{{ class.name }}"/>
 +  <meta name="twitter:description" content="Reference for {{ namespace.name }}.{{ class.name }}"/>
 +{% endblock %}
 +
 +{% macro sidebar_block(elements, class_name, section_title, section_class, section_fragment) -%}
 +{% if elements|length > 0 %}
 +<div class="section">
 +  <h5>{{ section_title }}</h5>
 +  <div class="links">
 +  {% for m in elements %}
 +    <a class="{{ section_class }}" href="{{ section_fragment }}.{{ class_name }}.{{ m.name }}.html">{{ m.name }}</a>
 +  {% endfor %}
 +  </div>
 +</div>
 +{% endif %}
 +{% endmacro %}
 +
 +{% block sidebar %}
 +<div class="section">
 +  <h5>Type</h5>
 +  <div class="links">
 +    <a class="current" href="class.{{ class.name }}.html#description">{{ class.name }}</a>
 +  </div>
 +</div>
 +
 +{{ sidebar_block(class.ctors, class.name, "Constructors", "ctor", "ctor") }}
++{{ sidebar_block(class.type_funcs, class.name, "Functions", "func", "type_func") }}
 +{{ sidebar_block(class.methods, class.name, "Instance methods", "method", "method") }}
 +{{ sidebar_block(class.properties, class.name, "Properties", "property", "property") }}
 +{{ sidebar_block(class.signals, class.name, "Signals", "signal", "signal") }}
 +{{ sidebar_block(class.class_methods, class.name, "Class methods", "method", "class_method") }}
-           <li class="class">{{ ancestor.type_cname }}</a></li>
 +{{ sidebar_block(class.virtual_methods, class.name, "Virtual methods", "method", "vfunc") }}
 +{% endblock %}
 +
++{% macro navbar_block(elements, section_title, section_link) -%}
++{% if elements|length > 0 %}
++<li class="toc-list-item"><a href="{{ section_link }}"><span class="link-text">{{ section_title }}</span></a></li>
++{% endif %}
++{% endmacro %}
++
++{% block navbar %}
++<div id="toc" class="toc">
++  <nav aria-labelledby="toc-title">
++    <p id="toc-title">Content</p>
++    <ul class="toc-list">
++      <li class="toc-list-item"><a href="#description"><span class="link-text">Description</span></a></li>
++      {% if CONFIG.show_class_hierarchy and (class.ancestors or class.interfaces) %}
++      <li class="toc-list-item"><a href="#hierarchy"><span class="link-text">Hierarchy</span></a></li>
++      {% endif %}
++      {% if class.ancestors %}
++      <li class="toc-list-item"><a href="#ancestors"><span class="link-text">Ancestors</span></a></li>
++      {% endif %}
++      {% if class.interfaces %}
++      <li class="toc-list-item"><a href="#implements"><span class="link-text">Implements</span></a></li>
++      {% endif %}
++      {{ navbar_block(class.ctors, "Constructors", "#constructors") }}
++      {{ navbar_block(class.type_funcs, "Functions", "#type-functions") }}
++      {{ navbar_block(class.methods, "Methods", "#methods") }}
++      {{ navbar_block(class.properties, "Properties", "#properties") }}
++      {{ navbar_block(class.signals, "Signals", "#signals") }}
++      {{ navbar_block(class.class_methods, "Class methods", "#class-methods") }}
++      {{ navbar_block(class.virtual_methods, "Virtual methods", "#virtual-methods") }}
++    </ul>
++  </nav>
++</div>
++{% endblock %}
++
 +{% block content %}
 +<section id="main" class="content">
 +  <header>
 +    <h3>Class</h3>
 +    <h1 aria-label="Name"><a href="index.html">{{ namespace.name }}</a><span class="sep" role="presentation"></span>{{ class.name }}</h1>
 +  </header>
 +
 +  <section>
 +    <summary>
 +      <div class="toggle-wrapper">
 +        <h4 id="description" style="display:flex;">
 +          Description
 +          <a href="#description" class="anchor"></a>
 +          {% if CONFIG.source_location_url and class.docs_location %}
 +          <a class="srclink" title="go to source location" href="{{ CONFIG.source_link(class.docs_location) }}">[src]</a>
 +          {% endif %}
 +        </h4>
 +
 +        <pre><code>{{ class.c_decl }}</pre></code>
 +
 +        <div class="docblock">
 +          {{ class.description }}
 +        </div>
 +
 +        <div class="docblock">
 +          <table class="attributes">
 +            {% if class.stability %}
 +            <tr><td>Stability:</td><td>{{ class.stability }}</td></tr>
 +            {% endif %}
 +            {% if class.available_since %}
 +            <tr><td>Available since:</td><td>{{ class.available_since }}</td></tr>
 +            {% endif %}
 +            {% if class.deprecated_since %}
 +            <tr><td>Deprecated since:</td><td>{{ class.deprecated_since.version }}</td></tr>
 +            <tr><td colspan="2">{{ class.deprecated_since.message }}</td></tr>
 +            {% endif %}
 +          </table>
 +        </div>
 +
 +        {% if class.attributes %}
 +        <div class="docblock">
 +          <table class="attributes">
 +          {% for (key, value) in class.attributes.items() %}
 +            <tr><td>{{ key|escape }}</td><td>{{ value|escape }}</td></tr>
 +          {% endfor %}
 +          </table>
 +        </div>
 +        {% endif %}
 +      </div>
 +    </summary>
 +
 +    {% if CONFIG.show_class_hierarchy and (class.ancestors or class.interfaces) %}
 +    <div class="toggle-wrapper hierarchy">
 +      <h4 id="hierarchy">
 +        Hierarchy
 +        <a href="#hierarchy" class="anchor"></a>
 +      </h4>
 +      <div class="docblock" alt="Hierarchy for {{ class.fqtn }}">
 +        {{ class.hierarchy_svg|safe }}
 +      </div>
 +    </div>
 +    {% endif %}
 +
 +    {% if class.ancestors %}
 +    <div class="toggle-wrapper ancestors">
 +      <h4 id="ancestors">
 +        Ancestors
 +        <a href="#ancestors" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +        <ul>
 +        {% for ancestor in class.ancestors %}
 +          {% if ancestor.namespace == namespace.name %}
 +          <li class="class"><a href="class.{{ ancestor.name }}.html" title="{{ ancestor.name }}">{{ ancestor.type_cname }}</a></li>
 +          {% else %}
-           <li class="interface">{{ iface.type_cname }}</a></li>
++          <li class="class"><a class="external" href="javascript:void(0)" data-link="class.{{ ancestor.name }}.html" data-namespace="{{ ancestor.namespace }}">{{ ancestor.type_cname }}</a></li>
 +          {% endif %}
 +        {% endfor %}
 +        </ul>
 +      </div>
 +    </div>
 +    {% endif %}
 +
++    {% if class.descendants %}
++    <div class="descendants toggle-wrapper default-hide">
++      <h4 id="descendants">Descendants <a href="#descendants" class="anchor"></a></h4>
++      <div class="docblock">
++        <ul>
++        {%- for cls in class.descendants %}
++          <li class="class"><a href="class.{{ cls.name }}.html" title="{{ cls.name }}">{{ cls.ctype }}</a></li>
++        {% endfor -%}
++        </ul>
++      </div>
++    </div>
++    {% endif %}
++
 +    {% if class.interfaces %}
 +    <div class="toggle-wrapper implements">
 +      <h4 id="implements">
 +        Implements
 +        <a href="#implements" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +        <ul>
 +        {% for iface in class.interfaces %}
 +          {% if iface.namespace == namespace.name %}
 +          <li class="interface"><a href="iface.{{ iface.name }}.html" title="{{ iface.name }}">{{ iface.type_cname }}</a></li>
 +          {% else %}
-     {% if class.methods %}
++          <li class="interface"><a class="external" href="javascript:void(0)" data-link="iface.{{ iface.name }}.html" data-namespace="{{ iface.namespace }}">{{ iface.type_cname }}</a></li>
 +          {% endif %}
 +        {% endfor %}
 +        </ul>
 +      </div>
 +    </div>
 +    {% endif %}
 +
 +    {% if class.ctors %}
 +    <div class="toggle-wrapper constructors">
 +      <h4 id="constructors">
 +        Constructors
 +        <a href="#constructors" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +      {% for ctor in class.ctors %}
 +        <div class="{% if ctor.deprecated_since %}deprecated{% endif %}">
 +          <h6><a href="ctor.{{ class.name }}.{{ ctor.name }}.html">{{ ctor.identifier }}</a></h6>
 +
 +          <div class="docblock">
 +            {{ ctor.summary }}
 +          </div>
 +
 +          {% if ctor.available_since or ctor.deprecated_since -%}
 +          <div class="docblock">
 +          {%- if ctor.available_since -%}
 +          <p>Available since: {{ ctor.available_since }}</p>
 +          {%- endif -%}
 +          {%- if ctor.deprecated_since -%}
 +          <p>Deprecated since: {{ ctor.deprecated_since }}</p>
 +          {%- endif -%}
 +          </div>
 +          {%- endif %}
 +        </div>
 +      {% endfor %}
 +      </div>
 +    </div>
 +    {% endif %}
 +
-         {% if ancestor.namespace == namespace.name and ancestor.n_methods > 0 %}
++    {% if class.type_funcs %}
++    <div class="toggle-wrapper methods">
++      <h4 id="type-functions">
++        Functions
++        <a href="#type-functions" class="anchor"></a>
++      </h4>
++
++      <div class="docblock">
++      {% for func in class.type_funcs %}
++      <div class="{% if func.deprecated_since %}deprecated{% endif %}">
++        <h6><a href="type_func.{{ class.name }}.{{ func.name }}.html">{{ func.identifier }}</a></h6>
++
++        <div class="docblock">
++          {{ func.summary }}
++        </div>
++
++        {% if func.available_since or func.deprecated_since -%}
++        <div class="docblock">
++        {%- if func.available_since -%}
++        <p>Available since: {{ func.available_since }}</p>
++        {%- endif -%}
++        {%- if func.deprecated_since -%}
++        <p>Deprecated since: {{ func.deprecated_since }}</p>
++        {%- endif -%}
++        </div>
++        {%- endif %}
++      </div>
++      {% endfor %}
++      </div>
++    </div>
++    {% endif %}
++
++    {% if class.show_methods %}
 +    <div class="toggle-wrapper methods">
 +      <h4 id="methods">
 +        Instance methods
 +        <a href="#methods" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +      {% for method in class.methods %}
 +        <div class="{% if method.deprecated_since %}deprecated{% endif %}">
 +          <h6><a href="method.{{ class.name}}.{{ method.name }}.html">{{ method.identifier }}</a></h6>
 +          <div class="docblock">
 +            {{ method.summary }}
 +          </div>
 +          {% if method.available_since or method.deprecated_since -%}
 +          <div class="docblock">
 +          {%- if method.available_since -%}
 +          <p>Available since: {{ method.available_since }}</p>
 +          {%- endif -%}
 +          {%- if method.deprecated_since -%}
 +          <p>Deprecated since: {{ method.deprecated_since }}</p>
 +          {%- endif -%}
 +          </div>
 +          {%- endif %}
 +        </div>
 +      {% endfor %}
 +      </div>
 +
 +      {% for ancestor in class.ancestors %}
-           {% if ancestor.methods %}
++        {% if ancestor.n_methods > 0 %}
 +        <div class="{% if ancestor.methods %}toggle-wrapper default-hide{% endif %} ancestor-methods">
++          {%- if ancestor.namespace == namespace.name %}
 +          <h5 style="display:block;">Methods inherited from <a href="class.{{ ancestor.name }}.html">{{ ancestor.type_cname }}</a> ({{ ancestor.n_methods }})</h5>
++          {%- else -%}
++          <h5 style="display:block;">Methods inherited from <a class="external" href="javascript:void(0)" data-link="class.{{ ancestor.name }}.html" data-namespace="{{ ancestor.namespace }}">{{ ancestor.type_cname }}</a> ({{ ancestor.n_methods }})</h5>
++          {% endif -%}
 +
-           {% endif %}
 +          <div class="docblock">
 +          {% for method in ancestor.methods %}
++            {%- if ancestor.namespace == namespace.name %}
 +            <h6><a href="method.{{ ancestor.name }}.{{ method.name }}.html">{{ method.identifier }}</a></h6>
++            {%- else -%}
++            <h6><a class="external" href="javascript:void(0)" data-namespace="{{ ancestor.namespace }}" data-link="method.{{ ancestor.name }}.{{ method.name }}.html">{{ method.identifier }}</a></h6>
++            {% endif -%}
 +            <div class="docblock">
 +              {{ method.summary }}
 +            </div>
 +            {% if method.available_since or method.deprecated_since -%}
 +            <div class="docblock">
 +            {%- if method.available_since -%}
 +              <p>Available since: {{ method.available_since }}</p>
 +            {%- endif -%}
 +            {%- if method.deprecated_since -%}
 +              <p>Deprecated since: {{ method.deprecated_since }}</p>
 +            {%- endif -%}
 +            </div>
 +            {%- endif %}
 +          {% endfor %}
 +          </div>
-         {% if iface.namespace == namespace.name and iface.n_methods > 0 %}
 +        </div>
 +        {% endif %}
 +      {% endfor %}
 +
 +      {% for iface in class.interfaces %}
-           {% if iface.methods %}
++        {% if iface.n_methods > 0 %}
 +        <div class="{% if iface.methods %}toggle-wrapper default-hide{% endif %} ancestor-methods">
++          {%- if iface.namespace == namespace.name %}
 +          <h5 style="display:block;">Methods inherited from <a href="iface.{{ iface.name }}.html">{{ iface.type_cname }}</a> ({{ iface.n_methods }})</h5>
++          {%- else -%}
++          <h5 style="display:block;">Methods inherited from <a class="external" href="javascript:void(0)" data-link="iface.{{ iface.name }}.html" data-namespace="{{ iface.namespace }}">{{ iface.type_cname }}</a> ({{ iface.n_methods }})</h5>
++          {% endif -%}
 +
-           {% endif %}
 +          <div class="docblock">
 +          {% for method in iface.methods %}
++            {%- if iface.namespace == namespace.name %}
 +            <h6><a href="method.{{ iface.name }}.{{ method.name }}.html">{{ method.identifier }}</a></h6>
++            {%- else -%}
++            <h6><a class="external" href="javascript:void(0)" data-namespace="{{ iface.namespace }}" data-link="method.{{ iface.name }}.{{ method.name }}.html">{{ method.identifier }}</a></h6>
++            {% endif -%}
 +            <div class="docblock">
 +              {{ method.summary }}
 +            </div>
 +            {% if method.available_since or method.deprecated_since -%}
 +            <div class="docblock">
 +            {%- if method.available_since -%}
 +              <p>Available since: {{ method.available_since }}</p>
 +            {%- endif -%}
 +            {%- if method.deprecated_since -%}
 +              <p>Deprecated since: {{ method.deprecated_since }}</p>
 +            {%- endif -%}
 +            </div>
 +            {%- endif %}
 +          {% endfor %}
 +          </div>
-     {% if class.properties %}
 +        </div>
 +        {% endif %}
 +      {% endfor %}
 +    </div>
 +    {% endif %}
 +
-         {% if ancestor.namespace == namespace.name and ancestor.n_properties > 0 %}
++    {% if class.show_properties %}
 +    <div class="toggle-wrapper properties">
 +      <h4 id="properties">
 +        Properties
 +        <a href="#properties" class="anchor"></a>
 +      </h4>
 +
++      {% if class.properties %}
 +      <div class="docblock">
 +      {% for property in class.properties %}
 +        <div class="{% if property.deprecated_since %}deprecated{% endif %}">
 +          <h6><a href="property.{{ class.name }}.{{ property.name }}.html">{{ class.fqtn }}:{{ property.name }}</a></h6>
 +
 +          <div class="docblock">
 +            {{ property.summary }}
 +          </div>
 +
 +          {% if property.available_since or property.deprecated_since -%}
 +          <div class="docblock">
 +          {%- if property.available_since -%}
 +          <p>Available since: {{ property.available_since }}</p>
 +          {%- endif -%}
 +          {%- if property.deprecated_since -%}
 +          <p>Deprecated since: {{ property.deprecated_since }}</p>
 +          {%- endif -%}
 +          </div>
 +          {%- endif %}
 +        </div>
 +      {% endfor %}
 +      </div>
++      {% endif %}
 +
 +      {% for ancestor in class.ancestors %}
-           {% if ancestor.properties %}
++        {% if ancestor.n_properties > 0 %}
 +        <div class="{% if ancestor.properties %}toggle-wrapper default-hide{% endif %} ancestor-properties">
++          {%- if ancestor.namespace == namespace.name %}
 +          <h5 style="display:block;">Properties inherited from <a href="class.{{ ancestor.name }}.html">{{ ancestor.type_cname }}</a> ({{ ancestor.n_properties }})</h5>
++          {%- else -%}
++          <h5 style="display:block;">Properties inherited from <a class="external" href="javascript:void(0)" data-link="class.{{ ancestor.name }}.html" data-namespace="{{ ancestor.namespace }}">{{ ancestor.type_cname }}</a> ({{ ancestor.n_properties }})</h5>
++          {% endif -%}
 +
-           {% endif %}
 +          <div class="docblock">
 +          {% for property in ancestor.properties %}
++            {%- if ancestor.namespace == namespace.name %}
 +            <h6><a href="property.{{ ancestor.name }}.{{ property.name }}.html">{{ ancestor.fqtn }}:{{ property.name }}</a></h6>
++            {%- else -%}
++            <h6><a class="external" href="javascript:void(0)" data-namespace="{{ ancestor.namespace }}" data-link="property.{{ ancestor.name }}.{{ property.name }}.html">{{ ancestor.fqtn }}:{{ property.name }}</a></h6>
++            {% endif -%}
 +            <div class="docblock">
 +              {{ property.summary }}
 +            </div>
 +            {% if property.available_since or property.deprecated_since -%}
 +            <div class="docblock">
 +            {%- if property.available_since -%}
 +              <p>Available since: {{ property.available_since }}</p>
 +            {%- endif -%}
 +            {%- if property.deprecated_since -%}
 +              <p>Deprecated since: {{ property.deprecated_since }}</p>
 +            {%- endif -%}
 +            </div>
 +            {%- endif %}
 +          {% endfor %}
 +          </div>
-         {% if iface.namespace == namespace.name and iface.n_properties > 0 %}
 +        </div>
 +        {% endif %}
 +      {% endfor %}
 +
 +      {% for iface in class.interfaces %}
-           {% if iface.properties %}
++        {% if iface.n_properties > 0 %}
 +        <div class="{% if iface.properties %}toggle-wrapper default-hide{% endif %} ancestor-properties">
++          {%- if iface.namespace == namespace.name %}
 +          <h5 style="display:block;">Properties inherited from <a href="iface.{{ iface.name }}.html">{{ iface.type_cname }}</a> ({{ iface.n_properties }})</h5>
++          {%- else -%}
++          <h5 style="display:block;">Properties inherited from <a class="external" href="javascript:void(0)" data-link="iface.{{ iface.name }}.html" data-namespace="{{ iface.namespace }}">{{ iface.type_cname }}</a> ({{ iface.n_properties }})</h5>
++          {% endif -%}
 +
-           {% endif %}
 +          <div class="docblock">
 +          {% for property in iface.properties %}
++            {%- if iface.namespace == namespace.name %}
 +            <h6><a href="property.{{ iface.name }}.{{ property.name }}.html">{{ iface.fqtn }}:{{ property.name }}</a></h6>
++            {%- else -%}
++            <h6><a class="external" href="javascript:void(0)" data-namespace="{{ iface.namespace }}" data-link="property.{{ iface.name }}.{{ property.name }}.html">{{ iface.fqtn }}:{{ property.name }}</a></h6>
++            {% endif -%}
 +            <div class="docblock">
 +              {{ property.summary }}
 +            </div>
 +            {% if property.available_since or property.deprecated_since -%}
 +            <div class="docblock">
 +            {%- if property.available_since -%}
 +              <p>Available since: {{ property.available_since }}</p>
 +            {%- endif -%}
 +            {%- if property.deprecated_since -%}
 +              <p>Deprecated since: {{ property.deprecated_since }}</p>
 +            {%- endif -%}
 +            </div>
 +            {%- endif %}
 +          {% endfor %}
 +          </div>
-     {% if class.signals %}
 +        </div>
 +        {% endif %}
 +      {% endfor %}
 +
 +    </div>
 +    {% endif %}
 +
-         {% if ancestor.namespace == namespace.name and ancestor.n_signals > 0 %}
++    {% if class.show_signals %}
 +    <div class="signals toggle-wrapper">
 +      <h4 id="signals">
 +        Signals
 +        <a href="#signals" class="anchor"></a>
 +      </h4>
 +
++      {% if class.signals %}
 +      <div class="docblock">
 +      {% for signal in class.signals %}
 +        <div class="{% if signal.deprecated_since %}deprecated{% endif %}">
 +          <h6><a href="signal.{{ class.name }}.{{ signal.name }}.html">{{ class.fqtn }}::{{ signal.name }}</a></h6>
 +          <div class="docblock">
 +            {{ signal.summary }}
 +          </div>
 +          {% if signal.available_since or signal.deprecated_since -%}
 +          <div class="docblock">
 +          {%- if signal.available_since -%}
 +          <p>Available since: {{ signal.available_since }}</p>
 +          {%- endif -%}
 +          {%- if signal.deprecated_since -%}
 +          <p>Deprecated since: {{ signal.deprecated_since }}</p>
 +          {%- endif -%}
 +          </div>
 +          {%- endif %}
 +        </div>
 +      {% endfor %}
 +      </div>
++      {% endif %}
 +
 +      {% for ancestor in class.ancestors %}
-           {% if ancestor.signals %}
++        {% if ancestor.n_signals > 0 %}
 +        <div class="{% if ancestor.signals %}toggle-wrapper default-hide{% endif %} ancestor-signals">
++          {%- if ancestor.namespace == namespace.name %}
 +          <h5 style="display:block;">Signals inherited from <a href="class.{{ ancestor.name }}.html">{{ ancestor.type_cname }}</a> ({{ ancestor.n_signals }})</h5>
++          {%- else -%}
++          <h5 style="display:block;">Signals inherited from <a class="external" href="javascript:void(0)" data-link="class.{{ ancestor.name }}.html" data-namespace="{{ ancestor.namespace }}">{{ ancestor.type_cname }}</a> ({{ ancestor.n_signals }})</h5>
++          {% endif -%}
 +
-           {% endif %}
 +          <div class="docblock">
 +          {% for signal in ancestor.signals %}
++            {%- if ancestor.namespace == namespace.name %}
 +            <h6><a href="signal.{{ ancestor.name }}.{{ signal.name }}.html">{{ ancestor.fqtn }}::{{ signal.name }}</a></h6>
++            {%- else -%}
++            <h6><a class="external" href="javascript:void(0)" data-namespace="{{ ancestor.namespace }}" data-link="signal.{{ ancestor.name }}.{{ signal.name }}.html">{{ ancestor.fqtn }}::{{ signal.name }}</a></h6>
++            {% endif -%}
 +            <div class="docblock">
 +              {{ signal.summary }}
 +            </div>
 +            {% if signal.available_since or signal.deprecated_since -%}
 +            <div class="docblock">
 +            {%- if signal.available_since -%}
 +              <p>Available since: {{ signal.available_since }}</p>
 +            {%- endif -%}
 +            {%- if signal.deprecated_since -%}
 +              <p>Deprecated since: {{ signal.deprecated_since }}</p>
 +            {%- endif -%}
 +            </div>
 +            {%- endif %}
 +          {% endfor %}
 +          </div>
-         {% if iface.namespace == namespace.name and iface.n_signals %}
 +        </div>
 +        {% endif %}
 +      {% endfor %}
 +
 +      {% for iface in class.interfaces %}
-           {% if iface.signals %}
++        {% if iface.n_signals %}
 +        <div class="{% if iface.signals %}toggle-wrapper default-hide{% endif %} ancestor-signals">
++          {%- if iface.namespace == namespace.name %}
 +          <h5 style="display:block;">Signals inherited from <a href="iface.{{ iface.name }}.html">{{ iface.type_cname }}</a> ({{ iface.n_signals }})</h5>
++          {%- else -%}
++          <h5 style="display:block;">Signals inherited from <a class="external" href="javascript:void(0)" data-link="iface.{{ iface.name }}.html" data-namespace="{{ iface.namespace }}">{{ iface.type_cname }}</a> ({{ iface.n_signals }})</h5>
++          {% endif -%}
 +
-           {% endif %}
 +          <div class="docblock">
 +          {% for signal in iface.signals %}
++            {%- if iface.namespace == namespace.name %}
 +            <h6><a href="signal.{{ iface.name }}.{{ signal.name }}.html">{{ iface.fqtn }}::{{ signal.name }}</a></h6>
++            {%- else -%}
++            <h6><a class="external" href="javascript:void(0)" data-namespace="{{ iface.namespace }}" data-link="signal.{{ iface.name }}.{{ signal.name }}.html">{{ iface.fqtn }}::{{ signal.name }}</a></h6>
++            {% endif -%}
 +            <div class="docblock">
 +              {{ signal.summary }}
 +            </div>
 +            {% if signal.available_since or signal.deprecated_since -%}
 +            <div class="docblock">
 +            {%- if signal.available_since -%}
 +              <p>Available since: {{ signal.available_since }}</p>
 +            {%- endif -%}
 +            {%- if signal.deprecated_since -%}
 +              <p>Deprecated since: {{ signal.deprecated_since }}</p>
 +            {%- endif -%}
 +            </div>
 +            {%- endif %}
 +          {% endfor %}
 +          </div>
-     {% if class.type_funcs %}
-     <div class="toggle-wrapper methods">
-       <h4 id="type-functions">
-         Functions
-         <a href="#type-functions" class="anchor"></a>
-       </h4>
-       <div class="docblock">
-       {% for func in class.type_funcs %}
-       <div class="{% if func.deprecated_since %}deprecated{% endif %}">
-         <h6><a href="type_func.{{ class.name }}.{{ func.name }}.html">{{ func.identifier }}</a></h6>
-         <div class="docblock">
-           {{ func.summary }}
-         </div>
-         {% if func.available_since or func.deprecated_since -%}
-         <div class="docblock">
-         {%- if func.available_since -%}
-         <p>Available since: {{ func.available_since }}</p>
-         {%- endif -%}
-         {%- if func.deprecated_since -%}
-         <p>Deprecated since: {{ func.deprecated_since }}</p>
-         {%- endif -%}
-         </div>
-         {%- endif %}
-       </div>
-       {% endfor %}
-       </div>
-     </div>
-     {% endif %}
 +        </div>
 +        {% endif %}
 +      {% endfor %}
 +
 +    </div>
 +    {% endif %}
 +
 +    {% if class.class_name %}
 +    <div class="class toggle-wrapper default-hide">
 +      <h4 id="class-struct">
 +        Class structure
 +        <a href="#class-struct" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +        <pre><code>struct {{ namespace.name}}{{ class.class_name }} {
 +  {% for field in class.class_fields %}
 +  {%- if field.is_callback -%}
 +  {{ field.type_cname }};
 +  {%- else -%}
 +  {{ field.type_cname }} {{ field.name }};
 +  {%- endif %}
 +  {% else %}/* no available fields */{% endfor %}
 +}</code></pre>
 +      </div>
 +
 +      {% if class.class_fields %}
 +      <div class="docblock">
 +        <h6>Class members</h6>
 +
 +        <table class="members">
 +        {% for field in class.class_fields %}
 +        <tr>
 +          <td style="vertical-align:top"><code>{{ field.name }}</code></td>
 +          <td style="vertical-align:top"><pre><code>{{ field.type_cname }}</code></pre></td>
 +        </tr>
 +        <tr>
 +          <td>&nbsp;</td>
 +          <td style="vertical-align:top">{{ field.description }}</td>
 +        </td>
 +        {% endfor %}
 +        </table>
 +      </div>
 +      {% endif %}
 +    </div>
 +    {% endif %}
 +
 +    {% if class.virtual_methods %}
 +    <div class="toggle-wrapper methods">
 +      <h4 id="virtual-methods">
 +        Virtual methods
 +        <a href="#virtual-methods" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +      {% for method in class.virtual_methods %}
 +      <div class="{% if method.deprecated_since %}deprecated{% endif %}">
 +        <h6 id="vfunc-{{ method.name }}"><a href="vfunc.{{ class.name }}.{{ method.name }}.html">{{ namespace.name }}.{{ class.class_name }}.{{ method.name }}</a></h6>
 +
 +        <div class="docblock">
 +          {{ method.summary }}
 +        </div>
 +
 +          {% if method.available_since or method.deprecated_since -%}
 +          <div class="docblock">
 +          {%- if method.available_since -%}
 +          <p>Available since: {{ method.available_since }}</p>
 +          {%- endif -%}
 +          {%- if method.deprecated_since -%}
 +          <p>Deprecated since: {{ method.deprecated_since }}</p>
 +          {%- endif -%}
 +          </div>
 +          {%- endif %}
 +      </div>
 +      {% endfor %}
 +      </div>
 +    </div>
 +    {% endif %}
 +
 +    {% if class.class_methods %}
 +    <div class="toggle-wrapper methods">
 +      <h4 id="class-methods">
 +        Class methods
 +        <a href="#class-methods" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +      {% for method in class.class_methods %}
 +      <div class="{% if method.deprecated_since %}deprecated{% endif %}">
 +        <h6><a href="class_method.{{ class.name }}.{{ method.name }}.html">{{ method.identifier }}</a></h6>
 +
 +        <div class="docblock">
 +          {{ method.summary }}
 +        </div>
 +
 +        {% if method.available_since or method.deprecated_since -%}
 +        <div class="docblock">
 +        {%- if method.available_since -%}
 +        <p>Available since: {{ method.available_since }}</p>
 +        {%- endif -%}
 +        {%- if method.deprecated_since -%}
 +        <p>Deprecated since: {{ method.deprecated_since }}</p>
 +        {%- endif -%}
 +        </div>
 +        {%- endif %}
 +      </div>
 +      {% endfor %}
 +      </div>
 +    </div>
 +    {% endif %} 
 +
 +  </section>
 +</section>
 +{% endblock %}
index a26e93f72c91b8d0fba08a0f714a4cde2ccbddc9,0000000000000000000000000000000000000000..51d11483ade47401c4eeadeda06793731d9110bc
mode 100644,000000..100644
--- /dev/null
@@@ -1,182 -1,0 +1,183 @@@
-     {% if class_method.arguments|length > 1 %}
 +<!--
 +SPDX-FileCopyrightText: 2021 GNOME Foundation
 +
 +SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +-->
 +
 +{% extends "base.html" %}
 +
 +{% block title %}{{ namespace.name }}.{{ class.class_name }}.{{ class_method.name }}{% endblock %}
 +
 +{% block meta_other %}
 +<meta name="og:title" content="{{ namespace.name }}.{{ class.class_name }}.{{ class_method.name }}"/>
 +<meta name="og:description" content="Reference for {{ namespace.name }}.{{ class.class_name }}.{{ class_method.name }}"/>
 +{% endblock %}
 +
 +{% block sidebar %}
 +<div class="section">
 +  <h5>Type</h5>
 +  <div class="links">
 +    <a href="{{ class.link_prefix }}.{{ class.name }}.html">{{ class.name }}</a>
 +  </div>
 +</div>
 +<div class="section">
 +  <h5>Class methods</h5>
 +  <div class="links">
 +  {% for m in class.class_methods %}
 +    <a class="method{% if class_method.name == m.name %} current{% endif %}" href="class_method.{{ class.name }}.{{ m.name }}.html">{{ m.name }}</a>
 +  {% endfor %}
 +  </div>
 +</div>
 +{% endblock %}
 +
 +{% block content %}
 +<section id="main" class="content">
 +  <header>
 +    <h3>Class method</h3>
 +    <h1><a href="index.html">{{ namespace.name }}</a><span class="sep"></span><a href="{{ class.link_prefix }}.{{ class.name }}.html">{{ class.class_name }}</a><span class="sep"></span>{{ class_method.name }}</h1>
 +  </header>
 +
 +  <section>
 +    <div class="declaration">
 +      <h4 id="declaration" style="display:flex;">
 +        Declaration
 +        <a href="#declaration" class="anchor"></a>
 +        {% if CONFIG.source_location_url and class_method.source_location %}
 +        <a class="srclink" title="go to source location" href="{{ CONFIG.source_link(class_method.source_location) }}">[src]</a>
 +        {% endif %}
 +      </h4>
 +
 +      <div>
 +        <pre><code>{{ class_method.c_decl }}</code></pre>
 +      </div>
 +    </div>
 +
 +    <div class="description toggle-wrapper">
 +      <h4 id="description" style="display:flex;">
 +        Description
 +        <a href="#description" class="anchor"></a>
 +        {% if CONFIG.source_location_url and class_method.docs_location %}
 +        <a class="srclink" title="go to source location" href="{{ CONFIG.source_link(class_method.docs_location) }}">[src]</a>
 +        {% endif %}
 +      </h4>
 +
 +      <div class="docblock">
 +        {{ class_method.description }}
 +      </div>
 +
 +      <div class="docblock">
 +        <table>
 +          {% if class_method.stability %}
 +          <tr><td>Stability:</td><td>{{ class_method.stability }}</td></tr>
 +          {% endif %}
 +          {% if class_method.available_since %}
 +          <tr><td>Available since:</td><td>{{ class_method.available_since }}</td></tr>
 +          {% endif %}
 +          {% if class_method.deprecated_since %}
 +          <tr><td>Deprecated since:</td><td>{{ class_method.deprecated_since.version }}</td></tr>
 +          <tr><td colspan="2">{{ class_method.deprecated_since.message }}</td></tr>
 +          {% endif %}
 +        </table>
 +      </div>
 +
 +      {% if class_method.attributes %}
 +      <div class="docblock">
 +        <table>
 +        {% for (key, value) in class_method.attributes.items() %}
 +          <tr><td>{{ key|escape }}</td><td>{{ value|escape }}</td></tr>
 +        {% endfor %}
 +        </table>
 +      </div>
 +      {% endif %}
 +    </div>
 +
++    {% if class_method.arguments|length != 0 %}
 +    <div class="parameters toggle-wrapper">
 +      <h4 id="parameters">
 +        Parameters
 +        <a href="#parameters" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +        <table class="arguments">
 +          {% for arg in class_method.arguments %}
 +          <tr class="arg-name">
 +            <td><code>{{ arg.name }}</code></td>
 +            <td>
 +            {%- if arg.is_array -%}An array of&nbsp;{%- endif -%}
 +            {%- if arg.is_list -%}A list of&nbsp;{%- endif -%}
 +            {%- if arg.link -%}
 +            {{ arg.link|safe }}
 +            {%- else -%}
 +            <code>{{ arg.type_cname }}</code>
 +            {%- endif -%}
 +            </td>
 +          </tr>
 +          <tr class="arg-description">
 +            <td>&nbsp;</td>
 +            <td>{{ arg.description|safe }}</td>
 +          </tr>
 +          {% if arg.direction != "in" %}<tr><td>&nbsp;</td><td title="direction: {{ arg.direction}}">{{ arg.direction_note }}</td></tr>{% endif %}
 +          {% if arg.direction == "in" and arg.is_pointer and arg.nullable %}<tr><td>&nbsp;</td><td>The argument can be <code>NULL</code>.</td></tr>{% endif %}
 +          {% if arg.direction == "out" and arg.is_pointer and arg.nullable %}<tr><td>&nbsp;</td><td>The argument can be set to <code>NULL</code>.</td></tr>{% endif %}
 +          {% if arg.optional %}<tr><td>&nbsp;</td><td>The argument can be <code>NULL</code>.</td></tr>{% endif %}
 +          {% if arg.is_array and arg.zero_terminated %}<tr><td>&nbsp;</td><td>The array must be <code>NULL</code>-terminated.</td></tr>{% endif %}
 +          {% if arg.is_array and arg.fixed_size > 0 %}<tr><td>&nbsp;</td><td>The array must have {{ arg.fixed_size }} elements.</td></tr>{% endif %}
 +          {% if arg.is_array and arg.len_arg %}<tr><td>&nbsp;</td><td>The length of the array is specified in the <code>{{ arg.len_arg }}</code> argument.</td></tr>{% endif %}
 +          {% if arg.is_pointer %}<tr><td>&nbsp;</td><td title="transfer: {{ arg.transfer }}">{{ arg.transfer_note }}</td></tr>{% endif %}
 +          {% if arg.string_note %}<tr><td>&nbsp;</td><td>{{ arg.string_note }}</td></tr>{% endif %}
 +          {% endfor %}
 +          {% if class_method.throws %}
 +          <tr class="arg-name">
 +            <td><code>error</code></td>
 +            <td><code>GError **</code></td>
 +          </tr>
 +          <tr class="arg-description">
 +            <td>&nbsp;</td>
 +            <td>The return location for a <code>GError*</code>, or <code>NULL</code>.</td>
 +          </tr>
 +          {% endif %}
 +        </table>
 +      </div>
 +    </div>
 +    {% endif %}
 +
 +    {% if class_method.return_value %}
 +    <div class="return-value toggle-wrapper">
 +      <h4 id="return-value">
 +        Return value
 +        <a href="#return-value" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +        <table class="returns">
 +          <tr class="arg-name">
 +            <td>Returns:</td>
 +            <td>
 +            {%- if class_method.return_value.is_array -%}An array of&nbsp;{%- endif -%}
 +            {%- if class_method.return_value.is_list -%}A list of&nbsp;{%- endif -%}
++            {%- if class_method.return_value.is_list_model -%}A list model of&nbsp;{%- endif -%}
 +            {%- if class_method.return_value.link -%}
 +            {{ class_method.return_value.link|safe }}
 +            {%- else -%}
 +            <code>{{ class_method.return_value.type_cname }}</code>
 +            {%- endif -%}
 +            </td>
 +          </tr>
 +          <tr class="arg-description">
 +            <td>&nbsp;</td>
 +            <td>{{ class_method.return_value.description|safe }}</td>
 +          </tr>
 +          {% if class_method.return_value.is_array and class_method.return_value.zero_terminated %}<tr><td>&nbsp;</td><td>The array is <code>NULL</code>-terminated.</td></tr>{% endif %}
 +          {% if class_method.return_value.is_array and class_method.return_value.fixed_size > 0 %}<tr><td>&nbsp;</td><td>The array has {{ class_method.return_value.fixed_size }} elements.</td></tr>{% endif %}
 +          {% if class_method.return_value.is_array and class_method.return_value.len_arg %}<tr><td>&nbsp;</td><td>The length of the array is in the <code>{{ class_method.return_value.len_arg }}</code> argument.</td></tr>{% endif %}
 +          {% if class_method.return_value.is_pointer %}<tr><td>&nbsp;</td><td title="transfer: {{ class_method.return_value.transfer }}">{{ class_method.return_value.transfer_note }}</td></tr>{% endif %}
 +          {% if class_method.return_value.is_pointer and class_method.return_value.nullable %}<tr><td>&nbsp;</td><td>The return value can be <code>NULL</code>.</td></tr>{% endif %}
 +          {% if class_method.return_value.string_note %}<tr><td>&nbsp;</td><td>{{ class_method.return_value.string_note }}</td></tr>{% endif %}
 +        </table>
 +      </div>
 +    </div>
 +    {% endif %}
 +  </section>
 +</section>
 +{% endblock %}
index 081dece27bf5932dd2d2242bd7f7275230ba2027,0000000000000000000000000000000000000000..b92b6f14c94bb7e6c28de44b4c57de6f1326af7a
mode 100644,000000..100644
--- /dev/null
@@@ -1,171 -1,0 +1,189 @@@
 +<!--
 +SPDX-FileCopyrightText: 2021 GNOME Foundation
 +
 +SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +-->
 +
 +{% extends "base.html" %}
 +
 +{% block title %}{{ namespace.name }}.{{ enum.name }}{% endblock %}
 +
 +{% block meta_other %}
 +  <meta property="og:title" content="{{ namespace.name }}.{{ enum.name }}"/>
 +  <meta property="og:description" content="Reference for {{ namespace.name }}.{{ enum.name }}"/>
 +  <meta name="twitter:title" content="{{ namespace.name }}.{{ enum.name }}"/>
 +  <meta name="twitter:description" content="Reference for {{ namespace.name }}.{{ enum.name }}"/>
 +{% endblock %}
 +
 +{% macro sidebar_block(elements, enum_name, section_title, section_class, section_fragment) -%}
 +{% if elements|length > 0 %}
 +<div class="section">
 +  <h5>{{ section_title }}</h5>
 +  <div class="links">
 +  {% for m in elements %}
 +    <a class="{{ section_class }}" href="{{ section_fragment }}.{{ enum_name }}.{{ m.name }}.html">{{ m.name }}</a>
 +  {% endfor %}
 +  </div>
 +</div>
 +{% endif %}
 +{% endmacro %}
 +
 +{% block sidebar %}
 +<div class="section">
 +  <h5>Type</h5>
 +  <div class="links">
 +    <a class="current" href="{{ enum.link_prefix }}.{{ enum.name }}.html">{{ enum.name }}</a>
 +  </div>
 +</div>
 +
 +{{ sidebar_block(enum.type_funcs, enum.name, "Type functions", "func", "type_func") }}
 +{% endblock %}
 +
++{% macro navbar_block(elements, section_title, section_link) -%}
++{% if elements|length > 0 %}
++<li class="toc-list-item"><a href="{{ section_link }}"><span class="link-text">{{ section_title }}</span></a></li>
++{% endif %}
++{% endmacro %}
++
++{% block navbar %}
++<div id="toc" class="toc">
++  <nav aria-labelledby="toc-title">
++    <p id="toc-title">Content</p>
++    <ul class="toc-list">
++      <li class="toc-list-item"><a href="#description"><span class="link-text">Description</span></a></li>
++      {{ navbar_block(enum.type_funcs, "Functions", "#type-functions") }}
++    </ul>
++  </nav>
++</div>
++{% endblock %}
++
 +{% block content %}
 +<section id="main" class="content">
 +  <header>
 +    <h3>Enumeration</h3>
 +    <h1><a href="index.html">{{ namespace.name }}</a><span class="sep"></span>{{ enum.name }}</h1>
 +  </header>
 +
 +  <section>
 +    <div class="declaration toggle-wrapper">
 +      <h4 style="display:flex;" id="declaration">
 +        Declaration
 +        <a href="#declaration" class="anchor"></a>
 +        {% if CONFIG.source_location_url and enum.source_location %}
 +        <a class="srclink" title="go to source location" href="{{ CONFIG.source_link(enum.source_location) }}">[src]</a>
 +        {% endif %}
 +      </h4>
 +
 +      <div class="docblock">
 +        <pre><code>{{ enum.c_decl }}</code></pre>
 +      </div>
 +    </div>
 +
 +    <div class="description toggle-wrapper">
 +      <h4 style="display:flex;" id="description">
 +        Description
 +        <a href="#description" class="anchor"></a>
 +        {% if CONFIG.source_location_url and enum.docs_location %}
 +        <a class="srclink" title="go to source location" href="{{ CONFIG.source_link(enum.docs_location) }}">[src]</a>
 +        {% endif %}
 +      </h4>
 +
 +      <div class="docblock">
 +      {{ enum.description }}
 +      </div>
 +
 +      <div class="docblock">
 +        <table class="attributes">
 +          {% if enum.stability %}
 +          <tr><td>Stability:</td><td>{{ enum.stability }}</td></tr>
 +          {% endif %}
 +          {% if enum.available_since %}
 +          <tr><td>Available since:</td><td>{{ enum.available_since }}</td></tr>
 +          {% endif %}
 +          {% if enum.deprecated_since %}
 +          <tr><td>Deprecated since:</td><td>{{ enum.deprecated_since.version }}</td></tr>
 +          <tr><td colspan="2">{{ enum.deprecated_since.message }}</td></tr>
 +          {% endif %}
 +        </table>
 +      </div>
 +
 +      {% if enum.attributes %}
 +      <div class="docblock">
 +        <table class="attributes">
 +        {% for (key, value) in enum.attributes.items() %}
 +          <tr><td>{{ key|escape }}</td><td>{{ value|escape }}</td></tr>
 +        {% endfor %}
 +        </table>
 +      </div>
 +      {% endif %}
 +    </div>
 +
 +    <div class="members toggle-wrapper">
 +      <h4 id="members">
 +        Members
 +        <a href="#members" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +      <table class="enum-members">
 +        <tr>
 +          <th>Name</th>
 +          <th>Description</th>
 +        </tr>
 +      {% for member in enum.members %}
 +        <tr>
 +          <td><code title="Value: {{ member.value }}">{{ member.name }}</code></td>
 +          <td>{{ member.description }}</td>
 +        </tr>
 +      {% endfor %}
 +      </table>
 +      </div>
 +    </div>
 +
 +    {% if enum.error_domain %}
 +    <div class="error-domain toggle-wrapper">
 +      <h4 id="error-domain">
 +        Error domain
 +        <a href="#error-domain" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +        <pre><code>&quot;{{ enum.domain }}&quot;</code></pre>
 +      </div>
 +    </div>
 +    {% endif %}
 +
 +    {% if enum.type_funcs %}
 +    <div class="type-funcs toggle-wrapper">
 +      <h4 id="type-functions">
 +        Type functions
 +        <a href="#type-functions" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +      {% for func in enum.type_funcs %}
 +        <div class="{% if func.deprecated_since %}deprecated{% endif %}">
 +          <h6><a href="type_func.{{ enum.name }}.{{ func.name }}.html">{{ func.identifier }}</a></h6>
 +
 +          <div class="docblock">
 +            {{ func.summary }}
 +          </div>
 +
 +          {% if func.available_since or func.deprecated_since -%}
 +          <div class="docblock">
 +          {%- if func.available_since -%}
 +          <p>Available since: {{ func.available_since }}</p>
 +          {%- endif -%}
 +          {%- if func.deprecated_since -%}
 +          <p>Deprecated since: {{ func.deprecated_since }}</p>
 +          {%- endif -%}
 +          </div>
 +          {%- endif %}
 +        </div>
 +      {% endfor %}
 +    </div>
 +    {% endif %}
 +
 +  </section>
 +</section>
 +{% endblock %}
index 5b19b7442593f8e2b190dedb4d25aed4ef8ab6f7,0000000000000000000000000000000000000000..4f8ffcf5b539eb76cea57f8cc54129d2094b2884
mode 100644,000000..100644
--- /dev/null
@@@ -1,189 -1,0 +1,190 @@@
-   {% for f in namespace.function_macross %}
 +<!--
 +SPDX-FileCopyrightText: 2021 GNOME Foundation
 +
 +SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +-->
 +
 +{% extends "base.html" %}
 +
 +{% block title %}{{ namespace.name }}.{{ func.name }}{% endblock %}
 +
 +{% block meta_other %}
 +  <meta property="og:title" content="{{ namespace.name }}.{{ func.name }}"/>
 +  <meta property="og:description" content="Reference for {{ namespace.name }}.{{ func.name }}"/>
 +  <meta name="twitter:title" content="{{ namespace.name }}.{{ func.name }}"/>
 +  <meta name="twitter:description" content="Reference for {{ namespace.name }}.{{ func.name }}"/>
 +{% endblock %}
 +
 +{% block sidebar %}
 +{% if func.is_macro %}
 +<div class="section">
 +  <h5>Function Macros</h5>
 +  <div class="links">
++  {% for f in namespace.function_macros %}
 +    <a class="function{% if func.name == f.name %} current{% endif %}" href="func.{{ f.name }}.html">{{ f.name }}</a>
 +  {% endfor %}
 +  </div>
 +</div>
 +{% else %}
 +<div class="section">
 +  <h5>Functions</h5>
 +  <div class="links">
 +  {% for f in namespace.functions %}
 +    <a class="function{% if func.name == f.name %} current{% endif %}" href="func.{{ f.name }}.html">{{ f.name }}</a>
 +  {% endfor %}
 +  </div>
 +</div>
 +{% endif %}
 +{% endblock %}
 +
 +{% block content %}
 +<section id="main" class="content">
 +  <header>
 +    <h3>Function {% if func.is_macro %}Macro{% endif %}</h3>
 +    <h1><a href="index.html">{{ namespace.name }}</a><span class="sep"></span>{{ func.name }}</h1>
 +  </header>
 +
 +  <section>
 +    <div class="declaration toggle-wrapper">
 +      <h4 id="declaration" style="display:flex;">
 +        Declaration
 +        <a href="#declaration" class="anchor"></a>
 +        {% if CONFIG.source_location_url and func.source_location %}
 +        <a class="srclink" title="go to source location" href="{{ CONFIG.source_link(func.source_location) }}">[src]</a>
 +        {% endif %}
 +      </h4>
 +
 +      <div class="docblock">
 +        <pre><code>{{ func.c_decl }}</code></pre>
 +      </div>
 +    </div>
 +
 +    <div class="description toggle-wrapper">
 +      <h4 id="description" style="display:flex;">
 +        Description
 +        <a href="#description" class="anchor"></a>
 +        {% if CONFIG.source_location_url and func.docs_location %}
 +        <a class="srclink" title="go to source location" href="{{ CONFIG.source_link(func.docs_location) }}">[src]</a>
 +        {% endif %}
 +      </h4>
 +
 +      <div class="docblock">
 +        {{ func.description }}
 +      </div>
 +
 +      <div class="docblock">
 +        <table>
 +          {% if func.stability %}
 +          <tr><td>Stability:</td><td>{{ func.stability }}</td></tr>
 +          {% endif %}
 +          {% if func.available_since %}
 +          <tr><td>Available since:</td><td>{{ func.available_since }}</td></tr>
 +          {% endif %}
 +          {% if func.deprecated_since %}
 +          <tr><td>Deprecated since:</td><td>{{ func.deprecated_since.version }}</td></tr>
 +          <tr><td colspan="2">{{ func.deprecated_since.message }}</td></tr>
 +          {% endif %}
 +        </table>
 +      </div>
 +
 +      {% if func.attributes %}
 +      <div class="docblock">
 +        <table>
 +        {% for (key, value) in func.attributes.items() %}
 +          <tr><td>{{ key|escape }}</td><td>{{ value|escape }}</td></tr>
 +        {% endfor %}
 +        </table>
 +      </div>
 +      {% endif %}
 +    </div>
 +
 +    {% if func.arguments|length != 0 %}
 +    <div class="parameters toggle-wrapper">
 +      <h4 id="parameters">
 +        Parameters
 +        <a href="#parameters" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +        <table class="arguments">
 +          {% for arg in func.arguments %}
 +          <tr class="arg-name">
 +            <td><code>{{ arg.name }}</code></td>
 +            <td>
 +            {%- if arg.is_array -%}An array of&nbsp;{%- endif -%}
 +            {%- if arg.is_list -%}A list of&nbsp;{%- endif -%}
 +            {%- if arg.link -%}
 +            {{ arg.link|safe }}
 +            {%- else -%}
 +            <code>{{ arg.type_cname }}</code>
 +            {%- endif -%}
 +            </td>
 +          </tr>
 +          <tr class="arg-description">
 +            <td>&nbsp;</td>
 +            <td>{{ arg.description|safe }}</td>
 +          </tr>
 +          {% if arg.direction != "in" %}<tr><td>&nbsp;</td><td title="direction: {{ arg.direction}}">{{ arg.direction_note }}</td></tr>{% endif %}
 +          {% if arg.direction == "in" and arg.is_pointer and arg.nullable %}<tr><td>&nbsp;</td><td>The argument can be <code>NULL</code>.</td></tr>{% endif %}
 +          {% if arg.direction == "out" and arg.is_pointer and arg.nullable %}<tr><td>&nbsp;</td><td>The argument can be set to <code>NULL</code>.</td></tr>{% endif %}
 +          {% if arg.optional %}<tr><td>&nbsp;</td><td>The argument can be <code>NULL</code>.</td></tr>{% endif %}
 +          {% if arg.is_array and arg.zero_terminated %}<tr><td>&nbsp;</td><td>The array must be <code>NULL</code>-terminated.</td></tr>{% endif %}
 +          {% if arg.is_array and arg.fixed_size > 0 %}<tr><td>&nbsp;</td><td>The array must have {{ arg.fixed_size }} elements.</td></tr>{% endif %}
 +          {% if arg.is_array and arg.len_arg %}<tr><td>&nbsp;</td><td>The length of the array is specified in the <code>{{ arg.len_arg }}</code> argument.</td></tr>{% endif %}
 +          {% if arg.is_pointer %}<tr><td>&nbsp;</td><td title="transfer: {{ arg.transfer }}">{{ arg.transfer_note }}</td></tr>{% endif %}
 +          {% if arg.string_note %}<tr><td>&nbsp;</td><td>{{ arg.string_note }}</td></tr>{% endif %}
 +          {% endfor %}
 +          {% if func.throws %}
 +          <tr class="arg-name">
 +            <td><code>error</code></td>
 +            <td><code>GError **</code></td>
 +          </tr>
 +          <tr class="arg-description">
 +            <td>&nbsp;</td>
 +            <td>The return location for a <code>GError*</code>, or <code>NULL</code>.</td>
 +          </tr>
 +          {% endif %}
 +        </table>
 +      </div>
 +    </div>
 +    {% endif %}
 +
 +    {% if func.return_value %}
 +    <div class="return-value toggle-wrapper">
 +      <h4 id="return-value">
 +        Return value
 +        <a href="#return-value" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +        <table class="returns">
 +          <tr class="arg-name">
 +            <td>Returns:</td>
 +            <td>
 +            {%- if func.return_value.is_array -%}An array of&nbsp;{%- endif -%}
 +            {%- if func.return_value.is_list -%}A list of&nbsp;{%- endif -%}
++            {%- if func.return_value.is_list_model -%}A list model of&nbsp;{%- endif -%}
 +            {%- if func.return_value.link -%}
 +            {{ func.return_value.link|safe }}
 +            {%- else -%}
 +            <code>{{ func.return_value.type_cname }}</code>
 +            {%- endif -%}
 +            </td>
 +          </tr>
 +          <tr class="arg-description">
 +            <td>&nbsp;</td>
 +            <td>{{ func.return_value.description|safe }}</td>
 +          </tr>
 +          {% if func.return_value.is_array and func.return_value.zero_terminated %}<tr><td>&nbsp;</td><td>The array is <code>NULL</code>-terminated.</td></tr>{% endif %}
 +          {% if func.return_value.is_array and func.return_value.fixed_size > 0 %}<tr><td>&nbsp;</td><td>The array has {{ func.return_value.fixed_size }} elements.</td></tr>{% endif %}
 +          {% if func.return_value.is_array and func.return_value.len_arg %}<tr><td>&nbsp;</td><td>The length of the array is in the <code>{{ func.return_value.len_arg }}</code> argument.</td></tr>{% endif %}
 +          {% if func.return_value.is_pointer %}<tr><td>&nbsp;</td><td title="transfer: {{ func.return_value.transfer }}">{{ func.return_value.transfer_note }}</td></tr>{% endif %}
 +          {% if func.return_value.is_pointer and func.return_value.nullable %}<tr><td>&nbsp;</td><td>The return value can be <code>NULL</code>.</td></tr>{% endif %}
 +          {% if func.return_value.string_note %}<tr><td>&nbsp;</td><td>{{ func.return_value.string_note }}</td></tr>{% endif %}
 +        </table>
 +      </div>
 +    </div>
 +    {% endif %}
 +  </section>
 +</section>
 +{% endblock %}
index d61ac2d2bebf04e5deb485450c67968128b7102c,0000000000000000000000000000000000000000..ea6f9943938a96fa44ec12cf2b83abce0126b0d9
mode 100644,000000..100644
--- /dev/null
@@@ -1,315 -1,0 +1,368 @@@
- {{ sidebar_block(interface.type_funcs, interface.name, "Functions", "func", "type_func") }}
 +<!--
 +SPDX-FileCopyrightText: 2021 GNOME Foundation
 +
 +SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +-->
 +
 +{% extends "base.html" %}
 +
 +{% block title %}{{ namespace.name }}.{{ interface.name }}{% endblock %}
 +
 +{% block meta_other %}
 +  <meta property="og:title" content="{{ namespace.name }}.{{ interface.name }}"/>
 +  <meta property="og:description" content="Reference for {{ namespace.name }}.{{ interface.name }}"/>
 +  <meta name="twitter:title" content="{{ namespace.name }}.{{ interface.name }}"/>
 +  <meta name="twitter:description" content="Reference for {{ namespace.name }}.{{ interface.name }}"/>
 +{% endblock %}
 +
 +{% macro sidebar_block(elements, iface_name, section_title, section_class, section_fragment) -%}
 +{% if elements|length > 0 %}
 +<div class="section">
 +  <h5>{{ section_title }}</h5>
 +  <div class="links">
 +  {% for m in elements %}
 +    <a class="{{ section_class }}" href="{{ section_fragment }}.{{ iface_name }}.{{ m.name }}.html">{{ m.name }}</a>
 +  {% endfor %}
 +  </div>
 +</div>
 +{% endif %}
 +{% endmacro %}
 +
 +{% block sidebar %}
 +<div class="section">
 +  <h5>Type</h5>
 +  <div class="links">
 +    <a class="current" href="iface.{{ interface.name }}.html#description">{{ interface.name }}</a>
 +  </div>
 +</div>
 +
++{{ sidebar_block(interface.type_funcs, interface.name, "Functions", "func", "type_func") }}
 +{{ sidebar_block(interface.methods, interface.name, "Instance methods", "method", "method") }}
 +{{ sidebar_block(interface.properties, interface.name, "Properties", "property", "property") }}
 +{{ sidebar_block(interface.signals, interface.name, "Signals", "signal", "signal") }}
 +{{ sidebar_block(interface.class_methods, interface.name, "Interface methods", "method", "class_method") }}
 +{{ sidebar_block(interface.virtual_methods, interface.name, "Virtual methods", "method", "vfunc") }}
 +{% endblock %}
 +
++{% macro navbar_block(elements, section_title, section_link) -%}
++{% if elements|length > 0 %}
++<li class="toc-list-item"><a href="{{ section_link }}"><span class="link-text">{{ section_title }}</span></a></li>
++{% endif %}
++{% endmacro %}
++
++{% block navbar %}
++<div id="toc" class="toc">
++  <nav aria-labelledby="toc-title">
++    <p id="toc-title">Content</p>
++    <ul class="toc-list">
++      <li class="toc-list-item"><a href="#description"><span class="link-text">Description</span></a></li>
++      {{ navbar_block(interface.type_funcs, "Functions", "#type-functions") }}
++      {{ navbar_block(interface.methods, "Methods", "#methods") }}
++      {{ navbar_block(interface.properties, "Properties", "#properties") }}
++      {{ navbar_block(interface.signals, "Signals", "#signals") }}
++      {{ navbar_block(interface.class_methods, "Class methods", "#class-methods") }}
++      {{ navbar_block(interface.virtual_methods, "Virtual methods", "#virtual-methods") }}
++    </ul>
++  </nav>
++</div>
++{% endblock %}
++
 +{% block content %}
 +<section id="main" class="content">
 +  <header>
 +    <h3>Interface</h3>
 +    <h1><a href="index.html">{{ namespace.name }}</a><span class="sep"></span>{{ interface.name }}</h1>
 +  </header>
 +
 +  <section>
 +    <summary>
 +      <div class="toggle-wrapper">
 +        <h4 id="description" style="display:flex;">
 +          Description
 +          <a href="#description" class="anchor"></a>
 +          {% if CONFIG.source_location_url and interface.docs_location %}
 +          <a class="srclink" title="go to source location" href="{{ CONFIG.source_link(interface.docs_location) }}">[src]</a>
 +          {% endif %}
 +        </h4>
 +
 +        <pre><code>{{ interface.c_decl }}</code></pre>
 +
 +        <div class="docblock">
 +          {{ interface.description }}
 +        </div>
 +
 +        <div class="docblock">
 +          <table class="attributes">
 +            {% if interface.stability %}
 +            <tr><td>Stability:</td><td>{{ interface.stability }}</td></tr>
 +            {% endif %}
 +            {% if interface.available_since %}
 +            <tr><td>Available since:</td><td>{{ interface.available_since }}</td></tr>
 +            {% endif %}
 +            {% if interface.deprecated_since %}
 +            <tr><td>Deprecated since:</td><td>{{ interface.deprecated_since.version }}</td></tr>
 +            <tr><td colspan="2">{{ interface.deprecated_since.message }}</td></tr>
 +            {% endif %}
 +          </table>
 +        </div>
 +
 +        {% if interface.attributes %}
 +        <div class="docblock">
 +          <table class="attributes">
 +          {% for (key, value) in interface.attributes.items() %}
 +            <tr><td>{{ key|escape }}</td><td>{{ value|escape }}</td></tr>
 +          {% endfor %}
 +          </table>
 +        </div>
 +        {% endif %}
 +      </div>
 +    </summary>
 +
++    <div class="toggle-wrapper prerequisite">
++      <h4 id="prerequisite">
++        Prerequisite
++        <a href="#prerequisite" class="anchor"></a>
++      </h4>
++
++      <div class="docblock">
++        <p>In order to implement {{ interface.name }}, your type must inherit from
++        {% if interface.requires_namespace == namespace.name -%}
++        <a href="class.{{ interface.requires_name }}.html">
++        {%- else -%}
++        <a data-namespace="{{ interface.requires_namespace }}" data-link="class.{{ interface.requires_name }}.html" href="javascript:void(0)" class="external">
++        {%- endif -%}
++        <code>{{ interface.requires_ctype }}</code></a>.</p>
++      </div>
++    </div>
++
++    {% if interface.implementations %}
++    <div class="implementations toggle-wrapper default-hide">
++      <h4 id="implementations">Implementations<a href="#implementations" class="anchor"></a></h4>
++      <div class="docblock">
++        <ul>
++        {%- for impl in interface.implementations %}
++          <li><a href="class.{{ impl.name }}.html">{{ impl.ctype }}</a></li>
++        {% endfor -%}
++        </ul>
++      </div>
++    </div>
++    {% endif %}
++
++    {% if interface.type_funcs %}
++    <div class="methods toggle-wrapper">
++      <h4 id="type-functions">
++        Functions
++        <a href="#type-functions" class="anchor"></a>
++      </h4>
++
++      <div class="docblock">
++      {% for func in interface.type_funcs %}
++      <div class="{% if func.deprecated_since %}deprecated{% endif %}">
++        <h6><a href="type_func.{{ interface.name }}.{{ func.name }}.html">{{ func.identifier }}</a></h6>
++
++        <div class="docblock">
++          {{ func.summary }}
++        </div>
++
++        {% if func.deprecated_since %}
++        <div class="docblock"><p>Deprecated since: {{ func.deprecated_since.version }}</p></div>
++        {% endif %}
++      </div>
++      {% endfor %}
++      </div>
++    </div>
++    {% endif %}
++
 +    {% if interface.methods %}
 +    <div class="methods toggle-wrapper">
 +      <h4 id="methods">
 +        Instance methods
 +        <a href="#methods" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +      {% for method in interface.methods %}
 +      <div class="{% if method.deprecated_since %}deprecated{% endif %}">
 +        <h6><a href="method.{{ interface.name}}.{{ method.name }}.html">{{ method.identifier }}</a></h6>
 +
 +        <div class="docblock">
 +          {{ method.summary }}
 +        </div>
 +
 +        {% if method.available_since or method.deprecated_since -%}
 +        <div class="docblock">
 +        {%- if method.available_since -%}
 +        <p>Available since: {{ method.available_since }}</p>
 +        {%- endif -%}
 +        {%- if method.deprecated_since -%}
 +        <p>Deprecated since: {{ method.deprecated_since }}</p>
 +        {%- endif -%}
 +        </div>
 +        {%- endif %}
 +      </div>
 +      {% endfor %}
 +      </div>
 +
 +    </div>
 +    {% endif %}
 +
 +    {% if interface.properties %}
 +    <div class="properties toggle-wrapper">
 +      <h4 id="properties">
 +        Properties
 +        <a href="#properties" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +      {% for property in interface.properties %}
 +      <div class="{% if property.deprecated_since %}deprecated{% endif %}">
 +        <h6><a href="property.{{ interface.name }}.{{ property.name }}.html">{{ interface.fqtn }}:{{ property.name }}</a></h6>
 +
 +        <div class="docblock">
 +          {{ property.summary }}
 +        </div>
 +
 +        {% if property.available_since or property.deprecated_since -%}
 +        <div class="docblock">
 +        {%- if property.available_since -%}
 +        <p>Available since: {{ property.available_since }}</p>
 +        {%- endif -%}
 +        {%- if property.deprecated_since -%}
 +        <p>Deprecated since: {{ property.deprecated_since }}</p>
 +        {%- endif -%}
 +        </div>
 +        {%- endif %}
 +      </div>
 +      {% endfor %}
 +      </div>
 +
 +    </div>
 +    {% endif %}
 +
 +    {% if interface.signals %}
 +    <div class="signals toggle-wrapper">
 +      <h4 id="signals">
 +        Signals
 +        <a href="#signals" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +      {% for signal in interface.signals %}
 +      <div class="{% if signal.deprecated_since %}deprecated{% endif %}">
 +        <h6><a href="signal.{{ interface.name }}.{{ signal.name }}.html">{{ interface.fqtn }}::{{ signal.name }}</a></h6>
 +
 +        <div class="docblock">
 +          {{ signal.summary }}
 +        </div>
 +
 +        {% if signal.available_since or signal.deprecated_since -%}
 +        <div class="docblock">
 +        {%- if signal.available_since -%}
 +        <p>Available since: {{ signal.available_since }}</p>
 +        {%- endif -%}
 +        {%- if signal.deprecated_since -%}
 +        <p>Deprecated since: {{ signal.deprecated_since }}</p>
 +        {%- endif -%}
 +        </div>
 +        {%- endif %}
 +      </div>
 +      {% endfor %}
-       {% endif %}
++      </div>
 +    </div>
 +    {% endif %}
 +
 +    {% if interface.class_name %}
 +    <div class="interface toggle-wrapper default-hide">
 +      <h4 style="display:flex;" id="interface-struct">
 +        Interface structure
 +        <a href="#interface-struct" class="anchor"></a>
 +        {% if CONFIG.source_location_url and interface.source_location %}
 +        <a class="srclink" title="go to source location" href="{{ CONFIG.source_link(interface.source_location) }}">[src]</a>
 +        {% endif %}
 +      </h4>
 +
 +      <div class="docblock">
 +        <pre><code>struct {{ namespace.name}}{{ interface.class_name }} {
 +  {% for field in interface.class_fields %}
 +  {%- if field.is_callback -%}
 +  {{ field.type_cname }};
 +  {%- else -%}
 +  {{ field.type_cname }} {{ field.name }};
 +  {%- endif %}
 +  {% else %}/* no available fields */{% endfor %}
 +}</code></pre>
 +      </div>
 +
 +      {% if interface.class_fields %}
 +      <div class="docblock">
 +        <h6>Interface members</h6>
 +
 +        <table>
 +        {% for field in interface.class_fields %}
 +        <tr>
 +          <td style="vertical-align:top"><code>{{ field.name }}</code></td>
 +          <td style="vertical-align:top"><pre><code>{{ field.type_cname }}</code></pre></td>
 +        </tr>
 +        <tr>
 +          <td>&nbsp;</td><td style="vertical-align:top">{{ field.description }}</td>
 +        </tr>
 +        {% endfor %}
 +        </table>
-     {% if interface.type_funcs %}
-     <div class="methods toggle-wrapper">
-       <h4 id="type-functions">
-         Functions
-         <a href="#type-functions" class="anchor"></a>
-       </h4>
-       <div class="docblock">
-       {% for func in interface.type_funcs %}
-       <div class="{% if func.deprecated_since %}deprecated{% endif %}">
-         <h6><a href="type_func.{{ interface.name }}.{{ func.name }}.html">{{ func.identifier }}</a></h6>
-         <div class="docblock">
-           {{ func.summary }}
-         </div>
-         {% if func.deprecated_since %}
-         <div class="docblock"><p>Deprecated since: {{ func.deprecated_since.version }}</p></div>
-         {% endif %}
-       </div>
-       {% endfor %}
-       </div>
-     </div>
-     {% endif %}
 +      </div>
++      {% endif %}
 +    </div>
 +    {% endif %}
 +
 +    {% if interface.class_methods %}
 +    <div class="toggle-wrapper methods">
 +      <h4 id="interface-methods">
 +        Interface methods
 +        <a href="#interface-methods" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +      {% for method in interface.class_methods %}
 +      <div class="{% if method.deprecated_since %}deprecated{% endif %}">
 +        <h6><a href="class_method.{{ interface.name }}.{{ method.name }}.html">{{ method.identifier }}</a></h6>
 +
 +        <div class="docblock">
 +          {{ method.summary }}
 +        </div>
 +
 +        {% if method.deprecated_since %}
 +        <div class="docblock"><p>Deprecated since: {{ method.deprecated_since.version }}</p></div>
 +        {% endif %}
 +      </div>
 +      {% endfor %}
 +      </div>
 +    </div>
 +    {% endif %}
 +
 +    {% if interface.virtual_methods %}
 +    <div class="toggle-wrapper methods">
 +      <h4 id="virtual-methods">
 +        Virtual methods
 +        <a href="#virtual-methods" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +      {% for method in interface.virtual_methods %}
 +      <div class="{% if method.deprecated_since %}deprecated{% endif %}">
 +        <h6 id="vfunc-{{ method.name }}"><a href="vfunc.{{ interface.name }}.{{ method.name }}.html">{{ namespace.name }}.{{ interface.name }}.{{ method.name }}</a></h6>
 +
 +        <div class="docblock">
 +          {{ method.summary }}
 +        </div>
 +
 +        {% if method.deprecated_since %}
 +        <div class="docblock"><p>Deprecated since: {{ method.deprecated_since.version }}</p></div>
 +        {% endif %}
 +      </div>
 +      {% endfor %}
 +      </div>
 +    </div>
 +    {% endif %}
 +
 +  </section>
 +</section>
 +{% endblock %}
index 7a3f45d72ab1df5687d54b463651e06b3efca7b6,0000000000000000000000000000000000000000..09ee4806e28541f5f672ef3deee34af65a17c87f
mode 100644,000000..100644
--- /dev/null
@@@ -1,172 -1,0 +1,176 @@@
-     if (event.code === "KeyS" && document.activeElement !== search_input) {
 +// SPDX-FileCopyrightText: 2021 GNOME Foundation
 +//
 +// SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +"use strict";
 +
 +
 +const urlMap = new Map(typeof baseURLs !== 'undefined' ? baseURLs : []);
 +
 +window.addEventListener("hashchange", onDidHashChange);
 +window.addEventListener("load", onDidLoad, false);
 +window.addEventListener("keydown", onKeyDown);
 +
 +function onDidLoad() {
 +    attachScrollHandlers()
 +    attachToggleHandlers()
 +    attachCopyHandlers()
 +
 +    if (window.onInitSearch) {
 +        window.onInitSearch()
 +    }
 +}
 +
 +function onDidHashChange() {
 +    // When URL fragment changes to ID of a collapsible section,
 +    // expand it when it is collapsed.
 +    // This is useful for clicking section links in the sidebar on the index page.
 +    const sectionHeader = document.querySelector(".section-header" + location.hash);
 +    if (sectionHeader !== null) {
 +        const parent = sectionHeader.parentNode;
 +        if (hasClass(parent, "toggle-wrapper")) {
 +            const toggle = parent.querySelector(".collapse-toggle");
 +            if (hasClass(toggle, "collapsed")) {
 +                toggle.click();
 +            }
 +        }
 +    }
 +}
 +
 +
 +function attachScrollHandlers() {
 +    const btnToTop = document.getElementById("btn-to-top");
 +
 +    btnToTop.addEventListener('click', onClick);
 +    window.addEventListener('scroll', onScroll);
 +
 +    function onClick(e) {
 +        e.preventDefault();
 +        window.scroll({ top: 0, behavior: 'smooth' });
 +    }
 +
 +    function onScroll() {
 +        if (window.scrollY < 400) {
 +            addClass(btnToTop, "hidden");
 +        } else {
 +            removeClass(btnToTop, "hidden");
 +        }
 +    }
 +}
 +
 +function attachToggleHandlers() {
 +    function label(isCollapsed) {
 +        return (
 +            "[<span class=\"inner\">" +
 +                (isCollapsed ? "+" : "\u2212") +
 +            "</span>]"
 +        )
 +    }
 +
 +    function createToggle(isCollapsed) {
 +        const toggle = document.createElement("a");
 +        toggle.href = "javascript:void(0)";
 +        toggle.className = "collapse-toggle";
 +        toggle.innerHTML = label(isCollapsed);
 +        toggle.addEventListener('click', onClickToggle);
 +        return toggle;
 +    }
 +
 +    function onClickToggle() {
 +        if (hasClass(this, "collapsed")) {
 +            removeClass(this, "collapsed");
 +            this.innerHTML = label(false);
 +            forEach(this.parentNode.querySelectorAll(".docblock"), function(e) {
 +                removeClass(e, "hidden");
 +            });
 +        } else {
 +            addClass(this, "collapsed");
 +            this.innerHTML = label(true);
 +            forEach(this.parentNode.querySelectorAll(".docblock"), function(e) {
 +                addClass(e, "hidden");
 +            });
 +        }
 +    }
 +
 +    forEach(document.querySelectorAll(".toggle-wrapper"), function(e) {
 +        const sectionHeader = e.querySelector(".section-header");
 +        const fragmentMatches = sectionHeader !== null && location.hash === "#" + sectionHeader.getAttribute('id');
 +        const collapsedByDefault = hasClass(e, "default-hide") && !fragmentMatches;
 +        const toggle = createToggle(collapsedByDefault);
 +        e.insertBefore(toggle, e.firstChild);
 +        if (collapsedByDefault) {
 +            addClass(toggle, "collapsed");
 +            forEach(e.querySelectorAll(".docblock"), function(d) {
 +                addClass(d, "hidden");
 +            });
 +        }
 +    });
 +
 +    function resolveNamespaceLink(namespace) {
 +        return urlMap.get(namespace);
 +    }
 +
 +    forEach(document.querySelectorAll(".external"), function(e) {
 +        if (e.tagName == "A" && e.dataset.hasOwnProperty('namespace')) {
 +            var data_namespace = e.dataset.namespace
 +            var data_link = e.dataset.link
 +            var base_url = resolveNamespaceLink(data_namespace)
 +            if (base_url !== undefined) {
 +                e.href = base_url + data_link;
 +            } else {
 +                e.title = "No reference to the " + data_namespace + " namespace";
 +            }
 +        }
 +    })
 +}
 +
 +function attachCopyHandlers() {
 +    if (!navigator.clipboard)
 +        return;
 +
 +    forEach(document.querySelectorAll(".codehilite"), function(e) {
 +        const button = document.createElement("button");
 +        button.className = "copy-button";
 +        button.innerText = "Copy";
 +        button.title = "Copy code to clipboard";
 +
 +        const text = e.innerText;
 +        button.addEventListener("click", () => {
 +            navigator.clipboard.writeText(text);
 +        });
 +
 +        e.appendChild(button);
 +    })
 +}
 +
 +function onKeyDown(event) {
 +    let search_input = document.querySelector("#search-input");
++    // We don't want to try to focus the search input if it isn't visible. That way
++    // we avoid the preventDefault(), hence allowing devhelp to use S as mnemonic.
++    let potentially_hidden_parent = search_input.closest('.hidden, .devhelp-hidden');
 +
++    if (window.getComputedStyle(potentially_hidden_parent).display !== 'none' &&
++        event.code === "KeyS" && document.activeElement !== search_input) {
 +        event.preventDefault();
 +        search_input.focus();
 +    }
 +}
 +
 +// Helpers
 +
 +function hasClass(elem, className) {
 +    return elem && elem.classList && elem.classList.contains(className);
 +}
 +
 +function addClass(elem, className) {
 +    return elem && elem.classList && elem.classList.add(className);
 +}
 +
 +function removeClass(elem, className) {
 +    return elem && elem.classList && elem.classList.remove(className);
 +}
 +
 +function forEach(arr, func) {
 +    for (let i = 0; i < arr.length; ++i) {
 +        func(arr[i])
 +    }
 +}
index 49d1fe1ec5a9119f60baed80a6595588140a5ccc,0000000000000000000000000000000000000000..fc8e9c2c87d20c74d17d310117eee46e06827636
mode 100644,000000..100644
--- /dev/null
@@@ -1,185 -1,0 +1,186 @@@
 +<!--
 +SPDX-FileCopyrightText: 2021 GNOME Foundation
 +
 +SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +-->
 +
 +{% extends "base.html" %}
 +
 +{% block title %}{{ namespace.name }}.{{ class.name }}.{{ method.name }}{% endblock %}
 +
 +{% block meta_other %}
 +  <meta priority="og:title" content="{{ namespace.name }}.{{ class.name }}.{{ method.name }}"/>
 +  <meta priority="og:description" content="Reference for {{ namespace.name }}.{{ class.name }}.{{ method.name }}"/>
 +  <meta name="twitter:title" content="{{ namespace.name }}.{{ class.name }}.{{ method.name }}"/>
 +  <meta name="twitter:description" content="Reference for {{ namespace.name }}.{{ class.name }}.{{ method.name }}"/>
 +{% endblock %}
 +
 +{% block sidebar %}
 +<div class="section">
 +  <h5>Type</h5>
 +  <div class="links">
 +    <a href="{{ class.link_prefix }}.{{ class.name }}.html">{{ class.name }}</a>
 +  </div>
 +</div>
 +<div class="section">
 +  <h5>Methods</h5>
 +  <div class="links">
 +  {% for m in class.methods %}
 +    <a class="method{% if method.name == m.name %} current{% endif %}" href="method.{{ class.name }}.{{ m.name }}.html">{{ m.name }}</a>
 +  {% endfor %}
 +  </div>
 +</div>
 +{% endblock %}
 +
 +{% block content %}
 +<section id="main" class="content">
 +  <header>
 +    <h3>Method</h3>
 +    <h1><a href="index.html">{{ namespace.name }}</a><span class="sep"></span><a href="{{ class.link_prefix }}.{{ class.name }}.html">{{ class.name }}</a><span class="sep"></span>{{ method.name }}</h1>
 +  </header>
 +
 +  <section>
 +    <div class="declaration toggle-wrapper">
 +      <h4 style="display:flex;" id="declaration">
 +        Declaration
 +        <a class="anchor" href="#declaration"></a>
 +        {% if CONFIG.source_location_url and method.source_location %}
 +        <a class="srclink" title="go to source location" href="{{ CONFIG.source_link(method.source_location) }}">[src]</a>
 +        {% endif %}
 +      </h4>
 +
 +      <div class="docblock c-decl">
 +        <pre><code>{{ method.c_decl|safe }}</code></pre>
 +      </div>
 +    </div>
 +
 +    <div class="description toggle-wrapper">
 +      <h4 style="display:flex;" id="description">
 +        Description
 +        <a class="anchor" href="#description"></a>
 +        {% if CONFIG.source_location_url and method.docs_location %}
 +        <a class="srclink" title="go to source location" href="{{ CONFIG.source_link(method.docs_location) }}">[src]</a>
 +        {% endif %}
 +      </h4>
 +
 +      <div class="docblock">
 +        {{ method.description|safe }}
 +      </div>
 +
 +      <div class="docblock">
 +        <table>
 +          {% if method.stability %}
 +          <tr><td>Stability:</td><td>{{ method.stability }}</td></tr>
 +          {% endif %}
 +          {% if method.available_since %}
 +          <tr><td>Available since:</td><td>{{ method.available_since }}</td></tr>
 +          {% endif %}
 +          {% if method.deprecated_since %}
 +          <tr><td>Deprecated since:</td><td>{{ method.deprecated_since.version }}</td></tr>
 +          <tr><td colspan="2">{{ method.deprecated_since.message|safe }}</td></tr>
 +          {% endif %}
 +        </table>
 +      </div>
 +
 +      {% if method.attributes %}
 +      <div class="docblock">
 +        <table>
 +        {% for (key, value) in method.attributes.items() %}
 +          <tr><td>{{ key|escape }}</td><td>{{ value|escape }}</td></tr>
 +        {% endfor %}
 +        </table>
 +      </div>
 +      {% endif %}
 +    </div>
 +
 +    {% if method.arguments|length != 0 %}
 +    <div class="parameters toggle-wrapper">
 +      <h4 id="parameters">
 +        Parameters
 +        <a href="#parameters" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +        <table class="arguments">
 +          {% for arg in method.arguments %}
 +          <tr class="arg-name">
 +            <td><code>{{ arg.name }}</code></td>
 +            <td>
 +            {%- if arg.is_array -%}An array of&nbsp;{%- endif -%}
 +            {%- if arg.is_list -%}A list of&nbsp;{%- endif -%}
 +            {%- if arg.link -%}
 +            {{ arg.link|safe }}
 +            {%- else -%}
 +            <code>{{ arg.type_cname }}</code>
 +            {%- endif -%}
 +            </td>
 +          </tr>
 +          <tr class="arg-description">
 +            <td>&nbsp;</td>
 +            <td>{{ arg.description|safe }}</td>
 +          </tr>
 +          {% if arg.direction != "in" %}<tr><td>&nbsp;</td><td title="direction: {{ arg.direction}}">{{ arg.direction_note }}</td></tr>{% endif %}
 +          {% if arg.direction == "in" and arg.is_pointer and arg.nullable %}<tr><td>&nbsp;</td><td>The argument can be <code>NULL</code>.</td></tr>{% endif %}
 +          {% if arg.direction == "out" and arg.is_pointer and arg.nullable %}<tr><td>&nbsp;</td><td>The argument can be set to <code>NULL</code>.</td></tr>{% endif %}
 +          {% if arg.optional %}<tr><td>&nbsp;</td><td>The argument can be <code>NULL</code>.</td></tr>{% endif %}
 +          {% if arg.is_array and arg.zero_terminated %}<tr><td>&nbsp;</td><td>The array must be <code>NULL</code>-terminated.</td></tr>{% endif %}
 +          {% if arg.is_array and arg.fixed_size > 0 %}<tr><td>&nbsp;</td><td>The array must have {{ arg.fixed_size }} elements.</td></tr>{% endif %}
 +          {% if arg.is_array and arg.len_arg %}<tr><td>&nbsp;</td><td>The length of the array is specified in the <code>{{ arg.len_arg }}</code> argument.</td></tr>{% endif %}
 +          {% if arg.is_pointer %}<tr><td>&nbsp;</td><td title="transfer: {{ arg.transfer }}">{{ arg.transfer_note }}</td></tr>{% endif %}
 +          {% if arg.string_note %}<tr><td>&nbsp;</td><td>{{ arg.string_note }}</td></tr>{% endif %}
 +          {% endfor %}
 +          {% if method.throws %}
 +          <tr class="arg-name">
 +            <td><code>error</code></td>
 +            <td><code>GError **</code></td>
 +          </tr>
 +          <tr class="arg-description">
 +            <td>&nbsp;</td>
 +            <td>The return location for a <code>GError*</code>, or <code>NULL</code>.</td>
 +          </tr>
 +          {% endif %}
 +        </table>
 +      </div>
 +    </div>
 +    {% endif %}
 +
 +    {% if method.return_value %}
 +    <div class="return-value toggle-wrapper">
 +      <h4 id="return-value">
 +        Return value
 +        <a href="#return-value" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +        <table class="returns">
 +          <tr class="arg-name">
 +            <td>Returns:</td>
 +            <td>
 +            {%- if method.return_value.is_array -%}An array of&nbsp;{%- endif -%}
 +            {%- if method.return_value.is_list -%}A list of&nbsp;{%- endif -%}
++            {%- if method.return_value.is_list_model -%}A list model of&nbsp;{%- endif -%}
 +            {%- if method.return_value.link -%}
 +            {{ method.return_value.link|safe }}
 +            {%- else -%}
 +            <code>{{ method.return_value.type_cname }}</code>
 +            {%- endif -%}
 +            </td>
 +          </tr>
 +          <tr class="arg-description">
 +            <td>&nbsp;</td>
 +            <td>{{ method.return_value.description|safe }}</td>
 +          </tr>
 +          {% if method.return_value.is_array and method.return_value.zero_terminated %}<tr><td>&nbsp;</td><td>The array is <code>NULL</code>-terminated.</td></tr>{% endif %}
 +          {% if method.return_value.is_array and method.return_value.fixed_size > 0 %}<tr><td>&nbsp;</td><td>The array has {{ method.return_value.fixed_size }} elements.</td></tr>{% endif %}
 +          {% if method.return_value.is_array and method.return_value.len_arg %}<tr><td>&nbsp;</td><td>The length of the array is in the <code>{{ method.return_value.len_arg }}</code> argument.</td></tr>{% endif %}
 +          {% if method.return_value.is_pointer %}<tr><td>&nbsp;</td><td title="transfer: {{ method.return_value.transfer }}">{{ method.return_value.transfer_note }}</td></tr>{% endif %}
 +          {% if method.return_value.is_pointer and method.return_value.nullable %}<tr><td>&nbsp;</td><td>The return value can be <code>NULL</code>.</td></tr>{% endif %}
 +          {% if method.return_value.string_note %}<tr><td>&nbsp;</td><td>{{ method.return_value.string_note }}</td></tr>{% endif %}
 +        </table>
 +      </div>
 +    </div>
 +    {% endif %}
 +
 +  </section>
 +</section>
 +{% endblock %}
index 0b2c6fc5db670d1701caa32d8e8238d1da2e7d3d,0000000000000000000000000000000000000000..f4fd0080a2a44cdd100351f10bddf6764d246a8e
mode 100644,000000..100644
--- /dev/null
@@@ -1,120 -1,0 +1,122 @@@
 +<!--
 +SPDX-FileCopyrightText: 2021 GNOME Foundation
 +
 +SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +-->
 +
 +{% extends "base.html" %}
 +
 +{% block title %}{{ namespace.name }}.{{ class.name }}:{{ property.name }}{% endblock %}
 +
 +{% block meta_other %}
 +  <meta property="og:title" content="{{ namespace.name }}.{{ class.name }}:{{ property.name }}"/>
 +  <meta property="og:description" content="Reference for property {{ namespace.name }}.{{ class.name }}:{{ property.name }}"/>
 +  <meta name="twitter:title" content="{{ namespace.name }}.{{ class.name }}:{{ property.name }}"/>
 +  <meta name="twitter:description" content="Reference for property {{ namespace.name }}.{{ class.name }}:{{ property.name }}"/>
 +{% endblock %}
 +
 +{% block sidebar %}
 +<div class="section">
 +  <h5>Type</h5>
 +  <div class="links">
 +    <a href="{{ class.link_prefix }}.{{ class.name }}.html">{{ class.name }}</a>
 +  </div>
 +</div>
 +<div class="section">
 +  <h5>Properties</h5>
 +  <div class="links">
 +  {% for p in class.properties %}
 +    <a class="property{% if p.name == property.name %} current{% endif %}"href="property.{{ class.name }}.{{ p.name }}.html">{{ p.name }}</a>
 +  {% endfor %}
 +  </div>
 +</div>
 +{% endblock %}
 +
 +{% block content %}
 +<section id="main" class="content">
 +  <header>
 +    <h3>Property</h3>
 +    <h1><a href="index.html">{{ namespace.name }}</a><span class="sep"></span><a href="{{ class.link_prefix }}.{{ class.name }}.html">{{ class.name }}</a>:{{ property.name }}</h1>
 +  </header>
 +
 +  <section>
 +    <div class="declaration toggle-wrapper">
 +      <h4 id="declaration">
 +        Declaration
 +        <a href="#declaration" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +        <pre><code>{{ property.c_decl|safe }}</code></pre>
 +      </div>
 +    </div>
 +
 +    <div class="description toggle-wrapper">
 +      <h4 id="description">
 +        Description
 +        <a href="#description" class="anchor"></a>
 +        {% if CONFIG.source_location_url and property.docs_location %}
 +        <a class="srclink" title="go to source location" href="{{ CONFIG.source_link(property.docs_location) }}">[src]</a>
 +        {% endif %}
 +      </h4>
 +
 +      <div class="docblock">
 +        {{ property.description }}
 +      </div>
 +
 +      <div class="docblock">
 +        <table>
 +          <tr><td>Type:</td>
 +            <td>
++            {%- if property.is_array -%}An array of&nbsp;{%- endif -%}
++            {%- if property.is_list -%}A list of&nbsp;{%- endif -%}
 +            {%- if property.link -%}
 +            {{ property.link|safe }}
 +            {%- else -%}
 +            <code>{{ property.type_cname }}</code>
 +            {%- endif -%}
 +            </td>
 +          </tr>
 +          {% if property.stability %}
 +          <tr><td>Stability:</td><td>{{ property.stability }}</td></tr>
 +          {% endif %}
 +          {% if property.available_since %}
 +          <tr><td>Available since:</td><td>{{ property.available_since }}</td></tr>
 +          {% endif %}
 +          {% if property.deprecated_since %}
 +          <tr><td>Deprecated since:</td><td>{{ property.deprecated_since.version }}</td></tr>
 +          <tr><td colspan="2">{{ property.deprecated_since.message }}</td></tr>
 +          {% endif %}
 +        </table>
 +      </div>
 +
 +      {% if property.attributes %}
 +      <div class="docblock">
 +        <table>
 +        {% for (key, value) in property.attributes.items() %}
 +          <tr><td>{{ key|escape }}</td><td>{{ value|escape }}</td></tr>
 +        {% endfor %}
 +        </table>
 +      </div>
 +      {% endif %}
 +    </div>
 +
 +    <div class="flags toggle-wrapper">
 +      <h4 id="flags">
 +        Flags
 +        <a href="#flags" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +      <table>
 +        <tr><td>Readable</td><td>{% if property.readable %}<b>yes</b>{% else %}<b>no</b>{% endif %}</td></tr>
 +        <tr><td>Writable</td><td>{% if property.writable %}<b>yes</b>{% else %}<b>no</b>{% endif %}</td></tr>
 +        <tr><td>Construct</td><td>{% if property.construct %}<b>yes</b>{% else %}<b>no</b>{% endif %}</td></tr>
 +        <tr><td>Construct only</td><td>{% if property.construct_only %}<b>yes</b>{% else %}<b>no</b>{% endif %}</td></tr>
 +      </table>
 +      </div>
 +    </div>
 +
 +  </section>
 +</section>
 +{% endblock %}
index 8913f6954c647e008baa2f3197d5d170cca875a9,0000000000000000000000000000000000000000..f635df656af39fbdabdb6260c5b28d4feb1c42f5
mode 100644,000000..100644
--- /dev/null
@@@ -1,303 -1,0 +1,372 @@@
-     refs.input  = document.querySelector("#search-input")
-     refs.form   = document.querySelector("#search-form")
-     refs.search = document.querySelector("#search")
-     refs.main   = document.querySelector("#main")
 +// SPDX-FileCopyrightText: 2021 GNOME Foundation
 +//
 +// SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +
 +(function() {
 +
 +const QUERY_TYPES = [
 +    "alias",
 +    "bitfield",
 +    "callback",
 +    "class",
 +    "constant",
++    "content",
 +    "ctor",
 +    "domain",
 +    "enum",
 +    "function_macro",
 +    "function",
 +    "interface",
 +    "method",
 +    "property",
 +    "record",
 +    "signal",
 +    "type_func",
 +    "union",
 +    "vfunc",
 +];
 +const QUERY_PATTERN = new RegExp("^(" + QUERY_TYPES.join('|') + ")\\s*:\\s*", 'i');
 +
 +
 +const fzy = window.fzy;
 +const searchParams = getSearchParams();
 +const refs = {
 +    input: null,
 +    form: null,
 +    search: null,
 +    main: null,
++    toc: null,
 +};
 +
 +let searchIndex = undefined;
 +let searchResults = [];
 +
 +// Exports
 +window.onInitSearch = onInitSearch;
 +
 +/* Event handlers */
 +
 +function onInitSearch() {
 +    fetchJSON('index.json', onDidLoadSearchIndex);
 +}
 +
 +function onDidLoadSearchIndex(data) {
 +    searchIndex = new SearchIndex(data)
 +
-     attachInputHandlers()
++    refs.input  = document.querySelector("#search-input");
++    refs.form   = document.querySelector("#search-form");
++    refs.search = document.querySelector("#search");
++    refs.main   = document.querySelector("#main");
++    refs.toc    = document.querySelector("#toc");
 +
-     const query = refs.input.value
-     if (query)
-         search(query)
-     else
-         hideSearchResults()
++    attachInputHandlers();
 +
 +    if (searchParams.q) {
 +        search(searchParams.q);
 +    }
 +}
 +
++function getNakedUrl() {
++    return window.location.href.split("?")[0].split("#")[0];
++}
++
 +function onDidSearch() {
-     if (searchResults.length > 0) {
-         window.location.href = searchResults[0].href
++    const query = refs.input.value;
++    if (query) {
++        search(query);
++    }
++    else {
++        hideSearchResults();
++    }
 +}
 +
 +function onDidSubmit(ev) {
 +    ev.preventDefault();
-     refs.input.addEventListener('keydown', debounce(200, onDidSearch))
++    if (searchResults.length == 1) {
++        window.location.href = searchResults[0].href;
 +    }
 +}
 +
 +function attachInputHandlers() {
 +    if (refs.input.value === "") {
 +        refs.input.value === searchParams.q || "";
 +    }
 +
-             text: getTextForDocument(doc, searchIndex.meta),
++    refs.input.addEventListener('keyup', debounce(500, onDidSearch))
 +    refs.form.addEventListener('submit', onDidSubmit)
 +}
 +
 +/* Searching */
 +
 +function searchQuery(query) {
 +    const q = matchQuery(query);
 +    const docs = searchIndex.searchDocs(q.term, q.type);
 +
 +    const results = docs.map(function(doc) {
 +        return {
 +            name: doc.name,
 +            type: doc.type,
-                         "<a href=\"" + item.href + "\"><code>" + item.text + "</code></a>" +
++            text: getLabelForDocument(doc, searchIndex.meta),
 +            href: getLinkForDocument(doc),
 +            summary: doc.summary,
 +        };
 +    });
 +
 +    return results;
 +}
 +
 +function search(query) {
 +    searchResults = searchQuery(query)
 +    showResults(query, searchResults);
 +}
 +
 +/* Rendering */
 +
 +function showSearchResults() {
 +    addClass(refs.main, "hidden");
++    if (refs.toc) {
++        addClass(refs.toc, "hidden");
++    }
 +    removeClass(refs.search, "hidden");
 +}
 +
 +function hideSearchResults() {
 +    addClass(refs.search, "hidden");
 +    removeClass(refs.main, "hidden");
++    if (refs.toc) {
++        removeClass(refs.toc, "hidden");
++    }
 +}
 +
 +function renderResults(query, results) {
 +    let html = "";
 +
 +    html += "<h1>Results for &quot;" + query + "&quot; (" + results.length + ")</h1>" +
 +                "<div id=\"search-results\">"
 +
 +    if (results.length === 0) {
 +        html += "No results found.";
 +    }
 +    else {
 +        html += "<table class=\"results\">" +
 +                  "<tr><th>Name</th><th>Description</th></tr>";
 +        results.forEach(function(item) {
 +            html += "<tr>" +
 +                        "<td class=\"result " + item.type + "\">" +
-         case "class_method": return "class_method." + doc.type_name + "." + doc.name + ".html";
++                        "<a href=\"" + item.href + "\">" + item.text + "</a>" +
 +                        "</td>" +
 +                        "<td>" + item.summary + "</td>" +
 +                    "</tr>";
 +        });
 +        html += "</table>";
 +    }
 +
 +    html += "</div>";
 +
 +    return html;
 +}
 +
 +function showResults(query, results) {
++    if (window.history && typeof window.history.pushState === "function") {
++        let baseUrl = getNakedUrl();
++        let extra = "?q=" + encodeURIComponent(refs.input.value);
++        window.history.replaceState(refs.input.value, "", baseUrl + extra + window.location.hash);
++    }
++
 +    window.title = "Results for: " + query;
 +    window.scroll({ top: 0 })
 +    refs.search.innerHTML = renderResults(query, results);
 +    showSearchResults(search);
 +}
 +
 +
 +/* Search data instance */
 +
 +function SearchIndex(searchIndex) {
 +    this.symbols = searchIndex.symbols;
 +    this.meta = searchIndex.meta;
 +}
 +SearchIndex.prototype.searchDocs = function searchDocs(term, type) {
 +    const filteredSymbols = !type ?
 +        this.symbols :
 +        this.symbols.filter(s => s.type === type);
 +    const results = fzy.filter(term, filteredSymbols, doc => getTextForDocument(doc, this.meta))
 +    return results.map(i => i.item)
 +}
 +
 +
 +/* Search metadata selectors */
 +
 +function getLinkForDocument(doc) {
 +    switch (doc.type) {
 +        case "alias": return "alias." + doc.name + ".html";
 +        case "bitfield": return "flags." + doc.name + ".html";
 +        case "callback": return "callback." + doc.name + ".html";
 +        case "class": return "class." + doc.name + ".html";
-         case "callback":
++        case "class_method": return "class_method." + doc.struct_for + "." + doc.name + ".html";
 +        case "constant": return "const." + doc.name + ".html";
++        case "content": return doc.href;
 +        case "ctor": return "ctor." + doc.type_name + "." + doc.name + ".html";
 +        case "domain": return "error." + doc.name + ".html";
 +        case "enum": return "enum." + doc.name + ".html";
 +        case "function": return "func." + doc.name + ".html";
 +        case "function_macro": return "func." + doc.name + ".html";
 +        case "interface": return "iface." + doc.name + ".html";
 +        case "method": return "method." + doc.type_name + "." + doc.name + ".html";
 +        case "property": return "property." + doc.type_name + "." + doc.name + ".html";
 +        case "record": return "struct." + doc.name + ".html";
 +        case "signal": return "signal." + doc.type_name + "." + doc.name + ".html";
 +        case "type_func": return "type_func." + doc.type_name + "." + doc.name + ".html";
 +        case "union": return "union." + doc.name + ".html";
 +        case "vfunc": return "vfunc." + doc.type_name + "." + doc.name + ".html";
 +    }
 +    return null;
 +}
 +
++function getLabelForDocument(doc, meta) {
++    switch (doc.type) {
++        case "alias":
++        case "bitfield":
++        case "callback":
++        case "class":
++        case "domain":
++        case "enum":
++        case "interface":
++        case "record":
++        case "union":
++            return "<code>" + doc.ctype + "</code>";
++
++        case "class_method":
++        case "constant":
++        case "ctor":
++        case "function":
++        case "function_macro":
++        case "method":
++        case "type_func":
++            return "<code>" + doc.ident + "</code>";
++
++        // NOTE: meta.ns added for more consistent results, otherwise
++        // searching for "Button" would return all signals, properties
++        // and vfuncs (eg "Button.clicked") before the actual object 
++        // (eg "GtkButton") because "Button" matches higher with starting
++        // sequences.
++        case "property":
++            return "<code>" + meta.ns + doc.type_name + ":" + doc.name + "</code>";
++        case "signal":
++            return "<code>" + meta.ns + doc.type_name + "::" + doc.name + "</code>";
++        case "vfunc":
++            return "<code>" + meta.ns + doc.type_name + "." + doc.name + "</code>";
++
++        case "content":
++            return doc.name;
++    }
++
++    return null;
++}
++
 +function getTextForDocument(doc, meta) {
 +    switch (doc.type) {
 +        case "alias":
 +        case "bitfield":
++        case "callback":
 +        case "class":
 +        case "domain":
 +        case "enum":
 +        case "interface":
 +        case "record":
 +        case "union":
 +            return doc.ctype;
++
 +        case "class_method":
 +        case "constant":
 +        case "ctor":
 +        case "function":
 +        case "function_macro":
 +        case "method":
 +        case "type_func":
 +            return doc.ident;
 +
 +        // NOTE: meta.ns added for more consistent results, otherwise
 +        // searching for "Button" would return all signals, properties
 +        // and vfuncs (eg "Button.clicked") before the actual object 
 +        // (eg "GtkButton") because "Button" matches higher with starting
 +        // sequences.
 +        case "property":
 +            return meta.ns + doc.type_name + ":" + doc.name;
 +        case "signal":
 +            return meta.ns + doc.type_name + "::" + doc.name;
 +        case "vfunc":
 +            return meta.ns + doc.type_name + "." + doc.name;
 +
-   let timeout
-   let savedArgs
-   return function() {
-     const self = this
-     savedArgs = Array.prototype.slice.call(arguments)
-     if (timeout)
-       clearTimeout(timeout)
-     timeout = setTimeout(function() {
-       fn.apply(self, savedArgs)
-       timeout = undefined
-     }, delay)
-   }
++        case "content":
 +            return doc.name;
 +    }
 +
 +    return null;
 +}
 +
 +
 +// Helpers
 +
 +function fetchJSON(url, callback) {
 +    const request = new XMLHttpRequest();
 +    request.open('GET', url, true);
 +    request.onreadystatechange = function() {
 +        if (request.readyState === XMLHttpRequest.DONE) {
 +            const status = request.status;
 +
 +            if (status === 0 || (status >= 200 && status < 400)) {
 +                callback(JSON.parse(request.responseText));
 +            }
 +        }
 +    }
 +    request.send(null);
 +}
 +
 +function getSearchParams() {
 +    const params = {};
 +    window.location.search.substring(1).split('&')
 +        .map(function(s) {
 +            const pair = s.split('=');
 +            params[decodeURIComponent(pair[0])] =
 +                typeof pair[1] === 'undefined' ? null : decodeURIComponent(pair[1].replace(/\+/g, '%20'));
 +        });
 +    return params;
 +}
 +
 +function matchQuery(input) {
 +    let type = null
 +    let term = input
 +
 +    const matches = term.match(QUERY_PATTERN);
 +    if (matches) {
 +        type = matches[1];
 +        term = term.substring(matches[0].length);
 +    }
 +
 +    // Remove all spaces, fzy will handle things gracefully.
 +    term = term.replace(/\s+/g, '')
 +
 +    return { type: type, term: term }
 +}
 +
 +function debounce(delay, fn) {
++    let timeout;
++    let savedArgs
++
++    return function() {
++        const self = this;
++        savedArgs = Array.prototype.slice.call(arguments);
++
++        if (timeout) {
++            clearTimeout(timeout);
++        }
++
++        timeout = setTimeout(function() {
++            fn.apply(self, savedArgs)
++            timeout = undefined
++        }, delay)
++    }
 +}
 +
 +})()
index ea27925f1a74a3cc114a867e332daf70bb1d5798,0000000000000000000000000000000000000000..68ef3f87ad7aa462d18674a77f6d89aba7db2158
mode 100644,000000..100644
--- /dev/null
@@@ -1,195 -1,0 +1,196 @@@
 +<!--
 +SPDX-FileCopyrightText: 2021 GNOME Foundation
 +
 +SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +-->
 +
 +{% extends "base.html" %}
 +
 +{% block title %}{{ namespace.name }}.{{ class.name }}::{{ signal.name }}{% endblock %}
 +
 +{% block meta_other %}
 +  <meta property="og:title" content="{{ namespace.name }}.{{ class.name }}::{{ signal.name }}"/>
 +  <meta property="og:description" content="Reference for signal {{ namespace.name }}.{{ class.name }}::{{ signal.name }}"/>
 +  <meta name="twitter:title" content="{{ namespace.name }}.{{ class.name }}::{{ signal.name }}"/>
 +  <meta name="twitter:description" content="Reference for signal {{ namespace.name }}.{{ class.name }}::{{ signal.name }}"/>
 +{% endblock %}
 +
 +{% block sidebar %}
 +<div class="section">
 +  <h5>Type</h5>
 +  <div class="links">
 +    <a href="{{ class.link_prefix }}.{{ class.name }}.html">{{ class.name }}</a>
 +  </div>
 +</div>
 +<div class="section">
 +  <h5>Signals</h5>
 +  <div class="links">
 +  {% for s in class.signals %}
 +    <a class="signal{% if s.name == signal.name %} current{% endif %}" href="signal.{{ class.name }}.{{ s.name }}.html">{{ s.name }}</a>
 +  {% endfor %}
 +  </div>
 +</div>
 +{% endblock %}
 +
 +{% block content %}
 +<section id="main" class="content">
 +  <header>
 +    <h3>Signal</h3>
 +    <h1><a href="index.html">{{ namespace.name }}</a><span class="sep"></span><a href="{{ class.link_prefix }}.{{ class.name }}.html">{{ class.name }}</a>::{{ signal.name }}</h1>
 +  </header>
 +
 +  <section>
 +    <div class="declaration toggle-wrapper">
 +      <h4 id="declaration">
 +        Declaration
 +        <a href="#declaration" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +        <pre><code>{{ signal.c_decl }}</code></pre>
 +      </div>
 +    </div>
 +
 +    <div class="description toggle-wrapper">
 +      <h4 id="description" style="display:flex;">
 +        Description
 +        <a href="#description" class="anchor"></a>
 +        {% if CONFIG.source_location_url and signal.docs_location %}
 +        <a class="srclink" title="go to source location" href="{{ CONFIG.source_link(signal.docs_location) }}">[src]</a>
 +        {% endif %}
 +      </h4>
 +
 +      <div class="docblock">
 +        {{ signal.description }}
 +      </div>
 +
 +      <div class="docblock">
 +        <table>
 +          <tr><td>Default handler:</td><td> {{ signal.when }}</td></tr>
 +          {% if signal.no_recurse %}
 +          <tr><td colspan="2">Signal emission will restart instead of recursing</td></tr>
 +          {% endif %}
 +          {% if signal.is_action %}
 +          <tr><td colspan="2">The signal can be emitted directly</td></tr>
 +          {% endif %}
 +          {% if signal.is_detailed %}
 +          <tr><td colspan="2">The signal can be detailed</td></tr>
 +          {% endif %}
 +          {% if signal.no_hooks %}
 +          <tr><td colspan="2">Hooks are disabled for this signal</td></tr>
 +          {% endif %}
 +          {% if signal.stability %}
 +          <tr><td>Stability:</td><td>{{ signal.stability }}</td></tr>
 +          {% endif %}
 +          {% if signal.available_since %}
 +          <tr><td>Available since:</td><td>{{ signal.available_since }}</td></tr>
 +          {% endif %}
 +          {% if signal.deprecated_since %}
 +          <tr><td>Deprecated since:</td><td>{{ signal.deprecated_since.version }}</td></tr>
 +          <tr><td colspan="2">{{ signal.deprecated_since.message }}</td></tr>
 +          {% endif %}
 +        </table>
 +      </div>
 +
 +      {% if signal.attributes %}
 +      <div class="docblock">
 +        <table>
 +        {% for (key, value) in signal.attributes.items() %}
 +          <tr><td>{{ key|escape }}</td><td>{{ value|escape }}</td></tr>
 +        {% endfor %}
 +        </table>
 +      </div>
 +      {% endif %}
 +    </div>
 +
 +    {% if signal.arguments|length != 0 %}
 +    <div class="parameters toggle-wrapper">
 +      <h4 id="parameters">
 +        Parameters
 +        <a href="#parameters" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +        <table class="arguments">
 +          {% for arg in signal.arguments %}
 +          <tr class="arg-name">
 +            <td><code>{{ arg.name }}</code></td>
 +            <td>
 +            {%- if arg.is_array -%}An array of&nbsp;{%- endif -%}
 +            {%- if arg.is_list -%}A list of&nbsp;{%- endif -%}
 +            {%- if arg.link -%}
 +            {{ arg.link|safe }}
 +            {%- else -%}
 +            <code>{{ arg.type_cname }}</code>
 +            {%- endif -%}
 +            </td>
 +          </tr>
 +          <tr class="arg-description">
 +            <td>&nbsp;</td>
 +            <td>{{ arg.description|safe }}</td>
 +          </tr>
 +          {% if arg.direction != "in" %}<tr><td>&nbsp;</td><td title="direction: {{ arg.direction}}">{{ arg.direction_note }}</td></tr>{% endif %}
 +          {% if arg.direction == "in" and arg.is_pointer and arg.nullable %}<tr><td>&nbsp;</td><td>The argument can be <code>NULL</code>.</td></tr>{% endif %}
 +          {% if arg.direction == "out" and arg.is_pointer and arg.nullable %}<tr><td>&nbsp;</td><td>The argument can be set to <code>NULL</code>.</td></tr>{% endif %}
 +          {% if arg.optional %}<tr><td>&nbsp;</td><td>The argument can be <code>NULL</code>.</td></tr>{% endif %}
 +          {% if arg.is_array and arg.zero_terminated %}<tr><td>&nbsp;</td><td>The array must be <code>NULL</code>-terminated.</td></tr>{% endif %}
 +          {% if arg.is_array and arg.fixed_size > 0 %}<tr><td>&nbsp;</td><td>The array must have {{ arg.fixed_size }} elements.</td></tr>{% endif %}
 +          {% if arg.is_array and arg.len_arg %}<tr><td>&nbsp;</td><td>The length of the array is specified in the <code>{{ arg.len_arg }}</code> argument.</td></tr>{% endif %}
 +          {% if arg.is_pointer %}<tr><td>&nbsp;</td><td title="transfer: {{ arg.transfer }}">{{ arg.transfer_note }}</td></tr>{% endif %}
 +          {% if arg.string_note %}<tr><td>&nbsp;</td><td>{{ arg.string_note }}</td></tr>{% endif %}
 +          {% endfor %}
 +          {% if signal.throws %}
 +          <tr class="arg-name">
 +            <td><code>error</code></td>
 +            <td><code>GError **</code></td>
 +          </tr>
 +          <tr class="arg-description">
 +            <td>&nbsp;</td>
 +            <td>The return location for a <code>GError*</code>, or <code>NULL</code>.</td>
 +          </tr>
 +          {% endif %}
 +        </table>
 +      </div>
 +    </div>
 +    {% endif %}
 +
 +    {% if signal.return_value %}
 +    <div class="return-value toggle-wrapper">
 +      <h4 id="return-value">
 +        Return value
 +        <a href="#return-value" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +        <table class="returns">
 +          <tr class="arg-name">
 +            <td>Returns:</td>
 +            <td>
 +            {%- if signal.return_value.is_array -%}An array of&nbsp;{%- endif -%}
 +            {%- if signal.return_value.is_list -%}A list of&nbsp;{%- endif -%}
++            {%- if signal.return_value.is_list_model -%}A list model of&nbsp;{%- endif -%}
 +            {%- if signal.return_value.link -%}
 +            {{ signal.return_value.link|safe }}
 +            {%- else -%}
 +            <code>{{ signal.return_value.type_cname }}</code>
 +            {%- endif -%}
 +            </td>
 +          </tr>
 +          <tr class="arg-description">
 +            <td>&nbsp;</td>
 +            <td>{{ signal.return_value.description|safe }}</td>
 +          </tr>
 +          {% if signal.return_value.is_array and signal.return_value.zero_terminated %}<tr><td>&nbsp;</td><td>The array is <code>NULL</code>-terminated.</td></tr>{% endif %}
 +          {% if signal.return_value.is_array and signal.return_value.fixed_size > 0 %}<tr><td>&nbsp;</td><td>The array has {{ signal.return_value.fixed_size }} elements.</td></tr>{% endif %}
 +          {% if signal.return_value.is_array and signal.return_value.len_arg %}<tr><td>&nbsp;</td><td>The length of the array is in the <code>{{ signal.return_value.len_arg }}</code> argument.</td></tr>{% endif %}
 +          {% if signal.return_value.is_pointer %}<tr><td>&nbsp;</td><td title="transfer: {{ signal.return_value.transfer }}">{{ signal.return_value.transfer_note }}</td></tr>{% endif %}
 +          {% if signal.return_value.is_pointer and signal.return_value.nullable %}<tr><td>&nbsp;</td><td>The return value can be <code>NULL</code>.</td></tr>{% endif %}
 +          {% if signal.return_value.string_note %}<tr><td>&nbsp;</td><td>{{ signal.return_value.string_note }}</td></tr>{% endif %}
 +        </table>
 +      </div>
 +    </div>
 +    {% endif %}
 +
 +  </section>
 +</section>
 +{% endblock %}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..2edc59b8846ac1a1f4b7c56362be50d0bd878416
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,88 @@@
++/*
++ * SPDX-FileCopyrightText: 2014 John Louis Del Rosario, Hank Gay, John Mastro, Brandon Bennett
++ * SPDX-License-Identifier: MIT
++ */
++
++pre { line-height: 125%; }
++td.linenos pre { color: #586e75; background-color: #073642; padding-left: 5px; padding-right: 5px; }
++span.linenos { color: #586e75; background-color: #073642; padding-left: 5px; padding-right: 5px; }
++td.linenos pre.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
++span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
++.codehilite .hll { background-color: #073642 }
++.codehilite { background: #002b36; color: #839496 }
++.codehilite .c { color: #586e75; font-style: italic } /* Comment */
++.codehilite .err { color: #839496; background-color: #dc322f } /* Error */
++.codehilite .esc { color: #839496 } /* Escape */
++.codehilite .g { color: #839496 } /* Generic */
++.codehilite .k { color: #859900 } /* Keyword */
++.codehilite .l { color: #839496 } /* Literal */
++.codehilite .n { color: #839496 } /* Name */
++.codehilite .o { color: #586e75 } /* Operator */
++.codehilite .x { color: #839496 } /* Other */
++.codehilite .p { color: #839496 } /* Punctuation */
++.codehilite .ch { color: #586e75; font-style: italic } /* Comment.Hashbang */
++.codehilite .cm { color: #586e75; font-style: italic } /* Comment.Multiline */
++.codehilite .cp { color: #d33682 } /* Comment.Preproc */
++.codehilite .cpf { color: #586e75 } /* Comment.PreprocFile */
++.codehilite .c1 { color: #586e75; font-style: italic } /* Comment.Single */
++.codehilite .cs { color: #586e75; font-style: italic } /* Comment.Special */
++.codehilite .gd { color: #dc322f } /* Generic.Deleted */
++.codehilite .ge { color: #839496; font-style: italic } /* Generic.Emph */
++.codehilite .gr { color: #dc322f } /* Generic.Error */
++.codehilite .gh { color: #839496; font-weight: bold } /* Generic.Heading */
++.codehilite .gi { color: #859900 } /* Generic.Inserted */
++.codehilite .go { color: #839496 } /* Generic.Output */
++.codehilite .gp { color: #839496 } /* Generic.Prompt */
++.codehilite .gs { color: #839496; font-weight: bold } /* Generic.Strong */
++.codehilite .gu { color: #839496; text-decoration: underline } /* Generic.Subheading */
++.codehilite .gt { color: #268bd2 } /* Generic.Traceback */
++.codehilite .kc { color: #2aa198 } /* Keyword.Constant */
++.codehilite .kd { color: #2aa198 } /* Keyword.Declaration */
++.codehilite .kn { color: #cb4b16 } /* Keyword.Namespace */
++.codehilite .kp { color: #859900 } /* Keyword.Pseudo */
++.codehilite .kr { color: #859900 } /* Keyword.Reserved */
++.codehilite .kt { color: #b58900 } /* Keyword.Type */
++.codehilite .ld { color: #839496 } /* Literal.Date */
++.codehilite .m { color: #2aa198 } /* Literal.Number */
++.codehilite .s { color: #2aa198 } /* Literal.String */
++.codehilite .na { color: #839496 } /* Name.Attribute */
++.codehilite .nb { color: #268bd2 } /* Name.Builtin */
++.codehilite .nc { color: #268bd2 } /* Name.Class */
++.codehilite .no { color: #268bd2 } /* Name.Constant */
++.codehilite .nd { color: #268bd2 } /* Name.Decorator */
++.codehilite .ni { color: #268bd2 } /* Name.Entity */
++.codehilite .ne { color: #268bd2 } /* Name.Exception */
++.codehilite .nf { color: #268bd2 } /* Name.Function */
++.codehilite .nl { color: #268bd2 } /* Name.Label */
++.codehilite .nn { color: #268bd2 } /* Name.Namespace */
++.codehilite .nx { color: #839496 } /* Name.Other */
++.codehilite .py { color: #839496 } /* Name.Property */
++.codehilite .nt { color: #268bd2 } /* Name.Tag */
++.codehilite .nv { color: #268bd2 } /* Name.Variable */
++.codehilite .ow { color: #859900 } /* Operator.Word */
++.codehilite .w { color: #839496 } /* Text.Whitespace */
++.codehilite .mb { color: #2aa198 } /* Literal.Number.Bin */
++.codehilite .mf { color: #2aa198 } /* Literal.Number.Float */
++.codehilite .mh { color: #2aa198 } /* Literal.Number.Hex */
++.codehilite .mi { color: #2aa198 } /* Literal.Number.Integer */
++.codehilite .mo { color: #2aa198 } /* Literal.Number.Oct */
++.codehilite .sa { color: #2aa198 } /* Literal.String.Affix */
++.codehilite .sb { color: #2aa198 } /* Literal.String.Backtick */
++.codehilite .sc { color: #2aa198 } /* Literal.String.Char */
++.codehilite .dl { color: #2aa198 } /* Literal.String.Delimiter */
++.codehilite .sd { color: #586e75 } /* Literal.String.Doc */
++.codehilite .s2 { color: #2aa198 } /* Literal.String.Double */
++.codehilite .se { color: #2aa198 } /* Literal.String.Escape */
++.codehilite .sh { color: #2aa198 } /* Literal.String.Heredoc */
++.codehilite .si { color: #2aa198 } /* Literal.String.Interpol */
++.codehilite .sx { color: #2aa198 } /* Literal.String.Other */
++.codehilite .sr { color: #cb4b16 } /* Literal.String.Regex */
++.codehilite .s1 { color: #2aa198 } /* Literal.String.Single */
++.codehilite .ss { color: #2aa198 } /* Literal.String.Symbol */
++.codehilite .bp { color: #268bd2 } /* Name.Builtin.Pseudo */
++.codehilite .fm { color: #268bd2 } /* Name.Function.Magic */
++.codehilite .vc { color: #268bd2 } /* Name.Variable.Class */
++.codehilite .vg { color: #268bd2 } /* Name.Variable.Global */
++.codehilite .vi { color: #268bd2 } /* Name.Variable.Instance */
++.codehilite .vm { color: #268bd2 } /* Name.Variable.Magic */
++.codehilite .il { color: #2aa198 } /* Literal.Number.Integer.Long */
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f1fa80f7370d5cdaff6e31f469a10713efdec725
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,88 @@@
++/*
++ * SPDX-FileCopyrightText: 2014 John Louis Del Rosario, Hank Gay, John Mastro, Brandon Bennett
++ * SPDX-License-Identifier: MIT
++ */
++
++pre { line-height: 125%; }
++td.linenos pre { color: #93a1a1; background-color: #eee8d5; padding-left: 5px; padding-right: 5px; }
++span.linenos { color: #93a1a1; background-color: #eee8d5; padding-left: 5px; padding-right: 5px; }
++td.linenos pre.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
++span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
++.codehilite .hll { background-color: #eee8d5 }
++.codehilite { background: #fdf6e3; color: #657b83 }
++.codehilite .c { color: #93a1a1; font-style: italic } /* Comment */
++.codehilite .err { color: #657b83; background-color: #dc322f } /* Error */
++.codehilite .esc { color: #657b83 } /* Escape */
++.codehilite .g { color: #657b83 } /* Generic */
++.codehilite .k { color: #859900 } /* Keyword */
++.codehilite .l { color: #657b83 } /* Literal */
++.codehilite .n { color: #657b83 } /* Name */
++.codehilite .o { color: #93a1a1 } /* Operator */
++.codehilite .x { color: #657b83 } /* Other */
++.codehilite .p { color: #657b83 } /* Punctuation */
++.codehilite .ch { color: #93a1a1; font-style: italic } /* Comment.Hashbang */
++.codehilite .cm { color: #93a1a1; font-style: italic } /* Comment.Multiline */
++.codehilite .cp { color: #d33682 } /* Comment.Preproc */
++.codehilite .cpf { color: #93a1a1 } /* Comment.PreprocFile */
++.codehilite .c1 { color: #93a1a1; font-style: italic } /* Comment.Single */
++.codehilite .cs { color: #93a1a1; font-style: italic } /* Comment.Special */
++.codehilite .gd { color: #dc322f } /* Generic.Deleted */
++.codehilite .ge { color: #657b83; font-style: italic } /* Generic.Emph */
++.codehilite .gr { color: #dc322f } /* Generic.Error */
++.codehilite .gh { color: #657b83; font-weight: bold } /* Generic.Heading */
++.codehilite .gi { color: #859900 } /* Generic.Inserted */
++.codehilite .go { color: #657b83 } /* Generic.Output */
++.codehilite .gp { color: #657b83 } /* Generic.Prompt */
++.codehilite .gs { color: #657b83; font-weight: bold } /* Generic.Strong */
++.codehilite .gu { color: #657b83; text-decoration: underline } /* Generic.Subheading */
++.codehilite .gt { color: #268bd2 } /* Generic.Traceback */
++.codehilite .kc { color: #2aa198 } /* Keyword.Constant */
++.codehilite .kd { color: #2aa198 } /* Keyword.Declaration */
++.codehilite .kn { color: #cb4b16 } /* Keyword.Namespace */
++.codehilite .kp { color: #859900 } /* Keyword.Pseudo */
++.codehilite .kr { color: #859900 } /* Keyword.Reserved */
++.codehilite .kt { color: #b58900 } /* Keyword.Type */
++.codehilite .ld { color: #657b83 } /* Literal.Date */
++.codehilite .m { color: #2aa198 } /* Literal.Number */
++.codehilite .s { color: #2aa198 } /* Literal.String */
++.codehilite .na { color: #657b83 } /* Name.Attribute */
++.codehilite .nb { color: #268bd2 } /* Name.Builtin */
++.codehilite .nc { color: #268bd2 } /* Name.Class */
++.codehilite .no { color: #268bd2 } /* Name.Constant */
++.codehilite .nd { color: #268bd2 } /* Name.Decorator */
++.codehilite .ni { color: #268bd2 } /* Name.Entity */
++.codehilite .ne { color: #268bd2 } /* Name.Exception */
++.codehilite .nf { color: #268bd2 } /* Name.Function */
++.codehilite .nl { color: #268bd2 } /* Name.Label */
++.codehilite .nn { color: #268bd2 } /* Name.Namespace */
++.codehilite .nx { color: #657b83 } /* Name.Other */
++.codehilite .py { color: #657b83 } /* Name.Property */
++.codehilite .nt { color: #268bd2 } /* Name.Tag */
++.codehilite .nv { color: #268bd2 } /* Name.Variable */
++.codehilite .ow { color: #859900 } /* Operator.Word */
++.codehilite .w { color: #657b83 } /* Text.Whitespace */
++.codehilite .mb { color: #2aa198 } /* Literal.Number.Bin */
++.codehilite .mf { color: #2aa198 } /* Literal.Number.Float */
++.codehilite .mh { color: #2aa198 } /* Literal.Number.Hex */
++.codehilite .mi { color: #2aa198 } /* Literal.Number.Integer */
++.codehilite .mo { color: #2aa198 } /* Literal.Number.Oct */
++.codehilite .sa { color: #2aa198 } /* Literal.String.Affix */
++.codehilite .sb { color: #2aa198 } /* Literal.String.Backtick */
++.codehilite .sc { color: #2aa198 } /* Literal.String.Char */
++.codehilite .dl { color: #2aa198 } /* Literal.String.Delimiter */
++.codehilite .sd { color: #93a1a1 } /* Literal.String.Doc */
++.codehilite .s2 { color: #2aa198 } /* Literal.String.Double */
++.codehilite .se { color: #2aa198 } /* Literal.String.Escape */
++.codehilite .sh { color: #2aa198 } /* Literal.String.Heredoc */
++.codehilite .si { color: #2aa198 } /* Literal.String.Interpol */
++.codehilite .sx { color: #2aa198 } /* Literal.String.Other */
++.codehilite .sr { color: #cb4b16 } /* Literal.String.Regex */
++.codehilite .s1 { color: #2aa198 } /* Literal.String.Single */
++.codehilite .ss { color: #2aa198 } /* Literal.String.Symbol */
++.codehilite .bp { color: #268bd2 } /* Name.Builtin.Pseudo */
++.codehilite .fm { color: #268bd2 } /* Name.Function.Magic */
++.codehilite .vc { color: #268bd2 } /* Name.Variable.Class */
++.codehilite .vg { color: #268bd2 } /* Name.Variable.Global */
++.codehilite .vi { color: #268bd2 } /* Name.Variable.Instance */
++.codehilite .vm { color: #268bd2 } /* Name.Variable.Magic */
++.codehilite .il { color: #2aa198 } /* Literal.Number.Integer.Long */
index 5fd9b7593b76607799ba566f6ee58ec93fbf130d,0000000000000000000000000000000000000000..0b0f27a20241b73877b9796def24c0d0d749096f
mode 100644,000000..100644
--- /dev/null
@@@ -1,216 -1,0 +1,236 @@@
- {{ sidebar_block(struct.methods, struct.name, "Instance methods", "method", "method") }}
 +<!--
 +SPDX-FileCopyrightText: 2021 GNOME Foundation
 +
 +SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +-->
 +
 +{% extends "base.html" %}
 +
 +{% block title %}{{ namespace.name }}.{{ struct.name }}{% endblock %}
 +
 +{% block meta_other %}
 +  <meta property="og:title" content="{{ namespace.name }}.{{ struct.name }}"/>
 +  <meta property="og:description" content="Reference for {{ namespace.name }}.{{ struct.name }}"/>
 +  <meta name="twitter:title" content="{{ namespace.name }}.{{ struct.name }}"/>
 +  <meta name="twitter:description" content="Reference for {{ namespace.name }}.{{ struct.name }}"/>
 +{% endblock %}
 +
 +{% macro sidebar_block(elements, struct_name, section_title, section_class, section_fragment) -%}
 +{% if elements|length > 0 %}
 +<div class="section">
 +  <h5>{{ section_title }}</h5>
 +  <div class="links">
 +  {% for m in elements %}
 +    <a class="{{ section_class }}" href="{{ section_fragment }}.{{ struct_name }}.{{ m.name }}.html">{{ m.name }}</a>
 +  {% endfor %}
 +  </div>
 +</div>
 +{% endif %}
 +{% endmacro %}
 +
 +{% block sidebar %}
 +<div class="section">
 +  <h5>Type</h5>
 +  <div class="links">
 +    <a class="current" href="struct.{{ struct.name }}.html#description">{{ struct.name }}</a>
 +  </div>
 +</div>
 +
 +{{ sidebar_block(struct.ctors, struct.name, "Constructors", "ctor", "ctor") }}
-     {% if struct.type_funcs %}
-     <div class="toggle-wrapper methods">
-       <h4 id="type-functions">
-         Functions
-         <a href="#type-functions" class="anchor"></a>
-       </h4>
-       <div class="docblock">
-       {% for func in struct.type_funcs %}
-       <div class="{% if func.deprecated_since %}deprecated{% endif %}">
-         <h6><a href="type_func.{{ struct.name }}.{{ func.name }}.html">{{ func.identifier }}</a></h6>
-         <div class="docblock">
-           {{ func.summary }}
-         </div>
-         {% if func.available_since or func.deprecated_since -%}
-         <div class="docblock">
-         {%- if func.available_since -%}
-         <p>Available since: {{ func.available_since }}</p>
-         {%- endif -%}
-         {%- if func.deprecated_since -%}
-         <p>Deprecated since: {{ func.deprecated_since }}</p>
-         {%- endif -%}
-         </div>
-         {%- endif %}
-       </div>
-       {% endfor %}
-       </div>
-     </div>
-     {% endif %}
 +{{ sidebar_block(struct.type_funcs, struct.name, "Functions", "func", "type_func") }}
++{{ sidebar_block(struct.methods, struct.name, "Instance methods", "method", "method") }}
++{% endblock %}
++
++{% macro navbar_block(elements, section_title, section_link) -%}
++{% if elements|length > 0 %}
++<li class="toc-list-item"><a href="{{ section_link }}"><span class="link-text">{{ section_title }}</span></a></li>
++{% endif %}
++{% endmacro %}
++
++{% block navbar %}
++<div id="toc" class="toc">
++  <nav aria-labelledby="toc-title">
++    <p id="toc-title">Content</p>
++    <ul class="toc-list">
++      <li class="toc-list-item"><a href="#description"><span class="link-text">Description</span></a></li>
++      {{ navbar_block(struct.ctors, "Constructors", "#constructors") }}
++      {{ navbar_block(struct.type_funcs, "Functions", "#type-functions") }}
++      {{ navbar_block(struct.methods, "Methods", "#methods") }}
++    </ul>
++  </nav>
++</div>
 +{% endblock %}
 +
 +{% block content %}
 +<section id="main" class="content">
 +  <header>
 +    <h3>Struct</h3>
 +    <h1><a href="index.html">{{ namespace.name }}</a><span class="sep"></span>{{ struct.name }}</h1>
 +  </header>
 +
 +  <section>
 +    <summary>
 +      <div class="toggle-wrapper">
 +        <h4 style="display:flex;" id="description">
 +          Description
 +          <a href="#description" class="anchor"></a>
 +          {% if CONFIG.source_location_url and struct.docs_location %}
 +          <a class="srclink" title="go to source location" href="{{ CONFIG.source_link(struct.docs_location) }}">[src]</a>
 +          {% endif %}
 +        </h4>
 +
 +        <pre><code>{{ struct.c_decl }}</code></pre>
 +
 +        <div class="docblock">
 +          {{ struct.description }}
 +        </div>
 +
 +        {% if struct.fields %}
 +        <div class="toggle-wrapper">
 +          <h6 style="display:flex;">
 +            Structure members
 +            {% if CONFIG.source_location_url and struct.source_location %}
 +            <a class="srclink" title="go to source location" href="{{ CONFIG.source_link(struct.source_location) }}">[src]</a>
 +            {% endif %}
 +          </h6>
 +
 +          <div class="docblock">
 +            <table>
 +            {% for field in struct.fields %}
 +              <tr>
 +                <td><code>{{ field.name }}</code></td>
 +                <td>{{ field.description }}</td>
 +              </tr>
 +            {% endfor %}
 +            </table>
 +          </div>
 +        </div>
 +        {% endif %}
 +
 +        <div class="docblock">
 +          <table class="attributes">
 +            {% if struct.stability %}
 +            <tr><td>Stability:</td><td>{{ struct.stability }}</td></tr>
 +            {% endif %}
 +            {% if struct.available_since %}
 +            <tr><td>Available since:</td><td>{{ struct.available_since }}</td></tr>
 +            {% endif %}
 +            {% if struct.deprecated_since %}
 +            <tr><td>Deprecated since:</td><td>{{ struct.deprecated_since.version }}</td></tr>
 +            <tr><td colspan="2">{{ struct.deprecated_since.message }}</td></tr>
 +            {% endif %}
 +          </table>
 +        </div>
 +
 +        {% if struct.attributes %}
 +        <div class="docblock">
 +          <table class="attributes">
 +          {% for (key, value) in struct.attributes.items() %}
 +            <tr><td>{{ key|escape }}</td><td>{{ value|escape }}</td></tr>
 +          {% endfor %}
 +          </table>
 +        </div>
 +        {% endif %}
 +      </div>
 +    </summary>
 +
 +    {% if struct.ctors %}
 +    <div class="toggle-wrapper constructors">
 +      <h4 id="constructors">
 +        Constructors
 +        <a href="#constructors" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +      {% for ctor in struct.ctors %}
 +        <div class="{% if ctor.deprecated_since %}deprecated{% endif %}">
 +          <h6><a href="ctor.{{ struct.name }}.{{ ctor.name }}.html">{{ ctor.identifier }}</a></h6>
 +
 +          <div class="docblock">
 +            {{ ctor.summary }}
 +          </div>
 +
 +          {% if ctor.available_since or ctor.deprecated_since -%}
 +          <div class="docblock">
 +          {%- if ctor.available_since -%}
 +          <p>Available since: {{ ctor.available_since }}</p>
 +          {%- endif -%}
 +          {%- if ctor.deprecated_since -%}
 +          <p>Deprecated since: {{ ctor.deprecated_since }}</p>
 +          {%- endif -%}
 +          </div>
 +          {%- endif %}
 +        </div>
 +      {% endfor %}
 +      </div>
 +    </div>
 +    {% endif %}
 +
++    {% if struct.type_funcs %}
++    <div class="toggle-wrapper methods">
++      <h4 id="type-functions">
++        Functions
++        <a href="#type-functions" class="anchor"></a>
++      </h4>
++
++      <div class="docblock">
++      {% for func in struct.type_funcs %}
++      <div class="{% if func.deprecated_since %}deprecated{% endif %}">
++        <h6><a href="type_func.{{ struct.name }}.{{ func.name }}.html">{{ func.identifier }}</a></h6>
++
++        <div class="docblock">
++          {{ func.summary }}
++        </div>
++
++        {% if func.available_since or func.deprecated_since -%}
++        <div class="docblock">
++        {%- if func.available_since -%}
++        <p>Available since: {{ func.available_since }}</p>
++        {%- endif -%}
++        {%- if func.deprecated_since -%}
++        <p>Deprecated since: {{ func.deprecated_since }}</p>
++        {%- endif -%}
++        </div>
++        {%- endif %}
++      </div>
++      {% endfor %}
++      </div>
++    </div>
++    {% endif %}
++
 +    {% if struct.methods %}
 +    <div class="toggle-wrapper methods">
 +      <h4 id="methods">
 +        Instance methods
 +        <a href="#methods" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +      {% for method in struct.methods %}
 +        <div class="{% if method.deprecated_since %}deprecated{% endif %}">
 +          <h6><a href="method.{{ struct.name}}.{{ method.name }}.html">{{ method.identifier }}</a></h6>
 +
 +          <div class="docblock">
 +            {{ method.summary }}
 +          </div>
 +
 +          {% if method.available_since or method.deprecated_since -%}
 +          <div class="docblock">
 +          {%- if method.available_since -%}
 +          <p>Available since: {{ method.available_since }}</p>
 +          {%- endif -%}
 +          {%- if method.deprecated_since -%}
 +          <p>Deprecated since: {{ method.deprecated_since }}</p>
 +          {%- endif -%}
 +          </div>
 +          {%- endif %}
 +        </div>
 +      {% endfor %}
 +      </div>
 +
 +    </div>
 +    {% endif %}
 +
 +  </section>
 +</section>
 +{% endblock %}
index 8ff4bf13af3d299931b0960ff3561d9c802b8f86,0000000000000000000000000000000000000000..889bbe8bc757fa5ea82201f4ecc5cbc803173287
mode 100644,000000..100644
--- /dev/null
@@@ -1,869 -1,0 +1,901 @@@
- @import url("pygment.css");
 +/*
 + * SPDX-FileCopyrightText: 2021 GNOME Foundation
 + *
 + * SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 + */
 +
-   --body-font-size: calc(var(--body-font-scale) * clamp(16px, 1vw, 20px));
++@import url("solarized-light.css") (prefers-color-scheme: light);
++@import url("solarized-dark.css") (prefers-color-scheme: dark);
++
 +@import url("fonts.css");
 +
 +/*********************************
 + * LIGHT THEME
 + *********************************/
 +:root {
 +
 +  /* colors */
 +  --text-color: #333;
 +  --text-color-muted: #999;
 +  --primary: rgb(28, 118, 228);
 +  --body-bg: #fff;
 +  --sidebar-primary: rgb(144, 194, 255);
 +  --sidebar-bg: #151515;
 +  --sidebar-selected-bg: var(--primary);
 +  --sidebar-hover-bg: rgba(127, 127, 127, 0.2);
 +  --sidebar-text-color: #fafafa;
 +  --sidebar-padding: 1.5em;
 +
 +  /* boxes, e.g. code blocks */
 +  --box-bg: rgba(135, 135, 135, 0.085);
 +  --box-radius: 0.35rem;
 +  --box-padding: 0.75rem;
 +  --box-margin: 0.75rem 0;
 +  --box-text-color: #111;
 +
 +  /* typography */
 +  --body-font-family: "Red Hat Text",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
 +  --body-font-scale: 0.95;
-   /* fix dark theme syntax highlighting with a filter (for now) */
-   .highlight pre span {
-       filter: brightness(6);
-   }
++  --body-font-size: calc(var(--body-font-scale) * clamp(16px, 1vw, 18px));
 +  --body-font-weight: normal;
 +
 +  --monospace-font-family: "Source Code Pro", monospace;
 +  --monospace-font-size: calc(0.86 * var(--body-font-size)); /* Monospace fonts are very different in terms of font-sizes. Adjust this value to scale it */
 +
 +  --heading-font-family: "Red Hat Display", var(--body-font-family);
 +  --heading-weight: 900;
 +  --heading-font-scale: 1.05;
 +
 +  --heading-small-font-family: var(--heading-font-family);
 +  --heading-small-weight: 600;
 +  --heading-small-font-scale: 1;
 +
 +  --heading-table-font-family: var(--heading-font-family);
 +  --heading-table-weight: 600;
 +
 +  --heading-docblock-color: #6d6d6d;  /* docblocks have headings from source comments. we want them to differ.*/
 +  --heading-docblock-scale: 0.9;        /* docblocks have headings from source comments. we want them to differ.*/
 +
 +  --symbol-font-family: var(--heading-font-family);
 +  --symbol-font-weight: 500;
 +  --symbol-font-scale: 1;
 +
 +  --table-font-size: 0.92em;    /* Tables often contain lots information. It's better to scale them down a big to get more sutff fitted inside */
 +
 +  /* misc */
 +  --prefered-content-width: 90ch; /* The preferred width for the readable content */
 +  --anchor-sign: "#";
 +
 +}
 +
 +/*********************************
 + * DARK THEME (overrides)
 + *********************************/
 + @media (prefers-color-scheme: dark) {
 +  :root {
 +    --primary: rgb(144, 194, 255);
 +    --text-color: #f6f6f6;
 +    --text-color-muted: #686868;
 +    --body-bg: #121212;
 +    --sidebar-primary: rgb(144, 194, 255);
 +    --sidebar-bg: #1e1e1e;
 +    --sidebar-selected-bg: rgb(17, 112, 228);
 +    --sidebar-text-color: #fafafa;
 +    --box-bg: rgba(135, 135, 135, 0.1);
 +    --box-text-color: #fff;
 +    --heading-docblock-color: #b7b7b7;
 +  }
 +}
 +
 +/*********************************
 + * GENERAL STYLING
 + *********************************/
 +*,
 +*:before,
 +*:after {
 +  box-sizing: border-box;
 +}
 +
 +::-moz-selection {
 +  color: white;
 +  background: var(--primary);
 +}
 +
 +::selection {
 +  color: white;
 +  background: var(--primary);
 +}
 +
 +::-webkit-scrollbar {
 +  width: 8px;
 +  height: 8px;
 +}
 +
 +::-webkit-scrollbar-thumb {
 +  border-radius: 10px;
 +  background: rgba(128, 128, 128, 0.6);
 +}
 +
 +::-webkit-scrollbar-thumb:hover {
 +  background: rgba(128, 128, 128, 1);
 +}
 +
 +::-webkit-scrollbar-track {
 +  background: rgba(128, 128, 128, 0.15);
 +}
 +
 +* {
 +  scrollbar-width: initial;
 +}
 +
 +body {
 +  font: 16px/1.5 var(--body-font-family);
 +  font-weight: var(--body-font-weight);
 +  font-size: var(--body-font-size);
 +  margin: 0;
 +  padding: 0;
 +  position: relative;
 +
 +  -webkit-font-feature-settings: "kern", "liga";
 +  -moz-font-feature-settings: "kern", "liga";
 +  font-feature-settings: "kern", "liga";
 +  color: var(--text-color);
 +  background: var(--body-bg);
 +}
 +
 +h1, h2, h3, h4, h5, h6 {
 +  font-family: var(--heading-font-family);
 +  font-weight: var(--heading-weight);
 +  margin: 1.75em 0 0.75em 0;
 +  display: flex;
 +  align-items: center;
 +}
 +
 +h1 {
 +  font-size: calc(1.75em * var(--heading-font-scale));
 +}
 +
 +
 +header h1 {
 +  margin-top: 0;
 +}
 +
 +h2 {
 +  font-size: calc(1.4em * var(--heading-font-scale));
 +}
 +
 +h3 {
 +  font-size: calc(1.2em * var(--heading-font-scale));
 +}
 +
 +header h3 {
 +  color: var(--text-color-muted);
 +  margin-bottom: 0;
 +}
 +
 +h4, h5 {
 +  font-size: calc(1em * var(--heading-font-scale));
 +}
 +
 +h6 {
 +  font-size: calc(1em * var(--heading-small-font-scale));
 +  font-family: var(--heading-small-font-family);
 +  font-weight: var(--heading-small-weight);
 +}
 +
 +ol, ul {
 +  padding-left: 1rem;
 +}
 +
 +ul ul, ol ul, ul ol, ol ol {
 +  margin-bottom: .6em;
 +}
 +
 +p {
 +  margin: 0 0 .6em 0;
 +}
 +
 +a {
 +  color: var(--primary);
 +  text-decoration: none;
 +}
 +
 +a:hover {
 +  text-decoration: underline;
 +}
 +
 +summary {
 +  outline: none;
 +}
 +
 +blockquote {
 +  border-left: 3px solid var(--primary);
 +  background: var(--box-bg);
 +  padding: var(--box-padding);
 +  border-radius: var(--box-radius);
 +  margin: var(--box--margin);
 +}
 +
 +span.sep::after {
 +  content: "â–¸";
 +}
 +
 +span.sep {
 +  font-size: calc(0.5em * var(--monospace-font-size));
 +  opacity: 0.55;
 +  padding-left: .25em;
 +  padding-right: .25em;
 +}
 +
 +code,
 +pre {
 +  font-family: var(--monospace-font-family);
 +  font-size: var(--monospace-font-size);
 +  color: var(--box-text-color);
 +}
 +
 +pre {
 +  background: var(--box-bg);
 +  padding: var(--box-padding);
 +  border-radius: var(--box-radius);
 +  overflow: auto;
 +}
 +
 +code {
 +  background: var(--box-bg);
 +  padding: 0 0.35em;
 +  border-radius: 0.35rem;
 +  word-break: break-word;
 +}
 +
 +a > code {
 +  color: var(--primary);
 +}
 +
 +
 +pre pre,
 +pre code {
 +  padding: 0;
 +  margin: 0;
 +  font-size: 1em;
 +  background: none;
 +  color: inherit;
 +}
 +
 +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
 +  font-family: inherit;
 +  font-weight: inherit;
 +  font-size: 0.85em;
 +}
 +
 +strong, b {
 +  font-weight: 600;
 +}
 +
 +/* fix alignment of images on small screen */
 +img, svg {
 +    display: block;
 +    max-width: 100%;
 +    height: auto;
 +}
 +
 +svg .node polygon, svg .node path {
 +  transition: fill 150ms ease;
 +  fill: var(--box-bg);
 +  stroke: none;
 +}
 +
 +svg .node a {
 +  text-decoration: none !important;
 +}
 +
 +svg .node a text {
 +  fill: var(--text-color);
 +  font-family: var(--body-font-family);
 +}
 +
 +svg .node.link text {
 +  fill: var(--primary);
 +}
 +
 +svg .node.link:hover polygon, svg .node.link:hover path {
 +  fill: var(--sidebar-hover-bg);
 +}
 +svg .node.link:hover text {
 +  fill: var(--box-text-color);
 +}
 +svg .edge path {
 +  stroke: var(--text-color);
 +}
 +
 +/* fix unwanted margins in tables, code, lists and blockquotes */
 +li > *:first-child,
 +li > *:first-child > *:first-child,
 +li > *:first-child > *:first-child > *:first-child,
 +td > *:first-child,
 +td > *:first-child > *:first-child,
 +td > *:first-child > *:first-child > *:first-child,
 +pre > *:first-child,
 +pre > *:first-child > *:first-child,
 +pre > *:first-child > *:first-child > *:first-child,
 +blockquote > *:first-child,
 +blockquote > *:first-child > *:first-child,
 +blockquote > *:first-child > *:first-child > *:first-child {
 +  margin-top: 0;
 +}
 +li > *:last-child,
 +li > *:last-child > *:last-child,
 +li > *:last-child > *:last-child > *:last-child,
 +td > *:last-child,
 +td > *:last-child > *:last-child,
 +td > *:last-child > *:last-child > *:last-child,
 +pre > *:last-child,
 +pre > *:last-child > *:last-child,
 +pre > *:last-child > *:last-child > *:last-child,
 +blockquote > *:last-child,
 +blockquote > *:last-child > *:last-child,
 +blockquote > *:last-child > *:last-child > *:last-child {
 +  margin-bottom: 0;
 +}
 +
 +/*********************************
 + * PAGE STRUCTURE
 + *********************************/
 +#body-wrapper {
 +  display: flex;
 +  flex-wrap: nowrap;
 +  flex-direction: row;
 +}
 +
 +#body-wrapper:focus {
 +  outline: none;
 +}
 +
 +#main {
 +  position: relative;
 +  flex-grow: 1;
 +  min-width: 0;
 +  box-shadow: 0 0 134px rgba(0, 0, 0, 0.1);
 +}
 +
 +footer {
 +  width: 100%;
 +  display: none;
 +}
 +
 +/*********************************
 + * Button
 + *********************************/
 +
 +#btn-to-top {
 +  position: fixed;
 +  bottom: 12px;
 +  right: 32px;
 +  z-index: 1000;
 +  border-radius: 50%;
 +  width: 42px;
 +  height: 42px;
 +  border: 1px solid var(--primary);
 +  background: var(--box-bg);
 +  color: var(--text-color);
 +  cursor: pointer;
 +  text-transform: none;
 +}
 +
 +#btn-to-top > .up-arrow {
 +  margin-left: -2px;
 +}
 +
 +#btn-to-top > .up-arrow:after {
 +  content: url(go-up-symbolic.png);
 +}
 +
 +/*********************************
 + * SIDEBAR
 + *********************************/
 +.sidebar {
 +  scrollbar-width: thin;
 +  background: var(--sidebar-bg);
 +  border-right: 1px solid var(--sidebar-bg);
 +  min-width: 35ch;
 +  padding: var(--sidebar-padding);
 +  color: var(--sidebar-text-color);
 +  position: sticky;
 +  top: 0;
 +  z-index: 2;
 +  height: 100vh;
 +  overflow-y: auto;
 +}
 +
 +.sidebar a,
 +.sidebar a:hover {
 +  text-decoration: none;
 +}
 +
 +.sidebar .logo {
 +  display: block;
 +  margin: 1rem auto 1.2rem auto;
 +  width: 50%;
 +}
 +
 +.sidebar .section > ul > li {
 +  margin-right: -10px;
 +}
 +
 +.sidebar .section h3, .sidebar .section h5 {
 +  text-align: left;
 +  padding-left: 0.5rem;
 +  padding-right: 0.5rem;
 +  font-weight: var(--heading-weight);
 +}
 +
 +.sidebar .section h5 {
 +  font-size: 1em;
 +  margin-bottom: 0.5em;
 +}
 +
 +.sidebar .namespace > h3 {
 +  margin-bottom: 0;
 +  padding: 0;
 +  font-size: 1.5em;
 +  text-transform: uppercase;
 +  font-weight: 900;
 +}
 +
 +.sidebar .namespace > p {
 +  font-size: 0.9em;
 +  opacity: 0.8;
 +  padding-left: 0.5rem;
 +}
 +
 +.sidebar .section {
 +  padding-left: 0.5rem;
 +  padding-right: 0.5rem;
 +  font-size: 80%;
 +}
 +
 +.sidebar .links {
 +  margin-bottom: 1rem;
 +}
 +
 +.sidebar .section a {
 +  display: block;
 +  text-overflow: ellipsis;
 +  overflow: hidden;
 +  transition: background-color 150ms ease;
 +  color: var(--sidebar-primary);
 +  border-radius: var(--box-radius);
 +   padding: 0.2rem 0.5rem;
 +  margin-bottom: 0.15rem;
 +}
 +
 +.sidebar .section a:hover {
 +  background-color: var(--sidebar-hover-bg);
 +  color: var(--sidebar-text-color);
 +}
 +
 +.sidebar .section a.current {
 +  background-color: var(--sidebar-selected-bg);
 +  color: white;
 +}
 +
 +.sidebar .search {
 +  box-sizing: border-box;
 +  text-align: center;
 +}
 +
 +.sidebar .search input[type="text"] {
 +  border-color: transparent;
 +  width: 100%;
 +  border: 1px solid #ccc;
 +  border-radius: 50px;
 +  padding: 6px 12px;
 +  display: inline-block;
 +  font-size: 14px;
 +  box-shadow: inset 0 1px 3px #ddd;
 +  transition: border .3s linear;
 +}
 +
++.toc {
++  display: block;
++  margin-top: 2em;
++  z-index: 3;
++  min-width: 15ch;
++  font-size: 80%;
++}
++
++.toc nav {
++  margin-left: 2em;
++  margin-right: 2em;
++}
++
++#toc-title {
++  text-transform: uppercase;
++  font-weight: var(--heading-weight);
++}
++
++.toc-list {
++  list-style-type: none;
++  margin: 0;
++  padding-left: 0;
++}
++
++.toc-list-item {
++  padding-top: .25em;
++}
++
 +/*********************************
 + * ANCHORS & TOGGLERS
 + *********************************/
 +.anchor,
 +.md-anchor {
 +  position: relative;
 +  z-index: 1;
 +  text-decoration: none;
 +  padding: 0 0.5em;
 +  color: var(--text-color-muted);
 +}
 +
 +.anchor:hover,
 +.md-anchor:hover {
 +  color: var(--primary);
 +}
 +
 +.anchor:not([href]),
 +.md-anchor:not([href]) {
 +  display: none;
 +}
 +
 +.anchor:before,
 +.md-anchor:before {
 +  content: var(--anchor-sign); /*'§'*/
 +}
 +
 +.toggle-wrapper {
 +  position: relative;
 +}
 +
 +.collapse-toggle {
 +  position: absolute;
 +  right: 0;
 +  left: -2em;
 +  white-space: nowrap;
 +  text-decoration: none;
 +  font-size: 0.8em;
 +  color: transparent;
 +}
 +
 +.collapse-toggle > .inner {
 +  width: 1rem;
 +  height: 1rem;
 +  border-radius: calc(0.75 * var(--box-radius));
 +  display: inline-flex;
 +  justify-content: center;
 +  align-items: center;
 +  text-align: center;
 +  vertical-align: middle;
 +  color: var(--box-text-color);
 +  position: relative;
 +  left: -0.25rem;
 +  font-family: monospace;
 +  font-size: 0.7rem;
 +  font-weight: bold;
 +  background: var(--box-bg);
 +}
 +
 +/*********************************
 + * UTILITY
 + *********************************/
 +.deprecated > h6 > a {
 +  opacity: 0.65;
 +}
 +
 +.hidden {
 +  display: none !important;
 +}
 +
 +/*********************************
 + * CONTENT STYLING
 + *********************************/
 +.content {
 +  padding: 2em 4em;
 +  overflow: visible;
 +  max-width: calc(var(--prefered-content-width) + 8em);
 +}
 +
 +.content table:not(.table-display) {
 +  border-spacing: 0 0.25rem;
 +}
 +
 +.content td {
 +  vertical-align: top;
 +}
 +
 +.content td:first-child {
 +  padding-right: 1rem;
 +}
 +
 +.content td p:first-child {
 +  margin-top: 0;
 +}
 +
 +.content td h1, .content td h2 {
 +  margin-left: 0;
 +  font-size: 1.1em;
 +}
 +
 +.content tr:first-child td {
 +  border-top: 0;
 +}
 +
 +kbd {
 +  display: inline-block;
 +  padding: 3px 5px;
 +  font: 15px monospace;
 +  line-height: 10px;
 +  vertical-align: middle;
 +  border: solid 1px;
 +  border-radius: 3px;
 +  box-shadow: inset 0 -1px 0;
 +  cursor: default;
 +}
 +
 +.content tr:first-child {
 +  border-bottom: 1px solid rgba(0, 0, 0, 0.35);
 +}
 +
 +.content td {
 +  vertical-align: top;
 +}
 +
 +.content td:first-child {
 +  padding-right: 1rem;
 +}
 +
 +.content td p:first-child {
 +  margin-top: 0;
 +}
 +
 +.content td h4, .content td h5 {
 +  margin-left: 0;
 +  font-size: 1.1em;
 +}
 +
 +.content tr:first-child td {
 +  border-top: 0;
 +}
 +
 +.srclink {
 +  color: var(--text-color-muted);
 +  font-size: 1rem;
 +  font-weight: var(--body-font-weight);
 +  flex-grow: 0;
 +  text-decoration: none;
 +  margin-left: auto;
 +  position: relative;
 +  z-index: 1;
 +}
 +
 +.meta tr > td:not(:first-child) {
 +  width: 100%;
 +}
 +
 +.meta tr > td:first-child {
 +  white-space: nowrap;
 +}
 +
 +/*********************************
 + * DOCBLOCK STYLING
 + *********************************/
 +.docblock {
 +  position: relative;
 +  text-align: left;
 +}
 +
 +.docblock h1 {
 +  font-size: calc(1.3em * var(--heading-docblock-scale) * var(--heading-font-scale));
 +}
 +
 +.docblock h2 {
 +  font-size: calc(1.2em * var(--heading-docblock-scale) * var(--heading-font-scale));
 +}
 +
 +.docblock h3 {
 +  font-size: calc(1.1em * var(--heading-docblock-scale) * var(--heading-font-scale));
 +}
 +
 +.docblock h4 {
 +  font-size: calc(1.05em * var(--heading-docblock-scale) * var(--heading-font-scale));
 +}
 +
 +.docblock h1,
 +.docblock h2,
 +.docblock h3,
 +.docblock h4,
 +.docblock h5,
 +.docblock h6 {
 +  color: var(--heading-docblock-color)
 +}
 +
 +.docblock table {
 +  margin: .25em 0;
 +  max-width: 100%;
 +  font-size: var(--table-font-size);
 +}
 +
 +.docblock table td {
 +  padding: .25em;
 +}
 +
 +.docblock table th {
 +  padding: .25em;
 +  text-align: left;
 +  font-family: var(--heading-table-font-family);
 +  font-weight: var(--heading-table-weight);
 +}
 +
 +.docblock table tr th:first-child,
 +.docblock table tr td:first-child {
 +  padding-left: 0;
 +}
 +
 +.docblock table tr th:last-child,
 +.docblock table tr td:last-child {
 +  padding-right: 0;
 +}
 +
 +table.enum-members,
 +table.results {
 +  border-radius: var(--box-radius);
 +  border: 1px solid var(--text-color-muted);
 +  border-spacing: 0 0 !important;
 +  font-size: 80%;
 +}
 +
 +table.enum-members tr th,
 +table.results tr th {
 +  border-top-color: var(--body-bg);
 +  background-color: var(--box-bg);
 +  border-bottom: 1px solid var(--text-color-muted);
 +}
 +
 +table.enum-members tr th:first-child,
 +table.enum-members tr td:first-child {
 +  min-width: 25em;
 +  padding-left: .5em;
 +}
 +
 +table.results tr th:first-child,
 +table.results tr td:first-child {
 +  padding-left: .5em;
 +}
 +
 +table.enum-members tr th:last-child,
 +table.enum-members tr td:last-child,
 +table.results tr th:last-child,
 +table.results tr td:last-child {
 +  max-width: 35em;
 +  padding-right: .5em;
 +}
 +
 +table.results tr td code {
 +  font-size: 100%;
 +}
 +
 +table.arguments tr td,
 +table.returns tr td {
 +  color: var(--text-color-muted);
 +}
 +
 +table.arguments tr td:first-child,
 +table.returns tr td:first-child {
 +  min-width: 12em;
 +}
 +
 +table.arguments tr.arg-name td,
 +table.arguments tr.arg-description td,
 +table.returns tr.arg-name td,
 +table.returns tr.arg-description td {
 +  color: var(--text-color);
 +}
 +
 +.docblock ul li,
 +.docblock ol li {
 +  padding-top: 0.15rem;
 +  padding-bottom: 0.15rem;
 +}
 +
 +.docblock ul.type {
 +  list-style: none;
 +}
 +
 +.docblock ul.type li::before {
 +  content: "»";
 +  color: var(--text-color);
 +  display: inline-block;
 +  width: 1em;
 +  margin-left: -1em;
 +}
 +
 +.docblock .codehilite {
 +  position: relative;
 +}
 +.docblock .codehilite > .copy-button {
 +  position: absolute;
 +  top: 0;
 +  right: 0;
 +
 +  border: none;
 +  background: none;
 +
 +  margin: var(--box-padding);
 +  cursor: pointer;
 +}
 +
 +.docblock .codehilite > .copy-button {
 +  transition: background-color 150ms ease;
 +  color: var(--primary);
 +  border-radius: var(--box-radius);
 +  padding: 0.2rem 0.5rem;
 +  margin: var(--box-padding);
 +}
 +
 +.docblock .codehilite > .copy-button:hover {
 +  background-color: var(--sidebar-hover-bg);
 +  color: var(--text-color);
 +}
 +
 +.docblock .codehilite > .copy-button:active {
 +  background-color: var(--primary);
 +}
 +
 +
 +/*************************************************************
 + SYMBOLS
 +**************************************************************/
 +.symbol,
 +.constructors h6,
 +.methods h6,
 +.signals h6,
 +.properties h6,
 +.type-funcs h6,
 +.implements a,
 +.ancestors a,
++.descendants a,
++.implementations a,
 +.sidebar .links a
++.toc a
 +{
 +  font-family: var(--symbol-font-family);
 +  font-size: calc(1em * var(--symbol-font-scale));
 +  font-weight: var(--symbol-font-weight);
 +}
 +
 +/**************************
 + RESPONSIVENESS
 +**************************/
 +@media (max-width: 700px) {
 +  body {
 +    padding-top: 0px;
 +  }
 +
 +  #body-wrapper {
 +    flex-direction: column;
 +    overflow: hidden;
 +  }
 +
 +  #main {
 +    width: 100%;
 +    padding: 2rem;
 +  }
 +
 +  .sidebar {
 +    position: static;
 +    height: initial;
 +    order: 1;
 +  }
++
++  .toc {
++    display: hidden;
++  }
 +}
index babde7a85c30b8497fc719a8d950ef3b62dfad27,0000000000000000000000000000000000000000..aadadfb958eb785314c9f7d33ae47b086dbc3d2f
mode 100644,000000..100644
--- /dev/null
@@@ -1,184 -1,0 +1,185 @@@
 +<!--
 +SPDX-FileCopyrightText: 2021 GNOME Foundation
 +
 +SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +-->
 +
 +{% extends "base.html" %}
 +
 +{% block title %}{{ namespace.name }}.{{ class.name }}.{{ type_func.name }}{% endblock %}
 +
 +{% block meta_other %}
 +  <meta property="og:title" content="{{ namespace.name }}.{{ class.name }}.{{ type_func.name }}"/>
 +  <meta property="og:description" content="Reference for {{ namespace.name }}.{{ class.name }}.{{ type_func.name }}"/>
 +  <meta name="twitter:title" content="{{ namespace.name }}.{{ class.name }}.{{ type_func.name }}"/>
 +  <meta name="twitter:description" content="Reference for {{ namespace.name }}.{{ class.name }}.{{ type_func.name }}"/>
 +{% endblock %}
 +
 +{% block sidebar %}
 +<div class="section">
 +  <h5>Type</h5>
 +  <div class="links">
 +    <a href="{{ class.link_prefix }}.{{ class.name }}.html">{{ class.name }}</a>
 +  </div>
 +</div>
 +<div class="section">
 +  <h5>Functions</h5>
 +  <div class="links">
 +  {% for m in class.type_funcs %}
 +    <a class="method{% if type_func.name == m.name %} current{% endif %}" href="type_func.{{ class.name }}.{{ m.name }}.html">{{ m.name }}</a>
 +  {% endfor %}
 +  </div>
 +</div>
 +{% endblock %}
 +
 +{% block content %}
 +<section id="main" class="content">
 +  <header>
 +    <h3>Function</h3>
 +    <h1><a href="index.html">{{ namespace.name }}</a><span class="sep"></span><a href="{{ class.link_prefix }}.{{class.name}}.html">{{ class.name }}</a><span class="sep"></span>{{ type_func.name }}</h1>
 +  </header>
 +
 +  <section>
 +    <div class="declaration toggle-wrapper">
 +      <h4 id="declaration" style="display:flex;">
 +        Declaration
 +        <a href="#declaration" class="anchor"></a>
 +        {% if CONFIG.source_location_url and type_func.source_location %}
 +        <a class="srclink" title="go to source location" href="{{ CONFIG.source_link(type_func.source_location) }}">[src]</a>
 +        {% endif %}
 +      </h4>
 +
 +      <div class="docblock">
 +        <pre><code>{{ type_func.c_decl }}</code></pre>
 +      </div>
 +    </div>
 +
 +    <div class="description toggle-wrapper">
 +      <h4 id="description" style="display:flex;">
 +        Description
 +        <a href="#description" class="anchor"></a>
 +        {% if CONFIG.source_location_url and type_func.docs_location %}
 +        <a class="srclink" title="go to source location" href="{{ CONFIG.source_link(type_func.docs_location) }}">[src]</a>
 +        {% endif %}
 +      </h4>
 +
 +      <div class="docblock">
 +        {{ type_func.description }}
 +      </div>
 +
 +      <div class="docblock">
 +        <table>
 +          {% if type_func.stability %}
 +          <tr><td>Stability:</td><td>{{ type_func.stability }}</td></tr>
 +          {% endif %}
 +          {% if type_func.available_since %}
 +          <tr><td>Available since:</td><td>{{ type_func.available_since }}</td></tr>
 +          {% endif %}
 +          {% if type_func.deprecated_since %}
 +          <tr><td>Deprecated since:</td><td>{{ type_func.deprecated_since.version }}</td></tr>
 +          <tr><td colspan="2">{{ type_func.deprecated_since.message }}</td></tr>
 +          {% endif %}
 +        </table>
 +      </div>
 +
 +      {% if type_func.attributes %}
 +      <div class="docblock">
 +        <table>
 +        {% for (key, value) in type_func.attributes.items() %}
 +          <tr><td>{{ key|escape }}</td><td>{{ value|escape }}</td></tr>
 +        {% endfor %}
 +        </table>
 +      </div>
 +      {% endif %}
 +    </div>
 +
 +    {% if type_func.arguments|length != 0 %}
 +    <div class="parameters toggle-wrapper">
 +      <h4 id="parameters">
 +        Parameters
 +        <a href="#parameters" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +        <table class="arguments">
 +          {% for arg in type_func.arguments %}
 +          <tr class="arg-name">
 +            <td><code>{{ arg.name }}</code></td>
 +            <td>
 +            {%- if arg.is_array -%}An array of&nbsp;{%- endif -%}
 +            {%- if arg.is_list -%}A list of&nbsp;{%- endif -%}
 +            {%- if arg.link -%}
 +            {{ arg.link|safe }}
 +            {%- else -%}
 +            <code>{{ arg.type_cname }}</code>
 +            {%- endif -%}
 +            </td>
 +          </tr>
 +          <tr class="arg-description">
 +            <td>&nbsp;</td>
 +            <td>{{ arg.description|safe }}</td>
 +          </tr>
 +          {% if arg.direction != "in" %}<tr><td>&nbsp;</td><td title="direction: {{ arg.direction}}">{{ arg.direction_note }}</td></tr>{% endif %}
 +          {% if arg.direction == "in" and arg.is_pointer and arg.nullable %}<tr><td>&nbsp;</td><td>The argument can be <code>NULL</code>.</td></tr>{% endif %}
 +          {% if arg.direction == "out" and arg.is_pointer and arg.nullable %}<tr><td>&nbsp;</td><td>The argument can be set to <code>NULL</code>.</td></tr>{% endif %}
 +          {% if arg.optional %}<tr><td>&nbsp;</td><td>The argument can be <code>NULL</code>.</td></tr>{% endif %}
 +          {% if arg.is_array and arg.zero_terminated %}<tr><td>&nbsp;</td><td>The array must be <code>NULL</code>-terminated.</td></tr>{% endif %}
 +          {% if arg.is_array and arg.fixed_size > 0 %}<tr><td>&nbsp;</td><td>The array must have {{ arg.fixed_size }} elements.</td></tr>{% endif %}
 +          {% if arg.is_array and arg.len_arg %}<tr><td>&nbsp;</td><td>The length of the array is specified in the <code>{{ arg.len_arg }}</code> argument.</td></tr>{% endif %}
 +          {% if arg.is_pointer %}<tr><td>&nbsp;</td><td title="transfer: {{ arg.transfer }}">{{ arg.transfer_note }}</td></tr>{% endif %}
 +          {% if arg.string_note %}<tr><td>&nbsp;</td><td>{{ arg.string_note }}</td></tr>{% endif %}
 +          {% endfor %}
 +          {% if type_func.throws %}
 +          <tr class="arg-name">
 +            <td><code>error</code></td>
 +            <td><code>GError **</code></td>
 +          </tr>
 +          <tr class="arg-description">
 +            <td>&nbsp;</td>
 +            <td>The return location for a <code>GError*</code>, or <code>NULL</code>.</td>
 +          </tr>
 +          {% endif %}
 +        </table>
 +      </div>
 +    </div>
 +    {% endif %}
 +
 +    {% if type_func.return_value %}
 +    <div class="return-value toggle-wrapper">
 +      <h4 id="return-value">
 +        Return value
 +        <a href="#return-value" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +        <table class="returns">
 +          <tr class="arg-name">
 +            <td>Returns:</td>
 +            <td>
 +            {%- if type_func.return_value.is_array -%}An array of&nbsp;{%- endif -%}
 +            {%- if type_func.return_value.is_list -%}A list of&nbsp;{%- endif -%}
++            {%- if type_func.return_value.is_list_model -%}A list model of&nbsp;{%- endif -%}
 +            {%- if type_func.return_value.link -%}
 +            {{ type_func.return_value.link|safe }}
 +            {%- else -%}
 +            <code>{{ type_func.return_value.type_cname }}</code>
 +            {%- endif -%}
 +            </td>
 +          </tr>
 +          <tr class="arg-description">
 +            <td>&nbsp;</td>
 +            <td>{{ type_func.return_value.description|safe }}</td>
 +          </tr>
 +          {% if type_func.return_value.is_array and type_func.return_value.zero_terminated %}<tr><td>&nbsp;</td><td>The array is <code>NULL</code>-terminated.</td></tr>{% endif %}
 +          {% if type_func.return_value.is_array and type_func.return_value.fixed_size > 0 %}<tr><td>&nbsp;</td><td>The array has {{ type_func.return_value.fixed_size }} elements.</td></tr>{% endif %}
 +          {% if type_func.return_value.is_array and type_func.return_value.len_arg %}<tr><td>&nbsp;</td><td>The length of the array is in the <code>{{ type_func.return_value.len_arg }}</code> argument.</td></tr>{% endif %}
 +          {% if type_func.return_value.is_pointer %}<tr><td>&nbsp;</td><td title="transfer: {{ type_func.return_value.transfer }}">{{ type_func.return_value.transfer_note }}</td></tr>{% endif %}
 +          {% if type_func.return_value.is_pointer and type_func.return_value.nullable %}<tr><td>&nbsp;</td><td>The return value can be <code>NULL</code>.</td></tr>{% endif %}
 +          {% if type_func.return_value.string_note %}<tr><td>&nbsp;</td><td>{{ type_func.return_value.string_note }}</td></tr>{% endif %}
 +        </table>
 +      </div>
 +    </div>
 +    {% endif %}
 +  </section>
 +</section>
 +{% endblock %}
index ef48af93ee38f5103ce45eba6b8ab89533d062ae,0000000000000000000000000000000000000000..b62c08a8c8f8d6545636d052e590ee22498c3348
mode 100644,000000..100644
--- /dev/null
@@@ -1,185 -1,0 +1,186 @@@
 +<!--
 +SPDX-FileCopyrightText: 2021 GNOME Foundation
 +
 +SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +-->
 +
 +{% extends "base.html" %}
 +
 +{% block title %}{{ namespace.name }}.{{ class.name }}.{{ vfunc.name }}{% endblock %}
 +
 +{% block meta_other %}
 +  <meta property="og:title" content="{{ namespace.name }}.{{ class.name }}.{{ vfunc.name }}"/>
 +  <meta property="og:description" content="Reference for {{ namespace.name }}.{{ class.name }}.{{ vfunc.name }}"/>
 +  <meta name="twitter:title" content="{{ namespace.name }}.{{ class.name }}.{{ vfunc.name }}"/>
 +  <meta name="twitter:description" content="Reference for {{ namespace.name }}.{{ class.name }}.{{ vfunc.name }}"/>
 +{% endblock %}
 +
 +{% block sidebar %}
 +<div class="section">
 +  <h5>Type</h5>
 +  <div class="links">
 +    <a href="{{ class.link_prefix }}.{{ class.name }}.html">{{ class.name }}</a>
 +  </div>
 +</div>
 +<div class="section">
 +  <h5>Virtual methods</h5>
 +  <div class="links">
 +  {% for m in class.virtual_methods %}
 +    <a class="method{% if vfunc.name == m.name %} current{% endif %}" href="vfunc.{{ class.name }}.{{ m.name }}.html">{{ m.name }}</a>
 +  {% endfor %}
 +  </div>
 +</div>
 +{% endblock %}
 +
 +{% block content %}
 +<section id="main" class="content">
 +  <header>
 +    <h3>Virtual Method</h3>
 +    <h1><a href="index.html">{{ namespace.name }}</a><span class="sep"></span><a href="{{ class.link_prefix }}.{{ class.name }}.html">{{ class.name }}</a><span class="sep"></span>{{ vfunc.name }}</h1>
 +  </header>
 +
 +  <section>
 +    <div class="declaration toggle-wrapper">
 +      <h4 id="declaration">
 +        Declaration
 +        <a href="#declaration" class="anchor"></a>
 +        {% if CONFIG.source_location_url and vfunc.source_location %}
 +        <a class="srclink" title="go to source location" href="{{ CONFIG.source_link(vfunc.source_location) }}">[src]</a>
 +        {% endif %}
 +      </h4>
 +
 +      <div class="docblock c-decl">
 +        <pre><code>{{ vfunc.c_decl }}</code></pre>
 +      </div>
 +    </div>
 +
 +    <div class="description toggle-wrapper">
 +      <h4 id="description">
 +        Description
 +        <a href="#description" class="anchor"></a>
 +        {% if CONFIG.source_location_url and vfunc.docs_location %}
 +        <a class="srclink" title="go to source location" href="{{ CONFIG.source_link(vfunc.docs_location) }}">[src]</a>
 +        {% endif %}
 +      </h4>
 +
 +      <div class="docblock">
 +        {{ vfunc.description }}
 +      </div>
 +
 +      <div class="docblock">
 +        <table>
 +          {% if vfunc.stability %}
 +          <tr><td>Stability:</td><td>{{ vfunc.stability }}</td></tr>
 +          {% endif %}
 +          {% if vfunc.available_since %}
 +          <tr><td>Available since:</td><td>{{ vfunc.available_since }}</td></tr>
 +          {% endif %}
 +          {% if vfunc.deprecated_since %}
 +          <tr><td>Deprecated since:</td><td>{{ vfunc.deprecated_since.version }}</td></tr>
 +          <tr><td colspan="2">{{ vfunc.deprecated_since.message }}</td></tr>
 +          {% endif %}
 +        </table>
 +      </div>
 +
 +      {% if vfunc.attributes %}
 +      <div class="docblock">
 +        <table>
 +        {% for (key, value) in vfunc.attributes.items() %}
 +          <tr><td>{{ key|escape }}</td><td>{{ value|escape }}</td></tr>
 +        {% endfor %}
 +        </table>
 +      </div>
 +      {% endif %}
 +    </div>
 +
 +    {% if vfunc.arguments|length != 0 %}
 +    <div class="parameters toggle-wrapper">
 +      <h4 id="parameters">
 +        Parameters
 +        <a href="#parameters" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +        <table class="arguments">
 +          {% for arg in vfunc.arguments %}
 +          <tr class="arg-name">
 +            <td><code>{{ arg.name }}</code></td>
 +            <td>
 +            {%- if arg.is_array -%}An array of&nbsp;{%- endif -%}
 +            {%- if arg.is_list -%}A list of&nbsp;{%- endif -%}
 +            {%- if arg.link -%}
 +            {{ arg.link|safe }}
 +            {%- else -%}
 +            <code>{{ arg.type_cname }}</code>
 +            {%- endif -%}
 +            </td>
 +          </tr>
 +          <tr class="arg-description">
 +            <td>&nbsp;</td>
 +            <td>{{ arg.description|safe }}</td>
 +          </tr>
 +          {% if arg.direction != "in" %}<tr><td>&nbsp;</td><td title="direction: {{ arg.direction}}">{{ arg.direction_note }}</td></tr>{% endif %}
 +          {% if arg.direction == "in" and arg.is_pointer and arg.nullable %}<tr><td>&nbsp;</td><td>The argument can be <code>NULL</code>.</td></tr>{% endif %}
 +          {% if arg.direction == "out" and arg.is_pointer and arg.nullable %}<tr><td>&nbsp;</td><td>The argument can be set to <code>NULL</code>.</td></tr>{% endif %}
 +          {% if arg.optional %}<tr><td>&nbsp;</td><td>The argument can be <code>NULL</code>.</td></tr>{% endif %}
 +          {% if arg.is_array and arg.zero_terminated %}<tr><td>&nbsp;</td><td>The array must be <code>NULL</code>-terminated.</td></tr>{% endif %}
 +          {% if arg.is_array and arg.fixed_size > 0 %}<tr><td>&nbsp;</td><td>The array must have {{ arg.fixed_size }} elements.</td></tr>{% endif %}
 +          {% if arg.is_array and arg.len_arg %}<tr><td>&nbsp;</td><td>The length of the array is specified in the <code>{{ arg.len_arg }}</code> argument.</td></tr>{% endif %}
 +          {% if arg.is_pointer %}<tr><td>&nbsp;</td><td title="transfer: {{ arg.transfer }}">{{ arg.transfer_note }}</td></tr>{% endif %}
 +          {% if arg.string_note %}<tr><td>&nbsp;</td><td>{{ arg.string_note }}</td></tr>{% endif %}
 +          {% endfor %}
 +          {% if vfunc.throws %}
 +          <tr class="arg-name">
 +            <td><code>error</code></td>
 +            <td><code>GError **</code></td>
 +          </tr>
 +          <tr class="arg-description">
 +            <td>&nbsp;</td>
 +            <td>The return location for a <code>GError*</code>, or <code>NULL</code>.</td>
 +          </tr>
 +          {% endif %}
 +        </table>
 +      </div>
 +    </div>
 +    {% endif %}
 +
 +    {% if vfunc.return_value %}
 +    <div class="return-value toggle-wrapper">
 +      <h4 id="return-value">
 +        Return value
 +        <a href="#return-value" class="anchor"></a>
 +      </h4>
 +
 +      <div class="docblock">
 +        <table class="returns">
 +          <tr class="arg-name">
 +            <td>Returns:</td>
 +            <td>
 +            {%- if vfunc.return_value.is_array -%}An array of&nbsp;{%- endif -%}
 +            {%- if vfunc.return_value.is_list -%}A list of&nbsp;{%- endif -%}
++            {%- if vfunc.return_value.is_list_model -%}A list model of&nbsp;{%- endif -%}
 +            {%- if vfunc.return_value.link -%}
 +            {{ vfunc.return_value.link|safe }}
 +            {%- else -%}
 +            <code>{{ vfunc.return_value.type_cname }}</code>
 +            {%- endif -%}
 +            </td>
 +          </tr>
 +          <tr class="arg-description">
 +            <td>&nbsp;</td>
 +            <td>{{ vfunc.return_value.description|safe }}</td>
 +          </tr>
 +          {% if vfunc.return_value.is_array and vfunc.return_value.zero_terminated %}<tr><td>&nbsp;</td><td>The array is <code>NULL</code>-terminated.</td></tr>{% endif %}
 +          {% if vfunc.return_value.is_array and vfunc.return_value.fixed_size > 0 %}<tr><td>&nbsp;</td><td>The array has {{ vfunc.return_value.fixed_size }} elements.</td></tr>{% endif %}
 +          {% if vfunc.return_value.is_array and vfunc.return_value.len_arg %}<tr><td>&nbsp;</td><td>The length of the array is in the <code>{{ vfunc.return_value.len_arg }}</code> argument.</td></tr>{% endif %}
 +          {% if vfunc.return_value.is_pointer %}<tr><td>&nbsp;</td><td title="transfer: {{ vfunc.return_value.transfer }}">{{ vfunc.return_value.transfer_note }}</td></tr>{% endif %}
 +          {% if vfunc.return_value.is_pointer and vfunc.return_value.nullable %}<tr><td>&nbsp;</td><td>The return value can be <code>NULL</code>.</td></tr>{% endif %}
 +          {% if vfunc.return_value.string_note %}<tr><td>&nbsp;</td><td>{{ vfunc.return_value.string_note }}</td></tr>{% endif %}
 +        </table>
 +      </div>
 +    </div>
 +    {% endif %}
 +
 +  </section>
 +</section>
 +{% endblock %}
index c32eeccb8db6cc83192ebd7cfb11ebcb4f1a159d,0000000000000000000000000000000000000000..e2ed0f3a2b4dd5e4f0da285497b04c66df775f95
mode 100644,000000..100644
--- /dev/null
@@@ -1,870 -1,0 +1,894 @@@
-         t = self._namespace.find_symbol(self._endpoint)
 +# SPDX-FileCopyrightText: 2021 GNOME Foundation
 +# SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +
 +import markdown
 +import os
 +import re
 +import subprocess
 +import sys
 +
 +from markupsafe import Markup
 +from pygments import highlight
 +from pygments.lexers import get_lexer_by_name
 +from pygments.formatters import HtmlFormatter
 +from typogrify.filters import typogrify
 +
 +from . import gir, log, mdext, porter
 +
 +
 +# The beginning of a gtk-doc code block:
 +#
 +# |[ (optional language identifier)
 +#
 +CODEBLOCK_START_RE = re.compile(
 +    r'''
 +    ^
 +    \s*
 +    \|\[
 +    \s*
 +    (?P<language>\<\!-- \s* language="\w+" \s* --\>)?
 +    \s*
 +    $
 +    ''',
 +    re.UNICODE | re.VERBOSE)
 +
 +# The optional language identifier for a gtk-doc code block:
 +#
 +# <!-- language="..." -->
 +#
 +LANGUAGE_RE = re.compile(
 +    r'''
 +    ^
 +    \s*
 +    <!--
 +    \s*
 +    language="(?P<language>\w+)"
 +    \s*
 +    -->
 +    \s*
 +    $
 +    ''',
 +    re.UNICODE | re.VERBOSE)
 +
 +# The ending of a gtk-doc code block:
 +#
 +# ]|
 +#
 +CODEBLOCK_END_RE = re.compile(
 +    r'''
 +    ^
 +    \s*
 +    \]\|
 +    \s*
 +    $
 +    ''',
 +    re.UNICODE | re.VERBOSE)
 +
 +LINK_RE = re.compile(
 +    r'''
++    (?P<text>\[ [\w\s,\-_:]+ \])?
 +    \[
 +    (`)?
 +    (?P<fragment>[\w]+)
 +    @
 +    (?P<endpoint>[\w\-_:\.]+)
 +    (`)?
 +    \]
 +    ''',
 +    re.VERBOSE)
 +
 +TYPE_RE = re.compile(
 +    r'''
 +    (?P<ns>[\w]+\.)?            # namespace (optional)
 +    (?P<name>[\w]+)             # type name
 +    ''',
 +    re.VERBOSE)
 +
 +PROPERTY_RE = re.compile(
 +    r'''
 +    (?P<ns>[\w]+\.)?            # namespace (optional)
 +    (?P<name>[\w]+)             # type name
 +    :{1}                        # delimiter
 +    (?P<property>[\w-]*\w)      # property name
 +    ''',
 +    re.VERBOSE)
 +
 +SIGNAL_RE = re.compile(
 +    r'''
 +    (?P<ns>[\w]+\.)?            # namespace (optional)
 +    (?P<name>[\w]+)             # type name
 +    :{2}                        # delimiter
 +    (?P<signal>[\w-]*\w)        # signal name
 +    ''',
 +    re.VERBOSE)
 +
 +METHOD_RE = re.compile(
 +    r'''
 +    (?P<ns>[\w]+\.)?            # namespace (optional)
 +    (?P<name>[\w]+)             # type name
 +    \.                          # delimiter
 +    (?P<method>[\w_]*\w)        # method name
 +    ''',
 +    re.VERBOSE)
 +
 +CAMEL_CASE_START_RE = re.compile(r"([A-Z]+)([A-Z][a-z])")
 +
 +CAMEL_CASE_CHUNK_RE = re.compile(r"([a-z\d])([A-Z])")
 +
 +LANGUAGE_MAP = {
 +    'c': 'c',
 +    'css': 'css',
 +    'plain': 'plain',
 +    'xml': 'xml',
++    'javascript': 'javascript',
 +}
 +
 +MD_EXTENSIONS = [
 +    # Standard extensions
 +    'codehilite',
 +    'def_list',
 +    'fenced_code',
 +    'meta',
 +    'tables',
 +    'toc',
 +
 +    # Local extensions
 +    mdext.GtkDocExtension(),
 +]
 +
 +MD_EXTENSIONS_CONF = {
 +    'codehilite': {'guess_lang': False},
 +    'toc': {'permalink_class': 'md-anchor', 'permalink': ''},
 +}
 +
 +EN_STOPWORDS = set("""
 +a  and  are  as  at
 +be  but  by
 +for
 +if  in  into  is  it
 +near  no  not
 +of  on  or
 +such
 +that  the  their  then  there  these  they  this  to
 +was  will  with
 +""".split())
 +
 +
 +def process_language(lang):
 +    if lang is None:
 +        return "plain"
 +
 +    res = LANGUAGE_RE.match(lang)
 +    if res:
 +        language = res.group("language") or "plain"
 +    else:
 +        language = "plain"
 +
 +    return LANGUAGE_MAP[language.lower()]
 +
 +
 +class LinkParseError:
 +    def __init__(self, line=None, start=0, end=0, fragment=None, rest=None, message="Unable to parse link"):
 +        self.line = line
 +        self.start = start
 +        self.end = end
 +        self.fragment = fragment
 +        self.rest = rest
 +        self.message = message
 +
 +    def __str__(self):
 +        if self.line is not None:
 +            msg = [self.message]
 +            msg.append(self.line)
 +            err_line = ['^'.rjust(self.start + 1, ' ')]
 +            err_line += [''.join(['~' for x in range(self.end - self.start - 1)])]
 +            msg.append("".join(err_line))
 +            return "\n".join(msg)
 +        else:
 +            return f"{self.message}: [{self.fragment}@{self.rest}]"
 +
 +
 +class LinkGenerator:
 +    def __init__(self, **kwargs):
 +        self._line = kwargs.get('line')
 +        self._start = kwargs.get('start', 0)
 +        self._end = kwargs.get('end', 0)
 +        self._namespace = kwargs.get('namespace')
 +        self._fragment = kwargs.get('fragment', '')
 +        self._endpoint = kwargs.get('endpoint', '')
 +        self._no_link = kwargs.get('no_link', False)
++        self._alt_text = kwargs.get('text')
 +
 +        assert self._namespace is not None
 +
 +        self._repository = self._namespace.repository
 +        self._valid_namespaces = [n for n in self._repository.includes]
 +        self._external = False
 +
 +        fragment_parsers = {
 +            "alias": self._parse_type,
 +            "callback": self._parse_type,
 +            "class": self._parse_type,
 +            "const": self._parse_type,
 +            "ctor": self._parse_method,
 +            "enum": self._parse_type,
 +            "error": self._parse_type,
 +            "flags": self._parse_type,
 +            "func": self._parse_func,
 +            "id": self._parse_id,
 +            "iface": self._parse_type,
 +            "method": self._parse_method,
 +            "property": self._parse_property,
 +            "signal": self._parse_signal,
 +            "struct": self._parse_type,
 +            "type": self._parse_type,
 +            "vfunc": self._parse_method,
 +        }
 +
 +        parser_method = fragment_parsers.get(self._fragment)
 +        if parser_method is not None:
 +            res = parser_method(self._fragment)
 +            if res is not None:
 +                self._fragment = None
 +                log.warning(str(res))
 +        else:
 +            self._fragment = None
 +            log.warning(str(LinkParseError(self._line, self._start, self._end,
 +                                           self._fragment, self._endpoint,
 +                                           "Unable to parse link")))
 +
 +    def _parse_id(self, fragment):
-             self._method_name = self._endpoint.replace(self._namespace.symbol_prefix[0] + '_', '')
++        symbol = self._repository.find_symbol(self._endpoint)
++        if symbol is None:
++            return LinkParseError(self._line, self._start, self._end,
++                                  self._fragment, self._endpoint,
++                                  f"Unable to find symbol {self._endpoint}")
++        (ns, t) = symbol
 +        if isinstance(t, gir.Class) or \
 +           isinstance(t, gir.Interface) or \
 +           isinstance(t, gir.Record):
++            self._external = ns is not self._namespace
++            self._ns = ns.name
 +            self._fragment = 'method'
 +            self._symbol_name = f"{self._endpoint}()"
 +            self._name = t.name
-             self._func_name = self._endpoint.replace(self._namespace.symbol_prefix[0] + '_', '')
++            self._method_name = self._endpoint.replace(ns.symbol_prefix[0] + '_', '')
 +            self._method_name = self._method_name.replace(t.symbol_prefix + '_', '')
 +            return None
 +        elif isinstance(t, gir.Function):
++            self._external = ns is not self._namespace
++            self._ns = ns.name
 +            self._fragment = 'func'
 +            self._symbol_name = f"{self._endpoint}()"
 +            self._name = None
-                                   f"Unable to find symbol {self._endpoint}")
++            self._func_name = self._endpoint.replace(ns.symbol_prefix[0] + '_', '')
 +            return None
 +        else:
 +            return LinkParseError(self._line, self._start, self._end,
 +                                  self._fragment, self._endpoint,
-         if self._fragment in ['alias', 'class', 'const', 'enum', 'error', 'flags', 'iface', 'struct']:
++                                  f"Unsupported symbol {self._endpoint}")
 +
 +    def _parse_type(self, fragment):
 +        res = TYPE_RE.match(self._endpoint)
 +        if res:
 +            ns = res.group('ns')
 +            name = res.group('name')
 +            if ns is not None:
 +                ns = ns[:len(ns) - 1]   # Drop the trailing dot
 +            else:
 +                ns = self._namespace.name
 +                # Accept FooBar in place of Foo.Bar
 +                if name.startswith(tuple(self._namespace.identifier_prefix)):
 +                    for prefix in self._namespace.identifier_prefix:
 +                        name = name.replace(prefix, '')
 +        else:
 +            return LinkParseError(self._line, self._start, self._end,
 +                                  self._fragment, self._endpoint,
 +                                  "Invalid type link")
 +        if ns == self._namespace.name:
 +            namespace = self._namespace
 +            self._external = False
 +            self._ns = ns
 +        else:
 +            repository = self._namespace.repository
 +            namespace = repository.find_included_namespace(ns)
 +            if namespace is not None:
 +                self._external = True
 +                self._ns = namespace.name
 +            else:
 +                self._fragment = None
 +                return None
 +        t = namespace.find_real_type(name)
 +        if t is not None and t.base_ctype is not None:
 +            if fragment == 'type':
 +                if isinstance(t, gir.Alias):
 +                    self._fragment = 'alias'
 +                elif isinstance(t, gir.BitField):
 +                    self._fragment = 'flags'
 +                elif isinstance(t, gir.Callback):
 +                    self._fragment = 'callback'
 +                elif isinstance(t, gir.Class):
 +                    self._fragment = 'class'
 +                elif isinstance(t, gir.Constant):
 +                    self._fragment = 'const'
 +                elif isinstance(t, gir.Enumeration):
 +                    self._fragment = 'enum'
 +                elif isinstance(t, gir.ErrorDomain):
 +                    self._fragment = 'error'
 +                elif isinstance(t, gir.Interface):
 +                    self._fragment = 'iface'
 +                elif isinstance(t, gir.Record) or isinstance(t, gir.Union):
 +                    self._fragment = 'struct'
 +                else:
 +                    return LinkParseError(self._line, self._start, self._end,
 +                                          self._fragment, self._endpoint,
 +                                          f"Invalid type {t} for '{ns}.{name}'")
 +            self._name = name
 +            self._type = t.base_ctype
 +            return None
 +        else:
 +            return LinkParseError(self._line, self._start, self._end,
 +                                  self._fragment, self._endpoint,
 +                                  f"Unable to find type '{ns}.{name}'")
 +
 +    def _parse_property(self, fragment):
 +        res = PROPERTY_RE.match(self._endpoint)
 +        if res:
 +            ns = res.group('ns')
 +            name = res.group('name')
 +            pname = res.group('property')
 +            if ns is not None:
 +                ns = ns[:len(ns) - 1]   # Drop the trailing dot
 +            else:
 +                ns = self._namespace.name
 +                # Accept FooBar in place of Foo.Bar
 +                if name.startswith(tuple(self._namespace.identifier_prefix)):
 +                    for prefix in self._namespace.identifier_prefix:
 +                        name = name.replace(prefix, '')
 +            # Canonicalize the property name
 +            pname = pname.replace('_', '-')
 +        else:
 +            return LinkParseError(self._line, self._start, self._end,
 +                                  self._fragment, self._endpoint,
 +                                  "Invalid property link")
 +        if ns == self._namespace.name:
 +            namespace = self._namespace
 +            self._external = False
 +            self._ns = ns
 +        else:
 +            repository = self._namespace.repository
 +            namespace = repository.find_included_namespace(ns)
 +            if namespace is not None:
 +                self._external = True
 +                self._ns = ns
 +            else:
 +                self._fragment = None
 +                return None
 +        t = namespace.find_real_type(name)
 +        if t is not None and t.base_ctype is not None:
 +            self._type = t.base_ctype
 +            self._name = name
 +        else:
 +            return LinkParseError(self._line, self._start, self._end,
 +                                  self._fragment, self._endpoint,
 +                                  f"Unable to find type '{ns}.{name}'")
 +        if (isinstance(t, gir.Class) or isinstance(t, gir.Interface)) and pname in t.properties:
 +            self._property_name = pname
 +        else:
 +            return LinkParseError(self._line, self._start, self._end,
 +                                  self._fragment, self._endpoint,
 +                                  f"Invalid property '{pname}' for type '{ns}.{name}'")
 +
 +    def _parse_signal(self, fragment):
 +        res = SIGNAL_RE.match(self._endpoint)
 +        if res:
 +            ns = res.group('ns')
 +            name = res.group('name')
 +            sname = res.group('signal')
 +            if ns is not None:
 +                ns = ns[:len(ns) - 1]   # Drop the trailing dot
 +            else:
 +                ns = self._namespace.name
 +                # Accept FooBar in place of Foo.Bar
 +                if name.startswith(tuple(self._namespace.identifier_prefix)):
 +                    for prefix in self._namespace.identifier_prefix:
 +                        name = name.replace(prefix, '')
 +            # Canonicalize the signal name
 +            sname = sname.replace('_', '-')
 +        else:
 +            return LinkParseError(self._line, self._start, self._end,
 +                                  self._fragment, self._endpoint,
 +                                  "Invalid signal link")
 +        if ns == self._namespace.name:
 +            namespace = self._namespace
 +            self._external = False
 +            self._ns = ns
 +        else:
 +            repository = self._namespace.repository
 +            namespace = repository.find_included_namespace(ns)
 +            if namespace is not None:
 +                self._external = True
 +                self._ns = namespace.name
 +            else:
 +                self._fragment = None
 +                return None
 +        t = namespace.find_real_type(name)
 +        if t is not None and t.base_ctype is not None:
 +            self._type = t.base_ctype
 +            self._name = name
 +        else:
 +            return LinkParseError(self._line, self._start, self._end,
 +                                  self._fragment, self._endpoint,
 +                                  f"Unable to find type '{ns}.{name}'")
 +        if (isinstance(t, gir.Class) or isinstance(t, gir.Interface)) and sname in t.signals:
 +            self._signal_name = sname
 +        else:
 +            return LinkParseError(self._line, self._start, self._end,
 +                                  self._fragment, self._endpoint,
 +                                  f"Invalid signal name '{sname}' for type '{ns}.{name}'")
 +
 +    def _parse_method(self, fragment):
 +        res = METHOD_RE.match(self._endpoint)
 +        if res:
 +            ns = res.group('ns')
 +            name = res.group('name')
 +            method = res.group('method')
 +            if ns is not None:
 +                ns = ns[:len(ns) - 1]   # Drop the trailing dot
 +            else:
 +                ns = self._namespace.name
 +                # Accept FooBar in place of Foo.Bar
 +                if name.startswith(tuple(self._namespace.identifier_prefix)):
 +                    for prefix in self._namespace.identifier_prefix:
 +                        name = name.replace(prefix, '')
 +        else:
 +            return LinkParseError(self._line, self._start, self._end,
 +                                  self._fragment, self._endpoint,
 +                                  "Invalid method link")
 +        if ns == self._namespace.name:
 +            namespace = self._namespace
 +            self._external = False
 +            self._ns = ns
 +        else:
 +            repository = self._namespace.repository
 +            namespace = repository.find_included_namespace(ns)
 +            if namespace is not None:
 +                self._ns = namespace.name
 +                self._external = True
 +            else:
 +                self._fragment = None
 +                return None
 +        t = namespace.find_real_type(name)
 +        if t is not None and t.base_ctype is not None:
 +            self._type = t.base_ctype
 +            self._method_name = method
 +            # method@Foo.BarClass.add_name -> class_method.Bar.add_name.html
 +            if isinstance(t, gir.Record) and t.struct_for is not None:
 +                self._name = t.struct_for
 +                self._fragment = "class_method"
 +            elif fragment == "vfunc" and t.type_struct is not None:
 +                self._name = name
 +                self._type = t.type_struct
 +            else:
 +                self._name = name
 +        else:
 +            return LinkParseError(self._line, self._start, self._end,
 +                                  self._fragment, self._endpoint,
 +                                  f"Unable to find type '{ns}.{name}'")
 +        if fragment == "ctor":
 +            methods = getattr(t, "constructors", [])
 +        elif fragment in ["method", "class_method"]:
 +            methods = getattr(t, "methods", [])
 +        elif fragment == "vfunc":
 +            methods = getattr(t, "virtual_methods", [])
 +        else:
 +            methods = []
 +        for m in methods:
 +            if m.name == method:
 +                if fragment == "vfunc":
 +                    self._vfunc_name = m.name
 +                else:
 +                    self._symbol_name = f"{m.identifier}()"
 +                return None
 +        return LinkParseError(self._line, self._start, self._end,
 +                              self._fragment, self._endpoint,
 +                              f"Unable to find method '{ns}.{name}.{method}'")
 +
 +    def _parse_func(self, fragment):
 +        tokens = self._endpoint.split('.')
 +        # Case 1: [func@init] => gtk_init()
 +        if len(tokens) == 1:
 +            ns = self._namespace.name
 +            name = None
 +            func_name = tokens[0]
 +        # Case 2: [func@Gtk.Foo.bar] => gtk_foo_bar()
 +        elif len(tokens) == 3:
 +            ns = tokens[0]
 +            name = tokens[1]
 +            func_name = tokens[2]
 +        # Case 3: either [func@Gtk.init] or [func@Foo.bar]
 +        elif len(tokens) == 2:
 +            if tokens[0] == self._namespace.name:
 +                ns = tokens[0]
 +                name = None
 +                func_name = tokens[1]
 +            elif tokens[0] in self._valid_namespaces:
 +                ns = tokens[0]
 +                name = None
 +                func_name = tokens[1]
 +            else:
 +                ns = self._namespace.name
 +                name = tokens[0]
 +                func_name = tokens[1]
 +        else:
 +            return LinkParseError(self._line, self._start, self._end,
 +                                  self._fragment, self._endpoint,
 +                                  "Invalid function link")
 +        if ns == self._namespace.name:
 +            namespace = self._namespace
 +            self._external = False
 +            self._ns = ns
 +        else:
 +            repository = self._namespace.repository
 +            namespace = repository.find_included_namespace(ns)
 +            if namespace is not None:
 +                self._external = True
 +                self._ns = namespace.name
 +            else:
 +                self._fragment = None
 +                log.warning(f"Namespace {ns} not found for link {self._endpoint}")
 +                return None
 +        if name is None:
 +            t = namespace.find_function(func_name)
 +            if t is not None:
 +                self._name = None
 +                self._func_name = func_name
 +                self._symbol_name = f"{t.identifier}()"
 +                return None
 +            else:
 +                return LinkParseError(self._line, self._start, self._end,
 +                                      self._fragment, self._endpoint,
 +                                      f"Unable to find function '{ns}.{func_name}'")
 +        else:
 +            t = namespace.find_real_type(name)
 +            if t is None:
 +                return LinkParseError(self._line, self._start, self._end,
 +                                      self._fragment, self._endpoint,
 +                                      f"Unable to find type '{ns}.{name}'")
 +            for func in t.functions:
 +                if func.name == func_name:
 +                    self._name = name
 +                    self._func_name = func.name
 +                    self._symbol_name = f"{func.identifier}()"
 +                    return None
 +            return LinkParseError(self._line, self._start, self._end,
 +                                  self._fragment, self._endpoint,
 +                                  f"Unable to find function '{ns}.{name}.{func_name}'")
 +
 +    @property
 +    def text(self):
-             return f"{self._symbol_name}"
++        if self._alt_text is not None:
++            return self._alt_text[1:len(self._alt_text) - 1]
++        elif self._fragment in ['alias', 'class', 'const', 'enum', 'error', 'flags', 'iface', 'struct']:
 +            return f"<code>{self._type}</code>"
 +        elif self._fragment == 'property':
 +            return f"<code>{self._type}:{self._property_name}</code>"
 +        elif self._fragment == 'signal':
 +            return f"<code>{self._type}::{self._signal_name}</code>"
 +        elif self._fragment in ['ctor', 'func', 'method', 'class_method']:
-                                      no_link=summary)
++            return f"<code>{self._symbol_name}</code>"
 +        elif self._fragment == 'vfunc':
 +            return f"<code>{self._ns}.{self._type}.{self._vfunc_name}</code>"
 +        else:
 +            return f"{self._endpoint}"
 +
 +    @property
 +    def href(self):
 +        if self._fragment in ['alias', 'class', 'const', 'enum', 'error', 'flags', 'iface', 'struct']:
 +            return f"{self._fragment}.{self._name}.html"
 +        elif self._fragment == 'property':
 +            return f"property.{self._name}.{self._property_name}.html"
 +        elif self._fragment == 'signal':
 +            return f"signal.{self._name}.{self._signal_name}.html"
 +        elif self._fragment in ['ctor', 'method', 'class_method', 'vfunc']:
 +            return f"{self._fragment}.{self._name}.{self._method_name}.html"
 +        elif self._fragment == 'func':
 +            if self._name is not None:
 +                return f"type_func.{self._name}.{self._func_name}.html"
 +            else:
 +                return f"func.{self._func_name}.html"
 +        else:
 +            return None
 +
 +    def __str__(self):
 +        text = self.text
 +        if self._no_link:
 +            return text
 +        link = self.href
 +        if link is None:
 +            return text
 +        if self._external:
 +            data_namespace = f"data-namespace=\"{self._ns}\""
 +            data_link = f"data-link=\"{link}\""
 +            href = "href=\"javascript:void(0)\""
 +            css = "class=\"external\""
 +            return f"<a {href} {data_namespace} {data_link} {css}>{text}</a>"
 +        else:
 +            return f"<a href=\"{link}\">{text}</a>"
 +
 +
 +def preprocess_docs(text, namespace, summary=False, md=None, extensions=[], plain=False, max_length=10):
 +    if plain:
 +        text = text.replace('\n', ' ')
 +        text = re.sub(r'<[^<]+?>', '', text)
 +        if max_length > 0:
 +            words = text.split(' ')
 +            if len(words) > max_length:
 +                words = words[:max_length - 1]
 +                words.append('...')
 +                text = ' '.join(words)
 +        return text
 +
 +    processed_text = []
 +
 +    code_block_text = []
 +    code_block_language = None
 +    inside_code_block = False
 +
 +    for line in text.split("\n"):
 +        # If we're in "summary" mode, we bail out at the first empty line
 +        # after a paragraph
 +        if summary and line == '' and len(processed_text) > 0:
 +            break
 +
 +        res = CODEBLOCK_START_RE.match(line)
 +        if res:
 +            code_block_language = process_language(res.group("language"))
 +            inside_code_block = True
 +            continue
 +
 +        res = CODEBLOCK_END_RE.match(line)
 +        if res and inside_code_block:
 +            if code_block_language == "plain":
 +                processed_text += ["```"]
 +                processed_text.extend(code_block_text)
 +                processed_text += ["```"]
 +            else:
 +                lexer = get_lexer_by_name(code_block_language)
 +                formatter = HtmlFormatter()
 +                code_block = highlight("\n".join(code_block_text), lexer, formatter)
 +                processed_text += [""]
 +                processed_text.extend(code_block.split("\n"))
 +                processed_text += [""]
 +
 +            code_block_language = None
 +            code_block_text = []
 +            inside_code_block = False
 +            continue
 +
 +        if inside_code_block:
 +            code_block_text.append(line)
 +        else:
 +            new_line = []
 +            idx = 0
 +            for m in LINK_RE.finditer(line, idx):
 +                fragment = m.group('fragment')
 +                endpoint = m.group('endpoint')
++                text = m.group('text')
 +                start = m.start()
 +                end = m.end()
 +                link = LinkGenerator(line=line, start=start, end=end,
 +                                     namespace=namespace,
 +                                     fragment=fragment, endpoint=endpoint,
-     if last_line and last_line[-1] != '.':
++                                     no_link=summary, text=text)
 +                left_pad = line[idx:start]
 +                replacement = re.sub(LINK_RE, str(link), line[start:end])
 +                new_line.append(left_pad)
 +                new_line.append(replacement)
 +                idx = end
 +            new_line.append(line[idx:])
 +
 +            if len(new_line) == 0:
 +                processed_text.append(line)
 +            else:
 +                processed_text.append("".join(new_line))
 +
 +    if len(processed_text) == 0:
 +        return ''
 +
 +    # Capitalize the first character of the first line, but only if it does not
 +    # start with a link or a gtk-doc marker, to avoid messing up the rest of
 +    # the string
 +    first_line = processed_text[0]
 +    if first_line and first_line[0].isalpha():
 +        processed_text[0] = ''.join([first_line[0:1].upper(), first_line[1:]])
 +
 +    # Append a period, if one isn't there already
 +    last_line = processed_text[-1]
++    if last_line and last_line[-1].isalpha():
 +        processed_text[-1] = ''.join([last_line, '.'])
 +
 +    if md is None:
 +        md_ext = extensions.copy()
 +        md_ext.extend(MD_EXTENSIONS)
 +        text = markdown.markdown("\n".join(processed_text),
 +                                 extensions=md_ext,
 +                                 extension_configs=MD_EXTENSIONS_CONF)
 +    else:
 +        text = md.reset().convert("\n".join(processed_text))
 +
 +    return Markup(typogrify(text, ignore_tags=['h1', 'h2', 'h3', 'h4']))
 +
 +
 +def stem(word, stemmer=None):
 +    if stemmer is None:
 +        stemmer = porter.PorterStemmer()
 +    return stemmer.stem(word, 0, len(word) - 1)
 +
 +
 +def index_description(text, stemmer=None):
 +    processed_text = []
 +
 +    inside_code_block = False
 +    for line in text.split("\n"):
 +        if not inside_code_block and (line.startswith('```') or line.startswith('|[')):
 +            inside_code_block = True
 +            continue
 +
 +        if inside_code_block and (line.startswith('```') or line.startswith(']|')):
 +            inside_code_block = False
 +            continue
 +
 +        if not inside_code_block:
 +            processed_text.append(line)
 +
 +    data = " ".join(processed_text)
 +    terms = set()
 +    for chunk in data.split(" "):
 +        chunk = chunk.lower()
 +        if chunk in ["\n", "\r", "\r\n"]:
 +            continue
 +        # Skip gtk-doc sygils
 +        if chunk.startswith('%') or chunk.startswith('#') or chunk.startswith('@') or chunk.endswith('()'):
 +            continue
 +        # Skip gi-docgen links
 +        if chunk.startswith('[') and chunk.endswith(']') and '@' in chunk:
 +            continue
 +        # Skip images
 +        if chunk.startswith('!['):
 +            continue
 +        if chunk in EN_STOPWORDS:
 +            continue
 +        chunk = re.sub(r"`(\w+)`", r"\g<1>", chunk)
 +        chunk = re.sub(r"[,\.:;`]$", '', chunk)
 +        chunk = re.sub(r"[\(\)]+", '', chunk)
 +        terms.add(stem(chunk, stemmer))
 +    return terms
 +
 +
 +def canonicalize(symbol):
 +    return symbol.replace('-', '_')
 +
 +
 +def index_identifier(symbol, stemmer=None):
 +    """Chunks an identifier (e.g. EventControllerClik) into terms useful for indexing."""
 +    symbol = re.sub(CAMEL_CASE_START_RE, r"\g<1>_\g<2>", symbol)
 +    symbol = re.sub(CAMEL_CASE_CHUNK_RE, r"\g<1>_\g<2>", symbol)
 +    symbol = symbol.replace('-', '_')
 +    symbol = symbol.lower()
 +    terms = set()
 +    for chunk in symbol.split('_'):
 +        if chunk in EN_STOPWORDS:
 +            continue
 +        terms.add(stem(chunk, stemmer))
 +    return terms
 +
 +
 +def index_symbol(symbol, stemmer=None):
 +    """Chunks a symbol (e.g. set_layout_manager) into terms useful for indexing."""
 +    terms = set()
 +    for chunk in canonicalize(symbol).split('_'):
 +        if chunk in EN_STOPWORDS:
 +            continue
 +        terms.add(stem(chunk, stemmer))
 +    return terms
 +
 +
 +def code_highlight(text, language='c'):
 +    lexer = get_lexer_by_name(language)
 +    formatter = HtmlFormatter()
 +    return Markup(highlight(text, lexer, formatter))
 +
 +
 +def render_dot(dot, output_format="svg"):
 +    if output_format not in ["svg", "png"]:
 +        log.error("Invalid output format for render_dot(): {output_format}")
 +
 +    args = ["dot", f"-T{output_format}"]
 +
 +    try:
 +        proc = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 +        proc.stdin.write(dot.encode("utf-8"))
 +        output, err = proc.communicate()
 +        if err:
 +            log.warning(f"Unable to process dot data: {err}")
 +            return None
 +        if output_format == "svg":
 +            return output.decode("utf-8")
 +    except Exception as e:
 +        log.warning(f"Unable to process dot data: {e}")
 +        return None
 +
 +
 +found_programs = {}
 +
 +
 +def find_program(bin_name, path=None):
 +    """Finds a program @bin_name inside the given @path, and returns
 +    its full path if found, or None if the program could not be found.
 +
 +    The @bin_name will automatically get an extension depending on the
 +    platform.
 +    """
 +    global found_programs
 +
 +    if path is None and bin_name in found_programs:
 +        return found_programs[bin_name]
 +
 +    if path is None:
 +        search_paths = os.environ['PATH'].split(os.pathsep)
 +    else:
 +        search_paths = path.split(os.pathsep)
 +
 +    bin_extensions = ['']
 +
 +    if sys.platform == 'win32':
 +        pathext = os.environ['PATHEXT'].lower().split(os.pathsep)
 +        (basename, extension) = os.path.splitext(bin_name)
 +        if extension.lower() not in pathext:
 +            bin_extensions = pathext
 +        search_paths.insert(0, '')
 +
 +    for ext in bin_extensions:
 +        executable = bin_name + ext
 +
 +        for p in search_paths:
 +            full_path = os.path.join(p, executable)
 +            if os.path.isfile(full_path):
 +                # Memoize the result with the default PATH, so we can
 +                # call this multiple times at no additional cost
 +                if path is None:
 +                    found_programs[bin_name] = full_path
 +                return full_path
 +
 +    return None
 +
 +
 +def default_search_paths():
 +    if not sys.platform == 'win32':
 +        xdg_data_dirs = os.environ.get("XDG_DATA_DIRS", "/usr/share:/usr/local/share").split(":")
 +        xdg_data_home = os.environ.get("XDG_DATA_HOME", os.path.expanduser("~/.local/share"))
 +    else:
 +        xdg_data_dirs = None
 +        xdg_data_home = None
 +
 +    paths = []
 +    paths.append(os.getcwd())
 +    # Add sys.base_prefix when using MSYS2
 +    if sys.platform == 'win32' and 'GCC' in sys.version:
 +        paths.append(os.path.join(sys.base_prefix, 'share', 'gir-1.0'))
 +    if xdg_data_home is not None:
 +        paths.append(os.path.join(xdg_data_home, "gir-1.0"))
 +    if xdg_data_dirs is not None:
 +        paths.extend([os.path.join(x, "gir-1.0") for x in xdg_data_dirs])
 +
 +    return paths
++
++
++def find_extra_content_file(content_dirs, file):
++    for p in content_dirs:
++        full_path = os.path.join(p, file)
++        if os.path.isfile(full_path):
++            return full_path
++
++    raise FileNotFoundError(f"Content file {file} not found in any content directory")
index 28b73e7a4251ac8f066bcaf2e04b84baf39c7a58,0000000000000000000000000000000000000000..62c4de2187f81ea96aaa9cb7ddf17957d6934165
mode 100644,000000..100644
--- /dev/null
@@@ -1,71 -1,0 +1,72 @@@
-   version: '2021.6',
 +# SPDX-FileCopyrightText: 2021 GNOME Foundation
 +#
 +# SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later
 +
 +project('gi-docgen',
-   mypy = find_program('mypy', required: false)
-   if mypy.found()
-     test('mypy',
-       mypy,
-       args: [
-         '--ignore-missing-imports',
-         '--disallow-incomplete-defs',
-         meson.current_source_dir() / 'gidocgen',
-       ],
-     )
-   endif
++  version: '2021.9',
 +  meson_version: '>= 0.55.0',
 +)
 +
 +py = import('python').find_installation('python3',
 +  modules: [
 +    'jinja2',
 +    'markdown',
 +    'markupsafe',
 +    'pygments',
 +    'toml',
 +    'typogrify',
 +  ],
 +)
 +
 +configure_file(
 +  input: 'gi-docgen.py',
 +  output: 'gi-docgen',
 +  copy: true,
 +  install: not meson.is_subproject(),
 +  install_dir: get_option('bindir'),
 +)
 +
 +# When using gi-docgen as a sub-project
 +dummy_dep = declare_dependency()
 +meson.override_find_program('gi-docgen', find_program('gi-docgen.py'))
 +
 +pkgconf = configuration_data()
 +pkgconf.set('VERSION', meson.project_version())
 +configure_file(
 +  input: 'gi-docgen.pc.in',
 +  output: 'gi-docgen.pc',
 +  configuration: pkgconf,
 +  install: not meson.is_subproject(),
 +  install_dir: get_option('datadir') / 'pkgconfig',
 +)
 +
 +if not meson.is_subproject()
 +  install_subdir('gidocgen', install_dir: py.get_install_dir())
 +endif
 +
 +# Development tests should not be run when in a subproject
 +if get_option('development_tests') and not meson.is_subproject()
 +  flake8 = find_program('flake8', required: false)
 +  if flake8.found()
 +    test('flake8',
 +      flake8,
 +      args: [
 +        '--show-source',
 +        meson.current_source_dir() / 'gidocgen',
 +      ],
 +    )
 +  endif
 +
++#  mypy = find_program('mypy', required: false)
++#  if mypy.found()
++#    test('mypy',
++#      mypy,
++#      args: [
++#        '--ignore-missing-imports',
++#        '--disallow-incomplete-defs',
++#        meson.current_source_dir() / 'gidocgen',
++#      ],
++#      should_fail: true,
++#    )
++#  endif
 +endif