The automatic cascade only reaches RPGGeek when BGG's board-game search comes up empty — so every D&D box, which BGG does list as board games, can never find its RPGGeek entry no matter how many times it is reopened. Eric hit exactly that and settled for keeping them local. Match cards now carry an editable query with two buttons, "search BGG" and "search RPGGeek", which replace the row's ballot with whatever the chosen database returns (owned counts and ranks attached when available; if that stats call fails the results still stand and the degradation is reported). The TUI's (f) re-search falls back to RPGGeek automatically when the board-game search is empty. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016jXZFSTZQKzAC8fqpWSz9g
624 lines
26 KiB
CSS
624 lines
26 KiB
CSS
/* bggpipe design system — one stylesheet for the whole app.
|
|
*
|
|
* The visual world is Juniper's mascot drawing: a sky-blue day, flat cel
|
|
* color inside confident dark outlines, a cream game board with a rainbow
|
|
* path, gold pipe fittings, purple hair, a spring-green shirt, an orange
|
|
* bow tie, navy jeans. Tokens map those to roles — purple is brand and
|
|
* action, green means go, bow-tie orange means danger, gold is trim, navy
|
|
* is ink and dark chrome. The one loud element is the rainbow path stripe
|
|
* under the header; everything else stays flat and outlined.
|
|
*
|
|
* Contrast rule: --accent/--go/--stop have *-ink variants for text on
|
|
* light surfaces; the base variants fill objects.
|
|
*/
|
|
|
|
:root {
|
|
--sky: #cbe7f7; /* the drawing's daytime background */
|
|
--sky-deep: #b3d9ef;
|
|
--board: #fbf5e6; /* cream game-board card */
|
|
--board-edge: #e9dfc6;
|
|
--ink: #1f2433; /* outline navy-black */
|
|
--ink-soft: #52607a;
|
|
--navy: #2c3a5c; /* jeans: dark chrome, header, log */
|
|
--navy-deep: #232e49;
|
|
--accent: #8330c2; /* hair purple: brand + actions */
|
|
--accent-ink: #6b27a0;
|
|
--go: #2f8a45; /* shirt green, darkened for white text */
|
|
--go-ink: #256e37;
|
|
--stop: #d94a26; /* bow-tie orange-red */
|
|
--stop-ink: #b03a1c;
|
|
--gold: #f2c04b; /* pipe fittings: rings, trim, hovers */
|
|
--gold-ink: #8a6414;
|
|
--ticket: #fdf3d2; /* reshoot work-orders */
|
|
--go-tint: #e2f2e4; /* pale state washes of the role colors */
|
|
--stop-tint: #fbe3da;
|
|
--gold-tint: #fdeebb;
|
|
--accent-tint: #ece5f7;
|
|
--navy-tint: #e3ecf3;
|
|
--focus: var(--accent);
|
|
--path: linear-gradient(90deg,
|
|
#f767b8, #f79a3e, #f2c04b, #6fce6f, #5aa7f0, #9a5be0);
|
|
--path-v: linear-gradient(180deg,
|
|
#f767b8, #f79a3e, #f2c04b, #6fce6f, #5aa7f0, #9a5be0);
|
|
--font-display: ui-rounded, "Hiragino Maru Gothic ProN", "Arial Rounded MT Bold", var(--font-body);
|
|
--font-body: system-ui, -apple-system, "Segoe UI", sans-serif;
|
|
--font-mono: ui-monospace, "SF Mono", Menlo, monospace;
|
|
--radius: 8px;
|
|
--radius-lg: 12px;
|
|
--line: 2px solid var(--ink);
|
|
--shadow-card: 3px 3px 0 rgba(31, 36, 51, .18);
|
|
--shadow-raised: 5px 5px 0 rgba(31, 36, 51, .22);
|
|
}
|
|
|
|
/* -- base ------------------------------------------------------------- */
|
|
* { box-sizing: border-box; }
|
|
html { background: var(--sky); }
|
|
body {
|
|
margin: 0;
|
|
font-family: var(--font-body);
|
|
color: var(--ink);
|
|
background:
|
|
radial-gradient(ellipse at 50% -20%, rgba(255,255,255,.5), transparent 55%),
|
|
var(--sky);
|
|
min-height: 100vh;
|
|
}
|
|
main { max-width: 62rem; margin: 0 auto; padding: 1.4rem 1.2rem 6rem; }
|
|
h2 {
|
|
font-family: var(--font-display);
|
|
font-weight: 700; font-size: 1.1rem; letter-spacing: .02em;
|
|
margin: 2rem 0 .8rem;
|
|
}
|
|
h2 .count { color: var(--ink-soft); font-size: .85rem; font-weight: 400; }
|
|
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
|
|
|
|
/* -- layout: sidebar rail + content column ----------------------------- */
|
|
body { display: grid; grid-template-columns: 15.5rem minmax(0, 1fr); }
|
|
.sidebar {
|
|
position: sticky; top: 0; height: 100vh;
|
|
background: var(--navy); color: #fff;
|
|
display: flex; flex-direction: column;
|
|
border-right: 4px solid transparent;
|
|
/* the rainbow game path, running the rail top to bottom */
|
|
border-image: var(--path-v) 1;
|
|
}
|
|
.brand {
|
|
display: flex; align-items: center; gap: .6rem;
|
|
text-decoration: none; color: inherit;
|
|
padding: .9rem 1rem .7rem;
|
|
}
|
|
.brand img {
|
|
width: 38px; height: 38px; border-radius: 50%;
|
|
border: 2px solid var(--gold); object-fit: cover; display: block;
|
|
background: var(--sky);
|
|
}
|
|
.wordmark {
|
|
font-family: var(--font-display);
|
|
font-size: 1.3rem; font-weight: 700; letter-spacing: .01em;
|
|
}
|
|
.wordmark small { display: block; opacity: .8; font-family: var(--font-body); font-weight: 400; font-size: .72rem; }
|
|
nav[aria-label="Primary"] { display: flex; flex-direction: column; padding: .4rem 0; }
|
|
nav[aria-label="Primary"] a {
|
|
color: #fff; text-decoration: none; opacity: .85;
|
|
padding: .45rem 1rem;
|
|
display: flex; align-items: center; gap: .6rem;
|
|
border-left: 4px solid transparent;
|
|
font-size: .95rem;
|
|
}
|
|
nav[aria-label="Primary"] a:hover { opacity: 1; background: rgba(255,255,255,.07); }
|
|
nav[aria-label="Primary"] a[aria-current="page"] {
|
|
opacity: 1; border-left-color: var(--gold); font-weight: 600;
|
|
background: rgba(255,255,255,.1);
|
|
}
|
|
.navbadge {
|
|
margin-left: auto;
|
|
font-size: .72rem; font-weight: 700;
|
|
background: var(--gold); color: var(--navy-deep);
|
|
border-radius: 999px; padding: .05rem .5rem;
|
|
min-width: 1.5em; text-align: center;
|
|
}
|
|
.navbadge:empty { display: none; }
|
|
.piperbox { margin-top: auto; padding: 1rem 1rem 1.1rem; text-align: center; }
|
|
.piperbox img {
|
|
width: 100%; max-width: 11.5rem;
|
|
border-radius: var(--radius-lg);
|
|
border: 2px solid var(--gold);
|
|
display: block; margin: 0 auto;
|
|
}
|
|
.piperbox figcaption { font-size: .72rem; opacity: .8; margin-top: .45rem; }
|
|
.navtoggle { display: none; }
|
|
.piperbox .legal { font-size: .62rem; opacity: .6; line-height: 1.45; text-align: left; }
|
|
.skip {
|
|
position: absolute; left: -999px; top: 0; z-index: 10;
|
|
background: var(--board); color: var(--ink);
|
|
padding: .5rem 1rem; border-radius: 0 0 var(--radius) 0;
|
|
}
|
|
.skip:focus { left: 0; }
|
|
|
|
/* per-page strip under the page title: section links, shortcuts, counts */
|
|
.pagebar {
|
|
display: flex; gap: 1rem; align-items: center; flex-wrap: wrap;
|
|
font-size: .85rem; color: var(--ink-soft); margin: -.4rem 0 1rem;
|
|
}
|
|
.pagebar a { color: inherit; text-decoration: underline dotted; text-underline-offset: 3px; }
|
|
.pagebar a:hover { color: var(--accent-ink); }
|
|
.pagebar b { color: var(--ink); }
|
|
.keyhelp { margin-left: auto; font-size: .75rem; }
|
|
h1 {
|
|
font-family: var(--font-display); font-weight: 700;
|
|
font-size: 1.45rem; margin: 1.2rem 0 .9rem;
|
|
}
|
|
kbd {
|
|
font-family: var(--font-mono);
|
|
font-size: .72rem;
|
|
background: var(--board);
|
|
color: var(--ink);
|
|
border: 1px solid var(--board-edge);
|
|
border-bottom-width: 2px;
|
|
border-radius: 4px;
|
|
padding: 0 .35em;
|
|
display: inline-block; min-width: 1.4em; text-align: center;
|
|
}
|
|
|
|
|
|
/* -- banners ----------------------------------------------------------- */
|
|
#banner { max-width: 62rem; margin: 0 auto; padding: 0 1.2rem; }
|
|
.banner {
|
|
border-radius: var(--radius); padding: .6rem .9rem; margin-top: .9rem;
|
|
font-size: .85rem; line-height: 1.4;
|
|
border: var(--line);
|
|
background: var(--board);
|
|
}
|
|
.banner.error { border-color: var(--stop); color: var(--stop-ink); background: var(--stop-tint); }
|
|
.banner.warn { border-color: var(--gold-ink); color: var(--gold-ink); background: var(--ticket); }
|
|
|
|
/* -- buttons ----------------------------------------------------------- */
|
|
button, .linkbtn {
|
|
font: inherit; font-size: .85rem;
|
|
border: var(--line); background: #fff; color: var(--ink);
|
|
border-radius: var(--radius); padding: .3rem .8rem; cursor: pointer;
|
|
text-decoration: none; display: inline-block;
|
|
box-shadow: 2px 2px 0 rgba(31, 36, 51, .18);
|
|
}
|
|
button:hover, .linkbtn:hover { background: var(--board); }
|
|
button:active, .linkbtn:active { transform: translate(1px, 1px); box-shadow: 1px 1px 0 rgba(31,36,51,.18); }
|
|
button:disabled { opacity: .45; cursor: default; box-shadow: none; }
|
|
button.primary { background: var(--go); border-color: var(--ink); color: #fff; }
|
|
button.primary:hover { background: var(--go-ink); }
|
|
button.danger { color: var(--stop-ink); border-color: var(--stop); background: #fff; }
|
|
|
|
/* -- decision cards (review) ------------------------------------------ */
|
|
.card {
|
|
background: var(--board);
|
|
border: var(--line);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow-card);
|
|
padding: 1rem 1.1rem;
|
|
margin-bottom: 1rem;
|
|
display: flex; gap: 1.1rem;
|
|
scroll-margin-top: 5rem;
|
|
}
|
|
.card.prose { display: block; }
|
|
.card.prose p, .card.prose ol { margin: .55rem 0; line-height: 1.55; }
|
|
.card.prose > :first-child { margin-top: 0; }
|
|
.card.prose > :last-child { margin-bottom: 0; }
|
|
.artcard { text-align: center; }
|
|
.artcard img {
|
|
width: 100%; max-width: 15rem;
|
|
border: var(--line); border-radius: var(--radius-lg);
|
|
background: var(--sky);
|
|
}
|
|
.artcard .legal { font-size: .74rem; color: var(--ink-soft); max-width: 30rem; margin: .6rem auto 0; }
|
|
.card.active {
|
|
border-color: var(--accent);
|
|
box-shadow: var(--shadow-raised);
|
|
}
|
|
@media (prefers-reduced-motion: no-preference) {
|
|
.card { transition: box-shadow .15s ease, border-color .15s ease; }
|
|
button, .linkbtn { transition: transform .06s ease, box-shadow .06s ease; }
|
|
}
|
|
.shots { flex: 0 0 180px; display: flex; flex-direction: column; gap: .5rem; }
|
|
.shots img { width: 100%; border-radius: 6px; border: var(--line); display: block; }
|
|
.shots .noshot {
|
|
color: var(--ink-soft); font-size: .8rem; border: 2px dashed var(--board-edge);
|
|
border-radius: 6px; padding: 1.2rem .6rem; text-align: center;
|
|
}
|
|
.body { flex: 1; min-width: 0; }
|
|
.title { font-size: 1.15rem; font-weight: 700; font-family: var(--font-display); margin: 0 0 .15rem; }
|
|
.status { font-size: .72rem; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-soft); }
|
|
.cues { margin: .5rem 0 .7rem; display: flex; flex-wrap: wrap; gap: .35rem; }
|
|
.cue {
|
|
font-size: .74rem; background: #fff; border: 1px solid var(--board-edge);
|
|
border-radius: 999px; padding: .1rem .6rem; color: var(--ink);
|
|
}
|
|
.cue b { font-weight: 600; color: var(--ink-soft); }
|
|
.cands { list-style: none; margin: 0; padding: 0; }
|
|
.cands li {
|
|
display: flex; align-items: center; gap: .6rem;
|
|
padding: .4rem .5rem; border-radius: var(--radius); cursor: pointer;
|
|
border: 2px solid transparent;
|
|
}
|
|
.cands li:hover, .cands li:focus-visible { background: #fff; border-color: var(--accent); }
|
|
.thumb { width: 42px; height: 42px; border-radius: 6px; object-fit: cover; border: 1px solid var(--board-edge); flex: 0 0 42px; }
|
|
.thumb.ph {
|
|
display: flex; align-items: center; justify-content: center;
|
|
background: var(--accent); color: #fff;
|
|
font-family: var(--font-display); font-size: 1.2rem;
|
|
}
|
|
.cname { font-weight: 600; }
|
|
.cmeta { color: var(--ink-soft); font-size: .8rem; margin-left: .4rem; }
|
|
.rowactions { margin-top: .7rem; display: flex; gap: 1rem; align-items: center; flex-wrap: wrap; font-size: .85rem; }
|
|
.rowactions button { padding: .25rem .7rem; box-shadow: none; }
|
|
.rowactions button.reject { color: var(--stop-ink); border-color: var(--stop); }
|
|
.research { display: flex; gap: .35rem; align-items: center; flex-wrap: wrap; }
|
|
.research input[type=text] { width: 12em; }
|
|
.research button { font-size: .78rem; }
|
|
.rowactions input[type=text] {
|
|
font: inherit; width: 8.5em; padding: .25rem .5rem;
|
|
border: 2px solid var(--board-edge); border-radius: var(--radius);
|
|
}
|
|
|
|
/* -- reshoot work-orders: tickets, not cards --------------------------- */
|
|
.ticket {
|
|
background: var(--ticket);
|
|
border: 2px dashed var(--gold-ink);
|
|
border-radius: var(--radius);
|
|
padding: .8rem 1rem;
|
|
margin-bottom: .8rem;
|
|
display: flex; gap: 1rem; align-items: flex-start;
|
|
scroll-margin-top: 5rem;
|
|
}
|
|
.ticket.active { border-style: solid; box-shadow: var(--shadow-raised); }
|
|
.ticket .stencil {
|
|
writing-mode: vertical-rl; text-orientation: mixed;
|
|
font-family: var(--font-mono);
|
|
font-size: .7rem; letter-spacing: .35em; font-weight: 700;
|
|
color: var(--gold-ink); text-transform: uppercase;
|
|
border-right: 1px solid var(--gold-ink); padding-right: .5rem;
|
|
}
|
|
.ticket img { width: 130px; border-radius: 4px; border: 1px solid var(--gold-ink); }
|
|
.ticket .loc { font-weight: 600; margin-bottom: .25rem; }
|
|
.ticket .partial { font-family: var(--font-mono); font-size: .85rem; }
|
|
.ticket .notes { color: var(--gold-ink); font-size: .85rem; margin-top: .2rem; }
|
|
.ticket button {
|
|
font-size: .8rem; margin-top: .5rem;
|
|
background: none; border: 1px solid var(--gold-ink); color: var(--gold-ink);
|
|
padding: .2rem .6rem; box-shadow: none;
|
|
}
|
|
|
|
/* -- all-done celebration ---------------------------------------------- */
|
|
.done {
|
|
background: var(--board); border: var(--line); border-radius: var(--radius-lg);
|
|
padding: 1.6rem; text-align: center; box-shadow: var(--shadow-raised);
|
|
}
|
|
.done .piper {
|
|
height: 165px; margin-bottom: .4rem;
|
|
border-radius: var(--radius-lg); border: var(--line);
|
|
background: var(--sky);
|
|
}
|
|
.done h2 { margin-top: 0; }
|
|
.done .nums { display: flex; justify-content: center; gap: 2rem; margin: 1rem 0; }
|
|
.done .nums div { font-size: 1.6rem; font-weight: 700; font-family: var(--font-display); }
|
|
.done .nums span { display: block; font-size: .72rem; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-soft); }
|
|
.done code {
|
|
font-family: var(--font-mono);
|
|
background: var(--navy); color: #fff;
|
|
padding: .3rem .8rem; border-radius: var(--radius);
|
|
display: inline-block; white-space: nowrap;
|
|
}
|
|
.done .waiting {
|
|
color: var(--gold-ink);
|
|
max-width: 34rem; margin: 1rem auto .2rem; line-height: 1.5;
|
|
}
|
|
.done .next { margin: .8rem 0 .2rem; }
|
|
|
|
/* -- catalog: read-only status ledger ---------------------------------- */
|
|
.catalog { background: var(--board); border: var(--line); border-radius: var(--radius-lg); padding: .4rem 1rem; box-shadow: var(--shadow-card); }
|
|
.catalog table { width: 100%; border-collapse: collapse; font-size: .85rem; }
|
|
.catalog td { padding: .38rem .5rem; border-top: 1px solid var(--board-edge); vertical-align: top; }
|
|
.catalog tr:first-child td { border-top: none; }
|
|
.catalog tr:hover td { background: #fff; }
|
|
.catalog .t { font-weight: 600; max-width: 22rem; }
|
|
.catalog .meta { color: var(--ink-soft); }
|
|
.catalog a {
|
|
color: inherit;
|
|
text-decoration: underline dotted;
|
|
text-underline-offset: 2px;
|
|
}
|
|
.catalog a:hover { color: var(--accent-ink); }
|
|
.catalog td.actions { text-align: right; }
|
|
.catalog td.actions button { margin: .1rem 0 .1rem .3rem; white-space: nowrap; }
|
|
.catalog td.actions .ballotlink {
|
|
display: inline-block; margin: .1rem 0 .1rem .3rem; white-space: nowrap;
|
|
font-size: .78rem; color: var(--accent-ink);
|
|
text-decoration: underline dotted; text-underline-offset: 3px;
|
|
}
|
|
.catalog td.actions button { font-size: .78rem; padding: .2rem .6rem; box-shadow: none; }
|
|
.catalog td.actions button:hover { background: var(--board); }
|
|
.catalog tr.editrow td { background: #fff; border-top: none; padding: .2rem .5rem .7rem; }
|
|
.editform { display: flex; gap: .7rem; align-items: end; flex-wrap: wrap; }
|
|
.editform label {
|
|
display: flex; flex-direction: column; gap: .15rem;
|
|
font-size: .72rem; text-transform: uppercase; letter-spacing: .06em;
|
|
color: var(--ink-soft);
|
|
}
|
|
.editform input {
|
|
font: inherit; font-size: .85rem; color: var(--ink);
|
|
border: 2px solid var(--board-edge); border-radius: var(--radius);
|
|
padding: .25rem .45rem; background: #fff;
|
|
}
|
|
.editactions { display: flex; gap: .5rem; }
|
|
.edithint { font-size: .78rem; color: var(--ink-soft); align-self: center; }
|
|
.chip {
|
|
font-size: .68rem; text-transform: uppercase; letter-spacing: .06em;
|
|
border-radius: 999px; padding: .1rem .55rem; white-space: nowrap;
|
|
border: 1px solid currentColor;
|
|
}
|
|
.card code {
|
|
font-family: var(--font-mono); font-size: .82em;
|
|
background: #fff; border: 1px solid var(--board-edge);
|
|
border-radius: 4px; padding: 0 .3em;
|
|
}
|
|
.card ol { padding-left: 1.3rem; }
|
|
.card ol li { margin: .35rem 0; }
|
|
.chip.ok { background: var(--go-tint); color: var(--go-ink); }
|
|
.chip.wait { background: var(--ticket); color: var(--gold-ink); }
|
|
.chip.no { background: var(--stop-tint); color: var(--stop-ink); }
|
|
.chip.open { background: var(--accent-tint); color: var(--accent-ink); }
|
|
.chip.merged { background: var(--navy-tint); color: var(--navy); }
|
|
.chip.shaky { background: var(--ticket); color: var(--gold-ink); border: 1px dashed var(--gold-ink); }
|
|
|
|
/* -- merge notices: slim, undoable ------------------------------------- */
|
|
.card.merge { padding: .55rem 1rem; align-items: center; }
|
|
.card.merge .body { display: flex; align-items: center; gap: .8rem; flex-wrap: wrap; }
|
|
.card.merge .arrow { color: var(--ink-soft); }
|
|
.card.merge button {
|
|
font-size: .8rem; margin-left: auto;
|
|
background: none; border: 1px solid var(--board-edge);
|
|
padding: .2rem .6rem; box-shadow: none;
|
|
}
|
|
.card.merge button:hover { border-color: var(--stop); color: var(--stop-ink); }
|
|
|
|
/* -- dashboard: stage cards, dropzone, activity log --------------------- */
|
|
.stages { display: grid; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); gap: .9rem; }
|
|
.stage {
|
|
background: var(--board); border: var(--line); border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow-card);
|
|
padding: .9rem 1rem;
|
|
display: flex; flex-direction: column; gap: .5rem;
|
|
}
|
|
.stage .top { display: flex; align-items: baseline; gap: .55rem; }
|
|
.stage .num {
|
|
font-family: var(--font-mono);
|
|
color: var(--accent-ink); font-size: .8rem; font-weight: 700;
|
|
}
|
|
.stage .name { font-weight: 700; font-family: var(--font-display); }
|
|
.stage .facts { color: var(--ink-soft); font-size: .84rem; line-height: 1.45; flex: 1; }
|
|
.stage .facts b { color: var(--ink); }
|
|
.stage .act { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }
|
|
.stage input[type=number] {
|
|
font: inherit; width: 4.5em; padding: .25rem .4rem;
|
|
border: 2px solid var(--board-edge); border-radius: var(--radius);
|
|
}
|
|
#dropzone {
|
|
display: block; width: 100%;
|
|
background: var(--ticket);
|
|
border: 2px dashed var(--gold-ink);
|
|
border-radius: var(--radius);
|
|
padding: 1.4rem;
|
|
text-align: center; color: var(--gold-ink);
|
|
font: inherit; cursor: pointer;
|
|
box-shadow: none;
|
|
}
|
|
#dropzone.hot, #dropzone:hover { border-style: solid; background: var(--gold-tint); }
|
|
#dropzone[aria-busy="true"] { cursor: progress; opacity: .8; }
|
|
#dropzone.ok { border-style: solid; border-color: var(--go-ink); color: var(--go-ink); background: var(--go-tint); }
|
|
#joblog {
|
|
background: var(--navy); color: #eaf1fb;
|
|
font-family: var(--font-mono); font-size: .78rem;
|
|
border: var(--line); border-radius: var(--radius-lg);
|
|
padding: .8rem 1rem;
|
|
max-height: 20rem; overflow-y: auto; white-space: pre-wrap;
|
|
}
|
|
#jobstate { font-size: .85rem; color: var(--ink); margin-bottom: .4rem; }
|
|
#jobstate .s-running { color: var(--accent-ink); font-weight: 600; }
|
|
#jobstate .s-done { color: var(--go-ink); font-weight: 600; }
|
|
#jobstate .s-failed { color: var(--stop-ink); font-weight: 600; }
|
|
|
|
/* (phone-width rules live in the responsive section at the end) */
|
|
|
|
/* -- photos page: gallery + status ------------------------------------- */
|
|
.gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); gap: .9rem; }
|
|
.shot {
|
|
background: var(--board); border: var(--line); border-radius: var(--radius);
|
|
box-shadow: var(--shadow-card); overflow: hidden;
|
|
display: flex; flex-direction: column;
|
|
}
|
|
.shot img { width: 100%; aspect-ratio: 4/3; object-fit: cover; display: block; }
|
|
.shot .meta { padding: .4rem .6rem; font-size: .78rem; color: var(--ink-soft); }
|
|
.shot .meta b { color: var(--ink); }
|
|
.fullshot {
|
|
width: 100%; max-height: 60vh; object-fit: contain;
|
|
background: var(--navy); border: var(--line); border-radius: var(--radius-lg);
|
|
display: block; margin-bottom: 1rem;
|
|
}
|
|
|
|
/* -- queue + library --------------------------------------------------- */
|
|
.ledger { background: var(--board); border: var(--line); border-radius: var(--radius-lg); padding: .4rem 1rem; box-shadow: var(--shadow-card); }
|
|
.ledger table { width: 100%; border-collapse: collapse; font-size: .85rem; }
|
|
.ledger td, .ledger th { padding: .38rem .5rem; border-top: 1px solid var(--board-edge); vertical-align: top; text-align: left; }
|
|
.ledger th { font-size: .72rem; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-soft); border-top: none; }
|
|
.ledger .meta { color: var(--ink-soft); }
|
|
.shelfgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr)); gap: .9rem; }
|
|
.game {
|
|
background: var(--board); border: var(--line); border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow-card); overflow: hidden;
|
|
display: flex; flex-direction: column;
|
|
}
|
|
.game img { width: 100%; aspect-ratio: 1; object-fit: cover; display: block; background: var(--sky-deep); }
|
|
.game .noart {
|
|
width: 100%; aspect-ratio: 1; display: flex; align-items: center; justify-content: center;
|
|
background: var(--sky-deep); color: var(--navy);
|
|
font-family: var(--font-display); font-size: 2.2rem; font-weight: 700;
|
|
}
|
|
.game .info { padding: .55rem .7rem .7rem; }
|
|
.game .gname { font-weight: 700; font-family: var(--font-display); }
|
|
.game .gmeta { font-size: .78rem; color: var(--ink-soft); margin-top: .2rem; line-height: 1.5; }
|
|
/* -- library: card grid links + one game's detail ---------------------- */
|
|
a.game { text-decoration: none; color: inherit; }
|
|
a.game:hover { border-color: var(--accent); box-shadow: var(--shadow-raised); }
|
|
a.game:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
|
|
.gamedetail { display: flex; gap: 1.4rem; align-items: flex-start; flex-wrap: wrap; }
|
|
.gameartcol { flex: 0 0 clamp(12rem, 28vw, 18rem); }
|
|
.gameart {
|
|
width: 100%; border: var(--line); border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow-card); display: block; background: var(--board);
|
|
}
|
|
.gameart.noart {
|
|
aspect-ratio: 1; display: flex; align-items: center; justify-content: center;
|
|
background: var(--sky-deep); color: var(--navy);
|
|
font-family: var(--font-display); font-size: 3rem; font-weight: 700;
|
|
}
|
|
.gamefacts {
|
|
flex: 1 1 18rem; background: var(--board); border: var(--line);
|
|
border-radius: var(--radius-lg); box-shadow: var(--shadow-card);
|
|
padding: .9rem 1.1rem;
|
|
}
|
|
.factrow { margin: .45rem 0; line-height: 1.5; }
|
|
.factrow b {
|
|
font-size: .72rem; text-transform: uppercase; letter-spacing: .06em;
|
|
color: var(--ink-soft); margin-right: .4rem;
|
|
}
|
|
.chiplist { display: inline-flex; flex-wrap: wrap; gap: .3rem; vertical-align: middle; }
|
|
.gdesc { white-space: pre-wrap; line-height: 1.6; }
|
|
.artbtn { margin-top: .6rem; width: 100%; font-size: .8rem; }
|
|
.editform label.wide { flex: 1 1 100%; }
|
|
.editform textarea {
|
|
font: inherit; font-size: .85rem; color: var(--ink); width: 100%;
|
|
border: 2px solid var(--board-edge); border-radius: var(--radius);
|
|
padding: .35rem .45rem; background: #fff; resize: vertical;
|
|
}
|
|
|
|
.empty {
|
|
background: var(--board); border: 2px dashed var(--board-edge);
|
|
border-radius: var(--radius-lg); padding: 2rem; text-align: center;
|
|
color: var(--ink-soft); line-height: 1.6;
|
|
}
|
|
.empty code {
|
|
font-family: var(--font-mono); background: var(--navy); color: #fff;
|
|
padding: .15rem .5rem; border-radius: 6px;
|
|
}
|
|
.filterbar { display: flex; gap: .6rem; margin-bottom: 1rem; flex-wrap: wrap; }
|
|
.filterbar button[aria-pressed="true"] {
|
|
background: var(--accent); border-color: var(--ink); color: #fff;
|
|
}
|
|
.filterbar input[type=search] {
|
|
font: inherit; padding: .35rem .7rem; min-width: 16rem;
|
|
border: var(--line); border-radius: var(--radius); background: #fff;
|
|
}
|
|
|
|
/* -- toast: viewport-pinned transient confirmations --------------------- */
|
|
#toast {
|
|
position: fixed; bottom: 1.1rem; left: 50%; transform: translateX(-50%);
|
|
z-index: 20; max-width: min(92vw, 34rem);
|
|
background: var(--navy); color: #fff;
|
|
border: var(--line); border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow-raised);
|
|
padding: .7rem 1rem; font-size: .9rem; line-height: 1.45;
|
|
}
|
|
#toast a { color: var(--gold); }
|
|
#toast button {
|
|
font-size: .8rem; padding: .25rem .7rem; margin-left: .5rem;
|
|
box-shadow: none;
|
|
}
|
|
|
|
/* -- responsive -------------------------------------------------------- */
|
|
|
|
/* The rail collapses to a top bar: brand + hamburger; the nav drops
|
|
* down as a stacked menu (a scrolling strip lost its position on every
|
|
* page load and hid the far entries). */
|
|
@media (max-width: 900px) {
|
|
body { display: block; }
|
|
.sidebar {
|
|
position: sticky; top: 0; height: auto; z-index: 5;
|
|
display: flex; flex-direction: row; align-items: center; flex-wrap: wrap;
|
|
border-right: none; border-bottom: 4px solid transparent;
|
|
border-image: var(--path) 1;
|
|
}
|
|
.brand { padding: .5rem .8rem; flex: 1; }
|
|
.brand img { width: 30px; height: 30px; }
|
|
.wordmark { font-size: 1.1rem; }
|
|
.wordmark small { display: inline; margin-left: .5rem; font-size: .68rem; }
|
|
.navtoggle {
|
|
display: inline-flex; align-items: center; justify-content: center;
|
|
width: 44px; height: 40px; margin-right: .6rem;
|
|
background: none; border: 2px solid rgba(255, 255, 255, .75);
|
|
border-radius: var(--radius); box-shadow: none; padding: 0;
|
|
}
|
|
.navtoggle .bars {
|
|
display: block; position: relative;
|
|
width: 18px; height: 2px; background: #fff; border-radius: 2px;
|
|
}
|
|
.navtoggle .bars::before, .navtoggle .bars::after {
|
|
content: ""; position: absolute; left: 0;
|
|
width: 18px; height: 2px; background: #fff; border-radius: 2px;
|
|
}
|
|
.navtoggle .bars::before { top: -6px; }
|
|
.navtoggle .bars::after { top: 6px; }
|
|
body.navopen .navtoggle { background: rgba(255, 255, 255, .15); }
|
|
nav[aria-label="Primary"] {
|
|
display: none; flex-basis: 100%; flex-direction: column;
|
|
padding: 0 0 .4rem;
|
|
}
|
|
body.navopen nav[aria-label="Primary"] { display: flex; }
|
|
nav[aria-label="Primary"] a { padding: .6rem 1rem; }
|
|
.piperbox { display: none; }
|
|
}
|
|
|
|
/* Phone-width layout: stacked cards, stacked tables, touch targets. */
|
|
@media (max-width: 700px) {
|
|
main { padding: 1rem .9rem 4rem; }
|
|
h1 { font-size: 1.3rem; margin: .9rem 0 .7rem; }
|
|
.keyhelp { display: none; } /* no keyboard on a phone */
|
|
button, .linkbtn { padding: .45rem .9rem; } /* finger-sized */
|
|
/* component buttons set their own padding at higher specificity —
|
|
* they need the touch bump spelled out */
|
|
.rowactions button, .ticket button, .card.merge button { padding: .4rem .8rem; }
|
|
|
|
.card, .ticket { flex-direction: column; }
|
|
.shots { flex-basis: auto; }
|
|
.ticket .stencil {
|
|
writing-mode: horizontal-tb; letter-spacing: .35em;
|
|
border-right: none; border-bottom: 1px solid var(--gold-ink);
|
|
padding: 0 0 .3rem;
|
|
}
|
|
.done { padding: 1.1rem .9rem; }
|
|
.done .nums { flex-wrap: wrap; gap: .8rem 1.6rem; }
|
|
|
|
.filterbar input[type=search] { min-width: 0; flex: 1 1 12rem; }
|
|
.editform { flex-direction: column; align-items: stretch; }
|
|
.editform input { width: 100%; }
|
|
.editactions { flex-wrap: wrap; }
|
|
.editactions button { flex: 1 1 auto; }
|
|
|
|
/* the titles/photo tables become stacked line-cards: one bordered
|
|
* block per game, cells flowing top to bottom, empty cells gone */
|
|
.catalog table, .catalog tbody, .catalog tr, .catalog td { display: block; }
|
|
.catalog tr { padding: .6rem 0; border-top: 1px solid var(--board-edge); }
|
|
.catalog tr:first-child { border-top: none; }
|
|
.catalog tr:hover td { background: none; }
|
|
.catalog td { border-top: none; padding: .12rem 0; }
|
|
.catalog td:empty { display: none; }
|
|
.catalog .t { max-width: none; font-size: .95rem; }
|
|
.catalog td.actions {
|
|
text-align: left; white-space: normal;
|
|
display: flex; gap: .5rem; flex-wrap: wrap; padding-top: .4rem;
|
|
}
|
|
.catalog td.actions button { padding: .4rem .8rem; }
|
|
.catalog tr.editrow { padding-top: 0; border-top: none; }
|
|
|
|
/* queue/library ledgers keep their columns but scroll inside their
|
|
* own card; long photo lists wrap within their cell */
|
|
.ledger { overflow-x: auto; }
|
|
.ledger td { overflow-wrap: anywhere; min-width: 6rem; }
|
|
}
|