Files
tiptoi-sync/src/index.css
T
arnef 8ef7b9ce8c
CI / Type-Check (push) Successful in 16s
CI / Build Android APK (push) Successful in 5m20s
Flatten repo: move client/ contents to repo root
The project is no longer a monorepo/workspace - there is only a single
app package. Remove the redundant client/ nesting: all source, the
Capacitor Android project, config files and package.json/tsconfig now
live directly at the repo root.

- Merge client/package.json into root package.json (drop the
  workspaces field and the now-unnecessary bun --cwd client wrappers).
- Merge client/bun.lock (the actual dependency lockfile) into the
  root, replacing the stale workspace-only root lockfile.
- Move src/, public/, android/, index.html, vite.config.ts,
  capacitor.config.ts, tsconfig.{app,node}.json to the repo root.
- Update Dockerfile.android to build from the repo root instead of
  cd'ing into client/.
- Update .github/workflows/ci.yml type-check step to run bun run build
  directly instead of bun --cwd client run build.
- Update README.md and .github/copilot-instructions.md to drop
  references to the client/ subdirectory.
- Drop the stale server/downloads/ entry from .gitignore (leftover
  from an old server-based architecture that no longer exists).
2026-08-13 21:52:32 +02:00

598 lines
13 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ── Reset & Base ─────────────────────────────────────────── */
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
/* Tiptoi-Farbwelt: dunkler Grund, kräftiges Orange als Hauptakzent,
Ravensburger-Blau als Sekundärfarbe */
--bg: #12181f;
--bg-card: #1c242e;
--bg-input: #242e3a;
--border: #2f3b48;
--accent: #f2841e;
--accent-dk: #cf6d0f;
--accent-rgb: 242, 132, 30;
--accent2: #3b9eea;
--accent2-rgb:59, 158, 234;
--text: #eef3f7;
--text-muted: #8ea1b2;
--ok: #46c98f;
--ok-rgb: 70, 201, 143;
--err: #ef5959;
--err-rgb: 239, 89, 89;
--warn: #f2b705;
--warn-rgb: 242, 183, 5;
--radius: 16px;
/* Markante tiptoi-Ecke, ausschließlich für Buttons und Textfelder:
Buttons unten links eckig, Textfelder (gespiegelt) unten rechts eckig.
Die sehr großen Werte clampen automatisch auf max. 50% der Elementgröße. */
--radius-book: 200px 200px 200px 20px;
--radius-book-input: 200px 200px 20px 200px;
--shadow: 0 4px 20px rgba(0, 0, 0, 0.35);
}
html, body, #app {
height: 100%;
}
body {
font-family: system-ui, -apple-system, sans-serif;
background: var(--bg);
color: var(--text);
-webkit-font-smoothing: antialiased;
}
/* ── Layout shell ─────────────────────────────────────────── */
.shell {
display: flex;
flex-direction: column;
height: 100dvh;
max-width: 480px;
margin: 0 auto;
}
.page {
flex: 1;
overflow-y: auto;
padding: 1.5rem 1rem 1rem;
display: flex;
flex-direction: column;
gap: 1.25rem;
}
/* ── Top bar ──────────────────────────────────────────────── */
.topbar {
display: flex;
align-items: center;
padding: calc(env(safe-area-inset-top) + 1rem) 1rem 0;
gap: 0.75rem;
}
.topbar__title {
font-size: 1.3rem;
font-weight: 700;
letter-spacing: -0.02em;
flex: 1;
}
.topbar__logo {
width: 28px;
height: 28px;
}
/* ── Bottom nav ───────────────────────────────────────────── */
.bottom-nav {
display: grid;
grid-auto-flow: column;
grid-auto-columns: 1fr;
border-top: 1px solid var(--border);
background: var(--bg-card);
padding-bottom: env(safe-area-inset-bottom);
}
.bottom-nav__item {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.2rem;
padding: 0.75rem 0;
background: none;
border: none;
color: var(--text-muted);
font-size: 0.7rem;
font-weight: 500;
cursor: pointer;
transition: color 0.15s;
}
.bottom-nav__item svg {
width: 22px;
height: 22px;
}
.bottom-nav__item.active {
color: var(--accent);
}
/* ── Cards ────────────────────────────────────────────────── */
.card {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 1.25rem;
}
/* ── Scanner ──────────────────────────────────────────────── */
.scanner {
display: flex;
flex-direction: column;
align-items: center;
gap: 1rem;
width: 100%;
}
.scanner__video {
width: 100%;
border-radius: var(--radius);
background: #000;
aspect-ratio: 4/3;
object-fit: cover;
}
.scanner__viewfinder {
position: relative;
width: 100%;
}
.scanner__viewfinder::after {
content: '';
position: absolute;
inset: 12px;
border: 2px solid var(--accent2);
border-radius: 10px;
pointer-events: none;
box-shadow: 0 0 0 9999px rgba(0,0,0,0.45);
}
/* ── Buttons ──────────────────────────────────────────────── */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.4rem;
padding: 0.8rem 1.5rem;
background: var(--accent);
color: #fff;
border: none;
border-radius: var(--radius-book);
font-size: 0.95rem;
font-weight: 600;
cursor: pointer;
transition: background 0.15s, transform 0.1s;
width: 100%;
}
.btn:active { transform: scale(0.97); }
.btn:hover { background: var(--accent-dk); }
.btn--ghost {
background: transparent;
border: 1px solid var(--border);
color: var(--text-muted);
}
.btn--ghost:hover { background: var(--bg-input); }
.btn--danger {
background: var(--err);
}
/* Dezente Variante für große Flächen (z. B. "QR-Code scannen") volles
Orange wäre auf so einer großen Fläche zu dominant. */
.btn--outline {
background: rgba(var(--accent-rgb), 0.12);
color: var(--accent);
border: 1.5px solid rgba(var(--accent-rgb), 0.5);
}
.btn--outline:hover {
background: rgba(var(--accent-rgb), 0.2);
}
/* ── Input ────────────────────────────────────────────────── */
.search-row {
display: flex;
gap: 0.5rem;
width: 100%;
}
.input {
flex: 1;
padding: 0.8rem 1rem;
background: var(--bg-input);
border: 1px solid var(--border);
border-radius: var(--radius-book-input);
color: var(--text);
font-size: 0.95rem;
outline: none;
transition: border-color 0.15s;
}
.input:focus { border-color: var(--accent); }
.input::placeholder { color: var(--text-muted); }
.search-row .btn { width: auto; padding: 0.8rem 1.2rem; }
/* ── Result card ──────────────────────────────────────────── */
.result-list {
display: flex;
flex-direction: column;
gap: 1rem;
}
.result-card {
display: flex;
flex-direction: column;
align-items: center;
gap: 1rem;
text-align: center;
}
.result-card__image {
width: 140px;
height: 147px;
object-fit: contain;
border-radius: var(--radius);
background: var(--bg-input);
}
.result-card__title {
font-size: 1rem;
font-weight: 600;
line-height: 1.4;
}
/* ── Status messages ──────────────────────────────────────── */
.status {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.9rem;
color: var(--text-muted);
}
.status--ok { color: var(--ok); font-weight: 600; }
.status--error { color: var(--err); }
/* ── Spinner ──────────────────────────────────────────────── */
.spinner {
width: 18px;
height: 18px;
border: 2px solid var(--border);
border-top-color: var(--accent);
border-radius: 50%;
animation: spin 0.7s linear infinite;
flex-shrink: 0;
}
@keyframes spin { to { transform: rotate(360deg); } }
/* ── Hint ─────────────────────────────────────────────────── */
.hint {
font-size: 0.85rem;
color: var(--text-muted);
}
/* ── Downloads list ───────────────────────────────────────── */
.downloads-list {
display: flex;
flex-direction: column;
gap: 0.6rem;
}
.download-item {
display: flex;
flex-direction: column;
gap: 0.5rem;
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 0.9rem 1rem;
}
.download-item__row {
display: flex;
align-items: center;
gap: 0.75rem;
}
.download-item__icon {
width: 36px;
height: 36px;
background: var(--accent);
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
font-size: 0.65rem;
font-weight: 700;
letter-spacing: 0.02em;
color: #fff;
}
.download-item__name {
flex: 1;
min-width: 0;
font-size: 0.9rem;
font-weight: 500;
word-break: break-all;
display: flex;
flex-direction: column;
gap: 0.15rem;
}
.download-item__size {
font-size: 0.72rem;
font-weight: 400;
color: var(--text-muted);
}
.empty {
text-align: center;
color: var(--text-muted);
padding: 3rem 0;
font-size: 0.9rem;
}
.section-title {
font-size: 0.75rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--text-muted);
}
.download-item__cover {
width: 48px;
height: 50px;
object-fit: cover;
border-radius: 8px;
flex-shrink: 0;
}
/* ── Pen status bar ──────────────────────────────────────── */
.pen-bar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 0.75rem;
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 0.7rem 1rem;
min-height: 52px;
}
.pen-bar__left {
display: flex;
align-items: center;
gap: 0.5rem;
flex: 1;
min-width: 0;
}
.pen-bar__info {
display: flex;
align-items: center;
gap: 0.4rem;
flex-wrap: wrap;
}
.pen-bar__name {
font-size: 0.87rem;
font-weight: 600;
color: var(--ok);
}
.pen-bar__actions {
display: flex;
align-items: center;
gap: 0.35rem;
flex-shrink: 0;
}
.pen-bar__action {
width: auto;
padding: 0.35rem 0.7rem;
font-size: 0.8rem;
gap: 0.3rem;
}
.pen-bar__action--icon {
padding: 0.35rem 0.55rem;
}
/* ── Badges ───────────────────────────────────────────────── */
.badge {
display: inline-flex;
align-items: center;
gap: 0.2rem;
padding: 0.18rem 0.45rem;
border-radius: 5px;
font-size: 0.7rem;
font-weight: 700;
white-space: nowrap;
}
.badge--ok {
background: rgba(var(--ok-rgb), 0.14);
color: var(--ok);
}
.badge--warn {
background: rgba(var(--warn-rgb), 0.16);
color: var(--warn);
}
/* ── Per-book copy button ─────────────────────────────────── */
.book-status {
margin-left: auto;
flex-shrink: 0;
}
.copy-btn {
width: 32px;
height: 32px;
padding: 0;
border-radius: var(--radius-book);
background: rgba(var(--accent-rgb), 0.12);
color: var(--accent);
border: 1px solid rgba(var(--accent-rgb), 0.25);
}
.copy-btn:hover {
background: rgba(var(--accent-rgb), 0.25);
}
.copy-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
transform: none;
}
.copy-btn--danger {
background: rgba(var(--err-rgb), 0.12);
color: var(--err);
border-color: rgba(var(--err-rgb), 0.25);
}
.copy-btn--danger:hover {
background: rgba(var(--err-rgb), 0.25);
}
.copy-btn--ghost {
background: rgba(92, 115, 133, 0.08);
color: var(--text-muted);
border-color: rgba(92, 115, 133, 0.2);
}
.copy-btn--ghost:hover {
background: rgba(92, 115, 133, 0.18);
}
/* ── Copy progress bar ────────────────────────────────────── */
.copy-progress {
height: 4px;
background: var(--bg-input);
border-radius: 2px;
overflow: hidden;
}
/* ── Dev Menu ────────────────────────────────────────────── */
.dev-menu-backdrop {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(4px);
z-index: 1000;
display: flex;
align-items: flex-end;
padding: 1rem;
padding-bottom: calc(env(safe-area-inset-bottom) + 1rem);
}
.dev-menu {
width: 100%;
max-width: 480px;
margin: 0 auto;
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 1.25rem;
display: flex;
flex-direction: column;
gap: 1rem;
}
.dev-menu__header {
display: flex;
align-items: center;
justify-content: space-between;
}
.dev-menu__title {
font-size: 1rem;
font-weight: 700;
}
.dev-menu__close {
background: none;
border: none;
color: var(--text-muted);
font-size: 1.1rem;
cursor: pointer;
padding: 0.25rem;
line-height: 1;
}
.dev-menu__desc {
font-size: 0.82rem;
color: var(--text-muted);
line-height: 1.5;
}
.dev-menu__active {
display: flex;
align-items: center;
gap: 0.4rem;
font-size: 0.82rem;
color: var(--ok);
word-break: break-all;
}
.dev-menu__active code {
font-family: monospace;
font-size: 0.8rem;
opacity: 0.85;
}
.dev-menu__active-dot {
width: 8px;
height: 8px;
background: var(--ok);
border-radius: 50%;
flex-shrink: 0;
animation: pulse 1.5s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.4; }
}
.dev-menu__row {
display: flex;
gap: 0.5rem;
}
.dev-menu__row .input {
flex: 1;
}
.dev-menu__actions {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.copy-progress__bar {
height: 100%;
background: var(--accent);
border-radius: 2px;
transition: width 0.15s ease;
}