/* The plugin's own palette, taken from Source/UI/Theme.h so the page and the
   instrument cannot drift apart.

   One colour deliberately does. The instrument's dim text is #6f7a86, which
   comes to 4.45 against the page background and 4.08 against a panel, either
   side of the 4.5 the contrast standard asks for at this size. The page lifts
   it to clear that on every surface it lands on: 5.76 on the background, 5.28
   on a panel, 5.02 on the alternate. Everything else here is the instrument's
   value unchanged. */
:root {
    --background: #0b0d10;
    --panel: #14181d;
    --panel-alt: #181d23;
    --groove: #090b0e;
    --outline: #272e37;
    --text: #d9dfe7;
    --text-dim: #838d97;
    --accent: #62bbd9;
    --warn: #e0733d;
    --hold: #e8c34a;

    --measure: 77ch;
    --page: 1180px;
}

* {
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
}

body {
    margin: 0;
    padding: 0 24px 96px;
    background: var(--background);
    color: var(--text);
    font:
        400 17px/1.65 ui-sans-serif,
        system-ui,
        -apple-system,
        "Segoe UI",
        Roboto,
        Helvetica,
        Arial,
        sans-serif;
    -webkit-font-smoothing: antialiased;
}

.page {
    max-width: var(--page);
    margin: 0 auto;
}

/* ---- masthead ------------------------------------------------------------ */

header {
    padding: 72px 0 8px;
}

h1 {
    margin: 0;
}

.wordmark {
    width: 100%;
    max-width: 460px;
    height: auto;
    display: block;
}

/* The heading a search engine and a screen reader read, where the wordmark is
   the one everyone else does. */
.offscreen {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.tagline {
    color: var(--text-dim);
    font-size: 15px;
    letter-spacing: 0.04em;
    margin: 6px 0 0;
}

/* ---- hero ---------------------------------------------------------------- */

/* The front page carries its name inside the hero picture, so its masthead is
   the section nav on its own with no wordmark to leave room for. */
header.nav-only {
    padding-top: 28px;
}

header.nav-only .sections {
    margin-top: 0;
}

.hero {
    margin-top: 28px;
}

/* The frame stacks three layers: the window shot, a scrim, and the reading
   matter. Its height comes from that content rather than from an aspect ratio,
   because the copy inside it wraps differently at every width and a fixed ratio
   would either crop the buttons off or leave a gap under them.

   isolation keeps the z-indexes below from competing with anything on the rest
   of the page. */
.hero-frame {
    position: relative;
    isolation: isolate;
    display: grid;
    place-items: center;
    overflow: hidden;
    min-height: 520px;
    padding: clamp(40px, 5.5vw, 76px) clamp(20px, 4vw, 56px);
    border: 1px solid var(--outline);
    border-radius: 6px;
    background: var(--groove);
}

/* Two elements rather than one because two transforms have to compose: the
   wrapper carries the scroll parallax and the picture inside it carries a slow
   drift of its own. One element cannot run both, since they would be the same
   property fighting over the same value. */
.hero-back {
    position: absolute;
    inset: 0;
    z-index: 0;
}

/* Texture, and nothing a reader has to make out, so cover may crop it freely.
   The zoom is headroom for the motion: at its smallest it leaves 13% of
   overhang on each edge, and the parallax and the drift together never ask for
   more than 10%. Kept on whether they run or not, so the framing does not
   change between browsers. */
.hero-back-img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transform: scale(1.26);
}

/* Held as light as the text will allow, so the mixer stays legible as a picture
   rather than becoming a dark smear behind a paragraph. Measured against the
   brightest patch under each line with the breath at its peak: the tagline
   lands at 6.2:1 and the paragraph at 8.7:1, where the standard asks 4.5.

   The colour is --background, which a gradient cannot take from a custom
   property without losing the alpha. */
.hero-frame::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    background: radial-gradient(82% 76% at 50% 44%, rgba(11, 13, 16, 0.16) 0%, rgba(11, 13, 16, 0.5) 58%, rgba(11, 13, 16, 0.78) 100%);
}

/* Wide enough for the four buttons to sit on one row, which needs about 690px
   at the widest font a browser is likely to pick. The mark and the paragraph
   have their own narrower caps, so only the button row spends the extra. */
.hero-body {
    position: relative;
    z-index: 2;
    display: grid;
    justify-items: center;
    max-width: 760px;
    text-align: center;
}

.hero-body h1 {
    margin: 0;
    width: 100%;
}

/* The mark carries its own halo, so it needs no drop-shadow here. */
.hero-mark {
    display: block;
    width: 100%;
    max-width: 600px;
    height: auto;
    margin: 0 auto;
}

/* Full strength rather than --text-dim: the dim tone is set for the page
   background, and over a picture at this scrim it stops carrying enough
   contrast to read at 15px. */
.hero .tagline {
    margin-top: 22px;
    color: var(--text);
    opacity: 0.85;
    text-shadow: 0 1px 10px rgba(11, 13, 16, 0.7);
}

/* Smaller than the 21px a lead runs at on the page. Centred over a picture it
   is read in a glance rather than settled into, and four lines glance better
   than five. */
.hero .lead {
    margin-top: 10px;
    max-width: 58ch;
    font-size: 19px;
    text-shadow: 0 1px 12px rgba(11, 13, 16, 0.8);
}

.hero .links {
    justify-content: center;
    margin-top: 30px;
}

/* Translucent over the picture, where the flat panel fill the buttons use
   elsewhere would read as a row of holes punched through it.

   No backdrop-filter. A blurred backdrop has to be recomputed from the pixels
   underneath on every frame, and the pixels underneath are a large picture that
   moves as you scroll, which made the whole page stutter. The extra opacity
   does the same job for nothing. */
.hero .links a {
    background: rgba(20, 24, 29, 0.82);
    border-color: rgba(217, 223, 231, 0.18);
}

.hero .links a:hover {
    border-color: var(--accent);
    color: var(--accent);
}

.hero .links a.primary {
    border-color: var(--accent);
    background: rgba(98, 187, 217, 0.16);
    color: var(--accent);
}

.hero .links a.primary:hover {
    background: var(--accent);
    color: var(--background);
}

/* ---- hero motion ----------------------------------------------------------

   Three movements: the picture drifts slowly on its own, it lags the page on
   scroll, and the mark breathes. All decoration, so all behind
   prefers-reduced-motion.

   Only transform and opacity are animated on the picture, never filter. A
   filter has to repaint the element every frame, and this one is 2360 pixels
   wide, which is enough to make the whole page stutter while scrolling.
   Transforms are handed to the compositor and cost nothing per frame.

   The mark keeps a filter because there it is both cheap and visible: it is a
   600 pixel element, and its pixels are bright, so the same swing that moves a
   near-black picture by 4 levels of 255 moves the glyphs by 15.
   -------------------------------------------------------------------------- */

@keyframes hero-mark-lift {
    from {
        filter: saturate(0.94) brightness(0.96);
    }
    to {
        filter: saturate(1.18) brightness(1.1);
    }
}

/* Slow enough to read as the picture being alive rather than as something
   sliding. Geometry, unlike tone, is visible on an image this dark. */
@keyframes hero-drift {
    from {
        transform: scale(1.26) translate3d(-1.2%, -0.8%, 0);
    }
    to {
        transform: scale(1.36) translate3d(1.2%, 1.2%, 0);
    }
}

@keyframes hero-parallax {
    from {
        transform: translate3d(0, -6%, 0);
    }
    to {
        transform: translate3d(0, 8%, 0);
    }
}

@media (prefers-reduced-motion: no-preference) {
    .hero-back-img {
        animation: hero-drift 44s ease-in-out infinite alternate;
    }

    .hero-mark {
        animation: hero-mark-lift 9s ease-in-out infinite alternate;
    }
}

/* The parallax is scroll-driven rather than scripted, so the page stays free of
   JavaScript. Browsers without scroll-driven animations keep the still picture
   and lose nothing else.

   The timeline is the document's own scroll over the first 90vh rather than the
   hero's passage through the viewport. A view() timeline spends half its range
   on the element entering, which an element already at the top of the page
   never does, so half the travel would be unreachable and the rest too small to
   notice.

   animation-timeline and animation-range come after the shorthand on purpose.
   The animation shorthand resets both to their initial values, so declaring
   them above it would leave the parallax running on the document clock. */
