/* global React, Icon, WaveBars, AILabel, AlbumCover, LANGS, BookmarkButton, ReadingModeToggle, DepthToggle, FeedbackBar, QuietAd */
const { useState, useEffect, useRef, useMemo } = React;

// ---- Song catalog ----
// Keyed by URL slug. Each line's `t` is the ORIGINAL lyric in the composer's
// language (never translated). Each line's `m` map carries an interpretation
// per UI language (lang -> text). `originalLang` is the BCP code of the lyric
// text — surfaced in UI so readers see lyrics stay in the songwriter's language.
const SONGS = {};

SONGS['vela-maren/cassette-light-meaning'] = {
  slug: 'vela-maren/cassette-light-meaning',
  title: 'Cassette Light',
  artist: 'Vela Maren',
  album: 'Indoor Weather',
  year: 2025,
  genre: 'Indie pop',
  length: '3:42',
  seed: 0,
  originalLang: 'EN',
  summary: {
    EN: 'A quiet meditation on staying loyal to a memory longer than the memory deserves. Vela Maren uses the worn-out cassette as a metaphor for replaying a relationship — gentle, knowing, and finally letting the signal fade without bitterness.',
    ID: 'Renungan tenang tentang setia pada sebuah kenangan lebih lama dari yang sebenarnya pantas. Vela Maren memakai kaset yang sudah tipis sebagai perumpamaan: terus memutar ulang hubungan yang sudah selesai — lembut, sadar, dan akhirnya merelakannya tanpa kepahitan.',
    ES: 'Una meditación serena sobre seguir fiel a un recuerdo más tiempo del que merece. Vela Maren usa la cinta gastada como metáfora para revivir una relación: tierna, lúcida y, al fin, dejando que la señal se apague sin amargura.',
    PT: 'Uma meditação silenciosa sobre permanecer leal a uma memória mais tempo do que ela merece. Vela Maren usa a fita desgastada como metáfora para repetir um relacionamento — gentil, consciente e, no fim, deixando o sinal desaparecer sem amargura.',
    FR: 'Une méditation paisible sur la fidélité à un souvenir qui ne la mérite plus. Vela Maren se sert de la cassette usée comme d\'une métaphore : on rejoue la relation, doucement, lucidement, puis on laisse le signal s\'éteindre sans amertume.',
    JP: '記憶に必要以上に忠実でいることを静かに見つめた一曲。すり減ったカセットを比喩に、関係を繰り返し再生し、やがて静かに、苦さもなく信号を消していく姿を描く。',
  },
  themes: {
    EN: ['Memory', 'Nostalgia', 'Tape & analog', 'Loneliness as warmth', 'Communication breakdown'],
    ID: ['Memori', 'Nostalgia', 'Kaset & analog', 'Kesepian sebagai kehangatan', 'Putusnya komunikasi'],
    ES: ['Memoria', 'Nostalgia', 'Cinta y analógico', 'Soledad como calor', 'Comunicación rota'],
    PT: ['Memória', 'Nostalgia', 'Fita & analógico', 'Solidão como calor', 'Comunicação rompida'],
    FR: ['Mémoire', 'Nostalgie', 'Cassette & analogique', 'Solitude comme chaleur', 'Rupture de communication'],
    JP: ['記憶', 'ノスタルジー', 'テープとアナログ', '温もりとしての孤独', 'コミュニケーションの断絶'],
  },
  mood: {
    EN: ['Wistful', 'Tender', 'Quietly hopeful'],
    ID: ['Sendu', 'Lembut', 'Diam-diam berharap'],
    ES: ['Melancólico', 'Tierno', 'Esperanzado en voz baja'],
    PT: ['Melancólico', 'Terno', 'Esperançoso em voz baixa'],
    FR: ['Mélancolique', 'Tendre', 'Doucement plein d\'espoir'],
    JP: ['切なげ', '優しい', '静かに希望的'],
  },
  references: {
    EN: [
      { t: 'Cassette / tape metaphor', n: 'The titular cassette echoes a long lineage of analog-decay songwriting — physical fragility standing in for emotional fragility.' },
      { t: 'Porch light as waiting', n: 'A familiar Americana image, reframed for a narrator who knows the person isn\'t coming back.' },
      { t: 'Static = unspoken affection', n: 'Reuses radio noise the way earlier writers used phone-line crackle: love that didn\'t arrive cleanly.' },
    ],
    ID: [
      { t: 'Perumpamaan kaset / pita', n: 'Kaset judulnya menggemakan tradisi panjang lagu bertema pelapukan analog — kerapuhan fisik berdiri sebagai kerapuhan emosional.' },
      { t: 'Lampu teras sebagai menanti', n: 'Citra Amerikana yang akrab, ditata ulang untuk narator yang tahu orangnya tak akan kembali.' },
      { t: 'Bising = afeksi yang tak terucap', n: 'Menggunakan bising radio seperti penulis lama memakai bunyi sambungan telepon: cinta yang tak datang dengan jernih.' },
    ],
    ES: [
      { t: 'Metáfora del casete', n: 'El casete del título se inscribe en una larga tradición de canciones sobre decadencia analógica — la fragilidad física como fragilidad emocional.' },
      { t: 'Luz del porche como espera', n: 'Imagen familiar del americana, reescrita para una voz que ya sabe que la persona no vuelve.' },
      { t: 'Estática = afecto no dicho', n: 'Reutiliza el ruido de radio como otros usaron el crepitar del teléfono: amor que no llegó limpio.' },
    ],
    PT: [
      { t: 'Metáfora da fita', n: 'A fita do título dialoga com uma longa linhagem de canções sobre decadência analógica — fragilidade física como fragilidade emocional.' },
      { t: 'Luz da varanda como espera', n: 'Imagem familiar do americana, recontada por uma voz que já sabe que a pessoa não volta.' },
      { t: 'Estática = afeto não dito', n: 'Usa o chiado do rádio como autores anteriores usavam o estalido do telefone: amor que não chegou limpo.' },
    ],
    FR: [
      { t: 'Métaphore de la cassette', n: 'La cassette du titre s\'inscrit dans une longue lignée de chansons sur le délabrement analogique — fragilité physique pour fragilité émotionnelle.' },
      { t: 'Lampe du perron comme attente', n: 'Image familière de l\'americana, reprise pour une voix qui sait déjà que la personne ne reviendra pas.' },
      { t: 'Friture = affection tue', n: 'Réutilise le bruit radio comme d\'autres ont utilisé le grésillement du téléphone : un amour qui n\'est pas arrivé propre.' },
    ],
    JP: [
      { t: 'カセット／テープの比喩', n: 'タイトルのカセットは、アナログの劣化を題材にしてきた長い系譜と響き合う — 物理的な脆さが、感情の脆さとして立ち上がる。' },
      { t: '待つことのポーチライト', n: '見慣れたアメリカーナのイメージを、相手はもう戻らないと知っている語り手のために再構築する。' },
      { t: 'ノイズ＝語られない愛情', n: 'かつての書き手が電話線の雑音を使ったように、ラジオのノイズを再利用 — きれいに届かなかった愛として。' },
    ],
  },
  sections: [
    {
      label: { EN: 'Verse 1', ID: 'Bait 1', ES: 'Verso 1', PT: 'Verso 1', FR: 'Couplet 1', JP: 'バース 1' },
      lines: [
        { t: 'I keep the porch light on like I forgot the year',
          m: {
            EN: 'The narrator performs the rituals of waiting long after waiting is reasonable. The porch light is small, domestic, and quietly delusional — comfort doing the work of denial.',
            ID: 'Narator menjalankan ritual menunggu jauh setelah menunggu masuk akal. Lampu teras itu kecil, rumahan, dan diam-diam delusi — kenyamanan yang sebenarnya sedang menyangkal.',
            ES: 'La voz mantiene los rituales de esperar mucho después de que esperar tenga sentido. La luz del porche es pequeña, doméstica y silenciosamente ilusoria — el consuelo haciendo el trabajo de la negación.',
            PT: 'A voz mantém os rituais de esperar muito depois de esperar fazer sentido. A luz da varanda é pequena, doméstica e em silêncio ilusória — o conforto fazendo o trabalho da negação.',
            FR: 'Le narrateur exécute les rituels de l\'attente bien après que l\'attente soit raisonnable. La lampe du perron est petite, domestique, silencieusement illusoire — un confort qui fait le travail du déni.',
            JP: '語り手は、待つことが理に適わなくなった後も、待つための儀式を続ける。ポーチの明かりは小さく、家庭的で、密かに自己欺瞞 — 安らぎが否認の役目を果たしている。',
          } },
        { t: 'A house full of sweaters that still know your shape',
          m: {
            EN: 'Possessions retain a body the body has left. The image is tactile, not tragic — closer to muscle memory than mourning.',
            ID: 'Benda-benda menyimpan bentuk tubuh yang sudah tak ada di sana. Citra ini taktil, bukan tragis — lebih dekat ke memori otot daripada berkabung.',
            ES: 'Los objetos guardan un cuerpo que el cuerpo ya dejó. La imagen es táctil, no trágica — más cercana a la memoria muscular que al duelo.',
            PT: 'Os objetos guardam um corpo que o corpo já deixou. A imagem é tátil, não trágica — mais perto da memória muscular do que do luto.',
            FR: 'Les objets retiennent un corps que le corps a quitté. L\'image est tactile, pas tragique — plus proche de la mémoire musculaire que du deuil.',
            JP: '物が、身体が去った後の身体の形を覚えている。触覚的で、悲劇的ではない — 喪というより筋肉の記憶に近い。',
          } },
        { t: 'I burn the same coffee, I make the same shape',
          m: {
            EN: 'Repetition as a way to keep someone present. The narrator notices their own pattern, which is the first crack in it.',
            ID: 'Pengulangan sebagai cara menahan kehadiran seseorang. Narator menyadari polanya sendiri — itu retakan pertamanya.',
            ES: 'Repetir como forma de retener a alguien. La voz nota su propio patrón, y esa es la primera grieta.',
            PT: 'Repetir como forma de manter alguém presente. A voz percebe o próprio padrão — e essa é a primeira rachadura.',
            FR: 'Répéter pour garder quelqu\'un présent. Le narrateur remarque sa propre habitude — c\'est la première fissure.',
            JP: '誰かを残す手段としての反復。語り手が自分のパターンに気づく — それが最初のひび割れ。',
          } },
        { t: 'You drove like a question I never asked out loud',
          m: {
            EN: 'Recklessness reads as a kind of curiosity. The line quietly admits the narrator wanted more than they ever said.',
            ID: 'Kenekatan dibaca sebagai bentuk keingintahuan. Baris ini diam-diam mengakui narator menginginkan lebih dari yang pernah diucapkan.',
            ES: 'La temeridad se lee como curiosidad. El verso confiesa, en voz baja, que la voz quería más de lo que llegó a decir.',
            PT: 'A imprudência se lê como curiosidade. O verso confessa, baixinho, que a voz queria mais do que chegou a dizer.',
            FR: 'L\'audace se lit comme une curiosité. Le vers admet à voix basse que le narrateur voulait plus qu\'il n\'a jamais dit.',
            JP: '無謀さは一種の好奇心として読める。語り手が口にした以上に望んでいたことを、この一行はそっと認める。',
          } },
      ],
    },
    {
      label: { EN: 'Pre-chorus', ID: 'Pra-chorus', ES: 'Pre-estribillo', PT: 'Pré-refrão', FR: 'Pré-refrain', JP: 'プリコーラス' },
      lines: [
        { t: 'And I know the song by heart',
          m: {
            EN: 'A flag for self-awareness: the narrator can see the loop they\'re in.',
            ID: 'Tanda kesadaran diri: narator bisa melihat lingkaran tempatnya berada.',
            ES: 'Una señal de autoconciencia: la voz ve el bucle en el que está.',
            PT: 'Um sinal de autoconsciência: a voz vê o loop em que está.',
            FR: 'Un drapeau de conscience de soi : le narrateur voit la boucle dans laquelle il est.',
            JP: '自己認識の合図 — 語り手は自分が回っているループを見ている。',
          } },
        { t: 'But I keep mouthing every part',
          m: {
            EN: 'Knowing is not the same as stopping. A small, honest line about how recovery actually moves.',
            ID: 'Mengerti tidak sama dengan berhenti. Baris jujur tentang bagaimana pemulihan sebenarnya berjalan.',
            ES: 'Saberlo no es lo mismo que dejarlo. Verso pequeño y honesto sobre cómo se mueve de verdad la recuperación.',
            PT: 'Saber não é o mesmo que parar. Verso pequeno e honesto sobre como a recuperação se move de fato.',
            FR: 'Savoir n\'est pas s\'arrêter. Petit vers honnête sur la façon dont la guérison avance vraiment.',
            JP: '分かっていることと止められることは違う。回復が実際にはどう動くかについての、小さく正直な一行。',
          } },
      ],
    },
    {
      label: { EN: 'Chorus', ID: 'Chorus', ES: 'Estribillo', PT: 'Refrão', FR: 'Refrain', JP: 'コーラス' },
      lines: [
        { t: 'So play it back, cassette light',
          m: {
            EN: '"Cassette light" is the song\'s coined image — the faint glow of a tape deck mid-rewind, here turned into something to live by. It frames memory as a small lamp, not a sun.',
            ID: '"Cassette light" adalah citra ciptaan lagu ini — kilauan lemah dek kaset yang sedang rewind, di sini menjadi sesuatu untuk dijadikan pegangan. Memori dibingkai sebagai lampu kecil, bukan matahari.',
            ES: '"Cassette light" es la imagen acuñada por la canción — el brillo tenue de la pletina rebobinando, vuelto aquí algo por lo que vivir. Encuadra la memoria como una lámpara pequeña, no un sol.',
            PT: '"Cassette light" é a imagem cunhada pela canção — o brilho fraco do tape deck rebobinando, aqui transformado em algo pelo qual viver. Enquadra a memória como uma lâmpada pequena, não um sol.',
            FR: '« Cassette light » est l\'image inventée par la chanson — la faible lueur d\'une platine en rembobinage, devenue ici quelque chose dont on vit. Elle cadre la mémoire comme une petite lampe, pas un soleil.',
            JP: '「カセットの明かり」はこの曲が編み出したイメージ — 巻き戻し中のテープデッキの淡い光が、生きる拠り所に変わる。記憶を、太陽ではなく小さなランプとして描く。',
          } },
        { t: 'Half a love, half a kite',
          m: {
            EN: 'A relationship sketched as something always partly tethered, partly drifting. The internal rhyme keeps the line gentle.',
            ID: 'Hubungan digambarkan sebagai sesuatu yang selalu setengah terikat, setengah terbang. Rima dalam baris menjaga nadanya tetap lembut.',
            ES: 'Una relación dibujada como algo siempre a medias atado, a medias a la deriva. La rima interna mantiene el verso suave.',
            PT: 'Uma relação esboçada como algo sempre meio amarrado, meio à deriva. A rima interna mantém o verso suave.',
            FR: 'Une relation esquissée comme toujours à demi attachée, à demi à la dérive. La rime interne garde le vers tendre.',
            JP: '常に半ば繋がれ、半ば漂う関係としてのスケッチ。内韻が一行を柔らかく保つ。',
          } },
        { t: 'We rewound the summer until the tape went thin',
          m: {
            EN: 'The thesis verb of the song — rewinding. Repeating something good is shown to be how it ends.',
            ID: 'Kata kerja tesis lagu — memutar ulang. Mengulang sesuatu yang baik justru jadi cara berakhirnya.',
            ES: 'El verbo-tesis de la canción — rebobinar. Repetir algo bueno se muestra como la forma en que acaba.',
            PT: 'O verbo-tese da canção — rebobinar. Repetir algo bom é mostrado como o jeito que ele acaba.',
            FR: 'Le verbe-thèse de la chanson : rembobiner. Répéter une bonne chose s\'avère être la manière dont elle se termine.',
            JP: '曲のテーゼ動詞は「巻き戻す」。良いものを繰り返すことが、その終わり方であると示される。',
          } },
        { t: 'Static is just love that didn\'t make it home',
          m: {
            EN: 'The song\'s most-quoted line. Noise and miscommunication get reframed as affection that simply lost its signal — generous, never bitter.',
            ID: 'Baris paling sering dikutip dari lagu. Bising dan miskomunikasi dimaknai ulang sebagai cinta yang sekadar kehilangan sinyalnya — lapang, tanpa kepahitan.',
            ES: 'La línea más citada de la canción. El ruido y los malentendidos se reformulan como afecto que solo perdió su señal — generoso, nunca amargo.',
            PT: 'O verso mais citado da canção. Ruído e mal-entendidos viram afeto que apenas perdeu o sinal — generoso, nunca amargo.',
            FR: 'Le vers le plus cité de la chanson. Bruit et malentendus deviennent un amour qui a juste perdu son signal — généreux, jamais amer.',
            JP: '最も引用される一行。ノイズとすれ違いが、ただ信号を失った愛として読み替えられる — 寛やかで、苦さがない。',
          } },
      ],
    },
    {
      label: { EN: 'Verse 2', ID: 'Bait 2', ES: 'Verso 2', PT: 'Verso 2', FR: 'Couplet 2', JP: 'バース 2' },
      lines: [
        { t: 'You learned my city by the diners we closed',
          m: {
            EN: 'Place is mapped through small late-night intimacies. A way of saying: we owned a version of this town together.',
            ID: 'Tempat dipetakan lewat keintiman-keintiman kecil di larut malam. Cara mengatakan: kami pernah memiliki satu versi kota ini bersama.',
            ES: 'El lugar se mapea por pequeñas intimidades nocturnas. Una forma de decir: tuvimos juntos una versión de esta ciudad.',
            PT: 'O lugar é mapeado por pequenas intimidades de madrugada. Um jeito de dizer: tivemos juntos uma versão desta cidade.',
            FR: 'On cartographie le lieu par de petites intimités tardives. Une manière de dire : on a possédé ensemble une version de cette ville.',
            JP: '夜更けの小さな親密さで、街は地図にされる。一緒にこの街のあるバージョンを所有していた、と言うやり方。',
          } },
        { t: 'I learned your weather like a second language',
          m: {
            EN: 'Emotional attunement framed as fluency. Tender, but also faintly past-tense — like a language she no longer needs.',
            ID: 'Penyesuaian emosi dibingkai sebagai kefasihan. Lembut, tapi juga samar-samar lampau — seperti bahasa yang tak ia perlukan lagi.',
            ES: 'La sintonía emocional enmarcada como fluidez. Tierna, pero también levemente en pasado — como un idioma que ya no le hace falta.',
            PT: 'A sintonia emocional enquadrada como fluência. Terna, mas também levemente em pretérito — como uma língua que ela não precisa mais.',
            FR: 'L\'accord émotionnel cadré comme une maîtrise. Tendre, mais aussi légèrement au passé — comme une langue dont elle n\'a plus besoin.',
            JP: '感情の同調が、言語の流暢さとして描かれる。優しい。同時にうっすら過去形 — もう必要のなくなった言語のように。',
          } },
        { t: 'We were a long song on a short drive',
          m: {
            EN: 'The relationship outscaled the situation it lived in. A clean, slightly rueful image of mismatch.',
            ID: 'Hubungan ini lebih besar dari situasi tempat ia hidup. Citra ketidakcocokan yang bersih, sedikit menyesal.',
            ES: 'La relación superaba la situación en la que vivía. Una imagen limpia, ligeramente apenada, de desajuste.',
            PT: 'A relação era maior do que a situação em que vivia. Uma imagem limpa e levemente pesarosa de descompasso.',
            FR: 'La relation dépassait la situation où elle vivait. Une image nette, légèrement teintée de regret, de décalage.',
            JP: '関係は、それが置かれた状況より大きかった。すれ違いを、清潔に、わずかに悔いを残して描くイメージ。',
          } },
        { t: 'And every red light felt like an answer',
          m: {
            EN: 'Forced pauses become meaningful in hindsight. The narrator reads the universe for signs only after the fact.',
            ID: 'Jeda paksa baru terasa berarti setelah lewat. Narator membaca tanda dari semesta hanya sesudahnya.',
            ES: 'Las pausas forzadas se vuelven significativas en retrospectiva. La voz lee al universo en busca de señales solo después.',
            PT: 'As pausas forçadas ganham sentido depois. A voz lê o universo em busca de sinais só após o fato.',
            FR: 'Les pauses forcées prennent du sens après coup. Le narrateur ne lit l\'univers pour y trouver des signes qu\'a posteriori.',
            JP: '強いられた停止が、振り返って意味を帯びる。語り手が宇宙に兆しを読むのは、いつも事の後。',
          } },
      ],
    },
    {
      label: { EN: 'Bridge', ID: 'Bridge', ES: 'Puente', PT: 'Ponte', FR: 'Pont', JP: 'ブリッジ' },
      lines: [
        { t: 'Maybe forgetting is a kind of mercy',
          m: {
            EN: 'A turn toward acceptance. The bridge softens the loop the rest of the song has been spinning in.',
            ID: 'Pergantian menuju penerimaan. Bridge melembutkan lingkaran yang diputar oleh sisa lagu.',
            ES: 'Un giro hacia la aceptación. El puente suaviza el bucle en el que lleva girando el resto de la canción.',
            PT: 'Uma virada para a aceitação. A ponte suaviza o loop em que o resto da música vinha girando.',
            FR: 'Un virage vers l\'acceptation. Le pont adoucit la boucle dans laquelle le reste de la chanson tournait.',
            JP: '受け入れへの転換。残りの曲がずっと回っていたループを、ブリッジが柔らかくする。',
          } },
        { t: 'Maybe the tape just wants to be tape',
          m: {
            EN: 'The metaphor steps out of metaphor: the cassette is allowed to be an object again, not a vessel. A quiet form of release.',
            ID: 'Perumpamaan melepaskan diri dari perumpamaan: kasetnya diizinkan jadi benda lagi, bukan bejana. Pembebasan yang tenang.',
            ES: 'La metáfora sale de la metáfora: al casete se le permite volver a ser objeto, no vasija. Una forma silenciosa de soltar.',
            PT: 'A metáfora sai da metáfora: a fita pode voltar a ser objeto, não recipiente. Uma forma silenciosa de soltar.',
            FR: 'La métaphore sort de la métaphore : on autorise la cassette à n\'être qu\'un objet, plus un vase. Une forme calme de lâcher-prise.',
            JP: '比喩が比喩から降りる — カセットはもう一度ただの物に戻ることを許される。静かなかたちの手放し。',
          } },
      ],
    },
    {
      label: { EN: 'Final chorus', ID: 'Chorus akhir', ES: 'Estribillo final', PT: 'Refrão final', FR: 'Refrain final', JP: '最終コーラス' },
      lines: [
        { t: 'So play it back, cassette light',
          m: {
            EN: 'Same line, lower stakes — the second time around the image feels like a goodbye instead of a ritual.',
            ID: 'Baris yang sama, tegangan lebih rendah — pada kedua kalinya gambar itu terasa seperti perpisahan, bukan ritual.',
            ES: 'La misma línea, con menos en juego — la segunda vez la imagen se siente como un adiós, no como un rito.',
            PT: 'O mesmo verso, com menos em jogo — na segunda volta a imagem soa como uma despedida, não um ritual.',
            FR: 'Le même vers, avec moins en jeu — au second passage, l\'image ressemble à un adieu plus qu\'à un rituel.',
            JP: '同じ一行、賭けるものは小さい — 二度目の出現は、儀式ではなく別れに聞こえる。',
          } },
        { t: 'Half a love, half a kite',
          m: {
            EN: 'The kite, by the final chorus, has clearly slipped the string. The repetition itself does the storytelling.',
            ID: 'Pada chorus akhir, layang-layang itu jelas sudah lepas dari talinya. Pengulangannya sendiri bertugas bercerita.',
            ES: 'Para el estribillo final, la cometa ya se soltó del hilo. La propia repetición cuenta la historia.',
            PT: 'No refrão final, a pipa já soltou da linha. A própria repetição conta a história.',
            FR: 'Au refrain final, le cerf-volant a clairement lâché la ficelle. La répétition raconte d\'elle-même.',
            JP: '最終コーラスでは、凧は明らかに糸を離れている。繰り返しそのものが物語を担う。',
          } },
        { t: 'We rewound the summer until the tape went thin',
          m: {
            EN: 'Returns one last time, but quieter — the song is letting itself end.',
            ID: 'Kembali sekali lagi, tapi lebih tenang — lagu ini sedang mengizinkan dirinya berakhir.',
            ES: 'Vuelve una última vez, pero más bajo — la canción se está dejando terminar.',
            PT: 'Volta uma última vez, mais quieto — a música está se deixando terminar.',
            FR: 'Revient une dernière fois, mais en sourdine — la chanson se laisse finir.',
            JP: '最後にもう一度戻る、しかしより静かに — 曲は自らを終わらせている。',
          } },
        { t: 'Static is just love that didn\'t make it home',
          m: {
            EN: 'The closing thesis. The song doesn\'t resolve the loss; it just gives it a kinder name.',
            ID: 'Tesis penutup. Lagu ini tidak menyelesaikan kehilangannya; ia hanya memberinya nama yang lebih lembut.',
            ES: 'La tesis de cierre. La canción no resuelve la pérdida; solo le pone un nombre más amable.',
            PT: 'A tese de encerramento. A canção não resolve a perda; apenas lhe dá um nome mais gentil.',
            FR: 'La thèse de clôture. La chanson ne résout pas la perte ; elle lui donne juste un nom plus doux.',
            JP: '締めくくりのテーゼ。曲は喪失を解決しない — ただ、よりやさしい名前を与える。',
          } },
      ],
    },
  ],
};

