:root {
  --bg: #fbf8f4;
  --ink: #1d1a17;
  --soft: #6b635b;
  --line: #e7dfd5;
  --gold: #a8740f;
  --card: #ffffff;
  /* Light: the palest of the app's moods. */
  --mesh-1: #f3e6f7;
  --mesh-2: #e3ecfb;
  --mesh-3: #fdf0e4;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #141318;
    --ink: #f3efe9;
    --soft: #a8a09a;
    --line: #2a2730;
    --gold: #f2c45a;
    --card: #1c1a21;
    /* Dark: the same moods, sunk almost to black. */
    --mesh-1: #2a1f3d;
    --mesh-2: #16243a;
    --mesh-3: #2e2115;
  }
}
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
/* The page runs under the notch and the home bar; padding keeps text clear. */
main { padding-left: max(20px, env(safe-area-inset-left)); padding-right: max(20px, env(safe-area-inset-right)); }
/* The mesh goes on <html>, which Safari propagates to the page CANVAS: the
   area behind the status bar and the bottom toolbar, and the overscroll. A
   fixed layer (or background-attachment: fixed) can't reach there, which is
   why those strips stayed flat white. No fixed attachment here: on iOS that
   sizes the image to the visible viewport and cuts it off again. */
html {
  min-height: 100%;
  background:
    radial-gradient(60% 40% at 12% 0%, var(--mesh-1) 0%, transparent 70%),
    radial-gradient(55% 35% at 92% 10%, var(--mesh-2) 0%, transparent 72%),
    radial-gradient(70% 45% at 50% 100%, var(--mesh-3) 0%, transparent 75%),
    var(--bg);
  background-repeat: no-repeat;
  background-size: 100% 100%;
  background-color: var(--bg);
}
body {
  margin: 0;
  background: transparent;
  min-height: 100dvh;
  color: var(--ink);
  font: 17px/1.6 -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", sans-serif;
}

main { max-width: 680px; margin: 0 auto; padding: 56px 20px 80px; }
.mark { display: inline-flex; align-items: center; gap: 10px; color: var(--soft); text-decoration: none; font-weight: 600; font-size: 15px; }
.mark svg { width: 30px; height: auto; }
h1, h2 { font-family: ui-serif, "New York", Georgia, serif; font-weight: 600; line-height: 1.2; }
h1 { font-size: 40px; margin: 28px 0 6px; }
h2 { font-size: 23px; margin: 40px 0 8px; }
.updated { color: var(--soft); font-size: 15px; margin: 0 0 28px; }
.lead { font-size: 19px; }
p, li { color: var(--ink); }
ul { padding-left: 22px; }
li { margin: 6px 0; }
a { color: var(--gold); }
.card { background: color-mix(in srgb, var(--card) 82%, transparent); backdrop-filter: saturate(140%) blur(6px); border: 1px solid var(--line); border-radius: 18px; padding: 18px 20px; margin: 20px 0; }
.card p { margin: 0; }
details { border-top: 1px solid var(--line); padding: 14px 0; }
details:last-of-type { border-bottom: 1px solid var(--line); }
summary { cursor: pointer; font-weight: 600; }
footer { margin-top: 56px; padding-top: 20px; border-top: 1px solid var(--line); color: var(--soft); font-size: 14px; }
/* The row of links is spaced; a link INSIDE a sentence is not, or the full
   stop after it sits 16px away from the name. */
footer > a, footer > .here { margin-right: 16px; }
/* The current page: named, so the row stays complete, but not a link to
   where you already are. */
.here { color: var(--soft); opacity: .55; }
footer a { color: var(--soft); }
footer p a { margin-right: 0; text-decoration: underline; text-underline-offset: 2px; }

/* --- Landing page --------------------------------------------------------
   Added for the launch page. Support, Privacy and Terms use only the rules
   above, so nothing here can disturb them. */

h1 { text-wrap: balance; }
.fine { color: var(--soft); font-size: 15px; }

