/* One stylesheet for both pages. No fonts are fetched, no scripts run and
   nothing is loaded from anywhere: a privacy policy that phoned a CDN would be
   an embarrassing thing to serve. */

:root {
    color-scheme: light dark;
    --ink: #12161d;
    --ink-soft: #4a5464;
    --page: #ffffff;
    --panel: #f4f6fa;
    --rule: #dfe4ec;
    --accent: #1f6bff;
    /* Donate is the one button that is not asking you to install anything, so
       it does not compete with the blue that is. */
    --give: #12855a;
}

@media (prefers-color-scheme: dark) {
    :root {
        --ink: #eef2f8;
        --ink-soft: #98a3b4;
        --page: #0d1016;
        --panel: #151a22;
        --rule: #252c38;
        --accent: #5b93ff;
        --give: #2ea36b;
    }
}

* { box-sizing: border-box; }

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

.wrap { max-width: 44rem; margin: 0 auto; }

header {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 40px 0 8px;
}

header svg { width: 34px; height: 34px; flex: none; }

header a {
    font-size: 22px;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--ink);
    text-decoration: none;
}

h1 {
    font-size: clamp(30px, 6vw, 42px);
    line-height: 1.15;
    letter-spacing: -0.03em;
    margin: 32px 0 8px;
}

h2 {
    font-size: 21px;
    letter-spacing: -0.015em;
    margin: 44px 0 10px;
    padding-top: 22px;
    border-top: 1px solid var(--rule);
}

p, li { color: var(--ink-soft); }
p { margin: 0 0 16px; }
li { margin-bottom: 6px; }
strong { color: var(--ink); font-weight: 600; }
a { color: var(--accent); }

.stamp {
    font-size: 15px;
    color: var(--ink-soft);
    margin-bottom: 36px;
}

.lede { font-size: 19px; }

.note {
    background: var(--panel);
    border: 1px solid var(--rule);
    border-radius: 12px;
    padding: 18px 20px;
    margin: 24px 0;
}

.note p:last-child { margin-bottom: 0; }

.actions { display: flex; flex-wrap: wrap; gap: 12px; margin: 28px 0 8px; }

.button {
    display: inline-block;
    padding: 11px 20px;
    border-radius: 10px;
    background: var(--accent);
    color: #fff;
    font-weight: 600;
    font-size: 16px;
    text-decoration: none;
}

.button.donate { background: var(--give); }

.button.secondary {
    background: transparent;
    color: var(--ink);
    border: 1px solid var(--rule);
}

footer {
    margin-top: 64px;
    padding-top: 22px;
    border-top: 1px solid var(--rule);
    font-size: 15px;
    color: var(--ink-soft);
}

/* The non-affiliation line under the footer links. Smaller than the links it
   sits below, because it is a fact people need available rather than a fact
   they need read. */
.fine {
    margin: 12px 0 0;
    font-size: 13px;
    line-height: 1.5;
    color: var(--ink-soft);
    opacity: 0.8;
}

.translated { margin-top: -12px; }

/* The language picker. A disclosure rather than a select: no script, works
   from the keyboard, and shut until someone wants it. In the footer because
   choosing a language is something you do once, not something the page is
   about. */
.languages {
    margin-top: 14px;
    font-size: 13px;
    color: var(--ink-soft);
}

.languages summary {
    cursor: pointer;
    display: inline-block;
    opacity: 0.8;
}

.languages summary:hover { color: var(--accent); opacity: 1; }

.languages nav {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 14px;
    margin-top: 8px;
}

.languages a { color: var(--ink-soft); text-decoration: none; }
.languages a:hover { color: var(--accent); text-decoration: underline; }
.languages .here { color: var(--ink); font-weight: 600; }

/* The real lockup, inline rather than in an <img>: the three stars have to
   turn on three different centres, and a stylesheet cannot reach inside an
   image. One copy serves both themes now, because the letters take
   `currentColor` and the theme sets them the way it sets any other text.
   The aspect ratio is written down so the masthead does not reflow if the
   width has to be worked out before the drawing is measured. */
header { --lockup: 34px; }

header .mark {
    display: block;
    height: var(--lockup);
    width: auto;
    aspect-ratio: 129 / 48.52;
    color: var(--ink);
}

/* The drawing carries empty space to the left of the star, 16.5% of its own
   height, and left in it the lockup read as indented against the text below,
   which starts hard against the column edge. The pull is written against the
   height rather than in pixels, so the larger masthead below needs one number
   changed and not two kept in step.

   It is on the link and not on the drawing inside it. Moving the drawing alone
   left the last few pixels of the star hanging outside the link's own box,
   where they looked clickable and were not. */
header a { margin-left: calc(var(--lockup) * -0.165); }

/* The version, under the buttons rather than beside the requirements: it is
   the line people look for before they click, not after. */
.version {
    margin: 18px 0 4px;
    font-size: 15px;
    color: var(--ink-soft);
}

/* The footer's own line: links at one end, the language picker at the other. */
footer .row {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px 20px;
}

footer .row p { margin: 0; }