// ============================================================================
// "Bintang Pulang" — Hara Mei (original: Bahasa Indonesia)
// ============================================================================
SONGS['hara-mei/bintang-pulang-meaning'] = {
  slug: 'hara-mei/bintang-pulang-meaning',
  title: 'Bintang Pulang',
  artist: 'Hara Mei',
  album: 'Lampu Beranda',
  year: 2024,
  genre: 'Indo R&B',
  length: '3:58',
  seed: 2,
  originalLang: 'ID',
  summary: {
    ID: 'Sebuah surat malam yang lembut tentang pulang sebagai arah, bukan tempat. Hara Mei menggunakan bintang yang "pulang" ke pagi sebagai metafora untuk seseorang yang akhirnya tahu di mana letak rumahnya — di dalam dirinya sendiri.',
    EN: 'A soft late-night letter about home as a direction, not a place. Hara Mei uses the image of a star "going home" at dawn as a metaphor for finally locating where home actually is — inside oneself.',
    ES: 'Una carta nocturna sobre el regreso como una dirección, no un lugar. Hara Mei usa la estrella que "vuelve" al amanecer como metáfora de quien por fin sabe dónde está su casa — dentro de sí.',
    PT: 'Uma carta noturna sobre voltar para casa como direção, não lugar. Hara Mei usa a estrela que "volta" ao amanhecer como metáfora de quem enfim sabe onde mora — dentro de si.',
    FR: 'Une lettre nocturne sur le retour comme direction, pas comme lieu. Hara Mei se sert de l\'étoile qui « rentre » à l\'aube pour dire qu\'on a enfin trouvé où l\'on habite — en soi.',
    JP: '帰ることを場所ではなく方角として描いた、夜の手紙のような一曲。明け方に「帰る」星を比喩に、本当の家が自分のなかにあると気づく姿を描く。',
  },
  themes: {
    ID: ['Pulang sebagai arah', 'Identitas', 'Subuh', 'Ketenangan'],
    EN: ['Home as direction', 'Identity', 'Dawn', 'Quiet selfhood'],
    ES: ['Volver como dirección', 'Identidad', 'Amanecer', 'Quietud propia'],
    PT: ['Voltar como direção', 'Identidade', 'Madrugada', 'Calma de si'],
    FR: ['Le retour comme direction', 'Identité', 'Aube', 'Soi tranquille'],
    JP: ['帰ること＝方角', 'アイデンティティ', '明け方', '静かな自己'],
  },
  mood: {
    ID: ['Lembut', 'Tenang', 'Diam-diam yakin'],
    EN: ['Soft', 'Calm', 'Quietly certain'],
    ES: ['Suave', 'Calmo', 'Certera en voz baja'],
    PT: ['Suave', 'Calma', 'Certeira em voz baixa'],
    FR: ['Doux', 'Calme', 'Tranquillement sûr'],
    JP: ['やわらか', '静か', '静かに確信を持って'],
  },
  references: {
    ID: [
      { t: 'Bintang & subuh', n: 'Citra astronomis dipakai bukan untuk megah, tapi untuk akrab — bintang yang "pulang" ke pagi, bukan yang jauh dan dingin.' },
      { t: 'Lampu beranda', n: 'Gema judul album. Lampu beranda di musik Indonesia kerap menandai siapa yang menunggu — di sini, lampu itu menandai diri sendiri.' },
      { t: 'R&B Indonesia 2020-an', n: 'Vokal lirih, drum lembut, ruang yang banyak — gaya yang mewarisi NIKI dan Pamungkas tapi lebih dalam pada keheningan.' },
    ],
    EN: [
      { t: 'Star & dawn imagery', n: 'Astronomy used not for grandeur but for intimacy — a star "going home" at sunrise, not a far cold thing.' },
      { t: 'Porch light', n: 'Echo of the album title. The porch light in Indonesian music often marks who waits — here, the light marks the self.' },
      { t: '2020s Indonesian R&B', n: 'Hushed vocal, soft drums, lots of space — inheriting NIKI and Pamungkas but deeper into the quiet.' },
    ],
    ES: [
      { t: 'Estrella y amanecer', n: 'La astronomía aquí no es grandeza, sino intimidad — una estrella que "vuelve" al alba, no algo lejano y frío.' },
      { t: 'Luz del porche', n: 'Eco del título del álbum. En la música indonesia esa luz suele señalar a quien espera — aquí señala al propio yo.' },
      { t: 'R&B indonesio de los 2020', n: 'Voz susurrada, batería suave, mucho espacio — herencia de NIKI y Pamungkas, pero más adentro del silencio.' },
    ],
    PT: [
      { t: 'Estrela e madrugada', n: 'A astronomia aqui não é grandiosidade, é intimidade — uma estrela que "volta" ao amanhecer, não algo distante e frio.' },
      { t: 'Luz da varanda', n: 'Eco do título do álbum. Na música indonésia essa luz costuma marcar quem espera — aqui marca o próprio eu.' },
      { t: 'R&B indonésio dos anos 2020', n: 'Voz sussurrada, bateria suave, muito espaço — herança de NIKI e Pamungkas, mas mais fundo no silêncio.' },
    ],
    FR: [
      { t: 'Étoile et aube', n: 'L\'astronomie sert ici l\'intimité, pas la grandeur — une étoile qui « rentre » à l\'aube, pas une chose lointaine et froide.' },
      { t: 'Lampe du perron', n: 'Écho du titre de l\'album. Dans la musique indonésienne, cette lampe marque souvent qui attend — ici, elle marque le soi.' },
      { t: 'R&B indonésien des années 2020', n: 'Voix retenue, batterie douce, beaucoup d\'air — héritage de NIKI et Pamungkas, plus profond dans le silence.' },
    ],
    JP: [
      { t: '星と明け方のイメージ', n: '天文を「大きさ」ではなく「親密さ」に使う — 遠く冷たいものではなく、夜明けに「帰る」星として。' },
      { t: 'ポーチの明かり', n: 'アルバムタイトルの反響。インドネシア音楽でこの明かりは「待つ人」を示すことが多い — ここでは「自分自身」を示す。' },
      { t: '2020年代インドネシアR&B', n: '抑えた声、柔らかなドラム、たっぷりの間 — NIKIやPamungkasの系譜の、より静寂寄りのスタイル。' },
    ],
  },
  sections: [
    {
      label: { ID: 'Bait 1', EN: 'Verse 1', ES: 'Verso 1', PT: 'Verso 1', FR: 'Couplet 1', JP: 'バース 1' },
      lines: [
        { t: 'Aku menulis surat ke pagi, tanpa alamat',
          m: {
            ID: 'Menulis ke "pagi" — bukan ke seseorang — pertanda bahwa lagu ini ditujukan kepada waktu, bukan orang. Tanpa alamat: tanpa penerima yang menunggu.',
            EN: 'Writing to "morning" — not a person — signals this song is addressed to time, not to anyone in particular. No address: no recipient waiting.',
            ES: 'Escribir a la "mañana" — no a una persona — indica que la canción se dirige al tiempo, no a nadie en particular. Sin dirección: sin destinatario que espere.',
            PT: 'Escrever para a "manhã" — não para uma pessoa — sinaliza que a canção se dirige ao tempo, não a alguém específico. Sem endereço: sem destinatário esperando.',
            FR: 'Écrire à « le matin » — pas à une personne — montre que la chanson s\'adresse au temps, pas à quelqu\'un en particulier. Sans adresse : sans destinataire qui attende.',
            JP: '「朝」に手紙を書く — 誰かではなく — というのは、この曲が人ではなく時間に宛てて語られていることを示す。宛先なし、つまり待つ人はいない。',
          } },
        { t: 'Cuma bilang aku baik, dan lampu beranda masih nyala',
          m: {
            ID: 'Dua kabar paling sederhana: "aku baik" dan "lampu masih nyala". Bukan kabar besar — kabar yang justru menenangkan karena tidak butuh dramatisasi.',
            EN: 'Two of the smallest possible updates: "I\'m OK" and "the light is still on." Not big news — and that\'s the comfort, no need for drama.',
            ES: 'Dos de las noticias más pequeñas posibles: "estoy bien" y "la luz sigue encendida". No es algo grande — y ahí está el consuelo, sin necesidad de drama.',
            PT: 'Duas das menores notícias possíveis: "estou bem" e "a luz ainda está acesa". Nada grande — e é aí que mora o consolo, sem precisar de drama.',
            FR: 'Deux des plus petites nouvelles possibles : « je vais bien » et « la lampe est encore allumée ». Rien de grand — et c\'est là le réconfort, sans drame.',
            JP: '最も小さな二つの近況：「私は元気」と「明かりはまだついてる」。大ごとではなく、それゆえに安らぐ — 劇は要らない。',
          } },
        { t: 'Bintang yang semalam mengantarku, sekarang giliran ia pulang',
          m: {
            ID: 'Bintang yang menemani lewat malam, kini pulang ke pagi. Citra utama lagu: yang menjaga kita, suatu saat juga butuh pulang. Hubungan yang setara, bukan sepihak.',
            EN: 'The star that walked the narrator through the night now goes home with the dawn. The song\'s central image: what guards us also needs to go home. A relationship that\'s mutual, not one-sided.',
            ES: 'La estrella que acompañó al narrador toda la noche ahora vuelve a casa con el amanecer. La imagen central: lo que nos cuida también necesita volver. Una relación mutua, no unilateral.',
            PT: 'A estrela que acompanhou o narrador na noite agora volta para casa com o amanhecer. A imagem central: quem nos guarda também precisa voltar. Uma relação mútua, não de mão única.',
            FR: 'L\'étoile qui a guidé le narrateur dans la nuit rentre chez elle avec l\'aube. L\'image centrale : ce qui nous protège a aussi besoin de rentrer. Une relation réciproque, pas à sens unique.',
            JP: '夜じゅう語り手を導いた星が、明け方に「家へ帰る」。曲の中心となるイメージ — 守ってくれるものにも、帰る場所がいる。一方通行ではなく、対等な関係。',
          } },
      ],
    },
    {
      label: { ID: 'Pra-chorus', EN: 'Pre-chorus', ES: 'Pre-estribillo', PT: 'Pré-refrão', FR: 'Pré-refrain', JP: 'プリコーラス' },
      lines: [
        { t: 'Pulang itu cuma arah, bukan tempat',
          m: {
            ID: 'Baris paling sering dikutip dari album. Pulang dibebaskan dari geografi — bukan rumah orang tua, bukan kampung halaman, melainkan ke mana hati menghadap.',
            EN: 'The album\'s most-quoted line. "Home" is freed from geography — not a childhood house, not a hometown, but wherever the heart is facing.',
            ES: 'La línea más citada del álbum. "Hogar" se libera de la geografía — no la casa de la infancia ni el pueblo natal, sino hacia donde mira el corazón.',
            PT: 'O verso mais citado do álbum. "Casa" se solta da geografia — não a casa da infância, nem a cidade natal, mas para onde o coração aponta.',
            FR: 'Le vers le plus cité de l\'album. « Rentrer » se détache de la géographie — pas la maison d\'enfance, pas la ville natale, mais là où le cœur se tourne.',
            JP: 'アルバムで最もよく引用される一行。「帰る」が地理から解き放たれる — 実家でも故郷でもなく、心が向いている方向のこと。',
          } },
      ],
    },
    {
      label: { ID: 'Chorus', EN: 'Chorus', ES: 'Estribillo', PT: 'Refrão', FR: 'Refrain', JP: 'コーラス' },
      lines: [
        { t: 'Bintang pulang, dan aku baru ngerti',
          m: {
            ID: 'Pemahaman datang justru di saat sang penjaga pergi. Bukan kehilangan yang menyakitkan — kehilangan yang membukakan mata.',
            EN: 'Understanding lands at the exact moment the guardian leaves. Not a painful loss — a loss that opens the eyes.',
            ES: 'El entendimiento llega justo cuando el guardián se va. No es una pérdida dolorosa — es una pérdida que abre los ojos.',
            PT: 'O entendimento chega exatamente quando o guardião vai embora. Não é uma perda dolorosa — é uma perda que abre os olhos.',
            FR: 'La compréhension arrive au moment exact où le gardien s\'en va. Pas une perte douloureuse — une perte qui ouvre les yeux.',
            JP: '理解は、守ってくれていた者が去る、まさにその瞬間に訪れる。痛みの喪失ではなく、目を開かせる喪失。',
          } },
        { t: 'Rumah itu bukan di luar, rumah itu di sini',
          m: {
            ID: 'Tesis lagu, dinyatakan tanpa drama. "Di sini" — di dalam dada, di dalam diri. Tidak ada lagi tempat untuk dirindukan secara tidak benar.',
            EN: 'The song\'s thesis, stated without drama. "Here" — in the chest, in the self. No more place to long for incorrectly.',
            ES: 'La tesis de la canción, dicha sin drama. "Aquí" — en el pecho, en uno mismo. Ya no hay lugar al que extrañar mal.',
            PT: 'A tese da canção, dita sem drama. "Aqui" — no peito, em si mesmo. Não há mais lugar a sentir falta de modo errado.',
            FR: 'La thèse de la chanson, énoncée sans drame. « Ici » — dans la poitrine, en soi. Plus de lieu qu\'on regrette à tort.',
            JP: '曲のテーゼ — 劇めかさず述べられる。「ここ」 — 胸のなか、自分のなか。もう、まちがった仕方で恋しがる場所はない。',
          } },
        { t: 'Aku menyalakan lampuku sendiri',
          m: {
            ID: 'Setelah lampu beranda di Verse 1, kini lampu yang dinyalakan sendiri. Tanda kepulangan ke diri — bukan menunggu cahaya dari luar lagi.',
            EN: 'After the porch light of Verse 1, now a light the narrator turns on herself. A sign of coming home to the self — no longer waiting for outside light.',
            ES: 'Tras la luz del porche del Verso 1, ahora una luz que la voz enciende ella misma. Señal de volver a sí — ya no espera la luz de afuera.',
            PT: 'Depois da luz da varanda do Verso 1, agora uma luz que a voz acende sozinha. Sinal de voltar a si — não espera mais a luz de fora.',
            FR: 'Après la lampe du perron du Couplet 1, voici une lampe que la narratrice allume elle-même. Signe d\'un retour à soi — plus d\'attente d\'une lumière venue d\'ailleurs.',
            JP: 'バース1のポーチの明かりに対し、ここでは自分で点ける明かり。自分のもとへ帰った合図 — もう外からの光を待たない。',
          } },
      ],
    },
    {
      label: { ID: 'Bridge', EN: 'Bridge', ES: 'Puente', PT: 'Ponte', FR: 'Pont', JP: 'ブリッジ' },
      lines: [
        { t: 'Terima kasih, sudah menjaga sampai ke sini',
          m: {
            ID: 'Bukan perpisahan yang pahit. Pengakuan tulus pada apa pun (orang, kenangan, kepercayaan lama) yang membawanya selamat. Lalu, dilepas dengan rasa terima kasih.',
            EN: 'Not a bitter goodbye. A genuine thanks to whatever (person, memory, old belief) carried her this far. Then released, with gratitude.',
            ES: 'No es una despedida amarga. Un gracias sincero a lo que sea (persona, recuerdo, vieja creencia) que la trajo hasta aquí. Y luego, soltado con gratitud.',
            PT: 'Não é uma despedida amarga. Um agradecimento sincero ao que quer que (pessoa, memória, antiga crença) a trouxe até aqui. Depois, solto com gratidão.',
            FR: 'Pas un adieu amer. Un vrai merci à ce qui (personne, souvenir, vieille croyance) l\'a portée jusqu\'ici. Puis laché, avec gratitude.',
            JP: '苦い別れではない。ここまで運んでくれた何か（人、記憶、古い信念）への、率直な感謝。そして、感謝とともに手放す。',
          } },
      ],
    },
  ],
};

