:root {
    /* Side margin of the page; shrinks with the window in the wide layout. */
    --side: clamp(1rem, 2vw, 2rem);
    --bg: #000;
    --fg: #ccc;
    --strong: #eee;
    --dim: #777;
    /* Konsole BackgroundIntense */
    --code-bg: #151515;
    --blue: #28a1c5;
    --red: #b52c27;
    --orange: #df8a13;
    --line: #333;
    --mono: ui-monospace, "DejaVu Sans Mono", "Liberation Mono", Menlo, Consolas, monospace;
    --sans: system-ui, -apple-system, "Segoe UI", "Noto Sans", "DejaVu Sans", sans-serif;
    /* Long enough for any width; ASCII rules are clipped to their box. */
    --dashes: "------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------";
}

*, *::before, *::after {
    box-sizing: border-box;
}

html {
    font-family: var(--sans);
    font-size: 100%;
    line-height: 1.6;
    color: var(--fg);
    background: var(--bg);
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    padding: 2rem 1.25rem;
}

/* Layout: menu above the content on narrow screens, beside it on wide ones. */

@media (min-width: 64em) {
    body {
        display: grid;
        /* Menu | text | contents. The menu shrinks with the window down to the ~11rem the logo needs.
         * The text column is filled first, up to its 42rem reading width (full at 1280px, ~35rem at
         * 1024px); the contents column then takes everything left up to the right margin, never less
         * than 12rem, so titles only get an ellipsis when space really runs out.
         * Pages without a table of contents simply leave the third column empty. */
        grid-template-columns: clamp(11rem, 15vw, 18rem) minmax(0, 42rem) minmax(12rem, 1fr);
        column-gap: clamp(1.5rem, 2.5vw, 4rem);
        padding: 4.5rem var(--side) 3rem;
    }
    .sidebar {
        position: sticky;
        top: 4.5rem;
        align-self: start;
    }
}

/* Prose is proportional; everything that frames it stays monospace. */
.sidebar,
h1, h2, h3, h4,
code,
.notice::before,
.notice::after {
    font-family: var(--mono);
}

/* Top bar: the site description on the left, links to other HNet services on the right.
 * Fixed at the top on wide screens, above the logo (scrolling with the page) on narrow ones. */

.topbar {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: baseline;
    column-gap: 3ch;
    margin-bottom: 1.5rem;
    font-family: var(--mono);
    color: var(--dim);
}
.services {
    margin-left: auto;
    text-align: right;
}
/* The description comes from an attribute and is drawn by CSS on wide screens only,
 * so phones and text browsers (which ignore CSS) don't show it at all. */
.tagline {
    display: none;
}
@media (min-width: 64em) {
    .tagline {
        display: block;
    }
    /* "HNet - HKr's space": the title in the colour of the service names, the description dimmed. */
    .tagline::before {
        content: attr(data-title);
        color: var(--strong);
    }
    .tagline::after {
        content: " - " attr(data-text);
    }
}
.services .service {
    display: inline-block;
    white-space: nowrap;
}
.services .name {
    color: var(--strong);
}
.services .sep + .service {
    margin-left: 3ch;
}
/* Separators exist for text browsers, which ignore CSS; graphical browsers space services by margin. */
.services .sep {
    display: none;
}
.services a {
    color: var(--blue);
    text-decoration: none;
}
.services a:hover,
.services a:focus {
    text-decoration: underline;
}

/* An ASCII rule separates the bar from the rest of the page. On narrow screens it runs right under the bar,
 * as a full-width flex item that always wraps onto its own line. */
.topbar::after {
    content: var(--dashes);
    flex-basis: 100%;
    margin-top: .25rem;
    overflow: hidden;
    white-space: nowrap;
}

/* On wide screens the bar stays in view like the sidebar: it is fixed in the body's top padding,
 * on top of a band of page background ending with a rule across the whole page between the side
 * margins. The page scrolls underneath the band, and the content column starts below it. */
@media (min-width: 64em) {
    html {
        scroll-padding-top: 4.5rem;
    }
    .topbar {
        position: fixed;
        z-index: 11;
        top: .9rem;
        left: var(--side);
        right: var(--side);
        margin: 0;
    }
    .topbar::after {
        content: none;
    }
    body::before {
        content: var(--dashes);
        position: fixed;
        z-index: 10;
        top: 0;
        left: 0;
        right: 0;
        /* A border, not padding: overflow clips at the padding edge, so the dashes stop at the side margins. */
        border: solid var(--bg);
        border-width: 2.5rem var(--side) 0;
        overflow: hidden;
        white-space: nowrap;
        background: var(--bg);
    }
}

/* Table of contents of an article, drawn like the output of `tree`, in the third column of the wide layout.
 * It stays in view like the sidebar and scrolls on its own when it's taller than the window.
 * Hidden on phones. */
