Initial commit: Personal Dashboard
Next.js 16 dashboard with configurable widgets (favorites, notes, calendar, clock, calculator, search, domain-check), multi-tab support, user auth, dark mode, and Docker deployment. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,378 @@
|
||||
/* Such-Widget
|
||||
Einheitliche Widget-Chrome bleibt erhalten:
|
||||
- normaler Rahmen
|
||||
- Bearbeitungsmenü bleibt sichtbar
|
||||
- Resize-Ecke bleibt frei
|
||||
- kein Widget-Titel
|
||||
- Suchzeile mittig und kompakt
|
||||
*/
|
||||
|
||||
.app .widgetCard-search {
|
||||
position: relative !important;
|
||||
border: 1px solid var(--border) !important;
|
||||
background: color-mix(in srgb, var(--surface) 82%, transparent) !important;
|
||||
border-radius: 14px !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
/* Titel ausblenden, aber Header-Struktur fuer Menu/Griff erhalten */
|
||||
.app .widgetCard-search .widgetTitle {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Normalmodus: kein leerer Titelbereich */
|
||||
.app .widgetCard-search:not(.widgetCardEditMode) .widgetHeader {
|
||||
height: 0 !important;
|
||||
min-height: 0 !important;
|
||||
max-height: 0 !important;
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
/* Bearbeitungsmodus: Header bleibt fuer Griff und Menue vorhanden */
|
||||
.app .widgetCard-search.widgetCardEditMode .widgetHeader {
|
||||
height: 26px !important;
|
||||
min-height: 26px !important;
|
||||
max-height: 26px !important;
|
||||
padding: 0 34px 0 32px !important;
|
||||
margin: 0 !important;
|
||||
overflow: visible !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
}
|
||||
|
||||
/* Menue im Suchwidget darf nie verschwinden */
|
||||
.app .widgetCard-search .widgetMenu {
|
||||
display: block !important;
|
||||
visibility: visible !important;
|
||||
opacity: 1 !important;
|
||||
z-index: 1500 !important;
|
||||
}
|
||||
|
||||
.app .widgetCard-search .widgetMenuButton {
|
||||
display: inline-flex !important;
|
||||
visibility: visible !important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.app .widgetCard-search.widgetCardMenuOpen {
|
||||
z-index: 1600 !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
.app .widgetCard-search.widgetCardMenuOpen .widgetDropdown {
|
||||
z-index: 1700 !important;
|
||||
max-height: min(260px, 70vh) !important;
|
||||
overflow-y: auto !important;
|
||||
}
|
||||
|
||||
/* Normalmodus: Suchzeile in kompletter Widgetflaeche zentrieren */
|
||||
.app .widgetCard-search:not(.widgetCardEditMode) .widgetContent {
|
||||
position: absolute !important;
|
||||
inset: 0 !important;
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
min-width: 0 !important;
|
||||
min-height: 0 !important;
|
||||
display: grid !important;
|
||||
place-items: center !important;
|
||||
padding: 8px !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
/* Bearbeitungsmodus: unterhalb Header zentrieren, Resize-Ecke freihalten */
|
||||
.app .widgetCard-search.widgetCardEditMode .widgetContent {
|
||||
position: absolute !important;
|
||||
inset: 26px 0 0 0 !important;
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
min-width: 0 !important;
|
||||
min-height: 0 !important;
|
||||
display: grid !important;
|
||||
place-items: center !important;
|
||||
padding: 6px 10px 12px 8px !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
/* Suchformular mittig, einzeilig, mit Luft zur Resize-Ecke */
|
||||
.app .widgetCard-search .searchWidgetForm {
|
||||
width: 100% !important;
|
||||
min-width: 0 !important;
|
||||
max-width: 100% !important;
|
||||
display: grid !important;
|
||||
grid-template-columns: minmax(92px, 140px) minmax(0, 1fr) 38px !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
gap: 6px !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
/* Eingaben gleich hoch und kompakt */
|
||||
.app .widgetCard-search .searchWidgetForm .select,
|
||||
.app .widgetCard-search .searchWidgetForm .searchInput {
|
||||
height: 34px !important;
|
||||
min-height: 34px !important;
|
||||
max-height: 34px !important;
|
||||
padding: 0 10px !important;
|
||||
border-radius: 9px !important;
|
||||
font-size: 12px !important;
|
||||
line-height: 34px !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
/* Suchbutton: einheitlich, nicht in die Ecke gedrueckt */
|
||||
.app .widgetCard-search .searchWidgetForm .button,
|
||||
.app .widgetCard-search .searchWidgetForm button[type="submit"] {
|
||||
width: 38px !important;
|
||||
min-width: 38px !important;
|
||||
max-width: 38px !important;
|
||||
height: 38px !important;
|
||||
min-height: 38px !important;
|
||||
max-height: 38px !important;
|
||||
position: relative !important;
|
||||
display: inline-grid !important;
|
||||
place-items: center !important;
|
||||
align-self: center !important;
|
||||
justify-self: center !important;
|
||||
padding: 0 !important;
|
||||
overflow: hidden !important;
|
||||
color: transparent !important;
|
||||
font-size: 0 !important;
|
||||
line-height: 0 !important;
|
||||
text-indent: -9999px !important;
|
||||
border-radius: 10px !important;
|
||||
}
|
||||
|
||||
/* Lupenkreis */
|
||||
.app .widgetCard-search .searchWidgetForm .button::before,
|
||||
.app .widgetCard-search .searchWidgetForm button[type="submit"]::before {
|
||||
content: "" !important;
|
||||
position: absolute !important;
|
||||
left: 50% !important;
|
||||
top: 50% !important;
|
||||
width: 14px !important;
|
||||
height: 14px !important;
|
||||
border: 2px solid #fff !important;
|
||||
border-radius: 999px !important;
|
||||
background: transparent !important;
|
||||
transform: translate(-58%, -58%) !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
/* Lupengriff */
|
||||
.app .widgetCard-search .searchWidgetForm .button::after,
|
||||
.app .widgetCard-search .searchWidgetForm button[type="submit"]::after {
|
||||
content: "" !important;
|
||||
position: absolute !important;
|
||||
left: 50% !important;
|
||||
top: 50% !important;
|
||||
width: 9px !important;
|
||||
height: 2px !important;
|
||||
background: #fff !important;
|
||||
border: 0 !important;
|
||||
border-radius: 999px !important;
|
||||
transform: translate(1px, 5px) rotate(45deg) !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
/* Schmale Widgets */
|
||||
@media (max-width: 640px) {
|
||||
.app .widgetCard-search .searchWidgetForm {
|
||||
grid-template-columns: minmax(72px, 110px) minmax(0, 1fr) 38px !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* FIX: Such-Widget-Menü wieder sichtbar machen.
|
||||
Nicht-destruktiv: Widget-Chrome bleibt erhalten, nur Layering/Clipping wird korrigiert. */
|
||||
|
||||
.app .widgetCard-search {
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
/* Im Bearbeitungsmodus muss der Header als Menü-/Griff-Zone sichtbar bleiben */
|
||||
.app .widgetCard-search.widgetCardEditMode .widgetHeader {
|
||||
position: relative !important;
|
||||
z-index: 50 !important;
|
||||
height: 26px !important;
|
||||
min-height: 26px !important;
|
||||
max-height: 26px !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
overflow: visible !important;
|
||||
pointer-events: auto !important;
|
||||
}
|
||||
|
||||
/* Menü explizit sichtbar und über dem Suchformular */
|
||||
.app .widgetCard-search.widgetCardEditMode .widgetMenu {
|
||||
display: block !important;
|
||||
position: absolute !important;
|
||||
top: 2px !important;
|
||||
right: 6px !important;
|
||||
z-index: 2000 !important;
|
||||
visibility: visible !important;
|
||||
opacity: 1 !important;
|
||||
pointer-events: auto !important;
|
||||
}
|
||||
|
||||
.app .widgetCard-search.widgetCardEditMode .widgetMenuButton {
|
||||
display: inline-flex !important;
|
||||
visibility: visible !important;
|
||||
opacity: 1 !important;
|
||||
pointer-events: auto !important;
|
||||
}
|
||||
|
||||
/* Dropdown über allem und scrollbar */
|
||||
.app .widgetCard-search.widgetCardMenuOpen,
|
||||
.app .widgetCard-search.widgetCardEditMode.widgetCardMenuOpen {
|
||||
overflow: visible !important;
|
||||
z-index: 2000 !important;
|
||||
}
|
||||
|
||||
.app .widgetCard-search.widgetCardMenuOpen .widgetDropdown {
|
||||
display: grid !important;
|
||||
visibility: visible !important;
|
||||
opacity: 1 !important;
|
||||
z-index: 2100 !important;
|
||||
max-height: min(260px, 70vh) !important;
|
||||
overflow-y: auto !important;
|
||||
pointer-events: auto !important;
|
||||
}
|
||||
|
||||
/* Content darf das Menü nicht überdecken */
|
||||
.app .widgetCard-search.widgetCardEditMode .widgetContent {
|
||||
z-index: 1 !important;
|
||||
pointer-events: auto !important;
|
||||
}
|
||||
|
||||
/* FINAL FIX: Such-Widget behält einheitliche Widget-Chrome.
|
||||
Ursache: vorherige Regeln haben den Header abhängig von widgetCardEditMode versteckt.
|
||||
Diese Regeln nutzen den tatsächlich vorhandenen Menü-/Drag-Button als Edit-Indikator. */
|
||||
|
||||
/* Sobald Menü oder Griff existieren, ist das Widget im Bearbeitungszustand:
|
||||
Header sichtbar halten, damit Menü/Griff nicht verschwinden. */
|
||||
.app .widgetCard-search:has(.widgetMenuButton) .widgetHeader,
|
||||
.app .widgetCard-search:has(.widgetDragHandle) .widgetHeader {
|
||||
display: flex !important;
|
||||
position: relative !important;
|
||||
z-index: 3000 !important;
|
||||
height: 26px !important;
|
||||
min-height: 26px !important;
|
||||
max-height: 26px !important;
|
||||
padding: 0 34px 0 32px !important;
|
||||
margin: 0 !important;
|
||||
align-items: center !important;
|
||||
overflow: visible !important;
|
||||
pointer-events: auto !important;
|
||||
border-bottom: 0 !important;
|
||||
}
|
||||
|
||||
/* Menü im Suchwidget sichtbar und klickbar halten */
|
||||
.app .widgetCard-search:has(.widgetMenuButton) .widgetMenu {
|
||||
display: block !important;
|
||||
position: absolute !important;
|
||||
top: 2px !important;
|
||||
right: 6px !important;
|
||||
z-index: 3100 !important;
|
||||
visibility: visible !important;
|
||||
opacity: 1 !important;
|
||||
pointer-events: auto !important;
|
||||
}
|
||||
|
||||
.app .widgetCard-search:has(.widgetMenuButton) .widgetMenuButton {
|
||||
display: inline-flex !important;
|
||||
visibility: visible !important;
|
||||
opacity: 1 !important;
|
||||
pointer-events: auto !important;
|
||||
}
|
||||
|
||||
/* Griff links sichtbar halten */
|
||||
.app .widgetCard-search:has(.widgetDragHandle) .widgetDragHandle {
|
||||
display: grid !important;
|
||||
visibility: visible !important;
|
||||
opacity: 1 !important;
|
||||
pointer-events: auto !important;
|
||||
z-index: 3100 !important;
|
||||
}
|
||||
|
||||
/* Im Bearbeitungszustand Content unter Header setzen und Resize-Ecke freihalten */
|
||||
.app .widgetCard-search:has(.widgetMenuButton) .widgetContent,
|
||||
.app .widgetCard-search:has(.widgetDragHandle) .widgetContent {
|
||||
position: absolute !important;
|
||||
inset: 26px 0 0 0 !important;
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
min-width: 0 !important;
|
||||
min-height: 0 !important;
|
||||
display: grid !important;
|
||||
place-items: center !important;
|
||||
padding: 5px 22px 18px 8px !important;
|
||||
overflow: visible !important;
|
||||
z-index: 1 !important;
|
||||
pointer-events: auto !important;
|
||||
}
|
||||
|
||||
/* Widget selbst darf Menü/Dropdown nicht clippen */
|
||||
.app .widgetCard-search,
|
||||
.app .widgetCard-search.widgetCardMenuOpen {
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
/* Dropdown über anderen Widgets und scrollbar */
|
||||
.app .widgetCard-search.widgetCardMenuOpen .widgetDropdown,
|
||||
.app .widgetCard-search:has(.widgetMenuButton) .widgetDropdown {
|
||||
display: grid !important;
|
||||
visibility: visible !important;
|
||||
opacity: 1 !important;
|
||||
z-index: 3200 !important;
|
||||
max-height: min(260px, 70vh) !important;
|
||||
overflow-y: auto !important;
|
||||
pointer-events: auto !important;
|
||||
}
|
||||
|
||||
/* Suchzeile bleibt einheitlich und ragt nicht in die Resize-Ecke */
|
||||
.app .widgetCard-search:has(.widgetMenuButton) .searchWidgetForm,
|
||||
.app .widgetCard-search:has(.widgetDragHandle) .searchWidgetForm {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
min-width: 0 !important;
|
||||
align-items: center !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
/* FINAL FIX: Such-Widget nutzt dieselbe Transparenzlogik wie alle Widgets.
|
||||
Nicht-destruktiv: Chrome, Menü, Drag, Resize und Suchfunktion bleiben erhalten. */
|
||||
|
||||
.app .widgetCard-search {
|
||||
background: transparent !important;
|
||||
border-color: var(--border) !important;
|
||||
box-shadow: var(--shadow) !important;
|
||||
isolation: isolate !important;
|
||||
}
|
||||
|
||||
/* Die normale Widget-Bubble wieder aktivieren.
|
||||
Wichtig: Transparenz kommt über --widget-opacity wie bei allen anderen Widgets. */
|
||||
.app .widgetCard-search::before {
|
||||
content: "" !important;
|
||||
display: block !important;
|
||||
position: absolute !important;
|
||||
inset: 0 !important;
|
||||
z-index: -1 !important;
|
||||
pointer-events: none !important;
|
||||
background:
|
||||
linear-gradient(
|
||||
180deg,
|
||||
color-mix(in srgb, var(--surface-strong) 92%, transparent),
|
||||
color-mix(in srgb, var(--surface) 92%, transparent)
|
||||
) !important;
|
||||
border-radius: inherit !important;
|
||||
opacity: var(--widget-opacity, 1) !important;
|
||||
}
|
||||
|
||||
/* Inhalt bleibt vollständig sichtbar und unabhängig von der Bubble-Transparenz */
|
||||
.app .widgetCard-search > * {
|
||||
position: relative !important;
|
||||
z-index: 1 !important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
Reference in New Issue
Block a user