// ============================================================================
// "Telegrama" — Lía Vera (original: Español)
// ============================================================================
SONGS['lia-vera/telegrama-meaning'] = {
  slug: 'lia-vera/telegrama-meaning',
  title: 'Telegrama',
  artist: 'Lía Vera',
  album: 'Cartas de Lejos',
  year: 2024,
  genre: 'Alt latino',
  length: '3:17',
  seed: 6,
  originalLang: 'ES',
  summary: {
    ES: 'Una carta-canción escrita en "clave de no volver". Lía Vera usa el formato anticuado del telegrama — corto, contado por palabras, sin lugar para excusas — para una despedida que se permite ser tierna y firme al mismo tiempo.',
    EN: 'A letter-song written in the "key of not coming back." Lía Vera uses the antique telegram format — short, counted by the word, no room for excuses — for a goodbye that lets itself be tender and firm at the same time.',
    ID: 'Sebuah lagu-surat yang ditulis dalam "kunci tidak kembali". Lía Vera memakai format kuno telegram — pendek, dihitung per kata, tanpa ruang untuk alasan — untuk perpisahan yang membiarkan dirinya lembut dan tegas sekaligus.',
    PT: 'Uma canção-carta escrita na "chave de não voltar". Lía Vera usa o formato antigo do telegrama — curto, contado palavra a palavra, sem espaço para desculpas — para um adeus que se permite ser terno e firme ao mesmo tempo.',
    FR: 'Une chanson-lettre écrite dans la « clé du non-retour ». Lía Vera reprend le format ancien du télégramme — court, compté au mot, sans place pour les excuses — pour un adieu qui s\'autorise à la fois la tendresse et la fermeté.',
    JP: '「戻らないという調」で書かれた手紙のような一曲。Lía Veraは古い電報の形式 — 短く、単語数で課金され、言い訳の余地もない — を使い、優しさと毅然さを同時に許す別れを描く。',
  },
  themes: {
    ES: ['Despedida sin amargura', 'Cartas y formatos antiguos', 'Decisión firme', 'Distancia'],
    EN: ['Goodbye without bitterness', 'Letters and old formats', 'Firm decision', 'Distance'],
    ID: ['Perpisahan tanpa kepahitan', 'Surat dan format kuno', 'Keputusan tegas', 'Jarak'],
    PT: ['Despedida sem amargura', 'Cartas e formatos antigos', 'Decisão firme', 'Distância'],
    FR: ['Adieu sans amertume', 'Lettres et formats anciens', 'Décision ferme', 'Distance'],
    JP: ['苦さのない別れ', '手紙と古い書式', '揺るがない決意', '距離'],
  },
  mood: {
    ES: ['Sereno', 'Tierno', 'Decidido'],
    EN: ['Serene', 'Tender', 'Decided'],
    ID: ['Tenang', 'Lembut', 'Mantap'],
    PT: ['Sereno', 'Terno', 'Decidido'],
    FR: ['Serein', 'Tendre', 'Décidé'],
    JP: ['静謐', '優しい', '決然と'],
  },
  references: {
    ES: [
      { t: 'Telegrama como forma', n: 'El telegrama desaparece en los 2000s. Usarlo en 2024 como cuadro lírico es decir: hay cosas que se merecen un canal lento y caro.' },
      { t: '"Clave de" — música y código', n: 'La frase juega entre "clave musical" y "clave para descifrar". La canción se lee como ambas cosas a la vez.' },
      { t: 'Alt-latino contemporáneo', n: 'Comparte aire con Silvana Estrada y Mon Laferte: voz expuesta, arreglos mínimos, tradición epistolar reescrita.' },
    ],
    EN: [
      { t: 'Telegram as form', n: 'The telegram vanishes in the 2000s. Using it in 2024 as a lyrical frame is saying: some things deserve a slow, expensive channel.' },
      { t: '"Key of" — music and code', n: 'The phrase plays between "musical key" and "key to decode." The song reads as both at once.' },
      { t: 'Contemporary alt-latino', n: 'Shares air with Silvana Estrada and Mon Laferte: exposed voice, minimal arrangement, epistolary tradition rewritten.' },
    ],
    ID: [
      { t: 'Telegram sebagai bentuk', n: 'Telegram hilang di tahun 2000-an. Memakainya pada 2024 sebagai bingkai lirik berarti: ada hal yang layak dikirim lewat saluran yang lambat dan mahal.' },
      { t: '"Clave" — musik & sandi', n: 'Frasa bermain antara "nada dasar musik" dan "kunci untuk memecahkan". Lagu ini bisa dibaca sebagai keduanya sekaligus.' },
      { t: 'Alt-latino kontemporer', n: 'Berbagi udara dengan Silvana Estrada dan Mon Laferte: vokal terbuka, aransemen minim, tradisi surat-menyurat ditulis ulang.' },
    ],
    PT: [
      { t: 'Telegrama como forma', n: 'O telegrama some nos anos 2000. Usá-lo em 2024 como moldura lírica é dizer: há coisas que merecem um canal lento e caro.' },
      { t: '"Clave" — música e código', n: 'A frase brinca entre "clave musical" e "chave para decifrar". A canção se lê como as duas coisas ao mesmo tempo.' },
      { t: 'Alt-latino contemporâneo', n: 'Divide o ar com Silvana Estrada e Mon Laferte: voz exposta, arranjo mínimo, tradição epistolar reescrita.' },
    ],
    FR: [
      { t: 'Télégramme comme forme', n: 'Le télégramme disparaît dans les années 2000. L\'utiliser en 2024 comme cadre poétique, c\'est dire : il y a des choses qui méritent un canal lent et coûteux.' },
      { t: '« Clé de » — musique et code', n: 'La formule joue entre « clé musicale » et « clé pour décoder ». La chanson se lit comme les deux à la fois.' },
      { t: 'Alt-latino contemporain', n: 'Partage l\'air avec Silvana Estrada et Mon Laferte : voix exposée, arrangement minimal, tradition épistolaire réécrite.' },
    ],
    JP: [
      { t: '形式としての電報', n: '電報は2000年代に消える。2024年にこれを叙情の枠として使うのは、「あるものごとは、遅くて高い回線にこそふさわしい」と言うこと。' },
      { t: '「Clave」— 音楽と暗号', n: '言葉は「音楽の調」と「解読のための鍵」のあいだで揺れる。この曲はその両方として読める。' },
      { t: '現代オルタ・ラティーノ', n: 'Silvana EstradaやMon Laferteと同じ空気 — むき出しの声、最小限の編成、書簡の伝統の再執筆。' },
    ],
  },
  sections: [
    {
      label: { ES: 'Verso 1', EN: 'Verse 1', ID: 'Bait 1', PT: 'Verso 1', FR: 'Couplet 1', JP: 'バース 1' },
      lines: [
        { t: 'Te escribo en clave de no volver',
          m: {
            ES: 'Verso de apertura y tesis del álbum. "Clave" funciona como tonalidad musical y como código secreto — la canción te avisa, desde la primera línea, que no es una vuelta.',
            EN: 'The opening line and the album\'s thesis. "Key" works both as a musical tonality and as a secret code — the song warns you, from line one, that this isn\'t a return.',
            ID: 'Baris pembuka dan tesis album. "Clave" berfungsi sekaligus sebagai nada dasar musik dan sandi rahasia — lagu memberi tahu sejak baris pertama bahwa ini bukan kepulangan.',
            PT: 'Verso de abertura e tese do álbum. "Clave" funciona como tonalidade musical e como código secreto — a canção te avisa, desde a primeira linha, que isso não é volta.',
            FR: 'Vers d\'ouverture et thèse de l\'album. « Clave » fonctionne à la fois comme tonalité musicale et comme code secret — la chanson prévient, dès la première ligne, que ce n\'est pas un retour.',
            JP: '冒頭の一行であり、アルバムのテーゼ。「Clave」は音楽の調であり同時に暗号でもある — 一行目から、これは戻る話ではないと告げる。',
          } },
        { t: 'Veinte palabras, ni una de más',
          m: {
            ES: 'Restricción autoimpuesta: la longitud del telegrama. Decir todo en veinte palabras es elegir la disciplina sobre el desahogo.',
            EN: 'A self-imposed restriction: the telegram\'s length. Saying everything in twenty words is choosing discipline over catharsis.',
            ID: 'Batasan yang dipilih sendiri: panjang telegram. Mengatakan semuanya dalam dua puluh kata berarti memilih disiplin alih-alih curahan.',
            PT: 'Uma restrição auto-imposta: o tamanho do telegrama. Dizer tudo em vinte palavras é escolher disciplina em vez de desabafo.',
            FR: 'Une contrainte auto-imposée : la longueur du télégramme. Tout dire en vingt mots, c\'est choisir la discipline plutôt que l\'épanchement.',
            JP: '自ら課した制約 — 電報の文字数。すべてを二十語で言うのは、感情の吐露ではなく規律を選ぶこと。',
          } },
        { t: 'Llevo la pluma sin temblor',
          m: {
            ES: 'La firmeza está en el cuerpo, no en la voz. Sin temblor = la decisión ya fue tomada. La carta solo la transcribe.',
            EN: 'Firmness lives in the body, not the voice. No tremor = the decision was already made. The letter is only transcribing it.',
            ID: 'Ketegaran tinggal di tubuh, bukan di suara. Tanpa gemetar = keputusan sudah diambil. Surat ini hanya menuliskannya.',
            PT: 'A firmeza mora no corpo, não na voz. Sem tremor = a decisão já foi tomada. A carta só transcreve.',
            FR: 'La fermeté habite le corps, pas la voix. Sans tremblement = la décision est déjà prise. La lettre ne fait que la transcrire.',
            JP: '毅然さは声ではなく身体に宿る。震えがない＝決断はすでに下されている。手紙はそれを書き写すだけ。',
          } },
      ],
    },
    {
      label: { ES: 'Estribillo', EN: 'Chorus', ID: 'Chorus', PT: 'Refrão', FR: 'Refrain', JP: 'コーラス' },
      lines: [
        { t: 'Stop. Te quise. Stop.',
          m: {
            ES: 'El "stop" del telegrama, usado como puntuación lírica. "Te quise" — pasado — sin espacio para enmendar el tiempo verbal. Dos palabras dicen lo que párrafos no podrían.',
            EN: 'The telegram\'s "stop," used as lyrical punctuation. "Te quise" — past tense — with no room to amend the verb. Two words say what paragraphs couldn\'t.',
            ID: '"Stop" dari telegram, dipakai sebagai tanda baca lirik. "Te quise" — bentuk lampau — tanpa ruang mengubah waktu. Dua kata mengatakan apa yang paragraf tak akan bisa.',
            PT: 'O "stop" do telegrama, usado como pontuação lírica. "Te quise" — passado — sem espaço para mudar o tempo verbal. Duas palavras dizem o que parágrafos não conseguiriam.',
            FR: 'Le « stop » du télégramme, en guise de ponctuation. « Te quise » — passé — sans espace pour changer le temps. Deux mots disent ce que des paragraphes ne pourraient pas.',
            JP: '電報の「STOP」が抒情の句読点として使われる。「Te quise」 — 過去形 — 時制を直す余地はない。二語が、段落でも言えないことを言う。',
          } },
        { t: 'No vuelvo. Stop. Cuídate. Stop.',
          m: {
            ES: 'El balance del estribillo: declaración firme + deseo tierno. La canción demuestra que las dos cosas caben en el mismo telegrama.',
            EN: 'The balance of the chorus: a firm declaration + a tender wish. The song proves both fit inside one telegram.',
            ID: 'Keseimbangan chorus: pernyataan tegas + harapan lembut. Lagu membuktikan bahwa keduanya muat dalam satu telegram.',
            PT: 'O equilíbrio do refrão: declaração firme + desejo terno. A canção prova que os dois cabem num só telegrama.',
            FR: 'L\'équilibre du refrain : déclaration ferme + souhait tendre. La chanson prouve que les deux tiennent dans un même télégramme.',
            JP: 'コーラスの均衡 — 毅然とした宣言と、やさしい願い。両方が一つの電報に収まることを、曲は証明する。',
          } },
        { t: 'Quedan diez palabras y dos las uso para reírme',
          m: {
            ES: 'El espacio que sobra se usa para reírse, no para suplicar. Acto de ternura más radical de la canción: el humor como forma de respeto.',
            EN: 'The leftover space gets used for laughter, not pleading. The song\'s most radical act of tenderness: humor as a form of respect.',
            ID: 'Sisa ruang dipakai untuk tertawa, bukan memohon. Tindakan kelembutan paling radikal dalam lagu: humor sebagai bentuk penghormatan.',
            PT: 'O espaço que sobra é usado para rir, não para implorar. O ato de ternura mais radical da canção: o humor como forma de respeito.',
            FR: 'L\'espace qui reste sert à rire, pas à supplier. L\'acte de tendresse le plus radical de la chanson : l\'humour comme forme de respect.',
            JP: '残ったスペースを、嘆願ではなく笑いに使う。曲のいちばん根源的なやさしさの所作 — 敬意としてのユーモア。',
          } },
      ],
    },
    {
      label: { ES: 'Verso 2', EN: 'Verse 2', ID: 'Bait 2', PT: 'Verso 2', FR: 'Couplet 2', JP: 'バース 2' },
      lines: [
        { t: 'La oficina huele a café y a otro siglo',
          m: {
            ES: 'Detalle escenográfico: la oficina de telegramas, en sí ya anacrónica. El olor a otro siglo dice que la decisión también pertenece a un tiempo más lento.',
            EN: 'A scenographic detail: the telegram office, already anachronistic. The smell of another century says the decision also belongs to a slower time.',
            ID: 'Detail panggung: kantor telegram, yang sudah ketinggalan zaman. Aroma abad lain mengatakan bahwa keputusannya pun milik waktu yang lebih lambat.',
            PT: 'Um detalhe cênico: a agência de telegramas, já anacrônica. O cheiro de outro século diz que a decisão também pertence a um tempo mais lento.',
            FR: 'Un détail scénique : le bureau du télégramme, déjà anachronique. L\'odeur d\'un autre siècle dit que la décision appartient elle aussi à un temps plus lent.',
            JP: '舞台装置としての一句 — 電報局そのものがもう時代遅れ。別の世紀の匂いは、決断もまた、もっとゆっくりした時間に属していることを言う。',
          } },
        { t: 'El empleado me sonríe sin preguntar a quién',
          m: {
            ES: 'El empleado entiende sin pedir nombres. La discreción reemplaza al duelo público. Pequeña dignidad de los formatos viejos.',
            EN: 'The clerk understands without asking names. Discretion replaces public mourning. The small dignity of old formats.',
            ID: 'Petugas mengerti tanpa menanyakan nama. Kebijaksanaan menggantikan duka di muka umum. Sebuah martabat kecil dari format lama.',
            PT: 'O funcionário entende sem perguntar nomes. A discrição substitui o luto público. A pequena dignidade dos formatos antigos.',
            FR: 'L\'employé comprend sans demander de noms. La discrétion remplace le deuil public. La petite dignité des formats anciens.',
            JP: '係員は名前を聞かずに理解する。配慮が、人前の悲しみに取って代わる — 古い書式が持つ、ささやかな品位。',
          } },
      ],
    },
    {
      label: { ES: 'Coda', EN: 'Coda', ID: 'Koda', PT: 'Coda', FR: 'Coda', JP: 'コーダ' },
      lines: [
        { t: 'Si lo recibes, no contestes. Stop.',
          m: {
            ES: 'La instrucción final invierte el contrato del telegrama, que tradicionalmente pedía respuesta. Esta vez la respuesta sería un retroceso. El silencio es la única respuesta correcta.',
            EN: 'The final instruction inverts the telegram\'s contract, which traditionally asked for a reply. This time a reply would be a step back. Silence is the only correct response.',
            ID: 'Petunjuk terakhir membalik kontrak telegram, yang biasanya meminta jawaban. Kali ini jawaban berarti mundur. Diam adalah satu-satunya jawaban yang benar.',
            PT: 'A instrução final inverte o contrato do telegrama, que tradicionalmente pedia resposta. Desta vez, responder seria recuar. O silêncio é a única resposta correta.',
            FR: 'L\'instruction finale inverse le contrat du télégramme, qui demandait traditionnellement une réponse. Cette fois, répondre serait un retour en arrière. Le silence est la seule bonne réponse.',
            JP: '最後の指示は、本来「返信を求める」という電報の契約を反転させる。今回は、返信が後退を意味する。沈黙だけが、正しい応答。',
          } },
      ],
    },
  ],
};