.toc {
    display: none;
}
@media (min-width: 64em) {
    .toc {
        display: block;
        position: sticky;
        top: 4.5rem;
        align-self: start;
        max-height: calc(100vh - 6rem);
        overflow-y: auto;
        font-family: var(--mono);
        font-size: .9rem;
        line-height: 1.4;
    }
    /* Everything visible is generated from data attributes; see templates/page.html. */
    .toc::before {
        content: attr(data-title);
        display: block;
        margin-bottom: .5rem;
        color: var(--strong);
        font-weight: bold;
    }
    .toc-row {
        display: flex;
    }
    /* Tree prefix; the "/ """ form keeps screen readers from reading out the pipes and dashes where supported. */
    .toc-row::before {
        content: attr(data-tree);
        content: attr(data-tree) / "";
        flex: none;
        white-space: pre;
        color: var(--dim);
    }
    .toc-row a::before {
        content: attr(data-title);
    }
    /* One line per entry; titles that don't fit end in an ellipsis (the full title is in the tooltip). */
    .toc-row a {
        min-width: 0;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
    }
    /* Chapters in the bright colour of headings in the text, subsections dimmed like the tree lines. */
    .toc a {
        color: var(--dim);
        text-decoration: none;
    }
    .toc .chapter a {
        color: var(--strong);
    }
    .toc a:hover,
    .toc a:focus {
        color: var(--blue);
        text-decoration: underline;
    }
}

/* Sidebar */

