/*
 * The look of the app, in a web page: the page, tile and text colours, the lime accent and the
 * corners are copied from the app's design system (core/designsystem/theme/Color.kt and
 * Shape.kt), and the typeface is the app's own Sora (fonts/sora.ttf, the same file as
 * app/src/main/res/font/sora.ttf). Change them together. Dark only, like the app.
 */

@font-face {
  font-family: "Sora";
  src: url("/fonts/sora.ttf") format("truetype");
  font-weight: 100 800;
  font-display: swap;
}

:root {
  --page: #121316;
  --tile: #1e2025;
  --quiet: #24262b;
  --outline: #3a3e46;
  --text: #f2f3f5;
  --text-secondary: #9298a3;
  /* The mascot's waving.webp carries this lime: see "The mascot" below before changing it. */
  --accent: #c6f432;
  --accent-pressed: #ddff7a;
  /* Buy Me a Coffee's own yellow, for its button alone (2026-10-08). */
  --coffee: #ffdd00;
  --coffee-pressed: #ffe94d;
  --tile-radius: 26px;
  --small-radius: 22px;
  --button-radius: 18px;
  --gap: 12px;
  color-scheme: dark;
}

* {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--page);
  color: var(--text);
  font-family: "Sora", system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.55;
  /* A web address is one long word: on a phone it breaks rather than run off the page. */
  overflow-wrap: break-word;
}

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

img {
  max-width: 100%;
  height: auto;
}

.page {
  max-width: 980px;
  margin: 0 auto;
  padding: 16px;
}

/* The top line: the mark and the name, as at the top of Home, and three links. */
.top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 16px;
  padding: 4px 0 16px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--text);
  font-weight: 700;
  font-size: 22px;
  text-decoration: none;
}

.top nav {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 18px;
}

.top nav a {
  color: var(--text-secondary);
  text-decoration: none;
  font-weight: 500;
}

.top nav a:hover,
.top nav a:focus-visible {
  color: var(--text);
}

main {
  display: grid;
  gap: var(--gap);
}

/* A grid item is as wide as its widest content unless told otherwise; the comparison's table
   must slide inside its tile, not widen the page. */
main > * {
  min-width: 0;
}

.tile {
  background: var(--tile);
  border-radius: var(--tile-radius);
  padding: 24px;
}

.tile h2 {
  margin: 0 0 10px;
  font-size: 20px;
  font-weight: 600;
  line-height: 1.3;
}

.tile p {
  margin: 0 0 12px;
}

.tile p:last-child,
.tile ul:last-child,
.tile ol:last-child {
  margin-bottom: 0;
}

.tile ul,
.tile ol {
  margin: 0 0 12px;
  padding-left: 1.25em;
}

.tile li + li {
  margin-top: 6px;
}

.secondary {
  color: var(--text-secondary);
}

/* The one lime tile of the page, as on Home: dark words on the accent. */
.accent {
  background: var(--accent);
  color: var(--page);
}

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

.hero {
  padding: 32px 24px;
}

.hero h1 {
  margin: 0 0 14px;
  font-size: clamp(32px, 7vw, 52px);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.02em;
}

.hero .lead {
  max-width: 40em;
  font-size: 18px;
  margin-bottom: 22px;
}

/* The main button, dark on the lime tile. Two classes, so the lime tile's own link colour
   does not reach its words. */
.accent .button {
  display: inline-block;
  background: var(--page);
  color: var(--accent);
  border-radius: var(--button-radius);
  padding: 16px 26px;
  font-weight: 700;
  font-size: 18px;
  text-decoration: none;
}

.accent .button:hover,
.accent .button:focus-visible {
  color: var(--accent-pressed);
}

/*
 * The Buy me a coffee button: Buy Me a Coffee's yellow with black words, as its own button
 * has them, drawn here so that the page loads nothing from another site.
 */
.coffee {
  display: inline-block;
  background: var(--coffee);
  color: #000;
  border-radius: var(--button-radius);
  padding: 12px 22px;
  font-weight: 700;
  text-decoration: none;
}

