/* @see: https://thecascade.dev/article/least-amount-of-css/ */
/* Daylight paper by default, blueprint - drafting blue under off-white line
   work - when the system asks for dark. The switch inverts whatever the system
   asked for, so #blueprint is checked exactly when the visible theme disagrees
   with the system preference. _partials/theme-memory.html stores the theme
   rather than that bit, so a later change of system preference can't invert a
   remembered choice. */
:root {
    color-scheme: light dark;
    --bg: light-dark(#fdfdfb, #062541);
    --ink: light-dark(#17181c, #eef3fb);
    --link: light-dark(#1a4f8a, #ffffff);
    --grid: light-dark(transparent, rgb(238 243 251 / 0.06));
    --grid-major: light-dark(transparent, rgb(238 243 251 / 0.1));
    --mono: ui-monospace, SFMono-Regular, Menlo, monospace;
    --panel: light-dark(rgb(23 24 28 / 0.04), rgb(238 243 251 / 0.06));
    /* an opacity, so there is no light-dark() to lean on */
    --machinery: 0.08;
}

/* the switch names the theme it would take you to */
.to-daylight {
    display: none;
}

@media (prefers-color-scheme: light) {
    :root:has(#blueprint:checked) {
        color-scheme: dark;
        --machinery: 0.15;

        .to-blueprint {
            display: none;
        }

        .to-daylight {
            display: inline;
        }
    }
}

@media (prefers-color-scheme: dark) {
    :root {
        --machinery: 0.15;
    }

    .to-blueprint {
        display: none;
    }

    .to-daylight {
        display: inline;
    }

    :root:has(#blueprint:checked) {
        color-scheme: light;
        --machinery: 0.08;

        .to-blueprint {
            display: inline;
        }

        .to-daylight {
            display: none;
        }
    }
}

html {
    background: var(--bg);
    color: var(--ink);
}

/* the grid is the paper, so it sits behind the clockwork (z-index -1) */
body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -2;
    pointer-events: none;
    background:
        repeating-linear-gradient(
            to right,
            var(--grid) 0 1px,
            transparent 1px 1.5rem
        ),
        repeating-linear-gradient(
            to bottom,
            var(--grid) 0 1px,
            transparent 1px 1.5rem
        ),
        repeating-linear-gradient(
            to right,
            var(--grid-major) 0 1px,
            transparent 1px 9rem
        ),
        repeating-linear-gradient(
            to bottom,
            var(--grid-major) 0 1px,
            transparent 1px 9rem
        );
}

a {
    color: var(--link);
}

body {
    font-family: system-ui;
    font-size: 1.25rem;
    line-height: 1.6;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

img,
svg,
video {
    max-width: 100%;
    display: block;
}

/* code is the machine register - the same mono the dossier fields are set in -
   and a block is a panel ruled onto the sheet */
code {
    font-family: var(--mono);
}

/* inline code runs inside a line, so it is tinted rather than boxed: a border
   would ride above and below the text it sits in */
:not(pre) > code {
    background: var(--panel);
    padding: 0.1em 0.35em;
    font-size: 0.85em;
    overflow-wrap: anywhere;
}

pre {
    background: var(--panel);
    /* a hairline at the plate frame's strength: full-strength ink is right for
       the one rule under a header, but not for a box around every command */
    border: 1px solid color-mix(in srgb, currentColor 22%, transparent);
    padding: 1rem 1.25rem;
    font-size: 1rem;
    line-height: 1.5;
    /* a long line scrolls inside the panel instead of widening the measure;
       Hugo gives the pre a tabindex so that scroll is reachable by keyboard */
    overflow-x: auto;
}

pre:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 2px;
}

main {
    max-width: min(70ch, 100% - 4rem);
    margin-inline: auto;
    padding-block: 2rem 4rem;
    flex: 1;
}

header {
    text-align: center;
    padding-block: 2rem;
}

/* the home link: inner pages define the header block as just this anchor, so it
   is the one direct child of body that is a link. Pinned opposite the theme
   switch - both sit in the gutter beside main's centred measure */
body > a {
    position: fixed;
    top: 1rem;
    left: 1rem;
    z-index: 1;
}

body > a:hover {
    opacity: 0.7;
}

footer {
    text-align: center;
    border-top: 1px solid currentColor;
    opacity: 0.6;
    width: 100%;
    font-size: xx-small;
}

article {
    backdrop-filter: blur(2px);
}

/* article footer (back-nav) is inline, not the page footer */
article > footer {
    border-top: none;
    opacity: 1;
    margin-top: 3rem;
}

/* post/section list */
ol {
    list-style: none;
    padding: 0;
}

ol li + li {
    margin-top: 1.5rem;
}

ol article {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 0.25rem 1rem;
    align-items: baseline;
}

ol article a {
    font-size: 1.1rem;
}

ol article time {
    font-size: 0.85rem;
    opacity: 0.7;
    white-space: nowrap;
}

ol article p {
    grid-column: 1 / -1;
    margin: 0.25rem 0 0;
    font-size: 1rem;
    opacity: 0.8;
}

/* single post */
article > header {
    text-align: left;
    padding-block: 0 1rem;
    border-bottom: 1px solid currentColor;
    margin-bottom: 2rem;
}

article > header h1 {
    margin-bottom: 0.25rem;
}

article > header p {
    margin: 0;
    font-size: 0.9rem;
    opacity: 0.7;
}

/* clockwork background: fixed line-drawn machinery behind everything */
.clockwork {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    max-width: none;
    z-index: -1;
    pointer-events: none;
    opacity: var(--machinery);
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
}

.clockwork .cw-spin {
    animation: cw-rotate linear infinite;
    transform-box: fill-box;
    transform-origin: center;
}

.clockwork .cw-belt {
    stroke-dasharray: 16 12;
    animation: cw-crawl linear infinite;
}

@keyframes cw-rotate {
    to {
        transform: rotate(360deg);
    }
}

@keyframes cw-crawl {
    to {
        stroke-dashoffset: -28;
    }
}

@media (prefers-reduced-motion: reduce) {
    .clockwork .cw-spin,
    .clockwork .cw-belt {
        animation: none;
    }
}

/* home nav tiles */
.home-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem;
    list-style: none;
    padding: 0;

    a {
        flex: 1 1 min(16ch, 100%);
        border-bottom: 1px solid currentColor;
        text-decoration: none;
        color: inherit;

        h2 {
            transform: translateY(0.8rem);
        }

        &:hover {
            opacity: 0.7;
        }
    }

    h2 {
        margin: 0;
    }
}

/* theme switch: the checkbox stays focusable (not [hidden]), the label is the
   visible control, and only the label for the *other* theme is shown */
.blueprint-input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    clip-path: inset(50%);
    overflow: hidden;
}

