Marketing

HowItWorks

Numbered steps with icons, titles and text, in a row joined by a line, or down a column.

#marketing#section#list#progress#no-js

Demo

Preview

How it works

From an empty folder to a page on the internet.

  1. Step 1: Install

    One binary for your machine; nothing else to set up.

  2. Step 2: Write a route

    A function that returns HTML. Views and components for the rest.

  3. Step 3: Run it

    quillo run app.qwe serves, watches and reloads.

  4. Step 4: Deploy

    Copy the binary and the file to a server. That is the pipeline.

  1. Step 1: Pick a plan

    Free for one project; teams pay per seat.

  2. Step 2: Invite the team

    Everyone gets the same file; Git keeps the history.

  3. Step 3: Ship

    A green check and it is live.

Get it

It needs theme.qwe, as every component does; or take the whole kit, quillo-ui.qwe. Each component brings its own styles to the pages that show it.

$ curl -O https://quillolang.org/components/ui/theme.qwe$ curl -O https://quillolang.org/components/ui/how_it_works.qwe
main.qwe
import ui/theme.qwe use theme_cssuse ui/how_it_works.qweroute GET / = <html><head><style>{theme_css}</style></head><body class="ui-root">...</body></html>

Example

The code of the preview above.

demos/how_it_works.qwe
let how_it_works_demo_steps = [    { title: "Install", text: "One binary for your machine; nothing else to set up." },    { title: "Write a route", text: "A function that returns HTML. Views and components for the rest." },    { title: "Run it", text: "quillo run app.qwe serves, watches and reloads." },    { title: "Deploy", text: "Copy the binary and the file to a server. That is the pipeline." },]view HowItWorksDemo() =    <div.demo-stack>        <HowItWorks id="how-it-works-demo" title="How it works" text="From an empty folder to a page on the internet." steps={how_it_works_demo_steps}/>        <HowItWorks direction="column" steps={[            { title: "Pick a plan", text: "Free for one project; teams pay per seat.", icon: "💳" },            { title: "Invite the team", text: "Everyone gets the same file; Git keeps the history.", icon: "👋" },            { title: "Ship", text: "A green check and it is live.", icon: <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg> },        ]}/>    </div>

Source

ui/how_it_works.qwe
// HowItWorks: the few steps from nothing to done, numbered, in a row (or a// column), each with an icon, a title and a sentence.////   <HowItWorks title="Three steps" steps={[//       { title: "Install", text: "One binary, on any machine.", icon: "⬇️" },//       { title: "Write", text: "A route that returns HTML." },//       { title: "Run", text: "quillo run app.qwe, and it is live." },//   ]}/>//   <HowItWorks direction="column" steps={steps}/>//// steps: a list of { title, text?, icon? }, in order; icon is HTML or a short// text, drawn in the step's circle instead of its number (the number is still// said to screen readers). title and text: a heading and a line above.// direction: "row" (default: side by side, with a line joining the circles,// stacking on a phone) or "column" (one under another, the line down the side).// It is an <ol>, so screen readers count the steps.import ui/theme.qwe use ui_clslet how_it_works_css = css`.ui-hiw { display: grid; gap: 28px; font: 15px/1.5 var(--ui-font); color: var(--ui-fg); }.ui-hiw-head { display: grid; gap: 8px; max-width: 640px; margin: 0 auto 4px; text-align: center; }.ui-hiw-title { margin: 0; font-size: clamp(24px, 3.4vw, 32px); font-weight: 700; line-height: 1.2; letter-spacing: -.015em; }.ui-hiw-text { margin: 0; color: var(--ui-muted); font-size: 17px; }.ui-hiw-steps { display: grid; gap: 24px; margin: 0; padding: 0; list-style: none; }.ui-hiw-row .ui-hiw-steps { grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); }.ui-hiw-step { position: relative; display: grid; gap: 6px; min-width: 0; }.ui-hiw-row .ui-hiw-step { justify-items: center; text-align: center; }.ui-hiw-mark { position: relative; z-index: 1; display: grid; place-items: center; width: 48px; height: 48px; margin-bottom: 6px;  border-radius: 50%; background: var(--ui-accent); color: var(--ui-accent-fg); font-size: 18px; font-weight: 700; line-height: 1;  box-shadow: 0 0 0 4px var(--ui-bg); }.ui-hiw-mark svg { width: 22px; height: 22px; }.ui-hiw-icon { background: var(--ui-accent-soft); color: var(--ui-accent); }.ui-hiw-row .ui-hiw-step:not(:last-child)::before { content: ""; position: absolute; top: 24px; left: 50%; width: 100%; height: 2px; background: var(--ui-border); }.ui-hiw-column .ui-hiw-step { grid-template-columns: 48px 1fr; column-gap: 16px; align-items: start; }.ui-hiw-column .ui-hiw-step > :not(.ui-hiw-mark) { grid-column: 2; }.ui-hiw-column .ui-hiw-mark { grid-row: 1 / span 3; margin: 0; }.ui-hiw-column .ui-hiw-step:not(:last-child)::before { content: ""; position: absolute; top: 48px; bottom: -24px; left: 23px; width: 2px; background: var(--ui-border); }.ui-hiw-step-title { margin: 0; font-size: 17px; font-weight: 600; line-height: 1.3; }.ui-hiw-column .ui-hiw-step-title { margin-top: 12px; }.ui-hiw-step-text { margin: 0; color: var(--ui-muted); }@media (max-width: 760px) {  .ui-hiw-row .ui-hiw-steps { grid-auto-flow: row; grid-auto-columns: auto; }  .ui-hiw-row .ui-hiw-step { grid-template-columns: 48px 1fr; column-gap: 16px; justify-items: start; text-align: left; align-items: start; }  .ui-hiw-row .ui-hiw-step > :not(.ui-hiw-mark) { grid-column: 2; }  .ui-hiw-row .ui-hiw-mark { grid-row: 1 / span 3; margin: 0; }  .ui-hiw-row .ui-hiw-step-title { margin-top: 12px; }  .ui-hiw-row .ui-hiw-step:not(:last-child)::before { top: 48px; bottom: -24px; left: 23px; width: 2px; height: auto; }}`view HowItWorks(steps: list, title: str? = null, text: str? = null, direction: str = "row", id: str? = null, class: str? = null) {    style global how_it_works_css    <section id={id} class={ui_cls(["ui-hiw", `ui-hiw-${direction}`, class])}>        {(title != null || text != null) && <div.ui-hiw-head>            {title != null && <h2.ui-hiw-title>{title}</h2>}            {text != null && <p.ui-hiw-text>{text}</p>}        </div>}        <ol.ui-hiw-steps>            {for [i, s] in enumerate(steps) => <li.ui-hiw-step>                <span class={ui_cls(["ui-hiw-mark", s.icon != null && "ui-hiw-icon"])} aria-hidden="true">{s.icon ?? i + 1}</span>                <h3.ui-hiw-step-title><span.ui-sr>Step {i + 1}: </span>{s.title}</h3>                {s.text != null && <p.ui-hiw-step-text>{s.text}</p>}            </li>}        </ol>    </section>}
Thread
68Useful? Like it, or add to its thread below.

Thread 0 posts

On HowItWorks: questions, tips, corrections, and code that uses it.

No posts yet. The first one opens the thread.