.logo {
    display: inline-block;
    text-decoration: none;
}
.logo pre {
    margin: 0 0 1.5rem;
    padding: 0;
    background: none;
    border: 0;
    font-size: 1.6rem;
    font-weight: bold;
    line-height: 1.15;
    overflow: visible;
}
.logo .b { color: var(--blue); }
.logo .r { color: var(--red); }
.logo .w { color: #fefefc; }

/* The menu is a list so text browsers put each item on its own line. */
.sidebar nav ul {
    list-style: none;
    margin: 0;
    padding: 0;
}
.sidebar nav li {
    margin: 0;
}

.sidebar nav a {
    display: block;
    color: var(--strong);
    text-decoration: none;
    white-space: pre;
}
.sidebar nav a::before {
    content: "  ";
}
.sidebar nav a.active::before {
    content: "> ";
    color: var(--blue);
}
.sidebar nav a:hover,
.sidebar nav a:focus {
    text-decoration: underline;
}

.sidebar footer {
    margin-top: 1.5rem;
    color: var(--dim);
    font-size: .875rem;
}

@media (max-width: 63.99em) {
    .sidebar {
        margin-bottom: 2.5rem;
    }
    .sidebar::after {
        content: var(--dashes);
        display: block;
        margin-top: 1.5rem;
        overflow: hidden;
        white-space: nowrap;
    }
}

/* Content */

.content {
    max-width: 42rem;
}

h1, h2, h3, h4 {
    color: var(--strong);
    line-height: 1.3;
    margin: 2rem 0 1rem;
}
h1 { font-size: 1.5rem; margin-top: 0; }
h2 { font-size: 1.25rem; }
h3, h4 { font-size: 1rem; }

strong { color: var(--strong); }

a {
    color: var(--blue);
}
a:hover,
a:focus {
    color: var(--strong);
}

code {
    font-size: .9em;
    color: var(--orange);
}

/* Code blocks are framed by text rules instead of a shaded box:
 * +-- config ----------
 * ...
 * +--------------------
 */
pre {
    margin: 1.25rem 0;
    padding: .5rem .75rem;
    background: var(--code-bg);
    overflow-x: auto;
    line-height: 1.4;
}
pre code {
    display: block;
    color: var(--fg);
    font-size: .9rem;
}
pre code::before,
pre code::after,
.notice::before,
.notice::after {
    display: block;
    overflow: hidden;
    white-space: nowrap;
    color: var(--dim);
}
pre code::before {
    content: "+-- " attr(data-name) " " var(--dashes);
}

/* Giallo lines, line numbers and highlighted lines (hl_lines).
 * Colors from the design pass, paired with highlighting/hnet.json. */
pre.giallo .giallo-l {
    display: inline-block;
    box-sizing: border-box;
    min-height: 1lh;
    min-width: 100%;
    position: relative;
    vertical-align: top;
}

/* The 2ch gutter for the ">" marker only where a block has highlighted lines,
 * so ordinary blocks stay aligned with their ASCII frame. */
pre.giallo:has(.z-hl) .giallo-l {
    padding-left: 2ch;
}
pre.giallo .giallo-l.z-hl {
    background-color: #212121;
}
pre.giallo .giallo-l.z-hl::after {
    content: ">";
    position: absolute;
    top: 0;
    left: 0;
    color: var(--orange);
}

pre.giallo .giallo-ln {
    display: inline-block;
    min-width: 3ch;
    margin-right: 2ch;
    text-align: right;
    color: #555;
    -webkit-user-select: none;
    user-select: none;
}
pre.giallo .giallo-l.z-hl > .giallo-ln {
    color: #9a9a9a;
}

pre.giallo ::selection {
    background-color: #222c38;
}
pre code::after,
.notice::after {
    content: "+" var(--dashes);
}

blockquote {
    margin: 1rem 0 1rem 2ch;
    color: var(--dim);
}

ol, ul {
    padding-left: 2.5em;
}
li + li {
    margin-top: .4rem;
}

/* Tables drawn as a full ASCII grid:
 * +----------+----------+
 * | Header   | Header   |
 * +----------+----------+
 * | cell     | cell     |
 * +----------+----------+
 * Column widths are rarely whole characters, so every horizontal rule is one continuous run of dashes
 * across the full table width (rows draw theirs in tr::before, the table closes with ::after); rules
 * restarted in each cell would drift out of phase with each other. Cells draw only their left "|"
 * column, topped by a "+" whose background hides the dash under the joint; rows draw the right edge.
 * Rows sit on a fixed line grid (no other vertical padding) so the bars join up between rows.
 * Wide tables scroll sideways instead of stretching the page on narrow screens. */
table {
    --bars: "|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A|\A";
    --rule: 1.3em;
    --cell-bg: var(--bg);
    position: relative;
    display: block;
    width: max-content;
    max-width: 100%;
    overflow-x: auto;
    border-collapse: collapse;
    margin: 1.5rem 0;
    padding-bottom: var(--rule);
    font-family: var(--mono);
    font-size: .9rem;
    line-height: 1.3;
}
tr {
    position: relative;
}
th, td {
    position: relative;
    padding: var(--rule) 1ch 0 2ch;
    text-align: left;
    vertical-align: top;
}
th:last-child,
td:last-child {
    padding-right: 2ch;
}
th {
    --cell-bg: var(--code-bg);
    color: var(--strong);
    background: var(--code-bg);
}
/* The rule between header and body belongs to the first body row; shade it like the header. */
thead tr,
tbody tr:first-child {
    --cell-bg: var(--code-bg);
}
tbody tr:first-child > td {
    background: linear-gradient(var(--code-bg), var(--code-bg)) top / 100% var(--rule) no-repeat;
}

tr::before,
table::after,
th::before,
td::before,
tr::after,
tbody tr:last-child > td + td::after,
table::before,
tbody::after {
    position: absolute;
    overflow: hidden;
    color: var(--dim);
    font-weight: normal;
}
/* Horizontal rules: one per row at its top, one closing the table. */
tr::before,
table::after {
    content: var(--dashes);
    z-index: 1;
    left: 0;
    right: 0;
    white-space: nowrap;
}
tr::before {
    top: 0;
}
table::after {
    bottom: 0;
}
/* Left column of each cell, and the right edge of each row: + at the joint, | below. */
th::before,
td::before,
tr::after {
    content: "+\A" var(--bars);
    top: 0;
    bottom: 0;
    z-index: 2;
    width: 1ch;
    white-space: pre;
    background: linear-gradient(var(--cell-bg), var(--cell-bg)) top / 100% var(--rule) no-repeat;
}
th::before,
td::before {
    left: 0;
}
tr::after {
    right: 0;
}
/* Joints and corners on the closing rule. */
tbody tr:last-child > td + td::after,
table::before,
tbody::after {
    content: "+";
    z-index: 2;
    width: 1ch;
    background: var(--bg);
}
tbody tr:last-child > td + td::after {
    left: 0;
    bottom: calc(-1 * var(--rule));
}
table::before {
    left: 0;
    bottom: 0;
}
/* Bottom right corner: tbody spans exactly the table width and ends right above the closing rule. */
tbody {
    position: relative;
}
tbody::after {
    right: 0;
    bottom: calc(-1 * var(--rule));
}

/* Section listings */

.posts li p {
    margin: .25rem 0 0;
    color: var(--dim);
}

/* Notices, replacing the markdown-notices plugin of the old site */

.notice {
    margin: 1.5rem 0;
}
.notice p {
    margin: .5rem 0;
}
.notice.info { color: var(--blue); }
.notice.warn { color: var(--orange); }
.notice.info::before { content: "+-- [i] " var(--dashes); }
.notice.warn::before { content: "+-- [!] " var(--dashes); }
.notice a { color: inherit; }

/* Shell prompt for command blocks; added by CSS so it isn't copied with the command. */
code[data-name="command"] .giallo-l::before {
    content: "$ ";
    color: var(--dim);
}
/* Blank lines separate groups of commands and get no prompt. */
code[data-name="command"] .giallo-l:empty::before {
    content: none;
}

/* Every ASCII line on the page shares one look: separators, code block and notice frames, the table grid. */
body::before,
.topbar::after,
.sidebar::after,
pre code::before,
pre code::after,
.notice::before,
.notice::after,
table::before,
table::after,
tbody::after,
tr::before,
tr::after,
th::before,
td::before,
td::after {
    font-family: var(--mono);
    font-size: .9rem;
    font-weight: normal;
    color: var(--dim);
}

/* Exception: notice frames keep the notice's colour, so the kind of notice reads from the frame too. */
.notice::before,
.notice::after {
    color: inherit;
}