// ============================================================================
// "月光便箋" (Tsukikō Binsen / Moonlight Stationery) — Niko Asano (original: 日本語)
// ============================================================================
SONGS['niko-asano/tsukiko-binsen-meaning'] = {
  slug: 'niko-asano/tsukiko-binsen-meaning',
  title: '月光便箋',
  artist: 'Niko Asano',
  album: '夜更けの郵便',
  year: 2024,
  genre: 'City pop revival',
  length: '4:12',
  seed: 7,
  originalLang: 'JP',
  summary: {
    JP: '深夜に書きはじめ、朝には読み返せなくなる種類の手紙についての一曲。Niko Asanoは「月光便箋」 — 月明かりだけで書く便箋 — を比喩に、書いたこと自体が癒しで、相手に届かなくてよい言葉を描く。',
    EN: 'A song about the kind of letter you start at midnight and can no longer read in the morning. Niko Asano uses "moonlight stationery" — paper written by moonlight alone — as a metaphor for words whose healing is the writing itself, not the arrival.',
    ID: 'Sebuah lagu tentang surat yang ditulis tengah malam dan tak bisa dibaca lagi di pagi hari. Niko Asano memakai "kertas surat sinar bulan" sebagai perumpamaan bagi kata-kata yang penyembuhannya ada pada penulisannya sendiri, bukan pada sampainya.',
    ES: 'Una canción sobre el tipo de carta que empiezas a medianoche y ya no puedes leer por la mañana. Niko Asano usa el "papel de luna" — escrito solo a la luz lunar — como metáfora de palabras cuya cura está en el acto de escribirlas, no en su llegada.',
    PT: 'Uma canção sobre o tipo de carta que se começa à meia-noite e já não se consegue reler de manhã. Niko Asano usa o "papel de luar" como metáfora de palavras cuja cura está no ato de escrevê-las, não na chegada.',
    FR: 'Une chanson sur ce type de lettre qu\'on commence à minuit et qu\'on ne peut plus relire le matin. Niko Asano se sert du « papier à la lune » comme métaphore : la guérison est dans l\'écriture, pas dans l\'arrivée.',
  },
  themes: {
    JP: ['夜更け', '届かない手紙', '月', 'シティポップ・リバイバル', '一人で書くこと'],
    EN: ['Late night', 'Letters that won\'t arrive', 'The moon', 'City pop revival', 'Writing alone'],
    ID: ['Larut malam', 'Surat yang tak sampai', 'Bulan', 'Kebangkitan city pop', 'Menulis sendirian'],
    ES: ['Madrugada', 'Cartas que no llegan', 'La luna', 'Renacimiento del city pop', 'Escribir a solas'],
    PT: ['Madrugada', 'Cartas que não chegam', 'A lua', 'Renascimento do city pop', 'Escrever sozinho'],
    FR: ['Tard dans la nuit', 'Lettres qui n\'arrivent pas', 'La lune', 'Renaissance du city pop', 'Écrire seul'],
  },
  mood: {
    JP: ['しっとり', '静かな決意', 'やさしい'],
    EN: ['Tender', 'Quietly resolved', 'Gentle'],
    ID: ['Sayu', 'Tenang penuh keputusan', 'Lembut'],
    ES: ['Tierno', 'Decidido en voz baja', 'Suave'],
    PT: ['Terno', 'Decidido em voz baixa', 'Suave'],
    FR: ['Tendre', 'Calmement décidé', 'Doux'],
  },
  references: {
    JP: [
      { t: '月光便箋という造語', n: '実在の文具ではない。月明かりだけで書ける（＝朝の光では読めない）紙を想像することで、夜にしか正しく書けない手紙を物質化する。' },
      { t: 'シティポップ・リバイバル', n: '亜咲花や三浦透子と同じ呼吸。山下達郎・大貫妙子の系譜のリバーブと、現代的なベースが同居する。' },
      { t: '届かない手紙の系譜', n: '中島みゆきから松任谷由実まで連なる「書いたが投函しない手紙」の歌の系譜。Niko Asanoはそこに「書くこと自体が癒し」という現代的な解釈を加える。' },
    ],
    EN: [
      { t: 'The coined word 月光便箋', n: 'No such stationery exists. Imagining paper that can be written only by moonlight (and not read by morning light) materializes the kind of letter that can only be properly written at night.' },
      { t: 'City pop revival', n: 'Breathes the same air as Akasaki Hana and Toko Miura. The reverb lineage of Yamashita Tatsuro and Onuki Taeko, with modern bass.' },
      { t: 'The undelivered-letter lineage', n: 'Songs about letters written but never mailed run from Miyuki Nakajima to Yumi Matsutoya. Niko Asano adds the modern reading: writing itself is the healing.' },
    ],
    ID: [
      { t: 'Istilah ciptaan 月光便箋', n: 'Tidak ada alat tulis seperti itu. Membayangkan kertas yang hanya bisa ditulis dengan cahaya bulan (dan tak bisa dibaca dalam terang pagi) memberi wujud pada surat yang hanya bisa ditulis dengan benar di malam hari.' },
      { t: 'Kebangkitan city pop', n: 'Bernapas seperti Akasaki Hana dan Toko Miura. Reverb dari garis keturunan Yamashita Tatsuro & Onuki Taeko, dengan bass modern.' },
      { t: 'Tradisi surat yang tak terkirim', n: 'Tradisi panjang dari Miyuki Nakajima hingga Yumi Matsutoya tentang surat yang ditulis tapi tak pernah dikirim. Niko Asano menambahkan tafsir modern: menulisnya sendiri adalah penyembuhannya.' },
    ],
    ES: [
      { t: 'El neologismo 月光便箋', n: 'No existe ese papel. Imaginar uno que solo se pueda escribir con luz de luna (y no leer con la del día) materializa la carta que solo se puede escribir bien de noche.' },
      { t: 'Renacimiento del city pop', n: 'Respira el mismo aire que Akasaki Hana y Toko Miura. El reverb del linaje Yamashita Tatsuro y Onuki Taeko, con un bajo moderno.' },
      { t: 'Linaje de la carta no enviada', n: 'De Miyuki Nakajima a Yumi Matsutoya, una larga tradición de cartas escritas y no enviadas. Niko Asano añade la lectura moderna: la escritura misma es la cura.' },
    ],
    PT: [
      { t: 'O neologismo 月光便箋', n: 'Não existe esse papel. Imaginar um que só se possa escrever ao luar (e não ler à luz do dia) materializa a carta que só se escreve bem à noite.' },
      { t: 'Renascimento do city pop', n: 'Respira o mesmo ar de Akasaki Hana e Toko Miura. O reverb do linhagem Yamashita Tatsuro/Onuki Taeko, com baixo moderno.' },
      { t: 'Linhagem da carta não enviada', n: 'De Miyuki Nakajima a Yumi Matsutoya, há uma longa tradição de cartas escritas e nunca enviadas. Niko Asano acrescenta a leitura moderna: escrever, por si só, já é cura.' },
    ],
    FR: [
      { t: 'Le néologisme 月光便箋', n: 'Ce papier n\'existe pas. Imaginer un papier qu\'on ne peut écrire qu\'au clair de lune (et qu\'on ne pourra plus lire à la lumière du matin) matérialise la lettre qui ne s\'écrit bien que la nuit.' },
      { t: 'Renaissance city pop', n: 'Même air qu\'Akasaki Hana et Toko Miura. La réverbération de la lignée Yamashita Tatsuro / Onuki Taeko, avec une basse moderne.' },
      { t: 'Lignée de la lettre non envoyée', n: 'De Miyuki Nakajima à Yumi Matsutoya, longue tradition des lettres écrites jamais postées. Niko Asano y ajoute la lecture moderne : écrire, en soi, est déjà la guérison.' },
    ],
  },
  sections: [
    {
      label: { JP: 'バース 1', EN: 'Verse 1', ID: 'Bait 1', ES: 'Verso 1', PT: 'Verso 1', FR: 'Couplet 1' },
      lines: [
        { t: '月の光だけで書ける紙を、私はずっと探してた',
          m: {
            JP: '物語を一挙に立ち上げる開幕の一行。実在しないものを「探していた」と言うことで、語り手の長年の願い — 夜だけに通じる言葉 — が一気に立ち上がる。',
            EN: 'An opening line that builds the whole story in one stroke. By saying she\'s been searching for something that doesn\'t exist, the narrator\'s long-standing wish — words that work only at night — rises to the surface instantly.',
            ID: 'Baris pembuka yang mendirikan seluruh cerita dalam satu sentuhan. Dengan mengatakan ia mencari sesuatu yang tidak ada, kerinduan lama sang narator — kata-kata yang hanya berfungsi di malam hari — langsung muncul ke permukaan.',
            ES: 'Una primera línea que levanta toda la historia de un solo gesto. Decir que ha estado buscando algo que no existe deja a la vista, de inmediato, su anhelo de años: palabras que solo sirven de noche.',
            PT: 'Um verso de abertura que ergue a história inteira num só gesto. Ao dizer que vem procurando algo que não existe, o desejo antigo da narradora — palavras que só funcionam à noite — vem à tona de imediato.',
            FR: 'Un vers d\'ouverture qui dresse toute l\'histoire d\'un seul coup. Dire qu\'elle cherchait quelque chose qui n\'existe pas met aussitôt à nu son vœu ancien : des mots qui ne fonctionnent qu\'à la nuit tombée.',
          } },
        { t: '朝には文字が消えてしまうような',
          m: {
            JP: '前行の延長 — 朝に消える文字は「届かなくていい言葉」の物質化。手紙の機能を逆転させる。',
            EN: 'An extension of the line before — letters that vanish by morning materialize the idea of "words that don\'t need to arrive." It inverts the function of a letter.',
            ID: 'Lanjutan baris sebelumnya — huruf yang lenyap di pagi hari memberi wujud pada gagasan "kata-kata yang tak perlu sampai". Membalik fungsi sebuah surat.',
            ES: 'Continuación del verso anterior: letras que desaparecen al amanecer materializan la idea de "palabras que no necesitan llegar". Invierte la función de una carta.',
            PT: 'Continuação do verso anterior: letras que desaparecem ao amanhecer materializam a ideia de "palavras que não precisam chegar". Inverte a função de uma carta.',
            FR: 'Prolongement du vers précédent : des lettres qui s\'effacent au matin matérialisent l\'idée de « mots qui n\'ont pas besoin d\'arriver ». Cela inverse la fonction même d\'une lettre.',
          } },
      ],
    },
    {
      label: { JP: 'プリコーラス', EN: 'Pre-chorus', ID: 'Pra-chorus', ES: 'Pre-estribillo', PT: 'Pré-refrão', FR: 'Pré-refrain' },
      lines: [
        { t: 'あなたに届けるためじゃない、私が書きたかっただけ',
          m: {
            JP: '手紙の前提 — 「届けるため」 — を、やさしく外す。書くこと自体が目的であり、行為であり、癒し。',
            EN: 'Gently removes the basic premise of a letter — that it\'s "to be delivered." The writing itself is the purpose, the act, the healing.',
            ID: 'Dengan lembut menanggalkan dasar paling pokok dari sebuah surat — bahwa ia "dikirim". Menulisnya sendiri adalah tujuannya, tindakannya, sekaligus penyembuhannya.',
            ES: 'Suavemente quita la premisa básica de una carta —que se "entregue"—. Escribir, en sí, es el fin, el acto y la cura.',
            PT: 'Suavemente desfaz a premissa básica de uma carta — que se "entregue". Escrever, em si, é o fim, o ato e a cura.',
            FR: 'Retire en douceur la prémisse de base d\'une lettre — qu\'elle « doive être livrée ». L\'écriture est elle-même le but, l\'acte, la guérison.',
          } },
      ],
    },
    {
      label: { JP: 'コーラス', EN: 'Chorus', ID: 'Chorus', ES: 'Estribillo', PT: 'Refrão', FR: 'Refrain' },
      lines: [
        { t: '月光便箋に、今夜だけの私を残す',
          m: {
            JP: '曲名の回収。「今夜だけの私」は、夜に許された自分 — 朝には少し違う自分になる予定の自分を、紙に置き去りにする身振り。',
            EN: 'The title image lands. "Tonight\'s me" is the self that night permits — a self the narrator will be slightly different from tomorrow, deliberately left on the page.',
            ID: 'Citra judul akhirnya muncul. "Aku malam ini" adalah diri yang diizinkan oleh malam — diri yang esok pagi akan sedikit berbeda, sengaja ditinggalkan di kertas.',
            ES: 'Aterriza la imagen del título. "Mi yo de esta noche" es el yo que la noche permite — un yo del que la narradora será un poco distinta mañana, dejado a propósito sobre el papel.',
            PT: 'A imagem do título pousa. "O meu eu desta noite" é o eu que a noite permite — um eu de que a narradora será um pouco diferente amanhã, deixado de propósito no papel.',
            FR: 'L\'image-titre se pose. « Mon moi de ce soir » est le moi que la nuit autorise — un moi dont la narratrice sera un peu différente demain, laissé volontairement sur la feuille.',
          } },
        { t: '朝が読めない言葉を、夜に手渡したいだけ',
          m: {
            JP: '相手は「夜」 — 受取人は時間。届かないのではなく、最初から夜にだけ宛てている。',
            EN: 'The recipient is "the night" — time itself. The letter doesn\'t fail to arrive; it was addressed to the night from the start.',
            ID: 'Penerima adalah "malam" — yaitu waktu itu sendiri. Suratnya bukan gagal sampai; ia memang ditujukan pada malam sejak awal.',
            ES: 'El destinatario es "la noche" — el tiempo mismo. La carta no fracasa en llegar: estuvo dirigida a la noche desde el principio.',
            PT: 'O destinatário é "a noite" — o próprio tempo. A carta não falha em chegar: foi endereçada à noite desde o início.',
            FR: 'Le destinataire, c\'est « la nuit » — le temps lui-même. La lettre n\'échoue pas à arriver : elle était adressée à la nuit dès le départ.',
          } },
        { t: '誰も読まなくていい、私が書けたなら',
          m: {
            JP: '書けた、という過去形に重みがある。書けたなら — その一行で、書けなかった他の夜たちが影として浮かぶ。',
            EN: 'The past-tense "if I was able to write" carries weight. With that one line, all the other nights when she couldn\'t write rise up as shadow.',
            ID: 'Bentuk lampau "jika aku bisa menulis" memikul beban. Dengan satu baris itu, semua malam lain di mana ia tak bisa menulis terangkat sebagai bayangan.',
            ES: 'El pasado "si pude escribir" carga peso. En esa sola línea aparecen, como sombra, todas las otras noches en que no pudo.',
            PT: 'O passado "se eu consegui escrever" carrega peso. Nessa única linha sobem, como sombra, todas as outras noites em que não conseguiu.',
            FR: 'Le passé « si j\'ai pu écrire » a du poids. En un seul vers se lèvent, comme une ombre, toutes les autres nuits où elle n\'a pas pu.',
          } },
      ],
    },
    {
      label: { JP: 'ブリッジ', EN: 'Bridge', ID: 'Bridge', ES: 'Puente', PT: 'Ponte', FR: 'Pont' },
      lines: [
        { t: '便箋がやがて朝に消えても、私は書いたことを覚えている',
          m: {
            JP: '物理的に残らなくても、書いたという経験は残る。記憶こそが本当の便箋 — 月光便箋の本体は、紙ではなく自分。',
            EN: 'Even if the paper vanishes by morning, the experience of having written stays. Memory is the real stationery — the true 月光便箋 is the self, not the paper.',
            ID: 'Meski kertasnya hilang di pagi hari, pengalaman menulisnya tetap tinggal. Kenangan itulah kertas suratnya yang sebenarnya — 月光便箋 yang sungguh adalah dirinya, bukan kertas.',
            ES: 'Aunque el papel desaparezca con el amanecer, queda la experiencia de haber escrito. La memoria es el verdadero papel — la auténtica 月光便箋 es el yo, no la hoja.',
            PT: 'Mesmo que o papel desapareça ao amanhecer, fica a experiência de ter escrito. A memória é o verdadeiro papel — o verdadeiro 月光便箋 é o eu, não a folha.',
            FR: 'Même si le papier s\'efface au matin, l\'expérience d\'avoir écrit, elle, demeure. La mémoire est le vrai papier — le véritable 月光便箋, c\'est le soi, pas la feuille.',
          } },
      ],
    },
  ],
};

