Website redesign
48 tasks shared with 6 members. Deleting the project removes its tasks and files for everyone.
Widgets, forms and pages built with femto alone.
Each example is plain HTML styled by femto alone: it uses HTML's elements and only the classes and attributes femto reads. It renders in a shadow root that loads dist/femto.min.css and nothing else, so none of this site's CSS reaches it. Open the markup under an example to copy its HTML.
Widgets
Forms
Widgets
A modal that asks before a project is deleted. A script opens it with showModal().
48 tasks shared with 6 members. Deleting the project removes its tasks and files for everyone.
<article>
<h3>Website redesign</h3>
<p>48 tasks shared with 6 members. Deleting the project removes its tasks and files for everyone.</p>
<button type="button" class="contrast" aria-haspopup="dialog" aria-controls="confirm-dialog-box">Delete project</button>
</article>
<dialog id="confirm-dialog-box" aria-labelledby="confirm-dialog-title">
<article>
<header>
<button type="button" aria-label="Close" rel="prev"></button>
<h3 id="confirm-dialog-title">Delete “Website redesign”?</h3>
</header>
<p>Its 48 tasks and their files will be deleted for all 6 members. You cannot undo this.</p>
<footer>
<button type="button" class="secondary">Cancel</button>
<button type="button">Delete project</button>
</footer>
</article>
</dialog>Widgets
Questions that open and close, each one a <details> element.
Yes. Change it in Billing at any time. We charge or credit the difference on your next invoice.
We refund any payment made in the last 30 days. Write to us with your order number.
In the United States or the European Union. You choose the region when you create a workspace.
Open Billing and choose Cancel subscription. Your workspace stays open until the end of the period you paid for.
Still have a question? Contact support.
<h3>Frequently asked questions</h3>
<details open>
<summary>Can I change my plan later?</summary>
<p>Yes. Change it in Billing at any time. We charge or credit the difference on your next invoice.</p>
</details>
<details>
<summary>Do you offer refunds?</summary>
<p>We refund any payment made in the last 30 days. Write to us with your order number.</p>
</details>
<details>
<summary>Where is my data stored?</summary>
<p>In the United States or the European Union. You choose the region when you create a workspace.</p>
</details>
<details>
<summary>How do I cancel?</summary>
<p>Open Billing and choose Cancel subscription. Your workspace stays open until the end of the period you paid for.</p>
</details>
<p>Still have a question? <a href="#">Contact support</a>.</p>Forms
An email and password form in a card, beside a short welcome.
Sign in to see your orders, saved items and messages.
<div class="grid">
<hgroup>
<h3>Welcome back</h3>
<p>Sign in to see your orders, saved items and messages.</p>
</hgroup>
<article>
<form>
<label>
Email
<input type="email" name="email" autocomplete="email" required>
</label>
<label>
Password
<input type="password" name="password" autocomplete="current-password" required>
</label>
<label>
<input type="checkbox" name="remember" checked>
Keep me signed in
</label>
<button type="submit">Sign in</button>
</form>
<footer>
<a href="#">Forgot your password?</a>
</footer>
</article>
</div>Forms
A registration form whose fields show their state with aria-invalid and helper text.
Free for 14 days. No credit card needed.
<article>
<hgroup>
<h3>Create your account</h3>
<p>Free for 14 days. No credit card needed.</p>
</hgroup>
<form>
<div class="grid">
<label>
First name
<input type="text" name="given-name" autocomplete="given-name" value="Priya" aria-invalid="false">
</label>
<label>
Last name
<input type="text" name="family-name" autocomplete="family-name" value="Patel" aria-invalid="false">
</label>
</div>
<label for="sign-up-email">Email</label>
<input type="email" id="sign-up-email" name="email" autocomplete="email" value="priya@example" aria-invalid="true" aria-describedby="sign-up-email-error">
<small id="sign-up-email-error">Enter a full email address, such as [email protected].</small>
<label for="sign-up-password">Password</label>
<input type="password" id="sign-up-password" name="password" autocomplete="new-password" aria-describedby="sign-up-password-help">
<small id="sign-up-password-help">Use 12 or more characters.</small>
<label>
<input type="checkbox" name="terms">
I agree to the <a href="#">terms of service</a>
</label>
<button type="submit">Create account</button>
</form>
</article>Forms
Contact details beside a form with a select, a textarea and radio buttons.
We answer every message within one business day.
Acme Support<div class="grid">
<div>
<h3>Get in touch</h3>
<p>We answer every message within one business day.</p>
<address>
Acme Support<br>
100 Main Street<br>
Springfield, IL 62701
</address>
<p><a href="#">[email protected]</a></p>
</div>
<form>
<div class="grid">
<label>
Name
<input type="text" name="name" autocomplete="name" required>
</label>
<label>
Email
<input type="email" name="email" autocomplete="email" required>
</label>
</div>
<label>
Topic
<select name="topic" required>
<option value="" selected disabled>Choose a topic</option>
<option>Billing</option>
<option>A technical problem</option>
<option>A feature request</option>
<option>Something else</option>
</select>
</label>
<label>
Message
<textarea name="message" rows="4" required></textarea>
</label>
<fieldset>
<legend>How should we reply?</legend>
<label>
<input type="radio" name="contact-reply" value="email" checked>
By email
</label>
<label>
<input type="radio" name="contact-reply" value="phone">
By phone
</label>
</fieldset>
<button type="submit">Send message</button>
</form>
</div>Pages
Three plans in cards on a grid, with a switch for yearly billing.
Start for free, and upgrade when your team grows.
For one person
$0 per month
For growing teams
$12 per member per month
For large organizations
Custom pricing
<hgroup>
<h3>Plans for teams of every size</h3>
<p>Start for free, and upgrade when your team grows.</p>
</hgroup>
<p>
<label>
<input type="checkbox" role="switch" name="yearly">
Pay yearly and get two months free
</label>
</p>
<div class="grid">
<article>
<hgroup>
<h4>Starter</h4>
<p>For one person</p>
</hgroup>
<p><strong>$0</strong> per month</p>
<ul>
<li>3 projects</li>
<li>1 GB of storage</li>
<li>Community support</li>
</ul>
<footer>
<a href="#" role="button" class="secondary outline">Start for free</a>
</footer>
</article>
<article>
<hgroup>
<h4>Team</h4>
<p>For growing teams</p>
</hgroup>
<p><strong>$12</strong> per member per month</p>
<ul>
<li>Unlimited projects</li>
<li>100 GB of storage</li>
<li>Email support</li>
</ul>
<footer>
<a href="#" role="button">Start a free trial</a>
</footer>
</article>
<article>
<hgroup>
<h4>Enterprise</h4>
<p>For large organizations</p>
</hgroup>
<p><strong>Custom</strong> pricing</p>
<ul>
<li>Single sign-on</li>
<li>Unlimited storage</li>
<li>A dedicated account manager</li>
</ul>
<footer>
<a href="#" role="button" class="contrast outline">Contact sales</a>
</footer>
</article>
</div>Pages
Summary cards, a progress bar, a loading card and a striped table that scrolls on small screens.
October 2026
$48,210, up 12% from September
1,284, down 3% from September
72 GB of 100 GB used
<nav aria-label="Dashboard">
<ul>
<li><strong>Acme</strong></li>
</ul>
<ul>
<li><a href="#" aria-current="page">Overview</a></li>
<li><a href="#">Orders</a></li>
</ul>
</nav>
<hgroup>
<h3>Overview</h3>
<p>October 2026</p>
</hgroup>
<div class="grid">
<article>
<hgroup>
<h4>Revenue</h4>
<p>$48,210, up 12% from September</p>
</hgroup>
</article>
<article>
<hgroup>
<h4>Orders</h4>
<p>1,284, down 3% from September</p>
</hgroup>
</article>
<article>
<hgroup>
<h4>Storage</h4>
<p>72 GB of 100 GB used</p>
</hgroup>
<progress value="72" max="100" aria-label="Storage used"></progress>
</article>
<article aria-busy="true">Counting visitors</article>
</div>
<h4>Recent orders</h4>
<div class="overflow-auto">
<table class="striped">
<thead>
<tr>
<th scope="col">Order</th>
<th scope="col">Customer</th>
<th scope="col">Date</th>
<th scope="col">Total</th>
<th scope="col">Status</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row"><a href="#">1042</a></th>
<td>Jordan Lee</td>
<td>Oct 30</td>
<td>$320.00</td>
<td>Paid</td>
</tr>
<tr>
<th scope="row"><a href="#">1041</a></th>
<td>Sam Rivera</td>
<td>Oct 29</td>
<td>$89.50</td>
<td>Shipped</td>
</tr>
<tr>
<th scope="row"><a href="#">1040</a></th>
<td>Alex Kim</td>
<td>Oct 29</td>
<td>$1,150.00</td>
<td>Paid</td>
</tr>
<tr>
<th scope="row"><a href="#">1039</a></th>
<td>Maria Garcia</td>
<td>Oct 28</td>
<td>$42.00</td>
<td>Refunded</td>
</tr>
</tbody>
</table>
</div>
<button type="button" class="secondary outline" data-tooltip="Download these orders as a CSV file">Export</button>Pages
A settings form with switches, a disabled option and radio buttons.
Your profile and the email you get from us.
<hgroup>
<h3>Account settings</h3>
<p>Your profile and the email you get from us.</p>
</hgroup>
<form>
<h4>Profile</h4>
<div class="grid">
<label>
Display name
<input type="text" name="display-name" autocomplete="nickname" value="Sam Rivera">
</label>
<label>
Email
<input type="email" name="email" autocomplete="email" value="[email protected]">
</label>
</div>
<label>
Time zone
<select name="time-zone">
<option>Pacific Time</option>
<option selected>Eastern Time</option>
<option>Central European Time</option>
</select>
</label>
<label>
Bio
<textarea name="bio" rows="2">Designer in Boston. I draw maps.</textarea>
</label>
<hr>
<fieldset>
<legend>Email me when</legend>
<label>
<input type="checkbox" role="switch" name="comments" checked>
Someone comments on my posts
</label>
<label>
<input type="checkbox" role="switch" name="mentions" checked>
Someone mentions me
</label>
<label>
<input type="checkbox" role="switch" name="news">
There is product news
</label>
<label aria-disabled="true">
<input type="checkbox" role="switch" name="security" checked disabled>
There is a security alert (always on)
</label>
</fieldset>
<hr>
<fieldset>
<legend>Color scheme</legend>
<label>
<input type="radio" name="settings-scheme" value="system" checked>
Match my device
</label>
<label>
<input type="radio" name="settings-scheme" value="light">
Light
</label>
<label>
<input type="radio" name="settings-scheme" value="dark">
Dark
</label>
</fieldset>
<button type="submit">Save changes</button>
<button type="reset" class="secondary outline">Discard changes</button>
</form>Pages
An article with a byline, a list, a quotation and a code block.
By Alex Kim,
Our pages had grown to 2 MB. Most of it was styles and scripts that no visitor needed, so we started again with plain HTML and one stylesheet.
Every byte we send is a byte someone waits for.
Build the site, then compare the page sizes in your browser's developer tools.
npm run build
The new pages load in under a second on a slow connection. Every page now weighs less than 500 KB.
Filed under Performance and Engineering.
<hgroup>
<h3>How we cut our page weight in half</h3>
<p>By Alex Kim, <time datetime="2026-10-28">October 28, 2026</time></p>
</hgroup>
<p>Our pages had grown to 2 MB. Most of it was styles and scripts that no visitor needed, so we started again with plain HTML and one stylesheet.</p>
<h4>What we removed</h4>
<ul>
<li>A front-end framework that only two pages used</li>
<li>Three icon fonts, replaced by inline SVG</li>
<li>Hundreds of <abbr title="Cascading Style Sheets">CSS</abbr> classes that no page used</li>
</ul>
<blockquote>
Every byte we send is a byte someone waits for.
<footer>
<cite>Our performance team</cite>
</footer>
</blockquote>
<h4>Try it yourself</h4>
<p>Build the site, then compare the page sizes in your browser's developer tools.</p>
<pre><code>npm run build</code></pre>
<p>The new pages load in under a second on a slow connection. <mark>Every page now weighs less than 500 KB.</mark></p>
<hr>
<p><small>Filed under <a href="#">Performance</a> and <a href="#">Engineering</a>.</small></p>Pages
A search field joined to its button, a sort dropdown, results and page links.
28 results for "dark mode"
Help center › Appearance
Open Settings, choose Appearance, then choose Dark. Choose Match my device to follow your device's dark mode.
Help center › Email
Emails we send follow your email app's dark mode when the app supports it.
Help center › Sharing
Visitors see a shared page in light or dark mode, following their own device.
<h3>Help center</h3>
<form role="search">
<input type="search" name="q" value="dark mode" aria-label="Search the help center">
<button type="submit">Search</button>
</form>
<div class="grid">
<p>28 results for "dark mode"</p>
<details class="dropdown">
<summary>Sort by</summary>
<ul>
<li>
<label>
<input type="radio" name="search-sort" value="relevance" checked>
Best match
</label>
</li>
<li>
<label>
<input type="radio" name="search-sort" value="newest">
Newest first
</label>
</li>
</ul>
</details>
</div>
<h4><a href="#">Turn on dark mode</a></h4>
<p><small>Help center › Appearance</small></p>
<p>Open Settings, choose Appearance, then choose Dark. Choose Match my device to follow your device's <mark>dark mode</mark>.</p>
<h4><a href="#">Dark mode in email</a></h4>
<p><small>Help center › Email</small></p>
<p>Emails we send follow your email app's <mark>dark mode</mark> when the app supports it.</p>
<h4><a href="#">Change the color scheme of a shared page</a></h4>
<p><small>Help center › Sharing</small></p>
<p>Visitors see a shared page in light or <mark>dark mode</mark>, following their own device.</p>
<nav aria-label="Result pages">
<ul>
<li><a href="#" aria-current="page" aria-label="Page 1">1</a></li>
<li><a href="#" aria-label="Page 2">2</a></li>
<li><a href="#" aria-label="Page 3">3</a></li>
</ul>
<ul>
<li><a href="#">Next page</a></li>
</ul>
</nav>