DIY — Electronics Platform Landing
A corporate open-hardware landing page for the fictional CIRCUITO platform, built in crisp teal and amber. It pairs a sticky header with a hover mega-menu of board families, a hero split between headline copy and an SVG microcontroller with pulsing pin headers, four hover-reveal ecosystem tiles, a snap-scrolling board carousel whose compare checkboxes feed a docked compare bar, level-badged tutorial cards, a blueprint-grid community band with counters that animate on scroll, and a classroom section with a quote card.
MCP
Code
:root{
--teal:#00979d; --teal-d:#007b80; --teal-l:#3fb6ba;
--ink:#1a2b34; --ink-2:#3b4f59; --muted:#69808b;
--amber:#f5a623; --amber-d:#d98a10;
--mist:#eef6f6; --white:#fff; --bg:#fff;
--line:rgba(26,43,52,.12); --line-2:rgba(26,43,52,.22);
--ok:#2f9e6f; --warn:#d98a2b; --danger:#d4503e;
--r-sm:6px; --r-md:12px; --r-lg:18px;
--sh-1:0 1px 2px rgba(26,43,52,.06), 0 4px 14px rgba(26,43,52,.06);
--sh-2:0 10px 34px rgba(26,43,52,.12);
--wrap:1180px;
}
*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;background:var(--bg);color:var(--ink);
font-family:Inter,system-ui,sans-serif;line-height:1.5;-webkit-font-smoothing:antialiased}
h1,h2,h3,h4{margin:0;line-height:1.15;letter-spacing:-.02em}
p{margin:0}
a{color:inherit;text-decoration:none}
ul{margin:0;padding:0;list-style:none}
img,svg{max-width:100%}
.mono{font-family:"JetBrains Mono",ui-monospace,monospace}
.wrap{width:100%;max-width:var(--wrap);margin:0 auto;padding:0 24px}
:focus-visible{outline:3px solid var(--amber);outline-offset:2px;border-radius:4px}
.skip{position:absolute;left:-999px;top:0;background:var(--ink);color:#fff;padding:10px 16px;z-index:99}
.skip:focus{left:12px;top:12px}
/* buttons */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;
font-weight:600;font-size:.94rem;padding:11px 20px;border-radius:999px;border:2px solid transparent;
cursor:pointer;transition:transform .16s ease,background .16s ease,box-shadow .16s ease,color .16s}
.btn:hover{transform:translateY(-2px)}
.btn:active{transform:translateY(0)}
.btn-lg{padding:15px 28px;font-size:1rem}
.btn-sm{padding:8px 15px;font-size:.85rem}
.btn-amber{background:var(--amber);color:#25190a;box-shadow:0 6px 18px rgba(245,166,35,.34)}
.btn-amber:hover{background:var(--amber-d)}
.btn-teal{background:var(--teal);color:#fff;box-shadow:0 6px 18px rgba(0,151,157,.3)}
.btn-teal:hover{background:var(--teal-d)}
.btn-outline{border-color:var(--teal);color:var(--teal-d);background:#fff}
.btn-outline:hover{background:var(--mist)}
.btn-ghost{color:var(--ink-2)}
.btn-ghost:hover{background:var(--mist);color:var(--teal-d)}
/* header */
.site-header{position:sticky;top:0;z-index:50;background:rgba(255,255,255,.92);
backdrop-filter:blur(12px);border-bottom:1px solid var(--line)}
.header-inner{display:flex;align-items:center;gap:22px;height:72px}
.brand{display:flex;align-items:center;gap:10px;color:var(--teal);flex:0 0 auto}
.brand-mark{width:30px;height:30px}
.brand-word{font-weight:800;letter-spacing:.14em;font-size:1.02rem;color:var(--ink)}
.nav{flex:1;display:flex;justify-content:center}
.nav-list{display:flex;gap:4px}
.nav-item{position:static}
.nav-link{display:inline-flex;align-items:center;gap:6px;background:none;border:0;cursor:pointer;
font:600 .93rem/1 Inter,sans-serif;color:var(--ink-2);padding:10px 14px;border-radius:999px;transition:.16s}
.nav-link:hover,.nav-item.open .nav-link{background:var(--mist);color:var(--teal-d)}
.caret{width:6px;height:6px;border-right:2px solid currentColor;border-bottom:2px solid currentColor;
transform:rotate(45deg) translateY(-2px);transition:transform .2s}
.nav-item.open .caret{transform:rotate(-135deg) translateY(-2px)}
.header-actions{display:flex;align-items:center;gap:8px;flex:0 0 auto}
/* mega */
.mega{position:absolute;left:0;right:0;top:100%;background:#fff;border-bottom:1px solid var(--line);
box-shadow:var(--sh-2);animation:megaIn .18s ease}
@keyframes megaIn{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}
.mega-inner{display:grid;grid-template-columns:repeat(4,1fr);gap:28px;padding-top:26px;padding-bottom:30px}
.mega-title{font-size:.78rem;text-transform:uppercase;letter-spacing:.12em;color:var(--muted);margin-bottom:12px}
.mega-links li+li{margin-top:4px}
.mega-links a{display:block;padding:9px 11px;border-radius:var(--r-md);transition:.15s}
.mega-links a:hover{background:var(--mist)}
.mega-links strong{display:block;font-size:.94rem}
.mega-links span{display:block;font-size:.8rem;color:var(--muted)}
.mega-promo{background:var(--mist);border-radius:var(--r-lg);padding:20px}
.mega-promo p{font-size:.86rem;color:var(--ink-2);margin:8px 0 14px}
.mega-promo .mega-title{margin:10px 0 0;font-size:1rem;text-transform:none;letter-spacing:-.01em;color:var(--ink)}
.mega-cta{font-weight:700;color:var(--teal-d);font-size:.88rem}
.chip{display:inline-block;font:700 .68rem/1 "JetBrains Mono",monospace;letter-spacing:.1em;
padding:5px 9px;border-radius:999px;text-transform:uppercase}
.chip-amber{background:var(--amber);color:#25190a}
.burger{display:none;flex-direction:column;gap:4px;background:none;border:0;padding:10px;cursor:pointer}
.burger span{width:20px;height:2px;background:var(--ink);border-radius:2px}
.mobile-nav{display:none;flex-direction:column;border-top:1px solid var(--line);padding:8px 24px 16px}
.mobile-nav a{padding:12px 0;font-weight:600;border-bottom:1px solid var(--line)}
/* hero */
.hero{padding:70px 0 84px;background:
radial-gradient(900px 420px at 82% 10%,rgba(0,151,157,.12),transparent 62%),
linear-gradient(180deg,#fff 0%,var(--mist) 100%)}
.hero-grid{display:grid;grid-template-columns:1.05fr .95fr;gap:56px;align-items:center}
.eyebrow{display:inline-flex;align-items:center;gap:9px;background:#fff;border:1px solid var(--line);
padding:7px 14px;border-radius:999px;font-size:.79rem;font-weight:600;color:var(--ink-2);box-shadow:var(--sh-1)}
.dot{width:8px;height:8px;border-radius:50%;background:var(--teal);box-shadow:0 0 0 4px rgba(0,151,157,.16)}
.hero h1{font-size:clamp(2.1rem,5vw,3.4rem);font-weight:800;margin:20px 0 16px;max-width:15ch}
.lede{font-size:1.06rem;color:var(--ink-2);max-width:52ch}
.lede-sm{font-size:1rem;color:var(--ink-2);margin:14px 0 20px;max-width:56ch}
.hero-cta{display:flex;gap:12px;flex-wrap:wrap;margin:28px 0 30px}
.hero-facts{display:flex;gap:34px;flex-wrap:wrap;padding-top:24px;border-top:1px solid var(--line)}
.hero-facts b{display:block;font-size:1.3rem;color:var(--teal-d)}
.hero-facts span{font-size:.8rem;color:var(--muted)}
.hero-art{position:relative}
.board-svg{width:100%;filter:drop-shadow(0 22px 40px rgba(0,123,128,.28))}
.chip-label{fill:#eef6f6;font:700 17px "JetBrains Mono",monospace;letter-spacing:.06em}
.chip-sub{fill:rgba(238,246,246,.6);font:400 12px "JetBrains Mono",monospace}
.pins rect{fill:#f5d78a;stroke:#c9922a;stroke-width:1.5}
.pins-top rect{animation:pinPulse 2.8s ease-in-out infinite}
.pins-bottom rect{animation:pinPulse 2.8s ease-in-out infinite;animation-delay:1.4s}
.pins rect:nth-child(2n){animation-delay:.35s}
.pins rect:nth-child(3n){animation-delay:.7s}
@keyframes pinPulse{0%,100%{fill:#f0cf85}50%{fill:#f5a623}}
.led{animation:blink 1.6s steps(1,end) infinite}
@keyframes blink{0%,49%{opacity:1}50%,100%{opacity:.25}}
.hero-tag{position:absolute;right:6%;bottom:-6px;background:var(--ink);color:#dff0f0;
font-size:.72rem;padding:7px 12px;border-radius:999px;letter-spacing:.06em}
/* sections */
.section{padding:82px 0}
.section-mist{background:var(--mist)}
.sec-head{max-width:620px;margin-bottom:38px}
.sec-head-row{display:flex;justify-content:space-between;align-items:flex-end;gap:20px;max-width:none}
.kicker{display:block;font-size:.73rem;letter-spacing:.18em;color:var(--teal-d);font-weight:700;margin-bottom:12px}
.kicker-light{color:var(--teal-l)}
.sec-head h2{font-size:clamp(1.6rem,3.4vw,2.35rem);font-weight:800}
.sec-head p{color:var(--ink-2);margin-top:10px}
/* tiles */
.tiles{display:grid;grid-template-columns:repeat(4,1fr);gap:18px}
.tile{background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);padding:26px 22px;
transition:transform .22s ease,box-shadow .22s ease,border-color .22s}
.tile:hover,.tile:focus{transform:translateY(-6px);box-shadow:var(--sh-2);border-color:rgba(0,151,157,.4)}
.tile-ico{width:34px;height:34px;fill:none;stroke:var(--teal);stroke-width:1.7;
stroke-linecap:round;stroke-linejoin:round;margin-bottom:16px}
.tile h3{font-size:1.16rem;margin-bottom:8px}
.tile p{font-size:.92rem;color:var(--ink-2)}
.tile-more{display:grid;gap:6px;max-height:0;opacity:0;overflow:hidden;
transition:max-height .28s ease,opacity .24s ease,margin .28s}
.tile:hover .tile-more,.tile:focus .tile-more,.tile:focus-within .tile-more{max-height:140px;opacity:1;margin-top:16px}
.tile-more span{font-size:.74rem;color:var(--teal-d);background:var(--mist);
padding:5px 9px;border-radius:var(--r-sm);justify-self:start}
/* carousel */
.carousel{overflow-x:auto;scroll-snap-type:x mandatory;scroll-behavior:smooth;
padding:6px 0 22px;-webkit-overflow-scrolling:touch}
.carousel::-webkit-scrollbar{height:8px}
.carousel::-webkit-scrollbar-thumb{background:rgba(0,151,157,.35);border-radius:999px}
.carousel-track{display:flex;gap:18px;padding:0 max(24px,calc((100vw - var(--wrap))/2 + 24px))}
.carousel-nav{display:flex;gap:8px}
.round{width:42px;height:42px;border-radius:50%;border:1px solid var(--line-2);background:#fff;
font-size:1.35rem;line-height:1;color:var(--ink-2);cursor:pointer;transition:.16s}
.round:hover{background:var(--teal);color:#fff;border-color:var(--teal)}
.card{position:relative;flex:0 0 292px;scroll-snap-align:start;background:#fff;
border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;
transition:transform .22s ease,box-shadow .22s ease}
.card:hover{transform:translateY(-6px);box-shadow:var(--sh-2)}
.card.selected{border-color:var(--teal);box-shadow:0 0 0 3px rgba(0,151,157,.18)}
.card-render{height:150px;display:grid;place-items:center;position:relative;
background:linear-gradient(135deg,var(--teal),var(--teal-d))}
.card-render::before{content:"";position:absolute;inset:16px;border-radius:10px;
border:2px solid rgba(255,255,255,.25);
background:
repeating-linear-gradient(90deg,rgba(255,255,255,.16) 0 3px,transparent 3px 15px),
repeating-linear-gradient(0deg,rgba(255,255,255,.1) 0 3px,transparent 3px 22px)}
.card-render::after{content:"";position:absolute;width:56px;height:40px;border-radius:6px;background:#16262e}
.render-tag{position:relative;z-index:2;color:#eef6f6;font-weight:700;font-size:.82rem;letter-spacing:.1em}
.render-b{background:linear-gradient(135deg,#0d8b91,#065c60)}
.render-c{background:linear-gradient(135deg,#12a3a9,#0a6f73)}
.render-d{background:linear-gradient(135deg,#1a2b34,#0b4b4f)}
.render-e{background:linear-gradient(135deg,#2c4652,#123c44)}
.render-f{background:linear-gradient(135deg,#00979d,#1a2b34)}
.card-body{padding:18px}
.card-top{display:flex;justify-content:space-between;align-items:baseline;gap:10px}
.card-top h3{font-size:1.08rem}
.price{color:var(--teal-d);font-weight:700}
.card-body p{font-size:.88rem;color:var(--ink-2);margin-top:8px;min-height:48px}
.specs{display:flex;gap:6px;flex-wrap:wrap;margin:14px 0}
.specs li{font-size:.7rem;background:var(--mist);color:var(--teal-d);padding:5px 8px;border-radius:var(--r-sm)}
.cmp{display:inline-flex;align-items:center;gap:8px;font-size:.85rem;font-weight:600;
color:var(--ink-2);cursor:pointer;padding:6px 2px}
.cmp input{width:17px;height:17px;accent-color:var(--teal);cursor:pointer}
.ribbon{position:absolute;top:12px;left:12px;z-index:3;background:#fff;color:var(--teal-d);
font:700 .68rem/1 "JetBrains Mono",monospace;letter-spacing:.1em;text-transform:uppercase;
padding:6px 10px;border-radius:999px;box-shadow:var(--sh-1)}
.ribbon-amber{background:var(--amber);color:#25190a}
/* tutorials */
.tut-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
.tut{display:block;background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);
padding:22px;transition:transform .2s ease,box-shadow .2s ease,border-color .2s}
.tut:hover{transform:translateY(-4px);box-shadow:var(--sh-2);border-color:rgba(0,151,157,.4)}
.tut h3{font-size:1.06rem;margin:12px 0 8px}
.tut p{font-size:.9rem;color:var(--ink-2)}
.tut code{font-family:"JetBrains Mono",monospace;font-size:.84em;background:var(--mist);
padding:1px 5px;border-radius:4px;color:var(--teal-d)}
.tut-meta{display:block;margin-top:14px;font-size:.74rem;color:var(--muted)}
.badge{display:inline-block;font:700 .68rem/1 "JetBrains Mono",monospace;letter-spacing:.08em;
text-transform:uppercase;padding:5px 9px;border-radius:999px}
.badge-ok{background:rgba(47,158,111,.14);color:#1f7452}
.badge-warn{background:rgba(217,138,43,.16);color:#95590f}
.badge-hard{background:rgba(212,80,62,.14);color:#a13525}
/* community band */
.band{padding:76px 0;color:#eef6f6;position:relative;
background:
linear-gradient(0deg,rgba(26,43,52,.86),rgba(26,43,52,.86)),
repeating-linear-gradient(90deg,rgba(140,220,220,.1) 0 1px,transparent 1px 8px),
repeating-linear-gradient(0deg,rgba(140,220,220,.1) 0 1px,transparent 1px 8px),
repeating-linear-gradient(90deg,rgba(140,220,220,.2) 0 1px,transparent 1px 80px),
repeating-linear-gradient(0deg,rgba(140,220,220,.2) 0 1px,transparent 1px 80px),
var(--ink)}
.band-title{font-size:clamp(1.6rem,3.4vw,2.3rem);font-weight:800;max-width:20ch}
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:20px;margin-top:40px}
.stat{border-top:2px solid rgba(63,182,186,.5);padding-top:16px}
.stat b{display:block;font-size:clamp(1.6rem,3vw,2.2rem);color:#fff;font-variant-numeric:tabular-nums}
.stat span{font-size:.84rem;color:rgba(238,246,246,.68)}
/* education */
.edu-grid{display:grid;grid-template-columns:1.05fr .95fr;gap:48px;align-items:center}
.edu-list{margin:0 0 26px;display:grid;gap:10px}
.edu-list li{display:flex;gap:10px;align-items:flex-start;font-size:.94rem;color:var(--ink-2)}
.tick{flex:0 0 18px;width:18px;height:18px;border-radius:50%;background:var(--teal);position:relative;margin-top:2px}
.tick::after{content:"";position:absolute;left:6px;top:3px;width:5px;height:9px;
border-right:2px solid #fff;border-bottom:2px solid #fff;transform:rotate(42deg)}
.quote{margin:0;background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);
padding:30px;box-shadow:var(--sh-1);position:relative}
.quote::before{content:"";position:absolute;left:0;top:26px;bottom:26px;width:4px;
background:var(--amber);border-radius:0 4px 4px 0}
.quote blockquote{margin:0;font-size:1.08rem;line-height:1.55;color:var(--ink)}
.quote figcaption{display:flex;align-items:center;gap:12px;margin-top:22px}
.avatar{width:42px;height:42px;border-radius:50%;display:grid;place-items:center;
background:var(--teal);color:#fff;font:700 .82rem/1 "JetBrains Mono",monospace}
.quote figcaption b{display:block;font-size:.92rem}
.quote figcaption small{color:var(--muted);font-size:.8rem}
/* footer */
.site-footer{background:var(--ink);color:#cfe2e3;padding:56px 0 24px}
.footer-grid{display:grid;grid-template-columns:1.6fr repeat(3,1fr);gap:32px}
.brand-footer{color:var(--teal-l);margin-bottom:12px}
.brand-footer .brand-word{color:#fff}
.footer-note{font-size:.86rem;color:rgba(207,226,227,.66);max-width:38ch}
.site-footer h4{font-size:.76rem;letter-spacing:.14em;text-transform:uppercase;
color:rgba(207,226,227,.55);margin-bottom:12px}
.site-footer a{display:block;padding:5px 0;font-size:.9rem;transition:color .15s}
.site-footer a:hover{color:var(--teal-l)}
.footer-bottom{margin-top:38px;padding-top:20px;border-top:1px solid rgba(255,255,255,.12);
font-size:.74rem;color:rgba(207,226,227,.5)}
/* compare bar */
.compare-bar{position:fixed;left:0;right:0;bottom:0;z-index:60;background:#fff;
border-top:1px solid var(--line);box-shadow:0 -10px 30px rgba(26,43,52,.14);
transform:translateY(110%);transition:transform .28s cubic-bezier(.2,.8,.3,1)}
.compare-bar.show{transform:none}
.compare-inner{display:flex;align-items:center;gap:16px;padding-top:14px;padding-bottom:14px;flex-wrap:wrap}
.compare-label{font-size:.7rem;letter-spacing:.16em;color:var(--muted);font-weight:700}
.compare-items{display:flex;gap:8px;flex:1;flex-wrap:wrap}
.pill{display:inline-flex;align-items:center;gap:8px;background:var(--mist);border:1px solid var(--line);
border-radius:999px;padding:7px 8px 7px 14px;font-size:.85rem;font-weight:600}
.pill .px{font-family:"JetBrains Mono",monospace;color:var(--teal-d)}
.pill button{width:22px;height:22px;border-radius:50%;border:0;background:rgba(26,43,52,.1);
cursor:pointer;line-height:1;font-size:.9rem;color:var(--ink-2)}
.pill button:hover{background:var(--danger);color:#fff}
.compare-actions{display:flex;gap:8px}
/* toasts */
.toast-wrap{position:fixed;right:18px;bottom:100px;z-index:80;display:grid;gap:8px;justify-items:end}
.toast{background:var(--ink);color:#eef6f6;padding:11px 16px;border-radius:var(--r-md);
font-size:.87rem;box-shadow:var(--sh-2);animation:tIn .22s ease}
.toast.out{animation:tOut .25s ease forwards}
@keyframes tIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@keyframes tOut{to{opacity:0;transform:translateY(10px)}}
/* reveal */
.reveal{opacity:0;transform:translateY(18px)}
.reveal.in{opacity:1;transform:none;transition:opacity .55s ease,transform .55s cubic-bezier(.2,.8,.3,1)}
@media (max-width:1040px){
.tiles,.tut-grid{grid-template-columns:repeat(2,1fr)}
.stats{grid-template-columns:repeat(2,1fr)}
.hero-grid,.edu-grid{grid-template-columns:1fr;gap:40px}
.nav{display:none}
.burger{display:flex}
.mega-inner{grid-template-columns:repeat(2,1fr)}
.footer-grid{grid-template-columns:repeat(2,1fr)}
body.nav-open .mobile-nav{display:flex}
}
@media (max-width:520px){
.wrap{padding:0 16px}
.hero{padding:44px 0 56px}
.section{padding:56px 0}
.sec-head-row{flex-direction:column;align-items:flex-start}
.carousel-nav{display:none}
.tiles,.tut-grid,.stats,.footer-grid{grid-template-columns:1fr}
.card{flex:0 0 82vw}
.carousel-track{padding:0 16px}
.hero-facts{gap:20px}
.hero-tag{right:0}
.btn-lg{width:100%}
.hero-cta{flex-direction:column;align-items:stretch}
.compare-inner{gap:10px}
.compare-actions{width:100%}
.compare-actions .btn{flex:1}
.toast-wrap{right:12px;left:12px;justify-items:stretch;bottom:130px}
}
@media (prefers-reduced-motion:reduce){
*{animation:none!important;transition:none!important;scroll-behavior:auto!important}
.reveal{opacity:1;transform:none}
}(function () {
"use strict";
/* ---------- toast ---------- */
var toasts = document.getElementById("toasts");
function toast(msg) {
if (!toasts) return;
var el = document.createElement("div");
el.className = "toast";
el.textContent = msg;
toasts.appendChild(el);
setTimeout(function () {
el.classList.add("out");
setTimeout(function () { el.remove(); }, 260);
}, 2400);
}
/* ---------- mega menu (hover + keyboard) ---------- */
var megaItems = document.querySelectorAll(".nav-item.has-mega");
megaItems.forEach(function (item) {
var btn = item.querySelector(".nav-link");
var panel = document.getElementById(btn.getAttribute("data-mega"));
var closeTimer;
function open() {
clearTimeout(closeTimer);
panel.hidden = false;
item.classList.add("open");
btn.setAttribute("aria-expanded", "true");
}
function close(delay) {
clearTimeout(closeTimer);
closeTimer = setTimeout(function () {
panel.hidden = true;
item.classList.remove("open");
btn.setAttribute("aria-expanded", "false");
}, delay || 0);
}
item.addEventListener("mouseenter", open);
item.addEventListener("mouseleave", function () { close(140); });
panel.addEventListener("mouseenter", open);
panel.addEventListener("mouseleave", function () { close(140); });
btn.addEventListener("click", function () {
panel.hidden ? open() : close(0);
});
item.addEventListener("focusin", open);
document.addEventListener("keydown", function (e) {
if (e.key === "Escape" && !panel.hidden) { close(0); btn.focus(); }
});
document.addEventListener("click", function (e) {
if (!item.contains(e.target) && !panel.contains(e.target)) close(0);
});
});
/* ---------- mobile nav ---------- */
var burger = document.querySelector(".burger");
var mobileNav = document.getElementById("mobile-nav");
if (burger) {
burger.addEventListener("click", function () {
var open = document.body.classList.toggle("nav-open");
burger.setAttribute("aria-expanded", String(open));
mobileNav.hidden = !open;
});
mobileNav.querySelectorAll("a").forEach(function (a) {
a.addEventListener("click", function () {
document.body.classList.remove("nav-open");
burger.setAttribute("aria-expanded", "false");
mobileNav.hidden = true;
});
});
}
/* ---------- carousel ---------- */
var carousel = document.getElementById("carousel");
document.querySelectorAll("[data-scroll]").forEach(function (btn) {
btn.addEventListener("click", function () {
var dir = Number(btn.getAttribute("data-scroll"));
var card = carousel.querySelector(".card");
var step = card ? card.getBoundingClientRect().width + 18 : 300;
carousel.scrollBy({ left: dir * step * 2, behavior: "smooth" });
});
});
if (carousel) {
carousel.addEventListener("keydown", function (e) {
if (e.key === "ArrowRight") { carousel.scrollBy({ left: 300, behavior: "smooth" }); e.preventDefault(); }
if (e.key === "ArrowLeft") { carousel.scrollBy({ left: -300, behavior: "smooth" }); e.preventDefault(); }
});
}
/* ---------- compare ---------- */
var MAX = 3;
var bar = document.getElementById("compareBar");
var itemsWrap = document.getElementById("compareItems");
var selected = [];
function findCard(name) {
return Array.prototype.find.call(
document.querySelectorAll(".card"),
function (c) { return c.getAttribute("data-board") === name; }
);
}
function render() {
itemsWrap.innerHTML = "";
selected.forEach(function (item) {
var pill = document.createElement("span");
pill.className = "pill";
pill.innerHTML =
'<span>' + item.name + '</span><span class="px">$' + item.price + '</span>';
var x = document.createElement("button");
x.type = "button";
x.setAttribute("aria-label", "Remove " + item.name + " from compare");
x.textContent = "×";
x.addEventListener("click", function () { remove(item.name); });
pill.appendChild(x);
itemsWrap.appendChild(pill);
});
if (selected.length) {
bar.hidden = false;
requestAnimationFrame(function () { bar.classList.add("show"); });
} else {
bar.classList.remove("show");
setTimeout(function () { if (!selected.length) bar.hidden = true; }, 300);
}
}
function remove(name) {
selected = selected.filter(function (s) { return s.name !== name; });
var card = findCard(name);
if (card) {
card.classList.remove("selected");
card.querySelector(".cmp-box").checked = false;
}
render();
}
document.querySelectorAll(".card").forEach(function (card) {
var box = card.querySelector(".cmp-box");
var name = card.getAttribute("data-board");
var price = card.getAttribute("data-price");
box.addEventListener("change", function () {
if (box.checked) {
if (selected.length >= MAX) {
box.checked = false;
toast("Compare up to " + MAX + " boards at a time.");
return;
}
selected.push({ name: name, price: price });
card.classList.add("selected");
} else {
selected = selected.filter(function (s) { return s.name !== name; });
card.classList.remove("selected");
}
render();
});
});
var clearBtn = document.getElementById("clearCompare");
if (clearBtn) clearBtn.addEventListener("click", function () {
selected.slice().forEach(function (s) { remove(s.name); });
toast("Compare list cleared.");
});
var doBtn = document.getElementById("doCompare");
if (doBtn) doBtn.addEventListener("click", function () {
if (selected.length < 2) { toast("Pick at least two boards to compare."); return; }
toast("Comparing " + selected.map(function (s) { return s.name; }).join(" vs ") + ".");
});
/* ---------- animated counters ---------- */
function format(n, suffix) {
if (n >= 1000000) return (n / 1000000).toFixed(2).replace(/\.?0+$/, "") + "M" + suffix;
if (n >= 10000) return Math.round(n / 1000) + "k" + suffix;
return n.toLocaleString("en-US") + suffix;
}
function countUp(el) {
var target = Number(el.getAttribute("data-count"));
var suffix = el.getAttribute("data-suffix") || "";
var dur = 1500, start = performance.now();
function tick(now) {
var p = Math.min(1, (now - start) / dur);
var eased = 1 - Math.pow(1 - p, 3);
el.textContent = format(Math.round(target * eased), suffix);
if (p < 1) requestAnimationFrame(tick);
}
requestAnimationFrame(tick);
}
/* ---------- reveal + counters via IntersectionObserver ---------- */
var revealTargets = document.querySelectorAll(
".tile, .card, .tut, .sec-head, .quote, .edu-grid > div, .stat"
);
revealTargets.forEach(function (el, i) {
el.classList.add("reveal");
el.style.transitionDelay = (i % 6) * 60 + "ms";
});
if ("IntersectionObserver" in window) {
var io = new IntersectionObserver(function (entries) {
entries.forEach(function (e) {
if (!e.isIntersecting) return;
e.target.classList.add("in");
var num = e.target.querySelector && e.target.querySelector("[data-count]");
if (num && !num.dataset.done) { num.dataset.done = "1"; countUp(num); }
io.unobserve(e.target);
});
}, { threshold: 0.18, rootMargin: "0px 0px -40px 0px" });
revealTargets.forEach(function (el) { io.observe(el); });
} else {
revealTargets.forEach(function (el) { el.classList.add("in"); });
document.querySelectorAll("[data-count]").forEach(countUp);
}
/* ---------- CTA feedback ---------- */
document.querySelectorAll(".btn-amber, .btn-teal").forEach(function (b) {
if (b.id === "doCompare") return;
b.addEventListener("click", function (e) {
if (b.getAttribute("href") && b.getAttribute("href").charAt(0) === "#") return;
e.preventDefault();
toast("Demo interface — nothing was submitted.");
});
});
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>CIRCUITO — Open Hardware Platform</title>
<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=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;600;700&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<a class="skip" href="#main">Skip to content</a>
<header class="site-header">
<div class="wrap header-inner">
<a class="brand" href="#main" aria-label="CIRCUITO home">
<svg class="brand-mark" viewBox="0 0 40 40" aria-hidden="true">
<circle cx="20" cy="20" r="18" fill="none" stroke="currentColor" stroke-width="3"/>
<path d="M9 20h6M25 20h6" stroke="currentColor" stroke-width="3" stroke-linecap="round"/>
<circle cx="20" cy="20" r="6" fill="none" stroke="currentColor" stroke-width="3"/>
<path d="M20 14v-4M20 30v-4" stroke="currentColor" stroke-width="3" stroke-linecap="round"/>
</svg>
<span class="brand-word">CIRCUITO</span>
</a>
<nav class="nav" aria-label="Main">
<ul class="nav-list">
<li class="nav-item has-mega">
<button class="nav-link" type="button" aria-expanded="false" aria-controls="mega-hardware" data-mega="mega-hardware">
Hardware <span class="caret" aria-hidden="true"></span>
</button>
<div class="mega" id="mega-hardware" hidden>
<div class="wrap mega-inner">
<div class="mega-col">
<h3 class="mega-title">Entry boards</h3>
<ul class="mega-links">
<li><a href="#boards"><strong>Nano C1</strong><span>8-bit, 20 GPIO, breadboard-ready</span></a></li>
<li><a href="#boards"><strong>Uno C3</strong><span>Classic footprint, shield compatible</span></a></li>
<li><a href="#boards"><strong>Micro C0</strong><span>USB-HID native, thumb sized</span></a></li>
</ul>
</div>
<div class="mega-col">
<h3 class="mega-title">Connected</h3>
<ul class="mega-links">
<li><a href="#boards"><strong>Vela W2</strong><span>Wi-Fi 6 + BLE 5.3 dual radio</span></a></li>
<li><a href="#boards"><strong>Vela LoRa</strong><span>Sub-GHz mesh, 10 km line of sight</span></a></li>
<li><a href="#boards"><strong>Portal Gate</strong><span>Ethernet + PoE field gateway</span></a></li>
</ul>
</div>
<div class="mega-col">
<h3 class="mega-title">Pro & industrial</h3>
<ul class="mega-links">
<li><a href="#boards"><strong>Forge M7</strong><span>Dual-core 480 MHz, ML ready</span></a></li>
<li><a href="#boards"><strong>Rail PLC-8</strong><span>DIN rail, 24 V I/O, -25→70 °C</span></a></li>
<li><a href="#boards"><strong>Shield Bay</strong><span>Sensor & motor expansion carriers</span></a></li>
</ul>
</div>
<div class="mega-col mega-promo">
<span class="chip chip-amber">New</span>
<h3 class="mega-title">Forge M7 Starter Lab</h3>
<p>Board, carrier, 12 sensors and 40 guided projects in one box.</p>
<a class="mega-cta" href="#boards">See the kit →</a>
</div>
</div>
</div>
</li>
<li class="nav-item"><a class="nav-link" href="#ecosystem">Software</a></li>
<li class="nav-item"><a class="nav-link" href="#ecosystem">Cloud</a></li>
<li class="nav-item"><a class="nav-link" href="#tutorials">Docs</a></li>
<li class="nav-item"><a class="nav-link" href="#community">Community</a></li>
</ul>
</nav>
<div class="header-actions">
<a class="btn btn-ghost" href="#boards">Sign in</a>
<a class="btn btn-amber" href="#ecosystem">Get started</a>
<button class="burger" type="button" aria-expanded="false" aria-controls="mobile-nav" aria-label="Open menu">
<span></span><span></span><span></span>
</button>
</div>
</div>
<nav class="mobile-nav" id="mobile-nav" aria-label="Mobile" hidden>
<a href="#boards">Hardware</a>
<a href="#ecosystem">Software</a>
<a href="#ecosystem">Cloud</a>
<a href="#tutorials">Docs</a>
<a href="#community">Community</a>
</nav>
</header>
<main id="main">
<!-- HERO -->
<section class="hero">
<div class="wrap hero-grid">
<div class="hero-copy">
<span class="eyebrow"><span class="dot" aria-hidden="true"></span> Open source hardware · since 2011</span>
<h1>Build the thing you keep sketching in the margins.</h1>
<p class="lede">CIRCUITO is an open platform of boards, editors and cloud services. Flash your first sketch in four minutes, then scale the same code from a breadboard to a field gateway.</p>
<div class="hero-cta">
<a class="btn btn-amber btn-lg" href="#ecosystem">Get started free</a>
<a class="btn btn-outline btn-lg" href="#boards">Browse boards</a>
</div>
<ul class="hero-facts">
<li><b class="mono">4 min</b><span>First blink</span></li>
<li><b class="mono">2,400+</b><span>Libraries</span></li>
<li><b class="mono">MIT</b><span>Schematics</span></li>
</ul>
</div>
<div class="hero-art" aria-hidden="true">
<svg class="board-svg" viewBox="0 0 420 300" role="img">
<defs>
<linearGradient id="pcb" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#00979d"/><stop offset="1" stop-color="#007b80"/>
</linearGradient>
<linearGradient id="chip" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#2c4652"/><stop offset="1" stop-color="#16262e"/>
</linearGradient>
</defs>
<rect x="24" y="30" width="372" height="240" rx="20" fill="url(#pcb)"/>
<rect x="34" y="40" width="352" height="220" rx="14" fill="none" stroke="rgba(255,255,255,.18)" stroke-width="2"/>
<g stroke="rgba(255,255,255,.22)" stroke-width="2" fill="none">
<path d="M70 96h58v40h72"/><path d="M300 110h44v52h-40"/>
<path d="M96 210h120v-28h74"/><path d="M150 60v34h60"/>
</g>
<g class="pins pins-top">
<rect x="70" y="46" width="14" height="14" rx="3"/><rect x="92" y="46" width="14" height="14" rx="3"/>
<rect x="114" y="46" width="14" height="14" rx="3"/><rect x="136" y="46" width="14" height="14" rx="3"/>
<rect x="158" y="46" width="14" height="14" rx="3"/><rect x="180" y="46" width="14" height="14" rx="3"/>
<rect x="202" y="46" width="14" height="14" rx="3"/><rect x="224" y="46" width="14" height="14" rx="3"/>
<rect x="246" y="46" width="14" height="14" rx="3"/><rect x="268" y="46" width="14" height="14" rx="3"/>
<rect x="290" y="46" width="14" height="14" rx="3"/><rect x="312" y="46" width="14" height="14" rx="3"/>
</g>
<g class="pins pins-bottom">
<rect x="70" y="240" width="14" height="14" rx="3"/><rect x="92" y="240" width="14" height="14" rx="3"/>
<rect x="114" y="240" width="14" height="14" rx="3"/><rect x="136" y="240" width="14" height="14" rx="3"/>
<rect x="158" y="240" width="14" height="14" rx="3"/><rect x="180" y="240" width="14" height="14" rx="3"/>
<rect x="202" y="240" width="14" height="14" rx="3"/><rect x="224" y="240" width="14" height="14" rx="3"/>
<rect x="246" y="240" width="14" height="14" rx="3"/><rect x="268" y="240" width="14" height="14" rx="3"/>
<rect x="290" y="240" width="14" height="14" rx="3"/><rect x="312" y="240" width="14" height="14" rx="3"/>
</g>
<rect x="150" y="112" width="110" height="86" rx="8" fill="url(#chip)"/>
<text x="205" y="150" text-anchor="middle" class="chip-label">CRT-M7</text>
<text x="205" y="172" text-anchor="middle" class="chip-sub">480 MHz</text>
<rect x="52" y="120" width="34" height="52" rx="6" fill="#16262e"/>
<rect x="330" y="118" width="46" height="40" rx="6" fill="#0f4f52"/>
<circle cx="300" cy="212" r="8" fill="#f5a623" class="led"/>
<circle cx="326" cy="212" r="8" fill="#eef6f6" opacity=".65"/>
<circle cx="60" cy="60" r="7" fill="none" stroke="rgba(255,255,255,.35)" stroke-width="3"/>
<circle cx="360" cy="240" r="7" fill="none" stroke="rgba(255,255,255,.35)" stroke-width="3"/>
</svg>
<div class="hero-tag mono">rev D · open schematics</div>
</div>
</div>
</section>
<!-- ECOSYSTEM -->
<section class="section" id="ecosystem">
<div class="wrap">
<header class="sec-head">
<span class="kicker mono">01 — ECOSYSTEM</span>
<h2>Four pieces, one workflow</h2>
<p>Every layer is documented, versioned and replaceable. Use all four, or bring your own.</p>
</header>
<div class="tiles">
<article class="tile" tabindex="0">
<svg class="tile-ico" viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="3" width="18" height="18" rx="4"/><rect x="8" y="8" width="8" height="8" rx="2"/><path d="M12 1v2M12 21v2M1 12h2M21 12h2"/></svg>
<h3>Boards</h3>
<p>Nine families from 8-bit trainers to industrial DIN-rail controllers.</p>
<div class="tile-more"><span class="mono">9 families</span><span class="mono">CERN-OHL-S</span><span class="mono">EAGLE + KiCad files</span></div>
</article>
<article class="tile" tabindex="0">
<svg class="tile-ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M8 6l-5 6 5 6M16 6l5 6-5 6M13 4l-2 16"/></svg>
<h3>IDE</h3>
<p>Desktop and browser editors sharing one compiler and one library index.</p>
<div class="tile-more"><span class="mono">macOS · Win · Linux</span><span class="mono">LSP autocomplete</span><span class="mono">Serial plotter</span></div>
</article>
<article class="tile" tabindex="0">
<svg class="tile-ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M6 18a4 4 0 010-8 6 6 0 0111.3-1.6A4.5 4.5 0 0118 18z"/><path d="M12 12v5M9.5 14.5L12 12l2.5 2.5"/></svg>
<h3>Cloud</h3>
<p>Device fleets, dashboards and over-the-air updates with signed images.</p>
<div class="tile-more"><span class="mono">OTA rollbacks</span><span class="mono">MQTT + HTTPS</span><span class="mono">Webhooks</span></div>
</article>
<article class="tile" tabindex="0">
<svg class="tile-ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M4 5.5A2.5 2.5 0 016.5 3H12v18H6.5A2.5 2.5 0 014 18.5z"/><path d="M20 5.5A2.5 2.5 0 0017.5 3H12v18h5.5a2.5 2.5 0 002.5-2.5z"/></svg>
<h3>Learn</h3>
<p>640 guided projects, classroom tracks and a certification path.</p>
<div class="tile-more"><span class="mono">640 projects</span><span class="mono">12 languages</span><span class="mono">Teacher packs</span></div>
</article>
</div>
</div>
</section>
<!-- BOARDS -->
<section class="section section-mist" id="boards">
<div class="wrap">
<header class="sec-head sec-head-row">
<div>
<span class="kicker mono">02 — LINE-UP</span>
<h2>Pick your board</h2>
<p>Tick up to three to compare specs side by side.</p>
</div>
<div class="carousel-nav">
<button class="round" type="button" data-scroll="-1" aria-label="Previous boards">‹</button>
<button class="round" type="button" data-scroll="1" aria-label="Next boards">›</button>
</div>
</header>
</div>
<div class="carousel" id="carousel" tabindex="0" aria-label="Board line-up carousel">
<div class="carousel-track">
<article class="card" data-board="Nano C1" data-price="21">
<div class="card-render render-a" aria-hidden="true"><span class="mono render-tag">C1</span></div>
<div class="card-body">
<div class="card-top"><h3>Nano C1</h3><span class="price mono">$21</span></div>
<p>Breadboard trainer with a forgiving 5 V bus and a real USB-C port.</p>
<ul class="specs mono"><li>16 MHz</li><li>32 KB</li><li>20 GPIO</li></ul>
<label class="cmp"><input type="checkbox" class="cmp-box" /> <span>Compare</span></label>
</div>
</article>
<article class="card" data-board="Uno C3" data-price="27">
<div class="card-render render-b" aria-hidden="true"><span class="mono render-tag">C3</span></div>
<div class="card-body">
<div class="card-top"><h3>Uno C3</h3><span class="price mono">$27</span></div>
<p>The classic footprint. Every shield made in the last decade still fits.</p>
<ul class="specs mono"><li>48 MHz</li><li>256 KB</li><li>22 GPIO</li></ul>
<label class="cmp"><input type="checkbox" class="cmp-box" /> <span>Compare</span></label>
</div>
</article>
<article class="card" data-board="Vela W2" data-price="39">
<span class="ribbon">Popular</span>
<div class="card-render render-c" aria-hidden="true"><span class="mono render-tag">W2</span></div>
<div class="card-body">
<div class="card-top"><h3>Vela W2</h3><span class="price mono">$39</span></div>
<p>Dual radio, secure element and cloud provisioning out of the box.</p>
<ul class="specs mono"><li>240 MHz</li><li>8 MB</li><li>26 GPIO</li></ul>
<label class="cmp"><input type="checkbox" class="cmp-box" /> <span>Compare</span></label>
</div>
</article>
<article class="card" data-board="Forge M7" data-price="72">
<span class="ribbon ribbon-amber">New</span>
<div class="card-render render-d" aria-hidden="true"><span class="mono render-tag">M7</span></div>
<div class="card-body">
<div class="card-top"><h3>Forge M7</h3><span class="price mono">$72</span></div>
<p>Dual-core Cortex-class silicon with a vector unit for on-device ML.</p>
<ul class="specs mono"><li>480 MHz</li><li>16 MB</li><li>76 GPIO</li></ul>
<label class="cmp"><input type="checkbox" class="cmp-box" /> <span>Compare</span></label>
</div>
</article>
<article class="card" data-board="Rail PLC-8" data-price="118">
<div class="card-render render-e" aria-hidden="true"><span class="mono render-tag">P8</span></div>
<div class="card-body">
<div class="card-top"><h3>Rail PLC-8</h3><span class="price mono">$118</span></div>
<p>DIN-rail controller with opto-isolated 24 V inputs and relay outputs.</p>
<ul class="specs mono"><li>200 MHz</li><li>2 MB</li><li>8 I/O</li></ul>
<label class="cmp"><input type="checkbox" class="cmp-box" /> <span>Compare</span></label>
</div>
</article>
<article class="card" data-board="Vela LoRa" data-price="46">
<div class="card-render render-f" aria-hidden="true"><span class="mono render-tag">LR</span></div>
<div class="card-body">
<div class="card-top"><h3>Vela LoRa</h3><span class="price mono">$46</span></div>
<p>Sub-GHz mesh node that runs three seasons on a pair of AA cells.</p>
<ul class="specs mono"><li>64 MHz</li><li>1 MB</li><li>18 GPIO</li></ul>
<label class="cmp"><input type="checkbox" class="cmp-box" /> <span>Compare</span></label>
</div>
</article>
</div>
</div>
</section>
<!-- TUTORIALS -->
<section class="section" id="tutorials">
<div class="wrap">
<header class="sec-head">
<span class="kicker mono">03 — TUTORIALS</span>
<h2>Start with a working sketch</h2>
<p>Each guide ships with wiring diagram, bill of materials and a test harness.</p>
</header>
<div class="tut-grid">
<a class="tut" href="#tutorials">
<span class="badge badge-ok">Beginner</span>
<h3>Blink, but properly</h3>
<p>Replace <code>delay()</code> with a millis scheduler and never block a loop again.</p>
<span class="tut-meta mono">12 min · Nano C1</span>
</a>
<a class="tut" href="#tutorials">
<span class="badge badge-ok">Beginner</span>
<h3>Read a soil moisture probe</h3>
<p>Analog calibration, averaging windows and a two-colour status LED.</p>
<span class="tut-meta mono">18 min · Uno C3</span>
</a>
<a class="tut" href="#tutorials">
<span class="badge badge-warn">Intermediate</span>
<h3>Wi-Fi provisioning over BLE</h3>
<p>Hand credentials to a headless node from a phone, no hardcoded SSID.</p>
<span class="tut-meta mono">35 min · Vela W2</span>
</a>
<a class="tut" href="#tutorials">
<span class="badge badge-warn">Intermediate</span>
<h3>Signed OTA updates</h3>
<p>Sign, stage and roll back firmware images with an A/B partition scheme.</p>
<span class="tut-meta mono">42 min · Vela W2</span>
</a>
<a class="tut" href="#tutorials">
<span class="badge badge-hard">Advanced</span>
<h3>Keyword spotting on the edge</h3>
<p>Quantise a small model and run inference in 190 KB of RAM.</p>
<span class="tut-meta mono">70 min · Forge M7</span>
</a>
<a class="tut" href="#tutorials">
<span class="badge badge-hard">Advanced</span>
<h3>Modbus RTU on a factory line</h3>
<p>Termination, bias resistors and a watchdog that survives a brownout.</p>
<span class="tut-meta mono">55 min · Rail PLC-8</span>
</a>
</div>
</div>
</section>
<!-- COMMUNITY -->
<section class="band" id="community">
<div class="wrap">
<span class="kicker kicker-light mono">04 — COMMUNITY</span>
<h2 class="band-title">Made by people who share their mistakes</h2>
<div class="stats" id="stats">
<div class="stat"><b class="mono" data-count="1840000" data-suffix="+">0</b><span>Registered makers</span></div>
<div class="stat"><b class="mono" data-count="2412" data-suffix="">0</b><span>Published libraries</span></div>
<div class="stat"><b class="mono" data-count="640" data-suffix="">0</b><span>Guided projects</span></div>
<div class="stat"><b class="mono" data-count="93" data-suffix="%">0</b><span>Questions answered < 24 h</span></div>
</div>
</div>
</section>
<!-- EDUCATION -->
<section class="section section-mist" id="education">
<div class="wrap edu-grid">
<div>
<span class="kicker mono">05 — CLASSROOM</span>
<h2>A curriculum that survives 28 teenagers</h2>
<p class="lede-sm">Classroom kits ship with spare parts, printed wiring cards and a teacher console that shows every bench's compile status in one grid. Lesson plans map to national curricula in nine countries.</p>
<ul class="edu-list">
<li><span class="tick" aria-hidden="true"></span> 30-seat kits with lifetime part replacements</li>
<li><span class="tick" aria-hidden="true"></span> Offline IDE bundle for locked-down school networks</li>
<li><span class="tick" aria-hidden="true"></span> Assessment rubrics and printable wiring cards</li>
</ul>
<a class="btn btn-teal" href="#education">Request a school quote</a>
</div>
<figure class="quote">
<blockquote>“The kits arrived on a Monday and by Friday a group that had never soldered was debugging their own I²C bus. The spare-parts drawer is the feature nobody advertises and everybody needs.”</blockquote>
<figcaption>
<span class="avatar" aria-hidden="true">MO</span>
<span><b>Marta Oyelaran</b><small>Technology lead · Fernbank Secondary</small></span>
</figcaption>
</figure>
</div>
</section>
</main>
<footer class="site-footer">
<div class="wrap footer-grid">
<div>
<div class="brand brand-footer"><svg class="brand-mark" viewBox="0 0 40 40" aria-hidden="true"><circle cx="20" cy="20" r="18" fill="none" stroke="currentColor" stroke-width="3"/><circle cx="20" cy="20" r="6" fill="none" stroke="currentColor" stroke-width="3"/><path d="M9 20h6M25 20h6M20 14v-4M20 30v-4" stroke="currentColor" stroke-width="3" stroke-linecap="round"/></svg><span class="brand-word">CIRCUITO</span></div>
<p class="footer-note">Open hardware, open docs, open bill of materials. A fictional platform built as a UI demo.</p>
</div>
<div><h4>Hardware</h4><a href="#boards">Boards</a><a href="#boards">Shields</a><a href="#boards">Kits</a></div>
<div><h4>Software</h4><a href="#ecosystem">Desktop IDE</a><a href="#ecosystem">Web editor</a><a href="#ecosystem">CLI</a></div>
<div><h4>Resources</h4><a href="#tutorials">Tutorials</a><a href="#tutorials">Reference</a><a href="#community">Forum</a></div>
</div>
<div class="wrap footer-bottom mono">© 2026 CIRCUITO — fictional brand · demo interface</div>
</footer>
<!-- COMPARE BAR -->
<div class="compare-bar" id="compareBar" hidden aria-live="polite">
<div class="wrap compare-inner">
<span class="compare-label mono">COMPARE</span>
<div class="compare-items" id="compareItems"></div>
<div class="compare-actions">
<button class="btn btn-ghost btn-sm" type="button" id="clearCompare">Clear</button>
<button class="btn btn-amber btn-sm" type="button" id="doCompare">Compare</button>
</div>
</div>
</div>
<div class="toast-wrap" id="toasts" aria-live="polite" aria-atomic="true"></div>
<script src="script.js"></script>
</body>
</html>Electronics Platform Landing
CIRCUITO is a fictional open-hardware platform, and this page is its front door. The sticky header carries a wordmark, a five-item nav and a full-width mega-menu that drops on hover (and on click or keyboard focus) to list three board families plus a promoted starter kit. Below it, the hero splits into headline copy with dual CTAs on the left and a hand-drawn SVG board on the right — gold pin headers pulse on staggered delays, and a single amber LED blinks on a steps() timing function.
The line-up is a horizontal snap carousel of six board cards, each with a CSS-drawn PCB render, a price, mono spec chips for clock, flash and GPIO, and a compare checkbox. Ticking a box slides a compare bar up from the bottom of the viewport with a removable pill per board; the limit is three, and exceeding it fires a toast instead of silently failing. Arrow buttons and left/right keys scroll the track by two cards at a time.
Around that sit four ecosystem tiles that expand a row of mono detail chips on hover or focus, six tutorial cards with beginner/intermediate/advanced badges, a dark community band whose four counters count up with a cubic ease when they scroll into view, and a classroom section with a checklist and an amber-ruled testimonial card.
How this look is built
The information architecture is in the spirit of corporate open-hardware sites like Arduino’s, but
everything here is original. Modern CSS carries most of it: position: sticky for the header,
CSS grid for every section band, scroll-snap-type: x mandatory plus scroll-padding on the track
so the carousel needs no JS layout math, and layered repeating-linear-gradient for the blueprint
grid on the community band instead of a tiled background image. Tile detail rows animate open with a
max-height + opacity transition driven purely by :hover/:focus-within, so they stay usable by
keyboard with zero script. JS only handles what CSS cannot: an IntersectionObserver drives both the
reveal transitions and the counter animations one time each, which beats the old scroll-listener
approach because it never runs on the main thread during scroll and unobserves as soon as an element
has fired.
Illustrative UI only — always follow real safety guidance when working with tools, electronics, or repairs.