.languages { position: relative; margin: 0; font-size: 15px; }

.languages summary {
    cursor: pointer;
    list-style: none;
    color: var(--ink-soft);
}

.languages summary::-webkit-details-marker { display: none; }
.languages summary::after { content: " ⌄"; opacity: 0.6; }
.languages summary:hover { color: var(--accent); }

/* The panel. No border: a shadow and a solid ground are enough to lift it,
   and a rule around it would be the loudest thing in the footer. */
.languages nav {
    position: absolute;
    right: 0;
    bottom: 1.9em;
    z-index: 2;
    display: flex;
    flex-direction: column;
    min-width: 148px;
    padding: 6px;
    border-radius: 10px;
    background: #ffffff;
    box-shadow: 0 8px 28px rgba(10, 16, 28, 0.28), 0 1px 2px rgba(10, 16, 28, 0.14);
}

.languages nav a,
.languages nav .here {
    padding: 7px 12px;
    border-radius: 6px;
    color: #12161d;
    text-decoration: none;
    white-space: nowrap;
}

.languages nav a:hover { background: rgba(31, 107, 255, 0.12); color: #12161d; }
.languages nav .here { font-weight: 600; background: rgba(10, 16, 28, 0.06); }

/* The panel, annotated. One picture, its own radius rather than the page's,
   because a screenshot with square corners inside a rounded layout reads as
   something pasted on rather than something shown. */
.modes-head { margin-top: 56px; }

.panel { margin: 0; }

.panel img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 18px;
}

/* Handwritten where a Mac has a hand to write with, and a plain cursive
   fallback anywhere else. Nothing is fetched for it. */
.hand {
    font-family: "Bradley Hand", "Chalkboard SE", "Marker Felt", cursive;
    font-size: 21px;
    color: var(--ink);
}

@media (max-width: 560px) {
    .pointers { display: none; }
    .modes figcaption { grid-template-columns: 1fr; text-align: left; }
    .modes figcaption span { grid-row: auto !important; }
}

/* The App Store button, when there is a listing to point it at. */
.button.appstore .apple {
    margin-right: 7px;
    font-size: 17px;
    line-height: 1;
}

/* Both of these are read after the decision, not before it. */
.version, .stamp { font-size: 13px; }

/* The lockup was sized for a footer and this is a masthead. */
header { --lockup: 42px; }

.button .glyph {
    width: 15px;
    height: 15px;
    margin-right: 8px;
    vertical-align: -2px;
}

/* A drawn chevron: the character that was here renders as a different glyph,
   or none, depending on the font the reader happens to have. */
.languages summary::after { content: none; }

.chevron {
    width: 10px;
    height: 7px;
    margin-left: 5px;
    opacity: 0.7;
}

/* Hover states. Everything that can be clicked says so on the way in, and
   says it over 150ms rather than instantly, because an instant change reads
   as a glitch and a slow one reads as lag. */
.button {
    transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out,
        filter 0.15s ease-in-out;
}

.button:hover { filter: brightness(1.12); }
.button.secondary:hover { border-color: rgba(255, 255, 255, 0.85); filter: none; }

footer a { transition: color 0.15s ease-in-out; }
footer .row a:hover { text-decoration: underline; }

/* The chevron turns over when the picker is open, so the control says which
   way it is going rather than only what it is. */
.chevron { transition: transform 0.18s ease-in-out; }
.languages[open] .chevron { transform: rotate(180deg); }

/* Air above "Helping out" to match what is below it. */
.actions + h2, .stamp + h2 { margin-top: 56px; }

.copyright { margin-top: 10px; opacity: 0.75; }
.copyright a { color: inherit; text-decoration: underline; }

/* The picker's rows: colour rather than a rule, and no second background
   fighting the one that marks where you are. */
.languages nav a:hover { background: none; color: var(--accent); text-decoration: none; }

/* A lighter grey than the resting border, not white. White on a dark page is
   the brightest thing in it, which is a lot to say for "you are hovering". */
.button.secondary:hover { border-color: rgba(255, 255, 255, 0.38); }

/* Underlined at rest, plain on hover. The link is already marked; what hover
   has to say is only "this one", and taking the rule away says it. */
footer .row a, .version a, .stamp a { text-decoration: underline; }
footer .row a:hover, .version a:hover, .stamp a:hover { text-decoration: none; }

/* Requirements as three quiet facts. */
.badges {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 10px 0 0;
    padding: 0;
    list-style: none;
}

.badges li {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 11px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--ink) 7%, transparent);
    font-size: 12.5px;
    color: var(--ink-soft);
}

.badges .apple { font-size: 13px; line-height: 1; }

/* One thing on the page is alive, and it is the mark rather than the lockup.
   The whole lockup used to breathe as a block, which moved the letters with it
   and read as a card being hovered; the stars carry the same idea and mean
   something, because turning is what these stars are drawn doing.

   `fill-box` is what lets each one turn on its own centre. Without it the
   origin is the corner of the viewBox and all three swing around the letters.
   It is set on the stars alone: the letters carry a transform of their own in
   the markup, and changing the box it is measured against would move them. */
