/* Doppelgänger website.
   Two layers, in this order:
     1. the shell  — brand, tokens, page furniture (from the announcement,
                     which is where the corrected brand landed first)
     2. components — buttons, tiles, cards, pricing, steps, FAQ, changelog
                     (from the hand-written site, retargeted onto the tokens)
   Edit here, not per page. */

/* Montserrat 300, the app's wordmark face. Self-hosted, not fetched from
   Google: a third-party font request would leak every visitor's IP address and
   contradict the privacy notice. Licence: fonts/montserrat-OFL.txt (SIL OFL 1.1). */
@font-face{
  font-family:"Montserrat";
  font-style:normal;
  font-weight:300;
  font-display:swap;
  src:url("fonts/montserrat-latin-300.woff2") format("woff2");
}

/* ============================ 1. shell ============================ */

:root{
  --bg:#0e0e0e; --surface:#161616; --surface-hover:#1e1e1e;
  --line:#262626; --line-strong:#3f3f46;
  --ink:#f4f4f5; --dim:#a1a1aa; --faint:#6b6b70;

  /* Straight off the mark in assets/logo.svg. --cyan-pale is that same cyan
     lightened to 70% (hue and saturation untouched) so link text carries the
     brand hue and still clears WCAG AA on --bg at 12.4:1.
     The -rgb pairs exist so the translucent tints further down cannot drift
     out of step with their solid colour again -- which is exactly what had
     happened: six tints were still frozen at the pre-brand rgb(56,194,220)
     and rgb(242,172,51) long after the hexes were corrected. Every tint below
     is now derived, so there is only ever one place to change a brand colour. */
  --yellow:#FFC131; --yellow-rgb:255,193,49;
  --yellow-hover:#FFCD58;   /* --yellow at +7.6% lightness, hue and sat held */
  --yellow-ink:#0e0e0e;     /* text on a --yellow fill */
  --cyan:#24C8DB; --cyan-rgb:36,200,219; --cyan-pale:#7CDEE9;

  /* Notices only. The brand has no alarm colour, and it should not acquire one
     by tinting --yellow: `important` and `critical` are two different claims and
     the whole point of the ladder is that they do not look alike. --red-pale is
     --red lightened to clear WCAG AA on --bg, the same derivation --cyan-pale
     uses, so there is one place to change it. */
  --red:#F2555A; --red-rgb:242,85,90; --red-pale:#F98A8E;

  --maxw:960px; --shotw:1180px; --readw:680px;
}

*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0; min-height:100vh; display:flex; flex-direction:column;
  background:var(--bg); color:var(--ink);
  font-family:-apple-system,BlinkMacSystemFont,"SF Pro Text","Segoe UI",system-ui,sans-serif;
  -webkit-font-smoothing:antialiased; line-height:1.6; font-size:16px;
}
/* Pairs with body's flex column to hold the footer at the bottom of short
   pages. baseof.html has always emitted this element; nothing ever styled it,
   so the sticky footer it implies has never actually worked. */
.grow{flex:1 0 auto}

.wrap{max-width:var(--maxw); margin:0 auto; padding:0 20px; width:100%}
.wrap-wide{max-width:var(--shotw); margin:0 auto; padding:0 20px; width:100%}
.wrap-read,.narrow{max-width:var(--readw); margin:0 auto; padding:0 20px; width:100%}

h1,h2,h3{
  font-family:-apple-system,BlinkMacSystemFont,"SF Pro Display","Segoe UI",system-ui,sans-serif;
  letter-spacing:-0.02em; line-height:1.2; font-weight:650;
}
h1{font-size:clamp(1.9rem,4.5vw,2.9rem); margin:0.4em 0}
h2{font-size:1.5rem; margin:2.2em 0 0.6em}
h3{font-size:1.15rem; margin:1.6em 0 0.4em}
p{color:var(--dim)}
strong{color:var(--ink); font-weight:600}
a{color:var(--cyan-pale); text-decoration:none}
a:hover{text-decoration:underline}

