/*** Icons ***/ :root { --icon-breadcrumb: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjE2IiB3aWR0aD0iMTYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTYgMTIgNC00LTQtNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjNTU0MjNlIiBzdHJva2Utd2lkdGg9IjIiLz48L3N2Zz4='); --icon-expand: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEyIiB3aWR0aD0iMTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggY2xpcC1ydWxlPSJldmVub2RkIiBkPSJtNyA1di0zaC0ydjNoLTN2MmgzdjNoMnYtM2gzdi0yeiIgZmlsbD0iIzU1NDIzZSIgZmlsbC1vcGFjaXR5PSIuNSIgZmlsbC1ydWxlPSJldmVub2RkIi8+PC9zdmc+'); --icon-leaf: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEyIiB3aWR0aD0iMTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGNpcmNsZSBjeD0iNiIgY3k9IjYiIGZpbGw9IiM1NTQyM2UiIGZpbGwtb3BhY2l0eT0iLjUiIHI9IjIiLz48L3N2Zz4='); --icon-collapse: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEyIiB3aWR0aD0iMTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTMgNmg2IiBzdHJva2U9IiM1NTQyM2UiIHN0cm9rZS1vcGFjaXR5PSIuNSIgc3Ryb2tlLXdpZHRoPSIyIi8+PC9zdmc+'); --icon-more: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjE2IiB3aWR0aD0iMTYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTQgNiA0IDQgNC00IiBmaWxsPSJub25lIiBzdHJva2U9IiM1NTQyM2UiIHN0cm9rZS1vcGFjaXR5PSIuNSIgc3Ryb2tlLXdpZHRoPSIyIi8+PC9zdmc+'); --icon-permalink: url("data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjE2IiB3aWR0aD0iMTYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTcuNjU2ODYgMiAxLjQxNDIxIDEuNDE0MjJjLjY4MDUxLjY4MDUxIDEuMDY0NTMgMS41NDUyMSAxLjE1MjEzIDIuNDMzNjIuODg4NC4wODc2IDEuNzUzMS40NzE2NSAyLjQzMzcgMS4xNTIxNmwxLjQxNDIgMS40MTQyMmMxLjU2MjEgMS41NjIwOSAxLjU2MjEgNC4wOTQ3OCAwIDUuNjU2ODhzLTQuMDk0NzkgMS41NjIxLTUuNjU2ODggMGwtMS40MTQyMi0xLjQxNDJjLS42ODA1MS0uNjgwNi0xLjA2NDU2LTEuNTQ1My0xLjE1MjE2LTIuNDMzNy0uODg4NDEtLjA4NzYtMS43NTMxMS0uNDcxNjItMi40MzM2Mi0xLjE1MjEzbC0xLjQxNDIyLTEuNDE0MjFjLTEuNTYyMDk0LTEuNTYyMS0xLjU2MjA5NC00LjA5NDc2IDAtNS42NTY4NiAxLjU2MjEtMS41NjIwOTQgNC4wOTQ3Ni0xLjU2MjA5NCA1LjY1Njg2IDB6bS42MTggNy42ODkwN2MtLjE0NDMuMDg1MjItLjI5MjgxLjE2MDYxLS40NDQ1NS4yMjYxNi4wMjA4My40ODI1Ny4yMTU0Ni45NTg5Ny41ODM5MSAxLjMyNzM3bDEuNDE0MjEgMS40MTQzYy43ODEwNy43ODEgMi4wNDczNy43ODEgMi44Mjg0NyAwIC43ODEtLjc4MTEuNzgxLTIuMDQ3NCAwLTIuODI4NDdsLTEuNDE0My0xLjQxNDIxYy0uMzY4NC0uMzY4NDUtLjg0NDgtLjU2MzA4LTEuMzI3MzctLjU4MzkxLS4wNjU1NS4xNTE3My0uMTQwOTMuMzAwMjQtLjIyNjE2LjQ0NDU0bDEuODQ2NDMgMS44NDY0NS0xLjQxNDIgMS40MTQyem0tLjYxOC00Ljg2MDY0Yy4zNjg0NC4zNjg0NS41NjMwOC44NDQ4OC41ODM5MSAxLjMyNzQyLS4xNTE3NC4wNjU1NC0uMzAwMjQuMTQwOTMtLjQ0NDU0LjIyNjE1bC0xLjkxNzU0LTEuOTE3NTMtMS40MTQyMSAxLjQxNDIxIDEuOTE3NTMgMS45MTc1M2MtLjA4NTIzLjE0NDMxLS4xNjA2MS4yOTI4Mi0uMjI2MTYuNDQ0NTYtLjQ4MjU0LS4wMjA4My0uOTU4OTctLjIxNTQ3LTEuMzI3NDItLjU4MzkxbC0xLjQxNDIxLTEuNDE0MjJjLS43ODEwNS0uNzgxMDUtLjc4MTA1LTIuMDQ3MzcgMC0yLjgyODQyczIuMDQ3MzctLjc4MTA1IDIuODI4NDIgMHoiIGZpbGw9IiM1NTQyM2UiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg=="); --icon-go: url("data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjE2IiB3aWR0aD0iMTYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTEwLjU4NTggNy0yLjI5Mjg5LTIuMjkyODkgMS40MTQyMS0xLjQxNDIyIDQuNzA3MDggNC43MDcxMS00LjcwNzA4IDQuNzA3MS0xLjQxNDIxLTEuNDE0MiAyLjI5Mjg5LTIuMjkyOWgtNy41ODU4di0yeiIgZmlsbD0iIzU1NDIzZSIvPjwvc3ZnPg=="); } @media (prefers-color-scheme: dark) { :root { --icon-breadcrumb: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjE2IiB3aWR0aD0iMTYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTYgMTIgNC00LTQtNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZDdjZGJmIiBzdHJva2Utd2lkdGg9IjIiLz48L3N2Zz4='); --icon-expand: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEyIiB3aWR0aD0iMTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggY2xpcC1ydWxlPSJldmVub2RkIiBkPSJtNyA1di0zaC0ydjNoLTN2MmgzdjNoMnYtM2gzdi0yeiIgZmlsbD0iI2Q3Y2RiZiIgZmlsbC1vcGFjaXR5PSIuNSIgZmlsbC1ydWxlPSJldmVub2RkIi8+PC9zdmc+'); --icon-leaf: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEyIiB3aWR0aD0iMTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGNpcmNsZSBjeD0iNiIgY3k9IjYiIGZpbGw9IiNkN2NkYmYiIGZpbGwtb3BhY2l0eT0iLjUiIHI9IjIiLz48L3N2Zz4='); --icon-collapse: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEyIiB3aWR0aD0iMTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTMgNmg2IiBzdHJva2U9IiNkN2NkYmYiIHN0cm9rZS1vcGFjaXR5PSIuNSIgc3Ryb2tlLXdpZHRoPSIyIi8+PC9zdmc+'); --icon-permalink: url("data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjE2IiB3aWR0aD0iMTYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTcuNjU2ODYgMiAxLjQxNDIxIDEuNDE0MjJjLjY4MDUxLjY4MDUxIDEuMDY0NTMgMS41NDUyMSAxLjE1MjEzIDIuNDMzNjIuODg4NC4wODc2IDEuNzUzMS40NzE2NSAyLjQzMzcgMS4xNTIxNmwxLjQxNDIgMS40MTQyMmMxLjU2MjEgMS41NjIwOSAxLjU2MjEgNC4wOTQ3OCAwIDUuNjU2ODhzLTQuMDk0NzkgMS41NjIxLTUuNjU2ODggMGwtMS40MTQyMi0xLjQxNDJjLS42ODA1MS0uNjgwNi0xLjA2NDU2LTEuNTQ1My0xLjE1MjE2LTIuNDMzNy0uODg4NDEtLjA4NzYtMS43NTMxMS0uNDcxNjItMi40MzM2Mi0xLjE1MjEzbC0xLjQxNDIyLTEuNDE0MjFjLTEuNTYyMDk0LTEuNTYyMS0xLjU2MjA5NC00LjA5NDc2IDAtNS42NTY4NiAxLjU2MjEtMS41NjIwOTQgNC4wOTQ3Ni0xLjU2MjA5NCA1LjY1Njg2IDB6bS42MTggNy42ODkwN2MtLjE0NDMuMDg1MjItLjI5MjgxLjE2MDYxLS40NDQ1NS4yMjYxNi4wMjA4My40ODI1Ny4yMTU0Ni45NTg5Ny41ODM5MSAxLjMyNzM3bDEuNDE0MjEgMS40MTQzYy43ODEwNy43ODEgMi4wNDczNy43ODEgMi44Mjg0NyAwIC43ODEtLjc4MTEuNzgxLTIuMDQ3NCAwLTIuODI4NDdsLTEuNDE0My0xLjQxNDIxYy0uMzY4NC0uMzY4NDUtLjg0NDgtLjU2MzA4LTEuMzI3MzctLjU4MzkxLS4wNjU1NS4xNTE3My0uMTQwOTMuMzAwMjQtLjIyNjE2LjQ0NDU0bDEuODQ2NDMgMS44NDY0NS0xLjQxNDIgMS40MTQyem0tLjYxOC00Ljg2MDY0Yy4zNjg0NC4zNjg0NS41NjMwOC44NDQ4OC41ODM5MSAxLjMyNzQyLS4xNTE3NC4wNjU1NC0uMzAwMjQuMTQwOTMtLjQ0NDU0LjIyNjE1bC0xLjkxNzU0LTEuOTE3NTMtMS40MTQyMSAxLjQxNDIxIDEuOTE3NTMgMS45MTc1M2MtLjA4NTIzLjE0NDMxLS4xNjA2MS4yOTI4Mi0uMjI2MTYuNDQ0NTYtLjQ4MjU0LS4wMjA4My0uOTU4OTctLjIxNTQ3LTEuMzI3NDItLjU4MzkxbC0xLjQxNDIxLTEuNDE0MjJjLS43ODEwNS0uNzgxMDUtLjc4MTA1LTIuMDQ3MzcgMC0yLjgyODQyczIuMDQ3MzctLjc4MTA1IDIuODI4NDIgMHoiIGZpbGw9IiNkN2NkYmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg=="); --icon-go: url("data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjE2IiB3aWR0aD0iMTYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTEwLjU4NTggNy0yLjI5Mjg5LTIuMjkyODkgMS40MTQyMS0xLjQxNDIyIDQuNzA3MDggNC43MDcxMS00LjcwNzA4IDQuNzA3MS0xLjQxNDIxLTEuNDE0MiAyLjI5Mjg5LTIuMjkyOWgtNy41ODU4di0yeiIgZmlsbD0iI2Q3Y2RiZiIvPjwvc3ZnPg=="); --icon-more: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjE2IiB3aWR0aD0iMTYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTQgNiA0IDQgNC00IiBmaWxsPSJub25lIiBzdHJva2U9IiNkN2NkYmYiIHN0cm9rZS1vcGFjaXR5PSIuNSIgc3Ryb2tlLXdpZHRoPSIyIi8+PC9zdmc+'); } } /*** Variables ***/ :root { --tree-indent-width: 28px; --transition-duration: 0.15s; --button-bar-icon-size: 24px; } /*** Breadcrumbs ***/ .breadcrumbs { list-style-type: none; display: flex; flex-direction: row; flex-wrap: wrap; height: min-content; margin: 0; padding: 0; align-items: center; opacity: 70%; } .breadcrumb::before { content: ''; display: inline-block; background-image: var(--icon-breadcrumb); background-repeat: no-repeat; background-position: 50% 50%; opacity: 70%; width: 32px; height: 1.2em; vertical-align: text-bottom; } .breadcrumb a { --recursive-mono: 1.0; --recursive-wght: 500; color: var(--text-color); text-decoration: none; } .breadcrumb a:hover { text-decoration: underline; } /*** Tree ***/ .tree { --tree-indent-guide-dim: transparent; --tree-indent-guide-highlighted: transparent; } .tree:has(.branch-container:hover) { --tree-indent-guide-dim: transparent; --tree-indent-guide-highlighted: var(--border-1); } @media (hover: none) { .tree { --tree-indent-guide-dim: var(--border-1); --tree-indent-guide-highlighted: var(--border-1); } } /* Use an indent level appropriate for the viewport. */ .tree ul { --tree-responsive-indent-width: clamp(8px, 2vw, var(--tree-indent-width)); /* Draw indent guides. */ padding-left: calc(var(--tree-responsive-indent-width) / 2); margin-left: calc(var(--tree-responsive-indent-width) / 2); border-left: 1px solid var(--tree-indent-guide-dim); transition: border-left-color var(--transition-duration); } .tree details:has(.branch-container:hover)>ul { border-left-color: var(--tree-indent-guide-highlighted); } /* Top level should not have an indent or a border. */ .tree>ul { padding-left: 0; border-left: none; } .tree details { /* Disable the rightwards chevron in
elements */ &>summary { list-style: none; cursor: pointer; &::-webkit-details-marker { display: none; } } } /* Child branches */ .tree li { /*
  • elements should not have any bullet points or whatever */ list-style: none; /* Stretch branch content to the full width of the page */ &>div, &>details { width: 100%; } /* Add an underline for leaf branches */ &>div { box-sizing: border-box; margin-bottom: -1px; border-bottom: 1px solid transparent; transition: border-bottom-color var(--transition-duration); &:hover { border-bottom-color: var(--border-1); } } &>div, &>details>summary { /* Child elements are laid out horizontally in a flexbox. */ display: flex; align-items: center; } } /* is used for the visual content of branches with children. It's the large horizontal bar and notably *excludes* children. */ .tree details>summary { /* Slightly round for elegance */ border-radius: 8px; /* Give it a shaded background on hover */ background-color: transparent; transition: background-color var(--transition-duration); &:hover { background-color: var(--shaded-background); } } /* For media without hover functionality, draw a bottom border everywhere as a visual anchor for where to tap */ @media (hover: none) { .tree li>div:first-child, .tree li>details>summary:first-child { border-bottom: 1px solid var(--border-1); } .tree details>summary { /* In that case summaries shall not be rounded. */ border-radius: 0px; } } /* The following three elements - bp, bc, and bb - are there in all branches, regardless of their parent. */ /* bp - bullet point */ th-bp { display: block; width: var(--tree-indent-width); height: 24px; background-image: var(--icon-leaf); background-repeat: no-repeat; background-position: 50% 50%; /* Prevent shrinkage when viewport is too low */ flex-shrink: 0; } /* Change image of th-bp if it has children and/or is collapsible */ .tree details[open]>summary>th-bp { background-image: var(--icon-collapse); } .tree details:not([open])>summary>th-bp { background-image: var(--icon-expand); } /* bc - branch content */ th-bc { display: block; padding-top: 6px; padding-bottom: 6px; /* Grow to fill the entire available space. This pushes out th-bb to the far right. */ flex-grow: 1; /* Bit of a hack to make
    s in  have scrollbars proper. */
        &:has(pre, th-literate-program) {
            overflow: hidden;
        }
    }
    
    /* Display a chevron hinting that the collapsed branch has more content in its children. */
    .tree details:not([open])>summary>th-bc>:last-child {
        &::after {
            content: '\00A0';
            display: inline-block;
    
            background-image: var(--icon-more);
            background-repeat: no-repeat;
            background-position: 50% 50%;
    
            width: 16px;
            height: 1.2em;
    
            vertical-align: text-bottom;
            margin-left: 0.5em;
    
            margin-right: -32px;
        }
    }
    
    /* Display a [draft] pill for branches that are drafts. */
    .tree li.draft {
    
        &>details>summary>th-bc::before,
        &>div>th-bc::before {
            content: 'draft';
    
            display: block;
            width: min-content;
    
            background-color: #058ef0;
            color: #ffffff;
            padding: 4px 12px;
            margin-bottom: 4px;
            border-radius: 100px;
        }
    }
    
    /* bb - button bar */
    th-bb {
        height: 100%;
        margin: 4px;
    
        /* Should be displayed on the top of the branch rather than in the middle. */
        align-self: start;
    
        display: flex;
        flex-direction: row;
        align-items: center;
    
        /* Keep the button bar invisible by default. */
        opacity: 0%;
        transition: opacity var(--transition-duration);
    }
    
    /* When the parent is hovered over, display the button bar. */
    .tree *:hover>th-bb {
        opacity: 100%;
    }
    
    /* For media without hover functionality, th-bb should always be visible. */
    @media (hover: none) {
        :root {
            --button-bar-icon-size: 32px;
        }
    
        .tree th-bb {
            opacity: 100%;
    
            /* Replace margin with button size to make it easier to click. */
            margin: 0px;
    
            & a.icon {
                width: 32px;
                height: 32px;
            }
        }
    }
    
    /* Style branch dates to be smaller and less noticable. */
    th-bb .branch-date {
        opacity: 50%;
        font-size: 0.8em;
    }
    
    /* Hide branch dates on very small displays. No clue how to fix this just yet. */
    @media (max-width: 600px) {
        th-bb .branch-date {
            display: none;
        }
    }
    
    /* Icons (used in the button bar) */
    .tree {
        & .icon {
            background-repeat: no-repeat;
            background-position: 50% 50%;
            opacity: 35%;
    
            width: var(--button-bar-icon-size);
            height: var(--button-bar-icon-size);
        }
    
        & .icon-permalink {
            background-image: var(--icon-permalink);
        }
    
        & .icon-go {
            background-image: var(--icon-go);
        }
    }
    
    /* Style the loading text to not be too attention grabbing. */
    .tree .link-loading {
        padding-left: 24px;
        opacity: 50%;
    }
    
    /* Highlight branch selected by # or ? in URL.
        The latter is not supported by CSS so we use some auxiliary JavaScript to add a .target class
        to the element highlighted by ?. */
    .tree :target,
    .tree .target {
    
        &>details>summary,
        &>div {
            background-color: var(--shaded-background);
            background: linear-gradient(to right,
                    transparent 12.5%, var(--shaded-background),
                    transparent, var(--shaded-background),
                    transparent, var(--shaded-background) 87.5%);
            background-size: 800% 100%;
            background-position-x: 100%;
            animation: hey-listen 2s linear;
        }
    }
    
    @keyframes hey-listen {
        0% {
            background-position-x: 0%;
        }
    
        100% {
            background-position-x: 100%;
        }
    }
    
    /*