MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m57s
Almost no side margin, 14 px indent per level (22 px from tablet width on), zoom and delete buttons only take width in the active row. Very deep rows keep about 14rem and the note scrolls sideways instead of squeezing the text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
565 lines
14 KiB
CSS
565 lines
14 KiB
CSS
/* ==========================================================================
|
|
MINDSIFT THEME ENGINE — ZENTRALE EINBINDUNG
|
|
Jedes Theme ist eine eigenständige CSS-Datei unter src/themes/ mit 6 Gruppen:
|
|
1. Akzentfarbe
|
|
2. Oberflächen & Hintergründe
|
|
3. Text & Kontraste
|
|
4. Rahmen, Linien & Schatten
|
|
5. Status- & Signalfarben
|
|
6. Rundungen (Geometrie)
|
|
========================================================================== */
|
|
|
|
@import './themes/theme-dark.css';
|
|
@import './themes/theme-light.css';
|
|
@import './themes/theme-high-contrast.css';
|
|
@import './themes/theme-soft.css';
|
|
@import './themes/theme-polarized.css';
|
|
@import './themes/theme-suri.css';
|
|
|
|
@tailwind base;
|
|
@tailwind components;
|
|
@tailwind utilities;
|
|
|
|
* {
|
|
box-sizing: border-box;
|
|
-webkit-tap-highlight-color: transparent;
|
|
}
|
|
|
|
body {
|
|
background-color: var(--bg-app);
|
|
color: var(--text-main);
|
|
font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
overflow-x: hidden;
|
|
transition: background-color 140ms ease, color 140ms ease;
|
|
}
|
|
|
|
/* Scrollbar über Theme-Variablen */
|
|
::-webkit-scrollbar {
|
|
width: 5px;
|
|
height: 5px;
|
|
}
|
|
|
|
::-webkit-scrollbar-track {
|
|
background: transparent;
|
|
}
|
|
|
|
::-webkit-scrollbar-thumb {
|
|
background: var(--scrollbar-thumb);
|
|
border-radius: var(--radius-btn);
|
|
}
|
|
|
|
::-webkit-scrollbar-thumb:hover {
|
|
background: var(--scrollbar-thumb-hover);
|
|
}
|
|
|
|
/* ==========================================================================
|
|
SEMANTISCHE KOMPONENTEN-KLASSEN (100% Theme-gesteuert)
|
|
========================================================================== */
|
|
|
|
@layer components {
|
|
/* Haupt-Karten, Sidebars und Container */
|
|
.panel-surface {
|
|
background-color: var(--bg-panel);
|
|
border: 1px solid var(--border-color);
|
|
border-radius: var(--radius-card);
|
|
}
|
|
|
|
.panel-elevated {
|
|
background-color: var(--bg-panel-elevated);
|
|
border: 1px solid var(--border-color);
|
|
border-radius: var(--radius-card);
|
|
}
|
|
|
|
.panel-header {
|
|
border-bottom: 1px solid var(--border-color);
|
|
}
|
|
|
|
/* Automatische Übernahme von --radius-card auf gerahmten Panels & Boxen */
|
|
.bg-panel.border,
|
|
.bg-canvas.border {
|
|
border-radius: var(--radius-card);
|
|
}
|
|
|
|
/* An explicit rounded-full (round icon buttons, avatars) wins over the theme radius above */
|
|
.bg-panel.border.rounded-full,
|
|
.bg-canvas.border.rounded-full {
|
|
border-radius: 9999px;
|
|
}
|
|
|
|
/* Quick-Capture-Blase im Header (immer vollständig abgerundet) */
|
|
.capture-pill,
|
|
.capture-pill.bg-panel.border {
|
|
border-radius: 9999px !important;
|
|
}
|
|
|
|
/* Quick-Capture-Blase bei mehrzeiliger Eingabe (Shift+Enter) */
|
|
.capture-bar-multiline,
|
|
.capture-bar-multiline.bg-panel.border {
|
|
border-radius: 18px !important;
|
|
}
|
|
|
|
/* Aufgaben-Checkboxen */
|
|
.checkbox-square {
|
|
border-radius: var(--radius-checkbox);
|
|
}
|
|
|
|
/* Standard-Aktionsbutton */
|
|
.btn-action {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 0.375rem;
|
|
height: 1.75rem;
|
|
padding-left: 0.625rem;
|
|
padding-right: 0.625rem;
|
|
background-color: var(--bg-input);
|
|
border: 1px solid var(--border-color);
|
|
border-radius: var(--radius-btn);
|
|
color: var(--text-muted);
|
|
font-size: 0.75rem;
|
|
font-weight: 500;
|
|
transition: all 120ms ease;
|
|
cursor: pointer;
|
|
}
|
|
.btn-action:hover {
|
|
background-color: var(--bg-panel-elevated);
|
|
color: var(--text-main);
|
|
}
|
|
|
|
/* Primärer Akzent-Button */
|
|
.btn-primary {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 0.375rem;
|
|
height: 1.75rem;
|
|
padding-left: 0.75rem;
|
|
padding-right: 0.75rem;
|
|
background-color: var(--accent-primary);
|
|
border: 1px solid var(--accent-border);
|
|
border-radius: var(--radius-btn);
|
|
color: var(--text-on-accent);
|
|
font-size: 0.75rem;
|
|
font-weight: 500;
|
|
transition: all 120ms ease;
|
|
cursor: pointer;
|
|
}
|
|
.btn-primary:hover {
|
|
background-color: var(--accent-hover);
|
|
}
|
|
|
|
/* Kleiner Icon-Button */
|
|
.btn-icon {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 1.75rem;
|
|
height: 1.75rem;
|
|
background-color: var(--bg-input);
|
|
border: 1px solid var(--border-color);
|
|
border-radius: var(--radius-btn);
|
|
color: var(--text-muted);
|
|
transition: all 120ms ease;
|
|
cursor: pointer;
|
|
}
|
|
.btn-icon:hover {
|
|
background-color: var(--bg-panel-elevated);
|
|
color: var(--text-main);
|
|
}
|
|
|
|
.btn-icon-danger {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 1.75rem;
|
|
height: 1.75rem;
|
|
background-color: var(--bg-input);
|
|
border: 1px solid var(--border-color);
|
|
border-radius: var(--radius-btn);
|
|
color: var(--text-muted);
|
|
transition: all 120ms ease;
|
|
cursor: pointer;
|
|
}
|
|
.btn-icon-danger:hover {
|
|
background-color: var(--bg-danger);
|
|
color: var(--color-danger);
|
|
border-color: var(--border-danger);
|
|
}
|
|
|
|
/* Sekundärer Button */
|
|
.btn-secondary {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 0.375rem;
|
|
height: 1.75rem;
|
|
padding-left: 0.75rem;
|
|
padding-right: 0.75rem;
|
|
background-color: var(--bg-panel-elevated);
|
|
border: 1px solid var(--border-color);
|
|
border-radius: var(--radius-btn);
|
|
color: var(--text-main);
|
|
font-size: 0.75rem;
|
|
font-weight: 500;
|
|
transition: all 120ms ease;
|
|
cursor: pointer;
|
|
}
|
|
.btn-secondary:hover {
|
|
background-color: var(--bg-panel-hover);
|
|
border-color: var(--border-strong);
|
|
}
|
|
|
|
/* Gefahren-/Löschen-Button */
|
|
.btn-danger {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 0.375rem;
|
|
height: 1.75rem;
|
|
padding-left: 0.75rem;
|
|
padding-right: 0.75rem;
|
|
background-color: var(--bg-danger);
|
|
border: 1px solid var(--border-danger);
|
|
border-radius: var(--radius-btn);
|
|
color: var(--color-danger);
|
|
font-size: 0.75rem;
|
|
font-weight: 500;
|
|
transition: all 120ms ease;
|
|
cursor: pointer;
|
|
}
|
|
.btn-danger:hover {
|
|
filter: brightness(1.15);
|
|
}
|
|
|
|
/* Zentrales Texteingabefeld & Aliasse */
|
|
.input-field,
|
|
.input-base {
|
|
background-color: var(--bg-input);
|
|
border: 1px solid var(--border-color);
|
|
border-radius: var(--radius-input);
|
|
color: var(--text-main);
|
|
font-size: 0.75rem;
|
|
transition: border-color 120ms ease;
|
|
}
|
|
.input-field:focus,
|
|
.input-base:focus {
|
|
outline: none;
|
|
border-color: var(--accent-primary);
|
|
}
|
|
.input-field::placeholder,
|
|
.input-base::placeholder {
|
|
color: var(--text-faint);
|
|
}
|
|
|
|
/* Header Tabs */
|
|
.tab-btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
padding: 0.5rem 0.875rem;
|
|
font-size: 0.75rem;
|
|
font-weight: 500;
|
|
color: var(--text-muted);
|
|
border-bottom: 2px solid transparent;
|
|
transition: all 120ms ease;
|
|
cursor: pointer;
|
|
}
|
|
.tab-btn:hover {
|
|
color: var(--text-main);
|
|
background-color: var(--bg-panel-elevated);
|
|
}
|
|
.tab-btn-active {
|
|
color: var(--accent-primary);
|
|
border-bottom-color: var(--accent-primary);
|
|
background-color: var(--bg-panel-elevated);
|
|
}
|
|
|
|
/* Status Badges */
|
|
.badge-accent {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.25rem;
|
|
padding: 0.125rem 0.5rem;
|
|
background-color: var(--accent-dim);
|
|
border: 1px solid var(--accent-border);
|
|
border-radius: var(--radius-btn);
|
|
color: var(--accent-primary);
|
|
font-size: 0.75rem;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.badge-neutral {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.25rem;
|
|
padding: 0.125rem 0.375rem;
|
|
background-color: var(--bg-input);
|
|
border: 1px solid var(--border-color);
|
|
border-radius: var(--radius-btn);
|
|
color: var(--text-muted);
|
|
font-size: 0.65rem;
|
|
font-weight: 500;
|
|
}
|
|
|
|
/* Round counter, rendered by <CountBadge> (Doku/ui-patterns.md). Accent = needs attention (nav bar),
|
|
muted = plain amount (tabs, lists). Corner = notification badge on the top right of a relative parent. */
|
|
.count-badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
min-width: 16px;
|
|
height: 16px;
|
|
padding: 0 0.25rem;
|
|
border-radius: 9999px;
|
|
font-size: 9px;
|
|
font-weight: 700;
|
|
line-height: 1;
|
|
font-variant-numeric: tabular-nums;
|
|
pointer-events: none;
|
|
}
|
|
.count-badge-accent {
|
|
background-color: var(--accent-primary);
|
|
color: var(--text-on-accent);
|
|
}
|
|
.count-badge-muted {
|
|
background-color: var(--text-muted);
|
|
color: var(--bg-panel);
|
|
}
|
|
.count-badge-corner {
|
|
position: absolute;
|
|
top: -0.5rem;
|
|
right: -0.5rem;
|
|
z-index: 1;
|
|
/* ring in the page colour keeps the badge readable on top of borders */
|
|
box-shadow: 0 0 0 2px var(--bg-app);
|
|
}
|
|
|
|
.badge-ok {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.25rem;
|
|
padding: 0.125rem 0.375rem;
|
|
background-color: var(--bg-success);
|
|
border: 1px solid var(--border-success);
|
|
border-radius: var(--radius-btn);
|
|
color: var(--color-success);
|
|
font-size: 0.65rem;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.badge-err {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.25rem;
|
|
padding: 0.125rem 0.375rem;
|
|
background-color: var(--bg-danger);
|
|
border: 1px solid var(--border-danger);
|
|
border-radius: var(--radius-btn);
|
|
color: var(--color-danger);
|
|
font-size: 0.65rem;
|
|
font-weight: 500;
|
|
}
|
|
|
|
/* Status Alert Boxen */
|
|
.alert-ok {
|
|
padding: 0.75rem;
|
|
background-color: var(--bg-success);
|
|
border: 1px solid var(--border-success);
|
|
border-radius: var(--radius-card);
|
|
color: var(--text-main);
|
|
font-size: 0.75rem;
|
|
}
|
|
|
|
.alert-err {
|
|
padding: 0.75rem;
|
|
background-color: var(--bg-danger);
|
|
border: 1px solid var(--border-danger);
|
|
border-radius: var(--radius-card);
|
|
color: var(--color-danger);
|
|
font-size: 0.75rem;
|
|
}
|
|
|
|
/* Code- & Terminal-Blöcke */
|
|
.code-block {
|
|
background-color: var(--bg-code);
|
|
border: 1px solid var(--border-color);
|
|
border-radius: var(--radius-card);
|
|
color: var(--text-main);
|
|
}
|
|
|
|
/* Modal-Hintergrund-Overlay */
|
|
.modal-overlay {
|
|
margin: 0 !important;
|
|
top: 0 !important;
|
|
left: 0 !important;
|
|
right: 0 !important;
|
|
bottom: 0 !important;
|
|
background-color: var(--bg-overlay);
|
|
backdrop-filter: blur(4px);
|
|
}
|
|
|
|
/* Verhindert, dass Elterncontainer mit space-y-* oder space-x-* feste Overlays nach unten verschieben */
|
|
.fixed.inset-0,
|
|
[class*="fixed inset-0"] {
|
|
margin: 0 !important;
|
|
}
|
|
|
|
/* File Tree Item */
|
|
.tree-node-active {
|
|
background-color: var(--bg-panel-elevated);
|
|
border-left: 2px solid var(--accent-primary);
|
|
color: var(--text-main);
|
|
}
|
|
|
|
/* Prism Syntax Highlighting Tokens (VS Code Dark+ / Light+ via Theme Variables) */
|
|
:root {
|
|
--code-keyword: #569cd6;
|
|
--code-string: #ce9178;
|
|
--code-number: #b5cea8;
|
|
--code-comment: #6a9955;
|
|
--code-property: #9cdcfe;
|
|
--code-function: #dcdcaa;
|
|
--code-type: #4ec9b0;
|
|
--code-punctuation: #d4d4d4;
|
|
--code-variable: #9cdcfe;
|
|
}
|
|
|
|
:root:not(.dark),
|
|
:root[data-theme="light"] {
|
|
--code-keyword: #0000ff;
|
|
--code-string: #a31515;
|
|
--code-number: #098658;
|
|
--code-comment: #008000;
|
|
--code-property: #0451a5;
|
|
--code-function: #795e26;
|
|
--code-type: #267f99;
|
|
--code-punctuation: #3b3b3b;
|
|
--code-variable: #001080;
|
|
}
|
|
|
|
.token.comment,
|
|
.token.prolog,
|
|
.token.doctype,
|
|
.token.cdata {
|
|
color: var(--code-comment);
|
|
font-style: italic;
|
|
}
|
|
|
|
.token.punctuation,
|
|
.token.operator {
|
|
color: var(--code-punctuation);
|
|
}
|
|
|
|
.token.property,
|
|
.token.key,
|
|
.token.attr-name {
|
|
color: var(--code-property);
|
|
}
|
|
|
|
.token.string,
|
|
.token.char,
|
|
.token.attr-value,
|
|
.token.scalar,
|
|
.token.inserted,
|
|
.language-css .token.string,
|
|
.style .token.string {
|
|
color: var(--code-string);
|
|
}
|
|
|
|
.token.number,
|
|
.token.constant,
|
|
.token.symbol,
|
|
.token.datetime {
|
|
color: var(--code-number);
|
|
}
|
|
|
|
.token.keyword,
|
|
.token.boolean,
|
|
.token.null,
|
|
.token.atrule,
|
|
.token.directive,
|
|
.token.tag,
|
|
.token.deleted {
|
|
color: var(--code-keyword);
|
|
}
|
|
|
|
.token.key.atrule {
|
|
color: var(--code-property);
|
|
}
|
|
|
|
.token.function,
|
|
.token.function-variable {
|
|
color: var(--code-function);
|
|
}
|
|
|
|
.token.class-name,
|
|
.token.type,
|
|
.token.builtin,
|
|
.token.namespace {
|
|
color: var(--code-type);
|
|
}
|
|
|
|
.token.variable,
|
|
.token.regex,
|
|
.token.important,
|
|
.token.selector,
|
|
.token.entity,
|
|
.token.url {
|
|
color: var(--code-variable);
|
|
}
|
|
|
|
.token.boolean.important,
|
|
.token.null.important {
|
|
color: var(--code-keyword);
|
|
}
|
|
}
|
|
|
|
/* ==========================================================================
|
|
EMOJI PICKER (emoji-picker-react Integration & Mobile Touch Tuning)
|
|
========================================================================== */
|
|
|
|
.mindsift-emoji-picker .EmojiPickerReact {
|
|
border: none !important;
|
|
font-family: inherit !important;
|
|
}
|
|
|
|
@media (max-width: 639px) {
|
|
/* Prevent iOS auto-zoom on input focus */
|
|
.mindsift-emoji-picker .EmojiPickerReact input.epr-search-input {
|
|
font-size: 1rem !important;
|
|
min-height: 44px !important;
|
|
}
|
|
|
|
/* Min 44px touch targets on mobile */
|
|
.mindsift-emoji-picker .EmojiPickerReact button.epr-emoji {
|
|
min-width: 44px !important;
|
|
min-height: 44px !important;
|
|
}
|
|
|
|
/* Category icons are sprite cut-outs: they must keep the library's square size (stretching them showed
|
|
two icons and an oval highlight). More breathing room comes from the nav row instead. */
|
|
.mindsift-emoji-picker .EmojiPickerReact .epr-category-nav {
|
|
padding-top: 6px !important;
|
|
padding-bottom: 6px !important;
|
|
}
|
|
}
|
|
|
|
/* Read-only sections (e.g. server settings in the demo): everything inside looks switched off */
|
|
fieldset:disabled :is(button, input, select, textarea) {
|
|
opacity: 0.5;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
/* Outliner: indent per level and the width a row keeps for its text. Phones indent less and let very
|
|
deep rows run wider than the screen (the note then scrolls sideways) instead of squeezing the text. */
|
|
:root {
|
|
--outline-indent: 14px;
|
|
--outline-min-text: 14rem;
|
|
}
|
|
@media (min-width: 640px) {
|
|
:root {
|
|
--outline-indent: 22px;
|
|
--outline-min-text: 0px;
|
|
}
|
|
}
|