/* ---- header ---- */
.nav{display:flex; align-items:center; gap:22px; padding:16px 0; border-bottom:1px solid var(--line)}
/* Wordmark geometry mirrors the app's TopBar exactly (src/lib/brand.ts):
   Montserrat 300 at 24px, +0.05em tracking, and the mark sized to the same
   24px as the glyphs with an 8px gap. */
.nav .brand{display:flex; align-items:center; gap:8px; color:var(--ink);
  font-family:"Montserrat",system-ui,sans-serif; font-weight:300;
  font-size:24px; letter-spacing:0.05em; line-height:1.15}
.nav .brand:hover{text-decoration:none}
.nav .brand-mark{display:block; width:24px; height:24px; flex:0 0 auto}
.nav .links{margin-left:auto; display:flex; gap:18px; align-items:center; flex-wrap:wrap}
.nav .links a{color:var(--dim); font-size:0.9rem}
.nav .links a:hover{color:var(--ink); text-decoration:none}
.nav .links a[aria-current="page"]{color:var(--ink)}
.nav .links a.btn-primary, .nav .links a.btn-primary:hover{color:var(--yellow-ink)}

/* Below ~720px the seven links no longer fit beside the wordmark, and
   flex-wrap turned them into a tall column that pushed the page off screen.
   They wrap under the brand instead, as rows. No JS, no hamburger: seven
   short links fit in two lines, and a menu nobody can see is worse. */
@media (max-width:720px){
  .nav{flex-wrap:wrap; gap:12px}
  .nav .links{margin-left:0; width:100%; gap:14px 16px; justify-content:flex-start}
  .nav .links a{font-size:0.85rem}
}

/* ---- footer ---- */
footer{border-top:1px solid var(--line); margin-top:80px; padding:28px 0 40px; font-size:0.85rem; color:var(--faint)}
footer .cols{display:flex; gap:28px; flex-wrap:wrap; align-items:flex-start}
footer .cols > div{flex:1 1 160px}
footer a{color:var(--dim)}
footer .cols > .legal-links{flex:2 1 auto; display:flex; flex-wrap:wrap; justify-content:flex-end; gap:6px 20px}
footer .legal{margin:0 0 8px; color:var(--dim)}
.nav .lang{font-size:0.85rem; color:var(--faint); white-space:nowrap}
.nav .lang a{color:var(--dim)}
.nav .lang .on{color:var(--ink); font-weight:600}

/* ---- hero ---- */
.hero{text-align:center; padding:72px 0 8px}
.hero .eyebrow{
  display:inline-block; font-size:0.8rem; color:var(--cyan-pale);
  background:rgba(var(--cyan-rgb),0.12); border-radius:999px; padding:4px 14px; margin-bottom:18px;
}
.hero .sub{max-width:540px; margin:14px auto 26px; font-size:1.1rem}
.hero .cta{display:flex; gap:12px; justify-content:center; flex-wrap:wrap}
.hero .micro,.micro{text-align:center; font-size:0.82rem; color:var(--faint); margin-top:16px}

/* ---- prose (legal, privacy, guides) ---- */
.doc{padding:56px 0 8px}
.doc h1{font-size:clamp(1.7rem,3.6vw,2.3rem); text-align:left; margin:0 0 6px}
.doc .lede,.legal .lede{font-size:1.05rem; color:var(--dim); margin:0 0 4px}
.doc .updated,.legal .updated{font-size:0.82rem; color:var(--faint); margin:0 0 34px}
.doc h2{font-size:1.05rem; font-weight:600; color:var(--ink); letter-spacing:-0.01em; margin:34px 0 8px}
.doc p{margin:0 0 12px}
.doc p code{overflow-wrap:anywhere} /* long stream URLs wrap on phones */
.doc ul{color:var(--dim); margin:0 0 12px; padding-left:20px}
.doc li{margin-bottom:6px}
.legal h2{font-size:1.15rem}
.legal p,.legal li{font-size:0.95rem}