@supports (animation-timeline: scroll()) {
    @media (prefers-reduced-motion: no-preference) {
        .hero-back {
            animation: hero-parallax linear both;
            animation-timeline: scroll(root block);
            animation-range: 0 90vh;
            will-change: transform;
        }
    }
}

.links {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin: 28px 0 0;
    padding: 0;
    list-style: none;
}

.links a {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 9px 16px;
    border: 1px solid var(--outline);
    border-radius: 4px;
    background: var(--panel-alt);
    color: var(--text);
    font-size: 15px;
    text-decoration: none;
}

.links a:hover {
    border-color: var(--accent);
    color: var(--accent);
}

.links a.primary {
    border-color: var(--accent);
    color: var(--accent);
}

.links a.primary:hover {
    background: var(--accent);
    color: var(--background);
}

/* ---- text ---------------------------------------------------------------- */

main {
    padding-top: 8px;
}

section {
    padding: 44px 0 0;
}

h2 {
    font-size: 15px;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--accent);
    margin: 0 0 14px;
}

h3 {
    font-size: 18px;
    font-weight: 600;
    margin: 28px 0 8px;
}

p,
li,
dd {
    max-width: var(--measure);
}

/* text-wrap: pretty is what actually keeps a lone word off the last line. A
   wider measure only moves the breaks around, so whether any given paragraph
   ends in one word stays a matter of where its words happen to fall. This asks
   the browser to solve it for every paragraph at once, and browsers without it
   wrap as they always did. */
p {
    margin: 0 0 16px;
    text-wrap: pretty;
}

.lead {
    font-size: 21px;
    line-height: 1.55;
}

/* The single paragraph between the row of facts and the window shot, both of
   which run the full width of the page. At the ordinary measure it hangs off
   the left edge and reads as a stranded column, so it is centred and a size up.
   That makes the short line length look chosen rather than left over, and
   carries the hero's centred block one step further before the page settles
   into left-aligned prose. */
.intro {
    max-width: 62ch;
    margin: 30px auto 0;
    font-size: 19px;
    line-height: 1.6;
    text-align: center;
}

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

strong {
    color: #fff;
    font-weight: 600;
}

code {
    font:
        14px/1.5 ui-monospace,
        SFMono-Regular,
        Menlo,
        Consolas,
        monospace;
    background: var(--groove);
    border: 1px solid var(--outline);
    border-radius: 3px;
    padding: 1px 5px;
}

pre {
    background: var(--groove);
    border: 1px solid var(--outline);
    border-radius: 5px;
    padding: 16px 18px;
    overflow-x: auto;
    max-width: var(--measure);
}

pre code {
    background: none;
    border: 0;
    padding: 0;
}

/* ---- figures ------------------------------------------------------------- */

figure {
    margin: 28px 0 0;
}

figure img {
    display: block;
    width: 100%;
    height: auto;
    border: 1px solid var(--outline);
    border-radius: 6px;
}

figcaption {
    color: var(--text-dim);
    font-size: 14px;
    margin-top: 10px;
}

/* A tall crop beside its text, which folds under on a narrow window. */
.split {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 316px;
    gap: 40px;
    align-items: start;
}

.split figure {
    margin: 0;
}

.split figure img {
    max-width: 316px;
}

/* ---- the row of facts ---------------------------------------------------- */

.facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 1px;
    background: var(--outline);
    border: 1px solid var(--outline);
    border-radius: 6px;
    overflow: hidden;
    margin: 28px 0 0;
    padding: 0;
}

.facts > div {
    background: var(--panel);
    padding: 18px 20px;
}

