mirror of
https://github.com/Nexoniarz/Niveus.git
synced 2026-11-02 20:24:26 +00:00
Selection markers, tab panels, brand changes and theme changes no longer use a view transition. The page snapshot could not blur what sits behind frosted glass, so every frosted surface went clear for the length of the change. nv.transition now measures the marker before and after, and animates the marker itself (FLIP); arriving content animates on its own; colours fade on their own surfaces. Verified in Firefox: no view transition is ever started. Time picker: wheels take every pointer type (mouse, pen, touch) with touch-action: none, so a phone, a browser's phone mode and a desktop behave alike. The rubber-band is capped at about 40% of a row (a whole row made the neighbour look selected). Each wheel has its own frame slot, so one wheel can no longer swallow another's last scroll event. Switching 24H / AM / PM happens when the wheel settles, and the hours animate into the new layout. Carousel arrows are frosted glass, as anything floating over content should be. At phone width the top bar keeps to one row and its link list scrolls. GUIDELINES.md records the new cross-engine rules. check.py, build.py and build.py --check pass. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
523 lines
30 KiB
HTML
523 lines
30 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>Northwire — an IT shop built with Niveus</title>
|
||
|
||
<link rel="stylesheet" href="../../dist/niveus.css">
|
||
<script src="../../niveus/niveus.js" defer></script>
|
||
<link rel="stylesheet" href="app.css">
|
||
|
||
<script>
|
||
try {
|
||
var saved = localStorage.getItem("northwire-theme");
|
||
if (saved && saved !== "system") document.documentElement.setAttribute("data-theme", saved);
|
||
} catch (error) {}
|
||
</script>
|
||
|
||
<!-- A shop, not an AI product. One declaration is the whole difference. -->
|
||
<style>
|
||
:root { --nv-brand: #ea580c; }
|
||
</style>
|
||
</head>
|
||
|
||
<body>
|
||
|
||
<nav class="nv-nav" id="topnav" aria-label="Main" style="--nv-selection-name: nv-shop-nav">
|
||
<a class="nv-nav__brand" href="#top">
|
||
<svg class="nv-nav__icon" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
||
<path d="M4 7h16l-1.5 12h-13z" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round"/>
|
||
<path d="M9 7V5.5a3 3 0 016 0V7" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/>
|
||
</svg>
|
||
Northwire
|
||
</a>
|
||
|
||
<div class="nv-input-group search">
|
||
<span class="nv-input-group__affix">
|
||
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true" style="inline-size: 1em; block-size: 1em">
|
||
<circle cx="11" cy="11" r="6.5" stroke="currentColor" stroke-width="2"/>
|
||
<path d="M16 16l4 4" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||
</svg>
|
||
</span>
|
||
<label class="nv-visually-hidden" for="search">Search products</label>
|
||
<input class="nv-input nv-input--sm" id="search" type="search" placeholder="Search 4,200 products…">
|
||
</div>
|
||
|
||
<span class="nv-nav__spacer"></span>
|
||
|
||
<div class="nv-button-group" role="group" aria-label="Appearance">
|
||
<button class="nv-button nv-button--sm" data-nv-theme="light" aria-pressed="false">Light</button>
|
||
<button class="nv-button nv-button--sm" data-nv-theme="dark" aria-pressed="false">Dark</button>
|
||
<button class="nv-button nv-button--sm" data-nv-theme="system" aria-pressed="true">Auto</button>
|
||
</div>
|
||
|
||
<button class="nv-button nv-button--sm nv-button--primary" data-nv-dialog="basket">
|
||
<svg class="nv-button__icon" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
||
<path d="M4 7h16l-1.5 12h-13z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/>
|
||
</svg>
|
||
Basket
|
||
<span class="nv-badge nv-badge--count nv-badge--solid" id="basket-count">3</span>
|
||
</button>
|
||
</nav>
|
||
|
||
<main id="top">
|
||
|
||
<section class="shell section">
|
||
<div class="nv-bed nv-bed--single">
|
||
<div class="nv-cluster nv-cluster--between">
|
||
<div style="max-inline-size: var(--nv-measure)">
|
||
<span class="nv-overline">Clearance</span>
|
||
<h1 class="nv-heading" style="margin-block: var(--nv-space-2)">
|
||
Ex-demo workstations, checked and warrantied.
|
||
</h1>
|
||
<p class="nv-prose">
|
||
Everything here has been bench-tested and comes with the same
|
||
two-year return window as new stock.
|
||
</p>
|
||
</div>
|
||
<button class="nv-button nv-button--lg nv-button--primary">See all 74 deals</button>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="shell section">
|
||
<div class="section__head">
|
||
<div>
|
||
<span class="nv-overline">This week</span>
|
||
<h2 class="nv-heading">Reduced while stock lasts</h2>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="nv-scroller-frame" data-nv-scroller>
|
||
<div class="nv-scroller" style="--nv-scroller-item: 15rem">
|
||
<article class="nv-card nv-card--interactive nv-card--flush">
|
||
<div class="nv-bed nv-bed--quiet product__art" style="aspect-ratio: 16/9"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M5 6.5h14v9H5z" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round"/><path d="M3 18.5h18" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></div>
|
||
<div class="nv-card__body" style="padding: var(--nv-space-4)">
|
||
<h3 class="nv-label">Forge 14 Developer</h3>
|
||
<p class="nv-caption" style="margin-block-start: var(--nv-space-1)">Ryzen 9 · 32 GB · 1 TB NVMe</p>
|
||
<p class="product__price" style="margin-block-start: var(--nv-space-2)">$1,849</p>
|
||
</div>
|
||
</article>
|
||
<article class="nv-card nv-card--interactive nv-card--flush">
|
||
<div class="nv-bed nv-bed--quiet product__art" style="aspect-ratio: 16/9"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><rect x="3" y="4.5" width="18" height="12" rx="1.8" stroke="currentColor" stroke-width="1.6"/><path d="M9.5 19.5h5M12 16.5v3" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></div>
|
||
<div class="nv-card__body" style="padding: var(--nv-space-4)">
|
||
<h3 class="nv-label">Clarity 27 4K</h3>
|
||
<p class="nv-caption" style="margin-block-start: var(--nv-space-1)">27″ · 3840×2160 · 144 Hz</p>
|
||
<p class="product__price" style="margin-block-start: var(--nv-space-2)">$629</p>
|
||
</div>
|
||
</article>
|
||
<article class="nv-card nv-card--interactive nv-card--flush">
|
||
<div class="nv-bed nv-bed--quiet product__art" style="aspect-ratio: 16/9"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><rect x="2.5" y="7" width="19" height="10" rx="2" stroke="currentColor" stroke-width="1.6"/><path d="M6 10.5h1M9 10.5h1M12 10.5h1M15 10.5h1M18 10.5h1M8 13.8h8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></div>
|
||
<div class="nv-card__body" style="padding: var(--nv-space-4)">
|
||
<h3 class="nv-label">Anvil TKL</h3>
|
||
<p class="nv-caption" style="margin-block-start: var(--nv-space-1)">Tactile · hot-swap · USB-C</p>
|
||
<p class="product__price" style="margin-block-start: var(--nv-space-2)">$139</p>
|
||
</div>
|
||
</article>
|
||
<article class="nv-card nv-card--interactive nv-card--flush">
|
||
<div class="nv-bed nv-bed--quiet product__art" style="aspect-ratio: 16/9"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><rect x="2.5" y="7.5" width="19" height="9" rx="1.6" stroke="currentColor" stroke-width="1.6"/><circle cx="8.5" cy="12" r="2.4" stroke="currentColor" stroke-width="1.6"/><circle cx="15.5" cy="12" r="2.4" stroke="currentColor" stroke-width="1.6"/></svg></div>
|
||
<div class="nv-card__body" style="padding: var(--nv-space-4)">
|
||
<h3 class="nv-label">Halo X900 16 GB</h3>
|
||
<p class="nv-caption" style="margin-block-start: var(--nv-space-1)">Triple fan · 2.6 GHz boost</p>
|
||
<p class="product__price" style="margin-block-start: var(--nv-space-2)">$1,099</p>
|
||
</div>
|
||
</article>
|
||
<article class="nv-card nv-card--interactive nv-card--flush">
|
||
<div class="nv-bed nv-bed--quiet product__art" style="aspect-ratio: 16/9"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><rect x="4" y="6" width="16" height="12" rx="2" stroke="currentColor" stroke-width="1.6"/><path d="M8 10h8M8 14h5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></div>
|
||
<div class="nv-card__body" style="padding: var(--nv-space-4)">
|
||
<h3 class="nv-label">Vault 4 TB NVMe</h3>
|
||
<p class="nv-caption" style="margin-block-start: var(--nv-space-1)">Gen4 · 7,400 MB/s read</p>
|
||
<p class="product__price" style="margin-block-start: var(--nv-space-2)">$289</p>
|
||
</div>
|
||
</article>
|
||
</div>
|
||
<button class="nv-button nv-button--icon nv-button--float" data-nv-scroll="prev" aria-label="Previous">
|
||
<svg class="nv-button__icon" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
||
<path d="M14 6l-6 6 6 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||
</svg>
|
||
</button>
|
||
<button class="nv-button nv-button--icon nv-button--float" data-nv-scroll="next" aria-label="Next">
|
||
<svg class="nv-button__icon" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
||
<path d="M10 6l6 6-6 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="shell section" id="catalogue">
|
||
<div class="catalogue">
|
||
|
||
<aside class="filters" aria-label="Filters">
|
||
<div class="filter-group">
|
||
<span class="nv-overline">Category</span>
|
||
<label class="nv-choice nv-caption"><input class="nv-checkbox" type="checkbox" checked> Workstations</label>
|
||
<label class="nv-choice nv-caption"><input class="nv-checkbox" type="checkbox" checked> Displays</label>
|
||
<label class="nv-choice nv-caption"><input class="nv-checkbox" type="checkbox"> Networking</label>
|
||
<label class="nv-choice nv-caption"><input class="nv-checkbox" type="checkbox"> Peripherals</label>
|
||
</div>
|
||
|
||
<hr class="nv-divider" style="margin: 0">
|
||
|
||
<div class="filter-group">
|
||
<span class="nv-overline">Price</span>
|
||
<div class="nv-cluster nv-cluster--tight" style="flex-wrap: nowrap">
|
||
<div class="nv-input-group">
|
||
<span class="nv-input-group__affix">$</span>
|
||
<label class="nv-visually-hidden" for="min">Minimum price</label>
|
||
<input class="nv-input nv-input--sm" id="min" inputmode="numeric" value="0">
|
||
</div>
|
||
<span class="nv-caption">to</span>
|
||
<div class="nv-input-group">
|
||
<span class="nv-input-group__affix">$</span>
|
||
<label class="nv-visually-hidden" for="max">Maximum price</label>
|
||
<input class="nv-input nv-input--sm" id="max" inputmode="numeric" value="2000">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<hr class="nv-divider" style="margin: 0">
|
||
|
||
<div class="filter-group">
|
||
<span class="nv-overline">Availability</span>
|
||
<label class="nv-choice nv-caption"><input class="nv-switch" type="checkbox" checked> In stock only</label>
|
||
<label class="nv-choice nv-caption"><input class="nv-switch" type="checkbox"> Ex-demo</label>
|
||
</div>
|
||
|
||
<hr class="nv-divider" style="margin: 0">
|
||
|
||
<div class="filter-group">
|
||
<span class="nv-overline">Condition</span>
|
||
<label class="nv-choice nv-caption"><input class="nv-radio" type="radio" name="condition" checked> Any</label>
|
||
<label class="nv-choice nv-caption"><input class="nv-radio" type="radio" name="condition"> New</label>
|
||
<label class="nv-choice nv-caption"><input class="nv-radio" type="radio" name="condition"> Refurbished</label>
|
||
</div>
|
||
|
||
<button class="nv-button nv-button--ghost nv-button--sm">Clear filters</button>
|
||
</aside>
|
||
|
||
<div>
|
||
<div class="section__head">
|
||
<div>
|
||
<h2 class="nv-title">Workstations & displays</h2>
|
||
<p class="nv-caption">8 of 412 products</p>
|
||
</div>
|
||
|
||
<button class="nv-button nv-button--sm nv-menu-trigger" popovertarget="sort-menu"
|
||
style="--nv-anchor: --sort">
|
||
Sort: <span id="sort-label">Relevance</span>
|
||
<span class="nv-disclosure__chevron" aria-hidden="true"
|
||
style="margin-inline-start: var(--nv-space-1)"></span>
|
||
</button>
|
||
|
||
<div class="nv-menu" popover id="sort-menu" style="--nv-anchor: --sort">
|
||
<button class="nv-menu__item" aria-checked="true" data-sort="Relevance">Relevance</button>
|
||
<button class="nv-menu__item" data-sort="Price, low to high">Price, low to high</button>
|
||
<button class="nv-menu__item" data-sort="Price, high to low">Price, high to low</button>
|
||
<button class="nv-menu__item" data-sort="Newest">Newest</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="products">
|
||
<article class="nv-card nv-card--flush nv-card--interactive">
|
||
<div class="nv-bed nv-bed--quiet product__art"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M5 6.5h14v9H5z" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round"/><path d="M3 18.5h18" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></div>
|
||
<div class="nv-card__body" style="padding: var(--nv-space-4)">
|
||
<div class="nv-cluster nv-cluster--between" style="gap: var(--nv-space-2)">
|
||
<h3 class="nv-label">Forge 14 Developer</h3>
|
||
<span class="nv-badge nv-badge--success"><span class="nv-badge__dot"></span>In stock</span>
|
||
</div>
|
||
<p class="nv-caption" style="margin-block-start: var(--nv-space-1)">Ryzen 9 · 32 GB · 1 TB NVMe</p>
|
||
<div class="nv-cluster" style="margin-block-start: var(--nv-space-3)">
|
||
<span class="product__price">$1,849</span>
|
||
|
||
</div>
|
||
</div>
|
||
<div class="nv-card__footer nv-card__footer--plain" style="padding: 0 var(--nv-space-4) var(--nv-space-4)">
|
||
<button class="nv-button nv-button--primary nv-button--sm nv-button--block"
|
||
data-add="Forge 14 Developer">Add to basket</button>
|
||
</div>
|
||
</article>
|
||
<article class="nv-card nv-card--flush nv-card--interactive">
|
||
<div class="nv-bed nv-bed--quiet product__art"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><rect x="3" y="4.5" width="18" height="12" rx="1.8" stroke="currentColor" stroke-width="1.6"/><path d="M9.5 19.5h5M12 16.5v3" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></div>
|
||
<div class="nv-card__body" style="padding: var(--nv-space-4)">
|
||
<div class="nv-cluster nv-cluster--between" style="gap: var(--nv-space-2)">
|
||
<h3 class="nv-label">Clarity 27 4K</h3>
|
||
<span class="nv-badge nv-badge--warning"><span class="nv-badge__dot"></span>4 left</span>
|
||
</div>
|
||
<p class="nv-caption" style="margin-block-start: var(--nv-space-1)">27″ · 3840×2160 · 144 Hz</p>
|
||
<div class="nv-cluster" style="margin-block-start: var(--nv-space-3)">
|
||
<span class="product__price">$629</span>
|
||
<span class="product__was">$749</span>
|
||
</div>
|
||
</div>
|
||
<div class="nv-card__footer nv-card__footer--plain" style="padding: 0 var(--nv-space-4) var(--nv-space-4)">
|
||
<button class="nv-button nv-button--primary nv-button--sm nv-button--block"
|
||
data-add="Clarity 27 4K">Add to basket</button>
|
||
</div>
|
||
</article>
|
||
<article class="nv-card nv-card--flush nv-card--interactive">
|
||
<div class="nv-bed nv-bed--quiet product__art"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><rect x="2.5" y="7" width="19" height="10" rx="2" stroke="currentColor" stroke-width="1.6"/><path d="M6 10.5h1M9 10.5h1M12 10.5h1M15 10.5h1M18 10.5h1M8 13.8h8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></div>
|
||
<div class="nv-card__body" style="padding: var(--nv-space-4)">
|
||
<div class="nv-cluster nv-cluster--between" style="gap: var(--nv-space-2)">
|
||
<h3 class="nv-label">Anvil TKL</h3>
|
||
<span class="nv-badge nv-badge--success"><span class="nv-badge__dot"></span>In stock</span>
|
||
</div>
|
||
<p class="nv-caption" style="margin-block-start: var(--nv-space-1)">Tactile · hot-swap · USB-C</p>
|
||
<div class="nv-cluster" style="margin-block-start: var(--nv-space-3)">
|
||
<span class="product__price">$139</span>
|
||
|
||
</div>
|
||
</div>
|
||
<div class="nv-card__footer nv-card__footer--plain" style="padding: 0 var(--nv-space-4) var(--nv-space-4)">
|
||
<button class="nv-button nv-button--primary nv-button--sm nv-button--block"
|
||
data-add="Anvil TKL">Add to basket</button>
|
||
</div>
|
||
</article>
|
||
<article class="nv-card nv-card--flush nv-card--interactive">
|
||
<div class="nv-bed nv-bed--quiet product__art"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><rect x="2.5" y="7.5" width="19" height="9" rx="1.6" stroke="currentColor" stroke-width="1.6"/><circle cx="8.5" cy="12" r="2.4" stroke="currentColor" stroke-width="1.6"/><circle cx="15.5" cy="12" r="2.4" stroke="currentColor" stroke-width="1.6"/></svg></div>
|
||
<div class="nv-card__body" style="padding: var(--nv-space-4)">
|
||
<div class="nv-cluster nv-cluster--between" style="gap: var(--nv-space-2)">
|
||
<h3 class="nv-label">Halo X900 16 GB</h3>
|
||
<span class="nv-badge nv-badge--danger"><span class="nv-badge__dot"></span>Backorder</span>
|
||
</div>
|
||
<p class="nv-caption" style="margin-block-start: var(--nv-space-1)">Triple fan · 2.6 GHz boost</p>
|
||
<div class="nv-cluster" style="margin-block-start: var(--nv-space-3)">
|
||
<span class="product__price">$1,099</span>
|
||
|
||
</div>
|
||
</div>
|
||
<div class="nv-card__footer nv-card__footer--plain" style="padding: 0 var(--nv-space-4) var(--nv-space-4)">
|
||
<button class="nv-button nv-button--primary nv-button--sm nv-button--block"
|
||
data-add="Halo X900 16 GB">Add to basket</button>
|
||
</div>
|
||
</article>
|
||
<article class="nv-card nv-card--flush nv-card--interactive">
|
||
<div class="nv-bed nv-bed--quiet product__art"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><rect x="4" y="6" width="16" height="12" rx="2" stroke="currentColor" stroke-width="1.6"/><path d="M8 10h8M8 14h5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></div>
|
||
<div class="nv-card__body" style="padding: var(--nv-space-4)">
|
||
<div class="nv-cluster nv-cluster--between" style="gap: var(--nv-space-2)">
|
||
<h3 class="nv-label">Vault 4 TB NVMe</h3>
|
||
<span class="nv-badge nv-badge--success"><span class="nv-badge__dot"></span>In stock</span>
|
||
</div>
|
||
<p class="nv-caption" style="margin-block-start: var(--nv-space-1)">Gen4 · 7,400 MB/s read</p>
|
||
<div class="nv-cluster" style="margin-block-start: var(--nv-space-3)">
|
||
<span class="product__price">$289</span>
|
||
<span class="product__was">$329</span>
|
||
</div>
|
||
</div>
|
||
<div class="nv-card__footer nv-card__footer--plain" style="padding: 0 var(--nv-space-4) var(--nv-space-4)">
|
||
<button class="nv-button nv-button--primary nv-button--sm nv-button--block"
|
||
data-add="Vault 4 TB NVMe">Add to basket</button>
|
||
</div>
|
||
</article>
|
||
<article class="nv-card nv-card--flush nv-card--interactive">
|
||
<div class="nv-bed nv-bed--quiet product__art"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><rect x="3" y="13" width="18" height="6" rx="2" stroke="currentColor" stroke-width="1.6"/><path d="M7 16.5h.01M10 16.5h.01M8 9.5a5 5 0 018 0M11 6.2a8.5 8.5 0 012 0" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></div>
|
||
<div class="nv-card__body" style="padding: var(--nv-space-4)">
|
||
<div class="nv-cluster nv-cluster--between" style="gap: var(--nv-space-2)">
|
||
<h3 class="nv-label">Mesh Six Pro</h3>
|
||
<span class="nv-badge nv-badge--success"><span class="nv-badge__dot"></span>In stock</span>
|
||
</div>
|
||
<p class="nv-caption" style="margin-block-start: var(--nv-space-1)">Wi-Fi 6E · 3-pack · 2.5 GbE</p>
|
||
<div class="nv-cluster" style="margin-block-start: var(--nv-space-3)">
|
||
<span class="product__price">$399</span>
|
||
|
||
</div>
|
||
</div>
|
||
<div class="nv-card__footer nv-card__footer--plain" style="padding: 0 var(--nv-space-4) var(--nv-space-4)">
|
||
<button class="nv-button nv-button--primary nv-button--sm nv-button--block"
|
||
data-add="Mesh Six Pro">Add to basket</button>
|
||
</div>
|
||
</article>
|
||
<article class="nv-card nv-card--flush nv-card--interactive">
|
||
<div class="nv-bed nv-bed--quiet product__art"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M5 15v-3a7 7 0 0114 0v3" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/><rect x="3" y="14" width="4" height="6" rx="1.6" stroke="currentColor" stroke-width="1.6"/><rect x="17" y="14" width="4" height="6" rx="1.6" stroke="currentColor" stroke-width="1.6"/></svg></div>
|
||
<div class="nv-card__body" style="padding: var(--nv-space-4)">
|
||
<div class="nv-cluster nv-cluster--between" style="gap: var(--nv-space-2)">
|
||
<h3 class="nv-label">Quiet Field 2</h3>
|
||
<span class="nv-badge nv-badge--warning"><span class="nv-badge__dot"></span>2 left</span>
|
||
</div>
|
||
<p class="nv-caption" style="margin-block-start: var(--nv-space-1)">ANC · 40 h · dual link</p>
|
||
<div class="nv-cluster" style="margin-block-start: var(--nv-space-3)">
|
||
<span class="product__price">$219</span>
|
||
|
||
</div>
|
||
</div>
|
||
<div class="nv-card__footer nv-card__footer--plain" style="padding: 0 var(--nv-space-4) var(--nv-space-4)">
|
||
<button class="nv-button nv-button--primary nv-button--sm nv-button--block"
|
||
data-add="Quiet Field 2">Add to basket</button>
|
||
</div>
|
||
</article>
|
||
<article class="nv-card nv-card--flush nv-card--interactive">
|
||
<div class="nv-bed nv-bed--quiet product__art"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><rect x="3" y="9" width="18" height="7" rx="2" stroke="currentColor" stroke-width="1.6"/><path d="M7 12.5h2M11 12.5h2M15.5 12.5h2" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></div>
|
||
<div class="nv-card__body" style="padding: var(--nv-space-4)">
|
||
<div class="nv-cluster nv-cluster--between" style="gap: var(--nv-space-2)">
|
||
<h3 class="nv-label">Bridge 13-in-1</h3>
|
||
<span class="nv-badge nv-badge--success"><span class="nv-badge__dot"></span>In stock</span>
|
||
</div>
|
||
<p class="nv-caption" style="margin-block-start: var(--nv-space-1)">Thunderbolt 4 · 96 W PD</p>
|
||
<div class="nv-cluster" style="margin-block-start: var(--nv-space-3)">
|
||
<span class="product__price">$179</span>
|
||
|
||
</div>
|
||
</div>
|
||
<div class="nv-card__footer nv-card__footer--plain" style="padding: 0 var(--nv-space-4) var(--nv-space-4)">
|
||
<button class="nv-button nv-button--primary nv-button--sm nv-button--block"
|
||
data-add="Bridge 13-in-1">Add to basket</button>
|
||
</div>
|
||
</article>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<footer class="shell site-footer">
|
||
<div class="nv-cluster nv-cluster--between">
|
||
<span class="nv-caption">Northwire — an example interface built with Niveus.</span>
|
||
<span class="nv-caption">Made by Nexoniarz</span>
|
||
</div>
|
||
</footer>
|
||
</main>
|
||
|
||
<dialog class="nv-dialog nv-dialog--wide" id="basket" aria-labelledby="basket-title">
|
||
<div class="nv-dialog__header">
|
||
<div>
|
||
<h2 class="nv-dialog__title" id="basket-title">Your basket</h2>
|
||
<p class="nv-dialog__description">Three items · delivered Thursday</p>
|
||
</div>
|
||
<button class="nv-button nv-button--ghost nv-button--icon nv-dialog__close"
|
||
aria-label="Close" data-nv-close>
|
||
<svg class="nv-button__icon" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
||
<path d="M6 6l12 12M18 6L6 18" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
|
||
<div class="nv-dialog__body">
|
||
<div class="nv-table-frame">
|
||
<table class="nv-table">
|
||
<thead>
|
||
<tr>
|
||
<th scope="col">Item</th>
|
||
<th scope="col" class="nv-table__number">Qty</th>
|
||
<th scope="col" class="nv-table__number">Price</th>
|
||
<th scope="col"><span class="nv-visually-hidden">Remove</span></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>
|
||
<div class="nv-cluster" style="flex-wrap: nowrap">
|
||
<span class="cart-line__art"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M5 6.5h14v9H5z" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round"/><path d="M3 18.5h18" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></span>
|
||
<span>
|
||
Forge 14 Developer
|
||
<span class="nv-caption" style="display: block">Ryzen 9 · 32 GB</span>
|
||
</span>
|
||
</div>
|
||
</td>
|
||
<td class="nv-table__number">1</td>
|
||
<td class="nv-table__number">$1,849</td>
|
||
<td class="nv-table__actions">
|
||
<button class="nv-button nv-button--ghost nv-button--icon nv-button--sm" aria-label="Remove Forge 14 Developer">
|
||
<svg class="nv-button__icon" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
||
<path d="M6 6l12 12M18 6L6 18" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||
</svg>
|
||
</button>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td>
|
||
<div class="nv-cluster" style="flex-wrap: nowrap">
|
||
<span class="cart-line__art"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><rect x="4" y="6" width="16" height="12" rx="2" stroke="currentColor" stroke-width="1.6"/><path d="M8 10h8M8 14h5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></span>
|
||
<span>
|
||
Vault 4 TB NVMe
|
||
<span class="nv-caption" style="display: block">Gen4 NVMe</span>
|
||
</span>
|
||
</div>
|
||
</td>
|
||
<td class="nv-table__number">1</td>
|
||
<td class="nv-table__number">$289</td>
|
||
<td class="nv-table__actions">
|
||
<button class="nv-button nv-button--ghost nv-button--icon nv-button--sm" aria-label="Remove Vault 4 TB NVMe">
|
||
<svg class="nv-button__icon" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
||
<path d="M6 6l12 12M18 6L6 18" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||
</svg>
|
||
</button>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td>
|
||
<div class="nv-cluster" style="flex-wrap: nowrap">
|
||
<span class="cart-line__art"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><rect x="2.5" y="7" width="19" height="10" rx="2" stroke="currentColor" stroke-width="1.6"/><path d="M6 10.5h1M9 10.5h1M12 10.5h1M15 10.5h1M18 10.5h1M8 13.8h8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/></svg></span>
|
||
<span>
|
||
Anvil TKL
|
||
<span class="nv-caption" style="display: block">Tactile · hot-swap</span>
|
||
</span>
|
||
</div>
|
||
</td>
|
||
<td class="nv-table__number">1</td>
|
||
<td class="nv-table__number">$139</td>
|
||
<td class="nv-table__actions">
|
||
<button class="nv-button nv-button--ghost nv-button--icon nv-button--sm" aria-label="Remove Anvil TKL">
|
||
<svg class="nv-button__icon" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
||
<path d="M6 6l12 12M18 6L6 18" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||
</svg>
|
||
</button>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div class="cart-totals">
|
||
<div class="cart-totals__row nv-caption"><span>Subtotal</span><span>$2,277.00</span></div>
|
||
<div class="cart-totals__row nv-caption"><span>Delivery</span><span>Free</span></div>
|
||
<div class="cart-totals__row nv-caption"><span>VAT (20%)</span><span>$455.40</span></div>
|
||
<div class="cart-totals__row cart-totals__row--due"><span>Due today</span><span>$2,732.40</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="nv-dialog__footer nv-dialog__footer--divided">
|
||
<button class="nv-button" data-nv-close>Keep shopping</button>
|
||
<button class="nv-button nv-button--primary">Checkout</button>
|
||
</div>
|
||
</dialog>
|
||
|
||
<script>
|
||
document.addEventListener("DOMContentLoaded", () => {
|
||
document.documentElement.addEventListener("nv:theme", (event) => {
|
||
try { localStorage.setItem("northwire-theme", event.detail.theme); } catch {}
|
||
});
|
||
nv.syncThemeControls(document.documentElement.getAttribute("data-theme") || "system");
|
||
|
||
/* Adding to the basket: the count changes, so it should be watchable. */
|
||
const count = document.getElementById("basket-count");
|
||
document.querySelectorAll("[data-add]").forEach((button) => {
|
||
button.addEventListener("click", () => {
|
||
count.textContent = String(Number(count.textContent) + 1);
|
||
if (!nv.prefersReducedMotion()) {
|
||
count.animate([{ scale: 1.4 }, { scale: 1 }], {
|
||
duration: 280,
|
||
easing: getComputedStyle(document.documentElement).getPropertyValue("--nv-ease-spring"),
|
||
});
|
||
}
|
||
button.textContent = "Added";
|
||
setTimeout(() => { button.textContent = "Add to basket"; }, 1200);
|
||
});
|
||
});
|
||
|
||
document.querySelectorAll("[data-sort]").forEach((option) => {
|
||
option.addEventListener("click", () => {
|
||
document.querySelectorAll("[data-sort]").forEach((other) => {
|
||
other.setAttribute("aria-checked", String(other === option));
|
||
});
|
||
document.getElementById("sort-label").textContent = option.dataset.sort;
|
||
document.getElementById("sort-menu").hidePopover();
|
||
});
|
||
});
|
||
|
||
const topnav = document.getElementById("topnav");
|
||
const onScroll = () => topnav.toggleAttribute("data-scrolled", scrollY > 8);
|
||
addEventListener("scroll", onScroll, { passive: true });
|
||
onScroll();
|
||
});
|
||
</script>
|
||
</body>
|
||
</html>
|