diff options
Diffstat (limited to 'index.html')
| -rw-r--r-- | index.html | 921 |
1 files changed, 921 insertions, 0 deletions
diff --git a/index.html b/index.html new file mode 100644 index 0000000..da42f99 --- /dev/null +++ b/index.html @@ -0,0 +1,921 @@ +<!doctype html> +<html lang="en"> + <head> + <meta charset="UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <title>Mìng Lìng — Macro magician in your CLI</title> + <link rel="icon" type="image/png" href="docs/res/icon_shadow.png" /> + <link rel="preconnect" href="https://fonts.googleapis.com" /> + <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> + <link + href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;600;700&display=swap" + rel="stylesheet" + /> + <link + rel="stylesheet" + href="docs/scripts/highlight/github-dark.min.css" + /> + <style> + *, + *::before, + *::after { + box-sizing: border-box; + margin: 0; + padding: 0; + } + + html { + scroll-behavior: smooth; + } + + body { + font-family: "Noto Serif SC", Georgia, "Times New Roman", serif; + background-color: #1a1410; + color: #e8ddd0; + line-height: 1.6; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + overflow-x: hidden; + } + + a { + color: #d4a84b; + text-decoration: none; + transition: color 0.2s; + } + a:hover { + color: #e8c46a; + } + + img { + max-width: 100%; + height: auto; + } + + .container { + max-width: 1080px; + margin: 0 auto; + padding: 0 1.5rem; + } + + .section-title { + font-size: 1.75rem; + font-weight: 700; + text-align: center; + margin-bottom: 3rem; + color: #e8ddd0; + } + + .section-title span { + color: #d4a84b; + } + + nav { + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 100; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0.8rem 2rem; + background: rgba(26, 20, 16, 0.88); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + border-bottom: 1px solid rgba(212, 168, 75, 0.12); + } + + nav .logo { + display: flex; + align-items: center; + gap: 0.5rem; + font-weight: 700; + font-size: 1.1rem; + color: #e8ddd0; + } + + nav .logo img { + width: 28px; + height: 28px; + filter: brightness(0) invert(1); + } + + nav .nav-links { + display: flex; + gap: 1.5rem; + align-items: center; + font-size: 0.9rem; + } + + nav .nav-links a { + color: #9a8a7a; + transition: color 0.2s; + } + + nav .nav-links a:hover { + color: #d4a84b; + } + + nav .nav-links .btn-nav { + display: inline-block; + padding: 0.35rem 1rem; + border: 1px solid #d4a84b; + border-radius: 20px; + color: #d4a84b; + font-weight: 600; + font-size: 0.85rem; + transition: + background 0.2s, + color 0.2s; + } + + nav .nav-links .btn-nav:hover { + background: #d4a84b; + color: #1a1410; + } + + .hero { + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + padding: 6rem 1.5rem 4rem; + position: relative; + overflow: hidden; + } + + /* subtle glow behind the title — now a warm golden halo */ + .hero::before { + content: ""; + position: absolute; + top: 20%; + left: 50%; + width: 600px; + height: 600px; + transform: translate(-50%, -50%); + background: radial-gradient( + circle, + rgba(212, 168, 75, 0.07) 0%, + transparent 70% + ); + pointer-events: none; + } + + .hero-content { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + gap: 1.5rem; + max-width: 820px; + position: relative; + z-index: 1; + } + + .hero h1 { + font-size: 5rem; + font-weight: 800; + letter-spacing: 2px; + color: #e8ddd0; + opacity: 0; + animation: fadeInDown 0.8s ease 0.2s forwards; + line-height: 1.2; + } + + .hero .slogan { + font-size: 2.2rem; + color: #c43931; + font-weight: 400; + opacity: 0; + animation: fadeInDown 0.8s ease 0.3s forwards; + min-height: 3rem; + } + + .hero .slogan .cursor { + display: inline-block; + width: 2px; + height: 1.2em; + background: #c43931; + margin-left: 2px; + vertical-align: text-bottom; + animation: blink 0.8s step-end infinite; + } + + @keyframes blink { + 0%, + 100% { + opacity: 1; + } + 50% { + opacity: 0; + } + } + + .hero .desc { + font-size: 1rem; + color: #9a8a7a; + max-width: 560px; + line-height: 1.6; + opacity: 0; + animation: fadeInDown 0.8s ease 0.4s forwards; + } + + .hero .cta-row { + display: flex; + gap: 1rem; + flex-wrap: wrap; + justify-content: center; + margin-top: 1rem; + opacity: 0; + animation: fadeInDown 0.8s ease 0.6s forwards; + } + + .btn-primary { + display: inline-flex; + align-items: center; + gap: 0.4rem; + padding: 0.75rem 2rem; + background: #c43931; + color: #e8ddd0; + font-weight: 700; + font-size: 1rem; + border-radius: 2px; + border: none; + cursor: pointer; + transition: + background 0.25s, + transform 0.15s; + } + .btn-primary:hover { + background: #d44a42; + color: #e8ddd0; + transform: translateY(-2px); + } + + .btn-secondary { + display: inline-flex; + align-items: center; + gap: 0.4rem; + padding: 0.75rem 2rem; + background: transparent; + color: #d4a84b; + font-weight: 600; + font-size: 1rem; + border-radius: 2px; + border: 1px solid #d4a84b; + cursor: pointer; + transition: + background 0.25s, + color 0.25s, + transform 0.15s; + } + .btn-secondary:hover { + background: rgba(212, 168, 75, 0.1); + color: #e8c46a; + transform: translateY(-2px); + } + + @keyframes fadeInDown { + 0% { + opacity: 0; + transform: translateY(20px); + } + 100% { + opacity: 1; + transform: translateY(0); + } + } + + .scroll-indicator { + position: absolute; + bottom: 2rem; + left: 50%; + transform: translateX(-50%); + display: flex; + flex-direction: column; + align-items: center; + gap: 0.3rem; + color: #6a5a4a; + font-size: 0.75rem; + opacity: 0; + animation: fadeInUp 0.8s ease 1s forwards; + } + + @keyframes watermarkIn { + 0% { + opacity: 0; + top: 30%; + } + 100% { + opacity: 0.3; + top: 15%; + } + } + + @keyframes fadeInUp { + 0% { + opacity: 0; + bottom: 0; + } + 100% { + opacity: 1; + bottom: 2rem; + } + } + + .scroll-indicator .arrow { + width: 20px; + height: 20px; + border-right: 2px solid #6a5a4a; + border-bottom: 2px solid #6a5a4a; + transform: rotate(45deg); + animation: bounceArrow 2s ease-in-out infinite; + } + + @keyframes bounceArrow { + 0%, + 100% { + transform: rotate(45deg) translateY(0); + } + 50% { + transform: rotate(45deg) translateY(6px); + } + } + + .code-demo { + padding: 5rem 1.5rem; + background: #241c16; + } + + .code-demo .code-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 3rem; + align-items: center; + } + + .code-demo .code-text h2 { + font-size: 1.75rem; + font-weight: 700; + color: #e8ddd0; + margin-bottom: 1rem; + } + + .code-demo .code-text h2 span { + color: #c43931; + } + + .code-demo .code-text p { + color: #9a8a7a; + font-size: 1rem; + margin-bottom: 1.5rem; + } + + .code-demo .code-text .features-list { + list-style: none; + display: flex; + flex-direction: column; + gap: 0.6rem; + } + + .code-demo .code-text .features-list li { + display: flex; + align-items: flex-start; + gap: 0.6rem; + color: #c0b0a0; + font-size: 0.95rem; + } + + .code-demo .code-text .features-list li::before { + content: "▸"; + color: #d4a84b; + font-weight: 700; + flex-shrink: 0; + } + + .code-block { + background: #241c16; + border: 1px solid #3a2e24; + border-radius: 2px; + padding: 2rem 1.5rem 1.5rem; + overflow-x: auto; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4); + position: relative; + } + + .code-block pre { + margin: 0; + padding: 0; + background: transparent; + } + + .code-block code { + font-family: + "Cascadia Code", "Fira Code", "JetBrains Mono", "Consolas", + monospace; + font-size: 0.85rem; + line-height: 1.65; + background: transparent !important; + padding: 0 !important; + } + + .code-block::before { + content: "▲ example-basic"; + position: absolute; + top: 0.5rem; + right: 1rem; + font-size: 0.7rem; + color: #6a5a4a; + font-family: "Segoe UI", sans-serif; + letter-spacing: 0.5px; + } + + .features { + padding: 5rem 1.5rem; + } + + .features-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 1.5rem; + } + + .feature-card { + background: #241c16; + border: 1px solid #3a2e24; + border-radius: 2px; + padding: 1.75rem 1.5rem; + transition: + border-color 0.25s, + transform 0.2s; + } + + .feature-card:hover { + border-color: #c43931; + transform: translateY(-4px); + } + + .feature-card .icon { + font-size: 1.6rem; + margin-bottom: 0.75rem; + display: block; + } + + .feature-card h3 { + font-size: 1.1rem; + font-weight: 700; + color: #e8ddd0; + margin-bottom: 0.5rem; + } + + .feature-card p { + font-size: 0.9rem; + color: #9a8a7a; + line-height: 1.6; + } + + .feature-card a { + font-size: 0.85rem; + font-weight: 600; + } + + .cta-banner { + padding: 4rem 1.5rem; + text-align: center; + background: linear-gradient( + 135deg, + rgba(212, 168, 75, 0.06), + transparent + ); + border-top: 1px solid rgba(212, 168, 75, 0.1); + border-bottom: 1px solid rgba(212, 168, 75, 0.1); + } + + .cta-banner h2 { + font-size: 1.75rem; + font-weight: 700; + color: #e8ddd0; + margin-bottom: 0.75rem; + } + + .cta-banner p { + color: #9a8a7a; + margin-bottom: 1.5rem; + font-size: 1.05rem; + } + + .cta-banner .cta-row { + display: flex; + gap: 1rem; + justify-content: center; + flex-wrap: wrap; + } + + .cta-banner code { + display: inline-block; + background: #241c16; + padding: 0.4rem 1rem; + border-radius: 8px; + font-size: 0.95rem; + color: #d4a84b; + border: 1px solid #3a2e24; + margin-top: 0.5rem; + } + + footer { + padding: 2rem 1.5rem; + text-align: center; + color: #6a5a4a; + font-size: 0.85rem; + border-top: 1px solid #2a1e14; + } + + footer a { + color: #7a6a5a; + } + + footer a:hover { + color: #d4a84b; + } + + /* ── Ink drop effect ── */ + .ink-drop { + position: fixed; + pointer-events: none; + border-radius: 50%; + background: radial-gradient( + circle, + rgba(212, 168, 75, 0.15) 0%, + rgba(196, 57, 49, 0.06) 50%, + transparent 100% + ); + width: 0; + height: 0; + transform: translate(-50%, -50%); + animation: inkSpread 0.9s ease-out forwards; + z-index: 9999; + } + + @keyframes inkSpread { + 0% { + width: 0; + height: 0; + opacity: 1; + } + 100% { + width: 500px; + height: 500px; + opacity: 0; + } + } + + @media (max-width: 768px) { + nav { + padding: 0.6rem 1rem; + } + + nav .nav-links { + gap: 1rem; + font-size: 0.8rem; + } + + nav .nav-links .btn-nav { + padding: 0.25rem 0.75rem; + font-size: 0.75rem; + } + + .hero h1 { + font-size: 2.2rem; + } + + .hero .slogan { + font-size: 1.4rem; + } + + .hero .desc { + font-size: 0.9rem; + } + + .code-demo .code-grid { + grid-template-columns: 1fr; + gap: 2rem; + } + + .code-block { + font-size: 0.75rem; + padding: 1rem; + } + } + + @media (max-width: 480px) { + .hero h1 { + font-size: 1.8rem; + } + + .hero .cta-row { + flex-direction: column; + align-items: center; + } + + .features-grid { + grid-template-columns: 1fr; + } + } + </style> + </head> + <body> + <!-- Navigation --> + <nav> + <a href="#" class="logo" aria-label="Home"> + <img + src="docs/res/icon.png" + alt="Mingling icon" + width="28" + height="28" + /> + Mìng Lìng + </a> + <div class="nav-links"> + <a href="docs/doc.html">Docs</a> + <a href="docs/examples.html">Examples</a> + <a href="https://github.com/catilgrass/mingling" target="_blank" + >GitHub</a + > + <a + href="https://crates.io/crates/mingling" + target="_blank" + class="btn-nav" + >cargo add mingling</a + > + </div> + </nav> + + <!-- Hero --> + <section class="hero"> + <div class="hero-content"> + <img + src="docs/res/icon.png" + alt="" + style=" + position: absolute; + top: 30%; + left: 50%; + transform: translate(-50%, -50%); + width: 600px; + aspect-ratio: 1 / 1; + height: auto; + opacity: 0; + pointer-events: none; + user-select: none; + z-index: -1; + animation: watermarkIn 2.5s ease-out 2s forwards; + " + /> + + <h1>#[Mìng Lìng]</h1> + <p class="slogan" id="typewriter"></p> + + <p class="desc">A <b>proc-macro based</b> Rust CLI framework</p> + + <div class="cta-row"> + <a href="docs/doc.html" class="btn-primary"> + 📖 Read The Docs + </a> + <a + href="https://github.com/catilgrass/mingling" + target="_blank" + class="btn-secondary" + > + GitHub → + </a> + </div> + </div> + + <div class="scroll-indicator"> + <span>scroll</span> + <div class="arrow"></div> + </div> + </section> + + <!-- Code Demo --> + <section class="code-demo"> + <div class="container code-grid"> + <div class="code-text"> + <h2> + Dispatch, Parse<br /> + Then <span>Render</span> + </h2> + <p> + A proc-macro & type-system CLI framework for + building complex command-line programs with many + subcommands. + </p> + <ul class="features-list"> + <li> + Separation of concerns: parsing, logic, rendering + </li> + <li> + Compile-time prefix-tree routing + <a + href="docs/example-viewer.html?name=example-dispatch-tree" + >(optional)</a + > + </li> + <li> + Dynamic shell completion out of the box + <a + href="docs/example-viewer.html?name=example-completion" + >(optional)</a + > + </li> + </ul> + </div> + + <div class="code-block"> + <pre><code class="language-rust"> +use mingling::prelude::*; + +dispatcher!("greet", CMDGreet => EntryGreet); + +fn main() { + let mut program = ThisProgram::new(); + program.with_dispatcher(CMDGreet); + program.exec_and_exit(); +} + +pack!(ResultGreeting = String); + +#[chain] +fn handle_greet(args: EntryGreet) -> Next { + let name = + args.pick_or((), "World").unpack(); + ResultGreeting::new(name) +} + +#[renderer] +fn render_greeting(greeting: ResultGreeting) { + r_println!("Hello, {}!", *greeting); +} + +gen_program!(); + </code></pre> + </div> + </div> + </section> + + <!-- Features --> + <section class="features"> + <div class="container"> + <h2 class="section-title"> + <span>Mìng Lìng</span> — Build Complex CLIs, For You! + </h2> + + <div class="features-grid"> + <div class="feature-card"> + <span class="icon">🧩</span> + <h3>Separation of Concerns</h3> + <p> + Decouple parsing, business logic, rendering, help + text, and completion — each is just a function with + the right attribute macro. + </p> + </div> + + <div class="feature-card"> + <span class="icon">⚡</span> + <h3>Blazing Dispatch</h3> + <p> + With the <code>dispatch_tree</code> feature, your + subcommand structure is hardened into a prefix tree + at compile time. O(len) lookup. + </p> + </div> + + <div class="feature-card"> + <span class="icon">🔄</span> + <h3>Dynamic Completion</h3> + <p> + Enable <code>comp</code> and get smart, + context-aware shell completions for bash, zsh, fish, + and pwsh — no manual registration. + </p> + </div> + + <div class="feature-card"> + <span class="icon">📦</span> + <h3>Lightweight & Modular</h3> + <p> + Minimal core dependencies. Pull in advanced features + (REPL, structured output, Clap binding) only when + you need them via feature flags. + </p> + </div> + + <div class="feature-card"> + <span class="icon">📤</span> + <h3>Structured Output</h3> + <p> + Add <code>general_renderer</code> and your program + gains <code>--json</code> / + <code>--yaml</code> flags automatically. Great for + scripting and pipe workflows. + </p> + </div> + + <div class="feature-card"> + <span class="icon">🔁</span> + <h3>REPL Mode</h3> + <p> + Call <code>program.exec_repl()</code> and your CLI + becomes an interactive shell — perfect for debugging + and exploration. + </p> + </div> + </div> + </div> + </section> + + <!-- CTA Banner --> + <section class="cta-banner"> + <h2>Ready to command your CLI?</h2> + <p> + Add Mingling to your project in one line, or dive straight into + the docs. + </p> + <code>cargo add mingling</code> + <div class="cta-row" style="margin-top: 1.5rem"> + <a href="docs/doc.html" class="btn-primary"> + 📖 Read The Docs + </a> + <a + href="https://github.com/catilgrass/mingling" + target="_blank" + class="btn-secondary" + > + GitHub → + </a> + </div> + </section> + + <!-- Footer --> + <script src="docs/scripts/highlight/highlight.min.js"></script> + <script src="docs/scripts/highlight/rust.min.js"></script> + <script> + hljs.highlightAll(); + </script> + + <script> + (function () { + var text = '"Macro magician in your CLI."'; + var el = document.getElementById("typewriter"); + var i = 0; + var timer = null; + + function type() { + if (i < text.length) { + el.innerHTML = + text.substring(0, i + 1) + + '<span class="cursor"></span>'; + i++; + var delay = + text[i - 1] === "." || text[i - 1] === "," + ? 200 + : 55; + timer = setTimeout(type, delay); + } else { + el.innerHTML = text + '<span class="cursor"></span>'; + } + } + + // Start typing after page settles + setTimeout(type, 2000); + })(); + </script> + + <script> + document.addEventListener("click", function (e) { + var drop = document.createElement("div"); + drop.className = "ink-drop"; + drop.style.left = e.clientX + "px"; + drop.style.top = e.clientY + "px"; + document.body.appendChild(drop); + setTimeout(function () { + drop.remove(); + }, 1000); + }); + </script> + + <footer> + <p> + Built With ❤️ by + <a href="https://github.com/Weicao-CatilGrass" target="_blank" + >Weicao-CatilGrass</a + > + · Licensed under + <a href="LICENSE-MIT" target="_blank">MIT</a> / + <a href="LICENSE-APACHE" target="_blank">Apache-2.0</a> + </p> + </footer> + </body> +</html> |