.coffee:hover,
.coffee:focus-visible {
  background: var(--coffee-pressed);
}

.hero .small {
  margin: 14px 0 0;
  font-size: 14px;
}

/*
 * The mascot stands in the lime tile: small and under the words on a phone, at their right
 * from a tablet's width up, and twice as large on a wide screen (both further down). Its
 * pictures are drawn from the 3D model by design/mascot/scripts/pack_clips.py, 720 by 608
 * pixels, and shown at half of that or at a quarter. The sizes and places here are what that
 * script prints: change them with the pictures.
 */
.mascot {
  position: relative;
  width: 180px;
  height: 152px;
  margin: 16px 0 -16px auto;
}

.mascot img {
  display: block;
  width: 100%;
  height: 100%;
}

/*
 * Nothing below moves for a visitor whose system asks for less motion: he stands, his needles
 * where the standing picture has them, and no other picture of him is fetched.
 */
@media (prefers-reduced-motion: no-preference) {
  /*
   * His needles keep moving. The website runs no script, so the stylesheet turns them:
   * dials.webp holds the two dials' faces without a needle, and under them the two needles'
   * blades pointing straight up. Each face is laid over its dial in the standing picture, and
   * its blade over it, turned about the middle of the dial. The two turn to their own times,
   * 7 and 11 seconds, so the pair does not repeat for over a minute. A needle's angle is its
   * figure less 120 degrees: 1 km/h is one degree, 1,000 RPM is thirty.
   */
  .dial {
    position: absolute;
    width: 17.7778%;
    height: 21.0526%;
    background: url("/mascot/dials.webp") 0 0 / 200% 200% no-repeat;
  }

  .dial::after {
    content: "";
    position: absolute;
    inset: 0;
    background: url("/mascot/dials.webp") 0 100% / 200% 200% no-repeat;
  }

  .dial-speed {
    left: 42.7778%;
    top: 9.8684%;
  }

  .dial-speed::after {
    transform-origin: 50.35% 50.86%;
    animation: mascot-speed 11s ease-in-out infinite;
  }

  .dial-rpm {
    left: 64.4444%;
    top: 15.1316%;
    background-position: 100% 0;
  }

  .dial-rpm::after {
    background-position: 100% 100%;
    transform-origin: 51.36% 51.34%;
    animation: mascot-rpm 7s ease-in-out infinite;
  }

  /*
   * Roll the pointer over him and he waves for as long as it stays: his arm goes up once, then
   * his hand waves again and again. waving.webp holds the frames one under the other, five of
   * the arm going up and six of one wave of the hand, twelve to the second. It is laid over
   * the standing picture and stepped through. When the pointer leaves, he stands again at
   * once. On a touch screen a tap on him does the same until the next tap elsewhere, where the
   * browser treats a tap as a pointer that stays, as phones' browsers do.
   *
   * The standing picture is never taken away: a stylesheet cannot know whether the strip has
   * arrived. Each frame of the strip covers it instead, needles and all, with this tile's
   * lime wherever the standing mascot would show beside the waving one. So waving.webp
   * carries --accent: change the colour and it has to be packed again (design/mascot/README.md,
   * "The website's pictures").
   *
   * Browsers keep these pictures for a week and this stylesheet for an hour. A picture that
   * changes in a way these rules count on, another number of frames most of all, gets another
   * name: the strip was wave.webp while it had 24 frames.
   */
  .mascot::after {
    content: "";
    position: absolute;
    inset: 0;
    background-repeat: no-repeat;
    background-size: 100% 1100%;
    visibility: hidden;
  }

  .mascot:hover::after {
    background-image: url("/mascot/waving.webp");
    animation: mascot-raise 0.4167s steps(5) forwards, mascot-wave 0.5s steps(6) 0.4167s infinite;
  }
}

