UI: slab brand mark replacing checkmark, header aligned to page column, flatter controls
This commit is contained in:
parent
fa5467e55d
commit
527558bef2
4 changed files with 73 additions and 46 deletions
|
|
@ -173,7 +173,7 @@ function renderGradeBlock(g, opts = {}) {
|
||||||
}).join('');
|
}).join('');
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="note">A photo can't show surface scratches, print lines, or light edge wear the
|
<div class="note note-warn">A photo can't show surface scratches, print lines, or light edge wear the
|
||||||
way a grader's raking light does — and a seller's listing photo is often lit to hide them.
|
way a grader's raking light does — and a seller's listing photo is often lit to hide them.
|
||||||
Treat this as a rough screen, not a prediction of what it comes back as.</div>
|
Treat this as a rough screen, not a prediction of what it comes back as.</div>
|
||||||
<div style="margin:14px 0">${renderSlab(g, opts)}</div>
|
<div style="margin:14px 0">${renderSlab(g, opts)}</div>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
|
||||||
<rect width="128" height="128" rx="24" fill="#16224a"/>
|
<!-- Matches the in-app brand mark: a graded slab — case, label, and the
|
||||||
<rect x="34" y="24" width="60" height="80" rx="8" fill="#2f6fd0" stroke="#35c6a8" stroke-width="3"/>
|
card sealed inside. Kept in step with .brand-mark in style.css. -->
|
||||||
<path d="M48 66 L60 78 L84 50" fill="none" stroke="#ffffff" stroke-width="7"
|
<rect width="128" height="128" rx="26" fill="#0e1522"/>
|
||||||
stroke-linecap="round" stroke-linejoin="round"/>
|
<rect x="38.5" y="20.5" width="51" height="87" rx="9" fill="none"
|
||||||
|
stroke="#4d9bff" stroke-width="5"/>
|
||||||
|
<rect x="48" y="31" width="32" height="9" rx="3.5" fill="#3ddcc0"/>
|
||||||
|
<rect x="48" y="49" width="32" height="45" rx="4.5" fill="#4d9bff" opacity="0.34"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 367 B After Width: | Height: | Size: 548 B |
|
|
@ -23,13 +23,23 @@
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<header class="topbar">
|
<header class="topbar">
|
||||||
<div class="brand">
|
<div class="topbar-inner">
|
||||||
<span class="brand-mark"></span>
|
<div class="brand">
|
||||||
<h1>Card Grader</h1>
|
<!-- A graded slab: the case, its label, and the card sealed inside.
|
||||||
</div>
|
This is the literal object the whole app estimates, so it says
|
||||||
<div class="topbar-actions">
|
what this is without belonging to any one card game — which a
|
||||||
<button id="btn-install" class="btn" hidden>Install app</button>
|
checkmark (or any single game's iconography) doesn't. -->
|
||||||
<button id="btn-settings" class="btn btn-quiet">Settings</button>
|
<svg class="brand-mark" viewBox="0 0 24 30" fill="none" aria-hidden="true" focusable="false">
|
||||||
|
<rect class="mark-case" x="1.15" y="1.15" width="21.7" height="27.7" rx="3.4" stroke-width="1.7"/>
|
||||||
|
<rect class="mark-label" x="5.2" y="5.3" width="13.6" height="3.3" rx="1.3"/>
|
||||||
|
<rect class="mark-card" x="5.2" y="11.9" width="13.6" height="12.9" rx="1.6"/>
|
||||||
|
</svg>
|
||||||
|
<h1>Card Grader</h1>
|
||||||
|
</div>
|
||||||
|
<div class="topbar-actions">
|
||||||
|
<button id="btn-install" class="btn" hidden>Install app</button>
|
||||||
|
<button id="btn-settings" class="btn btn-quiet">Settings</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -90,24 +90,34 @@ main {
|
||||||
|
|
||||||
.topbar {
|
.topbar {
|
||||||
position: sticky; top: 0; z-index: 20;
|
position: sticky; top: 0; z-index: 20;
|
||||||
display: flex; align-items: center; justify-content: space-between;
|
|
||||||
gap: 16px; flex-wrap: wrap;
|
|
||||||
padding: 14px 24px;
|
|
||||||
background: rgba(8, 12, 20, .82);
|
background: rgba(8, 12, 20, .82);
|
||||||
-webkit-backdrop-filter: blur(14px) saturate(1.4);
|
-webkit-backdrop-filter: blur(14px) saturate(1.4);
|
||||||
backdrop-filter: blur(14px) saturate(1.4);
|
backdrop-filter: blur(14px) saturate(1.4);
|
||||||
border-bottom: 1px solid var(--hairline);
|
border-bottom: 1px solid var(--hairline);
|
||||||
}
|
}
|
||||||
|
/* The bar spans the viewport, but its CONTENTS line up with the page
|
||||||
|
column — the logo sitting hard against a 3440px screen edge while the
|
||||||
|
panels floated in a narrow centre column was the single thing making
|
||||||
|
this read as unfinished rather than designed. */
|
||||||
|
.topbar-inner {
|
||||||
|
max-width: 940px; margin: 0 auto;
|
||||||
|
display: flex; align-items: center; justify-content: space-between;
|
||||||
|
gap: 16px; flex-wrap: wrap;
|
||||||
|
padding: 13px 24px;
|
||||||
|
}
|
||||||
/* Holo-foil edge: the rainbow sweep you get tilting a refractor. Purely
|
/* Holo-foil edge: the rainbow sweep you get tilting a refractor. Purely
|
||||||
decorative and it encodes nothing, so it's free to be vivid here where no
|
decorative and it encodes nothing, so it's free to be vivid here where no
|
||||||
number lives. Kept from the light theme — it's the app's signature. */
|
number lives — but dialled back from the original full-strength stripe,
|
||||||
|
which was the loudest thing on an otherwise restrained page. */
|
||||||
.topbar::after {
|
.topbar::after {
|
||||||
content: ''; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
|
content: ''; position: absolute; left: 0; right: 0; bottom: -1px; height: 1.5px;
|
||||||
background: linear-gradient(90deg,
|
background: linear-gradient(90deg,
|
||||||
#ff5f8f, #ffb347, #ffe66d, #3ddcc0, #4d9bff, #a97bff, #ff5f8f);
|
#ff5f8f, #ffb347, #ffe66d, #3ddcc0, #4d9bff, #a97bff, #ff5f8f);
|
||||||
opacity: .9;
|
opacity: .5;
|
||||||
|
}
|
||||||
|
.topbar h1 {
|
||||||
|
color: #fff; font-size: 16px; font-weight: 600; letter-spacing: -.005em;
|
||||||
}
|
}
|
||||||
.topbar h1 { color: #fff; letter-spacing: .005em; }
|
|
||||||
|
|
||||||
.topbar .btn {
|
.topbar .btn {
|
||||||
background: var(--accent-2); color: #04231d;
|
background: var(--accent-2); color: #04231d;
|
||||||
|
|
@ -120,41 +130,34 @@ main {
|
||||||
}
|
}
|
||||||
.topbar .btn-quiet:hover { background: rgba(255, 255, 255, .13); filter: none; }
|
.topbar .btn-quiet:hover { background: rgba(255, 255, 255, .13); filter: none; }
|
||||||
|
|
||||||
.brand { display: flex; align-items: center; gap: 12px; }
|
.brand { display: flex; align-items: center; gap: 11px; }
|
||||||
|
|
||||||
/* Brand mark: a graded slab, drawn in plain CSS. A rounded card outline with
|
/* Brand mark: a graded slab — case, label, and the card sealed inside.
|
||||||
a check — "this one's been looked at" — rather than any single game's
|
Drawn as flat two-tone geometry rather than the gradient-blob-with-a-
|
||||||
iconography, since this grades anything PSA does. */
|
checkmark it replaced: that read as a generic app badge and said nothing
|
||||||
.brand-mark {
|
about grading. Thin strokes and no glow keep it legible at 22px. */
|
||||||
position: relative; flex: none;
|
.brand-mark { flex: none; width: 21px; height: 26px; display: block; }
|
||||||
width: 30px; height: 30px; border-radius: 8px;
|
.brand-mark .mark-case { stroke: var(--accent); }
|
||||||
background: linear-gradient(150deg, var(--accent-2), var(--accent) 70%, #a97bff);
|
.brand-mark .mark-label { fill: var(--accent-2); }
|
||||||
box-shadow:
|
.brand-mark .mark-card { fill: var(--accent); opacity: .34; }
|
||||||
inset 0 0 0 1.5px rgba(255, 255, 255, .34),
|
|
||||||
0 2px 10px rgba(77, 155, 255, .45);
|
|
||||||
}
|
|
||||||
.brand-mark::after {
|
|
||||||
content: ''; position: absolute; left: 8px; top: 8px;
|
|
||||||
width: 9px; height: 5.5px;
|
|
||||||
border-left: 2.2px solid #04231d; border-bottom: 2.2px solid #04231d;
|
|
||||||
transform: rotate(-45deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.topbar-actions { display: flex; gap: 9px; flex-wrap: wrap; }
|
.topbar-actions { display: flex; gap: 9px; flex-wrap: wrap; }
|
||||||
|
|
||||||
/* ------------------------------------------------------------ controls */
|
/* ------------------------------------------------------------ controls */
|
||||||
|
|
||||||
|
/* Flat accent fill with a plain shadow. The previous gradient-plus-coloured-
|
||||||
|
glow made every button feel like the page's main event, which flattened
|
||||||
|
the hierarchy — the grade result should be the loudest thing here, not
|
||||||
|
the controls. */
|
||||||
.btn {
|
.btn {
|
||||||
font: inherit; font-weight: 550; font-size: 14.5px;
|
font: inherit; font-weight: 600; font-size: 14.5px;
|
||||||
padding: 9px 17px; border-radius: 10px; cursor: pointer;
|
padding: 9px 17px; border-radius: 9px; cursor: pointer;
|
||||||
background: linear-gradient(180deg,
|
background: var(--accent);
|
||||||
color-mix(in srgb, var(--accent) 92%, #fff),
|
|
||||||
var(--accent));
|
|
||||||
color: #04121f;
|
color: #04121f;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
text-decoration: none; display: inline-block; line-height: 1.4;
|
text-decoration: none; display: inline-block; line-height: 1.4;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 4px 14px rgba(77, 155, 255, .22);
|
box-shadow: 0 1px 2px rgba(0, 0, 0, .35);
|
||||||
transition: filter .13s ease, transform .13s ease, background .13s ease;
|
transition: filter .13s ease, transform .13s ease, background .13s ease;
|
||||||
}
|
}
|
||||||
.btn:hover { filter: brightness(1.08); }
|
.btn:hover { filter: brightness(1.08); }
|
||||||
|
|
@ -217,9 +220,15 @@ textarea { resize: vertical; min-height: 64px; }
|
||||||
box-shadow: var(--shadow);
|
box-shadow: var(--shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* A rule under the heading gives each panel a real header band instead of
|
||||||
|
a title floating above loose content — the cheapest structural cue there
|
||||||
|
is, and what most separates "designed" from "stacked divs". Suppressed
|
||||||
|
inside modals, which set their own tighter header treatment below. */
|
||||||
.panel-head {
|
.panel-head {
|
||||||
display: flex; align-items: baseline; justify-content: space-between;
|
display: flex; align-items: baseline; justify-content: space-between;
|
||||||
gap: 12px; flex-wrap: wrap; margin-bottom: 6px;
|
gap: 12px; flex-wrap: wrap;
|
||||||
|
padding-bottom: 13px; margin-bottom: 4px;
|
||||||
|
border-bottom: 1px solid var(--hairline);
|
||||||
}
|
}
|
||||||
.hint { font-size: 13px; color: var(--muted); font-variant-numeric: tabular-nums; }
|
.hint { font-size: 13px; color: var(--muted); font-variant-numeric: tabular-nums; }
|
||||||
.search-status {
|
.search-status {
|
||||||
|
|
@ -341,7 +350,7 @@ textarea { resize: vertical; min-height: 64px; }
|
||||||
line under the title. Pin it: title takes the slack, × stays top-right. */
|
line under the title. Pin it: title takes the slack, × stays top-right. */
|
||||||
.modal .panel-head {
|
.modal .panel-head {
|
||||||
flex-wrap: nowrap; align-items: flex-start; gap: 16px;
|
flex-wrap: nowrap; align-items: flex-start; gap: 16px;
|
||||||
margin-bottom: 14px;
|
padding-bottom: 0; margin-bottom: 12px; border-bottom: none;
|
||||||
}
|
}
|
||||||
.modal .panel-head h2 { flex: 1; min-width: 0; }
|
.modal .panel-head h2 { flex: 1; min-width: 0; }
|
||||||
.modal .close { flex: none; margin-top: 1px; }
|
.modal .close { flex: none; margin-top: 1px; }
|
||||||
|
|
@ -365,12 +374,17 @@ textarea { resize: vertical; min-height: 64px; }
|
||||||
}
|
}
|
||||||
.spacer { flex: 1; }
|
.spacer { flex: 1; }
|
||||||
|
|
||||||
|
/* Informational by default — accent, not amber. The shooting guidance
|
||||||
|
("front straight-on is the minimum") is instruction, not a caution, and
|
||||||
|
colouring it like a warning spent the page's only alarm colour on
|
||||||
|
something that never needed it. Genuine cautions opt into .note-warn. */
|
||||||
.note {
|
.note {
|
||||||
font-size: 13px; line-height: 1.55; color: var(--ink-2);
|
font-size: 13px; line-height: 1.55; color: var(--ink-2);
|
||||||
background: var(--surface-2); border: 1px solid var(--hairline);
|
background: var(--surface-2); border: 1px solid var(--hairline);
|
||||||
border-left: 3px solid var(--warning);
|
border-left: 3px solid var(--accent);
|
||||||
border-radius: 8px; padding: 12px 14px; margin-top: 14px;
|
border-radius: 8px; padding: 12px 14px; margin-top: 14px;
|
||||||
}
|
}
|
||||||
|
.note-warn { border-left-color: var(--warning); }
|
||||||
.note-flag {
|
.note-flag {
|
||||||
border-left-color: var(--critical);
|
border-left-color: var(--critical);
|
||||||
color: var(--critical);
|
color: var(--critical);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue