ommp.git

ommp

~ Oh My Music Player — a standalone terminal music player built with Rust and ratatui
git clone https://github.com/debuman/ommp.git

site/templates/landing.html (9119B)

      1 {%- set x = page.extra -%}
      2 {#- A command and a button that copies it. The button is separate so the box
      3     never changes size: the icon swaps, the command does not move. -#}
      4 {%- macro command(label, text) -%}
      5       <div class="install">
      6         <span class="install-label">{{ label }}</span>
      7         <div class="cmdline">
      8           <code class="cmd">{{ text }}</code>
      9           <button class="cmd-copy" type="button" aria-label="Copy {{ text }}" title="Copy">
     10             <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="9" y="9" width="12" height="12" rx="2.5"/><path d="M5 15H4.5A1.5 1.5 0 0 1 3 13.5v-9A1.5 1.5 0 0 1 4.5 3h9A1.5 1.5 0 0 1 15 4.5V5"/></svg>
     11             <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m5 12.5 5 5 9-11"/></svg>
     12           </button>
     13         </div>
     14       </div>
     15 {%- endmacro -%}
     16 <!doctype html>
     17 <html lang="en">
     18 <head>
     19 <meta charset="utf-8">
     20 <meta name="viewport" content="width=device-width, initial-scale=1">
     21 <title>ommp — a terminal music player</title>
     22 <meta name="description" content="{{ page.description }}">
     23 <meta name="color-scheme" content="dark">
     24 <meta name="theme-color" content="#0A051E">
     25 
     26 <meta property="og:type" content="website">
     27 <meta property="og:title" content="{{ site.title }} — Oh My Music Player">
     28 <meta property="og:description" content="{{ page.description }}">
     29 <meta property="og:url" content="{{ page.permalink }}">
     30 <meta property="og:image" content="{{ site.origin }}{{ asset('img/og.png') }}">
     31 <meta name="twitter:card" content="summary_large_image">
     32 
     33 {#- The wordmark is 723x421; at 16px it is a smear. This is the same 'O' block
     34     glyph lifted out of it, squared up, carrying the logo's two colours. It also
     35     sits at the site root so a bare /favicon.ico request resolves. -#}
     36 <link rel="icon" href="{{ asset('favicon.ico') }}" sizes="any">
     37 <link rel="preload" as="font" type="font/woff2" href="{{ asset('fonts/jetbrains-mono-400.woff2') }}" crossorigin>
     38 <link rel="preload" as="font" type="font/woff2" href="{{ asset('fonts/bricolage-grotesque-var.woff2') }}" crossorigin>
     39 <link rel="stylesheet" href="{{ asset('css/main.css') }}">
     40 </head>
     41 <body>
     42 
     43 <a class="skip" href="#art">Skip to content</a>
     44 
     45 <!-- ── Hero ──────────────────────────────────────────────────────────── -->
     46 <header class="hero">
     47   <div class="wrap hero-in">
     48     <img class="hero-logo" src="{{ asset('img/logo.png') }}" alt="ommp" width="723" height="421">
     49 
     50     <p class="kicker">{{ x.kicker }}</p>
     51     <h1 class="display">
     52       {{ x.headline }}<br><em>{{ x.headline2 }}</em>
     53     </h1>
     54     <p class="lede">{{ x.lede }}</p>
     55 
     56     <div class="installs">
     57 {{ command(x.install_primary_label, x.install_primary) }}
     58 {{ command(x.install_secondary_label, x.install_secondary) }}
     59     </div>
     60 
     61     <p class="hero-meta">
     62       Linux · Apache&nbsp;2.0 ·
     63       <a href="https://github.com/debuman/ommp">Source</a> ·
     64       <a href="https://crates.io/crates/ommp">crates.io</a> ·
     65       <a href="https://aur.archlinux.org/packages/ommp">AUR</a>
     66     </p>
     67   </div>
     68 </header>
     69 
     70 <!-- ── 1. The artwork: the first thing you scroll into ────────────────── -->
     71 <section id="art" class="band band-art" data-section="Album art">
     72   <div class="wrap">
     73     <h2 class="sec-title sec-title-lg">{{ x.art_title }}</h2>
     74     <p class="sec-lede sec-lede-lg">{{ x.art_lede }}</p>
     75   </div>
     76 
     77   <figure class="shot shot-hero">
     78     <img src="{{ asset('img/01-main.avif') }}" alt="ommp playing a track: the library on the left, the queue in the middle, and on the right the album cover drawn as a real image above thirteen lines of track detail"
     79          width="3840" height="2160" fetchpriority="high">
     80   </figure>
     81 
     82   <div class="wrap two-up">
     83     <p>{{ x.art_body_1 | safe }}</p>
     84     <p>{{ x.art_body_2 | safe }}</p>
     85   </div>
     86 </section>
     87 
     88 <!-- ── 2. Nothing to start ────────────────────────────────────────────── -->
     89 <section class="band band-alt" data-section="Nothing to start">
     90   <div class="wrap-wide split">
     91     <div class="split-text">
     92       <h2 class="sec-title">{{ x.start_title }}</h2>
     93       <p class="sec-lede">{{ x.start_lede | safe }}</p>
     94       <p class="sec-body">{{ x.start_body }}</p>
     95     </div>
     96 
     97     {#- The setup you do not do, struck through, and under it the one line you
     98         actually type. Presentational, so it is hidden from assistive tech —
     99         the paragraph beside it already says this in words. -#}
    100     <div class="setup" aria-hidden="true">
    101       <ul class="setup-skipped">
    102         {%- for step in x.skipped %}
    103         <li><span>{{ step }}</span></li>
    104         {%- endfor %}
    105       </ul>
    106       <p class="setup-real">ommp</p>
    107     </div>
    108   </div>
    109 </section>
    110 
    111 <!-- ── 3. Browse ──────────────────────────────────────────────────────── -->
    112 <section class="band" data-section="Browse">
    113   <div class="wrap-wide">
    114     <h2 class="sec-title">{{ x.browse_title }}</h2>
    115     <p class="sec-lede">{{ x.browse_lede | safe }}</p>
    116 
    117     {#- The app's own tab bar, set as type in the app's own tab colours. -#}
    118     <ol class="tabstrip">
    119       {%- for t in x.tabs %}
    120       <li style="--accent: {{ t.color }}">{{ t.name }}</li>
    121       {%- endfor %}
    122     </ol>
    123 
    124     <div class="two-up">
    125       <p>{{ x.browse_body_1 }}</p>
    126       <p>{{ x.browse_body_2 | safe }}</p>
    127     </div>
    128 
    129     <figure class="shot shot-wide">
    130       <img src="{{ asset('img/03-search.avif') }}" alt="The search overlay narrowing a library to fifty of its fifty-two tracks as the word yorushika is typed"
    131            width="3840" height="2160" loading="lazy">
    132     </figure>
    133   </div>
    134 </section>
    135 
    136 <!-- ── 4. Nothing lost ────────────────────────────────────────────────── -->
    137 <section class="band band-alt" data-section="Nothing lost">
    138   <div class="wrap">
    139     <h2 class="sec-title">{{ x.lost_title }}</h2>
    140     <p class="sec-lede">{{ x.lost_lede }}</p>
    141 
    142     <ul class="details">
    143       {%- for d in x.details %}
    144       <li style="--accent: {{ d.color }}">{{ d.body | safe }}</li>
    145       {%- endfor %}
    146     </ul>
    147 
    148     <p class="details-close">{{ x.lost_close }}</p>
    149   </div>
    150 </section>
    151 
    152 <!-- ── 5. Keys ────────────────────────────────────────────────────────── -->
    153 <section class="band" data-section="Keys">
    154   <div class="wrap-wide split split-reverse">
    155     <div class="split-text">
    156       <h2 class="sec-title sec-title-mono">{{ x.keys_title }}</h2>
    157       <p class="sec-lede">{{ x.keys_lede }}</p>
    158       <p class="sec-body">{{ x.keys_body_1 | safe }}</p>
    159       <p class="sec-body">{{ x.keys_body_2 | safe }}</p>
    160     </div>
    161     <figure class="shot">
    162       <img src="{{ asset('img/02-help.avif') }}" alt="The keybinding overlay open over the player, two columns covering playback and navigation"
    163            width="3840" height="2160" loading="lazy">
    164     </figure>
    165   </div>
    166 </section>
    167 
    168 <!-- ── 6. Install ─────────────────────────────────────────────────────── -->
    169 <section class="band band-close" data-section="Install">
    170   <div class="wrap">
    171     <h2 class="sec-title">{{ x.install_title }}</h2>
    172 
    173     <div class="installs installs-left">
    174 {{ command(x.install_primary_label, x.install_primary) }}
    175 {{ command(x.install_secondary_label, x.install_secondary) }}
    176     </div>
    177 
    178     <p class="install-close">{{ x.install_close | safe }}</p>
    179   </div>
    180 </section>
    181 
    182 <footer class="foot">
    183   <div class="wrap foot-in">
    184     <p class="foot-name">ommp</p>
    185     <nav class="foot-links">
    186       <a href="https://github.com/debuman/ommp">GitHub</a>
    187       <a href="https://crates.io/crates/ommp">crates.io</a>
    188       <a href="https://aur.archlinux.org/packages/ommp">AUR</a>
    189       <a href="https://github.com/debuman/ommp/blob/main/LICENSE">Apache&nbsp;2.0</a>
    190     </nav>
    191     <p class="foot-fine">{{ x.splash_note }}</p>
    192     <p class="foot-fine">Built with <a href="https://github.com/debuman/sqzass">sqzass</a>. Copyright 2026 debuman (hyukjin an).</p>
    193   </div>
    194 </footer>
    195 
    196 <!-- ── The app's own status bar, tracking the page ───────────────────── -->
    197 <div class="statusbar" aria-hidden="true">
    198   <div class="sb-fill"></div>
    199   <div class="sb-row">
    200     <span class="sb-state">&#9654; Playing</span>
    201     <span class="sb-track">ommp</span>
    202     <span class="sb-time"><span class="sb-elapsed">0:00</span> / 3:57</span>
    203   </div>
    204 </div>
    205 
    206 <script src="{{ asset('js/status.js') }}" defer></script>
    207 </body>
    208 </html>