// ============================================================================
// "Halo Driver" — Kestral (original: English)
// ============================================================================
SONGS['kestral/halo-driver-meaning'] = {
  slug: 'kestral/halo-driver-meaning',
  title: 'Halo Driver',
  artist: 'Kestral',
  album: 'Wet Neon',
  year: 2025,
  genre: 'Synthwave',
  length: '4:24',
  seed: 1,
  originalLang: 'EN',
  summary: {
    EN: 'A neon-soaked driving song where the headlights and the rain are arguing the whole way home. Kestral uses the highway as a stage for someone who keeps moving so they don\'t have to land on a feeling.',
    ID: 'Lagu mengemudi dengan suasana neon di mana lampu depan dan hujan bertengkar sepanjang jalan pulang. Kestral memakai jalan tol sebagai panggung untuk seseorang yang terus bergerak agar tidak harus mendarat pada satu perasaan.',
    ES: 'Una canción de manejo bañada en neón donde los faros y la lluvia discuten todo el camino a casa. Kestral usa la autopista como escenario para alguien que sigue moviéndose para no tener que aterrizar en un sentimiento.',
    PT: 'Uma canção de viagem banhada em neon em que os faróis e a chuva discutem o caminho inteiro até em casa. Kestral usa a rodovia como palco para alguém que continua em movimento para não ter que pousar num sentimento.',
    FR: 'Une chanson de conduite baignée de néon où les phares et la pluie se disputent tout le chemin du retour. Kestral utilise l\'autoroute comme scène pour quelqu\'un qui continue d\'avancer pour ne pas avoir à atterrir sur un sentiment.',
    JP: 'ネオンに濡れたドライブの一曲 — ヘッドライトと雨が、家までずっと言い争っている。Kestralは高速道路を舞台に、感情に着地しないために走り続ける人を描く。',
  },
  themes: {
    EN: ['Driving at night', 'Neon & rain', 'Avoidance', 'Synthwave nostalgia'],
    ID: ['Mengemudi di malam hari', 'Neon & hujan', 'Penghindaran', 'Nostalgia synthwave'],
    ES: ['Conducir de noche', 'Neón y lluvia', 'Evitación', 'Nostalgia synthwave'],
    PT: ['Dirigir de noite', 'Neon & chuva', 'Evitação', 'Nostalgia synthwave'],
    FR: ['Conduire la nuit', 'Néon & pluie', 'Évitement', 'Nostalgie synthwave'],
    JP: ['夜のドライブ', 'ネオンと雨', '回避', 'シンセウェイブのノスタルジー'],
  },
  mood: {
    EN: ['Restless', 'Glossy', 'Slightly numb'],
    ID: ['Resah', 'Berkilau', 'Sedikit mati rasa'],
    ES: ['Inquieto', 'Brillante', 'Levemente entumecido'],
    PT: ['Inquieto', 'Brilhante', 'Levemente entorpecido'],
    FR: ['Inquiet', 'Brillant', 'Légèrement engourdi'],
    JP: ['落ち着かない', '艶やか', 'うっすら麻痺'],
  },
  references: {
    EN: [
      { t: 'Synthwave & retro driving', n: 'Kestral works the lineage of Drive (2011), Kavinsky, and The Midnight — the highway as a place where time stops being linear.' },
      { t: 'Rain on neon', n: 'A film-noir hand-me-down image, repurposed by 2020s synthwave for a generation that drives more than it walks.' },
      { t: 'Headlights as argument', n: 'Light as language. The headlights "argue" because the only conversation the narrator can still hold is with the road itself.' },
    ],
    ID: [
      { t: 'Synthwave & mengemudi retro', n: 'Kestral mewarisi garis Drive (2011), Kavinsky, dan The Midnight — jalan tol sebagai tempat di mana waktu berhenti berjalan lurus.' },
      { t: 'Hujan di neon', n: 'Citra warisan film noir, didaur ulang oleh synthwave 2020-an untuk generasi yang lebih banyak menyetir daripada berjalan.' },
      { t: 'Lampu depan sebagai perdebatan', n: 'Cahaya sebagai bahasa. Lampu "berdebat" karena satu-satunya percakapan yang masih bisa dijalani sang narator adalah dengan jalan itu sendiri.' },
    ],
    ES: [
      { t: 'Synthwave y conducción retro', n: 'Kestral hereda el linaje de Drive (2011), Kavinsky y The Midnight — la autopista como lugar donde el tiempo deja de ser lineal.' },
      { t: 'Lluvia sobre neón', n: 'Imagen heredada del cine negro, reciclada por el synthwave de los 2020 para una generación que conduce más de lo que camina.' },
      { t: 'Faros como discusión', n: 'La luz como lenguaje. Los faros "discuten" porque la única conversación que el narrador aún sostiene es con la carretera.' },
    ],
    PT: [
      { t: 'Synthwave & direção retrô', n: 'Kestral herda a linhagem de Drive (2011), Kavinsky e The Midnight — a rodovia como lugar onde o tempo deixa de ser linear.' },
      { t: 'Chuva no neon', n: 'Imagem herdada do noir, reciclada pelo synthwave dos anos 2020 para uma geração que dirige mais do que caminha.' },
      { t: 'Faróis como discussão', n: 'Luz como linguagem. Os faróis "discutem" porque a única conversa que o narrador ainda mantém é com a estrada.' },
    ],
    FR: [
      { t: 'Synthwave et conduite rétro', n: 'Kestral s\'inscrit dans la lignée de Drive (2011), Kavinsky et The Midnight — l\'autoroute comme lieu où le temps cesse d\'être linéaire.' },
      { t: 'Pluie sur le néon', n: 'Image héritée du film noir, recyclée par la synthwave des années 2020 pour une génération qui conduit plus qu\'elle ne marche.' },
      { t: 'Phares comme dispute', n: 'La lumière comme langage. Les phares « se disputent » parce que la seule conversation que le narrateur tient encore, c\'est avec la route.' },
    ],
    JP: [
      { t: 'シンセウェイブとレトロなドライブ', n: 'Kestralは『Drive』（2011）、Kavinsky、The Midnightの系譜 — 高速道路は、時間が直線でなくなる場所として描かれる。' },
      { t: 'ネオンに落ちる雨', n: 'フィルム・ノワール由来のイメージを、2020年代のシンセウェイブが「歩くより運転する世代」のために再利用したもの。' },
      { t: '言い争いとしてのヘッドライト', n: '光が言語。語り手が今もできる唯一の会話は、道そのものとの会話だから、ライトが「言い争う」。' },
    ],
  },
  sections: [
    {
      label: { EN: 'Verse 1', ID: 'Bait 1', ES: 'Verso 1', PT: 'Verso 1', FR: 'Couplet 1', JP: 'バース 1' },
      lines: [
        { t: 'Headlights argue with the rain',
          m: {
            EN: 'The titular line. Two things that should cooperate — light and weather — are at odds. A small image that sets the song\'s whole emotional grammar.',
            ID: 'Baris berjudul. Dua hal yang seharusnya bekerja sama — cahaya dan cuaca — justru berseteru. Citra kecil yang mengatur seluruh tata bahasa emosional lagu ini.',
            ES: 'El verso del título. Dos cosas que deberían cooperar — la luz y el clima — están en pugna. Una imagen pequeña que arma toda la gramática emocional de la canción.',
            PT: 'O verso-título. Duas coisas que deveriam cooperar — luz e clima — estão em conflito. Uma imagem pequena que organiza toda a gramática emocional da canção.',
            FR: 'Le vers-titre. Deux choses qui devraient coopérer — la lumière et le temps qu\'il fait — sont en désaccord. Une petite image qui pose toute la grammaire émotionnelle du morceau.',
            JP: 'タイトルとなる一行。協力すべき二つ — 光と天気 — がかみ合わない。曲全体の感情の文法を、ひとつの小さなイメージで決めてしまう。',
          } },
        { t: 'The exit signs all sound the same',
          m: {
            EN: 'When every choice looks identical, none is a real choice. The narrator is technically free but practically frozen.',
            ID: 'Ketika setiap pilihan terlihat sama, tak ada yang benar-benar pilihan. Sang narator secara teknis bebas tapi praktiknya terjebak.',
            ES: 'Cuando toda salida luce idéntica, ninguna es una elección real. El narrador es libre en teoría, paralizado en la práctica.',
            PT: 'Quando toda saída parece igual, nenhuma é uma escolha real. O narrador é livre em teoria, paralisado na prática.',
            FR: 'Quand toutes les sorties se ressemblent, aucune n\'est vraiment un choix. Le narrateur est libre en théorie, figé en pratique.',
            JP: 'どの出口も同じに見えるとき、どれも本当の選択にならない。語り手は形式上は自由でも、実質的には動けないでいる。',
          } },
      ],
    },
    {
      label: { EN: 'Chorus', ID: 'Chorus', ES: 'Estribillo', PT: 'Refrão', FR: 'Refrain', JP: 'コーラス' },
      lines: [
        { t: 'Drive me past the feeling, halo driver',
          m: {
            EN: '"Halo driver" reframes the steering wheel as a saint. The plea is to be carried past the emotion — to not land on it. Driving as a form of avoidance, named lovingly.',
            ID: '"Halo driver" mengubah setir menjadi sosok suci. Doanya: tolong bawa aku melewati perasaan ini — jangan biarkan aku mendarat di sana. Mengemudi sebagai bentuk penghindaran, disebut dengan kasih.',
            ES: '"Halo driver" reconvierte el volante en un santo. La súplica es que la pasen por encima de la emoción, no aterrizar en ella. Manejar como evasión, llamada con ternura.',
            PT: '"Halo driver" reconverte o volante num santo. O pedido é que o passem por cima da emoção, não pousar nela. Dirigir como evasão, nomeada com ternura.',
            FR: '« Halo driver » transforme le volant en saint. La supplique : portez-moi au-delà de l\'émotion, ne me laissez pas atterrir dessus. Conduire comme évitement, nommé avec tendresse.',
            JP: '「Halo driver」 — ハンドルを聖人に見立てる。お願いは、感情の上を通り過ぎさせて、そこに着地させないで、というもの。回避という運転の名づけを、やさしくおこなう。',
          } },
        { t: 'Spin the city til it blurs',
          m: {
            EN: 'Motion as anesthesia. Speed turns specifics into smears — and that\'s the point, not a side effect.',
            ID: 'Gerakan sebagai obat bius. Kecepatan mengubah hal-hal spesifik jadi noda — dan itulah tujuannya, bukan efek samping.',
            ES: 'El movimiento como anestesia. La velocidad convierte lo específico en mancha — y ese es el objetivo, no un efecto secundario.',
            PT: 'O movimento como anestesia. A velocidade transforma o específico em borrão — e esse é o objetivo, não um efeito colateral.',
            FR: 'Le mouvement comme anesthésie. La vitesse transforme le particulier en flou — et c\'est le but, pas un effet secondaire.',
            JP: '動くこと、つまり麻酔。速度が固有のものを滲ませる — それは副作用ではなく、まさに目的。',
          } },
      ],
    },
    {
      label: { EN: 'Verse 2', ID: 'Bait 2', ES: 'Verso 2', PT: 'Verso 2', FR: 'Couplet 2', JP: 'バース 2' },
      lines: [
        { t: 'Radio runs on borrowed time',
          m: {
            EN: '"Borrowed time" works as a music cue (the song will end) and as a life cue (so will the avoidance). The radio is the song\'s metronome for both.',
            ID: '"Borrowed time" berfungsi sekaligus sebagai isyarat musik (lagu akan berakhir) dan isyarat hidup (penghindaran ini pun akan berakhir). Radio jadi metronom untuk keduanya.',
            ES: '"Borrowed time" funciona como pista musical (la canción terminará) y como pista vital (la evasión también). La radio es el metrónomo de ambas cosas.',
            PT: '"Borrowed time" funciona como deixa musical (a canção vai acabar) e como deixa de vida (a evasão também). O rádio é o metrônomo de ambas.',
            FR: '« Borrowed time » fonctionne comme indice musical (la chanson va finir) et comme indice de vie (l\'évitement aussi). La radio est le métronome des deux.',
            JP: '「Borrowed time」は音楽の合図（曲はやがて終わる）でもあり、人生の合図（回避もやがて終わる）でもある。ラジオがその両方のメトロノーム。',
          } },
        { t: 'Every chorus brings me close enough to mine',
          m: {
            EN: 'Other people\'s songs almost — but not quite — surface his own. Pop music as a near-miss with feeling.',
            ID: 'Lagu orang lain hampir — tapi tidak benar-benar — memunculkan perasaannya sendiri. Musik pop sebagai nyaris-bertemu dengan perasaan.',
            ES: 'Las canciones de otros casi —pero no del todo— sacan a flote las suyas. La música pop como un casi-encuentro con el sentir.',
            PT: 'As canções dos outros quase — mas não de todo — trazem à tona as dele. A música pop como um quase-encontro com o sentir.',
            FR: 'Les chansons des autres font presque — mais pas tout à fait — remonter les siennes. La pop comme une rencontre manquée avec le sentiment.',
            JP: '他人の曲が、自分のものをぎりぎり — でも、ぎりぎりまでで止まる — 浮かべる。ポップ・ミュージックは、感情との「もう少し」の出会い。',
          } },
      ],
    },
  ],
};

