/*
  The site in one stylesheet.

  Colours are the dark theme of the product, taken from DESIGN.md rather than
  invented here: a site that gets its own black would be a second opinion about
  what Topf looks like.

  The composition is the site's own decision, and a deliberate one. A landing
  page for an app of this class is usually a stack of cards: rounded rectangles
  with an icon, a heading and two lines, floating on a gradient. This page is
  built as a ledger instead — numbered entries separated by hairlines, the
  number in tabular figures on the left, the text on the right — because that is
  what the product itself looks like, and because it needs no icon set at all.
  Nothing is borrowed and nothing is decorative.

  The screenshots stand straight, at their own aspect ratio, without device
  frames or perspective. A phone drawn around a screenshot says «marketing
  material»; the screen alone says «this is the app».
*/

:root {
  /* Dark theme tokens — DESIGN.md 4.1. */
  --canvas: #000000;
  --surface: #1c1c1c;
  --surface-elevated: #242424;
  --text-primary: #f2f2f2;
  --text-secondary: #9a9a9a;
  --text-tertiary: #666666;
  --divider: #303030;
  --control-border: #353535;

  /* The only colours with a job: the semantics of money — DESIGN.md 4.2. */
  --income: #73d08c;
  --expense: #f7a15e;

  --measure: 34rem;
  --gutter: clamp(1.25rem, 5vw, 3rem);

  --font: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', Roboto,
    'Helvetica Neue', Arial, sans-serif;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

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

body {
  margin: 0;
  background: var(--canvas);
  color: var(--text-primary);
  font-family: var(--font);
  font-size: 1.0625rem;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

.page {
  max-width: 64rem;
  margin: 0 auto;
  padding: 0 var(--gutter) 4rem;
}

a {
  color: inherit;
  text-decoration-color: var(--text-tertiary);
  text-underline-offset: 0.2em;
}

a:hover {
  text-decoration-color: currentColor;
}

:focus-visible {
  outline: 2px solid var(--text-primary);
  outline-offset: 3px;
  border-radius: 4px;
}

/* --- header ------------------------------------------------------------- */

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.85rem 1rem;
  padding: 1.5rem 0;
  border-bottom: 1px solid var(--divider);
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-decoration: none;
}

.mark {
  display: block;
  flex: none;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  font-size: 0.9375rem;
  color: var(--text-secondary);
}

/*
  On a phone the header keeps one line by dropping the two links rather than
  wrapping: a header of two rows costs a fifth of the first screen, and both
  links are in the footer of every page anyway. What stays is the name and the
  language — the only control up here, and the one a reader arriving from a
  German search result actually needs.
*/
@media (max-width: 30rem) {
  .site-nav {
    gap: 0.75rem;
  }

  .site-nav > a {
    display: none;
  }
}

.site-nav a {
  text-decoration: none;
}

.site-nav a:hover {
  color: var(--text-primary);
}

/*
  The language control: a capsule that names the language being read, and a
  small menu of the alternatives under it.

  A capsule rather than another link in the row, because it is a control and
  every choosable value in the app sits in one. It names the current language
  rather than the other one — a control labelled with its destination is a coin
  flip for the reader.
*/
.language-menu {
  position: relative;
}

.language-menu summary {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.3rem 0.6rem 0.3rem 0.45rem;
  margin: -0.3rem 0;
  border: 1px solid var(--control-border);
  border-radius: 999px;
  color: var(--text-primary);
  white-space: nowrap;
  cursor: pointer;
  list-style: none;
}

.language-menu summary::-webkit-details-marker {
  display: none;
}

/* Safari draws the triangle through ::marker too, and ignores list-style here. */
.language-menu summary::marker {
  content: '';
}

.language-menu summary:hover {
  background: var(--surface);
}

.language-menu .chevron {
  color: var(--text-tertiary);
  transition: transform 160ms ease;
}

.language-menu[open] .chevron {
  transform: rotate(180deg);
}

.language-menu ul {
  position: absolute;
  top: calc(100% + 0.6rem);
  right: 0;
  z-index: 10;
  min-width: 11rem;
  margin: 0;
  padding: 0.3rem;
  list-style: none;
  background: var(--surface-elevated);
  border: 1px solid var(--control-border);
  border-radius: 16px;
}

.language-menu li a {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.5rem 0.6rem;
  border-radius: 11px;
  text-decoration: none;
  color: var(--text-primary);
  white-space: nowrap;
}

.language-menu li a:hover {
  background: var(--surface-strong);
}

.language-menu .tick {
  margin-left: auto;
  color: var(--text-secondary);
}

@media (prefers-reduced-motion: reduce) {
  .language-menu .chevron {
    transition: none;
  }
}

.flag {
  display: block;
  flex: none;
  border-radius: 4px;
}

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

.hero {
  padding: clamp(3rem, 10vw, 6.5rem) 0 clamp(2rem, 6vw, 3.5rem);
  max-width: 44rem;
}

h1 {
  margin: 0;
  font-size: clamp(2.25rem, 7vw, 3.75rem);
  line-height: 1.05;
  letter-spacing: -0.03em;
  font-weight: 600;
}

.hero .lede {
  margin: 1.5rem 0 0;
  max-width: var(--measure);
  font-size: clamp(1.0625rem, 2.4vw, 1.25rem);
  color: var(--text-secondary);
}

/*
  «Coming to the App Store» is a status, not a button. Making it look like one
  would promise a tap that leads nowhere — so it is a line of the ledger: a
  hairline above it, a marker, and the plain sentence.
*/
.availability {
  display: inline-flex;
  align-items: baseline;
  gap: 0.6rem;
  margin: 2.5rem 0 0;
  padding-top: 1.25rem;
  border-top: 1px solid var(--divider);
  font-size: 0.9375rem;
  color: var(--text-secondary);
  letter-spacing: 0.01em;
}

.availability::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--income);
  transform: translateY(-1px);
}

/* --- screenshots -------------------------------------------------------- */

/*
  A row that scrolls on a phone and lays itself out on a desktop. Screenshots
  keep their own proportions; `scroll-snap` makes the row behave like the
  shelves inside the app rather than like a carousel with arrows.
*/
.shots {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(13rem, 15rem);
  gap: clamp(1rem, 3vw, 1.75rem);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  /*
    Without this the snap engine parks the first shot against the very edge of
    the viewport — it snaps to the item's box and ignores the padding that pulls
    the row back inside the page margin.
  */
  scroll-padding-inline: var(--gutter);
  padding-bottom: 1rem;
  margin: 0 calc(-1 * var(--gutter));
  padding-left: var(--gutter);
  padding-right: var(--gutter);
  scrollbar-width: thin;
  scrollbar-color: var(--divider) transparent;
}

.shot {
  margin: 0;
  scroll-snap-align: start;
}

.shot img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: clamp(1.25rem, 3vw, 1.75rem);
  border: 1px solid var(--control-border);
  background: var(--surface);
}

.shot figcaption {
  margin-top: 0.75rem;
  font-size: 0.875rem;
  color: var(--text-secondary);
}

/* --- the ledger of what the app does ------------------------------------ */

.section-title {
  margin: 0 0 1.5rem;
  font-size: 0.8125rem;
  font-weight: 400;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

.ledger,
.privacy-note {
  padding-top: clamp(3.5rem, 9vw, 5.5rem);
}

.entries {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: entry;
  border-top: 1px solid var(--divider);
}

.entry {
  counter-increment: entry;
  display: grid;
  grid-template-columns: 2.75rem 1fr;
  gap: 0 1.25rem;
  padding: 1.5rem 0;
  border-bottom: 1px solid var(--divider);
}

/*
  The row number, in the tabular figures the app uses for money. It replaces the
  icon a feature list would otherwise carry — and an icon set is exactly the
  kind of thing this project does not borrow.
*/
.entry::before {
  content: counter(entry, decimal-leading-zero);
  grid-row: 1 / span 2;
  font-variant-numeric: tabular-nums;
  font-size: 0.875rem;
  color: var(--text-tertiary);
  padding-top: 0.25rem;
}

.entry h3 {
  margin: 0;
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.entry p {
  margin: 0.5rem 0 0;
  max-width: var(--measure);
  color: var(--text-secondary);
}

@media (min-width: 48rem) {
  .entry {
    grid-template-columns: 2.75rem minmax(11rem, 15rem) 1fr;
    align-items: baseline;
    gap: 0 2rem;
  }

  .entry::before {
    grid-row: auto;
    padding-top: 0.15rem;
  }

  .entry p {
    margin-top: 0;
  }
}

.privacy-note p {
  margin: 0;
  max-width: var(--measure);
  font-size: clamp(1.0625rem, 2.2vw, 1.1875rem);
  color: var(--text-secondary);
}

.privacy-note a {
  color: var(--text-primary);
}

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

.document {
  max-width: 40rem;
  padding-top: clamp(2.5rem, 8vw, 4.5rem);
}

.document h1 {
  font-size: clamp(1.875rem, 5vw, 2.75rem);
}

.document .updated {
  margin: 1rem 0 0;
  font-size: 0.875rem;
  color: var(--text-tertiary);
}

.document .lede {
  margin: 1.5rem 0 0;
  color: var(--text-secondary);
}

.document section {
  margin-top: 2.5rem;
  padding-top: 2.5rem;
  border-top: 1px solid var(--divider);
}

.document h2 {
  margin: 0 0 1rem;
  font-size: 1.1875rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.document p,
.document li {
  color: var(--text-secondary);
}

.document p {
  margin: 0 0 1rem;
}

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

.document ul {
  margin: 0 0 1rem;
  padding-left: 1.1rem;
}

.document li {
  margin-bottom: 0.35rem;
}

.document a {
  color: var(--text-primary);
}

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

.site-footer {
  margin-top: clamp(4rem, 10vw, 7rem);
  padding-top: 1.75rem;
  border-top: 1px solid var(--divider);
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.5rem;
  font-size: 0.9375rem;
}

.footer-links a {
  text-decoration: none;
  color: var(--text-secondary);
}

.footer-links a:hover {
  color: var(--text-primary);
}

.footer-note {
  margin: 1.25rem 0 0;
  font-size: 0.875rem;
  color: var(--text-tertiary);
}

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

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

/*
  Only ever rendered by `node site/build.mjs --draft`, when the operator's legal
  details are still missing. Loud on purpose: this page must not be mistaken for
  a finished one, least of all by whoever deploys it.
*/
.draft-banner {
  margin: 0 calc(-1 * var(--gutter));
  padding: 0.75rem var(--gutter);
  background: var(--expense);
  color: #1a1005;
  font-size: 0.875rem;
  font-weight: 600;
}

/* The imprint's postal address: lines, not list items. */
.document .address {
  line-height: 1.7;
}

/* The signature the app's settings screen ends with, flag and all. */
.signature {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 1.25rem 0 0;
  font-size: 0.875rem;
  color: var(--text-secondary);
}