/* With a pointer that can hover, the strip is fetched as soon as it comes over the lime tile,
   so that it is there when the pointer reaches him. Not with the page. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .hero:hover .mascot::after {
    background-image: url("/mascot/waving.webp");
  }
}

/* The strip is seen only while it plays. Its 11 frames lie a tenth of the way apart: the raise
   is the first five, and where it ends the wave takes over with the other six, for ever. */
@keyframes mascot-raise {
  from {
    visibility: visible;
  }

  to {
    visibility: visible;
    background-position-y: 50%;
  }
}

@keyframes mascot-wave {
  from {
    visibility: visible;
    background-position-y: 50%;
  }

  to {
    visibility: visible;
    background-position-y: 110%;
  }
}

/* The speed needle wanders between 0 and 36 km/h and comes back to 0, where the standing
   picture has it. */
@keyframes mascot-speed {
  0%,
  100% {
    transform: rotate(-120deg);
  }

  7% {
    transform: rotate(-117deg);
  }

  18% {
    transform: rotate(-98deg);
  }

  28% {
    transform: rotate(-106deg);
  }

  40% {
    transform: rotate(-84deg);
  }

  51% {
    transform: rotate(-102deg);
  }

  60% {
    transform: rotate(-94deg);
  }

  73% {
    transform: rotate(-114deg);
  }

  81% {
    transform: rotate(-108deg);
  }

  93% {
    transform: rotate(-118deg);
  }
}

/* The RPM needle is an engine ticking over at 900, where the standing picture has it, and
   revved three times: to 2,600, to 1,700, and twice in a row to 3,400. It goes up fast and
   comes down slower, and dips under 900 before it settles. */
@keyframes mascot-rpm {
  0%,
  100% {
    transform: rotate(-93deg);
  }

  7% {
    transform: rotate(-90deg);
  }

  13% {
    transform: rotate(-94deg);
  }

  18.5% {
    transform: rotate(-92deg);
    animation-timing-function: ease-out;
  }

  22% {
    transform: rotate(-42deg);
  }

  31% {
    transform: rotate(-88deg);
  }

  35% {
    transform: rotate(-96deg);
  }

  40% {
    transform: rotate(-91deg);
  }

  48.5% {
    transform: rotate(-94deg);
    animation-timing-function: ease-out;
  }

  51.5% {
    transform: rotate(-69deg);
  }

  58% {
    transform: rotate(-90deg);
  }

  63% {
    transform: rotate(-95deg);
  }

  70% {
    transform: rotate(-92deg);
    animation-timing-function: ease-out;
  }

  73% {
    transform: rotate(-24deg);
  }

  76.5% {
    transform: rotate(-45deg);
    animation-timing-function: ease-out;
  }

  79.5% {
    transform: rotate(-18deg);
  }

  88.5% {
    transform: rotate(-87deg);
  }

  93.5% {
    transform: rotate(-95deg);
  }
}

/* Four phone screenshots: two across on a phone, four on a wide screen. */
.shots {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--gap);
  margin: 0;
}

.shots figure {
  margin: 0;
  background: var(--tile);
  border-radius: var(--small-radius);
  padding: 10px 10px 12px;
}

.shots img {
  display: block;
  width: 100%;
  border-radius: 14px;
}

.shots figcaption {
  margin-top: 8px;
  font-size: 13px;
  color: var(--text-secondary);
  line-height: 1.4;
}

.pair {
  display: grid;
  gap: var(--gap);
}

.report img {
  display: block;
  width: 100%;
  max-width: 620px;
  margin: 4px auto 10px;
  border-radius: 12px;
}

.report .secondary {
  font-size: 14px;
  text-align: center;
}

footer {
  margin-top: 24px;
  padding: 8px 4px 24px;
  font-size: 13px;
  color: var(--text-secondary);
}

footer p {
  margin: 0 0 6px;
}

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

/* The questions: each opens in place, as the app's "About …" lines do. */
.faq details {
  border-top: 1px solid var(--outline);
  padding: 12px 0;
}

.faq details:last-child {
  padding-bottom: 0;
}

.faq summary {
  cursor: pointer;
  font-weight: 600;
}

.faq details p {
  margin: 8px 0 0;
  color: var(--text-secondary);
}

/* The comparison: a table that slides sideways inside its tile on a phone, never the page. */
.page-title {
  margin: 0 0 12px;
  font-size: clamp(26px, 5.5vw, 38px);
  line-height: 1.15;
}

.table-wrap {
  overflow-x: auto;
  margin: 0 -8px;
  padding: 0 8px;
}

.compare {
  border-collapse: collapse;
  min-width: 760px;
  width: 100%;
  font-size: 14px;
  line-height: 1.45;
}

.compare th,
.compare td {
  text-align: left;
  vertical-align: top;
  padding: 10px 12px;
  border-top: 1px solid var(--outline);
}

.compare thead th {
  border-top: 0;
  font-weight: 700;
}

.compare tbody th {
  color: var(--text-secondary);
  font-weight: 600;
  width: 150px;
}

.compare .ours {
  background: var(--quiet);
}

/* The row's name stays in view while the apps slide past it. */
.compare th:first-child {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--tile);
}

.compare thead .ours {
  color: var(--accent);
  border-radius: 12px 12px 0 0;
}

.table-note {
  margin-top: 10px;
  font-size: 13px;
}

@media (min-width: 900px) {
  .table-note {
    display: none;
  }
}

/* The privacy policy: one tile of text, read top to bottom. */
.policy h1 {
  margin: 0 0 6px;
  font-size: clamp(28px, 6vw, 40px);
  line-height: 1.15;
}

.policy h2 {
  margin-top: 28px;
}

.policy {
  max-width: 46em;
}

/* What's new: each version a tile, each change a row with its kind's tag, as in the app's
   What's new screen. The tags' colours are the app's (MiloChangeTagColors in Color.kt). */
.release h2 {
  margin-bottom: 4px;
}

.tile .changes {
  list-style: none;
  margin: 0;
  padding: 0;
}

.tile .changes li {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 12px;
  align-items: start;
  margin: 0;
  padding: 14px 0;
  border-top: 1px solid var(--outline);
}

.tile .changes li:first-child {
  border-top: 0;
}

.tile .changes li:last-child {
  padding-bottom: 0;
}

.changes p {
  margin: 4px 0 0;
}

.tag {
  display: inline-block;
  min-width: 6.5em;
  padding: 2px 10px;
  border-radius: 999px;
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 12px;
  font-weight: 600;
  line-height: 18px;
  letter-spacing: 0.04em;
  text-align: center;
  text-transform: uppercase;
}

.tag-new {
  background: var(--accent);
  color: var(--page);
}

.tag-improved {
  background: #2a3350;
  color: #c9d6ff;
}

.tag-fixed {
  background: #2a2416;
  color: #ffe7a8;
}

.tag-security {
  background: #3a1c1f;
  color: #ffb3b3;
}

@media (min-width: 720px) {
  .page {
    padding: 24px;
  }

  .shots {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .pair {
    grid-template-columns: 1fr 1fr;
  }

  .hero {
    padding: 44px 40px;
  }

  .tile {
    padding: 28px 32px;
  }

  /* The headline keeps the tile's whole width; under it the mascot stands at the right of
     the words, his feet near the tile's lower edge. Whatever else the tile holds goes in
     the first column, one under the other; a button that is the tile's own child keeps its
     own width there instead of the column's. */
  .hero {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: 16px;
  }

  .hero > * {
    grid-column: 1;
  }

  .hero h1 {
    grid-column: 1 / -1;
  }

  .hero > .button {
    justify-self: start;
  }

  .mascot {
    grid-column: 2;
    grid-row: 2 / span 3;
    align-self: end;
    margin: 0 0 -12px;
  }
}

/* A wide screen: the mascot at his full size. He is as tall as the words beside him, less
   what he stands below them, so the tile is no higher for him. */
@media (min-width: 900px) {
  .mascot {
    width: 360px;
    height: 304px;
    margin: 0 -8px -20px 0;
  }
}