.facts dt {
    color: var(--text-dim);
    font-size: 13px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.facts dd {
    margin: 4px 0 0;
    font-size: 17px;
}

/* ---- the questions ------------------------------------------------------- */

.qa {
    margin: 0;
}

.qa dt {
    font-weight: 600;
    color: #fff;
    margin: 24px 0 6px;
}

.qa dt:first-of-type {
    margin-top: 0;
}

.qa dd {
    margin: 0;
}

/* ---- footer -------------------------------------------------------------- */

footer {
    margin-top: 72px;
    padding-top: 28px;
    border-top: 1px solid var(--outline);
    color: var(--text-dim);
    font-size: 15px;
}

footer a {
    color: var(--text-dim);
}

footer a:hover {
    color: var(--accent);
}

.maker {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: 18px;
}

.maker img {
    width: 58px;
    height: auto;
    opacity: 0.55;
}

@media (max-width: 860px) {
    .split {
        grid-template-columns: minmax(0, 1fr);
    }

    header {
        padding-top: 44px;
    }

    header.nav-only {
        padding-top: 20px;
    }

    .hero-frame {
        min-height: 460px;
    }

    body {
        font-size: 16px;
    }
}

/* On a phone the copy alone fills the frame, so a floor on the height would
   only add empty space under the buttons. */
@media (max-width: 560px) {
    .hero-frame {
        min-height: 0;
    }

    .hero .lead {
        font-size: 17px;
    }
}

/* Section nav. The same list on every page, with the current one marked by
   aria-current rather than by a class, so the marker cannot drift from what a
   screen reader is told. */
.sections {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
    margin: 30px 0 0;
    padding: 0;
    list-style: none;
    border-bottom: 1px solid var(--outline);
}
.sections a {
    display: inline-block;
    padding: 10px 16px;
    color: var(--text-dim);
    font-size: 15px;
    text-decoration: none;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
}
.sections a:hover {
    color: var(--text);
}
.sections a[aria-current="page"] {
    color: var(--accent);
    border-bottom-color: var(--accent);
}

/* Breadcrumb, on the inner pages only. */
.crumbs {
    margin: 24px 0 0;
    color: var(--text-dim);
    font-size: 14px;
}
.crumbs a {
    color: var(--text-dim);
}
.crumbs a:hover {
    color: var(--accent);
}

/* Cards linking the sections from the overview. */
.cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 14px;
    margin: 28px 0 0;
    padding: 0;
    list-style: none;
}
.cards li {
    border: 1px solid var(--outline);
    border-radius: 4px;
    background: var(--panel);
}
.cards a {
    display: block;
    padding: 18px 20px;
    text-decoration: none;
    color: var(--text);
    height: 100%;
    box-sizing: border-box;
}
.cards a:hover {
    border-color: var(--accent);
}
.cards strong {
    display: block;
    color: var(--accent);
    font-size: 16px;
    margin-bottom: 6px;
}
.cards span {
    color: var(--text-dim);
    font-size: 15px;
    line-height: 1.5;
}

/* Wide reference tables. They scroll inside themselves rather than pushing the
   page sideways on a phone. */
.scroll {
    overflow-x: auto;
    margin: 22px 0;
}
table {
    border-collapse: collapse;
    width: 100%;
    font-size: 15px;
}
th,
td {
    text-align: left;
    padding: 9px 14px;
    border-bottom: 1px solid var(--outline);
    vertical-align: top;
}
th {
    color: var(--accent);
    font-weight: 600;
    white-space: nowrap;
}
td code {
    white-space: nowrap;
}

/* The next/previous pair at the foot of an inner page. */
.onward {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin: 44px 0 0;
    padding: 22px 0 0;
    border-top: 1px solid var(--outline);
}

/* On the inner pages the wordmark is a link home rather than the heading, so
   the h1 can be the subject of the page. */
.brand {
    margin: 0;
}
.brand img {
    width: 100%;
    max-width: 300px;
    height: auto;
    display: block;
}
main h1 {
    font-size: 34px;
    line-height: 1.2;
    margin: 30px 0 0;
    letter-spacing: -0.01em;
}

/* A figure whose image is narrower than the column it sits in. Without this
   the shared rule stretches it to the page width, which for a 316 pixel
   capture of six channel strips is an upscaled blur. */
.narrow img {
    max-width: 316px;
}

/* Icons inside a link button. currentColor rather than a fixed fill, so the
   mark follows the text through the hover and the accent state instead of
   staying black on a dark panel, which is what an SVG with no fill does. */
.links a svg {
    width: 16px;
    height: 16px;
    fill: currentColor;
    flex: none;
}