/* --- The demo ------------------------------------------------------------
   A prompt bar that types, then builds, then lands on real songs. Written in
   its FINISHED state and rewound by the script, so a browser with no
   JavaScript shows the answer rather than an empty box. */

/* NOTHING HERE IS CLICKABLE. A field you can put a cursor in but that cannot
   answer you is worse than one that is plainly a picture. */
/* Held at the height it will be once the result lands, so the page below does
   not jump when it does. Without this, everything under the demo moved down
   the moment the songs appeared, which on a phone looks like a reload. */
.demo { min-height: 232px; margin: 22px 0 8px; pointer-events: none; user-select: none; -webkit-user-select: none; }

.bar {
  display: flex; align-items: center; gap: 10px;
  background: color-mix(in srgb, var(--card) 88%, transparent);
  border: 1px solid var(--line); border-radius: 999px;
  padding: 12px 12px 12px 20px;
  box-shadow: 0 12px 34px -20px rgba(29, 26, 23, 0.45);
}
/* The caret has to sit AT the text. The typed span used to be flex: 1, which
   pushed the caret to the far right of the bar with a gap of nothing between
   them, as if something invisible had been typed. */
.field { flex: 1; min-width: 0; display: flex; align-items: center; gap: 3px; }
.typed { flex: 0 1 auto; min-width: 0; font-size: 17px; color: var(--ink); }
.typed:empty + .caret + .placeholder, .typed:empty::before {
  content: "Describe a moment, a mood, or an artist"; color: var(--soft);
}
.caret { flex: none; width: 2px; height: 21px; background: var(--gold); border-radius: 1px; animation: blink 1.1s step-end infinite; }
.caret[hidden] { display: none; }
@keyframes blink { 0%, 100% { opacity: 1 } 50% { opacity: 0 } }

/* The app's send: a dark circle that only fills in once there are words. */
.send {
  flex: none; width: 34px; height: 34px; border-radius: 50%;
  background: color-mix(in srgb, var(--ink) 16%, transparent);
  color: color-mix(in srgb, var(--ink) 45%, transparent);
  display: grid; place-items: center;
  transition: background .22s ease, color .22s ease, transform .22s ease;
}
.send.on { background: var(--ink); color: var(--bg); transform: scale(1.04); }

.building { color: var(--soft); margin: 16px 2px 0; font-size: 16px; }
.building[hidden] { display: none; }
.dots i { animation: dot 1.2s infinite; font-style: normal; }
.dots i:nth-child(2) { animation-delay: .18s }
.dots i:nth-child(3) { animation-delay: .36s }
@keyframes dot { 0%, 60%, 100% { opacity: .25 } 30% { opacity: 1 } }

.result {
  display: flex; gap: 18px; align-items: flex-start;
  margin-top: 18px; padding: 18px;
  background: color-mix(in srgb, var(--card) 84%, transparent);
  border: 1px solid var(--line); border-radius: 20px;
}
.result[hidden] { display: none; }
.result.in { animation: rise .5s cubic-bezier(.2,.7,.3,1) both; }
@keyframes rise { from { opacity: 0; transform: translateY(14px) } to { opacity: 1; transform: none } }

/* The cover, drawn the way the app draws one: its own mesh, the cassette mark
   at the top, the name in the serif at the bottom. */
