feat(studio): ten more sections, so the common page shapes need no hand-built HTML
The nine existing blocks covered a hero and the things under it. Anything with a header, an FAQ, a team, a set of numbers or a signup band had to be written by hand in the code widget — which is where people stopped. Each new block keeps to its own class namespace, so stacking two of them cannot make the first change shape: nothing here redefines a selector another block already owns. Two editor quirks are worked around in the markup rather than left for the owner to trip over. Form buttons and table cells parse as opaque boxes whose text is only reachable through the trait panel, so they carry data-gjs-type=text and behave like every other word on the page (the contact block's Send button gets the same treatment — it had the bug first). And a bare <video> is given controls and a play bar by the editor, which is wrong for a background film, so the video hero turns them off in the model instead. Neither attribute survives export. Panel icons now distinguish navigation blocks from page sections.
This commit is contained in:
parent
3d9301d239
commit
b1951aeed4
1 changed files with 35 additions and 7 deletions
42
js/studio.js
42
js/studio.js
|
|
@ -479,8 +479,8 @@ a{color:#e3e6eb}
|
||||||
<pre class="dc-pre"><code>curl -fsSL https://${esc(name)}/install.sh | sh</code></pre>
|
<pre class="dc-pre"><code>curl -fsSL https://${esc(name)}/install.sh | sh</code></pre>
|
||||||
<h2 id="config">Configure</h2>
|
<h2 id="config">Configure</h2>
|
||||||
<p>What to edit and where it lives. Say what the defaults are so most readers can stop here.</p>
|
<p>What to edit and where it lives. Say what the defaults are so most readers can stop here.</p>
|
||||||
<table class="dc-tab"><thead><tr><th>Key</th><th>Default</th><th>What it does</th></tr></thead>
|
<table class="dc-tab"><thead><tr><th data-gjs-type="text">Key</th><th data-gjs-type="text">Default</th><th data-gjs-type="text">What it does</th></tr></thead>
|
||||||
<tbody><tr><td>port</td><td>8080</td><td>Where it listens.</td></tr><tr><td>data_dir</td><td>./data</td><td>Where state is kept.</td></tr><tr><td>log_level</td><td>info</td><td>How loud it is.</td></tr></tbody></table>
|
<tbody><tr><td data-gjs-type="text">port</td><td data-gjs-type="text">8080</td><td data-gjs-type="text">Where it listens.</td></tr><tr><td data-gjs-type="text">data_dir</td><td data-gjs-type="text">./data</td><td data-gjs-type="text">Where state is kept.</td></tr><tr><td data-gjs-type="text">log_level</td><td data-gjs-type="text">info</td><td data-gjs-type="text">How loud it is.</td></tr></tbody></table>
|
||||||
<h2 id="first">First run</h2>
|
<h2 id="first">First run</h2>
|
||||||
<p>The happy path, end to end, with the output the reader should actually see.</p>
|
<p>The happy path, end to end, with the output the reader should actually see.</p>
|
||||||
<div class="dc-note"><b>Note</b> Anything that will bite a reader at 2am goes in a box like this one.</div>
|
<div class="dc-note"><b>Note</b> Anything that will bite a reader at 2am goes in a box like this one.</div>
|
||||||
|
|
@ -666,7 +666,7 @@ body{margin:0;background:#fdf6ec;color:#3a2a1c;font-family:Georgia,'Times New Ro
|
||||||
<input type="text" name="name" placeholder="Your name" required>
|
<input type="text" name="name" placeholder="Your name" required>
|
||||||
<input type="email" name="email" placeholder="Email" required>
|
<input type="email" name="email" placeholder="Email" required>
|
||||||
<input type="text" name="diet" placeholder="Anything you cannot eat">
|
<input type="text" name="diet" placeholder="Anything you cannot eat">
|
||||||
<button type="submit" class="ev-btn">Hold my seat</button>
|
<button type="submit" class="ev-btn" data-gjs-type="text">Hold my seat</button>
|
||||||
</form>
|
</form>
|
||||||
<p class="ev-fine">This form needs somewhere to post to. Until you set one up, put an email address here instead.</p>
|
<p class="ev-fine">This form needs somewhere to post to. Until you set one up, put an email address here instead.</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -709,7 +709,7 @@ body{margin:0;background:#fff9f2;color:#2f2418;font-family:system-ui,-apple-syst
|
||||||
<p class="nl-sub">Say what is in it and how often it lands. Then say what you will never do with the address — people read that line.</p>
|
<p class="nl-sub">Say what is in it and how often it lands. Then say what you will never do with the address — people read that line.</p>
|
||||||
<form class="nl-form" method="post">
|
<form class="nl-form" method="post">
|
||||||
<input type="email" name="email" placeholder="you@example" required>
|
<input type="email" name="email" placeholder="you@example" required>
|
||||||
<button type="submit">Subscribe</button>
|
<button type="submit" data-gjs-type="text">Subscribe</button>
|
||||||
</form>
|
</form>
|
||||||
<p class="nl-fine">No tracking pixels. Unsubscribe from the bottom of any issue.</p>
|
<p class="nl-fine">No tracking pixels. Unsubscribe from the bottom of any issue.</p>
|
||||||
</header>
|
</header>
|
||||||
|
|
@ -807,7 +807,7 @@ body{margin:0;background:#0a0c08;color:#eef3e4;font-family:system-ui,-apple-syst
|
||||||
<p class="cs-when">Opening 14 November ${new Date().getFullYear()} — edit these numbers by hand, or drop in the Countdown widget from the Widgets panel to make them run.</p>
|
<p class="cs-when">Opening 14 November ${new Date().getFullYear()} — edit these numbers by hand, or drop in the Countdown widget from the Widgets panel to make them run.</p>
|
||||||
<form class="cs-form" method="post">
|
<form class="cs-form" method="post">
|
||||||
<input type="email" name="email" placeholder="you@example">
|
<input type="email" name="email" placeholder="you@example">
|
||||||
<button type="submit">Tell me when</button>
|
<button type="submit" data-gjs-type="text">Tell me when</button>
|
||||||
</form>
|
</form>
|
||||||
<p class="cs-or">or follow along: <a href="https://">Nostr</a> · <a href="https://">Mastodon</a> · <a href="mailto:">Email</a></p>
|
<p class="cs-or">or follow along: <a href="https://">Nostr</a> · <a href="https://">Mastodon</a> · <a href="mailto:">Email</a></p>
|
||||||
</main>
|
</main>
|
||||||
|
|
@ -982,7 +982,7 @@ function setupEditing() {
|
||||||
}
|
}
|
||||||
// 4. Ready-made sections, Tilda style: drop, then edit text and images in place.
|
// 4. Ready-made sections, Tilda style: drop, then edit text and images in place.
|
||||||
const bm = editor.BlockManager;
|
const bm = editor.BlockManager;
|
||||||
const sec = (id, label, html, css) => bm.add(`sx-${id}`, { label, category: "Sections", media: SECTION_ICON, content: `<style>${css}</style>${html}` });
|
const sec = (id, label, html, css, icon = SECTION_ICON) => bm.add(`sx-${id}`, { label, category: "Sections", media: icon, content: `<style>${css}</style>${html}` });
|
||||||
sec("hero", "Hero", `<section class="sx-hero"><div class="sx-wrap"><p class="sx-kicker">NEW</p><h1>A headline that earns the scroll</h1><p class="sx-lead">One sentence on what this is and who it is for. Keep it honest and short.</p><a class="sx-btn" href="#">Get started</a></div></section>`,
|
sec("hero", "Hero", `<section class="sx-hero"><div class="sx-wrap"><p class="sx-kicker">NEW</p><h1>A headline that earns the scroll</h1><p class="sx-lead">One sentence on what this is and who it is for. Keep it honest and short.</p><a class="sx-btn" href="#">Get started</a></div></section>`,
|
||||||
`.sx-hero{padding:96px 24px;background:#0b0e14;color:#f1f4fa;text-align:center}.sx-wrap{max-width:820px;margin:0 auto}.sx-kicker{letter-spacing:.2em;font-size:12px;color:#d6ff3d;margin:0 0 12px}.sx-hero h1{font-size:44px;line-height:1.1;margin:0 0 16px}.sx-lead{font-size:18px;color:#b8c2d4;margin:0 0 28px}.sx-btn{display:inline-block;background:#d6ff3d;color:#0b0e14;padding:12px 22px;border-radius:10px;text-decoration:none;font-weight:600}`);
|
`.sx-hero{padding:96px 24px;background:#0b0e14;color:#f1f4fa;text-align:center}.sx-wrap{max-width:820px;margin:0 auto}.sx-kicker{letter-spacing:.2em;font-size:12px;color:#d6ff3d;margin:0 0 12px}.sx-hero h1{font-size:44px;line-height:1.1;margin:0 0 16px}.sx-lead{font-size:18px;color:#b8c2d4;margin:0 0 28px}.sx-btn{display:inline-block;background:#d6ff3d;color:#0b0e14;padding:12px 22px;border-radius:10px;text-decoration:none;font-weight:600}`);
|
||||||
sec("features", "Three features", `<section class="sx-feat"><div class="sx-grid3"><div><h3>Fast</h3><p>Say what it does in one line.</p></div><div><h3>Simple</h3><p>Say why it is easy.</p></div><div><h3>Yours</h3><p>Say what the visitor keeps.</p></div></div></section>`,
|
sec("features", "Three features", `<section class="sx-feat"><div class="sx-grid3"><div><h3>Fast</h3><p>Say what it does in one line.</p></div><div><h3>Simple</h3><p>Say why it is easy.</p></div><div><h3>Yours</h3><p>Say what the visitor keeps.</p></div></div></section>`,
|
||||||
|
|
@ -997,16 +997,44 @@ function setupEditing() {
|
||||||
`.sx-price{padding:64px 24px;background:#f6f7f9;color:#111}.sx-price .sx-grid3{max-width:1000px;margin:0 auto;display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:20px}.sx-plan{background:#fff;border:1px solid #e6e8ee;border-radius:16px;padding:28px 24px;text-align:center}.sx-hot{border-color:#111}.sx-amt{font-size:40px;font-weight:700;margin:8px 0 16px}.sx-plan ul{list-style:none;padding:0;margin:0 0 20px;color:#555;line-height:1.9}.sx-price .sx-btn{display:inline-block;background:#111;color:#fff;padding:10px 20px;border-radius:10px;text-decoration:none;font-weight:600}`);
|
`.sx-price{padding:64px 24px;background:#f6f7f9;color:#111}.sx-price .sx-grid3{max-width:1000px;margin:0 auto;display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:20px}.sx-plan{background:#fff;border:1px solid #e6e8ee;border-radius:16px;padding:28px 24px;text-align:center}.sx-hot{border-color:#111}.sx-amt{font-size:40px;font-weight:700;margin:8px 0 16px}.sx-plan ul{list-style:none;padding:0;margin:0 0 20px;color:#555;line-height:1.9}.sx-price .sx-btn{display:inline-block;background:#111;color:#fff;padding:10px 20px;border-radius:10px;text-decoration:none;font-weight:600}`);
|
||||||
sec("cta", "Call to action", `<section class="sx-cta"><h2>Ready when you are</h2><p>One line that removes the last doubt.</p><a class="sx-btn" href="#">Do the thing →</a></section>`,
|
sec("cta", "Call to action", `<section class="sx-cta"><h2>Ready when you are</h2><p>One line that removes the last doubt.</p><a class="sx-btn" href="#">Do the thing →</a></section>`,
|
||||||
`.sx-cta{padding:72px 24px;text-align:center;background:#d6ff3d;color:#0b0e14}.sx-cta h2{font-size:34px;margin:0 0 8px}.sx-cta p{margin:0 0 24px;font-size:17px}.sx-cta .sx-btn{display:inline-block;background:#0b0e14;color:#d6ff3d;padding:12px 22px;border-radius:10px;text-decoration:none;font-weight:600}`);
|
`.sx-cta{padding:72px 24px;text-align:center;background:#d6ff3d;color:#0b0e14}.sx-cta h2{font-size:34px;margin:0 0 8px}.sx-cta p{margin:0 0 24px;font-size:17px}.sx-cta .sx-btn{display:inline-block;background:#0b0e14;color:#d6ff3d;padding:12px 22px;border-radius:10px;text-decoration:none;font-weight:600}`);
|
||||||
sec("contact", "Contact form", `<section class="sx-contact"><div class="sx-wrap"><h2>Get in touch</h2><form class="sx-form" method="post"><input type="text" name="name" placeholder="Your name"><input type="email" name="email" placeholder="Email"><textarea name="message" rows="4" placeholder="Message"></textarea><button type="submit" class="sx-btn">Send</button></form></div></section>`,
|
sec("contact", "Contact form", `<section class="sx-contact"><div class="sx-wrap"><h2>Get in touch</h2><form class="sx-form" method="post"><input type="text" name="name" placeholder="Your name"><input type="email" name="email" placeholder="Email"><textarea name="message" rows="4" placeholder="Message"></textarea><button type="submit" class="sx-btn" data-gjs-type="text">Send</button></form></div></section>`,
|
||||||
`.sx-contact{padding:64px 24px;background:#fff;color:#111}.sx-contact .sx-wrap{max-width:560px;margin:0 auto}.sx-contact h2{margin:0 0 16px}.sx-form{display:grid;gap:10px}.sx-form input,.sx-form textarea{width:100%;padding:12px;border:1px solid #d9dce3;border-radius:10px;font:inherit}.sx-contact .sx-btn{background:#111;color:#fff;border:0;padding:12px 20px;border-radius:10px;font-weight:600;cursor:pointer}`);
|
`.sx-contact{padding:64px 24px;background:#fff;color:#111}.sx-contact .sx-wrap{max-width:560px;margin:0 auto}.sx-contact h2{margin:0 0 16px}.sx-form{display:grid;gap:10px}.sx-form input,.sx-form textarea{width:100%;padding:12px;border:1px solid #d9dce3;border-radius:10px;font:inherit}.sx-contact .sx-btn{background:#111;color:#fff;border:0;padding:12px 20px;border-radius:10px;font-weight:600;cursor:pointer}`);
|
||||||
sec("footer", "Footer", `<footer class="sx-footer"><div class="sx-wrap sx-foot-in"><span>© <b>your name</b> · on Bitcoin Cash</span><nav><a href="#">About</a><a href="#">Contact</a><a href="#">Privacy</a></nav></div></footer>`,
|
sec("footer", "Footer", `<footer class="sx-footer"><div class="sx-wrap sx-foot-in"><span>© <b>your name</b> · on Bitcoin Cash</span><nav><a href="#">About</a><a href="#">Contact</a><a href="#">Privacy</a></nav></div></footer>`,
|
||||||
`.sx-footer{padding:28px 24px;background:#0b0e14;color:#b8c2d4;font-size:14px}.sx-foot-in{max-width:1000px;margin:0 auto;display:flex;justify-content:space-between;gap:14px;flex-wrap:wrap}.sx-footer a{color:#b8c2d4;text-decoration:none;margin-left:16px}.sx-footer b{color:#f1f4fa}`);
|
`.sx-footer{padding:28px 24px;background:#0b0e14;color:#b8c2d4;font-size:14px}.sx-foot-in{max-width:1000px;margin:0 auto;display:flex;justify-content:space-between;gap:14px;flex-wrap:wrap}.sx-footer a{color:#b8c2d4;text-decoration:none;margin-left:16px}.sx-footer b{color:#f1f4fa}`);
|
||||||
|
// Ten more, added 2026-09: navigation, social proof and the small print
|
||||||
|
// that every real page ends up needing. Each block owns its own class
|
||||||
|
// namespace (.sx-nav1, .sx-faq, …) and never reuses a selector another
|
||||||
|
// block defines, so dropping two of them on one page cannot make the
|
||||||
|
// first one change shape. `data-gjs-type="text"` marks the elements the
|
||||||
|
// parser would otherwise treat as opaque — the editor eats the attribute,
|
||||||
|
// it never reaches the exported page.
|
||||||
|
sec("nav-simple", "Nav — simple", `<header class="sx-nav1"><div class="sx-nav1-in"><a class="sx-nav1-logo" href="/">your name</a><nav class="sx-nav1-links"><a href="#">Work</a><a href="#">About</a><a href="#">Contact</a></nav></div></header>`,
|
||||||
|
`.sx-nav1{background:#fff;border-bottom:1px solid #e8eaee}.sx-nav1-in{max-width:1040px;margin:0 auto;padding:16px 24px;display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap}.sx-nav1-logo{color:#111;font-weight:700;font-size:16px;text-decoration:none}.sx-nav1-links a{color:#5a6069;text-decoration:none;font-size:14.5px;margin-left:22px}.sx-nav1-links a:hover{color:#111}@media(max-width:480px){.sx-nav1-links a{margin:0 16px 0 0}}`, NAV_ICON);
|
||||||
|
sec("nav-cta", "Nav — with button", `<header class="sx-nav2"><div class="sx-nav2-in"><a class="sx-nav2-logo" href="/">your name</a><nav class="sx-nav2-links"><a href="#">Product</a><a href="#">Pricing</a><a href="#">Docs</a><a href="#">Blog</a><a href="#">Support</a></nav><a class="sx-nav2-btn" href="#">Get started</a></div></header>`,
|
||||||
|
`.sx-nav2{background:#0b0e14;color:#f1f4fa}.sx-nav2-in{max-width:1100px;margin:0 auto;padding:14px 24px;display:flex;align-items:center;gap:18px;flex-wrap:wrap}.sx-nav2-logo{color:#f1f4fa;font-weight:700;font-size:16px;text-decoration:none;margin-right:10px}.sx-nav2-links{flex:1;display:flex;gap:22px;flex-wrap:wrap}.sx-nav2-links a{color:#9aa4b5;text-decoration:none;font-size:14.5px}.sx-nav2-links a:hover{color:#fff}.sx-nav2-btn{background:#d6ff3d;color:#0b0e14;font-weight:700;font-size:14px;padding:9px 18px;border-radius:9px;text-decoration:none;white-space:nowrap}`, NAV_ICON);
|
||||||
|
sec("video-hero", "Video hero", `<section class="sx-vhero"><video class="sx-vhero-bg" data-gjs-controls="false" data-gjs-autoplay="true" data-gjs-loop="true" muted playsinline></video><div class="sx-vhero-in"><h1>Say it over moving pictures</h1><p>Click the video and set its source in the panel on the right — an MP4 you uploaded works, and so does any public URL. Until then the gradient stands in.</p><a class="sx-vhero-btn" href="#">Watch the film</a></div></section>`,
|
||||||
|
`.sx-vhero{position:relative;min-height:70vh;display:flex;align-items:center;justify-content:center;text-align:center;padding:80px 24px;overflow:hidden;background:linear-gradient(140deg,#131a2b,#2c1a3a 55%,#0b0e14)}.sx-vhero-bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;border:0}.sx-vhero-in{position:relative;max-width:720px;color:#fff;text-shadow:0 2px 24px rgba(0,0,0,.55)}.sx-vhero h1{font-size:46px;line-height:1.1;margin:0 0 14px;letter-spacing:-.02em}.sx-vhero p{font-size:17px;color:rgba(255,255,255,.82);margin:0 0 26px}.sx-vhero-btn{display:inline-block;background:#fff;color:#111;font-weight:700;padding:13px 26px;border-radius:999px;text-decoration:none}@media(max-width:600px){.sx-vhero h1{font-size:30px}}`);
|
||||||
|
sec("stats", "Big numbers", `<section class="sx-stat"><div class="sx-stat-in"><div><b>12k</b><span data-gjs-type="text">names registered</span></div><div><b>99.9%</b><span data-gjs-type="text">gateway uptime</span></div><div><b>4</b><span data-gjs-type="text">chains supported</span></div><div><b>$0</b><span data-gjs-type="text">renewal fees, ever</span></div></div></section>`,
|
||||||
|
`.sx-stat{padding:56px 24px;background:#f6f7f9;color:#111}.sx-stat-in{max-width:1000px;margin:0 auto;display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:32px;text-align:center}.sx-stat b{display:block;font-size:44px;font-weight:700;letter-spacing:-.03em;line-height:1.05;font-variant-numeric:tabular-nums}.sx-stat span{display:block;margin-top:6px;color:#6b727c;font-size:14px}`);
|
||||||
|
sec("steps", "Numbered steps", `<section class="sx-steps"><h2>How it works</h2><div class="sx-steps-in"><div class="sx-step"><span class="sx-step-n" data-gjs-type="text">1</span><h3>Pick a name</h3><p>Search, check it is free, pay once.</p></div><div class="sx-step"><span class="sx-step-n" data-gjs-type="text">2</span><h3>Build the page</h3><p>Drag sections in, rewrite the words.</p></div><div class="sx-step"><span class="sx-step-n" data-gjs-type="text">3</span><h3>Publish</h3><p>One click puts it on Sia, signed by you.</p></div></div></section>`,
|
||||||
|
`.sx-steps{padding:64px 24px;background:#fff;color:#111}.sx-steps>h2{max-width:1000px;margin:0 auto 32px;font-size:28px;letter-spacing:-.015em}.sx-steps-in{max-width:1000px;margin:0 auto;display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:28px}.sx-step-n{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:50%;background:#111;color:#fff;font-weight:700;font-size:16px;margin-bottom:12px}.sx-step h3{margin:0 0 6px;font-size:18px}.sx-step p{margin:0;color:#5a6069;line-height:1.6}`);
|
||||||
|
sec("team", "Team", `<section class="sx-team"><h2>Who you would be working with</h2><div class="sx-team-in"><div class="sx-member"><img src="https://silentmode.st/sirius-x/brand/avatar.svg" alt=""><b>A. Person</b><i data-gjs-type="text">Founder</i><p>One line on what they do and what they did before.</p></div><div class="sx-member"><img src="https://silentmode.st/sirius-x/brand/avatar.svg" alt=""><b>B. Person</b><i data-gjs-type="text">Design</i><p>One line on what they do and what they did before.</p></div><div class="sx-member"><img src="https://silentmode.st/sirius-x/brand/avatar.svg" alt=""><b>C. Person</b><i data-gjs-type="text">Engineering</i><p>One line on what they do and what they did before.</p></div></div></section>`,
|
||||||
|
`.sx-team{padding:64px 24px;background:#fff;color:#111}.sx-team>h2{max-width:980px;margin:0 auto 34px;font-size:28px;letter-spacing:-.015em}.sx-team-in{max-width:980px;margin:0 auto;display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:34px}.sx-member img{width:96px;height:96px;border-radius:50%;object-fit:cover;background:#eceef1;display:block;margin-bottom:14px}.sx-member b{display:block;font-size:16px}.sx-member i{display:block;font-style:normal;color:#8b9099;font-size:13.5px;margin-bottom:8px}.sx-member p{margin:0;color:#5a6069;font-size:15px;line-height:1.6}`);
|
||||||
|
sec("logos", "Logo cloud", `<section class="sx-logos"><p class="sx-logos-lab" data-gjs-type="text">Trusted by people who read the source</p><div class="sx-logos-in">${Array.from({ length: 6 }, () => `<img src="https://silentmode.st/sirius-x/brand/avatar.svg" alt="">`).join("")}</div></section>`,
|
||||||
|
`.sx-logos{padding:48px 24px;background:#fafbfc;border-top:1px solid #eceef1;border-bottom:1px solid #eceef1}.sx-logos-lab{max-width:1000px;margin:0 auto 26px;text-align:center;font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:#98a0ab}.sx-logos-in{max-width:1000px;margin:0 auto;display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:24px 48px}.sx-logos img{height:34px;width:auto;filter:grayscale(1);opacity:.6;transition:filter .18s,opacity .18s}.sx-logos img:hover{filter:none;opacity:1}`);
|
||||||
|
sec("timeline", "Timeline", `<section class="sx-tl"><h2>How we got here</h2><div class="sx-tl-in"><div class="sx-tl-row"><time data-gjs-type="text">2021</time><div><b>It started as a weekend thing</b><p>What happened, in one or two sentences.</p></div></div><div class="sx-tl-row"><time data-gjs-type="text">2023</time><div><b>The first real users</b><p>What happened, in one or two sentences.</p></div></div><div class="sx-tl-row"><time data-gjs-type="text">2024</time><div><b>It paid for itself</b><p>What happened, in one or two sentences.</p></div></div><div class="sx-tl-row"><time data-gjs-type="text">Today</time><div><b>Where it is now</b><p>What happened, in one or two sentences.</p></div></div></div></section>`,
|
||||||
|
`.sx-tl{padding:64px 24px;background:#0b0e14;color:#e8ecf2}.sx-tl>h2{max-width:720px;margin:0 auto 34px;font-size:28px;letter-spacing:-.015em}.sx-tl-in{max-width:720px;margin:0 auto;border-left:2px solid #232a36;padding-left:26px}.sx-tl-row{position:relative;padding-bottom:28px}.sx-tl-row:last-child{padding-bottom:0}.sx-tl-row::before{content:"";position:absolute;left:-33px;top:6px;width:12px;height:12px;border-radius:50%;background:#d6ff3d}.sx-tl-row time{display:block;font-size:13px;letter-spacing:.06em;color:#d6ff3d;margin-bottom:4px}.sx-tl-row b{display:block;font-size:17px;margin-bottom:4px}.sx-tl-row p{margin:0;color:#98a3b4;line-height:1.6}`);
|
||||||
|
sec("faq", "FAQ", `<section class="sx-faq"><h2>Questions people actually ask</h2><div class="sx-faq-in"><details class="sx-faq-i"><summary data-gjs-type="text">What happens if this site goes away?</summary><p>Answer it straight. The shortest true answer builds more trust than the longest reassuring one.</p></details><details class="sx-faq-i"><summary data-gjs-type="text">Do I need a wallet?</summary><p>Answer it straight.</p></details><details class="sx-faq-i"><summary data-gjs-type="text">What does it cost, in total?</summary><p>Answer it straight.</p></details><details class="sx-faq-i"><summary data-gjs-type="text">Can I move it somewhere else later?</summary><p>Answer it straight.</p></details><details class="sx-faq-i"><summary data-gjs-type="text">Who can see what I publish?</summary><p>Answer it straight.</p></details><details class="sx-faq-i"><summary data-gjs-type="text">How do I get help?</summary><p>Answer it straight.</p></details></div></section>`,
|
||||||
|
`.sx-faq{padding:64px 24px;background:#fff;color:#111}.sx-faq>h2{max-width:720px;margin:0 auto 26px;font-size:28px;letter-spacing:-.015em}.sx-faq-in{max-width:720px;margin:0 auto}.sx-faq-i{border-bottom:1px solid #e8eaee}.sx-faq-i summary{cursor:pointer;padding:16px 28px 16px 0;font-size:17px;font-weight:600;position:relative;list-style:none}.sx-faq-i summary::-webkit-details-marker{display:none}.sx-faq-i summary::after{content:"+";position:absolute;right:4px;top:14px;font-size:20px;font-weight:400;color:#98a0ab}.sx-faq-i[open] summary::after{content:"–"}.sx-faq-i p{margin:0 0 18px;color:#5a6069;line-height:1.65;max-width:62ch}`);
|
||||||
|
sec("newsletter", "Signup band", `<section class="sx-news"><div class="sx-news-in"><div><h2>One email a month, nothing else</h2><p>Say what is in it. People give an address to a promise, not to a form.</p></div><form class="sx-news-form" method="post"><input type="email" name="email" placeholder="you@example" required><button type="submit" data-gjs-type="text">Subscribe</button></form></div></section>`,
|
||||||
|
`.sx-news{padding:52px 24px;background:#d6ff3d;color:#0b0e14}.sx-news-in{max-width:1000px;margin:0 auto;display:flex;align-items:center;justify-content:space-between;gap:32px;flex-wrap:wrap}.sx-news h2{margin:0 0 6px;font-size:26px;letter-spacing:-.015em}.sx-news p{margin:0;font-size:15.5px;opacity:.75;max-width:46ch}.sx-news-form{display:flex;gap:8px;flex-wrap:wrap;flex:1;min-width:280px;max-width:440px}.sx-news-form input{flex:1;min-width:180px;padding:13px 15px;border:1px solid rgba(11,14,20,.22);border-radius:10px;font:inherit;background:#fff}.sx-news-form button{padding:13px 22px;border:0;border-radius:10px;background:#0b0e14;color:#d6ff3d;font:inherit;font-weight:700;cursor:pointer}`);
|
||||||
// Group the plugin blocks under readable categories.
|
// Group the plugin blocks under readable categories.
|
||||||
const cat = { navbar: "Sections", tabs: "Widgets", tooltip: "Widgets", "custom-code": "Widgets", countdown: "Widgets" };
|
const cat = { navbar: "Sections", tabs: "Widgets", tooltip: "Widgets", "custom-code": "Widgets", countdown: "Widgets" };
|
||||||
bm.getAll().forEach((b) => { const c = cat[b.getId()]; if (c) b.set("category", c); });
|
bm.getAll().forEach((b) => { const c = cat[b.getId()]; if (c) b.set("category", c); });
|
||||||
// 5. Selecting anything opens the style panel; the layer tree is one click away.
|
// 5. Selecting anything opens the style panel; the layer tree is one click away.
|
||||||
editor.on("component:selected", () => { const btn = editor.Panels.getButton("views", "open-sm"); if (btn && !btn.get("active")) btn.set("active", true); });
|
editor.on("component:selected", () => { const btn = editor.Panels.getButton("views", "open-sm"); if (btn && !btn.get("active")) btn.set("active", true); });
|
||||||
}
|
}
|
||||||
|
const NAV_ICON = `<svg viewBox="0 0 24 24" width="36" height="36"><rect x="2" y="6" width="20" height="5" rx="1.5" fill="currentColor" opacity=".9"/><rect x="2" y="14" width="9" height="2" rx="1" fill="currentColor" opacity=".35"/><rect x="13" y="14" width="9" height="2" rx="1" fill="currentColor" opacity=".35"/></svg>`;
|
||||||
const SECTION_ICON = `<svg viewBox="0 0 24 24" width="36" height="36"><rect x="2" y="4" width="20" height="5" rx="1.5" fill="currentColor" opacity=".9"/><rect x="2" y="11" width="20" height="9" rx="1.5" fill="currentColor" opacity=".45"/></svg>`;
|
const SECTION_ICON = `<svg viewBox="0 0 24 24" width="36" height="36"><rect x="2" y="4" width="20" height="5" rx="1.5" fill="currentColor" opacity=".9"/><rect x="2" y="11" width="20" height="9" rx="1.5" fill="currentColor" opacity=".45"/></svg>`;
|
||||||
|
|
||||||
function loadTemplate(key) {
|
function loadTemplate(key) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue