From 7f62e4ad7c4bd756b6fd20c759578fa9bace59b3 Mon Sep 17 00:00:00 2001 From: Barely Removable Date: Sat, 22 Aug 2026 09:48:26 -0700 Subject: [PATCH] Redesign: collector-grade dark theme, slab promoted to hero element --- static/index.html | 3 +- static/style.css | 483 ++++++++++++++++++++++++++++------------------ 2 files changed, 292 insertions(+), 194 deletions(-) diff --git a/static/index.html b/static/index.html index 5f9d03d..431deac 100644 --- a/static/index.html +++ b/static/index.html @@ -81,7 +81,8 @@ - + diff --git a/static/style.css b/static/style.css index b9028cb..7eb9fab 100644 --- a/static/style.css +++ b/static/style.css @@ -1,87 +1,89 @@ -/* Card Grader — neutral theme, card-type agnostic (Pokemon, sports, TCG). +/* Card Grader — "collector-grade" dark theme. + Card-type agnostic (Pokemon, sports, TCG). - Colour discipline: + Committed dark, not a dark *mode*. The light palette was removed rather + than kept as a fallback: this is one deliberate look, and a half-tended + second palette is how a design drifts out of sync with itself. Phones in + light mode get this same design, which is the intent. + + Colour discipline (carried over from the light theme, still true): - Grade severities ride a lightness ladder (none -> minor -> moderate -> major), so the table still reads as escalating severity in greyscale. - Red is reserved for "you should distrust this number" (unmeasurable edges, a low grade) — never decorative. - - Light and dark are separately selected steps, not an inverted flip. */ + - Foil/holo treatment is reserved for a 10. Every card shimmering would + say nothing. */ :root { - color-scheme: light; - --surface-1: #ffffff; - --plane: #eef2fa; - --ink: #101828; - --ink-2: #475467; - --muted: #7a8699; - --hairline: #dfe6f2; - --rule: #c3cede; - --accent: #2f6fd0; - --accent-2: #35c6a8; /* mark accent — fills only, never text on light */ - --accent-soft: #dbe8fc; - --good: #10a44a; - --good-text: #077a35; - --warning: #e8912f; - --critical: #d63a3a; - --header-1: #16224a; - --header-2: #24407e; - --header-3: #2f6fd0; + color-scheme: dark; - --ring: rgba(16, 24, 40, .10); - --shadow: 0 1px 2px rgba(16,24,40,.06), 0 8px 24px rgba(16,24,40,.10); - --radius: 13px; -} + /* Ground is nearly black with a blue cast — a neutral grey ground makes + the card thumbnails look washed, since most slabs and holos are cool. */ + --ground: #06090f; + --surface-1: #0e1522; + --surface-2: #141d2e; /* raised: modal, slab body, hover */ + --ink: #eef3fb; + --ink-2: #aab8cf; + --muted: #7e8da6; + --hairline: #1c2740; + --rule: #2a3852; -@media (prefers-color-scheme: dark) { - :root:where(:not([data-theme="light"])) { - color-scheme: dark; - --surface-1: #141c2f; - --plane: #0a0f1c; - --ink: #ffffff; - --ink-2: #b6c2d6; - --muted: #8592a8; - --hairline: #253150; - --rule: #35446a; - --accent: #4b8ee8; - --accent-2: #45dcbb; - --accent-soft: #1d3a66; - --good: #22c55e; - --good-text: #34d36a; - --warning: #ffa64d; - --critical: #ef5350; - --header-1: #0d1530; - --header-2: #17285a; - --header-3: #1f4488; + --accent: #4d9bff; + --accent-2: #3ddcc0; + --accent-soft: rgba(77, 155, 255, .14); - --ring: rgba(255,255,255,.12); - --shadow: 0 1px 2px rgba(0,0,0,.45), 0 8px 28px rgba(0,0,0,.55); - } + --good: #23c55e; + --good-text: #4ade80; + --warning: #f5a33c; + --critical: #f2555a; + + --ring: rgba(255, 255, 255, .12); + --shadow-sm: 0 1px 2px rgba(0, 0, 0, .5); + --shadow: 0 2px 6px rgba(0, 0, 0, .5), 0 16px 40px rgba(0, 0, 0, .55); + --shadow-lg: 0 4px 12px rgba(0, 0, 0, .55), 0 28px 70px rgba(0, 0, 0, .65); + + --radius: 14px; + --radius-lg: 18px; } * { box-sizing: border-box; } body { margin: 0; - background-color: var(--plane); - background-image: radial-gradient(circle at 1px 1px, var(--hairline) 1px, transparent 0); - background-size: 22px 22px; color: var(--ink); - font: 15px/1.5 system-ui, -apple-system, "Segoe UI", sans-serif; + font: 16px/1.55 ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif; -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; + + /* Two broad, very low-opacity glows instead of the old dot grid. A tiled + pattern reads as "utility dashboard"; soft light on a dark ground reads + as depth. Fixed so it doesn't slide around under the content. */ + background-color: var(--ground); + background-image: + radial-gradient(900px 600px at 12% -8%, rgba(77, 155, 255, .10), transparent 60%), + radial-gradient(760px 520px at 92% 4%, rgba(61, 220, 192, .07), transparent 62%); + background-attachment: fixed; + background-repeat: no-repeat; + min-height: 100vh; } -h1, h2, h3 { margin: 0; font-weight: 600; } -h1 { font-size: 16px; letter-spacing: -.01em; } -h2 { font-size: 15px; } -h3 { font-size: 13px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); font-weight: 600; } +/* ---------------------------------------------------------------- type */ + +h1, h2, h3 { margin: 0; font-weight: 650; } +h1 { font-size: 17px; letter-spacing: -.01em; } +h2 { font-size: 21px; letter-spacing: -.02em; } +h3 { + font-size: 12px; text-transform: uppercase; letter-spacing: .08em; + color: var(--muted); font-weight: 700; +} main { - max-width: 900px; + max-width: 940px; margin: 0 auto; - padding: 20px 24px 80px; + padding: 30px 24px 96px; display: flex; flex-direction: column; - gap: 20px; + gap: 22px; } /* ------------------------------------------------------------- topbar */ @@ -90,278 +92,373 @@ main { position: sticky; top: 0; z-index: 20; display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; - padding: 13px 24px; - background: linear-gradient(100deg, var(--header-1), var(--header-2) 55%, var(--header-3)); - color: #fff; - /* 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 number lives. */ - border-bottom: 3px solid transparent; - border-image: linear-gradient(90deg, - #ff5f8f, #ffb347, #ffe66d, #35c6a8, #4b8ee8, #a97bff, #ff5f8f) 1; + padding: 14px 24px; + background: rgba(8, 12, 20, .82); + -webkit-backdrop-filter: blur(14px) saturate(1.4); + backdrop-filter: blur(14px) saturate(1.4); + border-bottom: 1px solid var(--hairline); } -.topbar h1 { color: #fff; letter-spacing: .01em; } +/* 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 + number lives. Kept from the light theme — it's the app's signature. */ +.topbar::after { + content: ''; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; + background: linear-gradient(90deg, + #ff5f8f, #ffb347, #ffe66d, #3ddcc0, #4d9bff, #a97bff, #ff5f8f); + opacity: .9; +} +.topbar h1 { color: #fff; letter-spacing: .005em; } .topbar .btn { - background: var(--accent-2); color: #06231d; - border-color: transparent; font-weight: 600; + background: var(--accent-2); color: #04231d; + border-color: transparent; font-weight: 650; } -.topbar .btn:hover { filter: brightness(1.06); } +.topbar .btn:hover { filter: brightness(1.08); } .topbar .btn-quiet { - background: rgba(255,255,255,.14); color: #fff; - border-color: rgba(255,255,255,.38); font-weight: 500; + background: rgba(255, 255, 255, .07); color: var(--ink); + border-color: rgba(255, 255, 255, .16); font-weight: 550; } -.topbar .btn-quiet:hover { background: rgba(255,255,255,.26); filter: none; } +.topbar .btn-quiet:hover { background: rgba(255, 255, 255, .13); filter: none; } -.brand { display: flex; align-items: center; gap: 11px; } +.brand { display: flex; align-items: center; gap: 12px; } /* Brand mark: a graded slab, drawn in plain CSS. A rounded card outline with - a corner clipped and a check — "this one's been looked at" — rather than - any single game's iconography, since this grades anything PSA does. */ + a check — "this one's been looked at" — rather than any single game's + iconography, since this grades anything PSA does. */ .brand-mark { position: relative; flex: none; - width: 26px; height: 26px; border-radius: 6px; - background: linear-gradient(160deg, var(--accent-2), var(--accent)); - box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.4), 0 1px 4px rgba(0,0,0,.35); + width: 30px; height: 30px; border-radius: 8px; + background: linear-gradient(150deg, var(--accent-2), var(--accent) 70%, #a97bff); + box-shadow: + 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: 6px; top: 6px; - width: 8px; height: 5px; - border-left: 2px solid #06231d; border-bottom: 2px solid #06231d; + 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: 8px; flex-wrap: wrap; } +.topbar-actions { display: flex; gap: 9px; flex-wrap: wrap; } /* ------------------------------------------------------------ controls */ .btn { - font: inherit; font-weight: 500; font-size: 14px; - padding: 7px 14px; border-radius: 8px; cursor: pointer; - background: var(--accent); color: #fff; + font: inherit; font-weight: 550; font-size: 14.5px; + padding: 9px 17px; border-radius: 10px; cursor: pointer; + background: linear-gradient(180deg, + color-mix(in srgb, var(--accent) 92%, #fff), + var(--accent)); + color: #04121f; border: 1px solid transparent; text-decoration: none; display: inline-block; line-height: 1.4; white-space: nowrap; + box-shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 4px 14px rgba(77, 155, 255, .22); + transition: filter .13s ease, transform .13s ease, background .13s ease; +} +.btn:hover { filter: brightness(1.08); } +.btn:active { transform: translateY(1px); } +.btn[disabled] { opacity: .45; cursor: default; filter: none; box-shadow: none; } +.btn:focus-visible, .close:focus-visible { + outline: 2px solid var(--accent-2); outline-offset: 2px; } -.btn:hover { filter: brightness(1.07); } -.btn:active { transform: translateY(.5px); } -.btn[disabled] { opacity: .5; cursor: default; filter: none; } .btn-quiet { - background: var(--surface-1); color: var(--ink); - border-color: var(--rule); + background: var(--surface-2); color: var(--ink); + border-color: var(--rule); box-shadow: var(--shadow-sm); } -.btn-quiet:hover { background: var(--plane); filter: none; } +.btn-quiet:hover { background: #1a2439; filter: none; } -.btn-danger { background: transparent; color: var(--critical); border-color: var(--critical); } +.btn-danger { + background: transparent; color: var(--critical); + border-color: color-mix(in srgb, var(--critical) 55%, transparent); + box-shadow: none; +} .btn-danger:hover { background: var(--critical); color: #fff; filter: none; } -.btn-sm { padding: 4px 10px; font-size: 13px; } +.btn-sm { padding: 5px 12px; font-size: 13px; } .input, select, textarea { - font: inherit; font-size: 14px; - padding: 7px 10px; + font: inherit; font-size: 14.5px; + padding: 9px 12px; border: 1px solid var(--rule); - border-radius: 8px; - background: var(--surface-1); + border-radius: 10px; + background: #0a1120; color: var(--ink); width: 100%; + transition: border-color .13s ease, box-shadow .13s ease; } +.input::placeholder, textarea::placeholder { color: var(--muted); } .input:focus, select:focus, textarea:focus { - outline: 2px solid var(--accent); outline-offset: -1px; border-color: transparent; + outline: none; + border-color: var(--accent); + box-shadow: 0 0 0 3px var(--accent-soft); } -textarea { resize: vertical; min-height: 60px; } +textarea { resize: vertical; min-height: 64px; } /* --------------------------------------------------------------- tiles */ -.tile-value { font-size: 25px; font-weight: 700; letter-spacing: -.02em; } -.tile-sub { font-size: 12px; color: var(--ink-2); margin-top: 4px; } +.tile-value { font-size: 27px; font-weight: 750; letter-spacing: -.02em; } +.tile-sub { font-size: 12.5px; color: var(--ink-2); margin-top: 4px; } .pos { color: var(--good-text); } .neg { color: var(--critical); } /* -------------------------------------------------------------- panels */ .panel { - background: var(--surface-1); + position: relative; + background: + linear-gradient(180deg, rgba(255, 255, 255, .035), transparent 120px), + var(--surface-1); border: 1px solid var(--hairline); - border-radius: var(--radius); - padding: 16px 18px 18px; - box-shadow: 0 1px 2px rgba(16,24,40,.04); + border-radius: var(--radius-lg); + padding: 22px 24px 24px; + box-shadow: var(--shadow); } .panel-head { - display: flex; align-items: center; justify-content: space-between; - gap: 12px; flex-wrap: wrap; margin-bottom: 12px; + display: flex; align-items: baseline; justify-content: space-between; + gap: 12px; flex-wrap: wrap; margin-bottom: 6px; +} +.hint { font-size: 13px; color: var(--muted); font-variant-numeric: tabular-nums; } +.search-status { + margin-top: 14px; font-size: 13.5px; color: var(--ink-2); + padding: 11px 13px; border-radius: 10px; + background: var(--surface-2); border: 1px solid var(--hairline); } -.hint { font-size: 13px; color: var(--muted); } -.search-status { margin-top: 10px; font-size: 13px; color: var(--ink-2); } /* --------------------------------------------------------------- table */ -.table-scroll { overflow-x: auto; } -.grid { width: 100%; border-collapse: collapse; font-size: 14px; } +.table-scroll { overflow-x: auto; margin: 0 -6px; padding: 0 6px; } +.grid { width: 100%; border-collapse: collapse; font-size: 14.5px; } .grid th { - text-align: left; font-size: 11.5px; font-weight: 600; - text-transform: uppercase; letter-spacing: .05em; color: var(--muted); - padding: 8px 10px; border-bottom: 1px solid var(--rule); white-space: nowrap; + text-align: left; font-size: 11px; font-weight: 700; + text-transform: uppercase; letter-spacing: .07em; color: var(--muted); + padding: 10px 12px; border-bottom: 1px solid var(--rule); white-space: nowrap; } .grid td { - padding: 9px 10px; border-bottom: 1px solid var(--hairline); + padding: 13px 12px; border-bottom: 1px solid var(--hairline); vertical-align: middle; } -.grid tbody tr:hover { background: var(--accent-soft); } +.grid tbody tr { cursor: pointer; transition: background .12s ease; } +.grid tbody tr:hover { background: var(--surface-2); } +.grid tbody tr:last-child td { border-bottom: none; } .num { text-align: right; font-variant-numeric: tabular-nums; } -.cardcell { display: flex; align-items: center; gap: 10px; } +.cardcell { display: flex; align-items: center; gap: 13px; } .cardcell img, .cardcell .thumb-blank { - width: 40px; height: 56px; object-fit: cover; - border-radius: 4px; background: var(--plane); flex: none; + width: 46px; height: 64px; object-fit: cover; + border-radius: 6px; background: var(--surface-2); flex: none; + box-shadow: 0 2px 8px rgba(0, 0, 0, .55), inset 0 0 0 1px rgba(255, 255, 255, .07); } .thumb-blank { display: inline-block; border: 1px dashed var(--rule); background: repeating-linear-gradient(135deg, transparent 0 5px, var(--hairline) 5px 6px), - var(--plane); + var(--surface-2); } -.cardcell-name { font-weight: 600; line-height: 1.25; } -.cardcell-meta { font-size: 12px; color: var(--muted); } +.cardcell-name { font-weight: 600; line-height: 1.3; } +.cardcell-meta { font-size: 12.5px; color: var(--muted); } .dash { color: var(--muted); } /* --------------------------------------------------------------- pills */ .pill { display: inline-flex; align-items: center; gap: 6px; - font-size: 12px; font-weight: 600; - padding: 3.5px 10px; border-radius: 99px; + font-size: 12px; font-weight: 650; + padding: 4.5px 11px; border-radius: 99px; border: 1px solid var(--rule); color: var(--ink-2); white-space: nowrap; } -.pill-grade { border-color: var(--good); color: var(--good-text); - background: color-mix(in srgb, var(--good) 12%, transparent); } -.pill-marginal { border-color: var(--warning); - background: color-mix(in srgb, var(--warning) 14%, transparent); } +.pill-grade { border-color: color-mix(in srgb, var(--good) 55%, transparent); + color: var(--good-text); + background: color-mix(in srgb, var(--good) 15%, transparent); } +.pill-marginal { border-color: color-mix(in srgb, var(--warning) 55%, transparent); + color: var(--warning); + background: color-mix(in srgb, var(--warning) 15%, transparent); } .pill-raw { border-color: var(--rule); color: var(--muted); } -.pill-critical { border-color: var(--critical); color: var(--critical); - background: color-mix(in srgb, var(--critical) 12%, transparent); } +.pill-critical { border-color: color-mix(in srgb, var(--critical) 55%, transparent); + color: var(--critical); + background: color-mix(in srgb, var(--critical) 15%, transparent); } -.empty { text-align: center; color: var(--muted); padding: 28px 0 8px; font-size: 14px; } +/* Empty state. The old version was a one-line shrug; this gives the panel + something to hold and says what will show up here. */ +.empty { + text-align: center; color: var(--muted); font-size: 14px; + padding: 40px 20px 34px; +} +.empty::before { + content: ''; display: block; width: 42px; height: 58px; margin: 0 auto 14px; + border-radius: 6px; border: 1.5px dashed var(--rule); + background: + repeating-linear-gradient(135deg, transparent 0 6px, var(--hairline) 6px 7px), + var(--surface-2); + opacity: .8; +} /* -------------------------------------------------------------- modal */ .scrim { position: fixed; inset: 0; z-index: 30; - background: rgba(11,11,11,.32); + background: rgba(3, 5, 10, .68); + -webkit-backdrop-filter: blur(3px); + backdrop-filter: blur(3px); } .modal { position: fixed; z-index: 40; top: 50%; left: 50%; transform: translate(-50%, -50%); - width: min(560px, calc(100vw - 32px)); - max-height: min(86vh, 900px); overflow-y: auto; - background: var(--surface-1); - border: 1px solid var(--hairline); - border-radius: 14px; - box-shadow: var(--shadow); - padding: 20px 22px; + width: min(600px, calc(100vw - 28px)); + max-height: min(88vh, 940px); overflow-y: auto; + background: + linear-gradient(180deg, rgba(255, 255, 255, .04), transparent 140px), + var(--surface-1); + border: 1px solid var(--rule); + border-radius: var(--radius-lg); + box-shadow: var(--shadow-lg); + padding: 24px 26px 26px; } +.modal .panel-head { margin-bottom: 14px; } .close { - background: none; border: none; cursor: pointer; font-size: 22px; - color: var(--muted); line-height: 1; padding: 0 4px; + background: none; border: none; cursor: pointer; font-size: 24px; + color: var(--muted); line-height: 1; padding: 0 4px; border-radius: 6px; } .close:hover { color: var(--ink); } -.section { margin-bottom: 20px; } -.section > h3 { margin-bottom: 10px; } -.fields { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; } -.field { display: flex; flex-direction: column; gap: 4px; } +.section { margin-bottom: 24px; } +.section > h3 { margin-bottom: 12px; } +.fields { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; } +.field { display: flex; flex-direction: column; gap: 6px; } .field.wide { grid-column: 1 / -1; } -.field label { font-size: 12px; color: var(--ink-2); } -.suffix { display: block; font-size: 11.5px; line-height: 1.45; color: var(--muted); } +.field label { font-size: 12.5px; color: var(--ink-2); font-weight: 550; } +.suffix { display: block; font-size: 12px; line-height: 1.5; color: var(--muted); } .drawer-actions { - display: flex; gap: 8px; flex-wrap: wrap; - padding-top: 14px; border-top: 1px solid var(--hairline); + display: flex; gap: 9px; flex-wrap: wrap; align-items: center; + padding-top: 18px; margin-top: 18px; border-top: 1px solid var(--hairline); } .spacer { flex: 1; } .note { - font-size: 12.5px; color: var(--ink-2); - background: var(--plane); border: 1px solid var(--hairline); + font-size: 13px; line-height: 1.55; color: var(--ink-2); + background: var(--surface-2); border: 1px solid var(--hairline); border-left: 3px solid var(--warning); - border-radius: 6px; padding: 9px 11px; margin-top: 10px; + border-radius: 8px; padding: 12px 14px; margin-top: 14px; } .note-flag { border-left-color: var(--critical); color: var(--critical); - margin-top: 0; margin-bottom: 12px; + margin-top: 0; margin-bottom: 14px; } /* -------------------------------------------------------------- banner */ .banner { - position: sticky; top: 57px; z-index: 15; - padding: 10px 24px; font-size: 13.5px; - background: var(--accent-soft); color: var(--ink); + position: sticky; top: 60px; z-index: 15; + padding: 12px 24px; font-size: 13.5px; + background: color-mix(in srgb, var(--accent) 22%, var(--ground)); + color: var(--ink); border-bottom: 1px solid var(--hairline); } -.banner.err { background: var(--critical); color: #fff; } -.banner ul { margin: 4px 0 0; padding-left: 18px; } +.banner.err { + background: color-mix(in srgb, var(--critical) 82%, #000); + color: #fff; +} +.banner ul { margin: 5px 0 0; padding-left: 18px; } /* ---------------------------------------------------------- grade slab */ /* Styled after the label on a graded slab, because that's the thing this whole app is estimating — it makes the number read as a verdict rather - than as one more statistic on the page. */ + than as one more statistic on the page. Promoted to a hero element here: + full width, bigger numerals, real elevation. */ .slab { display: flex; align-items: stretch; gap: 0; - border-radius: 10px; overflow: hidden; + border-radius: var(--radius); overflow: hidden; border: 1px solid var(--rule); - background: var(--surface-1); - box-shadow: var(--shadow); - max-width: 420px; + background: var(--surface-2); + box-shadow: var(--shadow-lg); + width: 100%; } .slab-main { - flex: 1; padding: 12px 14px; - display: flex; flex-direction: column; justify-content: center; gap: 2px; + flex: 1; min-width: 0; padding: 20px 22px; + display: flex; flex-direction: column; justify-content: center; gap: 6px; } -.slab-title { font-size: 13px; font-weight: 700; line-height: 1.25; } -.slab-sub { font-size: 11.5px; color: var(--muted); } +.slab-title { font-size: 17px; font-weight: 700; line-height: 1.3; letter-spacing: -.01em; } +.slab-sub { font-size: 12.5px; color: var(--muted); } .slab-grade { - flex: none; width: 104px; + position: relative; overflow: hidden; + flex: none; width: 148px; display: flex; flex-direction: column; align-items: center; justify-content: center; - padding: 10px 8px; color: #fff; text-align: center; - background: linear-gradient(150deg, var(--header-2), var(--header-3)); + padding: 20px 10px; color: #fff; text-align: center; + background: linear-gradient(150deg, #1b4f8f, #2f6fd0); +} +.slab-grade .n { + font-size: 58px; font-weight: 800; line-height: .95; letter-spacing: -.035em; + font-variant-numeric: tabular-nums; + text-shadow: 0 2px 10px rgba(0, 0, 0, .4); +} +.slab-grade .word { + font-size: 10px; font-weight: 800; letter-spacing: .13em; + text-transform: uppercase; opacity: .9; margin-top: 7px; } -.slab-grade .n { font-size: 34px; font-weight: 800; line-height: 1; letter-spacing: -.02em; } -.slab-grade .word { font-size: 9.5px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; opacity: .85; margin-top: 3px; } -/* Grade bands. Green for a card worth submitting, amber mid, red low — - the same red reserved elsewhere for "distrust this", used here because a - low grade is genuinely the bad outcome. */ -.slab-10 .slab-grade, .slab-9 .slab-grade { background: linear-gradient(150deg, #0d7a3a, #10a44a); } -.slab-8 .slab-grade, .slab-7 .slab-grade { background: linear-gradient(150deg, #1b6fbf, #2f6fd0); } -.slab-6 .slab-grade, .slab-5 .slab-grade { background: linear-gradient(150deg, #b4700f, #e8912f); } -.slab-low .slab-grade { background: linear-gradient(150deg, #9e2626, #d63a3a); } +/* Grade bands. Green for a card worth submitting, blue upper-mid, amber mid, + red low — the same red reserved elsewhere for "distrust this", used here + because a low grade is genuinely the bad outcome. */ +.slab-10 .slab-grade, .slab-9 .slab-grade { background: linear-gradient(150deg, #0b6d33, #16a34a); } +.slab-8 .slab-grade, .slab-7 .slab-grade { background: linear-gradient(150deg, #1b4f8f, #2f6fd0); } +.slab-6 .slab-grade, .slab-5 .slab-grade { background: linear-gradient(150deg, #9a5c0b, #e0891f); } +.slab-low .slab-grade { background: linear-gradient(150deg, #8f1f24, #d13a40); } -/* A 10 gets the foil treatment. Deliberately reserved for the top grade so - it stays meaningful — every card shimmering would say nothing. */ +/* A 10 gets the foil treatment: a full holo sweep plus a slow shimmer pass, + the way a refractor catches light as you tilt it. Deliberately reserved + for the top grade so it stays meaningful. */ .slab-10 .slab-grade { - background: linear-gradient(140deg, #0d7a3a, #35c6a8 40%, #4b8ee8 70%, #a97bff); + background: linear-gradient(140deg, #0b6d33, #3ddcc0 38%, #4d9bff 66%, #a97bff); +} +.slab-10 .slab-grade::after { + content: ''; position: absolute; inset: -60% -20%; + background: linear-gradient(72deg, + transparent 38%, rgba(255, 255, 255, .5) 50%, transparent 62%); + animation: foil-sweep 3.6s ease-in-out infinite; +} +@keyframes foil-sweep { + 0%, 62% { transform: translateX(-115%); } + 100% { transform: translateX(115%); } +} +@media (prefers-reduced-motion: reduce) { + .slab-10 .slab-grade::after { animation: none; opacity: .25; } } .card-type-tag { - display: inline-block; font-size: 10.5px; font-weight: 700; - letter-spacing: .07em; text-transform: uppercase; - padding: 2px 7px; border-radius: 4px; - background: var(--accent-soft); color: var(--accent); - border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent); + display: inline-block; font-size: 10px; font-weight: 800; + letter-spacing: .1em; text-transform: uppercase; + padding: 3px 9px; border-radius: 5px; + background: var(--accent-soft); color: #8fc0ff; + border: 1px solid color-mix(in srgb, var(--accent) 38%, transparent); } /* --------------------------------------------------------------- phone */ @media (max-width: 700px) { - main { padding: 14px 12px 60px; } - .topbar { padding: 10px 12px; } + body { font-size: 15.5px; } + main { padding: 18px 13px 72px; gap: 16px; } + .topbar { padding: 11px 14px; } + .panel { padding: 18px 16px 20px; border-radius: var(--radius); } + h2 { font-size: 19px; } .fields { grid-template-columns: 1fr; } - .grid { font-size: 13.5px; } + .grid { font-size: 14px; } + .grid td { padding: 11px 8px; } + .grid th { padding: 9px 8px; } + .cardcell img, .cardcell .thumb-blank { width: 40px; height: 56px; } + .banner { top: 54px; padding: 11px 14px; } + + /* The slab stays horizontal — stacking it would bury the number, which is + the one thing someone opens this app to see. Just tighter. */ + .slab-main { padding: 15px 16px; } + .slab-title { font-size: 15.5px; } + .slab-grade { width: 108px; padding: 16px 8px; } + .slab-grade .n { font-size: 44px; } }