.cover {
  flex: none; width: 108px; height: 108px; border-radius: 13px; position: relative; overflow: hidden;
  background: radial-gradient(70% 60% at 18% 12%, #a9c2e0 0%, transparent 70%),
              radial-gradient(62% 60% at 88% 22%, #7091bb 0%, transparent 72%),
              radial-gradient(85% 70% at 45% 102%, #35577f 0%, transparent 76%),
              #4a6d99;
  box-shadow: 0 12px 26px -15px rgba(29,26,23,.75);
}
.cover::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to bottom, transparent 55%, rgba(0,0,0,.3)); }
.cover .wm { position: absolute; top: 9px; left: 10px; z-index: 1; display: inline-flex; align-items: center; gap: 4px; color: #fff; opacity: .9; font-size: 7.5px; font-weight: 700; letter-spacing: 1.5px; }
.cover .nm { position: absolute; bottom: 9px; left: 10px; z-index: 1; color: #fff; font-family: ui-serif, "New York", Georgia, serif; font-weight: 600; font-size: 15px; line-height: 1.15; }

.tracks { flex: 1; min-width: 0; }
.rtitle { margin: 0 0 8px; font-family: ui-serif, "New York", Georgia, serif; font-weight: 600; font-size: 18px; }
.rtitle span { font-family: inherit; color: var(--soft); font-size: 14px; font-weight: 400; margin-left: 8px; white-space: nowrap; }
.tracks ol { list-style: none; margin: 0; padding: 0; }
.tracks li { display: flex; justify-content: space-between; gap: 12px; padding: 5px 0; border-top: 1px solid var(--line); font-size: 15px; }
.tracks li b { font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tracks li span { color: var(--soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 0 1 auto; min-width: 0; max-width: 55%; }
.tracks li.in { animation: rise .4s ease both; }

/* --- Features ------------------------------------------------------------ */
.feature { margin: 54px 0; }
.feature .shot { margin-top: 20px; text-align: center; }
.feature .shot img { width: 100%; max-width: 360px; height: auto; }
.feature.plain .shot img { max-width: 300px; border-radius: 26px; border: 1px solid var(--line); }
.closing { margin: 54px 0 0; }

@media (min-width: 860px) {
  main { max-width: 940px; }
  .demo { min-height: 262px; }
  .badge img { height: 68px; }
  h1 { font-size: 54px; }
  /* Side by side, and alternating, so the eye is not walked down one column. */
  .feature { display: grid; grid-template-columns: 1fr 1fr; align-items: center; gap: 48px; }
  .feature .shot { margin-top: 0; }
  /* .flip is set in the markup, because nth-of-type counts every <section>
     on the page and the demo and closing block broke the rhythm. */
  .feature.flip .words { order: 2; }
  .feature h2 { margin-top: 0; }
  .result { gap: 24px; padding: 22px; }
  .cover { width: 132px; height: 132px; border-radius: 15px; }
}

@media (prefers-reduced-motion: reduce) {
  .caret, .dots i { animation: none }
  .result.in, .tracks li.in { animation: none }
}

/* --- App Store badge -----------------------------------------------------
   Apple's artwork, unmodified. Their guidelines set a minimum size and a
   clear space around it, so the badge is never scaled below 40px tall and
   never has anything set against its edge. */
.badge { display: inline-block; margin: 22px 0 4px; }
/* Apple's minimum is 40px tall; this sits well above it so the badge reads as
   the thing to press rather than a footnote. */
.badge img { height: 62px; width: auto; display: block; }
/* The link is live from the moment the App Store listing is. */

/* --- Press kit ----------------------------------------------------------- */
.facts { border-collapse: collapse; width: 100%; margin: 14px 0 8px; }
.facts th, .facts td { text-align: left; vertical-align: top; padding: 9px 0; border-top: 1px solid var(--line); font-size: 16px; }
.facts th { font-weight: 600; width: 34%; padding-right: 16px; }
.facts tr:last-child td, .facts tr:last-child th { border-bottom: 1px solid var(--line); }

.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 18px; margin: 18px 0 8px; }
.grid figure { margin: 0; display: flex; flex-direction: column; align-items: center; }
/* Matched on height, not width: three of these are framed phones and two are
   raw screens, and those two are a taller shape. Equal widths made them
   noticeably bigger than the rest. */
.grid img { height: 260px; width: auto; max-width: 100%; border-radius: 14px; }
.grid figcaption { color: var(--soft); font-size: 14px; margin-top: 6px; }

/* --- Questions ----------------------------------------------------------- */
.faq { margin: 54px 0 0; }
.faq details p { margin: 10px 0 2px; color: var(--soft); }
.faq summary::marker { color: var(--soft); }
