323 lines
17 KiB
HTML
323 lines
17 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Marks — C1 development</title>
|
|
<style>
|
|
:root{--ink:#14110C;--rule:rgba(20,17,12,.16);
|
|
--mono:ui-monospace,SFMono-Regular,Menlo,monospace;
|
|
--serif:ui-serif,Georgia,"Times New Roman",serif}
|
|
*{box-sizing:border-box}
|
|
body{margin:0;background:#EFEBE3;color:var(--ink);font-family:var(--mono);font-size:12px;-webkit-font-smoothing:antialiased}
|
|
header{padding:56px 40px 28px;border-bottom:1px solid var(--rule)}
|
|
h1{font-family:var(--serif);font-size:34px;font-weight:400;margin:0 0 8px}
|
|
header p{margin:0;max-width:66ch;line-height:1.7;opacity:.62}
|
|
section{padding:40px;border-bottom:1px solid var(--rule)}
|
|
h2{font-family:var(--serif);font-size:22px;font-weight:400;margin:0 0 4px}
|
|
.sub{opacity:.55;margin:0 0 28px;line-height:1.7;max-width:74ch}
|
|
.tag{display:inline-block;font-size:10px;letter-spacing:.14em;text-transform:uppercase;opacity:.45;margin-bottom:10px}
|
|
em{font-style:normal;border-bottom:1px solid rgba(20,17,12,.3)}
|
|
|
|
/* geometry is shared; colour is injected */
|
|
.pal {--c1:#22C7F0;--c2:#8B4DEE;--c3:#5E7CF5;--bg:#fff}
|
|
.p-orig {--c1:#22C7F0;--c2:#8B4DEE;--c3:#5E7CF5;--bg:#fff}
|
|
.p-paper{--c1:#001A55;--c2:#ED663F;--c3:#FECD00;--bg:#F8F5EF}
|
|
.p-ink {--c1:#14110C;--c2:#ED663F;--c3:#E0D1BB;--bg:#F8F5EF}
|
|
.p-tri {--c1:#FECD00;--c2:#ED663F;--c3:#115AB5;--bg:#F8F5EF}
|
|
.p-mono {--c1:#14110C;--c2:#14110C;--c3:#14110C;--bg:#F8F5EF}
|
|
.p-dark {--c1:#5B8FD0;--c2:#E07A5C;--c3:#D8AD10;--bg:#15130F}
|
|
|
|
.grid{display:flex;flex-wrap:wrap;gap:18px}
|
|
.card{background:var(--bg);border:1px solid var(--rule);border-radius:14px;padding:22px;width:243px}
|
|
.card .stage{display:flex;align-items:center;justify-content:center;height:150px}
|
|
.card svg{display:block}
|
|
.card h3{font-family:var(--serif);font-size:15px;font-weight:400;margin:14px 0 5px}
|
|
.card p{margin:0;font-size:10.5px;line-height:1.65;opacity:.62}
|
|
.card .own{margin-top:8px;font-size:9.5px;letter-spacing:.08em;text-transform:uppercase;opacity:.5}
|
|
|
|
table{border-collapse:collapse}
|
|
th{font-weight:400;font-size:10px;letter-spacing:.1em;text-transform:uppercase;opacity:.45;padding:0 0 12px;text-align:center}
|
|
th.rowh{text-align:right;padding-right:16px;text-transform:none;letter-spacing:0;font-size:11px;opacity:.7;white-space:nowrap}
|
|
td{padding:5px}
|
|
td .cell{width:92px;height:92px;border-radius:11px;background:var(--bg);border:1px solid var(--rule);display:flex;align-items:center;justify-content:center}
|
|
|
|
.ladder{display:flex;align-items:flex-end;gap:22px;background:var(--bg);border:1px solid var(--rule);border-radius:14px;padding:22px 26px;margin-bottom:12px}
|
|
.ladder .n{font-size:9.5px;opacity:.4;text-align:center;margin-top:8px}
|
|
.ladder .item{display:flex;flex-direction:column;align-items:center}
|
|
.ladder .name{font-family:var(--serif);font-size:14px;width:118px;opacity:.8}
|
|
|
|
.icons{display:flex;flex-wrap:wrap;gap:20px;align-items:flex-end}
|
|
.icon{width:118px;height:118px;border-radius:26px;display:flex;align-items:center;justify-content:center;background:var(--bg);box-shadow:0 6px 18px rgba(20,17,12,.14)}
|
|
.icon.sm{width:58px;height:58px;border-radius:13px}
|
|
.icoWrap{display:flex;flex-direction:column;align-items:center;gap:10px}
|
|
.icoWrap span{font-size:10px;opacity:.5}
|
|
|
|
.lockup{display:flex;align-items:center;gap:20px;background:var(--bg);border:1px solid var(--rule);border-radius:14px;padding:32px 40px;margin-bottom:12px}
|
|
.lockup .wm{font-family:var(--serif);font-size:50px;letter-spacing:-.02em;color:var(--ink)}
|
|
.lockup.p-dark .wm{color:#F1ECE1}
|
|
.lockup .tl{font-size:10px;letter-spacing:.22em;text-transform:uppercase;opacity:.5;margin-top:6px}
|
|
.lockup.p-dark .tl{color:#F1ECE1;opacity:.5}
|
|
|
|
.pattern{display:grid;grid-template-columns:repeat(13,54px);background:var(--bg);border-radius:14px;padding:20px;width:742px;overflow:hidden}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<header>
|
|
<h1>C1 — three ribbons, developed</h1>
|
|
<p>C1 had the most robust silhouette of the seven and the least ownership: three bookmark ribbons is a shape any read-later app could reach for. Ownability is the thing to attack, so each variant below adds one specific idea — a rhythm, a structure, a colour rule — and the caption says whether it actually buys anything.</p>
|
|
</header>
|
|
|
|
<svg width="0" height="0" style="position:absolute" aria-hidden="true"><defs>
|
|
|
|
<!-- a. Stepped — the baseline from the first sheet. Tops aligned, bottoms
|
|
stepped long/longest/short. -->
|
|
<symbol id="v-step" viewBox="0 0 120 120">
|
|
<path fill="var(--c1)" d="M24 14 H36 A6 6 0 0 1 42 20 V100 L30 86 L18 100 V20 A6 6 0 0 1 24 14 Z"/>
|
|
<path fill="var(--c2)" d="M54 14 H66 A6 6 0 0 1 72 20 V112 L60 98 L48 112 V20 A6 6 0 0 1 54 14 Z"/>
|
|
<path fill="var(--c3)" d="M84 14 H96 A6 6 0 0 1 102 20 V92 L90 78 L78 92 V20 A6 6 0 0 1 84 14 Z"/>
|
|
</symbol>
|
|
|
|
<!-- b. Stair — monotonic descent instead of an arbitrary step. Directional,
|
|
so it reads as progression rather than decoration. -->
|
|
<symbol id="v-stair" viewBox="0 0 120 120">
|
|
<path fill="var(--c1)" d="M24 14 H36 A6 6 0 0 1 42 20 V92 L30 78 L18 92 V20 A6 6 0 0 1 24 14 Z"/>
|
|
<path fill="var(--c2)" d="M54 14 H66 A6 6 0 0 1 72 20 V102 L60 88 L48 102 V20 A6 6 0 0 1 54 14 Z"/>
|
|
<path fill="var(--c3)" d="M84 14 H96 A6 6 0 0 1 102 20 V112 L90 98 L78 112 V20 A6 6 0 0 1 84 14 Z"/>
|
|
</symbol>
|
|
|
|
<!-- c. Tally — four thin equal ribbons. Tally marks and bookmarks are the
|
|
same shape, and the app is called Marks. The pun is the ownership. -->
|
|
<symbol id="v-tally" viewBox="0 0 120 120">
|
|
<path fill="var(--c1)" d="M21 16 H27 A4 4 0 0 1 31 20 V104 L24 94 L17 104 V20 A4 4 0 0 1 21 16 Z"/>
|
|
<path fill="var(--c2)" d="M45 16 H51 A4 4 0 0 1 55 20 V104 L48 94 L41 104 V20 A4 4 0 0 1 45 16 Z"/>
|
|
<path fill="var(--c1)" d="M69 16 H75 A4 4 0 0 1 79 20 V104 L72 94 L65 104 V20 A4 4 0 0 1 69 16 Z"/>
|
|
<path fill="var(--c3)" d="M93 16 H99 A4 4 0 0 1 103 20 V104 L96 94 L89 104 V20 A4 4 0 0 1 93 16 Z"/>
|
|
</symbol>
|
|
|
|
<!-- d. Rail — hung from a bar. Restores the shelf/box-file reading the
|
|
reference had and C1 threw away, for the cost of one rectangle. -->
|
|
<symbol id="v-rail" viewBox="0 0 120 120">
|
|
<path fill="var(--c2)" d="M22 30 H44 V104 L33 91 L22 104 Z"/>
|
|
<path fill="var(--c3)" d="M49 30 H71 V112 L60 99 L49 112 Z"/>
|
|
<path fill="var(--c2)" d="M76 30 H98 V96 L87 83 L76 96 Z"/>
|
|
<path fill="var(--c1)" d="M20 14 H100 A6 6 0 0 1 106 20 V34 H14 V20 A6 6 0 0 1 20 14 Z"/>
|
|
</symbol>
|
|
|
|
<!-- e. Overlap — wide ribbons that cross, multiplied. This is the trick the
|
|
reference actually runs on: depth from two flat colours, no shadow. -->
|
|
<symbol id="v-overlap" viewBox="0 0 120 120">
|
|
<g style="isolation:isolate">
|
|
<path style="mix-blend-mode:multiply" fill="var(--c1)" d="M16 14 H42 A8 8 0 0 1 50 22 V100 L29 84 L8 100 V22 A8 8 0 0 1 16 14 Z"/>
|
|
<path style="mix-blend-mode:multiply" fill="var(--c2)" d="M47 14 H73 A8 8 0 0 1 81 22 V112 L60 96 L39 112 V22 A8 8 0 0 1 47 14 Z"/>
|
|
<path style="mix-blend-mode:multiply" fill="var(--c1)" d="M78 14 H104 A8 8 0 0 1 112 22 V94 L91 78 L70 94 V22 A8 8 0 0 1 78 14 Z"/>
|
|
</g>
|
|
</symbol>
|
|
|
|
<!-- f. Foreground — one ribbon pulled forward and keylined in the ground
|
|
colour. Asymmetry is cheap ownership; symmetry is what makes C1 generic. -->
|
|
<symbol id="v-front" viewBox="0 0 120 120">
|
|
<path fill="var(--c1)" d="M26 14 H40 A6 6 0 0 1 46 20 V94 L33 81 L20 94 V20 A6 6 0 0 1 26 14 Z"/>
|
|
<path fill="var(--c1)" d="M80 14 H94 A6 6 0 0 1 100 20 V94 L87 81 L74 94 V20 A6 6 0 0 1 80 14 Z"/>
|
|
<path fill="var(--c2)" stroke="var(--bg)" stroke-width="5" stroke-linejoin="round"
|
|
d="M50 24 H70 A8 8 0 0 1 78 32 V114 L60 96 L42 114 V32 A8 8 0 0 1 50 24 Z"/>
|
|
</symbol>
|
|
|
|
<!-- g. Fan — the same ribbon rotated. Reads as pages fanned rather than
|
|
objects lined up; the only variant with any motion in it. -->
|
|
<symbol id="v-fan" viewBox="0 0 120 120">
|
|
<path fill="var(--c1)" transform="rotate(-15 60 110)" d="M53 18 H67 A6 6 0 0 1 73 24 V104 L60 90 L47 104 V24 A6 6 0 0 1 53 18 Z"/>
|
|
<path fill="var(--c3)" transform="rotate(15 60 110)" d="M53 18 H67 A6 6 0 0 1 73 24 V104 L60 90 L47 104 V24 A6 6 0 0 1 53 18 Z"/>
|
|
<path fill="var(--c2)" d="M53 14 H67 A6 6 0 0 1 73 20 V108 L60 94 L47 108 V20 A6 6 0 0 1 53 14 Z"/>
|
|
</symbol>
|
|
|
|
<!-- h. Pair — two, not three. Fewer parts survive smaller; the question is
|
|
whether two still reads as "a collection". -->
|
|
<symbol id="v-pair" viewBox="0 0 120 120">
|
|
<path fill="var(--c1)" d="M33 14 H49 A7 7 0 0 1 56 21 V100 L41 84 L26 100 V21 A7 7 0 0 1 33 14 Z"/>
|
|
<path fill="var(--c2)" d="M71 14 H87 A7 7 0 0 1 94 21 V112 L79 96 L64 112 V21 A7 7 0 0 1 71 14 Z"/>
|
|
</symbol>
|
|
|
|
<!-- i. Nested — concentric rather than side by side. A notch inside a notch
|
|
inside a notch: an archive, not a row. -->
|
|
<symbol id="v-nest" viewBox="0 0 120 120">
|
|
<path fill="var(--c1)" d="M26 14 H94 A10 10 0 0 1 104 24 V112 L60 92 L16 112 V24 A10 10 0 0 1 26 14 Z"/>
|
|
<path fill="var(--c3)" d="M42 14 H78 A8 8 0 0 1 86 22 V92 L60 77 L34 92 V22 A8 8 0 0 1 42 14 Z"/>
|
|
<path fill="var(--c2)" d="M54 14 H66 A6 6 0 0 1 72 20 V68 L60 58 L48 68 V20 A6 6 0 0 1 54 14 Z"/>
|
|
</symbol>
|
|
|
|
<!-- j. Scallop — one shape, four tails. Everything above is N objects; this
|
|
is a single path, which is what the tinted/mono icon modes want. -->
|
|
<symbol id="v-scallop" viewBox="0 0 120 120">
|
|
<clipPath id="clipScallop">
|
|
<path d="M26 14 H94 A10 10 0 0 1 104 24 V112 L89 96 L75 112 L60 96 L45 112 L31 96 L16 112 V24 A10 10 0 0 1 26 14 Z"/>
|
|
</clipPath>
|
|
<g clip-path="url(#clipScallop)">
|
|
<rect x="0" y="0" width="45" height="120" fill="var(--c1)"/>
|
|
<rect x="45" y="0" width="30" height="120" fill="var(--c2)"/>
|
|
<rect x="75" y="0" width="45" height="120" fill="var(--c3)"/>
|
|
</g>
|
|
</symbol>
|
|
|
|
</defs></svg>
|
|
|
|
<section>
|
|
<span class="tag">01</span>
|
|
<h2>Ten developments</h2>
|
|
<p class="sub">Shown in the app's own palette (navy / vermilion / yellow from <code>Paper.swatchPairs</code>) rather than the reference cyan-violet, since that was the conclusion of the last sheet. The <em>ownable?</em> line is the honest verdict, not a summary.</p>
|
|
<div class="grid" id="cards"></div>
|
|
</section>
|
|
|
|
<section>
|
|
<span class="tag">02</span>
|
|
<h2>Palette</h2>
|
|
<p class="sub">The three-swatch column is the interesting one. The app already hashes bookmarks into a twelve-swatch palette — a mark built from three of those swatches is describing the app's actual data model, which is ownership no competitor can copy without copying the system underneath it.</p>
|
|
<table id="matrix"></table>
|
|
</section>
|
|
|
|
<section>
|
|
<span class="tag">03</span>
|
|
<h2>Size ladder</h2>
|
|
<p class="sub">128 / 64 / 40 / 24 / 16 px. C1's whole argument is that it survives this; the developments have to survive it too or they've bought ownership with legibility.</p>
|
|
<div id="ladders"></div>
|
|
</section>
|
|
|
|
<section>
|
|
<span class="tag">04</span>
|
|
<h2>App icon</h2>
|
|
<p class="sub">Squircle at 118 and 58 px, mark at ~62% of the tile.</p>
|
|
<div class="icons" id="icons"></div>
|
|
<div class="icons" id="iconsSm" style="margin-top:22px"></div>
|
|
</section>
|
|
|
|
<section>
|
|
<span class="tag">05</span>
|
|
<h2>Lockups</h2>
|
|
<div id="lockups"></div>
|
|
</section>
|
|
|
|
<section style="border-bottom:none">
|
|
<span class="tag">06</span>
|
|
<h2>Pattern</h2>
|
|
<p class="sub">The test C1 is most likely to win: a repeating field is where a simple silhouette beats a clever one.</p>
|
|
<div class="pattern pal p-paper" id="pat"></div>
|
|
</section>
|
|
|
|
<script>
|
|
const VARIANTS = [
|
|
{id:'v-step', name:'C1·a Stepped', desc:'The baseline. Tops aligned, bottoms stepped. Balanced and readable, but the step pattern is arbitrary — nothing decides it, so nothing defends it.', own:'ownable? — no'},
|
|
{id:'v-stair', name:'C1·b Stair', desc:'Same three ribbons, monotonic descent. Now the rhythm means something (progression, a queue getting shorter) and the eye has a direction to travel.', own:'ownable? — a little'},
|
|
{id:'v-tally', name:'C1·c Tally', desc:'Four thin ribbons. A tally mark and a bookmark ribbon are already the same shape, and the app is called Marks — the mark states the name instead of illustrating the category.', own:'ownable? — yes'},
|
|
{id:'v-rail', name:'C1·d Rail', desc:'Hung from a bar. Buys back the shelf/box-file reading that made the reference work three ways, for the cost of one rectangle.', own:'ownable? — yes'},
|
|
{id:'v-overlap', name:'C1·e Overlap', desc:'Wide ribbons crossing, multiplied. This is the trick the reference actually runs on: depth out of two flat colours and no shadow at all.', own:'ownable? — a little'},
|
|
{id:'v-front', name:'C1·f Foreground', desc:'One ribbon pulled forward and keylined in the ground colour. Asymmetry is cheap ownership — the symmetry is most of why the baseline feels anonymous.', own:'ownable? — a little'},
|
|
{id:'v-fan', name:'C1·g Fan', desc:'The same ribbon rotated about a point below the mark. Reads as pages fanned rather than objects filed. The only one with motion, and the only one that animates for free.', own:'ownable? — yes'},
|
|
{id:'v-pair', name:'C1·h Pair', desc:'Two instead of three. Calmer and it holds smaller, but two things read as a pair, not a collection — which is the wrong idea for an archive.', own:'ownable? — no'},
|
|
{id:'v-nest', name:'C1·i Nested', desc:'Concentric instead of side by side: a notch inside a notch inside a notch. Says archive rather than row, and it is the only one that suggests depth without overlap.', own:'ownable? — yes'},
|
|
{id:'v-scallop', name:'C1·j Scallop', desc:'One path, four tails. Everything above is N objects fighting for space; this is a single shape, which is what iOS 26 tinted and monochrome icon modes actually want.', own:'ownable? — yes'},
|
|
]
|
|
const PALETTES = [
|
|
{cls:'p-paper', label:'Navy / Verm.'},
|
|
{cls:'p-tri', label:'Three swatches'},
|
|
{cls:'p-ink', label:'Ink / Verm.'},
|
|
{cls:'p-mono', label:'Ink only'},
|
|
{cls:'p-dark', label:'Dark'},
|
|
{cls:'p-orig', label:'Reference'},
|
|
]
|
|
const NS = 'http://www.w3.org/2000/svg'
|
|
const mark = (id, size, cls) => {
|
|
const svg = document.createElementNS(NS, 'svg')
|
|
svg.setAttribute('width', size); svg.setAttribute('height', size)
|
|
svg.setAttribute('viewBox', '0 0 120 120')
|
|
if (cls) svg.setAttribute('class', cls)
|
|
const use = document.createElementNS(NS, 'use')
|
|
use.setAttribute('href', '#' + id)
|
|
svg.appendChild(use)
|
|
return svg
|
|
}
|
|
const el = (tag, cls, html) => {
|
|
const n = document.createElement(tag)
|
|
if (cls) n.className = cls
|
|
if (html != null) n.innerHTML = html
|
|
return n
|
|
}
|
|
|
|
// 01 — cards
|
|
const cards = document.getElementById('cards')
|
|
for (const v of VARIANTS) {
|
|
const card = el('div', 'card pal p-paper')
|
|
const stage = el('div', 'stage'); stage.appendChild(mark(v.id, 132))
|
|
card.append(stage, el('h3', null, v.name), el('p', null, v.desc), el('div', 'own', v.own))
|
|
cards.appendChild(card)
|
|
}
|
|
|
|
// 02 — matrix
|
|
const matrix = document.getElementById('matrix')
|
|
const head = document.createElement('tr')
|
|
head.appendChild(el('th', 'rowh'))
|
|
for (const p of PALETTES) head.appendChild(el('th', null, p.label))
|
|
matrix.appendChild(head)
|
|
for (const v of VARIANTS) {
|
|
const row = document.createElement('tr')
|
|
row.appendChild(el('th', 'rowh', v.name))
|
|
for (const p of PALETTES) {
|
|
const td = document.createElement('td')
|
|
const cell = el('div', 'cell pal ' + p.cls)
|
|
cell.appendChild(mark(v.id, 68))
|
|
td.appendChild(cell); row.appendChild(td)
|
|
}
|
|
matrix.appendChild(row)
|
|
}
|
|
|
|
// 03 — size ladder, for the variants that claimed ownership
|
|
const ladders = document.getElementById('ladders')
|
|
for (const v of VARIANTS.filter(v => v.own.endsWith('yes'))) {
|
|
const row = el('div', 'ladder pal p-paper')
|
|
row.appendChild(el('div', 'name', v.name))
|
|
for (const s of [128, 64, 40, 24, 16]) {
|
|
const item = el('div', 'item')
|
|
item.appendChild(mark(v.id, s))
|
|
item.appendChild(el('div', 'n', s))
|
|
row.appendChild(item)
|
|
}
|
|
ladders.appendChild(row)
|
|
}
|
|
|
|
// 04 — icons
|
|
const ICONS = [
|
|
['v-tally', 'p-paper'], ['v-rail', 'p-tri'], ['v-fan', 'p-paper'],
|
|
['v-nest', 'p-ink'], ['v-scallop','p-tri'], ['v-scallop', 'p-dark'],
|
|
]
|
|
for (const [wrap, size, big] of [['icons', 72, true], ['iconsSm', 36, false]]) {
|
|
const host = document.getElementById(wrap)
|
|
for (const [id, cls] of ICONS) {
|
|
const w = el('div', 'icoWrap')
|
|
const tile = el('div', 'icon pal ' + cls + (big ? '' : ' sm'))
|
|
tile.appendChild(mark(id, size))
|
|
w.append(tile, el('span', null, big ? id.slice(2) + ' · ' + cls.slice(2) : '58pt'))
|
|
host.appendChild(w)
|
|
}
|
|
}
|
|
|
|
// 05 — lockups
|
|
const lockups = document.getElementById('lockups')
|
|
for (const [id, cls] of [['v-tally','p-paper'], ['v-rail','p-tri'], ['v-scallop','p-ink'], ['v-fan','p-dark']]) {
|
|
const row = el('div', 'lockup pal ' + cls)
|
|
row.appendChild(mark(id, 64))
|
|
const txt = el('div')
|
|
txt.append(el('div', 'wm', 'Marks'), el('div', 'tl', 'Everything you saved'))
|
|
row.appendChild(txt)
|
|
lockups.appendChild(row)
|
|
}
|
|
|
|
// 06 — pattern. Row offset stops the palette cycle lining up into stripes.
|
|
const cycle = ['p-paper', 'p-tri', 'p-ink', 'p-dark'], COLS = 13
|
|
const pat = document.getElementById('pat')
|
|
for (let i = 0; i < COLS * 5; i++) {
|
|
pat.appendChild(mark('v-tally', 54, 'pal ' + cycle[(i + Math.floor(i / COLS)) % cycle.length]))
|
|
}
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|