// Default song used when slug doesn't match
const DEFAULT_SLUG = 'vela-maren/cassette-light-meaning';

// Lookup a song by slug, fall back to default
function getSong(slug) {
  return SONGS[slug] || SONGS[DEFAULT_SLUG];
}

// Helper: resolve a localized field, falling back to EN
function loc(field, lang) {
  if (field == null) return '';
  if (typeof field === 'string') return field;
  return field[lang] || field.EN || '';
}

// ---- Inline meaning popover/aside ----
function MeaningAside({ active, song, lang, depth, setDepth }) {
  if (!active) {
    return (
      <div className="rounded-2xl border border-dashed border-ink-700 bg-ink-850/40 p-6 md:p-7 sticky top-24">
        <div className="flex items-center justify-between gap-2">
          <div className="flex items-center gap-2 text-[11px] font-mono uppercase tracking-[0.22em] text-ink-400">
            <Icon.Sparkle className="w-3.5 h-3.5"/> {window.t('songPage.meaningPanel', lang)}
          </div>
          <DepthToggle value={depth} onChange={setDepth} size="sm"/>
        </div>
        <p className="mt-4 font-display text-lg text-ink-200 leading-snug">
          {window.t('common.tapToDecode', lang)}
        </p>
        <p className="mt-3 text-sm text-ink-400 leading-relaxed">
          {window.t('songPage.meaningHint', lang)}
        </p>
        <div className="mt-6 flex items-center gap-2 text-xs text-ink-400">
          <kbd className="font-mono text-[10px] text-ink-300 border border-ink-700 rounded px-1.5 py-0.5">↑</kbd>
          <kbd className="font-mono text-[10px] text-ink-300 border border-ink-700 rounded px-1.5 py-0.5">↓</kbd>
          <span>{window.t('songPage.walkSong', lang)}</span>
        </div>
      </div>
    );
  }
  const { sectionLabel, line } = active;
  const full = line.m[lang] || line.m.EN;
  const firstSentence = (full.match(/^[^.!?。！？]*[.!?。！？]/)?.[0] || full).trim();
  const body = depth === 'quick' ? firstSentence : full;
  return (
    <div className="sticky top-24">
      <div className="rounded-2xl border border-ink-700 bg-ink-850 shadow-soft overflow-hidden">
        <div className="flex items-center justify-between px-5 py-3 border-b border-ink-800 bg-ink-850/60">
          <div className="flex items-center gap-2">
            <span className="inline-flex items-center gap-1.5 text-[10px] font-mono uppercase tracking-[0.22em] text-accent-300">
              <span className="w-1.5 h-1.5 rounded-full bg-accent-500"/>{loc(sectionLabel, lang)}
            </span>
          </div>
          <div className="flex items-center gap-2">
            <DepthToggle value={depth} onChange={setDepth} size="sm"/>
          </div>
        </div>
        <div key={`${loc(sectionLabel, lang)}-${line.t}-${depth}-${lang}`} className="p-5 md:p-7 meaning-enter">
          <div className="flex items-center justify-between gap-2 mb-2">
            <div className="text-[11px] uppercase tracking-wider text-ink-400">{window.t('common.thisLine', lang)}</div>
            <AILabel lang={lang}/>
          </div>
          <blockquote className="font-display text-lg md:text-[22px] leading-snug text-ink-100 border-l-2 border-accent-500/70 pl-4 italic">
            "{line.t}"
          </blockquote>
          <div className="mt-5 text-[11px] uppercase tracking-wider text-accent-300 mb-1.5">{window.t('common.meaning', lang)} · {LANGS.find(l => l.code === lang)?.name}</div>
          <p className="text-[15.5px] leading-relaxed text-ink-200">{body}</p>

          <FeedbackBar id={`${loc(sectionLabel, lang)}-${line.t}-${depth}-${lang}`} lang={lang}/>
        </div>
        <div className="px-5 py-3 border-t border-ink-800 flex items-center justify-between text-[11px] text-ink-400">
          <span className="font-mono">Lyrithm · interpretation v2.4</span>
          <a href="#" className="hover:text-ink-200">{window.t('songPage.whyReading', lang)}</a>
        </div>
      </div>
    </div>
  );
}