.blueprint-switch {
    position: fixed;
    top: 1rem;
    right: 1rem;
    z-index: 1;
    padding: 0.2rem 0.7rem;
    font-size: 0.75rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    border: 1px solid currentColor;
    cursor: pointer;
}

.blueprint-switch:hover {
    opacity: 0.7;
}

.blueprint-input:focus-visible + .blueprint-switch {
    outline: 2px solid currentColor;
    outline-offset: 2px;
}


/* Systems: dossier sheets. Field labels reuse the drafting register the theme
   switch already sets - uppercase, letterspaced, small - and every rule here is
   the site's own 1px solid currentColor, not a tinted hairline. */
.plate {
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.plate-frame {
    stroke-opacity: 0.22;
}

.plate-ticks {
    stroke-opacity: 0.75;
}

.fields dt,
.dossier-label {
    font-size: 0.7rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    opacity: 0.55;
}

/* a repo is a machine path, so it is set in mono; a status is one of a fixed
   few words, so it is set in the label register instead */
.fields dd {
    margin: 0;
    font-size: 0.85rem;
    font-family: var(--mono);
    overflow-wrap: anywhere;
}

.fields .state {
    font-family: inherit;
    font-size: 0.75rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.fields dd + dt {
    margin-top: 0.5rem;
}

.fields-inline {
    display: flex;
    flex-wrap: wrap;
    gap: 0.875rem 2.75rem;
    padding-block: 1rem;
    border-block: 1px solid currentColor;
}

.fields-inline > div {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}

.fields-inline dd + dt {
    margin-top: 0;
}

/* the plates carry the index, so it is the one page that leaves the 70ch
   measure - the posts and rules lists keep the narrow column */
main:has(> .systems) {
    max-width: min(1080px, 100% - 4rem);
}

.systems {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 2.75rem 2rem;
    margin-top: 2.5rem;
}

.systems li + li {
    margin-top: 0;
}

.systems > li {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.systems > li[data-status="Archived"] {
    opacity: 0.55;
}

.systems > li > a {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    color: inherit;
    text-decoration: none;
}

.systems h2 {
    margin: 0;
    font-size: 1.2rem;
    color: var(--link);
    text-decoration: underline;
    text-underline-offset: 4px;
}

.systems > li > a:hover h2 {
    text-decoration-thickness: 2px;
}

.systems > li > a:hover .plate-frame {
    stroke-opacity: 0.5;
}

/* three lines keeps every card the same height whatever the problem statement
   runs to; the whole statement is on the system's own page */
.systems > li > p {
    margin: 0;
    font-size: 0.95rem;
    opacity: 0.8;
    text-wrap: pretty;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    overflow: hidden;
}

.systems .fields {
    margin: auto 0 0;
    padding-top: 0.75rem;
    border-top: 1px solid currentColor;
}

/* system page */
.dossier-id {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    font-size: 0.7rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    opacity: 0.55;
}

.dossier-top {
    display: grid;
    grid-template-columns: 300px minmax(0, 1fr);
    gap: 0 1.75rem;
    align-items: start;
    margin-bottom: 2rem;
}

.dossier-top .plate {
    width: 300px;
    height: 210px;
}

.dossier-top p {
    margin: 0.5rem 0 0;
    font-size: 1.05rem;
    text-wrap: pretty;
}

.dossier .fields-inline {
    margin-bottom: 2rem;
}

/* narrow: the grid sheds columns, and the plate stops being a fixed 300px
   track so the problem statement below it keeps a full line to itself */
@media (max-width: 56rem) {
    .systems {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 38rem) {
    .systems {
        grid-template-columns: minmax(0, 1fr);
    }

    .dossier-top {
        grid-template-columns: minmax(0, 1fr);
        gap: 1rem;
    }

    .dossier-top .plate {
        width: 100%;
        height: auto;
    }
}
