/** Datei: themes/default/library/ARUNOX/Themes/Default/Theme.php **/ * @copyright 2025 ARUNOX * @version 1.0.0 * @since 1.0.0 File is created */ namespace ARUNOX\Themes\Default; use ARUNOX\Core; class Theme extends Core\Theme { /* ### PUBLIC FUNCTIONS ######################################### # */ public function getLable() : string { return 'Default Theme'; } } /** Datei: themes/default/hooks/init.php **/ * @copyright 2025 ARUNOX * @version 1.0.0 * @since 1.0.0 File is created */ use ARUNOX\Core\Hooks; use ARUNOX\Themes\LCARS\Theme; Hooks::add("theme::scripts->before", function() { ?> 0 ) { $color : lighten( $color, $brightness ); } @if( $alpha != 1 ) { $color : rgba( red( $color ), green( $color ), blue( $color ), $alpha ); } @return $color } @function getCoreColor( $color, $alpha : 1, $brightness : 0 ) { @return getColor( $core-colors, $color, $alpha, $brightness ); } @function getThemeColor( $color, $alpha : 1, $brightness : 0 ) { @return getColor( $theme-colors, $color, $alpha, $brightness ); } @function getColorTone( $color, $level : 100, $tint: null, $tint-strength: 15% ) { $base: getThemeColor( $color, 1, getBrightness( $level ) ); @if $tint == null { @return $base; } $accent: getThemeColor( $tint ); @return mix( $accent, $base, $tint-strength ); } @function getBrightness( $level : 100 ) { @return map-get( $brightness-levels, $level ); } $brightness-levels: ( 50 : 5%, 100 : 0%, 200 : -2.5%, 300 : -5%, 400 : -7.5%, 500 : -10%, ); // Farbvariablen $core-colors: ( blue : #33abc9, purple : #800080, green : #28a745, red : #dc3545, yellow : #ffc107, cyan : #17a2b8, gray-darkest : #212529, gray-darker : #495057, gray-dark : #adb5bd, gray : #dee2e6, gray-light : #f1f3f5, gray-lighter : #f8f9fa, gray-lightest : #fcfcfc, white : #ffffff, black : #000000, ); $theme-colors: ( primary : getCoreColor( blue ), secondary : getCoreColor( purple ), success : getCoreColor( green ), danger : getCoreColor( red ), warning : getCoreColor( yellow ), info : getCoreColor( cyan ), text : getCoreColor( gray-darkest ), label : getCoreColor( gray-darker ), border : getCoreColor( gray ), header : getCoreColor( gray-light ), content : getCoreColor( white ), background : getCoreColor( gray-lighter ), ); :root { @each $name, $color in $theme-colors { --theme-color-#{$name} : #{$color}; } } $icon-font-family: bootstrap-icons; // Layoutvariablen $sidebar-width : 250px; $header-height : 60px; $gap-tiny : 5px; $gap-small : 10px; $gap-default : 15px; $gap-wide : 20px; $border-radius : 0; /** Datei: themes/default/assets/scss/components/_breadcrumbs.scss **/ .breadcrumbs { display: flex; gap: 0.5rem; &__{ &item { color: getThemeColor( secondary ); cursor: pointer; &:hover { color: getThemeColor( primary ); } &--active { font-weight: bold; cursor: default; color: getThemeColor( primary ); } &--inactive { cursor: default; color: getThemeColor( primary ); } } &separator { &:before { content: '/'; display: block; } } } } /** Datei: themes/default/assets/scss/components/_button.scss **/ /** * _button.scss * * Stile für die Button-Komponente unter Berücksichtigung von BEM. * * @author Sparky * @copyright 2025 ARUNOX * @version 1.0.2 * @since 1.0.0 File is created * @since 1.0.1 Farben mit Bootstrap-Variablen korrigiert * @since 1.0.2 Dynamische Farben aus _buttons.scss übernommen */ @import "../variables"; // Stellt sicher, dass Theme-Variablen geladen werden @mixin buttonColors() { background-color: var( --color-background ); color: var( --color-text ); &:hover { background-color: var( --color-background-hover ); color: var( --color-text-hover ); } &:active { background-color: var( --color-background-acive ); color: var( --color-text-acive ); } } button { border: 0; background: transparent; outline: 0; } .button { display: inline-flex; align-items: center; justify-content: center; padding: 0.2em 0.6em; font-size: 1rem; border-radius: $border-radius; border: none; cursor: pointer; transition: background 0.3s ease, transform 0.2s ease, box-shadow 0.2s ease; font-weight: bold; gap: $gap-small; min-height: 2rem; outline: 0; @include buttonColors(); & { &-- { &wrapper { position: relative; display: inline-block; } } &__ { &dropdown { position: absolute; top: 100%; right: 0; display: none; z-index: 10; gap: $gap-small; padding: 5px; border: 1px solid #{getCoreColor( gray )}; background: #fff; border-radius: $border-radius; &.open { display: flex; flex-direction: column; } &__item { display: block; width: 100%; .button { width: 100%; background: none; color: #{getThemeColor( text )} !important; min-height: auto; padding: 0.4em 0.8em; font-size: 0.9rem; justify-content: start; white-space: nowrap; &:hover { background: rgba(0, 0, 0, 0.05); } } } } icon { // margin-right: 0.5rem; // font-size: 1.2rem; } } } } /** Datei: themes/default/assets/scss/_tooltip.scss **/ [title], [data-tooltip] { cursor: help; } .tooltip { position: absolute; padding: 0.5rem 1rem; border-radius: $border-radius; background-color: #000; color: #fff; font-size: 0.9rem; text-align: center; z-index: 10000; white-space: nowrap; &::after { content: ''; position: absolute; border-style: solid; border-width: 6px; /* Größe des Pfeils */ display: block; } &.tooltip-bottom::after { top: -12px; /* Pfeil über dem Tooltip */ border-color: transparent transparent #000 transparent; } &.tooltip-top::after { bottom: -12px; /* Pfeil unter dem Tooltip */ border-color: #000 transparent transparent transparent; } &.tooltip-top, &.tooltip-bottom { &.tooltip-align-left::after { left: 10%; transform: translateX(0); } &.tooltip-align-center::after { left: 50%; transform: translateX(-50%); } &.tooltip-align-right::after { right: 10%; transform: translateX(0); } } &.tooltip-left::after { right: -12px; /* Pfeil neben dem Tooltip */ border-color: transparent transparent transparent #000; } &.tooltip-right::after { left: -12px; /* Pfeil neben dem Tooltip */ border-color: transparent #000 transparent transparent; } &.tooltip-left, &.tooltip-right { &.tooltip-align-top::after { top: 10%; transform: translateX(0); } &.tooltip-align-middle::after { top: 50%; transform: translateY(-50%); } &.tooltip-align-bottom::after { bottom: 10%; transform: translateX(0); } } } /** Datei: themes/default/assets/scss/_sidebar.scss **/ .template__sidebar { &.menu { display: flex; flex-direction: column; gap: 0.5rem; overflow-y: auto; color: getThemeColor( primary ); } .menu { &__sub { // display: flex; flex-direction: column; gap: 0.5rem; } &__link, &__label { padding: 0.8rem 1rem; border-radius: $border-radius; font-weight: bold; cursor: pointer; flex: 1 1 auto; } &__link { &--active { background-color: getThemeColor( primary ); color: getCoreColor( white ); } &.behavior-default { &:hover { background-color: getHoverColor( primary ); color: getCoreColor( white ); } } } &__label { border-bottom: 1px solid getThemeColor( border ); background-color: getColorTone( content, 400 ); color: getThemeColor( text ); } &__item { > #{$menu-sub} { padding-left: 0; #{$menu-link} { color: getThemeColor( text ); &:hover { background-color: getHoverColor( border ); } &--active { background-color: getThemeColor( primary ); color: getCoreColor( white ); #{$menu-icon} { color: getCoreColor( white ) !important; } &:hover { background-color: getHoverColor( primary ); } } } } &.has-children { &::after { right: 1rem; top: 0.8rem; translate: 0 0.25em; color: inherit; pointer-events: none; } } &.has-active > #{$menu-link} { background-color: getHoverColor( border ); color: getHoverColor( primary ); &:hover { background-color: getHoverColor( primary ); color: getCoreColor( white ); } } } &__category { margin-block: $gap-wide; // background-color: getColorTone( content, 400 ); } &__icon { font-size: 1.2rem; &:not( :only-child ) { margin-right: 0.5rem; } } } } /** Datei: themes/default/assets/scss/_utilities.scss **/ // Statusfarben @function getContrastColor( $color, $dark, $light, $threshold : 55% ) { @return if( lightness( $color ) < $threshold, $light, $dark ) } $colors: map-merge( $theme-colors, $core-colors ); @each $name, $color in $colors { .bg--colored-#{$name} { --background-color: #{$color}; --color: #{getContrastColor( $color, getCoreColor( black ), getCoreColor( white ) )}; background-color: var( --background-color ) !important; color: var( --color ) !important; } .text--colored-#{$name} { --color: #{$color}; color: var( --color ) !important; } .icon--colored-#{$name} { --icon: #{$color}; i, &:is( i ) { color: var( --icon ) !important; } } .border--colored-#{$name} { --border-color: #{$color}; border-color: var( --border-color ) !important; } } .cursor--pointer { cursor : pointer; }; @keyframes animate-rotate { from { transform: rotate( 0deg ); } to { transform: rotate( 360deg ); } } .opacity-50 { opacity: 0.5 !important; } .opacity-75 { opacity: 0.75 !important; } .opacity-100 { opacity: 1 !important; } .p-1 { padding: 0.25rem !important; } .p-2 { padding: 0.5rem !important; } .p-3 { padding: 1rem !important; } .m-1 { margin: 0.25rem !important; } .m-2 { margin: 0.5rem !important; } .m-3 { margin: 1rem !important; } /** Datei: themes/default/assets/scss/_base.scss **/ html { font-size: 14px; } body { font-family: Arial, sans-serif; margin: 0; background-color: getThemeColor( background ); color: getThemeColor( text ); container-name: body; container-type: size; height: 100vh; width: 100vw; } a { text-decoration: none; color: getThemeColor( primary ); &:hover { color: getHoverColor( primary ); } &.link { cursor: pointer; } } h1, h2, h3, h4, h5, h6 { margin: 0; font-weight: bold; } .highlight { background-color: #f0f8ff; /* Hellblau */ transition: background-color 0.3s ease; } .headline, .paragraph { .icon { margin-right: $gap-small; } em { text-decoration: underline; font-style: normal; } } .paragraph { line-height: 1.48em; } /** Datei: themes/default/assets/scss/templates/_default.scss **/ .template { $parent: &; &__ { &wrapper { display: grid; grid-template-rows: $header-height 1fr; // Navbar oben grid-template-columns: $sidebar-width 1fr; // Sidebar links grid-template-areas: "sidebar header" "sidebar main"; height: 100vh; width: 100vw; } &header { grid-area: header; height: $header-height; background-color: getThemeColor( content ); border-bottom: 1px solid getThemeColor( border ); display: flex; align-items: center; padding: 0 1rem; } &sidebar { grid-area: sidebar; width: $sidebar-width; background-color: getThemeColor( content ); border-right: 1px solid getThemeColor( border ); padding: $gap-default; } &logo { margin: $gap-wide; max-height: #{$gap-wide * 1.5}; object-fit: contain; object-position: left; } &aside { grid-area: aside; padding: 1rem; } &content { grid-area: main; padding: $gap-wide; overflow-y: auto; } &headline { } &inner { display: flex; padding: 1.5rem; flex-direction: column; gap: $gap-default; .paragraph { margin: 0; } } } &-- { @import 'login'; } } /** Datei: themes/default/assets/scss/templates/_login.scss **/ &login { gap: 0; grid-template-rows: 1fr; grid-template-columns: 1fr 1fr; grid-template-areas: 'main aside'; @container ( orientation: portrait ) { grid-template-rows: 1fr 1fr; grid-template-columns: 1fr; grid-template-areas: 'main' 'aside'; } #{$parent} { &__ { &content { justify-content: center; align-items: center; display: flex; } &inner { min-width: 50%; background-color: getThemeColor( content ); border: 1px solid getThemeColor( border ); padding: $gap-wide; } &aside { background-color: getThemeColor( secondary ); border-left: 1px solid getThemeColor( secondary, 1, -15 ); display: grid; img { max-width : 50%; max-height: 100%; margin: auto } } } } } /** Datei: themes/default/assets/scss/_header.scss **/ #header { display: flex; justify-content: space-between; align-items: center; height: $header-height; padding: 0 1rem; .user-menu { display: flex; align-items: center; gap: 1rem; .user-name { font-weight: bold; } .dropdown { display: none; a { display: block; padding: 0.5rem; color: getThemeColor( secondary ); &:hover { color: getThemeColor( primary ); } } } } } /** Datei: themes/default/assets/scss/layouts/_menu.scss **/ .menu { list-style: none; padding: 0; margin: 0; &__ { &sub { $menu-sub: & !global; display: none; list-style: none; margin: 0; } &item, &category { position: relative; display: flex; cursor: pointer; &.has-children { display: flex; flex-direction: column; } } &link { $menu-link: & !global; display: flex; } &item { $menu-item: & !global; > #{$menu-sub} { padding-left: 16px; } &.has-children { > #{$menu-link}::after { content: "▼"; font-size: 12px; margin-left: auto; transition: transform 0.2s ease; position: absolute; right: 1rem; top: 1rem; } } &.is-expanded { #{$menu-link}::after { transform: rotate(180deg); } } &--active { font-weight: bold; } } &badge { margin-left: auto; aspect-ratio: 1; border-radius: 50%; background: #fff; color: #33abc9; display: flex; align-items: center; justify-content: center; height: 1.4rem; } &category { $menu-category: & !global; > #{$menu-sub} { display: block; } } &link, &label { text-decoration: none; color: inherit; display: flex; align-items: center; gap: 8px; flex-grow: 1; } &icon { $menu-icon: & !global; font-size: 16px; } } // Submenu öffnen, wenn Parent aktiv ist .is-expanded { > #{$menu-sub} { display: flex; } } } /** Datei: themes/default/assets/scss/layouts/_tabs.scss **/ /** * _tabs.scss * * Stile für das dynamische Tab-System im BEM-Format. * * @author Sparky * @copyright 2025 ARUNOX * @version 1.1.0 * @since 1.0.0 File is created * @since 1.1.0 Anpassung an BEM-Konventionen */ .tabs { display: flex; flex-direction: column; gap: $gap-wide; width: 100%; .headline, .paragraph { grid-column: 1/-1; } &__ { &list { display: flex; list-style: none; gap: $gap-tiny; padding: 0; margin: 0; border-bottom: 2px solid #{getCoreColor( gray )}; } &item { padding: 0.2em 0.6em; font-size: 1rem; gap: $gap-small; min-height: 2rem; border-radius: $border-radius; border: none; background: transparent; cursor: pointer; transition: background 0.2s ease; display: flex; align-items: center; user-select: none; &:hover { background: rgba(0, 0, 0, 0.05); } &--active { font-weight: bold; @include highlightBorder(); } &--action { margin-left: auto; // Action-Tabs immer rechts background: rgba(0, 0, 0, 0.05); border-radius: $border-radius; & + & { margin-left: 0; } } @include buttonColors(); } &content { padding: 15px; border: 1px solid #{getThemeColor( border )}; background: #fff; &__item { display: flex; flex-direction: column; gap: $gap-default; display: grid; grid-template-columns: repeat( 2, 1fr ); > * { margin-block: 0; } > .form__group { grid-column: 1/-1; } } } &icon { font-size: 16px; } } } /** Datei: themes/default/assets/scss/wrapper/_dialog.scss **/ // ===================================== // Dialog-Styles // ===================================== .dialog { width: 90%; max-width: 600px; background-color: var(--color-background, #fff); border: none; border-radius: 8px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2); z-index: 1000; transition: opacity 300ms ease, transform 0.3s ease; opacity: 0; overflow: hidden; padding: 0; max-height: calc( 100vh - 6rem ); &::backdrop { } &.is- { &open { transform: scale(1); opacity: 1; } &closing { transform: scale(0.95); opacity: 0; } } &-- { &sm { max-width: 400px; } &md { max-width: 600px; // Standard } &lg { max-width: 800px; } &xl { max-width: 1200px; } &full { width: 100%; height: 100%; max-width: none; max-height: none; border-radius: 0; } &max { margin-top: 3rem; height: 100%; .scroll__viewport { height : 100vh; } } &equal { .scroll__viewport { height : var( --height ); } } &top { margin-top: 3rem; } } &__{ &wrapper { // max-height: 50vh; } &close { position: absolute; top: 0rem; right: 0rem; background: transparent; border: none; font-size: 1.25rem; cursor: pointer; color: var(--color-text, #666); transition: color 0.2s ease; outline: 0; padding: 0; line-height: 1em; &:hover { color: var(--color-danger, #d00); } } &header { flex-shrink: 0; display: flex; justify-content: space-between; align-items: center; padding: 0 0 1rem 0; border-bottom: 1px solid #eee; background: var(--color-background, #fff); position: sticky; top: 0; z-index: 2; } &content { flex-grow: 1; overflow-y: auto; padding: 0 1.5rem; margin: 0 -1.5rem; &:has(.tabs__content) { overflow: visible; padding: 0; margin: 0; .tabs__content { max-height: calc( 100vh - 6rem - var( --maxHeight ) - 1.5rem + 10px ); overflow-y: auto; border: 0; margin-inline: -1.5rem; padding-inline: 1.5rem; padding-bottom: 1.5rem; padding-block: 5px; margin-blok: -5px; } } } &backdrop { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.6); backdrop-filter: blur(3px); opacity: 0; transition: opacity 300ms ease-in-out; z-index: 999; } } } /** Datei: themes/default/assets/scss/wrapper/notification.scss **/ .notification { display: flex; align-items: center; gap: $gap-default; padding: $gap-default; border-radius: $border-radius; background-color: getCoreColor( gray, 0.95); color: getThemeColor( text ); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); position: relative; min-width: 280px; max-width: 350px; opacity: 1; transform: translateY(0); transition: opacity 0.4s ease, transform 0.4s ease; pointer-events: auto; background-color: var( --color-background ); border-color: var( --color-border ); color: var( --color-text ); &.is-closing { opacity: 0; transform: translateY(-20px); } &__ { &wrapper { position: fixed; top: $gap-default; right: $gap-default; display: flex; flex-direction: column; gap: $gap-small; z-index: 1050; pointer-events: none; } &icon { display: flex; align-items: center; font-family: $icon-font-family; font-size: 1.4rem; opacity: 0.8; } &message { flex: 1; font-size: 0.95rem; line-height: 1.4; } &close { background: transparent; border: none; font-size: 1.2rem; cursor: pointer; padding: 0; color: inherit; opacity: 0.7; transition: all 0.3s ease-in-out; &:hover { opacity: 1; } } } @each $name, $color in $theme-colors { &--#{$name} { background-color: getThemeColor($name, 0.9); color: #{getContrastColor( #{$color}, getCoreColor(black), getCoreColor(white) )}; border-left: 4px solid getThemeColor($name); .notification__close { color: inherit; &:hover { color: getThemeColor( $name, 1, -10 ); } } } } } /** Datei: themes/default/assets/scss/_badge.scss **/ /** * _badge.scss * * Stile für das Badge-Element im BEM-Style, angepasst an bestehende Variablen und Utilities. * * @author Sparky * @copyright 2025 ARUNOX * @version 1.1.0 * @since 1.0.0 File is created * @since 1.1.0 Anpassung an Theme-Variablen und Utility-Klassen */ .badge { display: inline-flex; align-items: center; padding: $gap-small $gap-default; border-radius: $border-radius; font-size: 12px; font-weight: bold; color: getThemeColor(white); &--primary { background-color: getThemeColor(primary); } &--success { background-color: getThemeColor(success); } &--danger { background-color: getThemeColor(danger); } &--rounded { border-radius: $border-radius * 2; } &__text { padding: 0 4px; } } /** Datei: themes/default/assets/scss/_navbar.scss **/ .template__navbar { &.menu { display: flex; flex-direction: row-reverse; gap: $gap-tiny; } .menu { &__sub { $menu-sub: & !global; display: none; flex-direction: column; gap: $gap-tiny; &:hover { display: flex; } } &__link, &__label { padding: 0.8rem 1rem; color: getThemeColor( secondary ); border-radius: $border-radius; font-weight: bold; cursor: pointer; } &__link { &--active { background-color: getThemeColor( secondary ); color: getCoreColor( white ); } &.behavior-default { &:hover { background-color: getHoverColor( secondary ); color: getCoreColor( white ); } } } &__label { border-bottom: 1px solid getThemeColor( border ); background-color: getColorTone( content, 400 ); color: getThemeColor( text ); } &__item { &:hover, &--active { color: getCoreColor( white ); } &.has-children { &::after { right: 1rem; top: 0.8rem; translate: 0 0.25em; color: inherit; pointer-events: none; } } } &__category { // margin-block: $gap-wide; // background-color: getCoreColor( header ); &:hover { .menu__sub { display: flex; } } } &__icon { font-size: 1.2rem; &:not( :only-child ) { margin-right: $gap-tiny; } } } } /** Datei: themes/default/assets/scss/styles.scss **/ /** * styles.scss * * Hauptstylesheet für das Projekt, lädt alle SCSS-Module. * * @author Sparky * @copyright 2025 ARUNOX * @version 1.0.1 * @since 1.0.0 File is created * @since 1.0.1 Aktualisiert: BEM-Button-Stile importiert */ * { &, &::before, &::after { box-sizing: border-box; } } @mixin transition( $property: all, $duration: 200ms, $timing-function: ease-in-out, $behavior: normal, $delay: 0 ) { transition-property: $property; transition-duration: $duration; transition-timing-function: $timing-function; transition-behavior: $behavior; transition-delay: $delay; } @mixin highlightBorder( $position: bottom ) { position : relative; &:before { content: ''; display: block; position : absolute; bottom: 0; right: 0; left: 0; top: 0; pointer-events: none; @if( $position == all or $position == bottom or $position == horizontal ) { border-bottom: 3px solid #{getThemeColor( primary )}; } @if( $position == all or $position == top or $position == horizontal ) { border-top: 3px solid #{getThemeColor( primary )}; } @if( $position == all or $position == left or $position == vertical ) { border-left: 3px solid #{getThemeColor( primary )}; } @if( $position == all or $position == right or $position == vertical ) { border-right: 3px solid #{getThemeColor( primary )}; } } } #main { grid-area: main; } #header { grid-area: header; } #sidebar { grid-area: sidebar; } @import 'variables'; @import 'utilities'; @import 'base'; @import 'templates/default'; @import 'tooltip'; @import '#{$restdir}/colors/styles.scss'; @import 'components/button'; @import 'components/breadcrumbs'; @import 'layouts/menu'; @import 'layouts/tabs'; @import '#{$restdir}/layout/form'; @import '#{$restdir}/layout/table'; @import 'wrapper/notification'; @import '#{$restdir}/wrapper/dialog'; @import 'sidebar'; @import 'header'; @import 'navbar'; @import 'badge'; /** Datei: themes/default/assets/js/default.js **/ /** Datei: themes/default/templates/index.php **/ ARUNOX Framework
/** Datei: themes/default/config.php **/ '1.0.0', 'dependencies' => ['user'], // Abhängigkeit zum User-Plugin ];