// ---- Lyrics block ----
function LyricsBlock({ song, active, setActive, lang }) {
  const sections = song.sections;

  // Keyboard nav within lyrics list
  useEffect(() => {
    const allLines = sections.flatMap((s, si) => s.lines.map((l, li) => ({ s, si, li, line: l })));
    const onKey = (e) => {
      if (!active) return;
      if (e.key !== 'ArrowUp' && e.key !== 'ArrowDown') return;
      const idx = allLines.findIndex(x => x.si === active.si && x.li === active.li);
      if (idx === -1) return;
      e.preventDefault();
      const next = e.key === 'ArrowDown' ? Math.min(idx + 1, allLines.length - 1) : Math.max(idx - 1, 0);
      const n = allLines[next];
      setActive({ si: n.si, li: n.li, sectionLabel: n.s.label, line: n.line });
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [active, sections, setActive]);

  return (
    <div>
      <div className="flex items-center justify-between mb-5">
        <h2 className="font-display text-xl md:text-2xl font-semibold tracking-tight text-ink-100">{window.t('songPage.lyricsMeaning', lang)}</h2>
        <div className="flex items-center gap-3 text-xs text-ink-400">
          <span className="hidden sm:inline">{window.t('songPage.tap', lang)}</span>
          <WaveBars count={4} className="h-3 w-4"/>
        </div>
      </div>
      <div className="rounded-2xl border border-ink-700 bg-ink-850/60 overflow-hidden">
        {sections.map((sec, si) => (
          <div key={si} className={`px-5 md:px-7 py-5 md:py-7 ${si > 0 ? 'border-t border-ink-800' : ''}`}>
            <div className="flex items-center gap-3 mb-3">
              <span className="text-[10px] font-mono uppercase tracking-[0.25em] text-accent-300">{loc(sec.label, lang)}</span>
              <span className="flex-1 h-px bg-ink-800"/>
              <span className="text-[10px] font-mono text-ink-500">{String(si + 1).padStart(2, '0')}</span>
            </div>
            <ol className="space-y-1">
              {sec.lines.map((l, li) => {
                const isActive = active && active.si === si && active.li === li;
                return (
                  <li key={li}>
                    <button
                      onMouseEnter={() => setActive({ si, li, sectionLabel: sec.label, line: l })}
                      onFocus={() => setActive({ si, li, sectionLabel: sec.label, line: l })}
                      onClick={() => setActive({ si, li, sectionLabel: sec.label, line: l })}
                      className={`lyric-line w-full text-left px-2.5 py-2 font-display text-[19px] md:text-[22px] leading-[1.5] text-ink-200 ${isActive ? 'is-active' : ''}`}
                      aria-pressed={isActive ? true : false}
                      aria-label={`Decode line: ${l.t}`}
                    >
                      {l.t}
                    </button>
                  </li>
                );
              })}
            </ol>
          </div>
        ))}
      </div>
    </div>
  );
}

// ---- Song header ----
function SongHeader({ song, lang, depth, setDepth, reading, setReading }) {
  const songCard = { id: song.slug, t: song.title, a: song.artist, seed: song.seed, slug: song.slug };
  const langName = LANGS.find(l => l.code === lang)?.name || 'English';
  const origLangName = LANGS.find(l => l.code === song.originalLang)?.name || 'English';
  const subhead = (window.t('songPage.subhead', lang) || '').replace('{{lang}}', langName);
  // Notice text per locale: "Lyrics stay in {original language} · meaning translates to {user language}"
  const NOTICE_PREFIX = {
    EN: 'Lyrics stay in', ID: 'Lirik tetap dalam', ES: 'La letra se mantiene en', PT: 'Letra permanece em',
    FR: 'Les paroles restent en', JP: '歌詞は原語の', DE: 'Songtext bleibt auf', IT: 'Il testo resta in',
    NL: 'Tekst blijft in', RU: 'Текст остаётся на', ZH: '歌词保留', ZHT: '歌詞保留',
    KO: '가사는', AR: 'تبقى الكلمات بـ', TR: 'Sözler', PL: 'Tekst pozostaje w',
    VI: 'Lời giữ nguyên', TH: 'เนื้อเพลงคงเป็น', HI: 'गीत मूल', MS: 'Lirik kekal dalam', TL: 'Mananatili ang lirika sa',
    SV: 'Texten är på', DA: 'Teksten er på', NO: 'Teksten er på', FI: 'Sanat pysyvät kielellä',
    EL: 'Οι στίχοι παραμένουν στα', HE: 'המילים נשארות ב-', CS: 'Text zůstává v', HU: 'A szöveg marad', RO: 'Versurile rămân în',
    UK: 'Текст лишається мовою', FA: 'متن به زبان', UR: 'بول اصل', BN: 'গানের কথা মূল',
  };
  const noticePrefix = NOTICE_PREFIX[lang] || NOTICE_PREFIX.EN;
  return (
    <header className="relative pt-10 md:pt-16 pb-8 md:pb-10 overflow-hidden">
      <div aria-hidden="true" className="absolute inset-0 -z-0">
        <div className="absolute inset-x-0 top-0 h-[80%] bg-[radial-gradient(ellipse_at_top_left,rgba(124,92,255,0.18),transparent_55%)]"/>
      </div>
      <div className="relative max-w-7xl mx-auto px-5 md:px-8">
        <nav className="text-xs text-ink-400 mb-6 flex items-center gap-2" aria-label="Breadcrumb">
          <a href="#/" className="hover:text-ink-200">{window.t('common.home', lang)}</a>
          <span className="text-ink-600">/</span>
          <a href="#" className="hover:text-ink-200">{song.artist}</a>
          <span className="text-ink-600">/</span>
          <span className="text-ink-300">{song.title} — {window.t('common.breadcrumbMeaning', lang)}</span>
        </nav>
        <div className="flex items-end gap-5 md:gap-7">
          <AlbumCover seed={song.seed} className="w-24 h-24 md:w-40 md:h-40 shrink-0" rounded="rounded-2xl"/>
          <div className="min-w-0">
            <div className="text-[11px] font-mono uppercase tracking-[0.25em] text-accent-300">{window.t('songPage.eyebrow', lang)}</div>
            <h1 className="mt-2 font-display font-semibold tracking-[-0.025em] text-[28px] sm:text-[40px] md:text-[58px] leading-[1.02] text-ink-100 text-balance">
              {song.title} — {song.artist}
              <span className="block text-ink-300 text-base md:text-lg font-sans font-normal tracking-normal mt-2">
                {subhead}
              </span>
            </h1>
            <div className="mt-3 inline-flex items-center gap-2 text-[11px] font-mono uppercase tracking-[0.18em] text-ink-400 bg-ink-800/70 border border-ink-700 rounded-full px-3 py-1">
              <Icon.Globe className="w-3 h-3"/>
              <span>{noticePrefix} <span className="text-ink-100">{origLangName}</span></span>
              {lang !== song.originalLang && (
                <span className="text-ink-500">· {window.t('common.meaning', lang)} → <span className="text-ink-100">{langName}</span></span>
              )}
            </div>
            <ul className="mt-5 flex flex-wrap items-center gap-x-4 gap-y-2 text-xs text-ink-300">
              <li><span className="text-ink-400">Album </span><span className="text-ink-100">{song.album}</span></li>
              <li className="hidden sm:block w-1 h-1 rounded-full bg-ink-600"/>
              <li><span className="text-ink-400">Year </span><span className="text-ink-100">{song.year}</span></li>
              <li className="hidden sm:block w-1 h-1 rounded-full bg-ink-600"/>
              <li><span className="text-ink-400">Genre </span><span className="text-ink-100">{song.genre}</span></li>
              <li className="hidden sm:block w-1 h-1 rounded-full bg-ink-600"/>
              <li><span className="text-ink-400">Length </span><span className="text-ink-100 font-mono">{song.length}</span></li>
            </ul>
          </div>
        </div>

        {/* Action bar */}
        <div className="mt-7 md:mt-9 flex flex-wrap items-center gap-2 md:gap-3">
          <BookmarkButton song={songCard} label lang={lang}/>
          <ReadingModeToggle value={reading} onChange={setReading} lang={lang}/>
          <div className="hidden md:flex items-center gap-2 ml-1">
            <span className="text-[11px] font-mono uppercase tracking-widest text-ink-400">{window.t('common.depth', lang)}</span>
            <DepthToggle value={depth} onChange={setDepth}/>
          </div>
          <button className="ml-auto inline-flex items-center gap-1.5 h-9 px-3.5 rounded-full border border-ink-700 hover:border-ink-600 text-sm text-ink-200" title={window.t('common.share', lang)}>
            <svg viewBox="0 0 24 24" className="w-4 h-4" fill="none"><path d="M14 4h6v6M20 4 10 14M5 8v12h12" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round"/></svg>
            <span className="hidden sm:inline">{window.t('common.share', lang)}</span>
          </button>
        </div>
      </div>
    </header>
  );
}

// ---- Summary card ----
function SummaryCard({ song, lang, setLang }) {
  return (
    <section aria-labelledby="summary-heading" className="max-w-7xl mx-auto px-5 md:px-8 mt-2">
      <div className="rounded-3xl border border-ink-700 bg-gradient-to-br from-ink-850 to-ink-900 overflow-hidden shadow-soft">
        <div className="grid md:grid-cols-[1.4fr_1fr]">
          <div className="p-6 md:p-9">
            <div className="flex items-center gap-3 mb-3">
              <span className="text-[10px] font-mono uppercase tracking-[0.25em] text-accent-300">{window.t('songPage.whatAbout', lang)}</span>
              <AILabel lang={lang}/>
            </div>
            <h2 id="summary-heading" className="font-display text-2xl md:text-[34px] leading-[1.18] font-semibold tracking-tight text-ink-100 text-balance">
              {song.summary[lang] || song.summary.EN}
            </h2>
            <div className="mt-6 flex flex-wrap gap-2">
              {(song.themes[lang] || song.themes.EN).slice(0, 4).map((t, i) => (
                <span key={i} className="inline-flex items-center gap-1.5 text-xs text-ink-200 bg-ink-800 border border-ink-700 rounded-full px-3 py-1.5">
                  <span className="w-1 h-1 rounded-full bg-accent-400"/> {t}
                </span>
              ))}
            </div>
          </div>
          <div className="p-6 md:p-7 border-t md:border-t-0 md:border-l border-ink-800 bg-ink-900/60">
            <div className="text-[11px] font-mono uppercase tracking-[0.22em] text-ink-400 mb-3">{window.t('common.readMeaningIn', lang)}</div>
            <div className="flex flex-wrap gap-2 max-h-44 overflow-y-auto pr-1">
              {LANGS.map(({ code }) => (
                <button
                  key={code}
                  onClick={() => setLang(code)}
                  className={`inline-flex items-center gap-2 h-9 px-3.5 rounded-full border text-sm transition ${lang === code ? 'border-accent-500/70 bg-accent-500/10 text-ink-100' : 'border-ink-700 text-ink-200 hover:border-ink-600'}`}
                  aria-pressed={lang === code}
                >
                  <span className="font-mono text-[11px] text-ink-300">{code}</span>
                  <span>{(LANGS.find(l => l.code === code)?.name || code).split(' ')[0]}</span>
                </button>
              ))}
            </div>
            <div className="mt-6 grid grid-cols-2 gap-2">
              <div className="rounded-xl border border-ink-700 bg-ink-850 px-3.5 py-3">
                <div className="text-[10px] font-mono uppercase tracking-widest text-ink-400">{window.t('common.mood', lang)}</div>
                <div className="mt-1 text-sm text-ink-100">{(song.mood[lang] || song.mood.EN).join(' · ')}</div>
              </div>
              <div className="rounded-xl border border-ink-700 bg-ink-850 px-3.5 py-3">
                <div className="text-[10px] font-mono uppercase tracking-widest text-ink-400">{window.t('songPage.bestRead', lang)}</div>
                <div className="mt-1 text-sm text-ink-100">{window.t('songPage.headphones', lang)}</div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

// ---- Themes & references ----
function ThemesSection({ song, lang }) {
  return (
    <section className="max-w-7xl mx-auto px-5 md:px-8 mt-16 md:mt-24" aria-labelledby="themes-heading">
      <div className="md:flex md:items-end md:justify-between gap-8 mb-8">
        <div className="max-w-xl">
          <div className="text-[11px] font-mono uppercase tracking-[0.22em] text-accent-300">{window.t('songPage.themesEyebrow', lang)}</div>
          <h2 id="themes-heading" className="mt-3 font-display text-2xl md:text-4xl font-semibold tracking-tight text-ink-100">
            {window.t('songPage.themesH2', lang)}
          </h2>
        </div>
      </div>
      <div className="grid md:grid-cols-3 gap-4 md:gap-6">
        <div className="md:col-span-1 rounded-2xl border border-ink-700 bg-ink-850 p-5 md:p-6">
          <div className="text-[10px] font-mono uppercase tracking-widest text-ink-400 mb-3">{window.t('songPage.themesLabel', lang)}</div>
          <ul className="flex flex-wrap gap-2">
            {(song.themes[lang] || song.themes.EN).map((t, i) => (
              <li key={i}><span className="inline-flex items-center gap-1.5 text-sm text-ink-100 bg-ink-800 border border-ink-700 rounded-full px-3 py-1.5">
                <span className="w-1 h-1 rounded-full bg-accent-400"/>{t}
              </span></li>
            ))}
          </ul>
          <div className="mt-6 text-[10px] font-mono uppercase tracking-widest text-ink-400 mb-3">{window.t('songPage.moodLabel', lang)}</div>
          <ul className="flex flex-wrap gap-2">
            {(song.mood[lang] || song.mood.EN).map((m, i) => (
              <li key={i}><span className="text-sm text-ink-100 bg-ink-800 border border-ink-700 rounded-full px-3 py-1.5">{m}</span></li>
            ))}
          </ul>
        </div>
        <div className="md:col-span-2 rounded-2xl border border-ink-700 bg-ink-850 p-5 md:p-7">
          <div className="text-[10px] font-mono uppercase tracking-widest text-ink-400 mb-4">{window.t('songPage.refsLabel', lang)}</div>
          <ul className="divide-y divide-ink-800">
            {(song.references[lang] || song.references.EN).map((r, i) => (
              <li key={i} className="py-4 first:pt-0 last:pb-0">
                <div className="flex items-baseline gap-3">
                  <span className="font-display text-base md:text-lg text-ink-100">{r.t}</span>
                </div>
                <p className="mt-1 text-[14.5px] text-ink-300 leading-relaxed">{r.n}</p>
              </li>
            ))}
          </ul>
        </div>
      </div>
    </section>
  );
}

// ---- Related songs grid ----
function RelatedGrid({ lang, currentSlug }) {
  // Real entries: every song that has a full SONGS dataset entry. Other catalog
  // items are listed below as future placeholders.
  const realEntries = Object.values(SONGS)
    .filter(s => s.slug !== currentSlug)
    .map(s => ({ id: s.slug, t: s.title, a: s.artist, seed: s.seed, slug: s.slug }));
  const placeholders = [
    { id: 'indoor-weather',  t: 'Indoor Weather',      a: 'Vela Maren',     seed: 3, slug: 'vela-maren/indoor-weather-meaning' },
    { id: 'august-letter',   t: 'August Was a Letter', a: 'Vela Maren',     seed: 5, slug: 'vela-maren/august-was-a-letter-meaning' },
    { id: 'hotel-mileage',   t: 'Hotel Mileage',       a: 'June & Olive',   seed: 5, slug: 'june-olive/hotel-mileage-meaning' },
    { id: 'quiet-room',      t: 'Quiet Room',          a: 'The Soft Coast', seed: 7, slug: 'the-soft-coast/quiet-room-meaning' },
  ];
  const related = [...realEntries, ...placeholders].slice(0, 6);
  return (
    <section className="max-w-7xl mx-auto px-5 md:px-8 mt-16 md:mt-24" aria-labelledby="related-heading">
      <div className="md:flex md:items-end md:justify-between gap-8 mb-8">
        <div className="max-w-xl">
          <div className="text-[11px] font-mono uppercase tracking-[0.22em] text-accent-300">{window.t('songPage.relatedEyebrow', lang)}</div>
          <h2 id="related-heading" className="mt-3 font-display text-2xl md:text-4xl font-semibold tracking-tight text-ink-100">
            {window.t('songPage.relatedH2', lang)}
          </h2>
        </div>
        <a href="#/trending" className="hidden md:inline-flex items-center gap-1.5 text-sm text-ink-200 hover:text-ink-100">
          {window.t('songPage.allBy', lang)} Vela Maren <Icon.ArrowRight className="w-4 h-4"/>
        </a>
      </div>
      <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-3 md:gap-5">
        {related.map((s) => (
          <a key={s.id} href={`#/song/${s.slug}`} className="group block rounded-2xl border border-ink-700 bg-ink-850 hover:border-accent-500/40 hover:bg-ink-800/80 transition overflow-hidden">
            <div className="relative aspect-square">
              <AlbumCover seed={s.seed} className="w-full h-full" rounded="rounded-none"/>
              <div className="absolute top-2 right-2">
                <BookmarkButton song={s} size="sm"/>
              </div>
            </div>
            <div className="p-3.5">
              <div className="font-display font-semibold text-ink-100 text-[14px] truncate">{s.t}</div>
              <div className="mt-0.5 text-[11px] text-ink-400 truncate">{s.a}</div>
            </div>
          </a>
        ))}
      </div>
    </section>
  );
}

// ---- Reading mode view ----
function ReadingView({ song, onExit, lang, setLang }) {
  useEffect(() => {
    const onKey = (e) => { if (e.key === 'Escape') onExit(); };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [onExit]);
  const escMsg = (window.t('songPage.pressEsc', lang) || '').split('{{esc}}');
  return (
    <section className="max-w-3xl mx-auto px-5 md:px-8 py-10 md:py-16">
      <div className="flex items-center justify-between gap-3 mb-8 md:mb-12">
        <div className="flex items-center gap-3 min-w-0">
          <AlbumCover seed={song.seed} className="w-12 h-12 shrink-0" rounded="rounded-lg"/>
          <div className="min-w-0">
            <div className="font-display text-lg font-semibold text-ink-100 truncate">{song.title}</div>
            <div className="text-xs text-ink-400 truncate">{song.artist} · {song.album}</div>
          </div>
        </div>
        <button
          onClick={onExit}
          className="inline-flex items-center gap-1.5 h-9 px-3.5 rounded-full border border-ink-700 hover:border-ink-600 text-sm text-ink-200"
        >
          <Icon.Close/> {window.t('common.exitReading', lang)}
        </button>
      </div>

      <div className="text-[11px] font-mono uppercase tracking-[0.25em] text-ink-400 mb-2">{window.t('songPage.readingHeading', lang)}</div>
      <article className="font-display text-[22px] md:text-[26px] leading-[1.7] text-ink-100 [&_p]:mt-7 first:[&_p]:mt-0 tracking-[-0.005em]">
        {song.sections.map((sec, si) => (
          <p key={si} className="whitespace-pre-line">
            {sec.lines.map(l => l.t).join('\n')}
          </p>
        ))}
      </article>

      <div className="mt-12 text-center text-xs text-ink-400">
        {escMsg[0]}<kbd className="font-mono text-[10px] text-ink-300 border border-ink-700 rounded px-1.5 py-0.5">Esc</kbd>{escMsg[1] || ''}
      </div>
    </section>
  );
}

// ---- Song page shell ----
function SongPage({ lang, setLang, slug }) {
  const [active, setActive] = useState(null);
  const [depth, setDepth] = useState('quick');
  const [reading, setReading] = useState(false);

  // Resolve song from slug; reset active line when switching songs
  const song = getSong(slug);
  useEffect(() => { setActive(null); }, [song.slug]);

  if (reading) {
    return (
      <main id="main">
        <ReadingView song={song} onExit={() => setReading(false)} lang={lang} setLang={setLang}/>
      </main>
    );
  }

  return (
    <main id="main">
      <SongHeader song={song} lang={lang} depth={depth} setDepth={setDepth} reading={reading} setReading={setReading}/>
      <SummaryCard song={song} lang={lang} setLang={setLang}/>

      <section className="max-w-7xl mx-auto px-5 md:px-8 mt-12 md:mt-20">
        {/* Mobile depth toggle */}
        <div className="lg:hidden flex items-center justify-between gap-3 mb-5">
          <h2 className="font-display text-xl font-semibold text-ink-100">{window.t('songPage.lyricsMeaning', lang)}</h2>
          <div className="flex items-center gap-2">
            <span className="text-[11px] font-mono uppercase tracking-widest text-ink-400">{window.t('common.depth', lang)}</span>
            <DepthToggle value={depth} onChange={setDepth} size="sm"/>
          </div>
        </div>
        <div className="grid lg:grid-cols-[1.35fr_1fr] gap-6 md:gap-10">
          <LyricsBlock song={song} active={active} setActive={setActive} lang={lang}/>
          <aside>
            <MeaningAside active={active} song={song} lang={lang} depth={depth} setDepth={setDepth}/>
          </aside>
        </div>
      </section>

      <ThemesSection song={song} lang={lang}/>
      <RelatedGrid lang={lang} currentSlug={song.slug}/>
      <QuietAd note="A single, clearly-bounded ad slot lives here — never inside the lyrics, never autoplay."/>
      <div className="h-12"/>
    </main>
  );
}

window.SongPage = SongPage;
window.SONGS = SONGS;
window.getSong = getSong;