/* Breadcrumb on the feature detail pages. This was the same inline style
   copy-pasted onto three <p> elements; the separator is drawn by CSS so a
   screen reader announces the trail rather than reading "slash". */
.crumb{font-size:0.85rem; color:var(--faint); margin:0 0 8px}
.crumb [aria-current]::before{content:" / "}

/* Post list on the blog section. */
.posts{list-style:none; margin:24px 0 0; padding:0}
.posts li{padding:18px 0; border-bottom:1px solid var(--line)}
.posts h2{font-size:1.15rem; margin:0 0 4px}
.posts .date{font-size:0.82rem; color:var(--faint); margin:0 0 6px}
.posts p{margin:0; font-size:0.95rem}

/* ---- screenshots ---- */
.shot{
  display:block; width:100%; height:auto; overflow:hidden; border-radius:12px;
  border:1px solid var(--line-strong);
  box-shadow:0 30px 70px -20px rgba(0,0,0,.85), 0 0 0 1px rgba(255,255,255,.03);
  background:var(--surface);
}
.shot img{display:block; width:100%; height:auto}
.shot .placeholder{
  aspect-ratio:16 / 10; display:flex; align-items:center; justify-content:center;
  color:var(--faint); font-size:0.85rem; text-align:center; padding:20px;
}
.shot-sm .placeholder{aspect-ratio:16 / 9}
.shot-hero{margin-top:44px; border-radius:14px;
  -webkit-mask-image:linear-gradient(to bottom,#000 78%,transparent 100%);
          mask-image:linear-gradient(to bottom,#000 78%,transparent 100%)}
.shot-hero-wrap{position:relative}
.shot-hero-wrap::before{
  content:""; position:absolute; inset:12% 10% 30% 10%; z-index:-1; filter:blur(90px); opacity:.30;
  background:radial-gradient(60% 60% at 25% 40%,var(--cyan),transparent 70%),
             radial-gradient(60% 60% at 75% 60%,var(--yellow),transparent 70%);
}
/* A single captioned shot with its own dark/light control, standing on its
   own between sections. Caption styling matches .duo so the two agree. */
figure.shot-block{margin:56px 0 0}   /* figures carry a UA side margin; drop it */
.shot-block figcaption{margin-top:14px; font-size:0.92rem; color:var(--dim); text-align:center}
.shot-block figcaption b{display:block; color:var(--ink); font-weight:600; font-size:1rem; margin-bottom:2px}
.shot-block .theme-switch{margin-bottom:18px}

.duo{display:grid; grid-template-columns:1fr 1fr; gap:28px; margin-top:64px}
.duo figure{margin:0}
.duo figcaption{margin-top:14px; font-size:0.92rem; color:var(--dim)}
.duo figcaption b{display:block; color:var(--ink); font-weight:600; font-size:1rem; margin-bottom:2px}
@media (max-width:760px){ .duo{grid-template-columns:1fr; gap:40px; margin-top:48px} }

/* ---- dark / light control.
   Switches which app screenshot is shown, not the site theme. The site is
   dark only. Revealed just when JS runs, so it never sits there inert. ---- */
.theme-toggle{display:none}
.js .theme-toggle{
  display:inline-flex; gap:2px; margin:26px auto 0; padding:3px;
  border:1px solid var(--line); border-radius:999px; background:var(--surface);
}
.theme-switch{display:flex; justify-content:center}
.theme-toggle button{
  appearance:none; border:0; cursor:pointer; font:inherit; font-size:0.82rem; line-height:1;
  padding:7px 16px; border-radius:999px; background:transparent; color:var(--dim);
  transition:background .15s ease, color .15s ease;
}
.theme-toggle button:hover{color:var(--ink)}
.theme-toggle button[aria-pressed="true"]{background:rgba(var(--cyan-rgb),0.14); color:var(--cyan-pale)}
.theme-toggle button:focus-visible{outline:2px solid var(--cyan); outline-offset:2px}

/* ========================== 2. components ========================== */

.btn{display:inline-block; border-radius:8px; padding:10px 20px; font-size:0.95rem; font-weight:600; line-height:1.4}
.btn:hover{text-decoration:none}
.btn-primary{background:var(--yellow); color:var(--yellow-ink)}
.btn-primary:hover{background:var(--yellow-hover)}
.btn-ghost{border:1px solid var(--line-strong); color:var(--ink)}
.btn-ghost:hover{background:var(--surface-hover)}
.btn-sm{padding:6px 14px; font-size:0.85rem}
/* A button that is not available yet: shown, but visibly not clickable. */
.btn[aria-disabled="true"]{opacity:0.5; cursor:default; pointer-events:none}
/* A question list's heading with a quiet "Expand all" beside it. */
.faq-head{display:flex; align-items:baseline; justify-content:space-between; gap:16px}
.link-btn{background:none; border:0; padding:0; font:inherit; font-size:0.85rem; color:var(--dim); cursor:pointer; white-space:nowrap}
.link-btn:hover{color:var(--ink); text-decoration:underline}

/* ---- feature tiles ---- */
.tiles{display:grid; gap:12px; margin:24px 0}
.tiles-2{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
.tiles-4{grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}
.tile{background:var(--surface); border:1px solid var(--line); border-radius:12px; padding:18px}
.tile h3{margin:10px 0 6px; font-size:1.02rem; letter-spacing:-0.01em}
.tile p{margin:0; font-size:0.88rem}
.tile .ico{font-size:1.3rem; line-height:1}
.ico-y{color:var(--yellow)}
.ico-c{color:var(--cyan)}

/* ---- sections / cards / tables ---- */
.section{padding:28px 0}
.card{background:var(--surface); border:1px solid var(--line); border-radius:12px; padding:24px}
.card-accent{border:1.5px solid var(--yellow)}

table.cmp{width:100%; border-collapse:collapse; margin:24px 0; font-size:0.92rem}
table.cmp th,table.cmp td{padding:10px 12px; border-bottom:1px solid var(--line); text-align:left; vertical-align:top}
table.cmp th{color:var(--ink); font-weight:600}
table.cmp td{color:var(--dim)}
table.cmp td.y{color:var(--yellow)}
table.cmp td.c{color:var(--cyan-pale)}

/* ---- pricing ---- */
.price-cards{display:grid; grid-template-columns:repeat(auto-fit,minmax(260px,1fr)); gap:14px; margin:28px 0}
.price-cards .card p.tier{margin:0; font-size:0.85rem}
.price-cards .card .amount{font-size:2rem; font-weight:650; letter-spacing:-0.02em; margin:4px 0 12px; color:var(--ink)}
.price-cards .card .amount small{font-size:0.9rem; color:var(--dim); font-weight:400}
.price-cards ul{margin:0; padding-left:18px; color:var(--dim); font-size:0.92rem}
.price-cards li{margin:5px 0}

/* ---- steps (landers) ---- */
.steps{counter-reset:step; list-style:none; padding:0; margin:24px 0}
.steps li{counter-increment:step; position:relative; padding:6px 0 6px 44px; color:var(--dim); font-size:1rem}
.steps li::before{
  content:counter(step); position:absolute; left:0; top:6px;
  width:28px; height:28px; border-radius:50%;
  background:rgba(var(--yellow-rgb),0.15); color:var(--yellow); font-weight:600;
  display:flex; align-items:center; justify-content:center; font-size:0.9rem;
}

/* ---- FAQ ---- */
details{border-bottom:1px solid var(--line); padding:4px 0}
details summary{
  cursor:pointer; color:var(--ink); font-weight:500; padding:12px 0; list-style:none;
  display:flex; justify-content:space-between; align-items:center;
}
details summary::-webkit-details-marker{display:none}
details summary::after{content:"▾"; color:var(--faint); transition:transform 0.15s}
details[open] summary::after{transform:rotate(180deg)}
details .a{padding:0 0 16px; color:var(--dim); font-size:0.95rem}
details .a p{margin:0 0 10px}

/* ---- feature catalog ---- */
.cat h2{color:var(--yellow); font-size:0.95rem; text-transform:none; margin:26px 0 8px}
.cat ul{margin:0; padding:0; list-style:none; display:grid; grid-template-columns:repeat(auto-fit,minmax(260px,1fr)); gap:4px 24px}
.cat li{color:var(--dim); font-size:0.92rem; padding:5px 0; border-bottom:1px solid var(--line)}
.cat li strong{font-weight:500}

/* ---- changelog ---- */
.release{border-left:2px solid var(--line); padding-left:20px; margin:28px 0}
.release h1,.release h2,.release h3{margin-top:0}
.release h2{font-size:1.15rem}   /* changelog versions, and notices on the status page */
.release h1{font-size:1.5rem}    /* a notice on its own page, where it is the subject */
.release .date{font-size:0.82rem; color:var(--faint)}
.release ul{color:var(--dim); margin:0 0 12px; padding-left:20px}
.release li{margin-bottom:6px}

/* ---- waitlist ---- */
.waitlist{
  display:flex; gap:10px; flex-wrap:wrap; align-items:center;
  background:var(--surface); border:1px solid var(--line); border-radius:12px;
  padding:20px 24px; margin:40px 0;
}
.waitlist p{margin:0; flex:1 1 240px; font-size:0.95rem}
.waitlist input{
  background:var(--bg); border:1px solid var(--line-strong); border-radius:8px;
  color:var(--ink); padding:9px 14px; font-size:0.9rem; min-width:200px;
}
.waitlist input::placeholder{color:var(--faint)}
.waitlist button{
  background:none; border:1px solid rgba(var(--cyan-rgb),0.4); color:var(--cyan-pale);
  border-radius:8px; padding:9px 18px; font-size:0.9rem; cursor:pointer;
}
.waitlist button:hover{background:rgba(var(--cyan-rgb),0.1)}

/* ---- utilities ---- */
.center{text-align:center}
/* Music services we have tested, as plain-text chips (names only, no brand logos),
   drawn like .btn-ghost but not clickable. */
.chips{list-style:none; padding:0; margin:20px auto 6px; max-width:760px; display:flex; flex-wrap:wrap; justify-content:center; gap:10px}
.chips li{border:1px solid var(--line-strong); border-radius:8px; padding:10px 20px; font-weight:600; font-size:0.95rem; line-height:1.4; color:var(--ink)}
.mt0{margin-top:0}
.notice{
  background:rgba(var(--cyan-rgb),0.08); border:1px solid rgba(var(--cyan-rgb),0.25);
  border-radius:10px; padding:14px 18px; font-size:0.9rem; color:var(--dim); margin:20px 0;
}

/* ---- notices ---- */
/* The severity label is text, not a colour alone: the ladder has to survive
   being read by someone who cannot tell the three tints apart. Colour is the
   second signal, never the only one. */
.sev{
  font-size:0.72rem; letter-spacing:0.08em; text-transform:uppercase;
  margin:0 0 4px; color:var(--faint);
}
.sev-info{color:var(--cyan-pale)}
.sev-important{color:var(--yellow)}
.sev-critical{color:var(--red-pale)}

.release.notice-important{border-left-color:rgba(var(--yellow-rgb),0.55)}
.release.notice-critical{border-left-color:rgba(var(--red-rgb),0.6)}

.notice.notice-important{
  background:rgba(var(--yellow-rgb),0.08); border-color:rgba(var(--yellow-rgb),0.28);
}
.notice.notice-critical{
  background:rgba(var(--red-rgb),0.09); border-color:rgba(var(--red-rgb),0.32);
}

/* The band sits above the hero on the homepage and the download page. It is
   flush to the top and quiet: a notice, not an interstitial. */
.notice-band{margin:18px 0 0}
.notice-band p{margin:0}
