Iteration after the atmospheric-redesign checkpoint. The earlier A/B/C/D favicon set was scrapped — generic invented icons (roof, frame+horizon, skyline, wax seal) that didn't tie to the brand's own glyph. New direction: the yellow V from the wordmark, presented four ways. V-viewfinder (a V cut out of navy showing the harbor photo inside) is the chosen path; refinement 3b crops to Camogli's coloured row-houses for a more brand-specific small size reading. Also adds three logo-placement mockups (PWA cold-launch splash, library hero with the full wordmark logo, settings → about page) to give the wordmark room to live beyond emails and login badges. Self-contained: assets/ and spa/ copied into the design folder so the mockups render without depending on neighbouring directories. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@@ -0,0 +1,65 @@
|
|||||||
|
# WeVisto · favicons v2 + logo placements
|
||||||
|
|
||||||
|
2026-05-15 iteration following the atmospheric-redesign checkpoint.
|
||||||
|
Two threads:
|
||||||
|
|
||||||
|
1. **Favicons rebuilt** — scrapped the previous A/B/C/D (roof, frame+horizon,
|
||||||
|
skyline, wax seal) as generic invented icons. The new set reduces to the
|
||||||
|
brand's own glyph: the yellow V from the wordmark, presented four ways.
|
||||||
|
2. **The wordmark logo placed at hero scale** — three mockups giving the
|
||||||
|
full `wordmark.svg` (harbor photo + "WeVisto") room to live in the PWA
|
||||||
|
beyond the existing email + small-badge usage.
|
||||||
|
|
||||||
|
## Picked direction (favicons)
|
||||||
|
|
||||||
|
**3 · V-viewfinder.** The V cut out of navy with the harbor photo visible
|
||||||
|
inside — *you are looking at a photograph framed by the V.* Strongest
|
||||||
|
refinement is **3b** (`favicons/3b-viewfinder-buildings-*.png`) which tightens
|
||||||
|
the inner photo crop onto Camogli's coloured row-houses for a more
|
||||||
|
brand-specific small-size reading.
|
||||||
|
|
||||||
|
Runner-up: **4 · V-cropped** (`favicons/4-V-cropped-*.png`) — an actual
|
||||||
|
tight crop of the published wordmark. Most "WeVisto in the image itself"
|
||||||
|
of any direction.
|
||||||
|
|
||||||
|
## What's here
|
||||||
|
|
||||||
|
```
|
||||||
|
favicons-and-logo-v2/
|
||||||
|
├── index.html — entry point, shows everything
|
||||||
|
├── favicons/
|
||||||
|
│ ├── 1-V-pure-{16,32,64,180}.png — yellow V on navy, isolated
|
||||||
|
│ ├── 2-V-horizon-{...}.png — V plus horizon + sun
|
||||||
|
│ ├── 3-V-viewfinder-{...}.png — original V cut over full harbor
|
||||||
|
│ ├── 3a-viewfinder-full-thin-{...}.png — refinement A (full harbor, thin frame)
|
||||||
|
│ ├── 3b-viewfinder-buildings-{...}.png — recommended: Camogli row-houses
|
||||||
|
│ ├── 3c-viewfinder-noframe-{...}.png — no yellow outline
|
||||||
|
│ ├── 3d-viewfinder-thick-{...}.png — thick yellow frame
|
||||||
|
│ ├── 4-V-cropped-{...}.png — cropped from actual wordmark
|
||||||
|
│ └── 2-V-horizon.svg — SVG source for direction 2
|
||||||
|
├── logo-moments/
|
||||||
|
│ ├── splash.html — PWA cold-launch full-screen
|
||||||
|
│ ├── library-with-logo.html — library hero w/ full wordmark
|
||||||
|
│ └── about.html — settings → about page
|
||||||
|
├── assets/ — harbor.jpg, wordmark.svg, mark images
|
||||||
|
└── spa/ — shared atmospheric tokens + chrome
|
||||||
|
(so logo-moments can render)
|
||||||
|
```
|
||||||
|
|
||||||
|
## To view
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd webApp/_design/favicons-and-logo-v2
|
||||||
|
python3 -m http.server 8766 --bind 0.0.0.0
|
||||||
|
# → open http://<host>:8766/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Open work
|
||||||
|
|
||||||
|
- Decide between **3b** (recommended) and **4** (also "promising").
|
||||||
|
- Logo-moments not yet picked — Matt's review pending on which of the
|
||||||
|
three placements (splash / library hero / about page) to wire up first.
|
||||||
|
- Once selected, rasterize 3b at the standard PWA sizes (16/32/64 favicons,
|
||||||
|
180 apple-touch-icon, 192/512 PWA manifest icons, 512 maskable variant
|
||||||
|
with safe-zone padding) and ship into `webApp/frontend/public/icons/`
|
||||||
|
replacing the current split-W-on-photo set.
|
||||||
|
After Width: | Height: | Size: 264 KiB |
@@ -0,0 +1,12 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||||
|
<defs>
|
||||||
|
<clipPath id="wv-left"><rect x="0" y="0" width="32" height="64"/></clipPath>
|
||||||
|
<clipPath id="wv-right"><rect x="32" y="0" width="32" height="64"/></clipPath>
|
||||||
|
</defs>
|
||||||
|
<rect width="64" height="64" rx="12" fill="#1a3a5c"/>
|
||||||
|
<g font-family="system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif"
|
||||||
|
font-weight="900" font-size="56" text-anchor="middle">
|
||||||
|
<text x="32" y="50" fill="#fafafa" clip-path="url(#wv-left)">W</text>
|
||||||
|
<text x="32" y="50" fill="#f0d000" clip-path="url(#wv-right)">W</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 599 B |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 234 KiB |
|
After Width: | Height: | Size: 352 KiB |
|
After Width: | Height: | Size: 365 B |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 637 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 377 B |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 541 B |
|
After Width: | Height: | Size: 857 B |
@@ -0,0 +1,13 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||||
|
<rect width="64" height="64" fill="#0e2740"/>
|
||||||
|
|
||||||
|
<!-- full V — both strokes clearly meeting at bottom -->
|
||||||
|
<path d="M 14 14 L 32 50 L 50 14"
|
||||||
|
stroke="#f0d000" stroke-width="9"
|
||||||
|
stroke-linejoin="round" stroke-linecap="round" fill="none"/>
|
||||||
|
|
||||||
|
<!-- horizon line + sun below the V, like the sea visible past the wordmark -->
|
||||||
|
<line x1="6" y1="58" x2="58" y2="58"
|
||||||
|
stroke="#f0d000" stroke-width="1.4" opacity="0.5"/>
|
||||||
|
<circle cx="50" cy="58" r="2.4" fill="#f0d000"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 558 B |
|
After Width: | Height: | Size: 647 B |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 647 B |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 648 B |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 491 B |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 675 B |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 795 B |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 7.7 KiB |
@@ -0,0 +1,301 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>WeVisto — favicons v2 + logo moments</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=Nunito:wght@400;600;700;900&family=Marcellus&family=Cormorant+Garamond:ital,wght@1,400&family=DM+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--cream: #fdf6ee; --cream-deep: #f5ead4;
|
||||||
|
--ink: #2a1f15; --ink-soft: #6e6450;
|
||||||
|
--navy: #0e2740; --yellow: #f0d000;
|
||||||
|
--rule: rgba(42,31,21,0.15);
|
||||||
|
}
|
||||||
|
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||||
|
html, body { background: var(--cream); color: var(--ink); }
|
||||||
|
body { font-family: 'Nunito', sans-serif; font-size: 16px; line-height: 1.55; padding: 48px 40px 96px; max-width: 1280px; margin: 0 auto; }
|
||||||
|
|
||||||
|
.top { display: grid; grid-template-columns: auto 1fr auto; align-items: end; gap: 24px; padding-bottom: 14px; border-bottom: 1px solid var(--rule); }
|
||||||
|
.top .l, .top .r { font-family: 'DM Mono', monospace; font-size: 10px; letter-spacing: 0.28em; text-transform: uppercase; color: var(--ink-soft); }
|
||||||
|
.top .r { text-align: right; }
|
||||||
|
.top .name { font-family: 'Marcellus', serif; font-size: 44px; color: var(--navy); text-align: center; letter-spacing: 0.01em; }
|
||||||
|
.top .name .v { color: var(--yellow); }
|
||||||
|
.subhead { margin-top: 12px; padding-bottom: 22px; border-bottom: 1px solid var(--rule); text-align: center; font-family: 'Cormorant Garamond', serif; font-style: italic; font-size: 21px; color: var(--ink); }
|
||||||
|
|
||||||
|
h2.section { margin: 56px 0 8px; font-family: 'Marcellus', serif; font-weight: 400; font-size: 30px; color: var(--navy); }
|
||||||
|
h2.section .num { color: var(--yellow); margin-right: 8px; }
|
||||||
|
.lede { font-family: 'Cormorant Garamond', serif; font-style: italic; font-size: 19px; color: var(--ink); margin-bottom: 28px; max-width: 76ch; line-height: 1.5; }
|
||||||
|
.lede em { color: var(--navy); }
|
||||||
|
.lede strong { font-weight: 600; font-style: normal; color: var(--navy); }
|
||||||
|
|
||||||
|
/* favicon grid — 2x2, each shown at all four sizes + browser-tab + ios-tile */
|
||||||
|
.fav-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 28px; margin-top: 32px; }
|
||||||
|
.fav { background: #fff9ee; border: 1px solid var(--rule); padding: 24px; }
|
||||||
|
.fav__head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 12px; }
|
||||||
|
.fav__num { font-family: 'Marcellus', serif; font-size: 28px; color: var(--yellow); line-height: 1; }
|
||||||
|
.fav__tag { font-family: 'DM Mono', monospace; font-size: 10px; letter-spacing: 0.26em; text-transform: uppercase; color: var(--ink-soft); }
|
||||||
|
.fav h3 { font-family: 'Marcellus', serif; font-weight: 400; font-size: 24px; color: var(--navy); margin-bottom: 6px; }
|
||||||
|
.fav .desc { font-family: 'Cormorant Garamond', serif; font-style: italic; font-size: 17px; color: var(--ink); margin-bottom: 18px; line-height: 1.45; }
|
||||||
|
.fav .desc em { color: var(--navy); font-style: italic; }
|
||||||
|
.fav .row {
|
||||||
|
display: flex; align-items: flex-end; gap: 18px;
|
||||||
|
padding: 14px 0; border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
|
||||||
|
margin-bottom: 14px;
|
||||||
|
}
|
||||||
|
.fav .pip { text-align: center; }
|
||||||
|
.fav .pip img { display: block; image-rendering: pixelated; margin: 0 auto 6px; border-radius: 3px; }
|
||||||
|
.fav .pip .cap { font-family: 'DM Mono', monospace; font-size: 9px; letter-spacing: 0.2em; color: var(--ink-soft); }
|
||||||
|
.fav .ctx { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
|
||||||
|
.fav .ctx .box { padding: 12px; background: var(--cream); border: 1px solid var(--rule); }
|
||||||
|
.fav .ctx .box-label { font-family: 'DM Mono', monospace; font-size: 9px; letter-spacing: 0.22em; text-transform: uppercase; color: var(--ink-soft); margin-bottom: 8px; }
|
||||||
|
.tab-strip { background: #2a2a2a; border-radius: 4px 4px 0 0; padding: 4px 4px 0; display: inline-block; }
|
||||||
|
.tab-strip .tab { display: inline-flex; align-items: center; gap: 6px; background: #3a3a3a; padding: 5px 10px 5px 8px; border-radius: 4px 4px 0 0; font-family: -apple-system, sans-serif; font-size: 11px; color: #ddd; }
|
||||||
|
.tab-strip .tab img { width: 14px; height: 14px; }
|
||||||
|
.ios-tile { width: 56px; height: 56px; border-radius: 12px; overflow: hidden; box-shadow: 0 4px 10px rgba(0,0,0,0.25); }
|
||||||
|
.ios-tile img { width: 100%; height: 100%; display: block; }
|
||||||
|
|
||||||
|
/* logo-moment cards */
|
||||||
|
.stack { display: grid; gap: 32px; margin-top: 24px; grid-template-columns: repeat(3, 1fr); }
|
||||||
|
.moment { background: #fff9ee; border: 1px solid var(--rule); overflow: hidden; }
|
||||||
|
.moment .preview { position: relative; aspect-ratio: 9/16; background: #06121f; }
|
||||||
|
.moment .preview iframe { border: 0; width: 250%; height: 250%; transform: scale(0.4); transform-origin: top left; display: block; }
|
||||||
|
.moment .open { position: absolute; bottom: 12px; right: 12px; z-index: 5; font-family: 'DM Mono', monospace; font-size: 10px; letter-spacing: 0.28em; text-transform: uppercase; color: #fff; background: rgba(7,23,42,0.75); padding: 8px 14px; text-decoration: none; backdrop-filter: blur(6px); }
|
||||||
|
.moment .open:hover { background: var(--yellow); color: var(--navy); }
|
||||||
|
.moment .body { padding: 22px 24px 24px; }
|
||||||
|
.moment .body .roman { font-family: 'Marcellus', serif; font-size: 22px; color: var(--yellow); margin-bottom: 4px; }
|
||||||
|
.moment .body h3 { font-family: 'Marcellus', serif; font-weight: 400; font-size: 22px; color: var(--navy); margin-bottom: 6px; }
|
||||||
|
.moment .body p { font-size: 15px; line-height: 1.5; color: var(--ink); }
|
||||||
|
.moment .body p em { color: var(--navy); font-style: italic; }
|
||||||
|
|
||||||
|
.also { margin-top: 56px; padding: 16px 20px; background: rgba(240,208,0,0.18); border-left: 4px solid var(--yellow); font-style: italic; color: var(--ink); font-size: 15px; }
|
||||||
|
.also a { color: var(--navy); border-bottom: 1px solid var(--navy); text-decoration: none; }
|
||||||
|
|
||||||
|
footer { margin-top: 64px; padding-top: 22px; border-top: 1px solid var(--rule); text-align: center; font-family: 'Cormorant Garamond', serif; font-style: italic; font-size: 14px; color: var(--ink-soft); }
|
||||||
|
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
body { padding: 32px 20px; }
|
||||||
|
.fav-grid, .stack { grid-template-columns: 1fr; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="top">
|
||||||
|
<div class="l">v2 · 2026-05-15</div>
|
||||||
|
<div class="name">We<span class="v">V</span>isto</div>
|
||||||
|
<div class="r">Favicons rethought<br>+ logo placed</div>
|
||||||
|
</div>
|
||||||
|
<div class="subhead">— scrapping the previous favicon set; the brand's own V is the answer, not invented icons.</div>
|
||||||
|
|
||||||
|
<!-- FAVICONS — V2 -->
|
||||||
|
<h2 class="section"><span class="num">I.</span>Favicons, rebuilt around the V — <span style="color: var(--navy); font-style: italic; font-family: 'Cormorant Garamond', serif;">V-viewfinder picked, refining</span></h2>
|
||||||
|
<p class="lede">Direction 3 (V-viewfinder) is the chosen path — the V as a window onto the harbor. Four refinements of it below: <strong>3b is the strongest</strong> (tighter crop on Camogli's coloured row-houses + thin yellow frame). 3a, 3c, 3d shown for comparison.</p>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.v3-variants { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; margin-top: 24px; margin-bottom: 48px; }
|
||||||
|
.v3-card { background: #fff9ee; border: 1px solid var(--rule); padding: 18px; }
|
||||||
|
.v3-card.pick { background: #fffbe0; border-color: var(--yellow); box-shadow: 0 0 0 1px var(--yellow); }
|
||||||
|
.v3-card .pick-tag { display: inline-block; font-family: 'DM Mono', monospace; font-size: 9px; letter-spacing: 0.26em; text-transform: uppercase; color: var(--yellow); background: var(--navy); padding: 3px 8px; margin-bottom: 8px; }
|
||||||
|
.v3-card h4 { font-family: 'Marcellus', serif; font-weight: 400; font-size: 18px; color: var(--navy); margin-bottom: 4px; }
|
||||||
|
.v3-card .desc { font-family: 'Cormorant Garamond', serif; font-style: italic; font-size: 14px; line-height: 1.4; color: var(--ink); margin-bottom: 12px; min-height: 56px; }
|
||||||
|
.v3-card .row { display: flex; align-items: flex-end; gap: 10px; padding: 10px 0; border-top: 1px solid var(--rule); }
|
||||||
|
.v3-card .row img { display: block; image-rendering: pixelated; border-radius: 2px; }
|
||||||
|
.v3-card .row .cap { font-family: 'DM Mono', monospace; font-size: 8px; letter-spacing: 0.18em; color: var(--ink-soft); text-align: center; margin-top: 4px; }
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="v3-variants">
|
||||||
|
<div class="v3-card">
|
||||||
|
<h4>3a · full harbor</h4>
|
||||||
|
<div class="desc">Full harbor view inside the V. Detailed but busy at small sizes.</div>
|
||||||
|
<div class="row">
|
||||||
|
<div><img src="favicons/3a-viewfinder-full-thin-16.png" width="28" height="28"><div class="cap">16</div></div>
|
||||||
|
<div><img src="favicons/3a-viewfinder-full-thin-32.png" width="44" height="44"><div class="cap">32</div></div>
|
||||||
|
<div><img src="favicons/3a-viewfinder-full-thin-64.png" width="64" height="64"><div class="cap">64</div></div>
|
||||||
|
<div><img src="favicons/3a-viewfinder-full-thin-180.png" width="90" height="90"><div class="cap">180</div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="v3-card pick">
|
||||||
|
<span class="pick-tag">Recommended</span>
|
||||||
|
<h4>3b · Camogli row-houses</h4>
|
||||||
|
<div class="desc">Tighter crop on the colored row-houses. Most brand-specific — <em>Camogli is the brand origin.</em></div>
|
||||||
|
<div class="row">
|
||||||
|
<div><img src="favicons/3b-viewfinder-buildings-16.png" width="28" height="28"><div class="cap">16</div></div>
|
||||||
|
<div><img src="favicons/3b-viewfinder-buildings-32.png" width="44" height="44"><div class="cap">32</div></div>
|
||||||
|
<div><img src="favicons/3b-viewfinder-buildings-64.png" width="64" height="64"><div class="cap">64</div></div>
|
||||||
|
<div><img src="favicons/3b-viewfinder-buildings-180.png" width="90" height="90"><div class="cap">180</div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="v3-card">
|
||||||
|
<h4>3c · no frame</h4>
|
||||||
|
<div class="desc">No yellow outline. Cleanest silhouette but <em>loses the brand yellow at small sizes.</em></div>
|
||||||
|
<div class="row">
|
||||||
|
<div><img src="favicons/3c-viewfinder-noframe-16.png" width="28" height="28"><div class="cap">16</div></div>
|
||||||
|
<div><img src="favicons/3c-viewfinder-noframe-32.png" width="44" height="44"><div class="cap">32</div></div>
|
||||||
|
<div><img src="favicons/3c-viewfinder-noframe-64.png" width="64" height="64"><div class="cap">64</div></div>
|
||||||
|
<div><img src="favicons/3c-viewfinder-noframe-180.png" width="90" height="90"><div class="cap">180</div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="v3-card">
|
||||||
|
<h4>3d · thick frame</h4>
|
||||||
|
<div class="desc">Heavier yellow border, more "picture frame" reading. Veers toward decorative.</div>
|
||||||
|
<div class="row">
|
||||||
|
<div><img src="favicons/3d-viewfinder-thick-16.png" width="28" height="28"><div class="cap">16</div></div>
|
||||||
|
<div><img src="favicons/3d-viewfinder-thick-32.png" width="44" height="44"><div class="cap">32</div></div>
|
||||||
|
<div><img src="favicons/3d-viewfinder-thick-64.png" width="64" height="64"><div class="cap">64</div></div>
|
||||||
|
<div><img src="favicons/3d-viewfinder-thick-180.png" width="90" height="90"><div class="cap">180</div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="lede">Original first-round directions below for reference (1 V-pure, 2 V-horizon, 4 V-cropped).</p>
|
||||||
|
|
||||||
|
<div class="fav-grid">
|
||||||
|
|
||||||
|
<div class="fav">
|
||||||
|
<div class="fav__head"><span class="fav__num">1.</span><span class="fav__tag">Brand · isolated</span></div>
|
||||||
|
<h3>V-pure</h3>
|
||||||
|
<div class="desc">The yellow V on solid navy, drawn confidently. <em>The brand's own glyph, alone in a room.</em> Reads at every size, no decoration.</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="pip"><img src="favicons/1-V-pure-16.png" width="32" height="32"><div class="cap">16</div></div>
|
||||||
|
<div class="pip"><img src="favicons/1-V-pure-32.png" width="48" height="48"><div class="cap">32</div></div>
|
||||||
|
<div class="pip"><img src="favicons/1-V-pure-64.png" width="64" height="64"><div class="cap">64</div></div>
|
||||||
|
<div class="pip"><img src="favicons/1-V-pure-180.png" width="96" height="96"><div class="cap">180</div></div>
|
||||||
|
</div>
|
||||||
|
<div class="ctx">
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-label">browser tab</div>
|
||||||
|
<div class="tab-strip"><span class="tab"><img src="favicons/1-V-pure-32.png">WeVisto</span></div>
|
||||||
|
</div>
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-label">iOS home screen</div>
|
||||||
|
<div class="ios-tile"><img src="favicons/1-V-pure-180.png"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="fav">
|
||||||
|
<div class="fav__head"><span class="fav__num">2.</span><span class="fav__tag">Brand · with horizon</span></div>
|
||||||
|
<h3>V-horizon</h3>
|
||||||
|
<div class="desc">The V plus a hairline horizon and a single sun dot below — <em>the harbor is implied,</em> not depicted. Editorial echo of the rest of the brand.</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="pip"><img src="favicons/2-V-horizon-16.png" width="32" height="32"><div class="cap">16</div></div>
|
||||||
|
<div class="pip"><img src="favicons/2-V-horizon-32.png" width="48" height="48"><div class="cap">32</div></div>
|
||||||
|
<div class="pip"><img src="favicons/2-V-horizon-64.png" width="64" height="64"><div class="cap">64</div></div>
|
||||||
|
<div class="pip"><img src="favicons/2-V-horizon-180.png" width="96" height="96"><div class="cap">180</div></div>
|
||||||
|
</div>
|
||||||
|
<div class="ctx">
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-label">browser tab</div>
|
||||||
|
<div class="tab-strip"><span class="tab"><img src="favicons/2-V-horizon-32.png">WeVisto</span></div>
|
||||||
|
</div>
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-label">iOS home screen</div>
|
||||||
|
<div class="ios-tile"><img src="favicons/2-V-horizon-180.png"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="fav">
|
||||||
|
<div class="fav__head"><span class="fav__num">3.</span><span class="fav__tag">Brand · viewfinder</span></div>
|
||||||
|
<h3>V-viewfinder</h3>
|
||||||
|
<div class="desc">The V cut out of navy, with the harbor photo visible inside — <em>you are looking at a photograph framed by the V.</em> Strong at 64+, silhouette holds at 16.</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="pip"><img src="favicons/3-V-viewfinder-16.png" width="32" height="32"><div class="cap">16</div></div>
|
||||||
|
<div class="pip"><img src="favicons/3-V-viewfinder-32.png" width="48" height="48"><div class="cap">32</div></div>
|
||||||
|
<div class="pip"><img src="favicons/3-V-viewfinder-64.png" width="64" height="64"><div class="cap">64</div></div>
|
||||||
|
<div class="pip"><img src="favicons/3-V-viewfinder-180.png" width="96" height="96"><div class="cap">180</div></div>
|
||||||
|
</div>
|
||||||
|
<div class="ctx">
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-label">browser tab</div>
|
||||||
|
<div class="tab-strip"><span class="tab"><img src="favicons/3-V-viewfinder-32.png">WeVisto</span></div>
|
||||||
|
</div>
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-label">iOS home screen</div>
|
||||||
|
<div class="ios-tile"><img src="favicons/3-V-viewfinder-180.png"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="fav">
|
||||||
|
<div class="fav__head"><span class="fav__num">4.</span><span class="fav__tag">Brand · cropped</span></div>
|
||||||
|
<h3>V-cropped (the wordmark itself)</h3>
|
||||||
|
<div class="desc">A tight crop of the actual published wordmark. The favicon <em>is</em> a slice of the logo — V centered, "e" and "i" partially visible at large sizes. The most "WeVisto in the image."</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="pip"><img src="favicons/4-V-cropped-16.png" width="32" height="32"><div class="cap">16</div></div>
|
||||||
|
<div class="pip"><img src="favicons/4-V-cropped-32.png" width="48" height="48"><div class="cap">32</div></div>
|
||||||
|
<div class="pip"><img src="favicons/4-V-cropped-64.png" width="64" height="64"><div class="cap">64</div></div>
|
||||||
|
<div class="pip"><img src="favicons/4-V-cropped-180.png" width="96" height="96"><div class="cap">180</div></div>
|
||||||
|
</div>
|
||||||
|
<div class="ctx">
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-label">browser tab</div>
|
||||||
|
<div class="tab-strip"><span class="tab"><img src="favicons/4-V-cropped-32.png">WeVisto</span></div>
|
||||||
|
</div>
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-label">iOS home screen</div>
|
||||||
|
<div class="ios-tile"><img src="favicons/4-V-cropped-180.png"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- LOGO MOMENTS -->
|
||||||
|
<h2 class="section"><span class="num">II.</span>The wordmark logo, given room to live</h2>
|
||||||
|
<p class="lede">Currently the full <em>wordmark + harbor</em> logo only appears in email templates and as a small badge on Twig pages. These three mockups give it three new homes in the PWA at <strong>hero scale</strong> — each one a moment where the brand earns the room.</p>
|
||||||
|
|
||||||
|
<div class="stack">
|
||||||
|
|
||||||
|
<div class="moment">
|
||||||
|
<div class="preview">
|
||||||
|
<iframe src="logo-moments/splash.html" loading="lazy"></iframe>
|
||||||
|
<a class="open" href="logo-moments/splash.html" target="_blank">Open ⟶</a>
|
||||||
|
</div>
|
||||||
|
<div class="body">
|
||||||
|
<div class="roman">II·a</div>
|
||||||
|
<h3>PWA cold-launch splash</h3>
|
||||||
|
<p>Shown for ~1.5s on app cold-launch. Wordmark logo at ~520px, Ken-Burns harbor backdrop, three-dot loader. Then it fades to <em>HomeView.</em></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="moment">
|
||||||
|
<div class="preview">
|
||||||
|
<iframe src="logo-moments/library-with-logo.html" loading="lazy"></iframe>
|
||||||
|
<a class="open" href="logo-moments/library-with-logo.html" target="_blank">Open ⟶</a>
|
||||||
|
</div>
|
||||||
|
<div class="body">
|
||||||
|
<div class="roman">II·b</div>
|
||||||
|
<h3>Library hero (revised)</h3>
|
||||||
|
<p>The empty state's 112px mark replaced by the <em>full wordmark logo</em> at 320px. Same headline / sub / CTA below. The library page becomes a brand moment.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="moment">
|
||||||
|
<div class="preview">
|
||||||
|
<iframe src="logo-moments/about.html" loading="lazy"></iframe>
|
||||||
|
<a class="open" href="logo-moments/about.html" target="_blank">Open ⟶</a>
|
||||||
|
</div>
|
||||||
|
<div class="body">
|
||||||
|
<div class="roman">II·c</div>
|
||||||
|
<h3>About · the brand story</h3>
|
||||||
|
<p>A settings → about page with the wordmark logo as page hero, a two-section editorial about the frame and the V, then a credits card. <em>The place where the brand explains itself.</em></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="also">Saved iteration: this is in <code>/tmp/wevisto-mockups/v2/</code> for now. Approve a direction (or set of directions) and I'll save it into the repo alongside <a href="../">the previous checkpoint</a>.</div>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
Open each tile to interact at full scale.
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,173 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en" data-theme="ocean-dusk">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
|
<title>About — WeVisto</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=Nunito:wght@400;600;700;900&family=Marcellus&family=Cormorant+Garamond:ital,wght@1,400&family=DM+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="../spa/_tokens.css">
|
||||||
|
<link rel="stylesheet" href="../spa/_chrome.css">
|
||||||
|
<style>
|
||||||
|
.about-hero {
|
||||||
|
padding: var(--space-5) var(--space-5) var(--space-6);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.about-hero__plate {
|
||||||
|
font: var(--type-label);
|
||||||
|
letter-spacing: 0.32em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--text-muted);
|
||||||
|
margin-bottom: var(--space-4);
|
||||||
|
display: flex; align-items: center; gap: 10px;
|
||||||
|
}
|
||||||
|
.about-hero__plate .roman { color: var(--brand-yellow); font-family: var(--font-display); font-size: var(--text-md); }
|
||||||
|
.about-hero__plate .sep { width: 24px; height: 1px; background: var(--glass-bord); }
|
||||||
|
/* Wordmark logo as the page hero */
|
||||||
|
.about-hero__logo {
|
||||||
|
width: min(70vw, 280px);
|
||||||
|
aspect-ratio: 1;
|
||||||
|
border-radius: 18px;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: var(--space-5);
|
||||||
|
box-shadow:
|
||||||
|
0 1px 0 rgba(255,255,255,0.18) inset,
|
||||||
|
0 22px 44px -12px rgba(0,0,0,0.6);
|
||||||
|
}
|
||||||
|
.about-hero__logo img { width: 100%; height: 100%; display: block; }
|
||||||
|
.about-hero__title {
|
||||||
|
font: var(--type-display-lg);
|
||||||
|
color: var(--text);
|
||||||
|
margin-bottom: var(--space-2);
|
||||||
|
}
|
||||||
|
.about-hero__sub {
|
||||||
|
font: italic 400 17px/1.55 var(--font-accent);
|
||||||
|
color: var(--text-muted);
|
||||||
|
max-width: 38ch;
|
||||||
|
}
|
||||||
|
.about-hero__rule {
|
||||||
|
width: 80px; height: 1px;
|
||||||
|
background: linear-gradient(90deg, transparent, var(--brand-yellow), transparent);
|
||||||
|
margin-top: var(--space-5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.story {
|
||||||
|
margin: var(--space-6) var(--space-5);
|
||||||
|
padding: var(--space-5) var(--space-5) var(--space-6);
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
}
|
||||||
|
.story h2 {
|
||||||
|
font: var(--type-display-md);
|
||||||
|
color: var(--text);
|
||||||
|
margin-bottom: var(--space-3);
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
.story h2 .roman {
|
||||||
|
font-family: var(--font-display);
|
||||||
|
color: var(--brand-yellow);
|
||||||
|
font-size: var(--text-lg);
|
||||||
|
}
|
||||||
|
.story p {
|
||||||
|
font-size: var(--text-base);
|
||||||
|
line-height: 1.65;
|
||||||
|
color: var(--text);
|
||||||
|
margin-bottom: var(--space-3);
|
||||||
|
}
|
||||||
|
.story p em { font-family: var(--font-accent); font-style: italic; color: var(--brand-yellow); }
|
||||||
|
.story p strong { font-family: var(--font-display); font-weight: 400; color: var(--text); }
|
||||||
|
|
||||||
|
/* the credit list as a glass card */
|
||||||
|
.credits {
|
||||||
|
margin: var(--space-6) var(--space-5);
|
||||||
|
padding: var(--space-5);
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
}
|
||||||
|
.credits h3 {
|
||||||
|
font: var(--type-label);
|
||||||
|
letter-spacing: 0.32em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--text-muted);
|
||||||
|
margin-bottom: var(--space-4);
|
||||||
|
}
|
||||||
|
.credits dl { display: grid; grid-template-columns: auto 1fr; gap: var(--space-3) var(--space-5); }
|
||||||
|
.credits dt {
|
||||||
|
font-family: var(--font-display);
|
||||||
|
font-size: var(--text-sm);
|
||||||
|
color: var(--brand-yellow);
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
}
|
||||||
|
.credits dd { font-family: var(--font-accent); font-style: italic; font-size: var(--text-base); color: var(--text); }
|
||||||
|
|
||||||
|
.signature { margin: var(--space-6) var(--space-5) 0; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="atmosphere"></div>
|
||||||
|
|
||||||
|
<header class="app-bar">
|
||||||
|
<div class="app-bar__mark"><img src="../assets/mark-photo-64.png" alt=""></div>
|
||||||
|
<div class="app-bar__title-group">
|
||||||
|
<div class="app-bar__wordmark">We<span class="v">V</span>isto</div>
|
||||||
|
<div class="app-bar__sub">— about</div>
|
||||||
|
</div>
|
||||||
|
<div class="app-bar__spacer"></div>
|
||||||
|
<button class="app-bar__icon" aria-label="Close">
|
||||||
|
<svg viewBox="0 0 24 24"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
|
||||||
|
</button>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main class="main-scroll">
|
||||||
|
|
||||||
|
<div class="about-hero">
|
||||||
|
<div class="about-hero__plate"><span class="roman">○</span><span class="sep"></span><span>Edizione I</span></div>
|
||||||
|
<div class="about-hero__logo">
|
||||||
|
<img src="../assets/wordmark.svg" alt="WeVisto">
|
||||||
|
</div>
|
||||||
|
<h1 class="about-hero__title">A frame, gifted.</h1>
|
||||||
|
<p class="about-hero__sub">Handmade e-ink picture frames, given to the people who keep our photographs.</p>
|
||||||
|
<div class="about-hero__rule"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<article class="story glass">
|
||||||
|
<h2><span class="roman">I.</span>The thing itself</h2>
|
||||||
|
<p>A WeVisto frame is built by hand in <strong>Camogli</strong>, on the Ligurian coast. The display uses paper-like ink — the same family of screens as a Kindle — so it has the <em>quiet of a photograph</em> rather than the glow of a phone.</p>
|
||||||
|
<p>It connects to your wifi once. After that, nothing. It collects new photographs on its own and changes them as quietly as a clock.</p>
|
||||||
|
|
||||||
|
<h2><span class="roman">II.</span>The thing about the V</h2>
|
||||||
|
<p>The yellow V is the only thing in the wordmark that isn't white. It's how we remember the people we make these for — <em>the recipient is the V,</em> we are the letters around them.</p>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<div class="credits glass">
|
||||||
|
<h3>Edition I · MMXXVI</h3>
|
||||||
|
<dl>
|
||||||
|
<dt>Made by</dt> <dd>Matt Edholm</dd>
|
||||||
|
<dt>From</dt> <dd>Camogli, Liguria</dd>
|
||||||
|
<dt>For</dt> <dd>Margaret, Alice, and the rest</dd>
|
||||||
|
<dt>Version</dt> <dd>0.4 · pre-release</dd>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="signature">
|
||||||
|
<div class="signature__mark"><img src="../assets/mark-photo-64.png" alt=""></div>
|
||||||
|
<div class="signature__text">WeVisto <span class="v-mark">·</span> a frame, gifted</div>
|
||||||
|
<div class="signature__version">Plate i · v 0.4</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="bottom-nav">
|
||||||
|
<a class="bottom-nav__tab"><svg viewBox="0 0 24 24"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9,22 9,12 15,12 15,22"/></svg><span class="label">Home</span></a>
|
||||||
|
<a class="bottom-nav__tab"><svg viewBox="0 0 24 24"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></svg><span class="label">Library</span></a>
|
||||||
|
<a class="bottom-nav__tab active"><svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/></svg><span class="label">Settings</span></a>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,161 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en" data-theme="ocean-dusk">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
|
<title>Library — WeVisto</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=Nunito:wght@400;600;700;900&family=Marcellus&family=Cormorant+Garamond:ital,wght@1,400&family=DM+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="../spa/_tokens.css">
|
||||||
|
<link rel="stylesheet" href="../spa/_chrome.css">
|
||||||
|
<style>
|
||||||
|
/* This is the library empty state — but the FULL WORDMARK LOGO replaces the 112px mark */
|
||||||
|
.library-empty {
|
||||||
|
padding: 48px 24px 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.library-empty__plate {
|
||||||
|
font: var(--type-label);
|
||||||
|
letter-spacing: 0.32em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--text-muted);
|
||||||
|
margin-bottom: var(--space-5);
|
||||||
|
display: flex; align-items: center; gap: 10px;
|
||||||
|
}
|
||||||
|
.library-empty__plate .roman { color: var(--brand-yellow); font-family: var(--font-display); font-size: var(--text-md); }
|
||||||
|
.library-empty__plate .sep { width: 24px; height: 1px; background: var(--glass-bord); }
|
||||||
|
|
||||||
|
/* THE LOGO MOMENT — the actual wordmark+harbor logo, hero scale */
|
||||||
|
.library-empty__logo {
|
||||||
|
width: min(78vw, 320px);
|
||||||
|
aspect-ratio: 1;
|
||||||
|
border-radius: 20px;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: var(--space-5);
|
||||||
|
box-shadow:
|
||||||
|
0 1px 0 rgba(255,255,255,0.18) inset,
|
||||||
|
0 24px 48px -12px rgba(0,0,0,0.65),
|
||||||
|
0 10px 24px -8px rgba(0,0,0,0.4);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.library-empty__logo img { width: 100%; height: 100%; display: block; }
|
||||||
|
/* soft halo behind the logo */
|
||||||
|
.library-empty__logo::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
inset: -40px;
|
||||||
|
background: radial-gradient(circle, color-mix(in srgb, var(--brand-yellow) 22%, transparent), transparent 60%);
|
||||||
|
border-radius: 50%;
|
||||||
|
z-index: -1;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.library-empty__title {
|
||||||
|
font: var(--type-display-xl);
|
||||||
|
color: var(--text);
|
||||||
|
margin-bottom: var(--space-2);
|
||||||
|
text-shadow: 0 2px 10px rgba(0,0,0,0.3);
|
||||||
|
}
|
||||||
|
.library-empty__title em {
|
||||||
|
font-family: var(--font-accent);
|
||||||
|
font-style: italic;
|
||||||
|
color: var(--brand-yellow);
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
.library-empty__sub {
|
||||||
|
font: italic 400 18px/1.55 var(--font-accent);
|
||||||
|
color: var(--text-muted);
|
||||||
|
max-width: 34ch;
|
||||||
|
margin-bottom: var(--space-6);
|
||||||
|
}
|
||||||
|
.library-empty__rule {
|
||||||
|
width: 96px; height: 1px;
|
||||||
|
background: linear-gradient(90deg, transparent, var(--brand-yellow), transparent);
|
||||||
|
margin: 0 auto var(--space-6);
|
||||||
|
}
|
||||||
|
.library-empty__cta {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
background: var(--accent);
|
||||||
|
color: var(--accent-fg);
|
||||||
|
padding: 14px 28px;
|
||||||
|
border-radius: var(--radius-full);
|
||||||
|
font-family: var(--font-family);
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: var(--text-base);
|
||||||
|
text-decoration: none;
|
||||||
|
box-shadow: 0 8px 22px -4px color-mix(in srgb, var(--accent) 50%, transparent);
|
||||||
|
transition: transform var(--duration-fast), filter var(--duration-fast);
|
||||||
|
}
|
||||||
|
.library-empty__cta:hover { transform: translateY(-1px); filter: brightness(1.08); }
|
||||||
|
.library-empty__cta svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 2.5; stroke-linecap: round; }
|
||||||
|
.library-empty__or {
|
||||||
|
margin-top: var(--space-5);
|
||||||
|
font: italic 400 var(--text-md)/1.4 var(--font-accent);
|
||||||
|
color: var(--text-muted);
|
||||||
|
}
|
||||||
|
.library-empty__or a {
|
||||||
|
color: var(--text);
|
||||||
|
border-bottom: 1px solid var(--glass-bord);
|
||||||
|
text-decoration: none;
|
||||||
|
padding-bottom: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature { margin: 64px var(--space-5) 0; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="atmosphere"></div>
|
||||||
|
|
||||||
|
<header class="app-bar">
|
||||||
|
<div class="app-bar__mark"><img src="../assets/mark-photo-64.png" alt=""></div>
|
||||||
|
<div class="app-bar__title-group">
|
||||||
|
<div class="app-bar__wordmark">We<span class="v">V</span>isto</div>
|
||||||
|
<div class="app-bar__sub">— the library</div>
|
||||||
|
</div>
|
||||||
|
<div class="app-bar__spacer"></div>
|
||||||
|
<button class="app-bar__icon" aria-label="Filter">
|
||||||
|
<svg viewBox="0 0 24 24"><polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/></svg>
|
||||||
|
</button>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main class="main-scroll">
|
||||||
|
|
||||||
|
<div class="library-empty">
|
||||||
|
<div class="library-empty__plate"><span class="roman">○</span><span class="sep"></span><span>Accession no. 001</span></div>
|
||||||
|
<div class="library-empty__logo">
|
||||||
|
<img src="../assets/wordmark.svg" alt="WeVisto">
|
||||||
|
</div>
|
||||||
|
<h1 class="library-empty__title">A library, <em>waiting.</em></h1>
|
||||||
|
<p class="library-empty__sub">Photographs you upload will rotate through Margaret's frame, one at a time.</p>
|
||||||
|
<div class="library-empty__rule"></div>
|
||||||
|
<a class="library-empty__cta" href="#">
|
||||||
|
<svg viewBox="0 0 24 24"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
||||||
|
Upload the first photograph
|
||||||
|
</a>
|
||||||
|
<div class="library-empty__or">— or <a href="#">invite someone else</a> to send one</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="signature">
|
||||||
|
<div class="signature__mark"><img src="../assets/mark-photo-64.png" alt=""></div>
|
||||||
|
<div class="signature__text">WeVisto <span class="v-mark">·</span> a frame, gifted</div>
|
||||||
|
<div class="signature__version">Edizione I · MMXXVI</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="bottom-nav">
|
||||||
|
<a class="bottom-nav__tab"><svg viewBox="0 0 24 24"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9,22 9,12 15,12 15,22"/></svg><span class="label">Home</span></a>
|
||||||
|
<a class="bottom-nav__tab active"><svg viewBox="0 0 24 24"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></svg><span class="label">Library</span></a>
|
||||||
|
<a class="bottom-nav__tab"><svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/></svg><span class="label">Settings</span></a>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
|
<title>WeVisto — loading</title>
|
||||||
|
<style>
|
||||||
|
:root { --yellow: #f0d000; --cream: #faf3e4; --navy: #07172a; }
|
||||||
|
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||||
|
html, body { width: 100%; height: 100%; overflow: hidden; background: var(--navy); color: var(--cream); }
|
||||||
|
body { position: relative; display: flex; align-items: center; justify-content: center; }
|
||||||
|
|
||||||
|
/* harbor backdrop, Ken-Burns */
|
||||||
|
.bg {
|
||||||
|
position: absolute; inset: -4%;
|
||||||
|
background: url('../assets/harbor.jpg') center/cover no-repeat;
|
||||||
|
filter: brightness(0.45) saturate(0.85);
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(1.04);
|
||||||
|
animation:
|
||||||
|
bd-fade 1.4s 0.1s cubic-bezier(.2,.7,.2,1) forwards,
|
||||||
|
bd-zoom 26s 0.1s linear forwards;
|
||||||
|
}
|
||||||
|
@keyframes bd-fade { to { opacity: 0.5; } }
|
||||||
|
@keyframes bd-zoom { from { transform: scale(1.04); } to { transform: scale(1.14) translate(-2%, -1%); } }
|
||||||
|
|
||||||
|
.vignette {
|
||||||
|
position: absolute; inset: 0; pointer-events: none;
|
||||||
|
background:
|
||||||
|
radial-gradient(ellipse 70% 65% at 50% 50%, transparent 0%, rgba(7,23,42,0.6) 65%, rgba(7,23,42,0.95) 100%);
|
||||||
|
}
|
||||||
|
.grain {
|
||||||
|
position: absolute; inset: 0; pointer-events: none;
|
||||||
|
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='320' height='320'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='5'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.16 0'/></filter><rect width='320' height='320' filter='url(%23n)'/></svg>");
|
||||||
|
mix-blend-mode: overlay;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* THE LOGO — the full wordmark logo at hero scale */
|
||||||
|
.logo {
|
||||||
|
position: relative; z-index: 5;
|
||||||
|
width: min(78vw, 520px);
|
||||||
|
aspect-ratio: 1;
|
||||||
|
border-radius: 14px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow:
|
||||||
|
0 1px 0 rgba(255,240,200,0.15) inset,
|
||||||
|
0 32px 64px -16px rgba(0,0,0,0.7),
|
||||||
|
0 12px 28px -8px rgba(0,0,0,0.5);
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(12px) scale(0.98);
|
||||||
|
animation: logo-in 1.6s 0.4s cubic-bezier(.2,.7,.2,1) forwards;
|
||||||
|
}
|
||||||
|
@keyframes logo-in { to { opacity: 1; transform: translateY(0) scale(1); } }
|
||||||
|
.logo img { width: 100%; height: 100%; display: block; }
|
||||||
|
|
||||||
|
/* loader pulse below — dim brand confirmation */
|
||||||
|
.loader {
|
||||||
|
position: absolute; bottom: 56px; left: 0; right: 0;
|
||||||
|
text-align: center;
|
||||||
|
z-index: 5;
|
||||||
|
display: flex; align-items: center; justify-content: center; gap: 8px;
|
||||||
|
opacity: 0;
|
||||||
|
animation: tag-in 1.2s 1.8s ease forwards;
|
||||||
|
}
|
||||||
|
.loader .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--yellow); animation: pulse 1.4s infinite ease-in-out; }
|
||||||
|
.loader .dot:nth-child(2) { animation-delay: 0.18s; }
|
||||||
|
.loader .dot:nth-child(3) { animation-delay: 0.36s; }
|
||||||
|
@keyframes pulse { 0%, 80%, 100% { opacity: 0.25; transform: scale(0.85); } 40% { opacity: 1; transform: scale(1.2); } }
|
||||||
|
@keyframes tag-in { to { opacity: 0.85; transform: translateY(0); } }
|
||||||
|
|
||||||
|
.stamp {
|
||||||
|
position: absolute; top: 32px; right: 32px;
|
||||||
|
font-family: Georgia, serif;
|
||||||
|
font-size: 11px; letter-spacing: 0.46em; color: var(--cream);
|
||||||
|
text-transform: uppercase;
|
||||||
|
opacity: 0;
|
||||||
|
animation: tag-in 1.4s 2.0s ease forwards;
|
||||||
|
}
|
||||||
|
.stamp .y { color: var(--yellow); }
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.bg, .logo, .loader, .stamp { animation: none !important; opacity: 1 !important; transform: none !important; }
|
||||||
|
.bg { opacity: 0.5; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="bg"></div>
|
||||||
|
<div class="vignette"></div>
|
||||||
|
<div class="grain"></div>
|
||||||
|
|
||||||
|
<div class="stamp">Edizione I <span class="y">·</span> Plate i</div>
|
||||||
|
|
||||||
|
<div class="logo">
|
||||||
|
<img src="../assets/wordmark.svg" alt="WeVisto">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="loader"><span class="dot"></span><span class="dot"></span><span class="dot"></span></div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,183 @@
|
|||||||
|
/* Frosted-glass chrome — same vocabulary as the login.
|
||||||
|
Every surface that holds content is a glass card over the harbor backdrop. */
|
||||||
|
|
||||||
|
/* ─── Top app bar — translucent dark band ────────────────────────────── */
|
||||||
|
.app-bar {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 40;
|
||||||
|
background: var(--glass-2);
|
||||||
|
backdrop-filter: saturate(180%) blur(18px);
|
||||||
|
-webkit-backdrop-filter: saturate(180%) blur(18px);
|
||||||
|
border-bottom: 1px solid var(--glass-bord);
|
||||||
|
padding: 12px 18px;
|
||||||
|
padding-top: calc(12px + env(safe-area-inset-top));
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
.app-bar__mark {
|
||||||
|
width: 34px;
|
||||||
|
height: 34px;
|
||||||
|
border-radius: 9px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 2px 6px rgba(0,0,0,0.4);
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.app-bar__mark img { width: 100%; height: 100%; display: block; }
|
||||||
|
.app-bar__title-group { display: flex; flex-direction: column; }
|
||||||
|
.app-bar__wordmark {
|
||||||
|
font: 400 var(--text-lg)/1 var(--font-display);
|
||||||
|
letter-spacing: 0.005em;
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
.app-bar__wordmark .v { color: var(--brand-yellow); }
|
||||||
|
.app-bar__sub {
|
||||||
|
font: italic 400 13px/1 var(--font-accent);
|
||||||
|
color: var(--text-muted);
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
.app-bar__spacer { flex: 1; }
|
||||||
|
.app-bar__icon {
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: var(--text-muted);
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
border-radius: var(--radius-full);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out);
|
||||||
|
}
|
||||||
|
.app-bar__icon:hover { background: var(--glass); color: var(--text); }
|
||||||
|
.app-bar__icon svg { width: 20px; height: 20px; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
|
||||||
|
|
||||||
|
/* ─── Glass surface mixin ──────────────────────────────────────────────── */
|
||||||
|
.glass {
|
||||||
|
background: var(--glass);
|
||||||
|
backdrop-filter: saturate(160%) blur(20px);
|
||||||
|
-webkit-backdrop-filter: saturate(160%) blur(20px);
|
||||||
|
border: 1px solid var(--glass-bord);
|
||||||
|
box-shadow:
|
||||||
|
0 1px 0 rgba(255,255,255,0.06) inset,
|
||||||
|
0 20px 40px -16px rgba(0,0,0,0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ─── Bottom nav — translucent dark band ─────────────────────────────── */
|
||||||
|
.bottom-nav {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0; left: 0; right: 0;
|
||||||
|
background: var(--glass-2);
|
||||||
|
backdrop-filter: saturate(180%) blur(20px);
|
||||||
|
-webkit-backdrop-filter: saturate(180%) blur(20px);
|
||||||
|
border-top: 1px solid var(--glass-bord);
|
||||||
|
display: flex;
|
||||||
|
z-index: 50;
|
||||||
|
padding-bottom: env(safe-area-inset-bottom);
|
||||||
|
}
|
||||||
|
.bottom-nav__tab {
|
||||||
|
flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
|
||||||
|
gap: 2px; height: 64px; color: var(--text-muted);
|
||||||
|
text-decoration: none; min-height: 44px;
|
||||||
|
transition: color var(--duration-fast);
|
||||||
|
}
|
||||||
|
.bottom-nav__tab.active {
|
||||||
|
color: var(--brand-yellow);
|
||||||
|
}
|
||||||
|
.bottom-nav__tab.active .label { color: var(--text); }
|
||||||
|
.bottom-nav__tab svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 2; }
|
||||||
|
.bottom-nav__tab .label {
|
||||||
|
font-family: var(--font-display);
|
||||||
|
font-size: var(--text-xs);
|
||||||
|
letter-spacing: 0.16em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-scroll {
|
||||||
|
padding-bottom: calc(64px + env(safe-area-inset-bottom) + 32px);
|
||||||
|
min-height: 100dvh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ─── Brand signature ─────────────────────────────────────────────────── */
|
||||||
|
.signature {
|
||||||
|
margin-top: 32px;
|
||||||
|
padding: 32px 0 16px;
|
||||||
|
border-top: 1px solid var(--glass-bord);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
.signature__mark {
|
||||||
|
width: 44px;
|
||||||
|
height: 44px;
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
.signature__mark img { width: 100%; height: 100%; display: block; }
|
||||||
|
.signature__text {
|
||||||
|
font: 400 14px/1.2 var(--font-display);
|
||||||
|
letter-spacing: 0.32em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--text-muted);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
.signature__text .v-mark { color: var(--brand-yellow); }
|
||||||
|
.signature__version {
|
||||||
|
font: 400 italic 14px/1.3 var(--font-accent);
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
color: var(--text-muted);
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ─── Theme switcher (mockup only) ─────────────────────────────────────── */
|
||||||
|
.theme-switcher {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 84px;
|
||||||
|
right: 16px;
|
||||||
|
z-index: 60;
|
||||||
|
background: var(--glass-2);
|
||||||
|
backdrop-filter: saturate(180%) blur(20px);
|
||||||
|
border: 1px solid var(--glass-bord);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
box-shadow: 0 12px 24px -8px rgba(0,0,0,0.5);
|
||||||
|
padding: 10px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
max-width: 220px;
|
||||||
|
}
|
||||||
|
.theme-switcher__label {
|
||||||
|
font: var(--type-label);
|
||||||
|
letter-spacing: 0.24em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--text-muted);
|
||||||
|
}
|
||||||
|
.theme-switcher__chips {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
.theme-switcher__chip {
|
||||||
|
width: 26px; height: 26px;
|
||||||
|
border: 2px solid var(--glass-bord);
|
||||||
|
border-radius: var(--radius-full);
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
transition: transform var(--duration-fast);
|
||||||
|
}
|
||||||
|
.theme-switcher__chip:hover { transform: scale(1.1); }
|
||||||
|
.theme-switcher__chip.active { box-shadow: 0 0 0 2px var(--brand-yellow); }
|
||||||
|
/* each chip shows that theme's accent over its bg-base */
|
||||||
|
.theme-switcher__chip[data-theme="ocean-dusk"] { background: linear-gradient(135deg, #06121f 50%, #4e9fc8 50%); }
|
||||||
|
.theme-switcher__chip[data-theme="amber-dusk"] { background: linear-gradient(135deg, #1a0d05 50%, #e89048 50%); }
|
||||||
|
.theme-switcher__chip[data-theme="sage-dusk"] { background: linear-gradient(135deg, #081208 50%, #88c068 50%); }
|
||||||
|
.theme-switcher__chip[data-theme="rose-dusk"] { background: linear-gradient(135deg, #1a060f 50%, #d878a0 50%); }
|
||||||
|
.theme-switcher__chip[data-theme="mauve-dusk"] { background: linear-gradient(135deg, #100618 50%, #b890d8 50%); }
|
||||||
|
.theme-switcher__chip[data-theme="honey-dusk"] { background: linear-gradient(135deg, #18120a 50%, #e8c050 50%); }
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<div class="theme-switcher" role="region" aria-label="Theme switcher (mockup only)">
|
||||||
|
<span class="theme-switcher__label">User-pref theme</span>
|
||||||
|
<div class="theme-switcher__chips">
|
||||||
|
<button class="theme-switcher__chip active" data-theme="warm-craft" title="warm-craft"></button>
|
||||||
|
<button class="theme-switcher__chip" data-theme="ocean-dusk" title="ocean-dusk"></button>
|
||||||
|
<button class="theme-switcher__chip" data-theme="sage-cream" title="sage-cream"></button>
|
||||||
|
<button class="theme-switcher__chip" data-theme="playful-pop" title="playful-pop"></button>
|
||||||
|
<button class="theme-switcher__chip" data-theme="dusty-mauve" title="dusty-mauve"></button>
|
||||||
|
<button class="theme-switcher__chip" data-theme="honey-slate" title="honey-slate"></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
document.querySelectorAll('.theme-switcher__chip').forEach(chip => {
|
||||||
|
chip.addEventListener('click', () => {
|
||||||
|
document.documentElement.setAttribute('data-theme', chip.dataset.theme);
|
||||||
|
document.querySelectorAll('.theme-switcher__chip').forEach(c => c.classList.toggle('active', c === chip));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,164 @@
|
|||||||
|
/* Atmospheric design tokens — themes as dusks layered over the harbor photo.
|
||||||
|
The whole app shares the login's surface vocabulary. */
|
||||||
|
|
||||||
|
:root {
|
||||||
|
/* Type — same recipe as login */
|
||||||
|
--font-family: 'Nunito', system-ui, sans-serif;
|
||||||
|
--font-display: 'Marcellus', Georgia, serif;
|
||||||
|
--font-accent: 'Cormorant Garamond', Georgia, serif;
|
||||||
|
--font-mono: 'DM Mono', ui-monospace, monospace;
|
||||||
|
|
||||||
|
--text-xs: 11px; --text-sm: 13px; --text-base: 15px; --text-md: 17px;
|
||||||
|
--text-lg: 20px; --text-xl: 24px; --text-2xl: 28px; --text-3xl: 36px;
|
||||||
|
--space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px;
|
||||||
|
--space-5: 20px; --space-6: 24px; --space-8: 32px;
|
||||||
|
--radius-sm: 6px; --radius-md: 12px; --radius-lg: 20px; --radius-full: 9999px;
|
||||||
|
--duration-fast: 150ms; --duration-base: 250ms;
|
||||||
|
--ease-out: cubic-bezier(0, 0, 0.2, 1);
|
||||||
|
|
||||||
|
/* Brand layer — fixed regardless of theme. */
|
||||||
|
--brand-yellow: #f0d000;
|
||||||
|
--brand-yellow-soft: #c4a700;
|
||||||
|
|
||||||
|
/* Editorial recipes */
|
||||||
|
--type-display-xl: 400 var(--text-3xl)/1.05 var(--font-display);
|
||||||
|
--type-display-lg: 400 var(--text-2xl)/1.1 var(--font-display);
|
||||||
|
--type-display-md: 400 var(--text-xl)/1.15 var(--font-display);
|
||||||
|
--type-accent-md: 400 italic var(--text-md)/1.4 var(--font-accent);
|
||||||
|
--type-label: 700 var(--text-xs)/1 var(--font-mono);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ─── DUSKS ──────────────────────────────────────────────────────────────
|
||||||
|
Each dusk is:
|
||||||
|
--bg-base : the deep base color behind everything
|
||||||
|
--bg-tint : an rgba multiplied over the harbor photo (the "filter")
|
||||||
|
--glass : rgba background of cards (frosted, sits on photo)
|
||||||
|
--glass-2 : a more opaque variant for nav strips
|
||||||
|
--glass-bord : hairline border on glass surfaces
|
||||||
|
--accent : theme accent (was --color-primary) — CTAs that aren't brand
|
||||||
|
--accent-fg : text on accent
|
||||||
|
--text : main text on glass (always light)
|
||||||
|
--text-muted : muted text on glass
|
||||||
|
|
||||||
|
The yellow V brand constant survives across all dusks.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* OCEAN DUSK — default, closest to login */
|
||||||
|
[data-theme="ocean-dusk"], :root {
|
||||||
|
--bg-base: #06121f;
|
||||||
|
--bg-tint: rgba(8, 22, 38, 0.45);
|
||||||
|
--glass: rgba(10, 28, 48, 0.55);
|
||||||
|
--glass-2: rgba(8, 22, 38, 0.72);
|
||||||
|
--glass-bord: rgba(180, 210, 235, 0.18);
|
||||||
|
--accent: #4e9fc8;
|
||||||
|
--accent-fg: #06121f;
|
||||||
|
--text: #f4eed8;
|
||||||
|
--text-muted: #b8c8d8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* AMBER DUSK — successor to warm-craft */
|
||||||
|
[data-theme="amber-dusk"] {
|
||||||
|
--bg-base: #1a0d05;
|
||||||
|
--bg-tint: rgba(60, 25, 8, 0.45);
|
||||||
|
--glass: rgba(50, 22, 8, 0.55);
|
||||||
|
--glass-2: rgba(35, 14, 5, 0.72);
|
||||||
|
--glass-bord: rgba(230, 180, 130, 0.2);
|
||||||
|
--accent: #e89048;
|
||||||
|
--accent-fg: #1a0d05;
|
||||||
|
--text: #faecd0;
|
||||||
|
--text-muted: #d8b890;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SAGE DUSK — successor to sage-cream */
|
||||||
|
[data-theme="sage-dusk"] {
|
||||||
|
--bg-base: #081208;
|
||||||
|
--bg-tint: rgba(20, 40, 22, 0.45);
|
||||||
|
--glass: rgba(18, 38, 22, 0.55);
|
||||||
|
--glass-2: rgba(12, 26, 14, 0.72);
|
||||||
|
--glass-bord: rgba(180, 220, 180, 0.18);
|
||||||
|
--accent: #88c068;
|
||||||
|
--accent-fg: #081208;
|
||||||
|
--text: #ecf3e0;
|
||||||
|
--text-muted: #a8c0a0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ROSE DUSK — warmer, classier replacement for playful-pop */
|
||||||
|
[data-theme="rose-dusk"] {
|
||||||
|
--bg-base: #1a060f;
|
||||||
|
--bg-tint: rgba(56, 16, 38, 0.45);
|
||||||
|
--glass: rgba(48, 14, 36, 0.55);
|
||||||
|
--glass-2: rgba(32, 8, 22, 0.72);
|
||||||
|
--glass-bord: rgba(230, 180, 200, 0.2);
|
||||||
|
--accent: #d878a0;
|
||||||
|
--accent-fg: #1a060f;
|
||||||
|
--text: #f8e8ec;
|
||||||
|
--text-muted: #c898ac;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MAUVE DUSK — replaces dusty-mauve */
|
||||||
|
[data-theme="mauve-dusk"] {
|
||||||
|
--bg-base: #100618;
|
||||||
|
--bg-tint: rgba(40, 18, 56, 0.45);
|
||||||
|
--glass: rgba(36, 14, 50, 0.55);
|
||||||
|
--glass-2: rgba(24, 10, 34, 0.72);
|
||||||
|
--glass-bord: rgba(210, 190, 230, 0.18);
|
||||||
|
--accent: #b890d8;
|
||||||
|
--accent-fg: #100618;
|
||||||
|
--text: #f0e8f8;
|
||||||
|
--text-muted: #b8a8c8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* HONEY DUSK — replaces honey-slate */
|
||||||
|
[data-theme="honey-dusk"] {
|
||||||
|
--bg-base: #18120a;
|
||||||
|
--bg-tint: rgba(48, 36, 14, 0.45);
|
||||||
|
--glass: rgba(42, 32, 12, 0.55);
|
||||||
|
--glass-2: rgba(28, 22, 8, 0.72);
|
||||||
|
--glass-bord: rgba(232, 200, 130, 0.22);
|
||||||
|
--accent: #e8c050;
|
||||||
|
--accent-fg: #18120a;
|
||||||
|
--text: #faf0d8;
|
||||||
|
--text-muted: #c8b888;
|
||||||
|
}
|
||||||
|
|
||||||
|
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||||
|
html, body { background: var(--bg-base); color: var(--text); }
|
||||||
|
body {
|
||||||
|
font-family: var(--font-family);
|
||||||
|
font-size: var(--text-base);
|
||||||
|
line-height: 1.5;
|
||||||
|
min-height: 100dvh;
|
||||||
|
position: relative;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ─── PERMANENT ATMOSPHERIC BACKDROP ──────────────────────────────────── */
|
||||||
|
/* harbor photo fixed under everything */
|
||||||
|
body::before {
|
||||||
|
content: '';
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
background: url('../assets/harbor.jpg') center/cover no-repeat;
|
||||||
|
filter: brightness(0.6) saturate(0.85);
|
||||||
|
z-index: -3;
|
||||||
|
}
|
||||||
|
/* theme tint multiplied over photo */
|
||||||
|
body::after {
|
||||||
|
content: '';
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
background: var(--bg-tint);
|
||||||
|
mix-blend-mode: multiply;
|
||||||
|
z-index: -2;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
/* global vignette + film grain via one extra layer */
|
||||||
|
.atmosphere {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: -1;
|
||||||
|
background:
|
||||||
|
radial-gradient(ellipse 80% 70% at 50% 45%, transparent 0%, rgba(0,0,0,0.35) 70%, rgba(0,0,0,0.65) 100%),
|
||||||
|
url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='320' height='320'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='5'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.1 0'/></filter><rect width='320' height='320' filter='url(%23n)'/></svg>");
|
||||||
|
}
|
||||||
@@ -0,0 +1,310 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en" data-theme="ocean-dusk">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
|
<title>Home — WeVisto</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=Nunito:wght@400;600;700;900&family=Marcellus&family=Cormorant+Garamond:ital,wght@1,400&family=DM+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="_tokens.css">
|
||||||
|
<link rel="stylesheet" href="_chrome.css">
|
||||||
|
<style>
|
||||||
|
/* ─── hero — editorial moment, sits directly on the photo ──────────── */
|
||||||
|
.hero {
|
||||||
|
padding: var(--space-6) var(--space-5) var(--space-5);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.hero__plate {
|
||||||
|
font: var(--type-label);
|
||||||
|
letter-spacing: 0.32em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--text-muted);
|
||||||
|
margin-bottom: var(--space-3);
|
||||||
|
display: flex; align-items: center; gap: 10px;
|
||||||
|
}
|
||||||
|
.hero__plate .roman { color: var(--brand-yellow); font-family: var(--font-display); font-size: var(--text-md); }
|
||||||
|
.hero__plate .sep { width: 24px; height: 1px; background: var(--glass-bord); }
|
||||||
|
.hero__greeting {
|
||||||
|
font: var(--type-display-lg);
|
||||||
|
color: var(--text);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
.hero__greeting em {
|
||||||
|
font-family: var(--font-accent);
|
||||||
|
font-style: italic;
|
||||||
|
color: var(--brand-yellow);
|
||||||
|
}
|
||||||
|
.hero__sub {
|
||||||
|
font: var(--type-accent-md);
|
||||||
|
color: var(--text-muted);
|
||||||
|
line-height: 1.5;
|
||||||
|
max-width: 38ch;
|
||||||
|
}
|
||||||
|
.hero__sub strong { color: var(--text); font-style: normal; font-family: var(--font-display); font-weight: 400; }
|
||||||
|
.hero__rule {
|
||||||
|
margin-top: var(--space-4);
|
||||||
|
width: 80px; height: 1px;
|
||||||
|
background: linear-gradient(90deg, var(--brand-yellow), transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ─── frame card — frosted glass, the user's photo is the inner content ── */
|
||||||
|
.frame-card {
|
||||||
|
margin: var(--space-5);
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
overflow: hidden;
|
||||||
|
/* uses .glass class for the frost effect */
|
||||||
|
}
|
||||||
|
.frame-card__hero {
|
||||||
|
aspect-ratio: 4/3;
|
||||||
|
background-image: url('../assets/harbor.jpg');
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
position: relative;
|
||||||
|
/* the user's frame photo — keep at full saturation (it's user content, not brand backdrop) */
|
||||||
|
}
|
||||||
|
.frame-card__status {
|
||||||
|
position: absolute;
|
||||||
|
top: 14px; left: 14px;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
background: rgba(8, 18, 30, 0.7);
|
||||||
|
backdrop-filter: blur(8px);
|
||||||
|
padding: 6px 12px;
|
||||||
|
border-radius: var(--radius-full);
|
||||||
|
font: var(--type-label);
|
||||||
|
color: var(--text);
|
||||||
|
letter-spacing: 0.22em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
.frame-card__status .dot {
|
||||||
|
width: 7px; height: 7px;
|
||||||
|
background: #6cd498;
|
||||||
|
border-radius: 50%;
|
||||||
|
box-shadow: 0 0 0 3px rgba(108, 212, 152, 0.25);
|
||||||
|
}
|
||||||
|
.frame-card__plate {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 14px; left: 14px;
|
||||||
|
font: var(--type-label);
|
||||||
|
background: rgba(8, 18, 30, 0.7);
|
||||||
|
color: var(--text);
|
||||||
|
padding: 5px 10px;
|
||||||
|
letter-spacing: 0.28em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
backdrop-filter: blur(6px);
|
||||||
|
}
|
||||||
|
.frame-card__body { padding: var(--space-5) var(--space-5) var(--space-4); }
|
||||||
|
.frame-card__name {
|
||||||
|
font: var(--type-display-md);
|
||||||
|
color: var(--text);
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
.frame-card__meta {
|
||||||
|
font: italic 400 15px/1.4 var(--font-accent);
|
||||||
|
color: var(--text-muted);
|
||||||
|
margin-bottom: var(--space-4);
|
||||||
|
}
|
||||||
|
.frame-card__meta .sep { margin: 0 8px; opacity: 0.4; }
|
||||||
|
.frame-card__schedule {
|
||||||
|
background: rgba(255, 255, 255, 0.06);
|
||||||
|
border: 1px solid var(--glass-bord);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
padding: var(--space-4);
|
||||||
|
margin-bottom: var(--space-4);
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: var(--space-3);
|
||||||
|
font-size: var(--text-sm);
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
.frame-card__schedule svg {
|
||||||
|
width: 18px; height: 18px;
|
||||||
|
stroke: var(--brand-yellow);
|
||||||
|
fill: none;
|
||||||
|
stroke-width: 2;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
.frame-card__schedule strong { font-family: var(--font-display); font-size: var(--text-base); font-weight: 400; color: var(--text); display: block; margin-bottom: 2px; }
|
||||||
|
.frame-card__schedule span { color: var(--text-muted); }
|
||||||
|
.frame-card__actions { display: flex; gap: var(--space-3); }
|
||||||
|
.btn {
|
||||||
|
flex: 1;
|
||||||
|
padding: 14px 20px;
|
||||||
|
font-family: var(--font-family);
|
||||||
|
font-size: var(--text-base);
|
||||||
|
font-weight: 700;
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
border: 1px solid var(--glass-bord);
|
||||||
|
background: rgba(255, 255, 255, 0.06);
|
||||||
|
color: var(--text);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background var(--duration-fast);
|
||||||
|
display: inline-flex; align-items: center; justify-content: center; gap: 8px;
|
||||||
|
}
|
||||||
|
.btn:hover { background: rgba(255, 255, 255, 0.12); }
|
||||||
|
.btn--primary {
|
||||||
|
background: var(--accent);
|
||||||
|
color: var(--accent-fg);
|
||||||
|
border-color: var(--accent);
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.btn--primary:hover { filter: brightness(1.08); }
|
||||||
|
.btn svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 2; }
|
||||||
|
|
||||||
|
/* ─── upcoming photos strip — quiet teaser of what's queued ─────────── */
|
||||||
|
.upcoming {
|
||||||
|
margin: var(--space-5);
|
||||||
|
padding: var(--space-5);
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
}
|
||||||
|
.upcoming__head {
|
||||||
|
display: flex; align-items: baseline; justify-content: space-between;
|
||||||
|
margin-bottom: var(--space-4);
|
||||||
|
}
|
||||||
|
.upcoming__title {
|
||||||
|
font: var(--type-display-md);
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
.upcoming__hint {
|
||||||
|
font: var(--type-accent-md);
|
||||||
|
color: var(--text-muted);
|
||||||
|
}
|
||||||
|
.upcoming__row {
|
||||||
|
display: flex; gap: var(--space-3); overflow-x: auto; padding-bottom: 4px;
|
||||||
|
}
|
||||||
|
.upcoming__row::-webkit-scrollbar { display: none; }
|
||||||
|
.upcoming__row { scrollbar-width: none; }
|
||||||
|
.thumb {
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 92px; height: 92px;
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
overflow: hidden;
|
||||||
|
background: rgba(0,0,0,0.3);
|
||||||
|
position: relative;
|
||||||
|
border: 1px solid var(--glass-bord);
|
||||||
|
}
|
||||||
|
.thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
||||||
|
.thumb .when {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 4px; left: 4px;
|
||||||
|
font: var(--type-label);
|
||||||
|
background: rgba(0,0,0,0.7);
|
||||||
|
color: var(--text);
|
||||||
|
padding: 2px 6px;
|
||||||
|
letter-spacing: 0.18em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="atmosphere"></div>
|
||||||
|
|
||||||
|
<header class="app-bar">
|
||||||
|
<div class="app-bar__mark"><img src="../assets/mark-photo-64.png" alt=""></div>
|
||||||
|
<div class="app-bar__title-group">
|
||||||
|
<div class="app-bar__wordmark">We<span class="v">V</span>isto</div>
|
||||||
|
<div class="app-bar__sub">— Margaret's frame</div>
|
||||||
|
</div>
|
||||||
|
<div class="app-bar__spacer"></div>
|
||||||
|
<button class="app-bar__icon" aria-label="Notifications">
|
||||||
|
<svg viewBox="0 0 24 24"><path d="M18 8a6 6 0 0 0-12 0c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg>
|
||||||
|
</button>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main class="main-scroll">
|
||||||
|
|
||||||
|
<section class="hero">
|
||||||
|
<div class="hero__plate"><span class="roman">I.</span><span class="sep"></span><span>Plate · today</span></div>
|
||||||
|
<h1 class="hero__greeting">Good morning, <em>Alice.</em></h1>
|
||||||
|
<p class="hero__sub">Margaret's frame is in sync. The next photograph will arrive at <strong>7:00 AM</strong>, quietly, on its own.</p>
|
||||||
|
<div class="hero__rule"></div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<article class="frame-card glass">
|
||||||
|
<div class="frame-card__hero">
|
||||||
|
<div class="frame-card__status">
|
||||||
|
<span class="dot"></span><span>Synced 12 min ago</span>
|
||||||
|
</div>
|
||||||
|
<div class="frame-card__plate">Plate XII</div>
|
||||||
|
</div>
|
||||||
|
<div class="frame-card__body">
|
||||||
|
<h2 class="frame-card__name">Margaret's frame</h2>
|
||||||
|
<p class="frame-card__meta">7.3″ landscape <span class="sep">·</span> Camden, Maine <span class="sep">·</span> est. May 2026</p>
|
||||||
|
|
||||||
|
<div class="frame-card__schedule">
|
||||||
|
<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
|
||||||
|
<div>
|
||||||
|
<strong>Next photograph at 7:00 AM</strong>
|
||||||
|
<span>then again at 12:00 PM and 6:00 PM</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="frame-card__actions">
|
||||||
|
<button class="btn btn--primary">
|
||||||
|
<svg viewBox="0 0 24 24"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
||||||
|
Add photograph
|
||||||
|
</button>
|
||||||
|
<button class="btn">
|
||||||
|
<svg viewBox="0 0 24 24"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>
|
||||||
|
Settings
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<section class="upcoming glass">
|
||||||
|
<div class="upcoming__head">
|
||||||
|
<h3 class="upcoming__title">Up next</h3>
|
||||||
|
<span class="upcoming__hint">— in the library queue</span>
|
||||||
|
</div>
|
||||||
|
<div class="upcoming__row">
|
||||||
|
<div class="thumb"><img src="../assets/harbor.jpg" alt=""><span class="when">7am</span></div>
|
||||||
|
<div class="thumb"><img src="../assets/harbor.jpg" alt="" style="filter: hue-rotate(40deg);"><span class="when">noon</span></div>
|
||||||
|
<div class="thumb"><img src="../assets/harbor.jpg" alt="" style="filter: hue-rotate(-30deg) saturate(1.2);"><span class="when">6pm</span></div>
|
||||||
|
<div class="thumb"><img src="../assets/harbor.jpg" alt="" style="filter: brightness(0.85);"><span class="when">tmrw</span></div>
|
||||||
|
<div class="thumb"><img src="../assets/harbor.jpg" alt="" style="filter: sepia(0.4);"><span class="when">+5</span></div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="bottom-nav">
|
||||||
|
<a class="bottom-nav__tab active" href="home.html">
|
||||||
|
<svg viewBox="0 0 24 24"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9,22 9,12 15,12 15,22"/></svg>
|
||||||
|
<span class="label">Home</span>
|
||||||
|
</a>
|
||||||
|
<a class="bottom-nav__tab" href="library.html">
|
||||||
|
<svg viewBox="0 0 24 24"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></svg>
|
||||||
|
<span class="label">Library</span>
|
||||||
|
</a>
|
||||||
|
<a class="bottom-nav__tab" href="settings.html">
|
||||||
|
<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>
|
||||||
|
<span class="label">Settings</span>
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="theme-switcher" role="region" aria-label="Theme switcher (mockup only)">
|
||||||
|
<span class="theme-switcher__label">Dusk</span>
|
||||||
|
<div class="theme-switcher__chips">
|
||||||
|
<button class="theme-switcher__chip active" data-theme="ocean-dusk" title="Ocean dusk"></button>
|
||||||
|
<button class="theme-switcher__chip" data-theme="amber-dusk" title="Amber dusk"></button>
|
||||||
|
<button class="theme-switcher__chip" data-theme="sage-dusk" title="Sage dusk"></button>
|
||||||
|
<button class="theme-switcher__chip" data-theme="rose-dusk" title="Rose dusk"></button>
|
||||||
|
<button class="theme-switcher__chip" data-theme="mauve-dusk" title="Mauve dusk"></button>
|
||||||
|
<button class="theme-switcher__chip" data-theme="honey-dusk" title="Honey dusk"></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
document.querySelectorAll('.theme-switcher__chip').forEach(chip => {
|
||||||
|
chip.addEventListener('click', () => {
|
||||||
|
document.documentElement.setAttribute('data-theme', chip.dataset.theme);
|
||||||
|
document.querySelectorAll('.theme-switcher__chip').forEach(c => c.classList.toggle('active', c === chip));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,249 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en" data-theme="ocean-dusk">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
|
<title>Library — WeVisto</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=Nunito:wght@400;600;700;900&family=Marcellus&family=Cormorant+Garamond:ital,wght@1,400&family=DM+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="_tokens.css">
|
||||||
|
<link rel="stylesheet" href="_chrome.css">
|
||||||
|
<style>
|
||||||
|
.library-empty {
|
||||||
|
padding: 56px 24px 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.library-empty__plate {
|
||||||
|
font: var(--type-label);
|
||||||
|
letter-spacing: 0.32em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--text-muted);
|
||||||
|
margin-bottom: var(--space-5);
|
||||||
|
display: flex; align-items: center; gap: 10px;
|
||||||
|
}
|
||||||
|
.library-empty__plate .roman { color: var(--brand-yellow); font-family: var(--font-display); font-size: var(--text-md); }
|
||||||
|
.library-empty__plate .sep { width: 24px; height: 1px; background: var(--glass-bord); }
|
||||||
|
|
||||||
|
.library-empty__halo { position: relative; margin-bottom: var(--space-5); }
|
||||||
|
.library-empty__halo::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 50%; left: 50%;
|
||||||
|
width: 240px; height: 240px;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background: radial-gradient(circle, color-mix(in srgb, var(--brand-yellow) 25%, transparent), transparent 65%);
|
||||||
|
border-radius: 50%;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
.library-empty__mark {
|
||||||
|
width: 112px;
|
||||||
|
height: 112px;
|
||||||
|
border-radius: 24px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow:
|
||||||
|
0 1px 0 rgba(255,255,255,0.18) inset,
|
||||||
|
0 20px 40px -10px rgba(0,0,0,0.6),
|
||||||
|
0 8px 20px -6px rgba(0,0,0,0.4);
|
||||||
|
}
|
||||||
|
.library-empty__mark img { width: 100%; height: 100%; display: block; }
|
||||||
|
|
||||||
|
.library-empty__title {
|
||||||
|
font: var(--type-display-xl);
|
||||||
|
color: var(--text);
|
||||||
|
margin-bottom: var(--space-2);
|
||||||
|
text-shadow: 0 2px 10px rgba(0,0,0,0.3);
|
||||||
|
}
|
||||||
|
.library-empty__title em {
|
||||||
|
font-family: var(--font-accent);
|
||||||
|
font-style: italic;
|
||||||
|
color: var(--brand-yellow);
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
.library-empty__sub {
|
||||||
|
font: italic 400 18px/1.55 var(--font-accent);
|
||||||
|
color: var(--text-muted);
|
||||||
|
max-width: 36ch;
|
||||||
|
margin-bottom: var(--space-6);
|
||||||
|
}
|
||||||
|
.library-empty__rule {
|
||||||
|
width: 96px; height: 1px;
|
||||||
|
background: linear-gradient(90deg, transparent, var(--brand-yellow), transparent);
|
||||||
|
margin: 0 auto var(--space-6);
|
||||||
|
}
|
||||||
|
.library-empty__cta {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
background: var(--accent);
|
||||||
|
color: var(--accent-fg);
|
||||||
|
padding: 14px 28px;
|
||||||
|
border-radius: var(--radius-full);
|
||||||
|
font-family: var(--font-family);
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: var(--text-base);
|
||||||
|
text-decoration: none;
|
||||||
|
box-shadow: 0 8px 22px -4px color-mix(in srgb, var(--accent) 50%, transparent);
|
||||||
|
transition: transform var(--duration-fast) var(--ease-out), filter var(--duration-fast) var(--ease-out);
|
||||||
|
}
|
||||||
|
.library-empty__cta:hover { transform: translateY(-1px); filter: brightness(1.08); }
|
||||||
|
.library-empty__cta svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 2.5; stroke-linecap: round; }
|
||||||
|
.library-empty__or {
|
||||||
|
margin-top: var(--space-5);
|
||||||
|
font: italic 400 var(--text-md)/1.4 var(--font-accent);
|
||||||
|
color: var(--text-muted);
|
||||||
|
}
|
||||||
|
.library-empty__or a {
|
||||||
|
color: var(--text);
|
||||||
|
border-bottom: 1px solid var(--glass-bord);
|
||||||
|
text-decoration: none;
|
||||||
|
padding-bottom: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* steps card — frosted */
|
||||||
|
.intro-steps {
|
||||||
|
margin: 48px var(--space-5) 0;
|
||||||
|
padding: var(--space-5) var(--space-5) var(--space-6);
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.intro-steps__rule {
|
||||||
|
position: absolute;
|
||||||
|
top: -1px; left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
width: 60px; height: 1px;
|
||||||
|
background: var(--brand-yellow);
|
||||||
|
}
|
||||||
|
.intro-steps__title {
|
||||||
|
font: var(--type-display-md);
|
||||||
|
color: var(--text);
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: var(--space-2);
|
||||||
|
}
|
||||||
|
.intro-steps__title .v-mark { color: var(--brand-yellow); }
|
||||||
|
.intro-steps__sub {
|
||||||
|
font: var(--type-accent-md);
|
||||||
|
color: var(--text-muted);
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: var(--space-5);
|
||||||
|
}
|
||||||
|
.intro-steps__list { display: flex; gap: var(--space-3); }
|
||||||
|
.step { flex: 1; text-align: center; padding: var(--space-3); }
|
||||||
|
.step__num {
|
||||||
|
font-family: var(--font-display);
|
||||||
|
font-size: var(--text-2xl);
|
||||||
|
color: var(--brand-yellow);
|
||||||
|
line-height: 1;
|
||||||
|
margin-bottom: var(--space-2);
|
||||||
|
}
|
||||||
|
.step__label {
|
||||||
|
font-size: var(--text-xs);
|
||||||
|
color: var(--text-muted);
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
.step__label strong {
|
||||||
|
font-family: var(--font-display);
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: var(--text-sm);
|
||||||
|
color: var(--text);
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature { margin: 64px var(--space-5) 0; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="atmosphere"></div>
|
||||||
|
|
||||||
|
<header class="app-bar">
|
||||||
|
<div class="app-bar__mark"><img src="../assets/mark-photo-64.png" alt=""></div>
|
||||||
|
<div class="app-bar__title-group">
|
||||||
|
<div class="app-bar__wordmark">We<span class="v">V</span>isto</div>
|
||||||
|
<div class="app-bar__sub">— the library</div>
|
||||||
|
</div>
|
||||||
|
<div class="app-bar__spacer"></div>
|
||||||
|
<button class="app-bar__icon" aria-label="Filter">
|
||||||
|
<svg viewBox="0 0 24 24"><polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/></svg>
|
||||||
|
</button>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main class="main-scroll">
|
||||||
|
|
||||||
|
<div class="library-empty">
|
||||||
|
<div class="library-empty__plate"><span class="roman">○</span><span class="sep"></span><span>Accession no. 001</span></div>
|
||||||
|
<div class="library-empty__halo">
|
||||||
|
<div class="library-empty__mark"><img src="../assets/mark-photo.png" alt=""></div>
|
||||||
|
</div>
|
||||||
|
<h1 class="library-empty__title">A library, <em>waiting.</em></h1>
|
||||||
|
<p class="library-empty__sub">Photographs you upload will rotate through Margaret's frame, one at a time. We'll hold them here until the frame is ready.</p>
|
||||||
|
<div class="library-empty__rule"></div>
|
||||||
|
<a class="library-empty__cta" href="#">
|
||||||
|
<svg viewBox="0 0 24 24"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
||||||
|
Upload the first photograph
|
||||||
|
</a>
|
||||||
|
<div class="library-empty__or">— or <a href="#">invite someone else</a> to send one</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="intro-steps glass">
|
||||||
|
<div class="intro-steps__rule"></div>
|
||||||
|
<div class="intro-steps__title">How <span class="v-mark">V</span>isto works, briefly</div>
|
||||||
|
<div class="intro-steps__sub">— three steps, then forever</div>
|
||||||
|
<div class="intro-steps__list">
|
||||||
|
<div class="step"><div class="step__num">I.</div><div class="step__label"><strong>You upload</strong>family photos</div></div>
|
||||||
|
<div class="step"><div class="step__num">II.</div><div class="step__label"><strong>We hold</strong>them in the library</div></div>
|
||||||
|
<div class="step"><div class="step__num">III.</div><div class="step__label"><strong>Frame picks</strong>one each interval</div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="signature">
|
||||||
|
<div class="signature__mark"><img src="../assets/mark-photo-64.png" alt=""></div>
|
||||||
|
<div class="signature__text">WeVisto <span class="v-mark">·</span> a frame, gifted</div>
|
||||||
|
<div class="signature__version">Edizione I · MMXXVI</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="bottom-nav">
|
||||||
|
<a class="bottom-nav__tab" href="home.html">
|
||||||
|
<svg viewBox="0 0 24 24"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9,22 9,12 15,12 15,22"/></svg>
|
||||||
|
<span class="label">Home</span>
|
||||||
|
</a>
|
||||||
|
<a class="bottom-nav__tab active" href="library.html">
|
||||||
|
<svg viewBox="0 0 24 24"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></svg>
|
||||||
|
<span class="label">Library</span>
|
||||||
|
</a>
|
||||||
|
<a class="bottom-nav__tab" href="settings.html">
|
||||||
|
<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>
|
||||||
|
<span class="label">Settings</span>
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="theme-switcher" role="region" aria-label="Theme switcher (mockup only)">
|
||||||
|
<span class="theme-switcher__label">Dusk</span>
|
||||||
|
<div class="theme-switcher__chips">
|
||||||
|
<button class="theme-switcher__chip active" data-theme="ocean-dusk" title="Ocean dusk"></button>
|
||||||
|
<button class="theme-switcher__chip" data-theme="amber-dusk" title="Amber dusk"></button>
|
||||||
|
<button class="theme-switcher__chip" data-theme="sage-dusk" title="Sage dusk"></button>
|
||||||
|
<button class="theme-switcher__chip" data-theme="rose-dusk" title="Rose dusk"></button>
|
||||||
|
<button class="theme-switcher__chip" data-theme="mauve-dusk" title="Mauve dusk"></button>
|
||||||
|
<button class="theme-switcher__chip" data-theme="honey-dusk" title="Honey dusk"></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
document.querySelectorAll('.theme-switcher__chip').forEach(chip => {
|
||||||
|
chip.addEventListener('click', () => {
|
||||||
|
document.documentElement.setAttribute('data-theme', chip.dataset.theme);
|
||||||
|
document.querySelectorAll('.theme-switcher__chip').forEach(c => c.classList.toggle('active', c === chip));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,349 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en" data-theme="ocean-dusk">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
|
<title>Settings — WeVisto</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=Nunito:wght@400;600;700;900&family=Marcellus&family=Cormorant+Garamond:ital,wght@1,400&family=DM+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="_tokens.css">
|
||||||
|
<link rel="stylesheet" href="_chrome.css">
|
||||||
|
<style>
|
||||||
|
.page-title {
|
||||||
|
padding: var(--space-6) var(--space-5) var(--space-3);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.page-title__plate {
|
||||||
|
font: var(--type-label);
|
||||||
|
letter-spacing: 0.32em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--text-muted);
|
||||||
|
margin-bottom: var(--space-2);
|
||||||
|
}
|
||||||
|
.page-title__plate .v-mark { color: var(--brand-yellow); font-family: var(--font-display); font-size: var(--text-md); margin: 0 8px; }
|
||||||
|
.page-title__title {
|
||||||
|
font: var(--type-display-lg);
|
||||||
|
color: var(--text);
|
||||||
|
text-shadow: 0 2px 10px rgba(0,0,0,0.3);
|
||||||
|
}
|
||||||
|
.page-title__rule {
|
||||||
|
width: 60px; height: 1px;
|
||||||
|
margin: var(--space-3) auto 0;
|
||||||
|
background: linear-gradient(90deg, transparent, var(--brand-yellow), transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.section { margin: var(--space-6) var(--space-5) 0; }
|
||||||
|
.section__head {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: 12px;
|
||||||
|
margin-bottom: var(--space-3);
|
||||||
|
padding: 0 var(--space-2);
|
||||||
|
}
|
||||||
|
.section__roman {
|
||||||
|
font-family: var(--font-display);
|
||||||
|
font-size: var(--text-lg);
|
||||||
|
color: var(--brand-yellow);
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
.section__label {
|
||||||
|
font: var(--type-label);
|
||||||
|
letter-spacing: 0.32em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--text-muted);
|
||||||
|
}
|
||||||
|
.section__rule { flex: 1; height: 1px; background: var(--glass-bord); }
|
||||||
|
|
||||||
|
.list {
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--space-3);
|
||||||
|
padding: var(--space-4) var(--space-5);
|
||||||
|
border-bottom: 1px solid var(--glass-bord);
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background var(--duration-fast);
|
||||||
|
}
|
||||||
|
.row:last-child { border-bottom: 0; }
|
||||||
|
.row:hover { background: rgba(255,255,255,0.05); }
|
||||||
|
.row__icon { width: 22px; height: 22px; flex-shrink: 0; color: var(--text-muted); }
|
||||||
|
.row__icon svg { width: 100%; height: 100%; stroke: currentColor; fill: none; stroke-width: 2; }
|
||||||
|
.row__label {
|
||||||
|
flex: 1;
|
||||||
|
font-family: var(--font-family);
|
||||||
|
font-size: var(--text-base);
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
.row__value {
|
||||||
|
font: italic 400 14px/1.3 var(--font-accent);
|
||||||
|
color: var(--text-muted);
|
||||||
|
}
|
||||||
|
.row__chevron { color: var(--text-muted); opacity: 0.6; }
|
||||||
|
|
||||||
|
/* DUSK PICKER */
|
||||||
|
.theme-picker {
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
padding: var(--space-5);
|
||||||
|
}
|
||||||
|
.theme-picker__head {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: var(--space-4);
|
||||||
|
}
|
||||||
|
.theme-picker__title {
|
||||||
|
font: var(--type-display-md);
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
.theme-picker__hint {
|
||||||
|
font: var(--type-accent-md);
|
||||||
|
color: var(--text-muted);
|
||||||
|
}
|
||||||
|
.theme-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-3); }
|
||||||
|
.theme-swatch {
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
padding: var(--space-3);
|
||||||
|
border: 1px solid var(--glass-bord);
|
||||||
|
background: rgba(0,0,0,0.25);
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: left;
|
||||||
|
transition: transform var(--duration-fast), box-shadow var(--duration-fast);
|
||||||
|
font-family: inherit;
|
||||||
|
color: var(--text);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.theme-swatch.active {
|
||||||
|
border-color: var(--brand-yellow);
|
||||||
|
box-shadow: 0 0 0 2px color-mix(in srgb, var(--brand-yellow) 35%, transparent);
|
||||||
|
}
|
||||||
|
.theme-swatch:hover { transform: translateY(-2px); }
|
||||||
|
/* a tinted preview of harbor inside each swatch */
|
||||||
|
.theme-swatch__preview {
|
||||||
|
aspect-ratio: 3/2;
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: var(--space-2);
|
||||||
|
background-image: url('../assets/harbor.jpg');
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.theme-swatch__preview::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
mix-blend-mode: multiply;
|
||||||
|
}
|
||||||
|
.theme-swatch[data-pref="ocean-dusk"] .theme-swatch__preview::after { background: rgba(8, 22, 38, 0.55); }
|
||||||
|
.theme-swatch[data-pref="amber-dusk"] .theme-swatch__preview::after { background: rgba(60, 25, 8, 0.55); }
|
||||||
|
.theme-swatch[data-pref="sage-dusk"] .theme-swatch__preview::after { background: rgba(20, 40, 22, 0.55); }
|
||||||
|
.theme-swatch[data-pref="rose-dusk"] .theme-swatch__preview::after { background: rgba(56, 16, 38, 0.55); }
|
||||||
|
.theme-swatch[data-pref="mauve-dusk"] .theme-swatch__preview::after { background: rgba(40, 18, 56, 0.55); }
|
||||||
|
.theme-swatch[data-pref="honey-dusk"] .theme-swatch__preview::after { background: rgba(48, 36, 14, 0.55); }
|
||||||
|
.theme-swatch__name {
|
||||||
|
font-family: var(--font-display);
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--text);
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
}
|
||||||
|
.theme-swatch__italic {
|
||||||
|
font: italic 400 12px/1.2 var(--font-accent);
|
||||||
|
color: var(--text-muted);
|
||||||
|
margin-top: 2px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sign-out { margin: var(--space-6) var(--space-5); text-align: center; }
|
||||||
|
.sign-out a {
|
||||||
|
color: #e08070;
|
||||||
|
font-family: var(--font-family);
|
||||||
|
font-weight: 700;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: var(--text-base);
|
||||||
|
padding: var(--space-4) var(--space-5);
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.sign-out a:hover { text-decoration: underline; }
|
||||||
|
|
||||||
|
.signature { margin: 0 var(--space-5); }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="atmosphere"></div>
|
||||||
|
|
||||||
|
<header class="app-bar">
|
||||||
|
<div class="app-bar__mark"><img src="../assets/mark-photo-64.png" alt=""></div>
|
||||||
|
<div class="app-bar__title-group">
|
||||||
|
<div class="app-bar__wordmark">We<span class="v">V</span>isto</div>
|
||||||
|
<div class="app-bar__sub">— settings</div>
|
||||||
|
</div>
|
||||||
|
<div class="app-bar__spacer"></div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main class="main-scroll">
|
||||||
|
|
||||||
|
<div class="page-title">
|
||||||
|
<div class="page-title__plate">Settings <span class="v-mark">·</span> Plate i</div>
|
||||||
|
<h1 class="page-title__title">A few quiet choices.</h1>
|
||||||
|
<div class="page-title__rule"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<div class="section__head"><span class="section__roman">I.</span><span class="section__label">Account</span><span class="section__rule"></span></div>
|
||||||
|
<div class="list glass">
|
||||||
|
<a class="row">
|
||||||
|
<span class="row__icon"><svg viewBox="0 0 24 24"><circle cx="12" cy="8" r="4"/><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/></svg></span>
|
||||||
|
<span class="row__label">Alice Wexler</span>
|
||||||
|
<span class="row__value">alice@example.com</span>
|
||||||
|
<span class="row__chevron">›</span>
|
||||||
|
</a>
|
||||||
|
<a class="row">
|
||||||
|
<span class="row__icon"><svg viewBox="0 0 24 24"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg></span>
|
||||||
|
<span class="row__label">Notification email</span>
|
||||||
|
<span class="row__value">daily digest</span>
|
||||||
|
<span class="row__chevron">›</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<div class="section__head"><span class="section__roman">II.</span><span class="section__label">Appearance</span><span class="section__rule"></span></div>
|
||||||
|
<div class="theme-picker glass">
|
||||||
|
<div class="theme-picker__head">
|
||||||
|
<div class="theme-picker__title">Dusk</div>
|
||||||
|
<div class="theme-picker__hint">— pick a tint for the room</div>
|
||||||
|
</div>
|
||||||
|
<div class="theme-grid">
|
||||||
|
<button class="theme-swatch active" data-pref="ocean-dusk">
|
||||||
|
<div class="theme-swatch__preview"></div>
|
||||||
|
<div class="theme-swatch__name">Ocean dusk</div>
|
||||||
|
<span class="theme-swatch__italic">— the harbor</span>
|
||||||
|
</button>
|
||||||
|
<button class="theme-swatch" data-pref="amber-dusk">
|
||||||
|
<div class="theme-swatch__preview"></div>
|
||||||
|
<div class="theme-swatch__name">Amber dusk</div>
|
||||||
|
<span class="theme-swatch__italic">— the workshop</span>
|
||||||
|
</button>
|
||||||
|
<button class="theme-swatch" data-pref="sage-dusk">
|
||||||
|
<div class="theme-swatch__preview"></div>
|
||||||
|
<div class="theme-swatch__name">Sage dusk</div>
|
||||||
|
<span class="theme-swatch__italic">— the garden</span>
|
||||||
|
</button>
|
||||||
|
<button class="theme-swatch" data-pref="rose-dusk">
|
||||||
|
<div class="theme-swatch__preview"></div>
|
||||||
|
<div class="theme-swatch__name">Rose dusk</div>
|
||||||
|
<span class="theme-swatch__italic">— the parlor</span>
|
||||||
|
</button>
|
||||||
|
<button class="theme-swatch" data-pref="mauve-dusk">
|
||||||
|
<div class="theme-swatch__preview"></div>
|
||||||
|
<div class="theme-swatch__name">Mauve dusk</div>
|
||||||
|
<span class="theme-swatch__italic">— the study</span>
|
||||||
|
</button>
|
||||||
|
<button class="theme-swatch" data-pref="honey-dusk">
|
||||||
|
<div class="theme-swatch__preview"></div>
|
||||||
|
<div class="theme-swatch__name">Honey dusk</div>
|
||||||
|
<span class="theme-swatch__italic">— the alcove</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<div class="section__head"><span class="section__roman">III.</span><span class="section__label">Frames</span><span class="section__rule"></span></div>
|
||||||
|
<div class="list glass">
|
||||||
|
<a class="row">
|
||||||
|
<span class="row__icon"><svg viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21,15 16,10 5,21"/></svg></span>
|
||||||
|
<span class="row__label">Margaret's frame</span>
|
||||||
|
<span class="row__value">7.3″ landscape</span>
|
||||||
|
<span class="row__chevron">›</span>
|
||||||
|
</a>
|
||||||
|
<a class="row">
|
||||||
|
<span class="row__icon"><svg viewBox="0 0 24 24"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg></span>
|
||||||
|
<span class="row__label">Add another frame</span>
|
||||||
|
<span class="row__chevron">›</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<div class="section__head"><span class="section__roman">IV.</span><span class="section__label">Help</span><span class="section__rule"></span></div>
|
||||||
|
<div class="list glass">
|
||||||
|
<a class="row">
|
||||||
|
<span class="row__icon"><svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg></span>
|
||||||
|
<span class="row__label">How WeVisto works</span>
|
||||||
|
<span class="row__chevron">›</span>
|
||||||
|
</a>
|
||||||
|
<a class="row">
|
||||||
|
<span class="row__icon"><svg viewBox="0 0 24 24"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/></svg></span>
|
||||||
|
<span class="row__label">Contact us</span>
|
||||||
|
<span class="row__chevron">›</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sign-out"><a href="#">Sign out</a></div>
|
||||||
|
|
||||||
|
<div class="signature">
|
||||||
|
<div class="signature__mark"><img src="../assets/mark-photo-64.png" alt=""></div>
|
||||||
|
<div class="signature__text">WeVisto <span class="v-mark">·</span> a frame, gifted</div>
|
||||||
|
<div class="signature__version">Edizione I · MMXXVI · Camogli</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="bottom-nav">
|
||||||
|
<a class="bottom-nav__tab" href="home.html">
|
||||||
|
<svg viewBox="0 0 24 24"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9,22 9,12 15,12 15,22"/></svg>
|
||||||
|
<span class="label">Home</span>
|
||||||
|
</a>
|
||||||
|
<a class="bottom-nav__tab" href="library.html">
|
||||||
|
<svg viewBox="0 0 24 24"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></svg>
|
||||||
|
<span class="label">Library</span>
|
||||||
|
</a>
|
||||||
|
<a class="bottom-nav__tab active" href="settings.html">
|
||||||
|
<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>
|
||||||
|
<span class="label">Settings</span>
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="theme-switcher" role="region" aria-label="Theme switcher (mockup only)">
|
||||||
|
<span class="theme-switcher__label">Dusk</span>
|
||||||
|
<div class="theme-switcher__chips">
|
||||||
|
<button class="theme-switcher__chip active" data-theme="ocean-dusk" title="Ocean dusk"></button>
|
||||||
|
<button class="theme-switcher__chip" data-theme="amber-dusk" title="Amber dusk"></button>
|
||||||
|
<button class="theme-switcher__chip" data-theme="sage-dusk" title="Sage dusk"></button>
|
||||||
|
<button class="theme-switcher__chip" data-theme="rose-dusk" title="Rose dusk"></button>
|
||||||
|
<button class="theme-switcher__chip" data-theme="mauve-dusk" title="Mauve dusk"></button>
|
||||||
|
<button class="theme-switcher__chip" data-theme="honey-dusk" title="Honey dusk"></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
document.querySelectorAll('.theme-switcher__chip').forEach(chip => {
|
||||||
|
chip.addEventListener('click', () => {
|
||||||
|
const t = chip.dataset.theme;
|
||||||
|
document.documentElement.setAttribute('data-theme', t);
|
||||||
|
document.querySelectorAll('.theme-switcher__chip').forEach(c => c.classList.toggle('active', c === chip));
|
||||||
|
document.querySelectorAll('.theme-swatch').forEach(s => s.classList.toggle('active', s.dataset.pref === t));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
document.querySelectorAll('.theme-swatch').forEach(sw => {
|
||||||
|
sw.addEventListener('click', () => {
|
||||||
|
const t = sw.dataset.pref;
|
||||||
|
document.documentElement.setAttribute('data-theme', t);
|
||||||
|
document.querySelectorAll('.theme-swatch').forEach(s => s.classList.toggle('active', s === sw));
|
||||||
|
document.querySelectorAll('.theme-switcher__chip').forEach(c => c.classList.toggle('active', c.dataset.theme === t));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||