Put the contents beside the text instead of above it
Nineteen entries at the top of a long page are scrolled past once and then unreachable. A fixed column stays put and scrolls on its own. Below 66rem there is not room for two columns, so it collapses to a bar with a toggle — a checkbox, so the page still needs no script to navigate. The wordmark's dot was a circle at a guessed x, which drifted from the n whenever the reader's serif was not the one it was measured against. It is a full stop in the same text run now.
This commit is contained in:
parent
403e598145
commit
d995094b52
119
web/index.html
119
web/index.html
@ -67,6 +67,7 @@ body {
|
||||
color: var(--text);
|
||||
font: 17px/1.65 "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
|
||||
}
|
||||
main { display: block; }
|
||||
.wrap { max-width: 44rem; margin: 0 auto; padding: 0 1.25rem 6rem; }
|
||||
|
||||
header { padding: 3.5rem 0 2rem; }
|
||||
@ -117,12 +118,63 @@ th { font-weight: 600; color: var(--muted); }
|
||||
|
||||
.lede { font-size: 1.1rem; }
|
||||
.note { color: var(--muted); font-size: .94rem; }
|
||||
nav.toc { background: var(--panel); border-radius: 5px; padding: 1rem 1.25rem; margin: 2rem 0 0; }
|
||||
nav.toc ul { list-style: none; padding: 0; margin: 0; columns: 2; column-gap: 2rem; }
|
||||
nav.toc li { margin: .18rem 0; font-size: .93rem; break-inside: avoid; }
|
||||
|
||||
/* The table of contents: a bar with a toggle when the window is narrow, a
|
||||
fixed column beside the text when there is room for one. The toggle is a
|
||||
checkbox so that no script is needed to open it. */
|
||||
.toc-toggle { position: absolute; width: 1px; height: 1px; opacity: 0; }
|
||||
.toc-button {
|
||||
display: block; cursor: pointer; user-select: none;
|
||||
position: sticky; top: 0; z-index: 2;
|
||||
padding: .6rem 1.25rem;
|
||||
background: var(--panel); border-bottom: 1px solid var(--rule);
|
||||
color: var(--muted); font-size: .92rem; letter-spacing: .02em;
|
||||
}
|
||||
.toc-button::before { content: "\2261\00a0\00a0"; }
|
||||
.toc-toggle:focus-visible + .toc-button { outline: 2px solid var(--accent); outline-offset: -2px; }
|
||||
nav.toc {
|
||||
display: none;
|
||||
background: var(--panel); border-bottom: 1px solid var(--rule);
|
||||
padding: .75rem 1.25rem 1.1rem;
|
||||
}
|
||||
.toc-toggle:checked ~ nav.toc { display: block; }
|
||||
.toc-title {
|
||||
display: none; /* the toggle already says "Contents" */
|
||||
margin: 0 0 .5rem; font-size: .78rem; letter-spacing: .09em;
|
||||
text-transform: uppercase; color: var(--muted);
|
||||
}
|
||||
nav.toc ul { list-style: none; padding: 0; margin: 0; }
|
||||
nav.toc li { margin: 0; font-size: .93rem; }
|
||||
nav.toc a {
|
||||
display: block; padding: .2rem 0; color: var(--muted);
|
||||
text-decoration: none; border-left: 2px solid transparent; padding-left: .6rem;
|
||||
}
|
||||
nav.toc a:hover { color: var(--link); border-left-color: var(--accent); }
|
||||
h2, h3 { scroll-margin-top: 3.5rem; }
|
||||
|
||||
/* Nineteen entries one to a line fills a phone screen, so the opened panel
|
||||
goes to two columns as soon as there is room for them. */
|
||||
@media (min-width: 30rem) and (max-width: 65.99rem) {
|
||||
nav.toc ul { columns: 2; column-gap: 1.5rem; }
|
||||
nav.toc li { break-inside: avoid; }
|
||||
}
|
||||
footer { margin-top: 3.5rem; padding-top: 1.5rem; border-top: 1px solid var(--rule); color: var(--muted); font-size: .92rem; }
|
||||
|
||||
@media (max-width: 34rem) { nav.toc ul { columns: 1; } }
|
||||
/* Wide enough for both: the contents become a column of their own, scrolling
|
||||
independently of the page, and the text moves over to sit beside it. */
|
||||
@media (min-width: 66rem) {
|
||||
.toc-button { display: none; }
|
||||
nav.toc {
|
||||
display: block;
|
||||
position: fixed; top: 0; left: 0; bottom: 0;
|
||||
width: 15rem; overflow-y: auto; overscroll-behavior: contain;
|
||||
background: none; border-bottom: 0; border-right: 1px solid var(--rule);
|
||||
padding: 3.6rem 1rem 2rem 1.5rem;
|
||||
}
|
||||
main { margin-left: 15rem; }
|
||||
.toc-title { display: block; }
|
||||
h2, h3 { scroll-margin-top: 1rem; }
|
||||
}
|
||||
|
||||
.c { color: var(--c-comment); font-style: italic; }
|
||||
.s { color: var(--c-string); }
|
||||
@ -133,34 +185,11 @@ footer { margin-top: 3.5rem; padding-top: 1.5rem; border-top: 1px solid var(--ru
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrap">
|
||||
|
||||
<header>
|
||||
<svg class="mark" viewBox="0 0 210 44" role="img" aria-label="Flan">
|
||||
<text x="0" y="33" font-family="Iowan Old Style, Palatino, Georgia, serif"
|
||||
font-size="38" font-weight="600" letter-spacing="1.5"
|
||||
fill="currentColor">flan</text>
|
||||
<circle cx="128" cy="28" r="3.4" fill="var(--accent)"/>
|
||||
</svg>
|
||||
<p class="tagline">A statically typed Lisp for game development. Clojure's brackets,
|
||||
C's memory and value model, no garbage collector.</p>
|
||||
</header>
|
||||
|
||||
<p class="lede">Flan compiles s-expressions to LLVM IR and then to a native binary.
|
||||
There are no object headers, so a Flan struct is exactly its C struct. There is no
|
||||
collector, so nothing runs between frames that you did not write. And a running
|
||||
program can be edited: a function recompiled in Emacs is installed into the live
|
||||
process at its next frame boundary, in about twenty milliseconds.</p>
|
||||
|
||||
<p>This page describes the compiler <em>as it is</em>, not as it is planned. Where
|
||||
something is designed but not built, it says so and gives the message the compiler
|
||||
prints for it. Every Flan program on this page is a file in <code>web/examples/</code>
|
||||
with its output recorded beside it; <code>sh web/examples/check.sh</code> runs them all
|
||||
and compares, and <code>quotes.sh</code> re-derives the blocks that are transcripts
|
||||
rather than programs. If the page and the compiler disagree, one of those two goes
|
||||
red.</p>
|
||||
<input type="checkbox" id="toc-toggle" class="toc-toggle">
|
||||
<label class="toc-button" for="toc-toggle">Contents</label>
|
||||
|
||||
<nav class="toc" aria-label="Contents">
|
||||
<p class="toc-title">Contents</p>
|
||||
<ul>
|
||||
<li><a href="#what">What Flan is</a></li>
|
||||
<li><a href="#start">Getting started</a></li>
|
||||
@ -184,6 +213,35 @@ red.</p>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<main>
|
||||
<div class="wrap">
|
||||
|
||||
<header>
|
||||
<svg class="mark" viewBox="0 0 118 44" role="img" aria-label="Flan">
|
||||
<!-- The dot is a full stop in the same run, so it stays beside the n
|
||||
whichever serif the reader actually has. -->
|
||||
<text x="0" y="33" font-family="Iowan Old Style, Palatino, Georgia, serif"
|
||||
font-size="38" font-weight="600" letter-spacing="1"
|
||||
fill="currentColor">flan<tspan fill="var(--accent)">.</tspan></text>
|
||||
</svg>
|
||||
<p class="tagline">A statically typed Lisp for game development. Clojure's brackets,
|
||||
C's memory and value model, no garbage collector.</p>
|
||||
</header>
|
||||
|
||||
<p class="lede">Flan compiles s-expressions to LLVM IR and then to a native binary.
|
||||
There are no object headers, so a Flan struct is exactly its C struct. There is no
|
||||
collector, so nothing runs between frames that you did not write. And a running
|
||||
program can be edited: a function recompiled in Emacs is installed into the live
|
||||
process at its next frame boundary, in about twenty milliseconds.</p>
|
||||
|
||||
<p>This page describes the compiler <em>as it is</em>, not as it is planned. Where
|
||||
something is designed but not built, it says so and gives the message the compiler
|
||||
prints for it. Every Flan program on this page is a file in <code>web/examples/</code>
|
||||
with its output recorded beside it; <code>sh web/examples/check.sh</code> runs them all
|
||||
and compares, and <code>quotes.sh</code> re-derives the blocks that are transcripts
|
||||
rather than programs. If the page and the compiler disagree, one of those two goes
|
||||
red.</p>
|
||||
|
||||
<h2 id="what">What Flan is</h2>
|
||||
|
||||
<p>A minimal Lisp for games. In one line: Odin with a Lisp frontend and a live REPL.
|
||||
@ -1304,6 +1362,7 @@ macro is a function from <code>Form</code> to <code>Form</code>, which needs
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
// A small hand-written highlighter for the Flan blocks. One pass, no library.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user