@media (prefers-reduced-motion: no-preference) {
    .mark .star-big,
    .mark .star-mid,
    .mark .star-small {
        transform-box: fill-box;
        transform-origin: center;
    }

    .mark .star-big { animation: star-turn-big 8s 0.4s infinite; }
    .mark .star-mid { animation: star-turn-mid 8s 0.4s infinite; }
    .mark .star-small { animation: star-turn-small 8s 0.4s infinite; }
}

/* One gust turns all three at once, then they stand still until the next one.
   The turn is at the front of the cycle and the wait is behind it, so somebody
   who has just opened the page sees the thing move rather than arriving during
   the silence and being shown a still logo for five seconds. The delay before
   the first one is there only so the movement starts after the page has
   settled and not during it.

   The same period for all three is the point: three loops of different lengths
   would line up only occasionally, and the rest of the time the mark would look
   like it had something loose in it. What differs is how fast each one goes
   round, and that goes with the weight — the small ones are up to speed and
   finished while the big one is still turning, which is the only reason the
   three read as one impulse rather than three decisions.

   Each does exactly one turn. The stars have four points, so a whole turn ends
   where it started and nothing snaps back into place at the end. */
@keyframes star-turn-big {
    0% {
        transform: rotate(0turn);
        animation-timing-function: cubic-bezier(0.5, 0, 0.2, 1);
    }
    42%, 100% { transform: rotate(1turn); }
}

@keyframes star-turn-mid {
    0% {
        transform: rotate(0turn);
        animation-timing-function: cubic-bezier(0.46, 0, 0.13, 1);
    }
    24%, 100% { transform: rotate(1turn); }
}

@keyframes star-turn-small {
    0% {
        transform: rotate(0turn);
        animation-timing-function: cubic-bezier(0.42, 0, 0.11, 1);
    }
    16%, 100% { transform: rotate(1turn); }
}

/* The two architecture badges are outlines: the requirement is the filled one,
   these two are what it runs on, and a row of three identical chips made all
   three read as equally load-bearing. */
/* `background: none` alone lost to the shorthand on `.badges li` in some
   engines, so the fill is set to transparent outright. */
.badges .outline {
    background: transparent;
    border: 1px solid rgba(255, 255, 255, 0.14);
}

@media (prefers-color-scheme: light) {
    .badges .outline { border-color: rgba(10, 16, 28, 0.16); }
}

.badges .chip-glyph { width: 15px; height: 15px; }

/* The picker's links are inside the footer row and were catching its
   underline. They are marked by position and by colour on hover, which is
   enough for a list of six words. */
footer .row .languages a { text-decoration: none; }

/* The version belongs on the button it describes, not in a line under it.
   Thinner, smaller and half lit, so it reads as a detail of the button
   rather than a second thing to decide about. */
.button.stacked {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 1px;
    line-height: 1.25;
    padding-top: 9px;
    padding-bottom: 9px;
}

.button.stacked .under {
    font-size: 11.5px;
    font-weight: 400;
    color: rgba(255, 255, 255, 0.7);
}

/* The button's two lines share the left edge. Centring a short line under a
   long one puts the version somewhere the eye has to go and find. */
.button.stacked { align-items: flex-start; }

/* A break the headline asks for, in the one place there is room to grant it.
   The Russian headline has a comma where the thought turns, and above the
   phone width the line is broken there rather than wherever the words happen
   to run out. Narrower than that, two forced lines become four ragged ones, so
   the break is dropped and the browser goes back to deciding. */
h1 .turn { display: inline; }

@media (max-width: 560px) {
    h1 .turn { display: none; }

    /* 10, 11 — on a phone the two buttons share the width instead of sitting
       at their own natural sizes. Two pills of different lengths on one row
       read as a primary and an afterthought; equal halves read as a choice,
       and both are big enough to hit. */
    /* 10 — the pair that installs the app goes full width, one per row. Half a
       phone is not enough for "Download for macOS": it wraps, and a two-line
       label beside a one-line one is what makes equal halves look unequal.
       Full width also gives the primary action the whole thumb. */
    .actions.get { flex-direction: column; align-items: stretch; gap: 10px; }
    .actions.get .button { text-align: center; }

    /* 11 — the pair in the footer shares the width instead. Both labels are
       short enough to fit, and neither of them is the reason anybody is here. */
    .actions.give { flex-wrap: nowrap; gap: 10px; }
    .actions.give .button {
        flex: 1 1 0;
        text-align: center;
        padding-left: 8px;
        padding-right: 8px;
    }

    /* 8 — the picker opened off the left of the screen. It is anchored to a
       summary that sits at the left edge of the footer, and `right: 0` on a
       panel wider than that summary puts its left edge past the viewport. It
       opens from the left here, and is kept off both edges. */
    .languages nav {
        right: auto;
        left: 0;
        max-width: calc(100vw - 48px);
    }
}

/* The copyright sits under the third-party note, with room between them. */
footer .fine + .copyright { margin-top: 12px; }
